unit uOptions;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, ValEdit, INIFiles, StdCtrls, Buttons, FileCtrl;

type
  tOurEditStyle = ( oesSimple,                      // keyfield holds edit mask
                    oesPickList,                    // keyfield holds ';' delimited pick list entries
                    oesFilename,                    // keyfield holds extension mask
                    oesFolder                       // keyfield holds nothing
                    , oesSeparator                  // Separator
                    , oesLatLon                     // DMS DMS
  );
  tOurEditEntry = record
    Key: string;                   // the key (name)
    DefValue: string;              // the default value
    Hint: string;
    ValueType: tOurEditStyle;      // oesSimple, oesPickList ...
    KeyField: string;
    BackValue: string;             // backup value allows us to un-edit changes
  end;

  TfOptions = class(TForm)
    Optns: TValueListEditor;
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    Hint: TLabel;
    BitBtn3: TBitBtn;
    procedure OptnsGetPickList(Sender: TObject; const KeyName: String;
      Values: TStrings);
    procedure OptnsEditButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
    procedure FormConstrainedResize(Sender: TObject; var MinWidth,
      MinHeight, MaxWidth, MaxHeight: Integer);
    procedure OptnsSelectCell(Sender: TObject; ACol, ARow: Integer;
      var CanSelect: Boolean);
    procedure BitBtn3Click(Sender: TObject);
  private
    { Private declarations }
    A: array of tOurEditEntry;     // the master list of values
  public
    { Public declarations }
    procedure ClearEntries;
    procedure AddEntry( Key, DefValue: string;
                        ValueType: tOurEditStyle;
                        KeyField: string                   // ';' delimited list of piclist items
                        ; Hint: string
    );
    function _GetEntry( Key: string ): string;
    procedure SetEntry( Key, Value: string );
  end;

  function GetEntry( Key: string ): string;

var
  fOptions: TfOptions;

implementation

uses uUtility, uMonitors, uLatLonEntry;

{$R *.dfm}

function GetEntry( Key: string ): string;
begin
  if Assigned( fOptions ) then result := fOptions._GetEntry(Key);
end;


procedure TfOptions.ClearEntries;
begin
  SetLength( A, 0 );
  while Optns.RowCount > 2 do Optns.DeleteRow(1);
end;

procedure TfOptions.AddEntry( Key, DefValue: string;
                              ValueType: tOurEditStyle;
                              KeyField: string                   // ';' delimited list of piclist items
                              ; Hint: string
);
var
  H: integer;
  INIFile: tINIFile;
  Value: string;
begin
  // *** See if the INIFile contains a value
  INIFile := tINIFile.Create( ChangeFileExt( Application.EXEName, '.ini' ));
  try
    Value := INIFile.ReadString( 'OPTIONS', Key, DefValue );
  finally
    INIFile.Free;
  end;
  // Make a new entry for this item
  SetLength( A, High(A)+2 );
  H := High(A);
  A[H].Key       := Key;
  A[H].DefValue  := DefValue;
  A[H].ValueType := ValueType;
  A[H].KeyField  := KeyField;
  A[H].Hint      := Hint;
  Optns.InsertRow( Key, Value, TRUE );
  case ValueType of
    oesSimple:    Optns.ItemProps[ Key ].EditStyle := esSimple;
    oesPickList:  Optns.ItemProps[ Key ].EditStyle := esPickList;
    oesFilename:  Optns.ItemProps[ Key ].EditStyle := esEllipsis;
    oesFolder:    Optns.ItemProps[ Key ].EditStyle := esEllipsis;
    oesSeparator: Optns.ItemProps[ Key ].EditStyle := esEllipsis;
    oesLatLon:    Optns.ItemProps[ Key ].EditStyle := esEllipsis;
  end;

end;

function TfOptions._GetEntry( Key: string ): string;
// return the current value for Key
begin
  result := Optns.Values[ Key ];
end;

procedure TfOptions.SetEntry( Key, Value: string );
begin
  Optns.Values[Key] := Value;
end;

procedure TfOptions.OptnsGetPickList(Sender: TObject;
  const KeyName: String; Values: TStrings);
var
  i: integer;
  S,T: string;
begin
  // *** If the entry is a picklist then return the valid picklist entries in Values
  // Find the Keyname
  for i:=Low(A) to High(A) do
  begin
    if (A[i].Key = KeyName) then
    begin
      if A[i].ValueType = oesPickList then
      begin
        S := A[i].KeyField;
        while S <> '' do
        begin
          T := TokenParse(S,';');
          Values.Append(T);
        end;
      end;
      exit;
    end;
  end;
end;

procedure TfOptions.OptnsEditButtonClick(Sender: TObject);
var
  i: integer;
  S: string;
  SD: TSaveDialog;
begin
  i := Optns.Row - 1;
  if (i >= 0) AND (i <= High(A)) then
  begin
    case A[i].ValueType of
      oesSeparator:
                  begin
                    // Do nothing!
                  end;
      oesFolder:  begin
                    S := Optns.Values[ A[i].Key ];
                    if SelectDirectory( A[i].Key, '', S ) then
                    begin
                      S := AddBackSlash( S );
                      Optns.Values[ A[i].Key ] := S;
                    end;
                  end;
      oesFilename:    begin
                    S := Optns.Values[ A[i].Key ];
                    SD := TSaveDialog.Create( Self );
                    try
                      SD.DefaultExt := ExtractFileExt( S );
                      SD.Filename   := ExtractFilename( S );
                      SD.InitialDir := ExtractFilePath( S );
                      SD.Title      := A[i].Key;
                      SD.Filter     := A[i].KeyField;
                      if SD.Execute then Optns.Values[ A[i].Key ] := SD.Filename;
                    finally
                      SD.Free;
                    end;
                  end;
      oesLatLon:  begin
                    S := Optns.Values[ A[i].Key ];
                    if EditLatLonElv( A[i].Key, S ) = mrOK then
                      Optns.Values[ A[i].Key ] := S;
                  end;
    end;
  end;
end;

procedure TfOptions.FormCreate(Sender: TObject);
var
  INIFile: tINIFile;
begin
  // *** See if the INIFile contains a value
  INIFile := tINIFile.Create( ChangeFileExt( Application.EXEName, '.ini' ));
  try
    Height := INIFile.ReadInteger( 'OPTIONS_FORM', 'Height', Height );
    Width  := INIFile.ReadInteger( 'OPTIONS_FORM', 'Width',  Width );
    Top    := INIFile.ReadInteger( 'OPTIONS_FORM', 'Top',    Top );
    Left   := INIFile.ReadInteger( 'OPTIONS_FORM', 'Left',   Left );
  finally
    INIFile.Free;
  end;
  InsureOnScreen( Self );

end;

procedure TfOptions.FormDestroy(Sender: TObject);
var
  INIFile: tINIFile;
  i: integer;
begin
  // *** See if the INIFile contains a value
  INIFile := tINIFile.Create( ChangeFileExt( Application.EXEName, '.ini' ));
  try
    INIFile.WriteInteger( 'OPTIONS_FORM', 'Height', Height );
    INIFile.WriteInteger( 'OPTIONS_FORM', 'Width', Width );
    INIFile.WriteInteger( 'OPTIONS_FORM', 'Top', Top );
    INIFile.WriteInteger( 'OPTIONS_FORM', 'Left', Left );
    if Optns.Strings.Count >= 2 then
    begin
      for i := 1 to Optns.Strings.Count do
      begin
        INIFile.WriteString( 'OPTIONS', Optns.Keys[i], Optns.Values[Optns.Keys[i]] );
      end;
    end;
  finally
    INIFile.Free;
  end;

end;

procedure TfOptions.FormResize(Sender: TObject);
begin
  Optns.ColWidths[1] := ClientWidth - Optns.ColWidths[0] - 24;
end;

procedure TfOptions.FormShow(Sender: TObject);
var
  i: integer;
begin
  // Make a copy of all the values so we can replace if users cancels
  for i:= Low(A) to High(A) do A[i].BackValue := Optns.Values[ A[i].Key ];
end;

procedure TfOptions.BitBtn2Click(Sender: TObject);
// User cancels action, replace with old values
var
  i: integer;
begin
  // Make a copy of all the values so we can replace if users cancels
  for i:= Low(A) to High(A) do Optns.Values[ A[i].Key ] := A[i].BackValue;
  ModalResult := mrCancel;
end;

procedure TfOptions.FormConstrainedResize(Sender: TObject; var MinWidth,
  MinHeight, MaxWidth, MaxHeight: Integer);
begin
  MinHeight := 134;
  MinWidth  := 244;
end;

procedure TfOptions.OptnsSelectCell(Sender: TObject; ACol, ARow: Integer;
  var CanSelect: Boolean);
var
  i: integer;
begin
  // Show the hint
  i := ARow - 1;
  Hint.Caption := A[i].Key+': '+A[i].Hint;
end;

procedure TfOptions.BitBtn3Click(Sender: TObject);
var
  i: integer;
begin
  // Show the hint
  i := Optns.Row - 1;
  Optns.Values[ A[i].Key ] := A[i].DefValue;
end;


end.
