(************************************************************************
 *                                                                      *
 *   Ant Movie Catalog 4.x                                              *
 *   (C) 2000-2011 Antoine Potten, Mickaël Vanneufville                 *
 *   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 customfieldsmanager;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, Buttons, shellAPI, ComCtrls,

  ConstValues, AntCorelButton, AntJvExControls, AntJvToolEdit, AntAutoHintLabel,

  base, movieclass, AntStringList;

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

type
  TCustomFieldsManagerWin = class(TBaseDlg)
    LName: TLabel;
    EName: TEdit;
    EListValues: TMemo;
    LListValues: TLabel;
    EField: TComboBox;
    LField: TLabel;
    EType: TComboBox;
    LType: TLabel;
    Bevel2: TBevel;
    LDefaultValue: TLabel;
    LMultiValues: TLabel;
    EMultiValues: TCheckBox;
    btnDel: TButton;
    EDefaultValue: TEdit;
    ETag: TEdit;
    LTag: TLabel;
    Messages: TAntStringList;
    btnImport: TCorelButton;
    btnExport: TCorelButton;
    btnClearAll: TCorelButton;
    btnApply: TCorelButton;
    procedure btnApplyClick(Sender: TObject);
    procedure btnDelClick(Sender: TObject);
    procedure btn2Click(Sender: TObject);
    procedure ETagChange(Sender: TObject);
    procedure EFieldChange(Sender: TObject);
    procedure ENameChange(Sender: TObject);
    procedure ETypeChange(Sender: TObject);
    procedure EDefaultValueChange(Sender: TObject);
    procedure EMultiValuesClick(Sender: TObject);
    procedure EListValuesChange(Sender: TObject);
    procedure btnClearAllClick(Sender: TObject);
    procedure btnImportClick(Sender: TObject);
    procedure btnExportClick(Sender: TObject);
  private
  protected
    MsgImport: string;
    MsgExport: string;
    PropertiesCopy: TCustomFieldsProperties;
    Selected: TCustomFieldProperties;
    procedure LoadOptions; override;
    procedure SaveOptions; override;
    procedure RefreshFieldList;
    procedure LoadSelectedField;
  public
    Properties: TCustomFieldsProperties;
    function Execute(CustomFieldsProperties: TCustomFieldsProperties;
      ImportMessage, ExportMessage: String;
      SelectedCustomField: TCustomFieldProperties = nil): Boolean;
  end;

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

var
  CustomFieldsManagerWin: TCustomFieldsManagerWin;

implementation

uses
  Global, ProgramSettings;

const
  // Messages
  msgNewField         = 0;
  msgTypeString       = 1;
  msgTypeInteger      = 2;
  msgTypeReal         = 3;
  msgTypeBoolean      = 4;
  msgTypeList         = 5;
  msgTypeDate         = 6;
  msgTypeText         = 7;
  msgTypeUrl          = 8;
  TypeIndex : array[0..7] of TFieldType = (ftString, ftInteger, ftReal, ftBoolean, ftList, ftDate, ftText, ftUrl);

{$R *.DFM}

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

procedure TCustomFieldsManagerWin.LoadOptions;
var
  i: Integer;
begin
  with Settings do
  begin
    with rCustomFieldsManager do
    begin
      Self.Width := WindowWidth;
      Self.Height := WindowHeight;
    end; // with rCustomFieldsManager
  end; // with settings
  PropertiesCopy := TCustomFieldsProperties.Create;
  EType.Items.Clear;
  for i:=0 to Length(TypeIndex)-1 do
  begin
    EType.Items.Add(Messages.Strings[i + 1]);
  end;
end;

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

procedure TCustomFieldsManagerWin.SaveOptions;
begin
  with Settings do
  begin
    with rCustomFieldsManager do
    begin
      WindowWidth := Self.Width;
      WindowHeight := Self.Height;
    end; // with rCustomFieldsManager
  end; // with settings
  PropertiesCopy.Free;
end;

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

function TCustomFieldsManagerWin.Execute(CustomFieldsProperties: TCustomFieldsProperties;
  ImportMessage, ExportMessage: String;
  SelectedCustomField: TCustomFieldProperties): Boolean;
var
  i: Integer;
begin
  Properties := CustomFieldsProperties;
  PropertiesCopy.Assign(Properties);
  MsgImport := ImportMessage;
  MsgExport := ExportMessage;
  Selected := nil;
  i := Properties.IndexOfObject(SelectedCustomField);
  if (SelectedCustomField <> nil) and (i <> -1) then
    Selected := PropertiesCopy.Objects[i];
  RefreshFieldList;
  LoadSelectedField;

  Result := ShowModal = mrOk;
end;

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

procedure TCustomFieldsManagerWin.RefreshFieldList;
var
  i: Integer;
begin
  EField.OnChange := nil;
  EField.Items.Clear;
  EField.Items.Add(Messages.Strings[msgNewField]);
  EField.ItemIndex := 0;
  for i:=0 to PropertiesCopy.Count-1 do
  begin
    EField.Items.Add(PropertiesCopy.Objects[i].FieldName + ' (' + PropertiesCopy.Strings[i] + ')');
    if Selected = PropertiesCopy.Objects[i] then
      EField.ItemIndex := i+1;
  end;
  if EField.ItemIndex <= 0 then
    Selected := nil;
  EField.OnChange := EFieldChange;
end;

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

procedure TCustomFieldsManagerWin.LoadSelectedField;
var
  i: Integer;
begin
  if Selected = nil then
  begin
    btnDel.Enabled := False;
    btnApply.Enabled := False;
    LName.Enabled := False;
    EName.Enabled := False;
    LType.Enabled := False;
    EType.Enabled := False;
    LDefaultValue.Enabled := False;
    EDefaultValue.Enabled := False;
    LMultiValues.Enabled := False;
    EMultiValues.Enabled := False;
    LListValues.Enabled := False;
    EListValues.Enabled := False;

    ETag.Text := '';
    EName.Text := '';
    EType.ItemIndex := 0;
    EDefaultValue.Text := '';
    EMultiValues.Checked := False;
    EListValues.Text := '';
  end
  else
  begin
    btnDel.Enabled := True;
    btnApply.Enabled := False;
    LName.Enabled := True;
    EName.Enabled := True;
    LType.Enabled := True;
    EType.Enabled := True;
    LDefaultValue.Enabled := True;
    EDefaultValue.Enabled := True;
    LMultiValues.Enabled := (Selected.FieldType = ftString) or (Selected.FieldType = ftList) or (Selected.FieldType = ftText);
    EMultiValues.Enabled := LMultiValues.Enabled;
    LListValues.Enabled := Selected.FieldType = ftList;
    EListValues.Enabled := Selected.FieldType = ftList;
    EListValues.Text := '';

    ETag.Text := Selected.FieldTag;
    EName.Text := Selected.FieldName;

    EType.ItemIndex := 0;
    for i:=0 to Length(TypeIndex)-1 do
      if Selected.FieldType = TypeIndex[i] then
        EType.ItemIndex := i;
    EDefaultValue.Text := ConvertFieldValue(Selected.DefaultValue, Selected.FieldType, True, True, False);
    if LMultiValues.Enabled then
      EMultiValues.Checked := Selected.MultiValues
    else
      EMultiValues.Checked := False;
    EListValues.Text := Selected.ListValues.Text;
  end;
end;

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

procedure TCustomFieldsManagerWin.btnApplyClick(Sender: TObject);
begin
  inherited;
  if (Selected = nil) then
    Selected := PropertiesCopy.AddField(ETag.Text, True) // True = SpecialAdd
  else
    PropertiesCopy.ChangeFieldTag(Selected.FieldTag, ETag.Text);
  RefreshFieldList;
  LoadSelectedField;
end;

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

procedure TCustomFieldsManagerWin.btnDelClick(Sender: TObject);
begin
  inherited;
  if (Selected <> nil) then
  begin
    PropertiesCopy.DeleteField(Selected.FieldTag);
    RefreshFieldList;
    LoadSelectedField;
  end;
end;

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

procedure TCustomFieldsManagerWin.btn2Click(Sender: TObject);
begin
  inherited;
  Properties.Assign(PropertiesCopy);
  Properties.CheckFieldsTag;
  Properties.CheckFieldsValue;
end;

procedure TCustomFieldsManagerWin.ETagChange(Sender: TObject);
var
  s: string;
begin
  inherited;
  s := ETag.Text;
  if ((Selected <> nil) and (s = Selected.FieldTag)) or (not IsValidTag(s)) then
  begin
    btnApply.Enabled := False;
    Exit;
  end;

  if (PropertiesCopy.IndexOf(s) <> -1) and
    ((Selected = nil) or (UpperCase(s) <> UpperCase(Selected.FieldTag))) then
  begin
    btnApply.Enabled := False;
    Exit;
  end;

  btnApply.Enabled := True;
end;

procedure TCustomFieldsManagerWin.EFieldChange(Sender: TObject);
begin
  inherited;
  if EField.ItemIndex = 0 then
    Selected := nil
  else
    Selected := PropertiesCopy.Objects[EField.ItemIndex-1];
  LoadSelectedField;
end;

procedure TCustomFieldsManagerWin.ENameChange(Sender: TObject);
var
  i: Integer;
begin
  inherited;
  if (Selected <> nil) then
  begin
    Selected.FieldName := EName.Text;
    EField.OnChange := nil;
    i := EField.ItemIndex;
    EField.Items.Delete(i);
    EField.Items.Insert(i, Selected.FieldName + ' (' + Selected.FieldTag + ')');
    EField.ItemIndex := i;
    EField.OnChange := EFieldChange;
  end;
end;

procedure TCustomFieldsManagerWin.ETypeChange(Sender: TObject);
begin
  inherited;
  if (Selected <> nil) and (EType.ItemIndex >= 0) then
  begin
    if PropertiesCopy.ChangeFieldType(Selected.FieldTag, TypeIndex[EType.ItemIndex]) then
    begin
      LListValues.Enabled := Selected.FieldType = ftList;
      EListValues.Enabled := Selected.FieldType = ftList;
      EListValues.Text := Selected.ListValues.Text;
      EDefaultValue.Text := ConvertFieldValue(Selected.DefaultValue, Selected.FieldType, True, True, False);
      LMultiValues.Enabled := (Selected.FieldType = ftString) or (Selected.FieldType = ftList) or (Selected.FieldType = ftText);
      EMultiValues.Enabled := LMultiValues.Enabled;
      if not LMultiValues.Enabled then
        EMultiValues.Checked := False;
    end;
  end;
end;

procedure TCustomFieldsManagerWin.EDefaultValueChange(Sender: TObject);
begin
  inherited;
  if (Selected <> nil) then
    Selected.DefaultValue := EDefaultValue.Text;
end;

procedure TCustomFieldsManagerWin.EMultiValuesClick(Sender: TObject);
begin
  inherited;
  if (Selected <> nil) then
    Selected.MultiValues := EMultiValues.Checked;
end;

procedure TCustomFieldsManagerWin.EListValuesChange(Sender: TObject);
begin
  inherited;
  if (Selected <> nil) then
    Selected.ListValues.Text := EListValues.Text;
end;

procedure TCustomFieldsManagerWin.btnClearAllClick(Sender: TObject);
begin
  inherited;
  PropertiesCopy.Clear;
  RefreshFieldList;
  LoadSelectedField;
end;

procedure TCustomFieldsManagerWin.btnImportClick(Sender: TObject);
begin
inherited;
  with TOpenDialog.Create(Self) do
  try
    InitialDir := Settings.rOptions.rFolders[fuCustomFields].Value;
    Options := DialogOpenOptions;
    Title := MsgImport;
    Filter := DialogXmlFilter;
    FileName := '';
    if Execute then
    begin
      Settings.rOptions.rFolders[fuCustomFields].Value := ExtractFilePath(FileName);
      PropertiesCopy.ImportFromXML(FileName);
      RefreshFieldList;
      LoadSelectedField;
    end;
  finally
    Free;
  end;
end;

procedure TCustomFieldsManagerWin.btnExportClick(Sender: TObject);
begin
  inherited;
  with TSaveDialog.Create(Self) do
  try
    InitialDir := Settings.rOptions.rFolders[fuCustomFields].Value;
    Options := DialogSaveOptions;
    Title := MsgExport;
    Filter := DialogXmlFilter;
    FileName := 'CustomFields';
    DefaultExt := 'xml';
    if Execute then
    begin
      Settings.rOptions.rFolders[fuCustomFields].Value := ExtractFilePath(FileName);
      PropertiesCopy.ExportToXML(FileName);
    end;
  finally
    Free;
  end;
end;

end.
