unit uEmulatorSetup;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Buttons, ComCtrls, StdCtrls, IniFiles, FileCtrl, Menus;

const
  MaxSystems = 27; // always update this value when adding new systems!!!!!

type
  TFormEmulatorSetup = class(TForm)
    PageControlEmulatorSetup: TPageControl;
    TabSheetEmulators: TTabSheet;
    ButtonOk: TSpeedButton;
    ButtonCancel: TSpeedButton;
    LabelEmulator1: TGroupBox;
    ButtonSelectEmulator1: TSpeedButton;
    LabelEmuDescriptionSuperNintendo: TLabel;
    EmulatorFile1: TEdit;
    EmuDescription1: TEdit;
    LabelEmulatorSuperNintendo2: TGroupBox;
    ButtonSelectEmulator2: TSpeedButton;
    LabelLabelEmuDescriptionSuperNintendo1: TLabel;
    EmulatorFile2: TEdit;
    EmuDescription2: TEdit;
    ButtonClearEmulator1: TSpeedButton;
    ButtonSettingsEmulator1: TSpeedButton;
    ButtonSettingsEmulator2: TSpeedButton;
    ButtonClearEmulator2: TSpeedButton;
    SystemSelector: TComboBoxEx;
    Label1: TLabel;
    ButtonAddFolder: TSpeedButton;
    ButtonDeleteFolder: TSpeedButton;
    LabelGamesFolders: TLabel;
    GamesFolders: TListBox;
    GroupBoxPlayStation: TGroupBox;
    Label2: TLabel;
    Emulator1EmulatorType: TScrollBar;
    LabelEmulator1EmulatorTypeValue: TLabel;
    Emulator2EmulatorType: TScrollBar;
    LabelEmulator2EmulatorTypeValue: TLabel;
    Label3: TLabel;
    procedure ButtonCancelClick(Sender: TObject);
    procedure SystemSelectorChange(Sender: TObject);
    procedure ButtonAddFolderClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure ButtonDeleteFolderClick(Sender: TObject);
    procedure GamesFoldersKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure EmulatorFile1Change(Sender: TObject);
    procedure EmuDescription1Change(Sender: TObject);
    procedure EmulatorFile2Change(Sender: TObject);
    procedure EmuDescription2Change(Sender: TObject);
    procedure ButtonClearEmulator1Click(Sender: TObject);
    procedure ButtonClearEmulator2Click(Sender: TObject);
    procedure ButtonSelectEmulator1Click(Sender: TObject);
    procedure ButtonSelectEmulator2Click(Sender: TObject);
    procedure ButtonOkClick(Sender: TObject);
    procedure ButtonSettingsEmulator1Click(Sender: TObject);
    procedure Emulator1EmulatorTypeChange(Sender: TObject);
    procedure Emulator2EmulatorTypeChange(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
    newEmulatorFile,
    newEmulatorVersion{,
    EmulatorCRC32}: packed array[1..MaxSystems] of packed array[1..2] of String;
    newemuROMsFolders: packed array[1..MaxSystems] of THashedStringList;

    procedure InitializeEmulatorVariablesTemp;
    procedure UpdateEmulatorInfo;
    procedure SetPlayStationEmulatorType(ScrollBarHolder: TScrollBar; ValueLabel: TLabel);
  public
    { Public declarations }
  end;

var
  FormEmulatorSetup: TFormEmulatorSetup;

implementation

uses uMain, uCommon, uAtari2600_z26_Settings;

{$R *.dfm}

procedure TFormEmulatorSetup.InitializeEmulatorVariablesTemp;
var
  Loop, Loop2: Integer;
begin
  // define values for all arrays or exception error will occur....
  try
    for Loop:= 1 to MaxSystems-1 do
    begin
      for Loop2:= 1 to Length(newEmulatorFile[Loop]) do
      begin
        newEmulatorFile[Loop, Loop2]:= FormMain.EmulatorFile[Loop, Loop2];
        newEmulatorVersion[Loop, Loop2]:= FormMain.EmulatorVersion[Loop, Loop2];
        //EmulatorCRC32[Loop, Loop2]:= '';
      end;
      case Assigned(FormMain.emuROMsFolders[Loop]) of
        True:
          begin
            newemuROMsFolders[Loop]:= THashedStringList.Create;
            newemuROMsFolders[Loop].AddStrings(FormMain.emuROMsFolders[Loop]);
          end;
        False: newemuROMsFolders[Loop]:= nil;
      end;
    end;
  except
    GenerateMessage('Error', 'Could not define initial values to temporary emulator variables', 2);
  end;
end;

procedure TFormEmulatorSetup.UpdateEmulatorInfo;

  procedure VerifyEmulator(SystemID, EmulatorNumber: ShortInt; PopupHolder: TMenuItem);
  begin
    if newEmulatorFile[SystemID, EmulatorNumber] <> '' then
       begin
         if newEmulatorVersion[SystemID, EmulatorNumber] = '' then
            newEmulatorVersion[SystemID, EmulatorNumber]:= Format('%s - (%u)', [SystemSelector.ItemsEx[SystemID-1].Caption, EmulatorNumber]);
         PopupHolder.Caption:= newEmulatorVersion[SystemID, EmulatorNumber];
       end
    else
       begin
         if newEmulatorVersion[SystemID, EmulatorNumber] <> '' then
            newEmulatorVersion[SystemID, EmulatorNumber]:= '';
         PopupHolder.Caption:= '(none)';
       end;

    FormMain.EmulatorFile[SystemID, EmulatorNumber]:= newEmulatorFile[SystemID, EmulatorNumber];
    FormMain.EmulatorVersion[SystemID, EmulatorNumber]:= newEmulatorVersion[SystemID, EmulatorNumber];
    case Assigned(newemuROMsFolders[SystemID]) of
      True:
        begin
          case Assigned(FormMain.emuROMsFolders[SystemID]) of
            True : FormMain.emuROMsFolders[SystemID].Clear;
            False: FormMain.emuROMsFolders[SystemID]:= THashedStringList.Create;
          end;
          FormMain.emuROMsFolders[SystemID].AddStrings(newemuROMsFolders[SystemID]);
        end;
      False: FreeAndNil(FormMain.emuROMsFolders[SystemID]);
    end;
    FormMain.ExtractBinaryIcon(SystemID, EmulatorNumber);
  end;

begin
  VerifyEmulator(1, 1, FormMain.PopupSuperNintendo_1);
  VerifyEmulator(1, 2, FormMain.PopupSuperNintendo_2);

  VerifyEmulator(2, 1, FormMain.PopupGameboyAdvance_1);
  VerifyEmulator(2, 2, FormMain.PopupGameboyAdvance_2);

  VerifyEmulator(3, 1, FormMain.PopupNintendo_1);
  VerifyEmulator(3, 2, FormMain.PopupNintendo_2);

  VerifyEmulator(4, 1, FormMain.PopupGenesis_1);
  VerifyEmulator(4, 2, FormMain.PopupGenesis_2);

  VerifyEmulator(5, 1, FormMain.PopupAtari2600_1);
  VerifyEmulator(5, 2, FormMain.PopupAtari2600_2);

  VerifyEmulator(6, 1, FormMain.PopupIntellivision_1);
  VerifyEmulator(6, 2, FormMain.PopupIntellivision_2);

  VerifyEmulator(7, 1, FormMain.PopupMasterSystem_1);
  VerifyEmulator(7, 2, FormMain.PopupMasterSystem_2);

  VerifyEmulator(8, 1, FormMain.PopupOdyssey2_1);
  VerifyEmulator(8, 2, FormMain.PopupOdyssey2_2);

  VerifyEmulator(9, 1, FormMain.PopupGameGear_1);
  VerifyEmulator(9, 2, FormMain.PopupGameGear_2);

  VerifyEmulator(10, 1, FormMain.PopupColecoVision_1);
  VerifyEmulator(10, 2, FormMain.PopupColecoVision_2);

  VerifyEmulator(11, 1, FormMain.PopupGP32_1);
  VerifyEmulator(11, 2, FormMain.PopupGP32_2);

  VerifyEmulator(12, 1, FormMain.PopupPCEngine_1);
  VerifyEmulator(12, 2, FormMain.PopupPCEngine_2);

  VerifyEmulator(13, 1, FormMain.PopupAtariLynx_1);
  VerifyEmulator(13, 2, FormMain.PopupAtariLynx_2);

  VerifyEmulator(14, 1, FormMain.PopupAtari5200_1);
  VerifyEmulator(14, 2, FormMain.PopupAtari5200_2);

  VerifyEmulator(15, 1, FormMain.PopupAtariJaguar_1);
  VerifyEmulator(15, 2, FormMain.PopupAtariJaguar_2);

  VerifyEmulator(16, 1, FormMain.PopupSega32X_1);
  VerifyEmulator(16, 2, FormMain.PopupSega32X_2);

  VerifyEmulator(17, 1, FormMain.PopupNeoGeoPocket_1);
  VerifyEmulator(17, 2, FormMain.PopupNeoGeoPocket_2);

  VerifyEmulator(18, 1, FormMain.PopupNintendo64_1);
  VerifyEmulator(18, 2, FormMain.PopupNintendo64_2);

  VerifyEmulator(19, 1, FormMain.PopupSegaCD_1);
  VerifyEmulator(19, 2, FormMain.PopupSegaCD_2);

  VerifyEmulator(20, 1, FormMain.PopupGameboy_1);
  VerifyEmulator(20, 2, FormMain.PopupGameboy_2);

  VerifyEmulator(21, 1, FormMain.PopupPlayStation_1);
  VerifyEmulator(21, 2, FormMain.PopupPlayStation_2);

  VerifyEmulator(22, 1, FormMain.PopupGameCube_1);
  VerifyEmulator(22, 2, FormMain.PopupGameCube_2);

  VerifyEmulator(23, 1, FormMain.PopupAtari7800_1);
  VerifyEmulator(23, 2, FormMain.PopupAtari7800_2);

  VerifyEmulator(24, 1, FormMain.PopupDreamcast_1);
  VerifyEmulator(24, 2, FormMain.PopupDreamcast_2);

  VerifyEmulator(25, 1, FormMain.PopupWataraSupervision_1);
  VerifyEmulator(25, 2, FormMain.PopupWataraSupervision_2);

  VerifyEmulator(26, 1, FormMain.PopupWonderswan_1);
  VerifyEmulator(26, 2, FormMain.PopupWonderswan_2);

  FormMain.PopupPlayStation_1.Hint:= IntToStr(Emulator1EmulatorType.Position);
  FormMain.PopupPlayStation_2.Hint:= IntToStr(Emulator2EmulatorType.Position);
end;

procedure TFormEmulatorSetup.SetPlayStationEmulatorType(ScrollBarHolder: TScrollBar; ValueLabel: TLabel);
begin
  case ScrollBarHolder.Position of
    0: ValueLabel.Caption:= 'ePSXe';
    1: ValueLabel.Caption:= 'AdriPSX';
    2: ValueLabel.Caption:= 'PCSX';
  end;
end;

procedure TFormEmulatorSetup.ButtonCancelClick(Sender: TObject);
begin
  Close;
end;

procedure TFormEmulatorSetup.SystemSelectorChange(Sender: TObject);
begin
  TabSheetEmulators.Caption:= Format('Current System: %s', [SystemSelector.ItemsEx[SystemSelector.ItemIndex].Caption]);
  EmulatorFile1.Text:= newEmulatorFile[SystemSelector.ItemIndex+1, 1];
  EmuDescription1.Text:= newEmulatorVersion[SystemSelector.ItemIndex+1, 1];
  EmulatorFile2.Text:= newEmulatorFile[SystemSelector.ItemIndex+1, 2];
  EmuDescription2.Text:= newEmulatorVersion[SystemSelector.ItemIndex+1, 2];
  GamesFolders.Items.BeginUpdate;
  GamesFolders.Clear;
  GamesFolders.Items.EndUpdate;
  if Assigned(newemuROMsFolders[SystemSelector.ItemIndex+1]) then
     begin
       GamesFolders.Items.BeginUpdate;
       GamesFolders.Items.AddStrings(newemuROMsFolders[SystemSelector.ItemIndex+1]);
       GamesFolders.Items.EndUpdate;
     end;
  case SystemSelector.ItemIndex+1 of
     5: begin
          LabelEmulator1.Caption:= 'z26 - An Atari 2600 Emulator';
          ButtonSettingsEmulator1.Enabled:= True
        end;
    21: GroupBoxPlayStation.Visible:= True;
    23: LabelEmulator1.Caption:= 'EMU7800 - A .NET Atari 7800 Emulator';
    24: LabelEmulator1.Caption:= 'Chankast';
  else
     begin
       if LabelEmulator1.Caption <> 'Emulator 1' then
          LabelEmulator1.Caption:= 'Emulator 1';
       if ButtonSettingsEmulator1.Enabled then
          ButtonSettingsEmulator1.Enabled:= False;
       if GroupBoxPlayStation.Visible then
          GroupBoxPlayStation.Visible:= False;
     end;
  end;
end;

procedure TFormEmulatorSetup.ButtonAddFolderClick(Sender: TObject);
var
  Folder: String;
  AddFolder: Boolean;
begin
  if SelectDirectory('Select a folder', '', Folder) then
     begin
       Folder:= ExcludeTrailingPathDelimiter(Folder);
       AddFolder:= False;
       case Assigned(newemuROMsFolders[SystemSelector.ItemIndex+1]) of
         True:
           begin
             if newemuROMsFolders[SystemSelector.ItemIndex+1].IndexOf(Folder) = -1 then
                AddFolder:= True;

           end;
         False:
           begin
             newemuROMsFolders[SystemSelector.ItemIndex+1]:= THashedStringList.Create;
             AddFolder:= True;
           end;
       end;
       if AddFolder then
          begin
            newemuROMsFolders[SystemSelector.ItemIndex+1].Add(Folder);
            GamesFolders.Items.BeginUpdate;
            GamesFolders.Items.Add(Folder);
            GamesFolders.Items.EndUpdate;
          end;
     end;
end;

procedure TFormEmulatorSetup.ButtonDeleteFolderClick(Sender: TObject);
var
  Loop, FolderIndex: Integer;
begin
  if (GamesFolders.Items.Count = 0) or (GamesFolders.SelCount = 0) then
     Exit;

  newemuROMsFolders[SystemSelector.ItemIndex+1].BeginUpdate;
  for Loop:=0 to GamesFolders.Items.Count-1 do
  begin
    if GamesFolders.Selected[Loop] then
       begin
         FolderIndex:= newemuROMsFolders[SystemSelector.ItemIndex+1].IndexOf(GamesFolders.Items[Loop]);
         if FolderIndex <> -1 then
            newemuROMsFolders[SystemSelector.ItemIndex+1].Delete(FolderIndex);
       end;
  end;
  newemuROMsFolders[SystemSelector.ItemIndex+1].EndUpdate;
  GamesFolders.Items.BeginUpdate;
  GamesFolders.DeleteSelected;
  GamesFolders.Items.EndUpdate;
  if GamesFolders.Items.Count = 0 then
     FreeAndNil(newemuROMsFolders[SystemSelector.ItemIndex+1]);
end;

procedure TFormEmulatorSetup.FormCreate(Sender: TObject);
begin
  InitializeEmulatorVariablesTemp;
end;

procedure TFormEmulatorSetup.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
var
  Loop: ShortInt;
begin
  if CanClose then
     begin
       for Loop:=1 to MaxSystems-1 do
           FreeAndNil(newemuROMsFolders[Loop]);
     end;
end;


procedure TFormEmulatorSetup.GamesFoldersKeyUp(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
  if Key = VK_DELETE then
     ButtonDeleteFolder.Click;
end;

procedure TFormEmulatorSetup.EmulatorFile1Change(Sender: TObject);
begin
  newEmulatorFile[SystemSelector.ItemIndex+1, 1]:= TEdit(Sender).Text;
end;

procedure TFormEmulatorSetup.EmuDescription1Change(
  Sender: TObject);
begin
  newEmulatorVersion[SystemSelector.ItemIndex+1, 1]:= TEdit(Sender).Text;
end;

procedure TFormEmulatorSetup.EmulatorFile2Change(Sender: TObject);
begin
  newEmulatorFile[SystemSelector.ItemIndex+1, 2]:= TEdit(Sender).Text;
end;

procedure TFormEmulatorSetup.EmuDescription2Change(
  Sender: TObject);
begin
  newEmulatorVersion[SystemSelector.ItemIndex+1, 2]:= TEdit(Sender).Text;
end;

procedure TFormEmulatorSetup.ButtonClearEmulator1Click(Sender: TObject);
begin
  EmulatorFile1.Clear;
  EmuDescription1.Clear;
end;

procedure TFormEmulatorSetup.ButtonClearEmulator2Click(Sender: TObject);
begin
  EmulatorFile2.Clear;
  EmuDescription2.Clear;
end;

procedure TFormEmulatorSetup.ButtonSelectEmulator1Click(Sender: TObject);
begin
  FormMain.DialogOpenFile(0, Format('Select a "%s" binary', [SystemSelector.ItemsEx[SystemSelector.ItemIndex].Caption]),
                          EmulatorFile1, False, False);
end;

procedure TFormEmulatorSetup.ButtonSelectEmulator2Click(Sender: TObject);
begin
  FormMain.DialogOpenFile(0, Format('Select a "%s" binary', [SystemSelector.ItemsEx[SystemSelector.ItemIndex].Caption]),
                          EmulatorFile2, False, False);
end;

procedure TFormEmulatorSetup.ButtonOkClick(Sender: TObject);
begin
  UpdateEmulatorInfo;
  Close;
end;

procedure TFormEmulatorSetup.ButtonSettingsEmulator1Click(Sender: TObject);
begin
  if (SystemSelector.ItemIndex+1 = 5) and
     (FileExists(newEmulatorFile[SystemSelector.ItemIndex+1, 1])) then
     begin
       if not Assigned(FormAtari2600_z26_Settings) then
          FormAtari2600_z26_Settings:= TFormAtari2600_z26_Settings.Create(Self);
       FormAtari2600_z26_Settings.EmulatorFile:= newEmulatorFile[SystemSelector.ItemIndex+1, 1];
       FormMain.LoadButtonIcon(FormAtari2600_z26_Settings.ButtonClose, 7, False);
       FormMain.LoadButtonIcon(FormAtari2600_z26_Settings.ButtonDeleteAtari2600, 16, False);
       FormMain.LoadButtonIcon(FormAtari2600_z26_Settings.ButtonSaveAtari2600, 13, False);
       FormAtari2600_z26_Settings.ShowModal;
       FreeAndNil(FormAtari2600_z26_Settings);
     end;
end;

procedure TFormEmulatorSetup.Emulator1EmulatorTypeChange(Sender: TObject);
begin
  SetPlayStationEmulatorType(Emulator1EmulatorType, LabelEmulator1EmulatorTypeValue);
end;

procedure TFormEmulatorSetup.Emulator2EmulatorTypeChange(Sender: TObject);
begin
  SetPlayStationEmulatorType(Emulator2EmulatorType, LabelEmulator2EmulatorTypeValue);
end;

procedure TFormEmulatorSetup.FormShow(Sender: TObject);
begin
  FormMain.LoadButtonIcon(ButtonOk, 6, False);
  FormMain.LoadButtonIcon(ButtonCancel, 7, False);
  FormMain.LoadButtonIcon(ButtonSelectEmulator1, 2, False);
  FormMain.LoadButtonIcon(ButtonSelectEmulator2, 2, False);
  FormMain.LoadButtonIcon(ButtonSettingsEmulator1, 14, False);
  FormMain.LoadButtonIcon(ButtonSettingsEmulator2, 14, False);
  FormMain.LoadButtonIcon(ButtonClearEmulator1, 8, False);
  FormMain.LoadButtonIcon(ButtonClearEmulator2, 8, False);
  FormMain.LoadButtonIcon(ButtonAddFolder, 17, False);
  FormMain.LoadButtonIcon(ButtonDeleteFolder, 16, False);
  if SystemSelector.ItemIndex = -1 then
     begin
       SystemSelector.ItemIndex:= 0;
       SystemSelector.OnChange(Self);
     end;
end;

end.
