(************************************************************************
 *                                                                      *
 *   Ant Movie Catalog 4.x                                              *
 *   (C) 2000-2006 Antoine Potten                                       *
 *   http://www.antp.be/software                                        *
 *                                                                      *
 ************************************************************************
 *                                                                      *
 *   This program is free software; you can redistribute it and/or      *
 *   modify it under the terms of the GNU General Public License        *
 *   as published by the Free Software Foundation; either version 2     *
 *   of the License, or (at your option) any later version.             *
 *                                                                      *
 *   This program is distributed in the hope that it will be useful,    *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of     *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *
 *   GNU General Public License for more details.                       *
 *                                                                      *
 ************************************************************************)

unit getscript_properties;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, base, StdCtrls, ExtCtrls, Grids, ValEdit,

  AntCorelButton, AntAutoHintLabel, AntStringList,

  getscript_readscripts, memoform, TBXDkPanels;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

type
  TScriptPropertiesWin = class(TBaseDlg)
    lstProperties: TValueListEditor;
    Messages: TAntStringList;
    grpOptions: TGroupBox;
    lstOptions: TListBox;
    btnOptionAdd: TTBXButton;
    btnOptionDel: TTBXButton;
    lstValues: TStringGrid;
    grpValues: TGroupBox;
    lblValueDefault: TLabel;
    cbxValueDefault: TComboBox;
    procedure lstPropertiesEditButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure lstOptionsClick(Sender: TObject);
    procedure lstValuesSetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String);
    procedure cbxValueDefaultChange(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure btnOptionDelClick(Sender: TObject);
    procedure btnOptionAddClick(Sender: TObject);
    procedure btn1Click(Sender: TObject);
  private
    FScript: TScriptInfo;
    FOptionsBackup: string;
    procedure Load;
    procedure Save;
  protected
    procedure LoadOptions; override;
    procedure SaveOptions; override;
  public
    procedure Translate; override;
    function Execute(const AScript: TScriptInfo; const LanguagesList: TStrings): Boolean;
  end;

var
  ScriptPropertiesWin: TScriptPropertiesWin;

const
  msgInfoAuthors  =  0;
  msgInfoTitle    =  1;
  msgInfoDescr    =  2;
  msgInfoSite     =  3;
  msgInfoLanguage =  4;
  msgInfoVersion  =  5;
  msgInfoRequires =  6;
  msgInfoComments =  7;
  msgInfoLicense  =  8;
  msgInfoGetInfo  =  9;
  msgOptionValue  = 10;
  msgOptionDescr  = 11;
  msgOptionDelete = 12;
  msgOptionName   = 13;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

implementation

{$R *.dfm}

uses
  StrUtils, Math,

  Global, ConstValues, functions_str, functions_tbx;

{-------------------------------------------------------------------------------
  TScriptPropertiesWin
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.FormCreate(Sender: TObject);
begin
  inherited;
  MemoWin := TMemoWin.Create(Self);
  LoadButtonIcon(btnOptionAdd, ICON_ROWINSERT);
  LoadButtonIcon(btnOptionDel, ICON_ROWDELETE);
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.FormShow(Sender: TObject);
begin
  inherited;
  MemoWin.Icon.Assign(Icon);
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.FormDestroy(Sender: TObject);
begin
  FreeAndNil(MemoWin);
  inherited;
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

function TScriptPropertiesWin.Execute(const AScript: TScriptInfo; const LanguagesList: TStrings): Boolean;
begin
  FScript := AScript;
  FOptionsBackup := FScript.Options.AsString;
  Load;
  with lstProperties.ItemProps[msgInfoLanguage] do
  begin
    if LanguagesList.Count > 0 then
      EditStyle := esPickList
    else
      EditStyle := esSimple;
    PickList.Assign(LanguagesList);
  end;
  Result := ShowModal = mrOk;
  if Result then
    Save
  else
    FScript.Options.AsString := FOptionsBackup;
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.Load;
  procedure SetVal(const AIndex: Integer; const AString: string);
  begin
    if AString = '' then
      lstProperties.Strings[AIndex] := lstProperties.Strings.Names[AIndex] + '='
    else
      lstProperties.Strings.ValueFromIndex[AIndex] := AString;
  end;
begin
  Assert(msgInfoAuthors = 0);
  with FScript.Properties do
  begin
    lstProperties.Strings.BeginUpdate;
    try
      SetVal(msgInfoAuthors, Authors);
      SetVal(msgInfoTitle, Title);
      SetVal(msgInfoDescr, Description);
      SetVal(msgInfoSite, Site);
      SetVal(msgInfoLanguage, Language);
      SetVal(msgInfoVersion, Version);
      SetVal(msgInfoRequires, Requires);
      SetVal(msgInfoComments, Comments);
      SetVal(msgInfoLicense, License);
      lstProperties.Strings.ValueFromIndex[msgInfoGetInfo] := IfThen(GetInfo, DefaultTrueBoolStr, DefaultFalseBoolStr);
    finally
      lstProperties.Strings.EndUpdate;
    end;
  end;
  FScript.Options.FillNames(lstOptions.Items);
  lstOptions.ItemIndex := -1;
  lstOptionsClick(lstValues);
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.Save;
begin
  with lstProperties, FScript.Properties do
  begin
    Authors := Strings.ValueFromIndex[msgInfoAuthors];
    Title := Strings.ValueFromIndex[msgInfoTitle];
    Description := Strings.ValueFromIndex[msgInfoDescr];
    Site := Strings.ValueFromIndex[msgInfoSite];
    Language := Strings.ValueFromIndex[msgInfoLanguage];
    Version := Strings.ValueFromIndex[msgInfoVersion];
    Requires := Strings.ValueFromIndex[msgInfoRequires];
    Comments := Strings.ValueFromIndex[msgInfoComments];
    License := Strings.ValueFromIndex[msgInfoLicense];
    GetInfo := Strings.ValueFromIndex[msgInfoGetInfo] = DefaultTrueBoolStr;
  end;
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.lstPropertiesEditButtonClick(Sender: TObject);
var
  s: string;
  i: Integer;
begin
  i := lstProperties.Row - 1;
  if i in [msgInfoComments, msgInfoLicense] then
  begin
    s := InsertLineBreaks(lstProperties.Strings.ValueFromIndex[i]);
    if MemoWin.Execute(Messages.Strings[i], s) then
      if s = '' then
        lstProperties.Strings[i] := lstProperties.Strings.Names[i] + '='
      else
        lstProperties.Strings.ValueFromIndex[i] := ReplaceLineBreaks(s);
  end;
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.Translate;
var
  i: Integer;
begin
  inherited;
  with lstProperties do
  begin
    for i := msgInfoAuthors to msgInfoGetInfo do
      ItemProps[i].KeyDesc := Messages.Strings[i];
    ItemProps[msgInfoComments].EditStyle := esEllipsis;
    ItemProps[msgInfoLicense].EditStyle := esEllipsis;
    ItemProps[msgInfoGetInfo].EditStyle := esPickList;
    with ItemProps[msgInfoGetInfo].PickList do
    begin
      Add(DefaultTrueBoolStr);
      Add(DefaultFalseBoolStr);
    end;
  end;
  lstValues.Cells[0, 0] := Messages.Strings[msgOptionValue];
  lstValues.Cells[1, 0] := Messages.Strings[msgOptionDescr];
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.lstOptionsClick(Sender: TObject);
var
  i, idx, len: Integer;
  CurOption: TScriptOption;
begin
  lstValues.RowCount := 2;
  lstValues.Cells[0, 1] := '';
  lstValues.Cells[1, 1] := '';
  cbxValueDefault.Items.Clear;
  idx := lstOptions.ItemIndex;
  if idx = -1 then
  begin
    lstValues.Enabled := False;
    lblValueDefault.Enabled := False;
    cbxValueDefault.Enabled := False;
  end
  else
  begin
    lstValues.Enabled := True;
    lblValueDefault.Enabled := True;
    cbxValueDefault.Enabled := True;
    CurOption := lstOptions.Items.Objects[idx] as TScriptOption;
    len := Length(CurOption.Values);
    if len > 0 then
    begin
      lstValues.RowCount := len + 2;
      for i := 0 to len-1 do
      begin
        lstValues.Cells[0, i + 1] := IntToStr(CurOption.Values[i].Value);
        lstValues.Cells[1, i + 1] := CurOption.Values[i].Description;
      end;
      lstValues.Cells[0, len + 1] := '';
      lstValues.Cells[1, len + 1] := '';
      with cbxValueDefault.Items do
      begin
        Assign(lstValues.Cols[0]);
        Delete(Count-1);
        Delete(0);
        cbxValueDefault.ItemIndex := IndexOf(IntToStr(CurOption.DefValue));
      end;
    end;
  end;
  FormResize(Self);
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.lstValuesSetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String);
var
  i, last: Integer;
  defVal: string;
  CurOption: TScriptOption;
begin
  i := cbxValueDefault.ItemIndex;
  if i <> -1 then
    defVal := cbxValueDefault.Items[i]
  else
    defVal := '';
  last := lstValues.RowCount-1;
  if (lstValues.Cells[0, last] <> '') or (lstValues.Cells[1, last] <> '') then
  begin
    lstValues.RowCount := last + 2;
    lstValues.Cells[0, last + 1] := '';
    lstValues.Cells[1, last + 1] := '';
  end
  else
    while (last > 1) and (lstValues.Cells[0, last-1] = '') and (lstValues.Cells[1, last-1] = '') do
    begin
      lstValues.RowCount := last;
      Dec(last);
    end;
  with cbxValueDefault.Items do
  begin
    Assign(lstValues.Cols[0]);
    Delete(Count-1);
    Delete(0);
    cbxValueDefault.ItemIndex := IndexOf(defVal);
  end;
  CurOption := lstOptions.Items.Objects[lstOptions.ItemIndex] as TScriptOption;
  SetLength(CurOption.Values, lstValues.RowCount - 2);
  for i := 1 to lstValues.RowCount - 2 do
  begin
    CurOption.Values[i - 1].Value := StrToIntDef(lstValues.Cells[0, i], 0);
    CurOption.Values[i - 1].Description := lstValues.Cells[1, i];
  end;
  FormResize(Self);
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.cbxValueDefaultChange(Sender: TObject);
var
  idxO, idxV: Integer;
begin
  idxO := lstOptions.ItemIndex;
  idxV := cbxValueDefault.ItemIndex;
  if (idxO <> -1) and (idxV <> -1) then
    with lstOptions.Items.Objects[idxO] as TScriptOption do
    begin
      DefValue := StrToIntDef(cbxValueDefault.Items[idxV], 0);
      Value := DefValue;
    end;
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.FormResize(Sender: TObject);
begin
  inherited;
  lstValues.HandleNeeded;
  lstValues.ColWidths[1] := lstValues.ClientWidth - lstValues.ColWidths[0] - 2;
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.btnOptionAddClick(Sender: TObject);
var
  idx: Integer;
  NewOpt: TScriptOption;
  OptName: string;
begin
  OptName := '';
  if InputWin.Execute(GetLongHint(btnOptionAdd.Hint), Messages.Strings[msgOptionName], OptName) then
  begin
    OptName := RemoveLettersNotInList(Trim(OptName), ['A'..'Z', 'a'..'z', '0'..'9', '_']);
    idx := lstOptions.Items.IndexOf(OptName);
    if idx <> -1 then
    begin
      lstOptions.ItemIndex := idx;
      lstOptionsClick(lstOptions);
      Exit;
    end;
    NewOpt := FScript.Options.Add;
    NewOpt.Name := OptName;
    idx := lstOptions.Items.AddObject(OptName, NewOpt);
    lstOptions.ItemIndex := idx;
    lstOptionsClick(lstOptions);
  end;
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.btnOptionDelClick(Sender: TObject);
var
  idx: Integer;
  optIdx: Integer;
begin
  idx := lstOptions.ItemIndex;
  if idx = -1 then
    Exit;
  optIdx := FScript.Options.IndexOf(lstOptions.Items.Objects[idx]);
  if MessageWin.Execute(Format(Messages.Strings[msgOptionDelete], [lstOptions.Items[idx]]), mtWarning, [mbOk, mbCancel]) = 1 then
  begin
    if optIdx <> -1 then
      FScript.Options.Delete(optIdx);
    lstOptions.DeleteSelected;
    lstOptions.ItemIndex := Min(idx, lstOptions.Items.Count-1);
  end;
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.LoadOptions;
begin
  with Settings.rScripts.rProperties do
  begin
    Self.Width := WindowWidth;
    Self.Height := WindowHeight;
  end;
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.SaveOptions;
begin
  with Settings.rScripts.rProperties do
  begin
    WindowWidth := Self.Width;
    WindowHeight := Self.Height;
  end;
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

procedure TScriptPropertiesWin.btn1Click(Sender: TObject);
begin
  LaunchHelp;
end;

{-------------------------------------------------------------------------------
-------------------------------------------------------------------------------}

end.

