unit MdlForm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons, ExtCtrls, FileCtrl, ComCtrls, Registry, Printers, Menus,
  MyUtils, MyDates, Arrays,
  LBRMTypes, LBRMGlob, LBRMRead, LBRMThread;

type
  TMForm2 = class(TForm)
    Panel1: TPanel;
    Label1: TLabel;
    EBConfigFile: TEdit;
    BtnConfigLoad: TButton;
    BtnConfigSave: TButton;
    BtnConfigSaveAs: TButton;
    StartButton: TBitBtn;
    BtnClearLog: TButton;
    BtnSaveLog: TButton;
    BtnPrintLog: TButton;
    EBHidden: TEdit;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    PrintDialog1: TPrintDialog;
    Memo1: TMemo;
    Label_MetFile: TLabel;
    EBMetFile: TEdit;
    BtnMetFile: TButton;
    Label_OutFile: TLabel;
    EBOutputFile: TEdit;
    BtnOutFile: TButton;
    Label_Bound: TLabel;
    EBBoundaryFile: TEdit;
    BtnBoundaryFile: TButton;
    EBParmFile: TEdit;
    BtnParmFile: TButton;
    LabelParmFile: TLabel;
    GroupBox1: TGroupBox;
    Label_SD: TLabel;
    Label_ED: TLabel;
    BtnAdjustDate: TButton;
    DTPStart: TDateTimePicker;
    DTPEnd: TDateTimePicker;
    MainMenu1: TMainMenu;
    MainFile: TMenuItem;
    FileOpen: TMenuItem;
    FileClear: TMenuItem;
    N1: TMenuItem;
    FileExit: TMenuItem;
    MainHelp: TMenuItem;
    HelpAbout: TMenuItem;
    procedure BtnFileClick(Sender: TObject);
    procedure EBFileNameChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure EBFileBoxEnter(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
    procedure FormResize(Sender: TObject);
    procedure EBConfigFileExit(Sender: TObject);
    procedure EBFileBoxKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure EBFileBoxOldExit(Sender: TObject);
    procedure BtnConfigLoadClick(Sender: TObject);
    procedure BtnConfigSaveClick(Sender: TObject);
    procedure BtnConfigSaveAsClick(Sender: TObject);
    procedure StartButtonClick(Sender: TObject);
    procedure BtnClearLogClick(Sender: TObject);
    procedure BtnSaveLogClick(Sender: TObject);
    procedure BtnPrintLogClick(Sender: TObject);
    procedure EBHiddenChange(Sender: TObject);
    procedure BtnAdjustDateClick(Sender: TObject);
    procedure DTPStartChange(Sender: TObject);
    procedure DTPEndChange(Sender: TObject);
    procedure FileClearClick(Sender: TObject);
    procedure FileExitClick(Sender: TObject);
    procedure HelpAboutClick(Sender: TObject);

  private

    DS, BC           : longint;
    MetStart, MetEnd : longint;

    FormIsBeingCreated : boolean;
    FormIsBeingClosed  : boolean;
    UserPressedStop    : boolean;
    SavingPriorToLoad  : boolean;
    CfgInfoIsDirty     : boolean;
    ParmInfoIsDirty    : boolean;
    BoundaryDataIsGood : boolean;
    LastWasBeforeFirst : boolean;
    OkToWriteOutput    : boolean;

    BoxPrevValue  : string;

    RunThread : TLBRMThread;
    MyReg     : TRegistry;

    ConfigInfo   : TConfigInfo;
    MetData      : TMetData;
    BoundaryInfo : TBoundaryInfo;
    ParmInfo     : TParameterInfo;


    procedure LoadNewConfigFile;
    procedure LoadNewMetFile;
    procedure LoadNewBoundFile;
    procedure LoadNewParmFile;
    procedure FillFileNameBoxes;
    procedure GetFormDates(var SSeq, ESeq : longint);
    procedure UpdateDateBoxes(Start, Last : longint; ForceMax : boolean);
    procedure CfgVisualToCfgInternal;
    procedure CheckStartDates;
    procedure DisableControlsWhileRunning;
    procedure EnableControlsAfterRunning;

    procedure RunTheLBRM;
    procedure StopTheLBRM;
    procedure LBRMThreadDone(Sender : TObject);
    procedure ChangeViaWin(s: string);

    function  CreateLBRMCfgFile : boolean;
    function  PromptForDirtyFileSave(EditBox : TEdit) : word;
    function  SaveOldFile(EB : TEdit) : boolean;
    function  FindMaxDateRange(var Start, Last : longint) : boolean;

  public
    { Public declarations }
  end;

var
  MForm2: TMForm2;

implementation

uses MdlAbtBox;

{$R *.DFM}
{$R Bitmaps.RES}

//--------------------------------------------
procedure TMForm2.FormCreate(Sender: TObject);
var
  I     : integer;
  Flag1 : boolean;
  S     : string;
begin
   FormIsBeingCreated := TRUE;
   FormIsBeingClosed  := FALSE;
   UserPressedStop    := FALSE;
   SavingPriorToLoad  := FALSE;

   // Default and/or starting values for some global control variables
   CfgInfoIsDirty    := FALSE;
   ParmInfoIsDirty   := FALSE;

   //
   // Set up the glyph (picture) for the start button
   //
   StartButton.Glyph.LoadFromResourceName(HInstance,'GOBTN');
   StartButton.Caption := 'Start';

   BoundaryInfo := TBoundaryInfo.Create;
   MetData[1] := TMyArrayOfInt.Create;
   MetData[2] := TMyArrayOfInt.Create;
   MetData[3] := TMyArrayOfInt.Create;

   //
   //  Get entries from the Windows registry, if possible.
   //
   MyReg := TRegistry.Create;
   try
     MyReg.RootKey := HKEY_CURRENT_USER;
     Flag1 := MyReg.OpenKey('\Software\GLERL\WinModel', True);
     if (Flag1) then begin
        try
          I := MyReg.ReadInteger('WinTop');
          Top := I;
          I := MyReg.ReadInteger('WinLeft');
          Left := I;
          I := MyReg.ReadInteger('WinWidth');
          Width := I;
          I := MyReg.ReadInteger('WinHeight');
          Height := I;
        except
          Top := 100;
          Left := 150;
          Width := 450;
          Height := 535;
        end;

        //
        // File names
        //
        S := MyReg.ReadString('FileParm');
        if (not FileExists(S)) then S := '';
        EBParmFile.Text := S;

        S := MyReg.ReadString('FileBound');
        if (not FileExists(S)) then S := '';
        EBBoundaryFile.Text := S;

        S := MyReg.ReadString('FileMet');
        if (not FileExists(S)) then S := '';
        EBMetFile.Text := S;

        S := MyReg.ReadString('FileOutput');
        EBOutputFile.Text := S;

        //
        // Configuration file name
        //
        S := MyReg.ReadString('FileConfig');
        if (not FileExists(S)) then S := '';
        EBConfigFile.Text := S;
        if (FileExists(S)) then begin
           LoadNewConfigFile;
        end;
     end;
   finally
     MyReg.CloseKey;
     MyReg.Free;
   end;

   ActiveControl := StartButton;
   CfgVisualToCfgInternal;
   FormIsBeingCreated := FALSE;
end;

//---------------------------------------------------------------------------
procedure TMForm2.FormResize(Sender: TObject);
begin
   Memo1.Height := ClientHeight - 455;
end;

//--------------------------------------------
procedure TMForm2.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
   Answer : word;
begin
   FormIsBeingClosed := TRUE;
   ActiveControl := Memo1;
   CanClose := TRUE;        // default value

   if (ParmInfoIsDirty) then begin
      Answer := PromptForDirtyFileSave(EBParmFile);  // ask (and save if they say yes)
      if (Answer = mrYes) then CanClose := TRUE;
      if (Answer = mrNo) then begin
         CanClose := TRUE;
         ParmInfoIsDirty := FALSE;
      end;
      if (Answer = mrCancel) then begin
         CanClose := FALSE;
         FormIsBeingClosed := FALSE;
         exit;
      end;
      if (ParmInfoIsDirty) then begin   // if attempt to save failed
         CanClose := FALSE;
         FormIsBeingClosed := FALSE;
         exit;
      end;
   end;

   if (CfgInfoIsDirty) then begin
      Answer := PromptForDirtyFileSave(EBConfigFile);  // ask (and save if they say yes)
      if (Answer = mrYes) then CanClose := TRUE;
      if (Answer = mrNo) then begin
         CanClose := TRUE;
         CfgInfoIsDirty := FALSE;
      end;
      if (Answer = mrCancel) then begin
         CanClose := FALSE;
         FormIsBeingClosed := FALSE;
         exit;
      end;
      if (CfgInfoIsDirty) then begin   // if attempt to save failed
         CanClose := FALSE;
         FormIsBeingClosed := FALSE;
         exit;
      end;
   end;
end;

//--------------------------------------------
procedure TMForm2.FormClose(Sender: TObject; var Action: TCloseAction);
var
   Flag1  : boolean;
begin
   BoundaryInfo.Free;
   MetData[1].Free;
   MetData[2].Free;
   MetData[3].Free;
   MyReg := TRegistry.Create;
   try
     MyReg.RootKey := HKEY_CURRENT_USER;
     Flag1 := MyReg.OpenKey('\Software\GLERL\WinModel', TRUE);
     if (Flag1) then begin
        MyReg.WriteInteger('WinTop',     Top);
        MyReg.WriteInteger('WinLeft',    Left);
        MyReg.WriteInteger('WinWidth',   Width);
        MyReg.WriteInteger('WinHeight',  Height);
        MyReg.WriteString ('FileConfig', EBConfigFile.Text);
        MyReg.WriteString ('FileMet',    EBMetFile.Text);
        MyReg.WriteString ('FileBound',  EBBoundaryFile.Text);
        MyReg.WriteString ('FileParm',   EBParmFile.Text);
        MyReg.WriteString ('FileOutput', EBOutputFile.Text);
     end;
   finally
     MyReg.CloseKey;
     MyReg.Free;
   end;
end;

//--------------------------------------------
procedure TMForm2.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
   Screen.Cursor := crDefault;
   //
   // If the process is currently running then change cursor shape
   // if the mouse is over Panel1.
   //
   if (CompareText(StartButton.Caption, 'Stop') = 0) then begin
       if (Y < Panel1.Height) then Screen.Cursor := crNo;
   end;
end;

//--------------------------------------------
procedure TMForm2.BtnFileClick(Sender: TObject);
var
    AppDir, CfgDir, S : string;
    FName, DlgTitle   : string;
    EditBox  : TEdit;
    TheBtn   : TButton;
    LoadProc : procedure of object;
begin
    //
    // Default values
    //
    AppDir  := '';
    CfgDir  := '';
    AppDir := ExtractFilePath(Application.ExeName);
    S := AppDir;
    CfgDir := ExtractFilePath(EBConfigFile.Text);
    if (DirectoryExists(CfgDir))  then S := CfgDir;

    TheBtn := Sender as TButton;

    EditBox  := nil;
    DlgTitle := 'INVALID';
    FName    := '';
    LoadProc := nil;
    
    if (TheBtn = BtnMetFile) then begin
        EditBox  := EBMetFile;
        DlgTitle := 'Choose Input Met Data File';
        FName    := 'MetFile.Dat';
        LoadProc := LoadNewMetFile;
    end;
    if (TheBtn = BtnBoundaryFile) then begin
        EditBox  := EBBoundaryFile;
        DlgTitle := 'Choose Input Boundary Conditions File';
        FName    := 'Boundary.Dat';
        LoadProc := LoadNewBoundFile;
    end;
    if (TheBtn = BtnParmFile) then begin
        EditBox  := EBParmFile;
        DlgTitle := 'Choose Input Parameter File';
        FName    := 'Parameter.Dat';
        LoadProc := LoadNewParmFile;
    end;
    if (TheBtn = BtnOutFile) then begin
        EditBox  := EBOutputFile;
        DlgTitle := 'Choose Output File Name';
        FName    := 'Output.Dat';
        LoadProc := nil;
    end;
    if (CompareText(DlgTitle, 'INVALID') = 0) then exit;

    OpenDialog1.Title      := DlgTitle;
    OpenDialog1.FileName   := FName;
    OpenDialog1.InitialDir := S;

    //
    // Is existing file named o.k.?  If so use it as a default value
    //
    FName := EditBox.Text;
    S     := StripTrailingSlash(ExtractFilePath(EditBox.Text));
    if (DirectoryExists(S)) then begin
       OpenDialog1.FileName := FName;
       OpenDialog1.InitialDir := ExtractFilePath(FName);
    end;

    //
    if (OpenDialog1.Execute) then begin
       EditBox.Text := OpenDialog1.FileName;
       if (TheBtn <> BtnOutFile) then LoadProc;
    end;
end;

//--------------------------------------------
procedure TMForm2.EBFileNameChange(Sender: TObject);
begin
  if (not FormIsBeingCreated) then CfgInfoIsDirty := TRUE;
end;

//--------------------------------------------
procedure TMForm2.EBFileBoxEnter(Sender: TObject);
var
   TEB : TEdit;
begin
   TEB := Sender as TEdit;
   if (TEB = EBConfigFile)   then  BoxPrevValue := EBConfigFile.Text;
   if (TEB = EBMetFile)      then  BoxPrevValue := EBMetFile.Text;
   if (TEB = EBBoundaryFile) then  BoxPrevValue := EBBoundaryFile.Text;
   if (TEB = EBParmFile)     then  BoxPrevValue := EBParmFile.Text;
   if (TEB = EBOutputFile)   then  BoxPrevValue := EBOutputFile.Text;
end;

//--------------------------------------------
procedure TMForm2.EBFileBoxKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
   TEB : TEdit;
begin
   TEB := Sender as TEdit;
   if (Key = VK_ESCAPE) then TEB.Text := BoxPrevValue;
   if (Key = VK_RETURN) then begin
      if (TEB = EBConfigFile)   then ActiveControl := BtnConfigLoad;
      if (TEB = EBMetFile)      then ActiveControl := BtnMetFile;
      if (TEB = EBBoundaryFile) then ActiveControl := BtnBoundaryFile;
      if (TEB = EBParmFile)     then ActiveControl := BtnParmFile;
      if (TEB = EBOutputFile)   then ActiveControl := BtnOutFile;
   end;
end;

//--------------------------------------------
procedure TMForm2.EBConfigFileExit(Sender: TObject);
var
   X, Y      : integer;
   FName, S  : string;
   Answer    : word;
begin
   FName := TRIM(EBConfigFile.Text);
   if (Length(FName) = 0) then exit;
   if (CompareText(BoxPrevValue, FName) = 0) then exit;
   if (CfgInfoIsDirty) then begin
      Answer := PromptForDirtyFileSave(EBConfigFile);
      if ((Answer = mrCancel) OR (Answer = mrAbort)) then exit;
   end;
   if (FileExists(FName)) then
      LoadNewConfigFile
   else begin
      S := 'The specified configuration file does not exist!';
      X := Left + 50;
      Y := Top + 150;
      MessageDlgPos(S, mtError, [mbOk], 0, X, Y);
      EBConfigFile.Text := BoxPrevValue;
   end;
end;

//--------------------------------------------
procedure TMForm2.EBFileBoxOldExit(Sender: TObject);
var
   X, Y       : integer;
   FName      : string;
   EMsg, S    : string;
   EditBox    : TEdit;
begin
   X := Left + 50;
   Y := Top + 150;
   EditBox := Sender as TEdit;

   FName := TRIM(EditBox.Text);
   if (CompareText(BoxPrevValue, FName) = 0) then exit;

   if (Length(FName) = 0) then exit;

   if (EditBox = EBOutputFile)   then exit;
   if (EditBox = EBMetFile)      then EMsg := 'met data file';
   if (EditBox = EBBoundaryFile) then EMsg := 'boundary conditions file';
   if (EditBox = EBParmFile)     then EMsg := 'parameter file';

   if (not FileExists(FName)) then begin
      S := 'The specified ' + EMsg + ' does not exist!';
      MessageDlgPos(S, mtError, [mbOk], 0, X, Y);
      EditBox.Text := BoxPrevValue;
      exit;
   end;

   if (EditBox = EBMetFile)      then LoadNewMetFile;
   if (EditBox = EBBoundaryFile) then LoadNewBoundFile;
   if (EditBox = EBParmFile)     then LoadNewParmFile;
end;

//--------------------------------------------
procedure TMForm2.BtnConfigLoadClick(Sender: TObject);
var
   X, Y        : integer;
   FName       : string;
   Answer      : word;
begin
   FName := EBConfigFile.Text;
   if (CfgInfoIsDirty) then begin
      Answer := PromptForDirtyFileSave(EBConfigFile);
      if ((Answer = mrCancel) OR (Answer = mrAbort)) then exit;
   end;

   //
   //  Initial values for dialog caption and filename
   //
   OpenDialog1.Title := 'Load New Configuration File';
   OpenDialog1.FileName := 'LBRM.CFG';
   OpenDialog1.InitialDir := ExtractFilePath(Application.ExeName);
   if (FileExists(EBBoundaryFile.Text)) then
      OpenDialog1.InitialDir := ExtractFilePath(EBBoundaryFile.Text);
   if (FileExists(EBMetFile.Text)) then
      OpenDialog1.InitialDir := ExtractFilePath(EBMetFile.Text);
   if (FileExists(EBParmFile.Text)) then
      OpenDialog1.InitialDir := ExtractFilePath(EBParmFile.Text);

   FName := EBConfigFile.Text;
   if (FileExists(FName)) then begin
      OpenDialog1.FileName   := FName;
      OpenDialog1.InitialDir := ExtractFilePath(FName);
   end;

   if (OpenDialog1.Execute) then begin
      FName := OpenDialog1.FileName;
      if (not FileExists(FName)) then begin
         X := Left + 50;
         Y := Top + 150;
         MessageDlgPos('The specified configuration file does not exist!',
                        mtError, [mbOk], 0, X, Y);
         exit;
      end;
      EBConfigFile.Text := FName;
      LoadNewConfigFile;
   end;
end;

//--------------------------------------------
procedure TMForm2.BtnConfigSaveClick(Sender: TObject);
var
   FName : string;
begin
   FName := EBConfigFile.Text;
   if (Length(Trim(FName)) = 0) then begin    // file name is empty
      SaveOldFile(EBConfigFile);
      exit;
   end;
   CfgVisualToCfgInternal;
   WriteConfigFile(FName, ConfigInfo);
   CfgInfoIsDirty := FALSE;
end;

//--------------------------------------------
procedure TMForm2.BtnConfigSaveAsClick(Sender: TObject);
begin
    SaveOldFile(EBConfigFile);      // In this procedure we don't care if it worked
end;

//-------------------------------------------------------------------
function TMForm2.SaveOldFile(EB : TEdit) : boolean;
var
   SSeq, ESeq  : longint;
   FName, Dir  : string;
   DialogTitle : string;
begin
    DialogTitle  := '';
    Result       := FALSE;

    GetDir(0, Dir);

    if (EB = EBConfigFile) then begin
       CfgVisualToCfgInternal;
       DialogTitle := 'Save Configuration File As:';
    end;

    if (EB = EBParmFile) then begin
       GetFormDates(SSeq, ESeq);
       ParmInfo.SDate := SSeq;
       ParmInfo.CDate := SSeq;
       ParmInfo.EDate := ESeq;
       DialogTitle := 'Save Parameter File As:';
    end;

    //
    // Default values
    //
    SaveDialog1.Title      := DialogTitle;
    SaveDialog1.InitialDir := ExtractFilePath(EB.Text);
    SaveDialog1.FileName   := ExtractFileName(EB.Text);

    //
    if (SaveDialog1.Execute) then begin
       FName := SaveDialog1.FileName;
       EB.Text := FName;
       if (EB = EBConfigFile) then begin
          Result := WriteConfigFile(FName, ConfigInfo);
          if (Result) then CfgInfoIsDirty := FALSE;
       end;
       if (EB = EBParmFile) then begin
          Result := WriteParmFile(FName, ParmInfo);
          if (Result) then ParmInfoIsDirty := FALSE;
       end;
    end;
    chdir(Dir);
end;


//--------------------------------------------
procedure TMForm2.BtnClearLogClick(Sender: TObject);
begin
   Memo1.Lines.Clear;
end;

//--------------------------------------------
procedure TMForm2.BtnSaveLogClick(Sender: TObject);
var
   I : integer;
   FName, S : string;
   F : TextFile;
begin
   //
   // Default values
   //
   SaveDialog1.Title := 'Save Log File As:';
   SaveDialog1.FileName := 'CalibLog.txt';
   SaveDialog1.InitialDir := ExtractFilePath(EBConfigFile.Text);

   //
   if (SaveDialog1.Execute) then begin
      FName := SaveDialog1.FileName;
      AssignFile(F, FName);
      ReWrite(F);
      for I:=0 to Memo1.Lines.Count-1 do begin
         S := Memo1.Lines[I];
         writeln(F, S);
      end;
      CloseFile(F);
   end;
end;

//--------------------------------------------
procedure TMForm2.BtnPrintLogClick(Sender: TObject);
var
   I, J, X, Y, Y2 : integer;
   S  : string;
begin
   PrintDialog1.Execute;
   Printer.BeginDoc;

   with Printer.Canvas.Font do begin
      Name := 'Arial';
      Size := 8;
   end;

   J := 0;
   for I:=0 to Memo1.Lines.Count-1 do begin
      S := Memo1.Lines[I];
      inc(J);
      X := 10;
      Y := 10 + J * Printer.Canvas.TextHeight(S);     // top of text
      Y2 := Y + Printer.Canvas.TextHeight(S);         // bottom of text
      if (Y2 > Printer.PageHeight-10) then begin
         Printer.NewPage;
         J := 1;
         Y := 10 + J * Printer.Canvas.TextHeight(S);     // top of text
      end;
      Printer.Canvas.TextOut(X, Y, S);
   end;

   Printer.EndDoc;
end;

//--------------------------------------------------------------------------
procedure TMForm2.CfgVisualToCfgInternal;
begin
   ConfigInfo.ParmFile  := EBParmFile.Text;
   ConfigInfo.BoundFile := EBBoundaryFile.Text;
   ConfigInfo.MetFile   := EBMetFile.Text;
   ConfigInfo.LBRMFile  := EBOutputFile.Text;
end;

//-------------------------------------------------------------------
function TMForm2.PromptForDirtyFileSave(EditBox : TEdit) : word;
var
   X, Y       : integer;
   Answer     : word;
   DialogText : string;
   DTextPart2 : string;
begin
   if (EditBox = EBConfigFile)   then DialogText := 'configuration';
   if (EditBox = EBBoundaryFile) then DialogText := 'boundary';
   if (EditBox = EBParmFile)     then DialogText := 'parameter';

   if (FormIsBeingClosed) then
      DTextPart2 := 'closing the application?'
   else
      DTextPart2 := 'loading a new file?';

   X := Left + 50;
   Y := Top + 150;
   Answer := MessageDlgPos('You have not saved the updated ' + DialogText +
                           ' file information.' + #13#10 +
                           'Do you want to do so before ' + DTextPart2,
                           mtConfirmation, [mbYes, mbNo, mbCancel], 0, X, Y);
   Result := Answer;
   if ((Answer = mrNo) OR (Answer = mrCancel)) then exit;
   if (Answer = mrYes) then begin
      if (not SaveOldFile(EditBox)) then Result := mrAbort;
      exit;
   end;
end;

//---------------------------------------------------------------------------
procedure TMForm2.LoadNewConfigFile;
var
   FName  : string;
begin
   FName := EBConfigFile.Text;
   if (not FileExists(FName)) then begin
      if (not FormIsBeingCreated) then
         ChangeViaWin('~!~WARNING!!! Specified configuration file does not exist!');
      exit;
   end;
   if (ReadConfigFile(FName, ConfigInfo)) then FillFileNameBoxes;
   CfgInfoIsDirty := FALSE;
end;

//---------------------------------------------------------------------------
procedure TMForm2.LoadNewMetFile;
var
   SSeq, ESeq : longint;
   FName      : string;
begin
   DateSequence(31, 12, 9999, MetStart);
   DateSequence( 1,  1,    1, MetEnd);
   FName := EBMetFile.Text;
   if (not FileExists(FName)) then begin
      if (not FormIsBeingCreated) then
         ChangeViaWin('~!~WARNING!!! Specified met data file does not exist!');
      exit;
   end;
   if (not GetMetStartEnd(FName, SSeq, ESeq)) then exit;
   MetStart := SSeq;
   MetEnd   := ESeq;

   //
   // There is no need to read the met data file here.  All we needed to do
   // is check for its existence.
   //
//   if (not ReadMetFile(FName, MetStart, MetEnd, MetData)) then begin
//      if (not FormIsBeingCreated) then
//         ChangeViaWin('~!~' + ReadDataErrMessage);
//      exit;
//   end;

end;

//---------------------------------------------------------------------------
procedure TMForm2.LoadNewBoundFile;
var
   FName, S  : string;
   FIBC_Save : boolean;
begin
   FName := EBBoundaryFile.Text;
   S := ExtractFilePath(FName);
   if (Length(S) = 0) then begin
      FIBC_Save := FormIsBeingCreated;
      FormIsBeingCreated := TRUE;
      EBBoundaryFile.Text := FName;
      FormIsBeingCreated := FIBC_Save;
   end;

   if (not FileExists(FName)) then begin
      ChangeViaWin('~!~WARNING!!! Specified boundary conditions file does not exist!');
      exit;
   end;
   if (ReadBoundaryFile(FName, BoundaryInfo)) then begin
      BoundaryDataIsGood := TRUE;
   end;
   CfgInfoIsDirty := TRUE;
end;

//---------------------------------------------------------------------------
procedure TMForm2.LoadNewParmFile;
var
   Start, Last   : integer;
   FName, S      : string;
   FIBC_Save     : boolean;
begin
   FName := EBParmFile.Text;

   S := ExtractFilePath(FName);
   if (Length(S) = 0) then begin
      FIBC_Save := FormIsBeingCreated;
      FormIsBeingCreated := TRUE;
      EBParmFile.Text    := FName;
      FormIsBeingCreated := FIBC_Save;
   end;

   if (not FileExists(FName)) then begin
      ChangeViaWin('~!~WARNING!!! Specified parameter file does not exist!');
      DateSequence(1, 1, 1900, Start);
      ParmInfo.SDate := Start;
      ParmInfo.EDate := Start;
      Last           := Start;
      UpdateDateBoxes(Start, Last, TRUE);
      exit;
   end;
   if (ReadParmFile(FName, ParmInfo)) then begin
      Start := ParmInfo.SDate;
      Last  := ParmInfo.EDate;
      UpdateDateBoxes(Start, Last, TRUE);
   end;

   CfgInfoIsDirty := TRUE;
end;

//--------------------------------------------------------------------------
procedure TMForm2.FillFileNameBoxes;
var
    X, Y            : integer;
    SomeWereBad     : boolean;
    S, S2, CfgPath  : string;
begin
    S := EBConfigFile.Text;
    if (Length(S) > 0) then CfgPath := ExtractFilePath(S);

    EBMetFile.Text      := '';
    EBBoundaryFile.Text := '';
    EBParmFile.Text     := '';
    EBOutputFile.Text   := '';

    SomeWereBad := FALSE;

    S := ConfigInfo.MetFile;
    S2 := ExtractFilePath(S);
    if ((Length(S2) < 1) AND (Length(S) > 0)) then S := CfgPath + S;
    if ((Length(S) > 0) AND (FileExists(S))) then
        begin
        EBMetFile.Text := S;
        ConfigInfo.MetFile := S;
        end
    else begin
        ConfigInfo.MetFile := '';
        SomeWereBad := TRUE;
    end;

    S := ConfigInfo.BoundFile;
    S2 := ExtractFilePath(S);
    if ((Length(S2) < 1) AND (Length(S) > 0)) then S := CfgPath + S;
    if ((Length(S) > 0) AND (FileExists(S))) then
        begin
        EBBoundaryFile.Text := S;
        ConfigInfo.BoundFile := S;
        end
    else begin
        ConfigInfo.BoundFile := '';
        SomeWereBad := TRUE;
    end;

    S := ConfigInfo.ParmFile;
    S2 := ExtractFilePath(S);
    if ((Length(S2) < 1) AND (Length(S) > 0)) then S := CfgPath + S;
    if ((Length(S) > 0) AND (FileExists(S))) then
        begin
        EBParmFile.Text := S;
        ConfigInfo.ParmFile := S;
        end
    else begin
        ConfigInfo.ParmFile := '';
        SomeWereBad := TRUE;
    end;

    S := ConfigInfo.LBRMFile;
    S2 := ExtractFilePath(S);
    if ((Length(S2) < 1) AND (Length(S) > 0)) then S := CfgPath + S;
    if (Length(S) > 0) then
        begin
        EBOutputFile.Text := S;
        ConfigInfo.LBRMFile := S;
        end
    else begin
        ConfigInfo.LBRMFile := '';
    end;

    if (FileExists(ConfigInfo.BoundFile)) then LoadNewBoundFile;
    if (FileExists(ConfigInfo.ParmFile))  then LoadNewParmFile;

    if (SomeWereBad) then begin
      S := 'One or more of the files specified in the configuration' + #13#10 +
           'file do not exist.  Those fields are left blank.';
      X := Left + 50;
      Y := Top + 150;
      MessageDlgPos(S, mtCustom, [mbOk], 0, X, Y);
    end;
end;

//------------------------------------------------------------------------
function TMForm2.CreateLBRMCfgFile : boolean;
var
   FName : string;
   F     : TextFile;
begin
   Result := FALSE;   // default in case of early exit

   FName  := ExtractFilePath(EBOutputFile.Text) + 'LBRM.CFG';
   try
     AssignFile(F, FName);
   except
     ChangeViaWin('~!~Error writing LBRM configuration file');
     exit;
   end;

   try
     Rewrite(F);
     Writeln(F, 'PARMFILE=' + EBParmFile.Text);
     Writeln(F, 'BCFILE='   + EBBoundaryFile.Text);
     Writeln(F, 'METFILE='  + EBMetFile.Text);
     Writeln(F, 'OUTFILE='  + EBOutputFile.Text);
     CloseFile(F);
   except
     CloseFile(F);
     ChangeViaWin('~!~Error writing LBRM configuration file');
     exit;
   end;

   Result := TRUE;   // successful completion
end;

//--------------------------------------------------------------------------
procedure TMForm2.BtnAdjustDateClick(Sender: TObject);
var
   Start, Last : longint;
begin
   if (FindMaxDateRange(Start, Last)) then begin
       UpdateDateBoxes(Start, Last, TRUE);
       ParmInfoIsDirty := TRUE;
       GetFormDates(Start, Last);
       ParmInfo.SDate := Start;
       ParmInfo.CDate := Start;
       ParmInfo.EDate := Last;
       end
   else begin
       ChangeViaWin('Unable to determine maximum date range.');
       ChangeViaWin('One or more files were unreadable.');
   end;
   CheckStartDates;
end;

//--------------------------------------------------------------------------
function TMForm2.FindMaxDateRange(var Start, Last : longint) : boolean;
var
   MetS, MetE  : longint;       // sequence numbers
   FName : string;
begin
   Result := FALSE;  // default return value is that we failed to complete
   FName := EBMetFile.Text;
   if (not FileExists(FName)) then exit;

   //
   // Get allowable start/end date range for each input data file.
   // The end date is the earlier of the two files.
   //
   FName := EBMetFile.Text;
   if (not GetMetStartEnd(FName, MetS, MetE)) then exit;
   Start := MetS;
   Last  := MetE;
   Result := TRUE;    // completed successfully
end;


//--------------------------------------------------------------------------
procedure TMForm2.UpdateDateBoxes(Start, Last : longint;
                                  ForceMax    : boolean);
var
   X, Y : integer;
   FStart, FEnd, F1, F2 : longint;
   D1, M1, Y1 : word;
   D2, M2, Y2 : word;
   FormBlank : boolean;
begin
   //
   // Save the original values of First and Last just in
   // case we need them later.  Usually we won't.
   //
   F1 := Start;
   F2 := Last;

   FormBlank := FALSE;
   DecodeDate(DTPStart.Date, Y1, M1, D1);
   DecodeDate(DTPEnd.Date,   Y2, M2, D2);
   if ((Y1=1950) AND (M1=1) AND (D1=1)  AND
       (Y2=1950) AND (M2=1) AND (D2=1)) then FormBlank := TRUE;
   if (FormBlank) then ForceMax := TRUE;

   //
   // Get the current date entries from the form
   //
   if (not FormBlank) then GetFormDates(FStart, FEnd);

   //
   // If ForceMax is TRUE then set the form date variables to the passed-in values.
   //
   if (ForceMax) then begin
      FStart := Start;
      FEnd   := Last;
   end;

   //
   // Set the form variables to the period which is common (intersection)
   // between the form and the max values passed in.
   // Note that if ForceMax was TRUE then they are already set to the
   // same values so the common period will be the max range.
   //
   if (Start < FStart) then Start := FStart; // adjust "Start" to match edit box
   if (Last  > FEnd)   then Last  := FEnd;   // adjust "Last" to match edit box

   //
   // Make sure that the start date is on/before the end date.
   // If, for some weird reason it is not, then arbitrarily set the start/end
   // to the maximum range.
   // This is that rare occasion when we need the original values back
   // again, cuz we just changed them.
   //
   // As long as the form has already been created, tell the user you did it.
   // If the form is in the process of being created, however, the call to
   // MessageDlgPos will cause an access violation error, so save that for
   // the OnFormShow event.  *THEN* we will kick out the informative message.
   //
   LastWasBeforeFirst := FALSE;
   if (Start > Last) then begin
      Start := F1;
      Last := F2;
      if (FormIsBeingCreated) then
          LastWasBeforeFirst := TRUE
      else begin
         X := Left + 50;
         Y := Top + 150;
         MessageDlgPos('File dates did not intersect the start/end dates' +#13+#10+
                       ' that you specified.  Dates were set to the file maximums.',
                       mtInformation, [mbOk], 0, X, Y);
      end;
   end;

   //
   // Update the start/end date edit boxes with the allowable values
   // (or the existing values which have been assigned into the same variables)
   //
   DTPStart.Date := MyDateToDelphiDate(Start);
   DTPEnd.Date   := MyDateToDelphiDate(Last);

   CheckStartDates;
end;

//--------------------------------------------------------------------------
procedure TMForm2.GetFormDates(var SSeq, ESeq : longint);
begin
    try
      SSeq := DelphiDateToMyDate(DTPStart.Date);
      ESeq  := DelphiDateToMyDate(DTPEnd.Date);
    except
      SSeq := -999;
      ESeq := -999;
    end;
end;

//--------------------------------------------------------------------------
procedure TMForm2.CheckStartDates;
var
   X, Y       : integer;
   Seq1, Seq2 : longint;
   S : string;
begin
   Seq1 := DelphiDateToMyDate(DTPStart.Date);    // calibration start date
   Seq2 := DelphiDateToMyDate(DTPEnd.Date);    // calibration start date

   if (Seq2 < Seq1) then begin
      S := 'Start Date must be on or before the End Date!';
      X := Left + 50;
      Y := Top + 150;
      MessageDlgPos(S, mtError, [mbOk], 0, X, Y);
   end;
end;

//--------------------------------------------
procedure TMForm2.DTPStartChange(Sender: TObject);
var
   SSeq, ESeq : longint;
begin
   GetFormDates(SSeq, ESeq);
   ParmInfo.SDate := SSeq;
   ParmInfo.CDate := SSeq;
   ParmInfoIsDirty := TRUE;
end;

//--------------------------------------------
procedure TMForm2.DTPEndChange(Sender: TObject);
var
   SSeq, ESeq : longint;
begin
   GetFormDates(SSeq, ESeq);
   ParmInfo.EDate  := ESeq;
   ParmInfoIsDirty := TRUE;
end;

//--------------------------------------------
procedure TMForm2.DisableControlsWhileRunning;
begin
   MainFile.Enabled    := FALSE;
   Panel1.Enabled      := FALSE;
   BtnClearLog.Enabled := FALSE;
   BtnSaveLog.Enabled  := FALSE;
   BtnPrintLog.Enabled := FALSE;
end;

//--------------------------------------------
procedure TMForm2.EnableControlsAfterRunning;
begin
   MainFile.Enabled    := TRUE;
   Panel1.Enabled      := TRUE;
   BtnClearLog.Enabled := TRUE;
   BtnSaveLog.Enabled  := TRUE;
   BtnPrintLog.Enabled := TRUE;
end;


//--------------------------------------------
procedure TMForm2.StartButtonClick(Sender: TObject);
var
   I, Err, WH   : integer;
   FSD, FED     : longint;
   FName, Dir1, Dir2  : string;
begin
   //
   // If the user has already told the process to stop, but it hasn't
   // quite finished yet.
   //
   if (CompareText(StartButton.Caption, 'Stopping') = 0) then exit;

   //
   // If the process is currently running freely
   //
   if (CompareText(StartButton.Caption, 'Stop') = 0) then begin
      StartButton.Caption    := 'Stopping';
      StartButton.Enabled    := FALSE;     // don't allow it to be clicked again
      UserPressedStop        := TRUE;

      try
        RunThread.Terminate;
      except
        // Sometimes an "access violation" error is generated here, but it doesn't
        // seem to cause any damage.  I don't know *why* it is generated.  But
        // if it happens we will just ignore it and continue.
      end;
      exit;
   end;

   //
   // If the process is waiting to be started
   //
   if (CompareText(StartButton.Caption, 'Start') = 0) then begin

      //
      // Make sure all the Dir/File page entries are filled in
      //
      FName := EBMetFile.Text;
      if (not FileExists(FName)) then begin
          MessageDlgPos('You must specify the met data file!', mtError,
                        [mbOk], 0, Top+100, Left+50);
          exit;
      end;

      FName := EBBoundaryFile.Text;
      if (not FileExists(FName)) then begin
          MessageDlgPos('You must specify the boundary conditions file!', mtError,
                        [mbOk], 0, Top+100, Left+50);
          exit;
      end;

      FName := EBParmFile.Text;
      if (not FileExists(FName)) then begin
          MessageDlgPos('You must specify the parameter file!', mtError,
                        [mbOk], 0, Top+100, Left+50);
          exit;
      end;

      FName := TRIM(EBOutputFile.Text);
      if (Length(FName) < 1) then begin
          MessageDlgPos('You must specify an output file!', mtError,
                        [mbOk], 0, Top+100, Left+50);
          exit;
      end;

      FName := TRIM(EBConfigFile.Text);
      if (Length(FName) < 1) then begin
          BtnConfigSaveAsClick(BtnConfigSaveAs);
          if (CfgInfoIsDirty) then exit;
      end;

      //
      // Write updated parameter file
      //
      GetFormDates(FSD, FED);
      ParmInfo.SDate := FSD;
      ParmInfo.CDate := FSD;
      ParmInfo.EDate := FED;
      FName := EBParmFile.Text;
      WriteParmFile(FName, ParmInfo);
      ParmInfoIsDirty := FALSE;

      //
      // Create the LBRM.CFG file for use by the next Fortran DLL procedures
      //
      if (not CreateLBRMCfgFile) then exit;

      DisableControlsWhileRunning;

      UserPressedStop     := FALSE;
      StartButton.Caption := 'Stop';
      StartButton.Glyph.LoadFromResourceName(HInstance, 'StopBtn');

      ChangeViaWin('-------------------------------------');

      //
      // Find array dimensions
      //    DS = Days_of_Simulation      i.e. days to run LBRM
      //    BC = Boundary_Condition_count
      //
      DS := FED - FSD + 1;
      if not (GetBoundCount(EBBoundaryFile.Text, FSD, FED, BC)) then begin
          ChangeViaWin('Error reading boundary conditions file. Aborting!');
          StopTheLBRM;
          exit;
      end;
      GetDir(0, Dir1);
      try
        Dir2 := ExtractFilePath(EBConfigFile.Text);
        chdir(Dir2);
        LBRM_ArraySizes(Err, WH, BC, DS);
      except
        ChangeViaWin('Error reading LBRM array sizes.');
        StopTheLBRM;
        exit;
      end;
      chdir(Dir1);

      //
      // Set the array sizes (i.e. allocate the RAM)
      //
      GetMem(iBCD,    BC*sizeof(longint));
      GetMem(AUpper,  BC*sizeof(single));
      GetMem(ALower,  BC*sizeof(single));
      GetMem(AGround, BC*sizeof(single));
      GetMem(ASurf,   BC*sizeof(single));
      GetMem(ASnow,   BC*sizeof(single));

      GetMem(Tmx, DS*sizeof(smallint));
      GetMem(Tmn, DS*sizeof(smallint));
      GetMem(Prc, DS*sizeof(smallint));

      GetMem(ORun, DS*sizeof(single));
      GetMem(OUsz, DS*sizeof(single));
      GetMem(OLsz, DS*sizeof(single));
      GetMem(OGzm, DS*sizeof(single));
      GetMem(OSs,  DS*sizeof(single));
      GetMem(OSnw, DS*sizeof(single));

      //
      // Assign the values of BC and DS to the "global" variables in
      // unit LBRMGlob so that the LBRM thread can access them.
      //
      LBRMGlob.BC := BC;
      LBRMGlob.DS := DS;

      GetDir(0, Dir1);
      try
        Dir2 := ExtractFilePath(EBConfigFile.Text);
        chdir(Dir2);
        I := EBHidden.Handle;
        LBRM_ReadData(Err, I, BC, DS, iBCD^, AUpper^, ALower^,
                      AGround^, ASurf^, ASnow^, Tmx^, TMn^, Prc^);
        if (Err <> 0) then begin
           StopTheLBRM;
           exit;
        end;
      except
        ChangeViaWin('Error reading LBRM input data.');
        StopTheLBRM;
        exit;
      end;
      chdir(Dir1);

      RunTheLBRM;
   end;
end;


//-------------------------------------------------------------------------
procedure TMForm2.RunTheLBRM;
begin
   RunThread := TLBRMThread.Create;
   RunThread.EditBoxHndl  := EBHidden.Handle;
   RunThread.KCons        := ParmInfo.KCons;
   RunThread.CfgFileName  := EBConfigFile.Text;
   RunThread.ParmFileName := EBParmFile.Text;
   RunThread.BCFileName   := EBBoundaryFile.Text;
   RunThread.MetFileName  := EBMetFile.Text;
   RunThread.OutFileName  := EBOutputFile.Text;
   RunThread.OnTerminate  := LBRMThreadDone;  // set the termination routine
   RunThread.Resume;                          // start the Execute method
end;

//-------------------------------------------------------------------------
procedure TMForm2.LBRMThreadDone(Sender : TObject);
var
   RS : longint;
begin
   RS := RunThread.ReturnStatus;
   Application.ProcessMessages;
   ParmInfo.KCons := RunThread.KCons;
   RunThread := nil;

   OkToWriteOutput := TRUE;
   if (RS <> 0) then begin
       OkToWriteOutput := FALSE;
       if (RS =  1) then ChangeViaWin('LBRM terminated prematurely.');
       if (RS = -2) then ChangeViaWin('Error in results from LBRM.');
       if (RS = -9) then ChangeViaWin('LBRM caused an exception.');
       StopTheLBRM;
       exit;
   end;

   StopTheLBRM;
end;


//--------------------------------------------------------------------------
procedure TMForm2.StopTheLBRM;
var
   Err, WH : integer;
begin
    //
    // Write the output file
    //
    if (OkToWriteOutput) then begin
       WH := EBHidden.Handle;
       LBRM_WriteData(Err, WH, DS, ORun^, OUsz^, OLsz^, OGzm^, OSs^, OSnw^);
    end;

    //
    // Free the allocated RAM
    //
    FreeMem(iBCD);
    FreeMem(AUpper);
    FreeMem(ALower);
    FreeMem(AGround);
    FreeMem(ASurf);
    FreeMem(ASnow);

    FreeMem(Tmx);
    FreeMem(Tmn);
    FreeMem(Prc);

    FreeMem(ORun);
    FreeMem(OUsz);
    FreeMem(OLsz);
    FreeMem(OGzm);
    FreeMem(OSs);
    FreeMem(OSnw);

    //
    Screen.Cursor := crDefault;

    EnableControlsAfterRunning;

    StartButton.Glyph.LoadFromResourceName(HInstance, 'GoBtn');
    StartButton.Caption    := 'Start';
    StartButton.Enabled    := TRUE;

    ChangeViaWin('LBRM is finished');
end;

//--------------------------------------------
procedure TMForm2.EBHiddenChange(Sender: TObject);
var
    X, Y : integer;
    S_All, S_4n, SC1, SC2, SC3, LText  : string;
    ProcessSpecial, Special1, Special3 : boolean;
begin
  try
    Application.ProcessMessages;
    S_All  := EBHidden.Text;              // characters 1-n
    S_4n := Copy(EBHidden.Text, 4, 999);  // characters 4-n
    SC1 := Copy(EBHidden.Text, 1, 1);     // character 1 only
    SC2 := Copy(EBHidden.Text, 2, 1);     // the special prefix char (?)
    SC3 := Copy(EBHidden.Text, 3, 1);     // character 3 only
    LText := '';                          // text to write to log file

    //
    // Test for special characters as first and third characters of the string.
    // If they are both tildes, then test character 2.  If it IS one of the
    // special characters then process the data accordingly and set the flag.
    //
    ProcessSpecial := FALSE;
    Special1 := FALSE;
    Special3 := FALSE;
    if (CompareText(SC1, '~') = 0) then Special1 := TRUE;
    if (CompareText(SC3, '~') = 0) then Special3 := TRUE;
    if (Special1 AND Special3) then begin
       ProcessSpecial := TRUE;

       // I've defined "^" to mean that the rest of the text should
       // over-write the current last line.  This is used to simulate the
       // behavior we had in the DOS-based program where we wrote the
       // current status (percent complete, date, etc) over and over on
       // the same line without scrolling.
       if (CompareText(SC2, '^') = 0) then begin
          Memo1.Lines[Memo1.Lines.Count-1] := S_4n;
       end;

       // I've defined "&" to mean that the rest of the text should be
       // written to the log file, but not to the screen.  Useful for
       // debugging info and other summary stuff.
       if (CompareText(SC2, '&') = 0) then begin
          LText := S_4n;
       end;

       // I've defined "*" to mean that the rest of the text should be
       // written to the screen, but not to the log file.  Useful for
       // on-screen progress info and other multiple-write stuff.
       if (CompareText(SC2, '*') = 0) then begin
          LText := '';
       end;

       // I've defined "!" to mean that the rest of the text is an error
       // message which will be displayed modally in a dialog box.
       if (CompareText(SC2, '!') = 0) then begin
          X := Left + 50;
          Y := Top + 150;
          MessageDlgPos(S_4n, mtError, [mbOk], 0, X, Y);
          LText := '';
       end;

       // I've defined "T" to mean that the rest of the text is a
       // new caption ("Title") for the interface.
       if (CompareText(SC2, 'T') = 0) then begin
          Application.MainForm.Caption := S_4n;
          LText := '';
       end;
    end;

    //
    // "Normal" text without special meaning is echoed to both the screen
    // and the log file.
    //
    if (not ProcessSpecial) then begin
       Memo1.Lines.add(S_All);
       LText := S_All;
    end;

    Application.ProcessMessages;

  except
    ShowMessage('Exception in EBHidden.text update');
  end;
end;

//---------------------------------------------------------------------------
//  Changes the value of the EBHidden.text object via Windows messaging
//  facility.  This ensures that the object is accessed only 1 way at a time.
//  Previously, this program could try to change the value directly while
//  the object was already in a state of being changed via a windows message.
//  This could potentially cause access violation problems.
//
procedure TMForm2.ChangeViaWin(s: string);
var
   P : pChar;
begin
 try
   P := PChar(S);       // convert to PChar for Win API call
   SetWindowTextA(EBHidden.handle, P);
   Application.ProcessMessages;
  except
    ShowMessage('Exception in ChangeViaWin');
  end;
end;

//--------------------------------------------
procedure TMForm2.FileClearClick(Sender: TObject);
var
   FIBC_Save : boolean;
begin
   FIBC_Save := FormIsBeingCreated;
   FormIsBeingCreated := TRUE;

   EBConfigFile.Text   := '';
   EBMetFile.Text      := '';
   EBBoundaryFile.Text := '';
   EBParmFile.Text     := '';
   EBOutputFile.Text   := '';
   DTPStart.Date  := StrToDate('1/1/1950');
   DTPEnd.Date    := StrToDate('1/1/1950');
   BtnClearLogClick(BtnClearLog);

   ClearConfigInfo(ConfigInfo);
   CfgInfoIsDirty := FALSE;
   ClearParmInfo(ParmInfo);
   ParmInfoIsDirty := FALSE;
   BoundaryInfo.Clear;

   BoxPrevValue := '';

   FormIsBeingCreated := FIBC_Save;
end;

//--------------------------------------------
procedure TMForm2.FileExitClick(Sender: TObject);
begin
   Close;
end;

//--------------------------------------------
procedure TMForm2.HelpAboutClick(Sender: TObject);
begin
   MdlAboutBox.ShowModal;
end;

end.
