unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, IniFiles, backup, FileCtrl, ShellAPI;

type
  TMainWindow = class(TForm)
    Label1: TLabel;
    Install: TBackupFile;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormPaint(Sender: TObject);
  private
    { Private declarations }
  public
   AppTitle, AppVer, AppCompany, AppExe, InstDir: String;
   a: String;
   IniFile: TIniFile;
   x: Integer;
   NumGroups: Integer;
   procedure Go;
   procedure Go2;
   procedure Go3;
   procedure Go4;
  end;

var
  MainWindow: TMainWindow;
  Lang: String;
  WW1,WW2,WW3,WW4,WW5: String;
  DW1,DW2,DW3,DW4,DW5: String;
  EW1,EW2,EW3,EW4,EW5: String;

implementation

uses Welcome, Dest, EULA, Progress, SetupComplete;
{$R *.DFM}

procedure TMainWindow.Go;
begin
  if not FileExists(ExtractFilePath(Application.ExeName)+'setup.inf') then
  begin
    Application.MessageBox('Setup files not found.','ERROR!',mb_ok+mb_iconstop);
    Application.Terminate;
  end;
  IniFile := TIniFile.Create(ExtractFilePath(Application.ExeName)+'setup.inf');
  AppTitle:=IniFile.ReadString('App','Title','');
  AppVer:=IniFile.ReadString('App','Version','');
  AppCompany:=IniFile.ReadString('App','Company','');
  AppExe:=IniFile.ReadString('App','ExeName','');
  InstDir:=IniFile.ReadString('Options','Dir','');
  MainWindow.Caption :=IniFile.ReadString('Options','Title','');
  WelcomeWindow.ComboBox1.Text:=IniFile.ReadString('Options','Language','');
  Label1.Caption :=AppTitle;

  Lang:=WelcomeWindow.ComboBox1.Text+'Dialogs';
  WW1:=IniFile.ReadString(Lang,'Welcome1','');
  WW2:=IniFile.ReadString(Lang,'Welcome2','');
  WW3:=IniFile.ReadString(Lang,'Welcome3','');
  WW4:=IniFile.ReadString(Lang,'Welcome4','');
  DW1:=IniFile.ReadString(Lang,'Destination1','');
  DW2:=IniFile.ReadString(Lang,'Destination2','');
  DW3:=IniFile.ReadString(Lang,'Destination3','');
  DW4:=IniFile.ReadString(Lang,'Destination4','');
  DW5:=IniFile.ReadString(Lang,'Destination5','');
  EW1:=IniFile.ReadString(Lang,'EULA1','');
  EW2:=IniFile.ReadString(Lang,'EULA2','');
  EW3:=IniFile.ReadString(Lang,'EULA3','');
  EW4:=IniFile.ReadString(Lang,'EULA4','');
  EW5:=IniFile.ReadString(Lang,'EULA5','');

  WelcomeWindow.Caption:=WW1;
  WelcomeWindow.Label1.Caption:=WW2;
  WelcomeWindow.CloseBtn.Caption:=WW3;
  WelcomeWindow.ContinueBtn.Caption:=WW4;
  DestWindow.Caption:=DW1;
  DestWindow.Label1.Caption:=DW2;
  DestWindow.Label2.Caption:=DW3;
  DestWindow.Button1.Caption:=DW4;
  DestWindow.Button2.Caption:=DW5;
  EULAWindow.Caption:=EW1;
  EULAWindow.Label1.Caption:=EW2;
  EULAWindow.RadioButton1.Caption:=EW3;
  EULAWindow.RadioButton2.Caption:=EW4;
  EULAWindow.Button1.Caption:=EW5;

 if IniFile.ReadString('Dialogs','Welcome','')='True' then
 begin
  WelcomeWindow.Show;
  WelcomeWindow.SetFocus();
 end;
 if IniFile.ReadString('Dialogs','Welcome','')='False' then
  Go2;
end;

procedure TMainWindow.Go2;
begin
 if IniFile.ReadString('Dialogs','Destination','')='True' then
 begin
  DestWindow.Edit1.Text:=InstDir;
  DestWindow.Show;
  DestWindow.SetFocus();
 end;
 if IniFile.ReadString('Dialogs','Destination','')='False' then
  Go3;
end;

procedure TMainWindow.Go3;
begin
 if IniFile.ReadString('Dialogs','EULA','')='True' then
 begin
  if not FileExists(ExtractFilePath(Application.ExeName)+'eula.txt') then begin
   Go4;
   Exit;
  end;

  EULAWindow.Memo1.Lines.LoadFromFile(ExtractFilePath(Application.ExeName)+'eula.txt');
  EULAWindow.Show;
  EULAWindow.SetFocus();
 end;
 if IniFile.ReadString('Dialogs','EULA','')='False' then
  Go4;
end;

function ExecuteFile(const FileName, Params, DefaultDir: string;
  ShowCmd: Integer): THandle;
var
  zFileName, zParams, zDir: array[0..79] of Char;
begin
  Result := ShellExecute(Application.MainForm.Handle, nil,
    StrPCopy(zFileName, FileName), StrPCopy(zParams, Params),
    StrPCopy(zDir, DefaultDir), ShowCmd);
end;

function GetWinDir : string;
var sWinDir: String;
    iLength: Integer;
begin
  iLength := 255;
  setLength(sWinDir, iLength);
  iLength := GetWindowsDirectory(PChar(sWinDir), iLength);
  setLength(sWinDir, iLength);
  Result := sWinDir;
end;

function GetWinSysDir : string;
const
  dwLength: DWORD = 255;
var
  pcSysDir: PChar;
begin
  GetMem(pcSysDir, dwLength);
  GetSystemDirectory(pcSysDir, dwLength);
  Result := string(pcSysDir);
  FreeMem(pcSysDir, dwLength);
end;

procedure TMainWindow.Go4;
var
  qw, Step: Integer;
  FileSection, GroupDir : string;

  procedure MakeSubDir(s : string);
  var tmp, Drive : string;
      i, k : integer;
  begin
    if pos('<INSTALLDIR>',UpperCase(s)) <> 0 then begin
       Delete(s, pos('<INSTALLDIR>',s), length('<INSTALLDIR>'));
       Insert(InstDir, s, 1);
       s := ExcludeTrailingBackslash(s);
    end
    else if pos('<WINDIR>',UpperCase(s)) <> 0 then begin
       Delete(s, pos('<WINDIR>',s), length('<WINDIR>'));
       Insert(GetWinDir, s, 1);
       s := ExcludeTrailingBackslash(s);
    end
    else if pos('<WINSYSDIR>',UpperCase(s)) <> 0 then begin
       Delete(s, pos('<WINSYSDIR>',s), length('<WINSYSDIR>'));
       Insert(GetWinSysDir, s, 1);
       s := ExcludeTrailingBackslash(s);
    end;

    Drive := ExtractFileDrive(s);
    Delete(s, 1, 3);
    for i := 1 to length(s) do begin
        if IsPathDelimiter(s,i) then begin
           tmp := '';
           for k := 1 to i-1 do
               tmp := tmp + s[k];
           if not DirectoryExists(Drive+'\'+tmp) then
              MkDir(Drive+'\'+tmp);
        end;
    end;
  end;
begin
 ProgressForm.Show;
 Application.ProcessMessages;

 NumGroups:=StrToInt(IniFile.ReadString('Groups','Count',''));

 Step := 100 div NumGroups;

 for qw:=0 to NumGroups-1 do
 begin
  FileSection := IniFile.ReadString(IniFile.ReadString('Groups','Group'+IntToStr(qw),''),'Dir','');
  if not DirectoryExists(IniFile.ReadString(IniFile.ReadString('Groups','Group'+IntToStr(qw),''),'Dir','')) then
     MakeSubDir(FileSection);

  GroupDir := IniFile.ReadString(IniFile.ReadString('Groups','Group'+IntToStr(qw),''),'Dir','');

  if pos('<INSTALLDIR>',UpperCase(GroupDir)) <> 0 then begin
     Delete(GroupDir, pos('<INSTALLDIR>',GroupDir), length('<INSTALLDIR>'));
     Insert(InstDir, GroupDir, 1);
     GroupDir := ExcludeTrailingBackslash(GroupDir);
  end
  else if pos('<WINDIR>',UpperCase(GroupDir)) <> 0 then begin
     Delete(GroupDir, pos('<WINDIR>',GroupDir), length('<WINDIR>'));
     Insert(GetWinDir, GroupDir, 1);
     GroupDir := ExcludeTrailingBackslash(GroupDir);
  end
  else if pos('<WINSYSDIR>',UpperCase(GroupDir)) <> 0 then begin
     Delete(GroupDir, pos('<WINSYSDIR>',GroupDir), length('<WINSYSDIR>'));
     Insert(GetWinSysDir, GroupDir, 1);
     GroupDir := ExcludeTrailingBackslash(GroupDir);
  end;

  ProgressForm.Text.Caption := 'Extracting '+IniFile.ReadString('Groups','Group'+IntToStr(qw),'')+' group ...';
  ProgressForm.ProgressBar.Position := ProgressForm.ProgressBar.Position + Step;
  Application.ProcessMessages;

  Install.Restore(ExtractFilePath(Application.ExeName)+IniFile.ReadString(IniFile.ReadString('Groups','Group'+IntToStr(qw),''),'Cabinet',''),GroupDir);
 end;
 ProgressForm.Close;

 SetupCompletedForm.Image1.Picture.Assign(WelcomeWindow.Image1.Picture);
 SetupCompletedForm.AppLabel.Caption := AppTitle;
 if not FileExists(AppExe) then
    SetupCompletedForm.ExeCheck.Visible := False;

 SetupCompletedForm.ShowModal;

 if SetupCompletedForm.ExeCheck.Checked then begin
    if FileExists(AppExe) then
       ExecuteFile(AppExe,'',ExtractFilePath(AppExe), SW_SHOW)
    else if FileExists(ExtractFilePath(InstDir) + ExtractFileName(AppExe)) then
       ExecuteFile(ExtractFilePath(InstDir) + ExtractFileName(AppExe),'',ExtractFilePath(InstDir), SW_SHOW)
 end;

 if SetupCompletedForm.RebootCheck.Checked then
    ExitWindowsEx(EWX_REBOOT or EWX_FORCE, 0);

 Application.Terminate;
end;

procedure TMainWindow.FormCreate(Sender: TObject);
begin
 MainWindow.Top:=0;
 MainWindow.Left:=0;
 MainWindow.Width:=Screen.Width;
 MainWindow.Height:=Screen.Height;
end;

procedure TMainWindow.FormShow(Sender: TObject);
begin
 Go;
end;

procedure TMainWindow.FormPaint(Sender: TObject);
var
  Row, Ht: Word;
begin
Ht := (ClientHeight + 255) div 256 ;

if IniFile.ReadString('Options','BGColor','')='Blue' then
for Row := 0 to 255 do
    with Canvas do begin
         Brush.Color := RGB(0, 0, Row+50) ;
         FillRect(Rect(0, Row * Ht, ClientWidth, (Row + 1) * Ht)) ;
    end ;

if IniFile.ReadString('Options','BGColor','')='Yellow' then
for Row := 0 to 255 do
    with Canvas do begin
         Brush.Color := RGB(255, 255, Row+50) ;
         FillRect(Rect(0, Row * Ht, ClientWidth, (Row + 1) * Ht)) ;
    end ; 

if IniFile.ReadString('Options','BGColor','')='Green' then
for Row := 0 to 255 do
    with Canvas do begin
         Brush.Color := RGB(100, 200, Row+50) ;
         FillRect(Rect(0, Row * Ht, ClientWidth, (Row + 1) * Ht)) ;
    end ;

if IniFile.ReadString('Options','BGColor','')='Red' then
for Row := 0 to 255 do
    with Canvas do begin
         Brush.Color := RGB(255, 0, Row+50) ;
         FillRect(Rect(0, Row * Ht, ClientWidth, (Row + 1) * Ht)) ;
    end ;
end;

end.
