unit Unit1;

{$MODE Delphi}

interface

uses
  LCLIntf, LCLType, LMessages, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, CheckLst, FileUtil, Math;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button6: TButton;
    OpenDialog1: TOpenDialog;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Edit1: TEdit;
    Button2: TButton;
    OpenDialog2: TOpenDialog;
    Label2: TLabel;
    Edit2: TEdit;
    Button3: TButton;
    SaveDialog1: TSaveDialog;
    GroupBox2: TGroupBox;
    CheckBox1: TCheckBox;
    Label3: TLabel;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    ComboBox1: TComboBox;
    Label4: TLabel;
    CheckBox4: TCheckBox;
    CheckBox5: TCheckBox;
    Button1: TButton;
    Button4: TButton;
    Button5: TButton;
    BitBtn1: TBitBtn;
    ComboBox2: TComboBox;
    Label5: TLabel;
    Memo1: TMemo;
    Label6: TLabel;
    CheckBox7: TCheckBox;
    CheckBox8: TCheckBox;
    CheckListBox1: TCheckListBox;
    Label7: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure ComboBox1Click(Sender: TObject);
    procedure ComboBox2Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure CheckBox7Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses erg_base, erg_code, erg_color, erg_vector, erg_types, fortwrap, erg_pseudo3d, Unix2Dos;

{$R *.lfm}

var
  MaxFileAge: Integer;

procedure TForm1.Button1Click(Sender: TObject);
var s: String;
    err: Integer;
    i, j, k: Integer;
    havingModelInfo: Boolean;
    sl: TStringList;
begin
  s:=ExtractFilePath(OpenDialog1.FileName);
  if sender=ComboBox1 then
    havingModelInfo:=FileExistsUTF8(s+'modelinfos.txt') { *Converted from FileExists*  }
  else
    havingModelInfo:=OpenDialog1.Execute;

  if havingModelInfo then
  begin
    Label6.Caption:='loading txt files...';
    Label6.Repaint;

    s:=ExtractFilePath(OpenDialog1.FileName);

    setLength(limitations,0);

    MaxFileAge:=max(FileAge(s+'/modelinfos.txt'),max(FileAge(s+'/constants.txt'),
                            max(FileAge(s+'/tracers.txt'),max(FileAge(s+'/auxiliaries.txt'),
                            max(FileAge(s+'/processes.txt'),max(FileAge(s+'/elements.txt'),
                            FileAge(s+'/celements.txt')))))));

    err:=LoadModelInfos(s+'/modelinfos.txt');
    if err=1 then MessageDlg('Could not load modelinfos file.',mtError,[mbOk],0)
    else if err=2 then MessageDlg('Some lines of the modelinfos file contained errors.',mtWarning,[mbOk],0);

    err:=LoadConstants(s+'/constants.txt');
    if err=1 then MessageDlg('Could not load constants file.',mtError,[mbOk],0)
    else if err=2 then MessageDlg('Some lines of the constants file contained errors.',mtWarning,[mbOk],0);

    err:=LoadElements(s+'/elements.txt');
    if err=1 then MessageDlg('Could not load elements file.',mtError,[mbOk],0)
    else if err=2 then MessageDlg('Some lines of the elements file contained errors.',mtWarning,[mbOk],0);

    err:=LoadTracers(s+'/tracers.txt');
    if err=1 then MessageDlg('Could not load tracers file.',mtError,[mbOk],0)
    else if err=2 then MessageDlg('Some lines of the tracers file contained errors.',mtWarning,[mbOk],0);

    err:=LoadAuxiliaries(s+'/auxiliaries.txt');
    if err=1 then MessageDlg('Could not load auxiliaries file.',mtError,[mbOk],0)
    else if err=2 then MessageDlg('Some lines of the auxiliaries file contained errors.',mtWarning,[mbOk],0);

    err:=LoadProcesses(s+'/processes.txt');
    if err=1 then MessageDlg('Could not load processes file.',mtError,[mbOk],0)
    else if err=2 then MessageDlg('Some lines of the processes file contained errors.',mtWarning,[mbOk],0)
    else if err=3 then MessageDlg('The processes file contained an invalid equation.',mtWarning,[mbOk],0)
    else if err=4 then MessageDlg('The processes file contained an invalid limitation.',mtWarning,[mbOk],0);

    err:=LoadCElements(s+'/celements.txt');
    if err=1 then MessageDlg('Could not load celements file.',mtError,[mbOk],0)
    else if err=2 then MessageDlg('Some lines of the celements file contained errors.',mtWarning,[mbOk],0);

    GroupBox1.visible:=true;
    GroupBox2.visible:=true;
    BitBtn1.Enabled:=true;
    ComboBox2.Enabled:=true;

    //apply settings of modelinfos.txt
    if sender <> ComboBox1 then
    begin
      Edit1.Text:=modelinfos.templatePath;
      Edit2.Text:=modelinfos.outputPath;
      if modelinfos.autoSplitColors=1 then checkbox4.Checked:=true else CheckBox4.Checked:=false;
      if modelinfos.autoLimitProcesses=1 then checkbox8.Checked:=true else Checkbox8.Checked:=false;
      ComboBox1.ItemIndex:=modelinfos.autoMassClassProp;
      if modelinfos.debugMode=1 then checkbox5.Checked:=true else Checkbox5.Checked:=false;
      if modelinfos.autoWrapF=1 then checkbox2.Checked:=true else Checkbox2.Checked:=false;
      if modelinfos.autoWrapF90=1 then checkbox3.Checked:=true else Checkbox3.Checked:=false;
      if modelinfos.autoUnixOutput=1 then checkbox1.Checked:=true else Checkbox1.Checked:=false;
    end;

    s:=GenerateIndexes;
    if s<>'' then
      MessageDlg(s,mtError,[mbOk],0);

    ComboBox2.Items.Clear;
    for i:=0 to length(elements)-1 do
      ComboBox2.Items.Add(elements[i].description);

    Label6.Caption:='performing vector splitting...';
    Label6.Repaint;

    if ComboBox1.ItemIndex=0 then
      SplitVectorTracers(false,false)
    else if ComboBox1.ItemIndex=1 then
      SplitVectorTracers(true,false)
    else if ComboBox1.ItemIndex=2 then
      SplitVectorTracers(true,true);

    Label6.Caption:='generating list of process types...';
    Label6.Repaint;

    sl:=TStringList.Create;
    GetProcessTypes(sl);
    CheckListBox1.Items.Clear;
    for i:=0 to sl.Count-1 do
    begin
      CheckListBox1.Items.Add(copy(sl[i],2,length(sl[i])));
      if copy(sl[i],1,1)='1' then CheckListBox1.Checked[i]:=true else CheckListBox1.Checked[i]:=false;
    end;
    sl.Free;

    Label6.Caption:='idle.';
    Label6.Repaint;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  OpenDialog2.InitialDir:=Edit1.Text;
  If OpenDialog2.Execute then
  begin
    Edit1.Text:=ExtractFilePath(OpenDialog2.FileName);
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  SaveDialog1.InitialDir:=Edit2.Text;
  If SaveDialog1.Execute then
  begin
    Edit2.Text:=ExtractFilePath(SaveDialog1.FileName);
  end;
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
  ShowMessage('CGT - Code Generation Tool for ecosystem models'+chr(13)+
              'Copyright (C) 2013 Hagen Radtke (hagen.radtke@io-warnemuende.de)'+chr(13)+chr(13)+
              'This program was developed at Leibniz Institute for Baltic Sea Research Warnemuende.'+chr(13)+
              'Source code can be downloaded from http://www.ergom.net'+chr(13)+chr(13)+
              'This program is free software: you can redistribute it and/or modify'+chr(13)+
              'it under the terms of the GNU General Public License as published by'+chr(13)+
              'the Free Software Foundation, either version 3 of the License, or'+chr(13)+
              '(at your option) any later version.'+chr(13)+chr(13)+
              'This program is distributed in the hope that it will be useful,'+chr(13)+
              'but WITHOUT ANY WARRANTY; without even the implied warranty of'+chr(13)+
              'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the'+chr(13)+
              'GNU General Public License for more details.'+chr(13)+chr(13)+
              'You should have received a copy of the GNU General Public License'+chr(13)+
              'along with this program.  If not, see <http://www.gnu.org/licenses/>.');
end;

procedure TForm1.ComboBox1Click(Sender: TObject);
begin
  Button1Click(ComboBox1);
end;

procedure TForm1.ComboBox2Click(Sender: TObject);
var
  sources, sinks: TStringList;
begin
  Label6.Caption:='calculating sources and sinks...';
  Label6.Repaint;

  Sources:=TStringList.Create; Sinks:=TStringList.Create;
  FindSourcesSinks(ComboBox2.ItemIndex,Sources,Sinks,CheckBox7.Checked);
  Memo1.Lines.Clear;
  Memo1.Lines.Add('SOURCES:');
  Memo1.Lines.AddStrings(sources);
  Memo1.Lines.Add('');
  Memo1.Lines.Add('SINKS:');
  Memo1.Lines.AddStrings(sinks);

  Label6.Caption:='idle.';
  Label6.Repaint;
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  s: String;
begin
  s:=ExtractFilePath(OpenDialog1.FileName);
  if max(FileAge(s+'/modelinfos.txt'),max(FileAge(s+'/constants.txt'),
                            max(FileAge(s+'/tracers.txt'),max(FileAge(s+'/auxiliaries.txt'),
                            max(FileAge(s+'/processes.txt'),max(FileAge(s+'/elements.txt'),
                            FileAge(s+'/celements.txt'))))))) > MaxFileAge then
    if MessageDlg('Textfiles have changed on disk. Reload the files?',mtConfirmation,[mbYes,mbNo],0)=mrYes then
      Button1Click(ComboBox1);
  modelinfos.templatePath:=edit1.Text;
  modelinfos.outputPath:=edit2.Text;
  SaveModelInfos(OpenDialog1.FileName);
  MaxFileAge:=max(FileAge(s+'/modelinfos.txt'),max(FileAge(s+'/constants.txt'),
                            max(FileAge(s+'/tracers.txt'),max(FileAge(s+'/auxiliaries.txt'),
                            max(FileAge(s+'/processes.txt'),max(FileAge(s+'/elements.txt'),
                            FileAge(s+'/celements.txt')))))));
end;

procedure TForm1.Button5Click(Sender: TObject);
var
  i: Integer;
  s: String;
begin
  s:=ExtractFilePath(OpenDialog1.FileName);
  if max(FileAge(s+'/modelinfos.txt'),max(FileAge(s+'/constants.txt'),
                            max(FileAge(s+'/tracers.txt'),max(FileAge(s+'/auxiliaries.txt'),
                            max(FileAge(s+'/processes.txt'),max(FileAge(s+'/elements.txt'),
                            FileAge(s+'/celements.txt'))))))) > MaxFileAge then
    if MessageDlg('Textfiles have changed on disk. Reload the files?',mtConfirmation,[mbYes,mbNo],0)=mrYes then
      Button1Click(ComboBox1);
  if CheckBox4.Checked then modelinfos.autoSplitColors:=1 else modelinfos.autoSplitColors:=0;
  if CheckBox8.Checked then modelinfos.autoLimitProcesses:=1 else modelinfos.autoLimitProcesses:=0;
  modelinfos.autoMassClassProp:=ComboBox1.ItemIndex;
  if CheckBox5.Checked then modelinfos.debugMode:=1 else modelinfos.debugMode:=0;
  if CheckBox2.Checked then modelinfos.autoWrapF:=1 else modelinfos.autoWrapF:=0;
  if CheckBox3.Checked then modelinfos.autoWrapF90:=1 else modelinfos.autoWrapF90:=0;
  if CheckBox1.Checked then modelinfos.autoUnixOutput:=1 else modelinfos.autoUnixOutput:=0;
  modelinfos.inactiveProcessTypes:='';
  for i:=0 to CheckListBox1.Items.Count-1 do
    if CheckListBox1.Checked[i]=false then
    begin
      if modelinfos.inactiveProcessTypes='' then modelinfos.inactiveProcessTypes:=CheckListBox1.Items[i]
      else modelinfos.inactiveProcessTypes:='; '+CheckListBox1.Items[i];
    end;
  SaveModelInfos(OpenDialog1.FileName);
  MaxFileAge:=max(FileAge(s+'/modelinfos.txt'),max(FileAge(s+'/constants.txt'),
                            max(FileAge(s+'/tracers.txt'),max(FileAge(s+'/auxiliaries.txt'),
                            max(FileAge(s+'/processes.txt'),max(FileAge(s+'/elements.txt'),
                            FileAge(s+'/celements.txt')))))));

end;

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  doGenerate: Boolean;
  sr: tSearchRec;
  wrappedlines: Integer;
  oldModelinfo: TErgModelInfo;
  sl: TStringList;
  i: Integer;
  s: String;
begin
  s:=ExtractFilePath(OpenDialog1.FileName);
  if max(FileAge(s+'/modelinfos.txt'),max(FileAge(s+'/constants.txt'),
                            max(FileAge(s+'/tracers.txt'),max(FileAge(s+'/auxiliaries.txt'),
                            max(FileAge(s+'/processes.txt'),max(FileAge(s+'/elements.txt'),
                            FileAge(s+'/celements.txt'))))))) > MaxFileAge then
    if MessageDlg('Textfiles have changed on disk. Reload the files?',mtConfirmation,[mbYes,mbNo],0)=mrYes then
      Button1Click(ComboBox1);
  Label6.Caption:='checking paths...';
  Label6.Repaint;

  doGenerate:=true;
  if length(Edit1.Text)<2 then
    if MessageDlg('Are you sure that the code template path is really "'+Edit1.Text+'"?',mtConfirmation,[mbYes,mbNo],0) = mrNo then
      doGenerate:=false;
  if length(Edit2.Text)<2 then
    if MessageDlg('Are you sure that the code output path is really "'+Edit2.Text+'"?',mtConfirmation,[mbYes,mbNo],0) = mrNo then
      doGenerate:=false;
  if Edit1.Text = Edit2.Text then
  begin
    MessageDlg('Code template path and code output path must not be the same.',mtError,[mbOk],0);
    doGenerate:=false;
  end;

  if doGenerate then
  begin
    try

    Label6.Caption:='applying process limitations ...';
    Label6.Repaint;

    if CheckBox8.Checked then AutoLimitProcesses;

    ApplyLimitations;

    oldModelInfo:=ModelInfos;
    if checkbox5.Checked then modelinfos.debugMode:=1 else modelinfos.debugMode:=0;

    Label6.Caption:='treating isFlat=3 tracers and processes ...';
    Label6.Repaint;






    sl:=tStringList.Create;
    TreatPseudo3d(sl);
    if sl.Count>0 then
      ShowMessage('The following errors occurred with isFlat=3 tracers or processes:'+chr(13)+sl.Text)
    else



    begin
      sl.Clear;
      sl.Add(GenerateIndexes);
      if sl[0]<>'' then ShowMessage(sl[0]);

      cellheightTimesDensity:='(cgt_cellheight*cgt_density)';
      if CheckBox4.Checked then
      begin
        Label6.Caption:='color splitting tracers and processes...';
        Label6.Repaint;
        SplitColoredElements(true,CheckBox5.checked);
      end;

      sl.Clear;
      for i:=0 to CheckListBox1.Items.Count-1 do
        if CheckListBox1.Checked[i] then sl.Add('1'+CheckListBox1.Items[i])
                                    else sl.Add('0'+CheckListBox1.Items[i]);
      SetDisabledProcessesInactive(sl);
      sl.Free;

      if FindFirst(Edit1.Text+'*',$0000002F,sr)=0 then
      begin
        Memo1.Lines.Clear;
        Memo1.Repaint;
        repeat
          Label6.Caption:='generating code...';
          Label6.Repaint;
          if lowercase(ExtractFileExt(sr.Name))='.m' then
            erg_code.outputLanguage:='matlab'
          else
            erg_code.outputLanguage:='';
          generateCode(Edit1.Text+ExtractFileName(sr.Name),
                       Edit2.Text+ExtractFileName(sr.Name), CheckBox4.Checked);
          Memo1.Lines.Add('file '+ExtractFileName(sr.Name)+': '+'code generated.');
          if CheckBox2.Checked and (lowercase(ExtractFileExt(sr.Name))='.f') then
          begin
            Label6.Caption:='wrapping long lines...';
            Label6.Repaint;
            wrappedlines:= FortranWrap(Edit2.text+ExtractFileName(sr.Name));
            if wrappedlines>0 then Memo1.Lines.Add('file '+ExtractFileName(sr.Name)+': '+IntToStr(wrappedlines)+' lines wrapped.');
          end;
          if CheckBox3.Checked and (lowercase(ExtractFileExt(sr.Name))='.f90') then
          begin
            Label6.Caption:='wrapping long lines...';
            Label6.Repaint;
            wrappedlines:= Fortran90Wrap(Edit2.text+ExtractFileName(sr.Name));
            if wrappedlines>0 then Memo1.Lines.Add('file '+ExtractFileName(sr.Name)+': '+IntToStr(wrappedlines)+' lines wrapped.');
          end;
          if CheckBox1.Checked then
          begin
            Label6.Caption:='converting CR+LF to LF (DOS->UNIX)...';
            Label6.Repaint;
            ConvertDosToUnix(Edit2.text+ExtractFileName(sr.Name));
          end;
        until FindNext(sr) <> 0;
        findClose(sr);
      end;

    end;

    ModelInfos:=OldModelInfo;

    finally
      //reload the text files to undo the color splitting
      Button1Click(ComboBox1);
    end;
  end;

  Label6.Caption:='idle.';
  Label6.Repaint;
end;

procedure TForm1.CheckBox7Click(Sender: TObject);
begin
  ComboBox2Click(self);
end;

end.
