unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, StdCtrls, ComCtrls, ExtCtrls, ToolWin, Buttons, devTabs,
  ShellAPI, ImgList, IniFiles;

type
  TMainForm = class(TForm)
    MainMenu1: TMainMenu;
    Package1: TMenuItem;
    Help1: TMenuItem;
    About1: TMenuItem;
    Exit1: TMenuItem;
    InstallPackage1: TMenuItem;
    N1: TMenuItem;
    ToolBar1: TToolBar;
    DetailsPanel: TPanel;
    Splitter1: TSplitter;
    Packages: TListView;
    StatusBar1: TStatusBar;
    Panel2: TPanel;
    Label1: TLabel;
    SpeedButton1: TSpeedButton;
    devPages1: TdevPages;
    devPage1: TdevPage;
    devPage2: TdevPage;
    FileList: TRichEdit;
    Label2: TLabel;
    PackageName: TEdit;
    PackageVersion: TEdit;
    Label3: TLabel;
    Label4: TLabel;
    PackageDescription: TMemo;
    Label5: TLabel;
    PackageURL: TEdit;
    BitBtn1: TBitBtn;
    InstallBtn: TToolButton;
    ToolbarImages: TImageList;
    ExitBtn: TToolButton;
    ToolButton1: TToolButton;
    AboutBtn: TToolButton;
    ToolButton2: TToolButton;
    View1: TMenuItem;
    Details1: TMenuItem;
    RemoveBtn: TToolButton;
    N2: TMenuItem;
    ListImages: TImageList;
    OpenDialog1: TOpenDialog;
    PopupMenu1: TPopupMenu;
    Copy1: TMenuItem;
    MenuImages: TImageList;
    Verify1: TMenuItem;
    Remove1: TMenuItem;
    VerifyBtn: TToolButton;
    N3: TMenuItem;
    ToolbarMenu1: TMenuItem;
    N4: TMenuItem;
    ReloadDatabase1: TMenuItem;
    Help2: TMenuItem;
    N5: TMenuItem;
    HelpButton: TToolButton;
    procedure Label5Click(Sender: TObject);
    procedure Exit1Click(Sender: TObject);
    procedure View1Click(Sender: TObject);
    procedure Details1Click(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure InstallPackage1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure PackagesSelectItem(Sender: TObject; Item: TListItem;
      Selected: Boolean);
    procedure Copy1Click(Sender: TObject);
    procedure PopupMenu1Popup(Sender: TObject);
    procedure ToolbarMenu1Click(Sender: TObject);
    procedure Remove1Click(Sender: TObject);
    procedure ReloadDatabase1Click(Sender: TObject);
    procedure Verify1Click(Sender: TObject);
    procedure About1Click(Sender: TObject);
    procedure Help2Click(Sender: TObject);
  private
    procedure AppHint(Sender: TObject);
    procedure Reload;
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

uses
  InstallWizards, PackmanUtils, RemoveForms, VerifyForms, AboutForms,
  PackmanExitCodesU;

{$R *.dfm}

procedure TMainForm.Label5Click(Sender: TObject);
begin
  if Length(PackageURL.Text) > 0 then
      ShellExecute(GetDesktopWindow, nil, PChar(PackageURL.Text), nil, nil, 0);
end;

procedure TMainForm.Exit1Click(Sender: TObject);
begin
  Close;
end;

procedure TMainForm.View1Click(Sender: TObject);
begin
  Details1.Checked := DetailsPanel.Visible;
end;

procedure TMainForm.Details1Click(Sender: TObject);
begin
  DetailsPanel.Visible := Details1.Checked;
end;

procedure TMainForm.SpeedButton1Click(Sender: TObject);
begin
  DetailsPanel.Hide;
end;

procedure TMainForm.InstallPackage1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
      InstallWizard := TInstallWizard.Create(Self);
      with InstallWizard do
      try
         Self.Hide;
         Application.ProcessMessages;
         if SetFileName(OpenDialog1.FileName) then
             ShowModal
         else if not DontShowError then
             Application.MessageBox('An error has occured.' + #13#10 +
               'The selected installation file may be damaged or invalid.',
               'Error', MB_ICONHAND);
      finally
         Self.Show;
         Free;
      end;
  end;
  Reload;
end;

procedure TMainForm.AppHint(Sender: TObject);
begin
  if Length(Application.Hint) > 0 then
      StatusBar1.Panels.Items[0].Text := Application.Hint
  else
      StatusBar1.Panels.Items[0].Text := 'Ready.';
end;

procedure TMainForm.FormCreate(Sender: TObject);
var
  FileName: String;
  Auto: Boolean;
begin
  Randomize;
  Application.OnHint := AppHint;

  Auto := False;
  if CompareText(ParamStr(1), '/auto') = 0 then
  begin
      FileName := ParamStr(2);
      Auto := True;
  end else
      FileName := ParamStr(1);

  if FileExists(FileName) then
  begin
      InstallWizard := TInstallWizard.Create(Self);
      with InstallWizard do
      try
         Application.ProcessMessages;
         if SetFileName(FileName) then
         begin
             ShowModal;
             if Auto then
                 Halt(PMExitCode);
         end else begin
             if (not DontShowError) and (not Auto) then
                 Application.MessageBox('An error has occured.' + #13#10 +
                   'The selected installation file may be damaged or invalid.',
                   'Error', MB_ICONHAND);

             if Auto then
                 Halt(PMExitCode);
         end;
      finally
         Free;
      end;
  end else if Auto then
      Halt(PACKMAN_EXITCODE_FILE_NOT_FOUND);

  Reload;
end;

procedure TMainForm.PackagesSelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
var
  i: Integer;
  FileName: PChar;
  Ini: TIniFile;
  IniFile: TStringList;
begin
  for i := 0 to devPage1.ControlCount - 1 do
      devPage1.Controls[i].Enabled := Selected;
  for i := 0 to devPage2.ControlCount - 1 do
      devPage2.Controls[i].Enabled := Selected;
  RemoveBtn.Enabled := Selected;
  Remove1.Enabled := Selected;
  VerifyBtn.Enabled := Selected;
  Verify1.Enabled := Selected;
  if not Selected then Exit;

  FileName := Item.Data;
  if not FileExists(FileName) then
  begin
      Reload;
      Exit;
  end;

  Ini := TIniFile.Create(FileName);
  PackageName.Text := Ini.ReadString('Setup', 'AppName', 'Package');
  PackageVersion.Text := Ini.ReadString('Setup', 'AppVersion', '1.0');
  PackageDescription.Text := Ini.ReadString('Setup', 'Description', '');
  PackageURL.Text := Ini.ReadString('Setup', 'Url', '');
  Label5.Visible := Length(PackageURL.Text) > 0;
  PackageURL.Visible := Length(PackageURL.Text) > 0;

  IniFile := TStringList.Create;
  IniFile.LoadFromFile(FileName);
  for i := 0 to IniFile.Count - 1 do
  begin
      if CompareText(IniFile.Strings[0], '[Files]') = 0 then
      begin
          IniFile.Delete(0);
          Break;
      end else
          IniFile.Delete(0);
  end;
  FileList.Lines.Text := IniFile.Text;
  FileList.SelStart := 0;
  IniFile.Free;

  Ini.Free;
end;

procedure TMainForm.Reload;
var
  Files: TStringList;
  Ini: TIniFile;
  Item: TListItem;
  i: Integer;
  FileName: PChar;
begin
  Packages.Items.BeginUpdate;
  while Packages.Items.Count > 0 do
  begin
      FreeMem(Packages.Items[0].Data);
      Packages.Items[0].Delete;
  end;

  Files := TStringList.Create;
  FilesFromWildcard(ExtractFilePath(ParamStr(0)) + 'Packages', '*.entry',
    Files, False, False);

  for i := 0 to Files.Count - 1 do
  begin
      Ini := TIniFile.Create(Files.Strings[i]);
      Item := Packages.Items.Add;
      Item.Caption := Ini.ReadString('Setup', 'AppName', 'Package');
      Item.ImageIndex := 0;

      FileName := GetMemory(Length(Files.Strings[i]) + 1);
      FileName := StrPLCopy(FileName, Files.Strings[i],
        Length(Files.Strings[i]));
      FileName[Length(Files.Strings[i])] := #0;
      Item.Data := FileName;
      Ini.Free;
  end;
  Files.Free;
  Packages.Items.EndUpdate;
end;

procedure TMainForm.Copy1Click(Sender: TObject);
begin
  FileList.CopyToClipboard;
end;

procedure TMainForm.PopupMenu1Popup(Sender: TObject);
begin
  Copy1.Enabled := FileList.SelLength > 0;
end;

procedure TMainForm.ToolbarMenu1Click(Sender: TObject);
begin
  ToolbarMenu1.Checked := not ToolbarMenu1.Checked;
  Toolbar1.Visible := ToolbarMenu1.Checked;
end;

procedure TMainForm.Remove1Click(Sender: TObject);
begin
  if Application.MessageBox('Are you sure you want to remove this package ' +
    'and all associated files?', 'Remove confirmation',
    MB_ICONQUESTION + MB_YESNO) <> 6 then
      Exit;

  RemoveForm := TRemoveForm.Create(Self);
  with RemoveForm do
  try
     Entry := PChar(Packages.Selected.Data);
     ShowModal;
  finally
     Free;
  end;
  Reload;
end;

procedure TMainForm.ReloadDatabase1Click(Sender: TObject);
begin
  Reload;
end;

procedure TMainForm.Verify1Click(Sender: TObject);
begin
  VerifyForm := TVerifyForm.Create(Self);
  with VerifyForm do
  try
     Entry := PChar(Packages.Selected.Data);
     ShowModal;
  finally
     Free;
  end;
end;

procedure TMainForm.About1Click(Sender: TObject);
begin
  AboutForm := TAboutForm.Create(Self);
  with AboutForm do
  try
     ShowModal;
  finally
     Free;
  end;
end;

procedure TMainForm.Help2Click(Sender: TObject);
begin
  Application.MessageBox(
    'Package Manager is a tool to install and manage add-on ' + #13#10 +
    'libraries for Dev-C++.' + #13#10#13#10 +
    'To install a library, click on the Install button and select a' + #13#10 +
    '.DevPak file or .DevPackage file, and follow the instructions.' + #13#10 +
    'To uninstall an installed library, select it and click on the' + #13#10 +
    'Remove button.',
    'Help', MB_ICONINFORMATION);
end;

end.
