unit uColumnsEditor;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  StdCtrls, ExtCtrls, ComCtrls, IniFiles, Dialogs, VirtualTrees,
  ImgList, jkSpinEdit, Buttons, ToolWin, GR32_Image, GR32_RangeBars;

type
  TFormColumnsEditor = class(TForm)
    ButtonOk: TButton;
    ButtonCancel: TButton;
    LabelProfile: TLabel;
    ColumnsList: TListView;
    TopImage: TImage32;
    ButtonLoad: TButton;
    ButtonSave: TButton;
    ButtonReset: TButton;
    ButtonShowHide: TButton;
    ButtonUp: TButton;
    ButtonDown: TButton;
    SystemSelector: TComboBoxEx;
    NewProfile: TEdit;
    ButtonCreateNewProfile: TButton;
    ProfileList: TListBox;
    LabelNewProfile: TLabel;
    ColumnSize: TGaugeBar;
    LabelColumnSizeValue: TEdit;
    Label1: TLabel;
    procedure ButtonCancelClick(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure FormShow(Sender: TObject);
    procedure ButtonUpClick(Sender: TObject);
    procedure ButtonDownClick(Sender: TObject);
    procedure ButtonShowHideClick(Sender: TObject);
    procedure ColumnsListSelectItem(Sender: TObject; Item: TListItem;
      Selected: Boolean);
    procedure ColumnsListClick(Sender: TObject);
    procedure ColumnsListKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure ButtonResetClick(Sender: TObject);
    procedure ButtonLoadClick(Sender: TObject);
    procedure ColumnsListCustomDrawItem(Sender: TCustomListView;
      Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
    procedure ButtonSaveClick(Sender: TObject);
    procedure ButtonOkClick(Sender: TObject);
    procedure SystemSelectorSelect(Sender: TObject);
    procedure ProfileListClick(Sender: TObject);
    procedure ButtonCreateNewProfileClick(Sender: TObject);
    procedure ColumnSizeChange(Sender: TObject);
    procedure LabelColumnSizeValueChange(Sender: TObject);
  private
    ProfileFile: String;
    procedure LoadProfile;
    procedure SaveProfile(IsButtonSave: Boolean);
    procedure UpdateProfileLabel;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FormColumnsEditor: TFormColumnsEditor;

implementation

uses uMain, uCommon;

{$R *.DFM}

procedure TFormColumnsEditor.UpdateProfileLabel;
begin
  LabelProfile.Caption:= LabelProfile.Hint+#13#10#13#10+Format('Profile: %s', [ProfileFile]);
end;

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

procedure TFormColumnsEditor.FormKeyPress(Sender: TObject;
  var Key: Char);
begin
  if Key = #27 then
     ButtonCancel.OnClick(Self)
  else
  if Key = #13 then
     ButtonOk.OnClick(Self);
end;

procedure TFormColumnsEditor.FormShow(Sender: TObject);
var
  Loop: Integer;
  pList: THashedStringList;
begin
  pList:= THashedStringList.Create;
  GetFilesList(FormMain.GetColumnsProfileFolder, '.ini', '*.*', pList, False, True, False);
  if pList.Count > 0 then
     begin
       pList.Sort;
       ProfileList.Items.BeginUpdate;
       for Loop:=0 to pList.Count-1 do
       begin
         ProfileList.Items.Add(pList[Loop]);
       end;
       ProfileList.Items.EndUpdate;
       FreeAndNil(pList);
     end
  else
     begin
       GenerateMessage('Error', Format('No profiles files were found in "%s" folder!'
                       +#13+'Forcing "%s" profile...', [FormMain.GetColumnsProfileFolder, FormMain.ColumnsProfile[FormMain.ButtonGameFilterArcade.Tag]]), 2);
       ProfileList.Items.Add(FormMain.ColumnsProfile[FormMain.ButtonGameFilterArcade.Tag]);
     end;

  FormMain.FillEmuDescriptionsSelector(SystemSelector);
  SetComboBoxEx(SystemSelector, FormMain.ButtonGameFilterArcade.Tag, True);

  FormMain.LoadTopBar(TopImage, 'columns.png');
  Caption:= FormMain.FixCaption(FormMain.MenuColumnsEditor.Caption);
end;

procedure TFormColumnsEditor.ButtonUpClick(Sender: TObject);
var
  ItemCaption: String;
  ItemPosition, ItemID: ShortInt;
  ItemChecked: Boolean;
  ItemSize: Integer;
  InsertItem: TListItem;
begin
  if (ColumnsList.Selected <> nil) and (ColumnsList.Selected.Index > 1) then
     begin
       ItemCaption:= ColumnsList.Selected.Caption;
       ItemPosition:= ColumnsList.Selected.Index;
       ItemChecked:= ColumnsList.Selected.Checked;
       ItemSize:= StrToInt(ColumnsList.Selected.SubItems[0]);
       ItemID:= ColumnsList.Selected.ImageIndex;
       ColumnsList.DeleteSelected;
       with ColumnsList do
         InsertItem:= Items.Insert(ItemPosition-1);
       InsertItem.Caption:= ItemCaption;
       InsertItem.Checked:= ItemChecked;
       InsertItem.SubItems.Add(IntToStr(ItemSize));
       InsertItem.ImageIndex:= ItemID;
       ColumnsList.ItemFocused:= ColumnsList.Items[ItemPosition-1];
       ColumnsList.ItemIndex:= ItemPosition-1;
       ColumnsList.Selected.MakeVisible(False);
     end;
  ColumnsList.SetFocus;
end;

procedure TFormColumnsEditor.ButtonDownClick(Sender: TObject);
var
  ItemCaption: String;
  ItemPosition, ItemID: ShortInt;
  ItemChecked: Boolean;
  ItemSize: Integer;
  InsertItem: TListItem;
begin
  if (ColumnsList.Selected <> nil) and (ColumnsList.Selected.Index < (FormMain.GamesTreeView.Header.Columns.Count-1)) and
     (ColumnsList.Selected.Index > 0) then
     begin
       ItemCaption:= ColumnsList.Selected.Caption;
       ItemPosition:= ColumnsList.Selected.Index;
       ItemChecked:= ColumnsList.Selected.Checked;
       ItemSize:= StrToInt(ColumnsList.Selected.SubItems[0]);
       ItemID:= ColumnsList.Selected.ImageIndex;
       ColumnsList.DeleteSelected;
       with ColumnsList do
         InsertItem:= Items.Insert(ItemPosition+1);
       InsertItem.Caption:= ItemCaption;
       InsertItem.Checked:= ItemChecked;
       InsertItem.SubItems.Add(IntToStr(ItemSize));
       InsertItem.ImageIndex:= ItemID;
       ColumnsList.ItemFocused:= ColumnsList.Items[ItemPosition+1];
       ColumnsList.ItemIndex:= ItemPosition+1;
       ColumnsList.Selected.MakeVisible(False);
     end;
  ColumnsList.SetFocus;
end;

procedure TFormColumnsEditor.ButtonShowHideClick(Sender: TObject);
begin
  if (ColumnsList.Selected <> nil) and (ColumnsList.Selected.Index > 0) then
     begin
       case Boolean(ButtonShowHide.Tag) of
         True : ButtonShowHide.Caption:= '&Show';
         False: ButtonShowHide.Caption:= '&Hide';
       end;
       ButtonShowHide.Tag:= Ord(not Boolean(ButtonShowHide.Tag));
       ColumnsList.Selected.Checked:= Boolean(ButtonShowHide.Tag);
     end;
  ColumnsList.SetFocus;
end;

procedure TFormColumnsEditor.ColumnsListSelectItem(Sender: TObject;
  Item: TListItem; Selected: Boolean);
begin
  if Selected then
     ColumnsList.OnClick(Self);
end;

procedure TFormColumnsEditor.ColumnsListClick(Sender: TObject);
begin
  if ColumnsList.Selected <> nil then
     begin
       if ColumnsList.Selected.Index <> 0 then
          begin
            ButtonShowHide.Tag:= Ord(ColumnsList.Selected.Checked);
            case ColumnsList.Selected.Checked of
              True : ButtonShowHide.Caption:= '&Hide';
              False: ButtonShowHide.Caption:= '&Show';
            end;
          end;
       ColumnSize.Position:= StrToInt(ColumnsList.Selected.SubItems[0]);
       if ColumnsList.Selected.Index = 0 then
          ColumnsList.Selected.Checked:= True;
     end;
end;

procedure TFormColumnsEditor.ColumnsListKeyUp(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
  if Key = VK_SPACE then
     ColumnsList.OnClick(Self);
end;

procedure TFormColumnsEditor.ButtonResetClick(Sender: TObject);
var
  Loop: ShortInt;
begin
  ColumnsList.Items.BeginUpdate;
  ColumnsList.Clear;
  for Loop:=0 to FormMain.GamesTreeView.Header.Columns.Count-1 do
  begin
    with ColumnsList.Items.Add do
    begin
      Caption:= FormMain.GamesTreeView.Header.Columns.Items[Loop].Text;
      ImageIndex:= Loop;
      Checked:= True;
      SubItems.Add(IntToStr(FormMain.GamesTreeView.Header.Columns.Items[Loop].Tag));
    end;
  end;
  ColumnsList.Items.EndUpdate;
end;

procedure TFormColumnsEditor.LoadProfile;
var
  Loop: Integer;
  columnFile: TMemIniFile;
  Value: Integer;
  Continue: Boolean;
begin

  Continue:= True;
  columnFile:= TMemIniFile.Create(FormMain.GetColumnsProfileFolder+ProfileFile);

  if Continue then
     begin
       UpdateProfileLabel;
       try
         if not FormMain.SetColumnsMemList(columnFile) then
            begin
              FreeAndNil(columnFile);
              Exit;
            end;

         ColumnsList.Items.BeginUpdate;
         ColumnsList.Items.Clear;
         for Loop:=0 to FormMain.GamesTreeView.Header.Columns.Count-1 do
         begin
           with ColumnsList.Items.Add do
           begin
             ImageIndex:= FormMain.ColumnsPosList[Loop]; // column ID number (fixed, never changes)
             Caption:=  FormMain.GamesTreeView.Header.Columns.Items[ImageIndex].Text;
             Value:= columnFile.ReadInteger('Width', aColumns[FormMain.ColumnsPosList[Loop]], FormMain.GamesTreeView.Header.Columns.Items[FormMain.ColumnsPosList[Loop]].Tag);
             SubItems.Add(IntToStr(Value));
             if FormMain.ColumnsPosList[Loop] = 0 then
                Value:= 1
             else
                Value:= columnFile.ReadInteger('Visible', aColumns[FormMain.ColumnsPosList[Loop]], 1);
             Checked:= Boolean(Value);
           end;
         end;
         ColumnsList.Items.EndUpdate;
       finally
         FreeAndNil(columnFile);
         for Loop:=0 to Length(FormMain.ColumnsPosList) do
             Finalize(FormMain.ColumnsPosList);
       end;
     end;
  ColumnsList.SetFocus;
end;

procedure TFormColumnsEditor.SaveProfile(IsButtonSave: Boolean);
var
  Loop: Integer;
  columnFile: TMemIniFile;
  profileFileName: String;
  Continue: Boolean;

  procedure WriteEntries(EntryName: String; EntryIndex: ShortInt);
  begin
    columnFile.WriteInteger('Position', EntryName, EntryIndex);
    columnFile.WriteInteger('Width', EntryName, StrToInt(ColumnsList.Items[EntryIndex].SubItems[0]));
    columnFile.WriteInteger('Visible', EntryName, Ord(ColumnsList.Items[EntryIndex].Checked));
  end;

begin
  Continue:= True;
  profileFileName:= FormMain.GetColumnsProfileFolder+ProfileFile;

  if Continue then
     begin
       UpdateProfileLabel;
       try
         columnFile:= TMemIniFile.Create(profileFileName);
         for Loop:=0 to ColumnsList.Items.Count-1 do
         begin
           if ColumnsList.Items[Loop].ImageIndex = 0 then
              columnFile.WriteInteger('Width', aColumns[0], StrToInt(ColumnsList.Items[0].SubItems[0]))
           else
              WriteEntries(aColumns[ColumnsList.Items[Loop].ImageIndex], Loop)
         end;
         columnFile.UpdateFile;
       finally
         FreeAndNil(columnFile);
       end;
     end;
  case IsButtonSave of
    True : ColumnsList.SetFocus;
    False:
      begin
        FormMain.ReadColumnProfile;
        Close;
      end;
  end;
end;

procedure TFormColumnsEditor.ButtonLoadClick(Sender: TObject);
begin
  LoadProfile;
end;

procedure TFormColumnsEditor.ButtonSaveClick(Sender: TObject);
begin
  SaveProfile(True);
end;

procedure TFormColumnsEditor.ColumnsListCustomDrawItem(
  Sender: TCustomListView; Item: TListItem; State: TCustomDrawState;
  var DefaultDraw: Boolean);
begin
  if not Item.Checked then
     Sender.Canvas.Font.Color:= clGray;
end;

procedure TFormColumnsEditor.ButtonOkClick(Sender: TObject);
begin
  SaveProfile(False);
end;

procedure TFormColumnsEditor.SystemSelectorSelect(Sender: TObject);
begin
  if ProfileFile <> FormMain.ColumnsProfile[SystemSelector.ItemsEx[SystemSelector.ItemIndex].ImageIndex] then
     begin
       ProfileFile:= FormMain.ColumnsProfile[SystemSelector.ItemsEx[SystemSelector.ItemIndex].ImageIndex];
       ProfileList.ItemIndex:= ProfileList.Items.IndexOf(ProfileFile);
       if ProfileList.ItemIndex = -1 then
          GenerateMessage('Error', Format('Could not find profile "%s" in list box, '+
                          'columns settings cannot be loaded!', [ProfileFile]), 2)
       else
          ProfileList.OnClick(Self);

     end;
end;

procedure TFormColumnsEditor.ProfileListClick(Sender: TObject);
begin
  if ProfileFile <> ProfileList.Items[ProfileList.ItemIndex] then
     ProfileFile:= ProfileList.Items[ProfileList.ItemIndex];
  LoadProfile;
  if FormMain.ColumnsProfile[SystemSelector.ItemsEx[SystemSelector.ItemIndex].ImageIndex] <> ProfileFile then
     FormMain.ColumnsProfile[SystemSelector.ItemsEx[SystemSelector.ItemIndex].ImageIndex]:= ProfileFile;
end;

procedure TFormColumnsEditor.ButtonCreateNewProfileClick(Sender: TObject);
var
  nFile: String;
  nIndex: Integer;
begin
  if NewProfile.Text <> '' then
     begin
       nFile:= ChangeFileExt(NewProfile.Text, '.ini');
       if ProfileList.Items.IndexOf(nFile) = -1 then
          begin
            ProfileList.Items.BeginUpdate;
            ProfileList.Sorted:= True;
            nIndex:= ProfileList.Items.Add(nFile);
            ProfileList.Items.EndUpdate;
            ProfileList.ItemIndex:= nIndex;
            ProfileList.OnClick(Self);
          end
       else
          GenerateMessage('Warning', 'Filename already exist. Please enter a new name.', 2);
     end
  else
     GenerateMessage('Error', 'Filename not defined!', 2);
end;

procedure TFormColumnsEditor.ColumnSizeChange(Sender: TObject);
begin
  if ColumnsList.Selected = nil then
     Exit;
  LabelColumnSizeValue.Text:= IntToStr(ColumnSize.Position);
  ColumnsList.Selected.SubItems[0]:= IntToStr(ColumnSize.Position);
end;

procedure TFormColumnsEditor.LabelColumnSizeValueChange(Sender: TObject);
begin
  if ColumnSize.Position <> StrToInt(LabelColumnSizeValue.Text) then
     ColumnSize.Position:= StrToInt(LabelColumnSizeValue.Text);
end;

end.
