; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "CherryTree"
#define MyAppPublisher "Giuseppe Penone"
#define MyAppURL "https://www.giuspen.net/cherrytree/"
#define MyAppExeName "cherrytree.exe"
#define MyAppVersion GetFileVersion('C:\msys64\home\PenoneG\git\cherrytree\build\cherrytree.exe')

[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{DBA7384C-E1C6-44B5-A3B4-C94F2F0B8C0C}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppName}
DisableProgramGroupPage=yes
OutputDir=C:\msys64\home\PenoneG\git\cherrytree\build
ArchitecturesAllowed=x64
ArchitecturesInstallIn64BitMode=x64
LicenseFile=C:\msys64\home\PenoneG\git\cherrytree\build\cherrytree_{#MyAppVersion}_win64_portable\license.txt
; Uncomment the following line to run in non administrative install mode (install for current user only.)
;PrivilegesRequired=lowest
OutputBaseFilename=cherrytree_{#MyAppVersion}_win64_setup
SetupIconFile=C:\msys64\home\PenoneG\git\cherrytree\icons\cherrytree.ico
Compression=lzma2
SolidCompression=yes
WizardStyle=modern
ChangesAssociations=yes

[Registry]
Root: HKCR; Subkey: ".ctb"; ValueType: string; ValueName: ""; ValueData: "CherryTreeB"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "CherryTreeB"; ValueType: string; ValueName: ""; ValueData: "CherryTree SQLite Document"; Flags: uninsdeletekey
Root: HKCR; Subkey: "CherryTreeB\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\ucrt64\bin\{#MyAppExeName},0"
Root: HKCR; Subkey: "CherryTreeB\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\ucrt64\bin\{#MyAppExeName}"" ""%1"""
Root: HKCR; Subkey: ".ctx"; ValueType: string; ValueName: ""; ValueData: "CherryTreeX"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "CherryTreeX"; ValueType: string; ValueName: ""; ValueData: "CherryTree SQLite Zipped"; Flags: uninsdeletekey
Root: HKCR; Subkey: "CherryTreeX\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\ucrt64\bin\{#MyAppExeName},0"
Root: HKCR; Subkey: "CherryTreeX\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\ucrt64\bin\{#MyAppExeName}"" ""%1"""
Root: HKCR; Subkey: ".ctd"; ValueType: string; ValueName: ""; ValueData: "CherryTreeD"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "CherryTreeD"; ValueType: string; ValueName: ""; ValueData: "CherryTree XML Document"; Flags: uninsdeletekey
Root: HKCR; Subkey: "CherryTreeD\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\ucrt64\bin\{#MyAppExeName},0"
Root: HKCR; Subkey: "CherryTreeD\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\ucrt64\bin\{#MyAppExeName}"" ""%1"""
Root: HKCR; Subkey: ".ctz"; ValueType: string; ValueName: ""; ValueData: "CherryTreeZ"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "CherryTreeZ"; ValueType: string; ValueName: ""; ValueData: "CherryTree XML Zipped"; Flags: uninsdeletekey
Root: HKCR; Subkey: "CherryTreeZ\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\ucrt64\bin\{#MyAppExeName},0"
Root: HKCR; Subkey: "CherryTreeZ\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\ucrt64\bin\{#MyAppExeName}"" ""%1"""

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "armenian"; MessagesFile: "compiler:Languages\Armenian.isl"
Name: "brazilianportuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl"
Name: "catalan"; MessagesFile: "compiler:Languages\Catalan.isl"
Name: "corsican"; MessagesFile: "compiler:Languages\Corsican.isl"
Name: "czech"; MessagesFile: "compiler:Languages\Czech.isl"
Name: "danish"; MessagesFile: "compiler:Languages\Danish.isl"
Name: "dutch"; MessagesFile: "compiler:Languages\Dutch.isl"
Name: "finnish"; MessagesFile: "compiler:Languages\Finnish.isl"
Name: "french"; MessagesFile: "compiler:Languages\French.isl"
Name: "german"; MessagesFile: "compiler:Languages\German.isl"
Name: "hebrew"; MessagesFile: "compiler:Languages\Hebrew.isl"
Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl"
Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl"
Name: "norwegian"; MessagesFile: "compiler:Languages\Norwegian.isl"
Name: "polish"; MessagesFile: "compiler:Languages\Polish.isl"
Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl"
Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"
Name: "slovak"; MessagesFile: "compiler:Languages\Slovak.isl"
Name: "slovenian"; MessagesFile: "compiler:Languages\Slovenian.isl"
Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl"
Name: "turkish"; MessagesFile: "compiler:Languages\Turkish.isl"
Name: "ukrainian"; MessagesFile: "compiler:Languages\Ukrainian.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: "C:\msys64\home\PenoneG\git\cherrytree\build\cherrytree_{#MyAppVersion}_win64_portable\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\ucrt64\bin\{#MyAppExeName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\ucrt64\bin\{#MyAppExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}\ucrt64\bin\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

[Code]
// This helper function searches all common registry locations for an app whose name begins with AppName.
function GetUninstallStringByName(const AppName: string; var UninstallString: string): Boolean;
var
  UninstallRegKey: string;
  SubKeyNames: TArrayOfString;
  I: Integer;
  DisplayName: string;
begin
  Result := False;
  UninstallString := '';
  UninstallRegKey := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall';

  // --- Search 1: Current User (HKCU) ---
  if RegGetSubkeyNames(HKCU, UninstallRegKey, SubKeyNames) then
  begin
    for I := 0 to GetArrayLength(SubKeyNames) - 1 do
    begin
      if RegQueryStringValue(HKCU, UninstallRegKey + '\' + SubKeyNames[I], 'DisplayName', DisplayName) then
      begin
        if Pos(AppName, DisplayName) = 1 then
        begin
          if RegQueryStringValue(HKCU, UninstallRegKey + '\' + SubKeyNames[I], 'UninstallString', UninstallString) then
          begin
            Result := True;
            Exit; // Found it!
          end;
        end;
      end;
    end;
  end;

  // --- Search 2: All Users - 64-bit (HKLM64) ---
  if RegGetSubkeyNames(HKLM64, UninstallRegKey, SubKeyNames) then
  begin
    for I := 0 to GetArrayLength(SubKeyNames) - 1 do
    begin
      if RegQueryStringValue(HKLM64, UninstallRegKey + '\' + SubKeyNames[I], 'DisplayName', DisplayName) then
      begin
        if Pos(AppName, DisplayName) = 1 then
        begin
          if RegQueryStringValue(HKLM64, UninstallRegKey + '\' + SubKeyNames[I], 'UninstallString', UninstallString) then
          begin
            Result := True;
            Exit; // Found it!
          end;
        end;
      end;
    end;
  end;

  // --- Search 3: All Users - 32-bit (HKLM32) ---
  if RegGetSubkeyNames(HKLM32, UninstallRegKey, SubKeyNames) then
  begin
    for I := 0 to GetArrayLength(SubKeyNames) - 1 do
    begin
      if RegQueryStringValue(HKLM32, UninstallRegKey + '\' + SubKeyNames[I], 'DisplayName', DisplayName) then
      begin
        if Pos(AppName, DisplayName) = 1 then
        begin
          if RegQueryStringValue(HKLM32, UninstallRegKey + '\' + SubKeyNames[I], 'UninstallString', UninstallString) then
          begin
            Result := True;
            Exit; // Found it!
          end;
        end;
      end;
    end;
  end;
end;

// This is the main function that runs when setup starts.
function InitializeSetup(): Boolean;
var
  UninstallString: string;
  ResultCode: Integer;
begin
  // Set the default result to True, allowing installation to proceed.
  Result := True;

  // Use our search function to find the uninstaller.
  if GetUninstallStringByName('{#MyAppName}', UninstallString) then
  begin
    // A previous version was found.
    if WizardSilent() then
    begin
      // SILENT MODE: Uninstall automatically and silently.
      // We pass '/SILENT' to the uninstaller and use SW_HIDE to keep it hidden.
      Exec(RemoveQuotes(UninstallString), '/SILENT', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
    end
    else
    begin
      // INTERACTIVE MODE: Ask the user for permission.
      if MsgBox('A previous version of {#MyAppName} was found. Would you like to uninstall it first?', mbConfirmation, MB_YESNO) = IDYES then
      begin
        // User clicked "Yes". Run the uninstaller normally.
        if Exec(RemoveQuotes(UninstallString), '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode) then
        begin
          // Uninstall successful. Let setup continue.
          Result := True;
        end
        else
        begin
          // The uninstaller failed. Abort the setup.
          MsgBox('The previous version''s uninstaller failed to run.'#13#10'Setup will now exit.', mbError, MB_OK);
          Result := False;
        end;
      end
      else
      begin
        // User clicked "No". Abort the setup.
        MsgBox('Setup cannot continue because the previous version was not uninstalled.'#13#10'Setup will now exit.', mbInformation, MB_OK);
        Result := False;
      end;
    end;
  end;
end;
