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;
    Button7: TButton;
    CheckBox6: TCheckBox;
    Edit3: TEdit;
    Label8: TLabel;
    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 Button7Click(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;
  ListOfPaths: TStringList;

//! Button Click on Object TForm1: TODO
{!
  \public
  \author Hagen Radtke, hagen.radtke@io-warnemuende.de

  TODO
  }
procedure TForm1.Button1Click(Sender: TObject);
var s: String;
    err: Integer;
    i, numAddOn: Integer;
    havingModelInfo: Boolean;
    sl: TStringList;
begin
  s:=ExtractFilePath(OpenDialog1.FileName);
  if sender=ComboBox1 then
  begin
    havingModelInfo:=assigned(ListOfPaths);
    if HavingModelInfo then
      for i:=0 to ListOfPaths.Count-1 do
        if not FileExistsUTF8(ListOfPaths[i]+'modelinfos.txt') then HavingModelInfo:=false;
  end
  else
  begin
    if not assigned(ListOfPaths) then ListOfPaths:=TStringList.Create;
    ListOfPaths.Clear;
    havingModelInfo:=false;
    if OpenDialog1.Execute then
    begin
      ListOfPaths.Add(ExtractFilePath(OpenDialog1.FileName));
      if MessageDlg('Do you want to load an add-on?',mtConfirmation,[mbYes,mbNo],0)=mrYes then
        if OpenDialog1.Execute then
        begin
          ListOfPaths.Add(ExtractFilePath(OpenDialog1.FileName));
          while MessageDlg('Do you want to load another add-on?',mtConfirmation,[mbYes,mbNo],0)=mrYes do
            if OpenDialog1.Execute then
              ListOfPaths.Add(ExtractFilePath(OpenDialog1.FileName))
            else
              break;
        end;
      havingModelInfo:=true;
    end;
  end;

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

    s:=ListOfPaths[0];

    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);

    for numAddOn:=1 to ListOfPaths.Count-1 do
    begin
      s:=ListOfPaths[numAddOn];
      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',true);
      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',true);
      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',true);
      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',true);
      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',true);
      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',true);
      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);

      s:=erg_base.FinishLoadingAddOn;
      if s<>'' then ShowMessage(s);
    end;

    GroupBox1.visible:=true;
    GroupBox2.visible:=true;
    BitBtn1.Enabled:=true;
    Button7.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.autoSortMoving=1 then checkbox6.Checked:=true else CheckBox6.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;
      Edit3.Text:=modelinfos.RealSuffixF90;
    end;

    s:=GenerateIndexes(CheckBox6.Checked);
    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)+
              'Version '+erg_code.codegenVersion+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.Button7Click(Sender: TObject);
var
  pt_list: Array of String;
  found: Boolean;
  i,j: Integer;
  oldpath: String;
begin
  //If this button is clicked, we will create the code several times.
  //Each time, we choose another "process type" as selected.
  //Then a subdirectory is created according to this process type,
  //and the code is put in this subdirectory.
  //This is especially useful when creating a documentation from a template
  //which  is structured by process type.

  // first, we create a list of all process types which are available
  setLength(pt_list,0);
  for i:=0 to length(processes)-1 do
  begin
    found:=false;
    for j:=0 to length(pt_list)-1 do
      if lowercase(pt_list[j])=lowercase(processes[i].processType) then found:=true;
    if (not found) then
    begin
      setLength(pt_list,length(pt_list)+1);
      pt_list[length(pt_list)-1]:=processes[i].processType;
      if trim(processes[i].processType)='' then ShowMessage(processes[i].name);
    end;
  end;

  //save the original output path - we will create subdirectories
  oldpath:=Edit2.Text;
  if copy(oldpath,length(oldpath),1) <> '/' then
    oldpath:=oldpath+'/';
  //now we loop over each of this process types
  for i:=0 to length(pt_list)-1 do
  begin
    //select this process type
    for j:=0 to length(processes)-1 do
      if (lowercase(processes[j].processType)=lowercase(pt_list[i])) //exactly this type selected
      then
        processes[j].myIsSelected:=true
      else
        processes[j].myIsSelected:=false;
    //update it for the constants, auxiliaries and tracers as well
    GenerateIndexes;
    //append the process type to the output directory
    Edit2.Text:=oldpath+pt_list[i]+'/';
    //windows:Edit2.Text:=oldpath+StringReplace(pt_list[i],'/','\',[rfReplaceAll, rfIgnoreCase])+'\';
    //make sure this directory exists
    ForceDirectories(Edit2.Text);
    //set the current process type in modelinfos
    modelinfos.mySelectedProcessType:=pt_list[i];
    //generate the code
    BitBtn1click(self);
  end;
  Edit2.Text:=oldpath;

  //reload the text files
  Button1Click(ComboBox1);
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;
  i: Integer;
begin
  for i:=0 to ListOfPaths.Count-1 do
  begin
    s:=ListOfPaths[i];
    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
    begin
      if MessageDlg('Textfiles have changed on disk. Reload the files?',mtConfirmation,[mbYes,mbNo],0)=mrYes then
        Button1Click(ComboBox1);
      break;
    end;
  end;
  modelinfos.templatePath:=edit1.Text;
  modelinfos.outputPath:=edit2.Text;
  SaveModelInfos(ListOfPaths[ListOfPaths.count-1]+'/modelinfos.txt');
  for i:=0 to ListOfPaths.Count-1 do
  begin
    s:=ListOfPaths[i];
    MaxFileAge:=max(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;
end;

procedure TForm1.Button5Click(Sender: TObject);
var
  i: Integer;
  s: String;
begin
  for i:=0 to ListOfPaths.Count-1 do
  begin
    s:=ListOfPaths[i];
    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
    begin
      if MessageDlg('Textfiles have changed on disk. Reload the files?',mtConfirmation,[mbYes,mbNo],0)=mrYes then
        Button1Click(ComboBox1);
      break;
    end;
  end;

  if CheckBox4.Checked then modelinfos.autoSplitColors:=1 else modelinfos.autoSplitColors:=0;
  if CheckBox6.Checked then modelinfos.autoSortMoving:=1 else modelinfos.autoSortMoving:=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.RealSuffixF90:=Edit3.Text;
  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:=modelinfos.inactiveProcessTypes+'; '+CheckListBox1.Items[i];
    end;
  SaveModelInfos(ListOfPaths[ListOfPaths.count-1]+'/modelinfos.txt');
  for i:=0 to ListOfPaths.Count-1 do
  begin
    s:=ListOfPaths[i];
    MaxFileAge:=max(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;
end;

//! Button Click on Object TForm1 starting the main program for template file processing
{!
  \public
  \author Hagen Radtke, hagen.radtke@io-warnemuende.de

  Calls
  - \ref erg_code::generateCode()
  - Button1Click()
  - \ref erg_pseudo3d::TreatPseudo3d()
  - \ref erg_base::SetDisabledProcessesInactive()
  - \ref erg_color::SplitColoredElements()
  }
procedure TForm1.BitBtn1Click(Sender: TObject);
var
  doGenerate: Boolean;
  sr: tSearchRec;
  wrappedlines: Integer;
  oldModelinfo: TErgModelInfo;
  sl: TStringList;
  i: Integer;
  s: String;
begin
  for i:=0 to ListOfPaths.Count-1 do
  begin
    s:=ListOfPaths[i];
    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
    begin
      if MessageDlg('Textfiles have changed on disk. Reload the files?',mtConfirmation,[mbYes,mbNo],0)=mrYes then
        Button1Click(ComboBox1);
      break;
    end;
  end;
  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(CheckBox6.Checked));
      sl.Add(CheckAuxiliaryOrder);
      if sl[0]<>'' then ShowMessage(sl[0]);

      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 if lowercase(ExtractFileExt(sr.Name))='.jnl' then
            erg_code.outputLanguage:='ferret'
          else if lowercase(ExtractFileExt(sr.Name))='.xml' then
            erg_code.outputLanguage:='xml'
          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 (Edit3.Text<>'') and (lowercase(ExtractFileExt(sr.Name))='.f90') then
          begin
            Label6.Caption:='adding suffixes for real values in .f90 files';
            Label6.Repaint;
            wrappedLines:=AddRealSuffixF90(Edit2.text+ExtractFileName(sr.Name),Edit3.Text);
            if wrappedlines>0 then Memo1.Lines.Add('file '+ExtractFileName(sr.Name)+': '+IntToStr(wrappedlines)+' real values got a suffix.');
          end;
          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 CheckBox3.Checked and (lowercase(ExtractFileExt(sr.Name))='.pas') then
          begin
            Label6.Caption:='wrapping long lines...';
            Label6.Repaint;
            wrappedlines:= PascalWrap(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.
