unit Unit1;

{$MODE Delphi}

interface

uses
  LCLIntf, LCLType, LMessages, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, Dialogs, StdCtrls, ComCtrls, CheckLst, ExtCtrls, Buttons,
  FileUtil, SynEdit, SynHighlighterAny,  StrUtils, erg_base,
  erg_types, SynHighlighterPosition, unit6, Unit7, Unit8;

type

  { TForm1 }

  TForm1 = class(TForm)
    BitBtn3: TBitBtn;
    BitBtn4: TBitBtn;
    BitBtn5: TBitBtn;
    BitBtn6: TBitBtn;
    BitBtn7: TBitBtn;
    Button1: TButton;
    Button4: TButton;
    Button5: TButton;
    Button6: TButton;
    Button11: TButton;
    Button7: TButton;
    Button9: TButton;
    Button8: TButton;
    CheckBox3: TCheckBox;
    CheckBox2: TCheckBox;
    Edit8: TEdit;
    Label5: TLabel;
    Label6: TLabel;
    Memo1: TMemo;
    Label2: TLabel;
    Edit1: TEdit;
    Label3: TLabel;
    Panel2: TPanel;
    Panel4: TPanel;
    Panel5: TPanel;
    Panel6: TPanel;
    Panel7: TPanel;
    SaveDialog1: TSaveDialog;
    SpeedButton1: TSpeedButton;
    SpeedButton2: TSpeedButton;
    Label1: TLabel;
    SpeedButton3: TSpeedButton;
    SpeedButton4: TSpeedButton;
    SpeedButton5: TSpeedButton;
    SpeedButton6: TSpeedButton;
    Panel1: TPanel;
    RadioButton1: TRadioButton;
    RadioButton2: TRadioButton;
    RadioButton3: TRadioButton;
    RadioButton4: TRadioButton;
    RadioButton5: TRadioButton;
    RadioButton6: TRadioButton;
    RadioButton7: TRadioButton;
    CheckListBox1: TCheckListBox;
    OpenDialog1: TOpenDialog;
    ListBox1: TListBox;
    Button2: TButton;
    Panel3: TPanel;
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    Label4: TLabel;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    Edit7: TEdit;
    Button3: TButton;
    SynAnySyn1: TSynAnySyn;
    SynEdit1: TSynEdit;
    procedure BitBtn3Click(Sender: TObject);
    procedure BitBtn4Click(Sender: TObject);
    procedure BitBtn5Click(Sender: TObject);
    procedure BitBtn6Click(Sender: TObject);
    procedure BitBtn7Click(Sender: TObject);
    procedure Button11Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure Button9Click(Sender: TObject);
    procedure Button8Click(Sender: TObject);
    procedure CheckBox2Change(Sender: TObject);
    procedure CheckBox2Click(Sender: TObject);
    procedure CheckListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure CheckListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure CheckListBox1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Edit8Change(Sender: TObject);
    procedure Edit8KeyPress(Sender: TObject; var Key: char);
    procedure FormShow(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure ListBox1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Panel6Click(Sender: TObject);
    procedure Panel7Click(Sender: TObject);
    procedure RadioButton1Click(Sender: TObject);
    procedure RadioButton2Click(Sender: TObject);
    procedure RadioButton3Click(Sender: TObject);
    procedure RadioButton4Change(Sender: TObject);
    procedure RadioButton4Click(Sender: TObject);
    procedure RadioButton5Click(Sender: TObject);
    procedure RadioButton6Click(Sender: TObject);
    procedure RadioButton7Click(Sender: TObject);
    procedure ListBox1Click(Sender: TObject);
    procedure CheckListBox1Click(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
    procedure Edit2Click(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure CheckBox3Click(Sender: TObject);
    procedure CheckListBox1ClickCheck(Sender: TObject);
    procedure CheckListBox1Exit(Sender: TObject);
    procedure Memo1Change(Sender: TObject);
    procedure SpeedButton2Click(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure SpeedButton3Click(Sender: TObject);
    procedure SpeedButton4Click(Sender: TObject);
    procedure SpeedButton5Click(Sender: TObject);
    procedure SpeedButton6Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure SynEdit1Change(Sender: TObject);
    procedure SynEdit1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  newform=class(TForm)
  protected
    procedure CreateParams(var Params :TCreateParams); override;
  private
  public
    procedure FormClose(Sender: TObject);
  end;

  procedure GoToExpression(s: String; BackButtonPressed: Boolean=false);
  procedure SaveAllFiles;
  
var
  Form1: TForm1;
  ShowFirstTime: Boolean;
  selConstant, selTracer, selAuxiliary, selProcess, selElement, selCElement: Integer;
  TempFileName: String;
  SynEditBusy: Boolean;
  ChangedCheck: Boolean;
  BackList: TStringList; BackListPosition: Integer;
  Highlighter: SynHighlighterPosition.TSynPositionHighlighter;
  InconsistencyString: String;
  StartingPoint : TPoint; // to sort tracers, auxiliaries etc.
  SelectedProcessType: String; //currently selected filter on which process types are shown, default=''

  ref_constants:   Array of tErgConstant;
  ref_elements:    Array of tErgElement;
  ref_tracers:     Array of tErgTracer;
  ref_auxiliaries: Array of tErgAuxiliary;
  ref_limitations: Array of tErgLimitation;
  ref_processes:   Array of tErgProcess;
  ref_cElements:   Array of tErgCElement;
  ref_modelinfos:  tErgModelInfo;

  selectedConstants, selectedTracers, selectedAuxiliaries, selectedProcesses: Array of Integer;

implementation

uses unit3, Unit4, Unit5;

{$R *.lfm}

procedure newform.CreateParams(var Params :TCreateParams);
begin
  inherited;
  Params.ExStyle := Params.ExStyle OR WS_EX_APPWINDOW;
  Params.WndParent := Form1.Handle;
end;
procedure newform.FormClose(Sender: TObject);
begin
  self.Close;
end;


function IsStandardChar(c: Char):Boolean;
begin
  if (ord(c)>=ord(char('a'))) and (ord(c)<=ord(char('z'))) then
    result:=true
  else if (ord(c)>=ord(char('A'))) and (ord(c)<=ord(char('Z'))) then
    result:=true
  else if (ord(c)>=ord(char('0'))) and (ord(c)<=ord(char('9'))) then
    result:=true
  else if (ord(c)=ord(char('_'))) or (ord(c)=ord(char('$')))  then
    result:=true
  else
    result:=false;
end;

procedure PaintTheWord(myWord: String; lines: TStrings; tk: TtkTokenKind; Highlighter: TSynPositionHighlighter; matchCase: Boolean=false);
var
  i: Integer;
  text, lmyword: String;
  found: Boolean;
  myPos: Integer;
  c: Char;
begin
  for i:=0 to lines.Count-1 do
  begin
    text:=lines[i];
    if matchCase=false then text:=lowercase(text);
    myPos:=0;
    lmyWord:=myWord;
    if matchCase=false then lmyWord:=lowercase(lmyWord);
    while pos(lmyWord,text)>0 do
    begin
      found:=true;
      if pos(lmyWord,text)>1 then
      begin
        c:=copy(text,pos(lmyWord,text)-1,1)[1];
        if IsStandardChar(c) then found:=false;
      end;
      if pos(lmyWord,text)+length(myWord)-1<length(text) then
      begin
        c:=copy(text,pos(lmyWord,text)+length(myWord),1)[1];
        if IsStandardChar(c) then found:=false;
      end;
      if found then
      begin
        Highlighter.AddToken(i,myPos+pos(lmyWord,text)-1,tkText);
        Highlighter.AddToken(i,myPos+pos(lmyWord,text)-1+length(myWord),tk);
      end;
      myPos:=myPos+pos(lmyWord,text)+length(myWord)-2;
      text:=copy(text,pos(lmyWord,text)+length(myWord)-1,length(text));
      if (length(myWord)=1) and (pos(lmyWord,text)=1) then
        if myWord='_' then text:='a'+copy(text,2,length(text))
          else text:='_'+copy(text,2,length(text));
    end;
  end;
end;

procedure PaintTheWords;
var
  tkConstant, tkTracer, tkAuxiliary, tkProcess, tkElement, tkCElement, tkKeyword: TtkTokenKind;
  i, line: Integer;
  s: String;
begin
  // add some attributes
  tkConstant:=Highlighter.CreateTokenID('constant',clBlack,Form1.RadioButton1.Color,[]);
  tkTracer:=Highlighter.CreateTokenID('tracer',clBlack,Form1.RadioButton2.Color,[]);
  tkAuxiliary:=Highlighter.CreateTokenID('auxiliary',clBlack,Form1.RadioButton3.Color,[]);
  tkProcess:=Highlighter.CreateTokenID('process',clBlack,Form1.RadioButton4.Color,[]);
  tkElement:=Highlighter.CreateTokenID('element',clBlack,Form1.RadioButton5.Color,[]);
  tkCElement:=Highlighter.CreateTokenID('celement',clBlack,clSilver,[]);
  tkKeyword:=Highlighter.CreateTokenID('keyword',clBlack,clSilver,[]);

  for line:=0 to Form1.SynEdit1.Lines.Count do
    Highlighter.ClearTokens(line);
  for i:=0 to length(constants)-1 do
    PaintTheWord(constants[i].name,Form1.SynEdit1.lines,tkConstant,Highlighter);
  for i:=0 to length(tracers)-1 do
    PaintTheWord(tracers[i].name,Form1.SynEdit1.lines,tkTracer,Highlighter);
  for i:=0 to length(auxiliaries)-1 do
    PaintTheWord(auxiliaries[i].name,Form1.SynEdit1.lines,tkAuxiliary,Highlighter);
  for i:=0 to length(processes)-1 do
    PaintTheWord(processes[i].name,Form1.SynEdit1.lines,tkProcess,Highlighter);
  for i:=0 to length(elements)-1 do
    PaintTheWord(elements[i].name,Form1.SynEdit1.lines,tkElement,Highlighter);
  for i:=0 to length(celements)-1 do
    PaintTheWord(celements[i].color+'_'+celements[i].element,Form1.SynEdit1.lines,tkCElement,Highlighter);
  for i:=0 to length(keywords)-1 do
    PaintTheWord(keywords[i],Form1.SynEdit1.lines,tkKeyword,Highlighter,true);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  F: TextFile;
  s: string;
begin
  AssignFile(F,TempFileName);
  rewrite(F);
  if RadioButton1.Checked then //constants
    WriteConstantsHeader(F)
  else if RadioButton2.Checked then //tracers
    WriteTracersHeader(F)
  else if RadioButton3.Checked then //auxiliaries
    WriteAuxiliariesHeader(F)
  else if RadioButton4.Checked then //processes
    WriteProcessesHeader(F)
  else if RadioButton5.Checked then //elements
    WriteElementsHeader(F)
  else if RadioButton6.Checked then //celements
    WriteCElementsHeader(F)
  else if RadioButton7.Checked then //modelinfos
    WriteModelinfosHeader(F);
  closefile(F);

  Form5.Memo1.lines.clear;
  AssignFile(F,TempFileName);
  reset(F);
  readln(F,s); readln(F,s); readln(F,s);
  while not EOF(F) do
  begin
    readln(F,s);
    Form5.Memo1.Lines.add(s);
  end;
  closefile(F);

  Form5.ShowModal;
end;

function selectedConstant: Integer;
begin
  if selectedProcessType='' then
    result:=Form1.ListBox1.ItemIndex
  else if Form1.ListBox1.ItemIndex>=0 then
    result:=selectedConstants[Form1.ListBox1.ItemIndex]
  else
    result:=-1;
end;

function selectedTracer: Integer;
begin
  if selectedProcessType='' then
    result:=Form1.CheckListBox1.ItemIndex
  else if Form1.CheckListBox1.ItemIndex>=0 then
    result:=selectedTracers[Form1.CheckListBox1.ItemIndex]
  else
    result:=-1;
end;

function selectedAuxiliary: Integer;
begin
  if selectedProcessType='' then
    result:=Form1.CheckListBox1.ItemIndex
  else if Form1.CheckListBox1.ItemIndex>=0 then
    result:=selectedAuxiliaries[Form1.CheckListBox1.ItemIndex]
  else
    result:=-1;
end;

function selectedProcess: Integer;
begin
  if selectedProcessType='' then
    result:=Form1.CheckListBox1.ItemIndex
  else if Form1.CheckListBox1.ItemIndex>=0 then
    result:=selectedProcesses[Form1.CheckListBox1.ItemIndex]
  else
    result:=-1;
end;

function selectedElement: Integer;
begin
  result:=Form1.ListBox1.ItemIndex;
end;

function selectedCElement: Integer;
begin
  result:=Form1.ListBox1.ItemIndex;
end;

function indexOfConstant(i: Integer; NeedsToBePresent: Boolean=true):Integer;
var j: Integer;
begin
  if selectedProcessType='' then
    result:=i
  else
  begin
    result:=-1;
    for j:=0 to length(selectedConstants)-1 do
      if selectedConstants[j]=i then result:=j;
  end;
  if NeedsToBePresent and (Form1.ListBox1.Items.Count<=result) then result:=-1;
end;

function indexOfTracer(i: Integer; NeedsToBePresent: Boolean=true):Integer;
var j: Integer;
begin
  if selectedProcessType='' then
    result:=i
  else
  begin
    result:=-1;
    for j:=0 to length(selectedTracers)-1 do
      if selectedTracers[j]=i then result:=j;
  end;
  if NeedsToBePresent and (Form1.CheckListBox1.Items.Count<=result) then result:=-1;
end;

function indexOfAuxiliary(i: Integer; NeedsToBePresent: Boolean=true):Integer;
var j: Integer;
begin
  if selectedProcessType='' then
    result:=i
  else
  begin
    result:=-1;
    for j:=0 to length(selectedAuxiliaries)-1 do
      if selectedAuxiliaries[j]=i then result:=j;
  end;
  if NeedsToBePresent and (Form1.CheckListBox1.Items.Count<=result) then result:=-1;
end;

function indexOfProcess(i: Integer; NeedsToBePresent: Boolean=true):Integer;
var j: Integer;
begin
  if selectedProcessType='' then
    result:=i
  else
  begin
    result:=-1;
    for j:=0 to length(selectedProcesses)-1 do
      if selectedProcesses[j]=i then result:=j;
  end;
  if NeedsToBePresent and (Form1.CheckListBox1.Items.Count<=result) then result:=-1;
end;

function indexOfElement(i: Integer; NeedsToBePresent: Boolean=true):Integer;
begin
  result:=i;
  if NeedsToBePresent and (Form1.ListBox1.Items.Count<=result) then result:=-1;
end;

function indexOfCElement(i: Integer; NeedsToBePresent: Boolean=true):Integer;
begin
  result:=i;
  if NeedsToBePresent and (Form1.ListBox1.Items.Count<=result) then result:=-1;
end;

procedure LoadAllFiles(loadAddOn: Boolean=false);
var
  s: String;
  err: Integer;
begin
  s:=ExtractFilePath(Form1.OpenDialog1.FileName);
  if FileExistsUTF8(s+'/modelinfos.txt') { *Converted from FileExists*  } then
  begin
    TempFileName:=s+'/temp.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',loadAddOn);
    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',loadAddOn);
    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',loadAddOn);
    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',loadAddOn);
    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',loadAddOn);
    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',loadAddOn);
    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);

    InconsistencyString:=GenerateIndexes;
    if InconsistencyString<>'' then
      Form1.Panel5.Visible:=true
    else
      Form1.Panel5.Visible:=false;
  end
  else Halt;
end;

procedure SaveAllFiles;
var
  s: String;
begin
  s:=ExtractFilePath(Form1.OpenDialog1.FileName);
//  if FileExistsUTF8(s+'/modelinfos.txt') { *Converted from FileExists*  } then
//  begin
    SaveModelInfos(s+'modelinfos.txt');
    SaveConstants(s+'constants.txt');
    SaveElements(s+'elements.txt');
    SaveTracers(s+'tracers.txt');
    SaveAuxiliaries(s+'auxiliaries.txt');
    SaveProcesses(s+'processes.txt');
    SaveCElements(s+'celements.txt');
//  end
//  else Halt;
end;

function WhatHasChangedConstant(i: Integer): String;
var
  name: String;
  j, ref_i: Integer;
  F: TextFile;
  s: String;
begin
  name:=trim(lowercase(constants[i].name));
  ref_i:=-1;
  for j:=0 to length(ref_constants)-1 do
    if trim(lowercase(ref_constants[j].name))=name then ref_i:=j;
  if ref_i=-1 then result:='new'
  else
  begin
    AssignFile(F,ExtractFilePath(Form1.OpenDialog1.FileName)+'temp.txt');
    rewrite(F);
    SaveSingleConstantRef(F,i,ref_constants[ref_i],false);
    closefile(F);
    AssignFile(F,ExtractFilePath(Form1.OpenDialog1.FileName)+'temp.txt');
    reset(F);
    result:='no';
    while not EOF(F) do
    begin
      readln(F,s);
      if copy(trim(lowercase(s)),1,4)<>'name' then
      begin
        if (copy(trim(lowercase(s)),1,11)='description') then
        begin
          if result='no' then result:='desc/comm';
        end
        else if (copy(trim(lowercase(s)),1,7)='comment') then
        begin
          if result='no' then result:='desc/comm';
        end
        else result:='yes';
      end;
    end;
    closefile(F);
  end;
end;

function WhatHasChangedTracer(i: Integer): String;
var
  name: String;
  j, ref_i: Integer;
  F: TextFile;
  s: String;
begin
  name:=trim(lowercase(Tracers[i].name));
  ref_i:=-1;
  for j:=0 to length(ref_Tracers)-1 do
    if trim(lowercase(ref_Tracers[j].name))=name then ref_i:=j;
  if ref_i=-1 then result:='new'
  else
  begin
    AssignFile(F,ExtractFilePath(Form1.OpenDialog1.FileName)+'temp.txt');
    rewrite(F);
    SaveSingleTracerRef(F,i,ref_Tracers[ref_i],false);
    closefile(F);
    AssignFile(F,ExtractFilePath(Form1.OpenDialog1.FileName)+'temp.txt');
    reset(F);
    result:='no';
    while not EOF(F) do
    begin
      readln(F,s);
      if copy(trim(lowercase(s)),1,4)<>'name' then
      begin
        if (copy(trim(lowercase(s)),1,11)='description') then
        begin
          if result='no' then result:='desc/comm';
        end
        else if (copy(trim(lowercase(s)),1,7)='comment') then
        begin
          if result='no' then result:='desc/comm';
        end
        else result:='yes';
      end;
    end;
    closefile(F);
  end;
end;

function WhatHasChangedAuxiliary(i: Integer): String;
var
  name: String;
  j, ref_i: Integer;
  F: TextFile;
  s: String;
begin
  name:=trim(lowercase(Auxiliaries[i].name));
  ref_i:=-1;
  for j:=0 to length(ref_Auxiliaries)-1 do
    if trim(lowercase(ref_Auxiliaries[j].name))=name then ref_i:=j;
  if ref_i=-1 then result:='new'
  else
  begin
    AssignFile(F,ExtractFilePath(Form1.OpenDialog1.FileName)+'temp.txt');
    rewrite(F);
    SaveSingleAuxiliaryRef(F,i,ref_Auxiliaries[ref_i],false);
    closefile(F);
    AssignFile(F,ExtractFilePath(Form1.OpenDialog1.FileName)+'temp.txt');
    reset(F);
    result:='no';
    while not EOF(F) do
    begin
      readln(F,s);
      if copy(trim(lowercase(s)),1,4)<>'name' then
      begin
        if (copy(trim(lowercase(s)),1,11)='description') then
        begin
          if result='no' then result:='desc/comm';
        end
        else if (copy(trim(lowercase(s)),1,7)='comment') then
        begin
          if result='no' then result:='desc/comm';
        end
        else result:='yes';
      end;
    end;
    closefile(F);
  end;
end;

function WhatHasChangedProcess(i: Integer): String;
var
  name: String;
  j, ref_i: Integer;
  F: TextFile;
  s: String;
begin
  name:=trim(lowercase(Processes[i].name));
  ref_i:=-1;
  for j:=0 to length(ref_Processes)-1 do
    if trim(lowercase(ref_Processes[j].name))=name then ref_i:=j;
  if ref_i=-1 then result:='new'
  else
  begin
    AssignFile(F,ExtractFilePath(Form1.OpenDialog1.FileName)+'temp.txt');
    rewrite(F);
    SaveSingleProcessRef(F,i,ref_Processes[ref_i],ref_limitations,false);
    closefile(F);
    AssignFile(F,ExtractFilePath(Form1.OpenDialog1.FileName)+'temp.txt');
    reset(F);
    result:='no';
    while not EOF(F) do
    begin
      readln(F,s);
      if copy(trim(lowercase(s)),1,4)<>'name' then
      begin
        if (copy(trim(lowercase(s)),1,11)='description') then
        begin
          if result='no' then result:='desc/comm';
        end
        else if (copy(trim(lowercase(s)),1,7)='comment') then
        begin
          if result='no' then result:='desc/comm';
        end
        else result:='yes';
      end;
    end;
    closefile(F);
  end;
end;

function WhatHasChangedElement(i: Integer): String;
var
  name: String;
  j, ref_i: Integer;
  F: TextFile;
  s: String;
begin
  name:=trim(lowercase(Elements[i].name));
  ref_i:=-1;
  for j:=0 to length(ref_Elements)-1 do
    if trim(lowercase(ref_Elements[j].name))=name then ref_i:=j;
  if ref_i=-1 then result:='new'
  else
  begin
    AssignFile(F,ExtractFilePath(Form1.OpenDialog1.FileName)+'temp.txt');
    rewrite(F);
    SaveSingleElementRef(F,i,ref_Elements[ref_i],false);
    closefile(F);
    AssignFile(F,ExtractFilePath(Form1.OpenDialog1.FileName)+'temp.txt');
    reset(F);
    result:='no';
    while not EOF(F) do
    begin
      readln(F,s);
      if copy(trim(lowercase(s)),1,4)<>'name' then
      begin
        if (copy(trim(lowercase(s)),1,11)='description') then
        begin
          if result='no' then result:='desc/comm';
        end
        else if (copy(trim(lowercase(s)),1,7)='comment') then
        begin
          if result='no' then result:='desc/comm';
        end
        else result:='yes';
      end;
    end;
    closefile(F);
  end;
end;

function WhatHasChangedCElement(i: Integer): String;
var
  element, color: String;
  j, ref_i: Integer;
  F: TextFile;
  s: String;
begin
  element:=trim(lowercase(CElements[i].element));
  color:=trim(lowercase(CElements[i].color));
  ref_i:=-1;
  for j:=0 to length(ref_CElements)-1 do
    if (trim(lowercase(ref_CElements[j].element))=element) and (trim(lowercase(ref_CElements[j].color))=color) then ref_i:=j;
  if ref_i=-1 then result:='new'
  else
  begin
    AssignFile(F,ExtractFilePath(Form1.OpenDialog1.FileName)+'temp.txt');
    rewrite(F);
    SaveSingleCElementRef(F,i,ref_CElements[ref_i],false);
    closefile(F);
    AssignFile(F,ExtractFilePath(Form1.OpenDialog1.FileName)+'temp.txt');
    reset(F);
    result:='no';
    while not EOF(F) do
    begin
      readln(F,s);
      if (copy(trim(lowercase(s)),1,5)<>'color') and (copy(trim(lowercase(s)),1,7)<>'element') then
      begin
        if (copy(trim(lowercase(s)),1,11)='description') then
        begin
          if result='no' then result:='desc/comm';
        end
        else if (copy(trim(lowercase(s)),1,7)='comment') then
        begin
          if result='no' then result:='desc/comm';
        end
        else result:='yes';
      end;
    end;
    closefile(F);
  end;
end;

function OriginalConstant(i: Integer): TErgConstant;
var
  name: String;
  j, ref_i: Integer;
begin
  name:=trim(lowercase(Constants[i].name));
  ref_i:=-1;
  for j:=0 to length(ref_Constants)-1 do
    if trim(lowercase(ref_Constants[j].name))=name then ref_i:=j;
  if ref_i=-1 then InitErgConstant(result)
  else CopyErgConstant(ref_Constants[ref_i],result);
end;

function OriginalTracer(i: Integer): TErgTracer;
var
  name: String;
  j, ref_i: Integer;
begin
  name:=trim(lowercase(tracers[i].name));
  ref_i:=-1;
  for j:=0 to length(ref_tracers)-1 do
    if trim(lowercase(ref_tracers[j].name))=name then ref_i:=j;
  if ref_i=-1 then InitErgTracer(result)
  else CopyErgTracer(ref_tracers[ref_i],result);
end;

function OriginalAuxiliary(i: Integer): TErgAuxiliary;
var
  name: String;
  j, ref_i: Integer;
begin
  name:=trim(lowercase(Auxiliaries[i].name));
  ref_i:=-1;
  for j:=0 to length(ref_Auxiliaries)-1 do
    if trim(lowercase(ref_Auxiliaries[j].name))=name then ref_i:=j;
  if ref_i=-1 then InitErgAuxiliary(result)
  else CopyErgAuxiliary(ref_Auxiliaries[ref_i],result);
end;

function OriginalProcess(i: Integer): TErgProcess;
var
  name: String;
  j, ref_i: Integer;
begin
  name:=trim(lowercase(Processes[i].name));
  ref_i:=-1;
  for j:=0 to length(ref_Processes)-1 do
    if trim(lowercase(ref_Processes[j].name))=name then ref_i:=j;
  if ref_i=-1 then InitErgProcess(result)
  else CopyErgProcess(ref_Processes[ref_i],result);
end;

function OriginalElement(i: Integer): TErgElement;
var
  name: String;
  j, ref_i: Integer;
begin
  name:=trim(lowercase(Elements[i].name));
  ref_i:=-1;
  for j:=0 to length(ref_Elements)-1 do
    if trim(lowercase(ref_Elements[j].name))=name then ref_i:=j;
  if ref_i=-1 then InitErgElement(result)
  else CopyErgElement(ref_Elements[ref_i],result);
end;

function OriginalCElement(i: Integer): TErgCElement;
var
  color, element: String;
  j, ref_i: Integer;
begin
  color:=trim(lowercase(celements[i].color));
  element:=trim(lowercase(celements[i].element));
  ref_i:=-1;
  for j:=0 to length(ref_celements)-1 do
    if (trim(lowercase(ref_celements[j].color))=color) and (trim(lowercase(ref_celements[j].element))=element) then ref_i:=j;
  if ref_i=-1 then InitErgCElement(result)
  else CopyErgCElement(ref_CElements[ref_i],result);
end;

procedure LoadTheTracer(i: Integer);
var
  F: TextFile;
  s: String;
  j: Integer;
begin
 if i<0 then
 begin
  SynEditBusy:=true;
  Form1.Edit1.Text:='';
  Form1.SynEdit1.Lines.Clear;
  Form1.Memo1.Clear;
  SynEditBusy:=false;
 end
 else
 begin
  SynEditBusy:=true;
  Form1.SynEdit1.Font.Color:=clWhite;

  //first, export the tracer to a temporary file
  AssignFile(F,TempFileName);
  rewrite(F);
  if Form1.CheckBox2.Checked then
  begin
    for j:=0 to length(ref_tracers)-1 do
      if trim(lowercase(tracers[i].name))=trim(lowercase(ref_tracers[j].name)) then
        SaveSingleTracerRef(F,i,ref_tracers[j],false);
  end
  else
    SaveSingleTracer(F,i);
  closefile(F);

  //now, load the contents of the exported file to the SynEdit
  Form1.SynEdit1.Lines.Clear;
  Form1.Memo1.Lines.Clear;
  AssignFile(F,TempFileName);
  reset(F);
  while not EOF(F) do
  begin
    readln(F,s);
    if (copy(trim(lowercase(s)),1,4)<>'name') and
       (copy(trim(lowercase(s)),1,7)<>'comment') and
       (copy(trim(lowercase(s)),1,8)<>'isoutput') then
    Form1.SynEdit1.Lines.Add(s);
    if copy(trim(lowercase(s)),1,7)='comment' then
      Form1.Memo1.Lines.Add(AnsiReplaceStr(tracers[i].comment,'\\',chr(13)+chr(10)));
  end;
  closefile(F);
  Form1.SynEdit1.Font.Color:=clBlack;
  //apply the painting
  PaintTheWords;

  //put name and comment to their places
  Form1.Edit1.text:=tracers[i].name;

  //write Label3
  with form1 do
  begin
  Label3.caption:='tracer';
  if tracers[i].vertLoc=1 then Label3.caption:='bottom '+Label3.caption;
  if tracers[i].vertLoc=2 then Label3.caption:='surface '+Label3.caption;
  if (tracers[i].vertSpeed<>'0') and (tracers[i].vertSpeed<>'0.0') then Label3.caption:='moving '+Label3.caption;
  if tracers[i].isActive=0 then Label3.caption:='virtual '+Label3.caption;
  if tracers[i].isCombined=1 then Label3.caption:='combined '+Label3.caption;
  end;

  //compare with the reference
  Form1.label6.caption := WhatHasChangedTracer(i);
  if Form1.Label6.caption='no' then Form1.Label6.Color:=Form1.Color;
  if Form1.Label6.caption='yes' then Form1.Label6.Color:=Form1.RadioButton4.color;
  if Form1.Label6.caption='desc/comm' then Form1.Label6.Color:=Form1.RadioButton3.color;
  if Form1.Label6.caption='new' then Form1.Label6.Color:=Form1.RadioButton1.color;

  if (Form1.Label6.Caption='no') or (Form1.Label6.Caption='new') or (length(ref_tracers)=0) then Form1.Button8.Visible:=false
  else Form1.Button8.Visible:=true;

  //finally, delete the file
  DeleteFileUTF8(tempFileName); { *Converted from DeleteFile*  }
  SynEditBusy:=false;
 end;
end;

procedure LoadTheAuxiliary(i: Integer);
var
  F: TextFile;
  s: String;
  j: Integer;
begin
 if i<0 then
 begin
  SynEditBusy:=true;
  Form1.Edit1.Text:='';
  Form1.SynEdit1.Lines.Clear;
  Form1.Memo1.Clear;
  SynEditBusy:=false;
 end
 else
 begin
  SynEditBusy:=true;
  Form1.SynEdit1.Font.Color:=clWhite;

  //first, export the tracer to a temporary file
  AssignFile(F,TempFileName);
  rewrite(F);
    if Form1.CheckBox2.Checked then
  begin
    for j:=0 to length(ref_auxiliaries)-1 do
      if trim(lowercase(auxiliaries[i].name))=trim(lowercase(ref_auxiliaries[j].name)) then
        SaveSingleAuxiliaryRef(F,i,ref_auxiliaries[j],false);
  end
  else
    SaveSingleAuxiliary(F,i);
  closefile(F);

  //now, load the contents of the exported file to the SynEdit
  Form1.SynEdit1.Lines.Clear;
  Form1.Memo1.Lines.Clear;
  AssignFile(F,TempFileName);
  reset(F);
  while not EOF(F) do
  begin
    readln(F,s);
    if (copy(trim(lowercase(s)),1,4)<>'name') and
       (copy(trim(lowercase(s)),1,7)<>'comment') and
       (copy(trim(lowercase(s)),1,8)<>'isoutput') then
    Form1.SynEdit1.Lines.Add(s);
    if copy(trim(lowercase(s)),1,7)='comment' then
      Form1.Memo1.Lines.Add(AnsiReplaceStr(auxiliaries[i].comment,'\\',chr(13)+chr(10)));
  end;
  closefile(F);
  Form1.SynEdit1.Font.Color:=clBlack;
  //apply the painting
  PaintTheWords;

  //put name and comment to their places
  Form1.Edit1.text:=auxiliaries[i].name;

  //write Label3
  with form1 do
  begin
  Label3.caption:='auxiliary variable';
  if auxiliaries[i].vertLoc=1 then Label3.caption:='bottom '+Label3.caption;
  if auxiliaries[i].vertLoc=2 then Label3.caption:='surface '+Label3.caption;
  if auxiliaries[i].isUsedElsewhere=1 then Label3.caption:=Label3.caption+' for external use';
  if auxiliaries[i].calcAfterProcesses=1 then Label3.caption:=Label3.caption+', calculated after the process rates';
  end;

    //compare with the reference
  Form1.label6.caption := WhatHasChangedAuxiliary(i);
  if Form1.Label6.caption='no' then Form1.Label6.Color:=Form1.Color;
  if Form1.Label6.caption='yes' then Form1.Label6.Color:=Form1.RadioButton4.color;
  if Form1.Label6.caption='desc/comm' then Form1.Label6.Color:=Form1.RadioButton3.color;
  if Form1.Label6.caption='new' then Form1.Label6.Color:=Form1.RadioButton1.color;

  if (Form1.Label6.Caption='no') or (Form1.Label6.Caption='new') or (length(ref_tracers)=0) then Form1.Button8.Visible:=false
  else Form1.Button8.Visible:=true;


  //finally, delete the file
  DeleteFileUTF8(tempFileName); { *Converted from DeleteFile*  }
  SynEditBusy:=false;
 end;
end;

procedure LoadTheProcess(i: Integer);
var
  F: TextFile;
  s: String;
  j: Integer;
begin
 if i<0 then
 begin
  SynEditBusy:=true;
  Form1.Edit1.Text:='';
  Form1.SynEdit1.Lines.Clear;
  Form1.Memo1.Clear;
  SynEditBusy:=false;
 end
 else
 begin
  SynEditBusy:=true;
  Form1.SynEdit1.Font.Color:=clWhite;

  //first, export the tracer to a temporary file
  AssignFile(F,TempFileName);
  rewrite(F);
  if Form1.CheckBox2.Checked then
  begin
    for j:=0 to length(ref_processes)-1 do
      if trim(lowercase(processes[i].name))=trim(lowercase(ref_processes[j].name)) then
        SaveSingleProcessRef(F,i,ref_processes[j],ref_limitations,false);
  end
  else
    SaveSingleProcess(F,i);
  closefile(F);

  //now, load the contents of the exported file to the SynEdit
  Form1.SynEdit1.Lines.Clear;
  Form1.Memo1.Lines.Clear;
  AssignFile(F,TempFileName);
  reset(F);
  while not EOF(F) do
  begin
    readln(F,s);
    if (copy(trim(lowercase(s)),1,4)<>'name') and
       (copy(trim(lowercase(s)),1,7)<>'comment') and
       (copy(trim(lowercase(s)),1,8)<>'isoutput') then
    Form1.SynEdit1.Lines.Add(s);
    if copy(trim(lowercase(s)),1,7)='comment' then
      Form1.Memo1.Lines.Add(AnsiReplaceStr(processes[i].comment,'\\',chr(13)+chr(10)));
  end;
  closefile(F);
  Form1.SynEdit1.Font.Color:=clBlack;
  //apply the painting
  PaintTheWords;

  //put name and comment to their places
  Form1.Edit1.text:=processes[i].name;

  //check if this process is conservative
  if InconsistencyString='' then
  begin
    if ProcessIsConservative(i) then
      Form1.Panel4.Color:=Form1.Color
    else
      Form1.Panel4.Color:=Form1.Edit1.Color;
  end
  else
    Form1.Panel4.Visible:=false;

  //write Label3
  with form1 do
  begin
  Label3.caption:='process';
  if processes[i].vertLoc=1 then Label3.caption:='bottom '+Label3.caption;
  if processes[i].vertLoc=2 then Label3.caption:='surface '+Label3.caption;
  if processes[i].isActive=0 then Label3.caption:='inactive '+Label3.caption;
  //if (CheckListBox1.ItemEnabled[i]=false) and (processes[i].isActive=1) then Label3.caption:=Label3.caption+', deactivated by settings in modelinfos';
  end;

    //compare with the reference
  Form1.label6.caption := WhatHasChangedProcess(i);
  if Form1.Label6.caption='no' then Form1.Label6.Color:=Form1.Color;
  if Form1.Label6.caption='yes' then Form1.Label6.Color:=Form1.RadioButton4.color;
  if Form1.Label6.caption='desc/comm' then Form1.Label6.Color:=Form1.RadioButton3.color;
  if Form1.Label6.caption='new' then Form1.Label6.Color:=Form1.RadioButton1.color;

  if (Form1.Label6.Caption='no') or (Form1.Label6.Caption='new') or (length(ref_tracers)=0) then Form1.Button8.Visible:=false
  else Form1.Button8.Visible:=true;


  //finally, delete the file
  deleteFile(tempFileName);
  SynEditBusy:=false;
 end;
end;

procedure LoadTheConstant(i: Integer);
var
  F: TextFile;
  s: String;
  j: Integer;
begin
 if i<0 then
 begin
  SynEditBusy:=true;
  Form1.Edit1.Text:='';
  Form1.SynEdit1.Lines.Clear;
  Form1.Memo1.Clear;
  SynEditBusy:=false;
 end
 else
 begin
  SynEditBusy:=true;
  Form1.SynEdit1.Font.Color:=clWhite;

  //first, export the tracer to a temporary file
  AssignFile(F,TempFileName);
  rewrite(F);
  if Form1.CheckBox2.Checked then
  begin
    for j:=0 to length(ref_constants)-1 do
      if trim(lowercase(constants[i].name))=trim(lowercase(ref_constants[j].name)) then
        SaveSingleConstantRef(F,i,ref_constants[j],false);
  end
  else
    SaveSingleConstant(F,i);
  closefile(F);

  //now, load the contents of the exported file to the SynEdit
  Form1.SynEdit1.Lines.Clear;
  Form1.Memo1.Lines.Clear;
  AssignFile(F,TempFileName);
  reset(F);
  while not EOF(F) do
  begin
    readln(F,s);
    if (copy(trim(lowercase(s)),1,4)<>'name') and
       (copy(trim(lowercase(s)),1,7)<>'comment') then
    Form1.SynEdit1.Lines.Add(s);
    if copy(trim(lowercase(s)),1,7)='comment' then
      Form1.Memo1.Lines.Add(AnsiReplaceStr(constants[i].comment,'\\',chr(13)+chr(10)));
  end;
  closefile(F);
  Form1.SynEdit1.Font.Color:=clBlack;
  //apply the painting
  PaintTheWords;

  //put name and comment to their places
  Form1.Edit1.text:=Constants[i].name;

  //write Label3
  with form1 do
  begin
    Label3.caption:='constant';
  end;

  //compare with the reference
  Form1.label6.caption := WhatHasChangedConstant(i);
  if Form1.Label6.caption='no' then Form1.Label6.Color:=Form1.Color;
  if Form1.Label6.caption='yes' then Form1.Label6.Color:=Form1.RadioButton4.color;
  if Form1.Label6.caption='desc/comm' then Form1.Label6.Color:=Form1.RadioButton3.color;
  if Form1.Label6.caption='new' then Form1.Label6.Color:=Form1.RadioButton1.color;

  if (Form1.Label6.Caption='no') or (Form1.Label6.Caption='new') or (length(ref_tracers)=0) then Form1.Button8.Visible:=false
  else Form1.Button8.Visible:=true;

  //finally, delete the file
  DeleteFileUTF8(tempFileName); { *Converted from DeleteFile*  }
  SynEditBusy:=false;
 end;
end;

procedure LoadTheElement(i: Integer);
var
  F: TextFile;
  s: String;
  j: Integer;
begin
 if i<0 then
 begin
  SynEditBusy:=true;
  Form1.Edit1.Text:='';
  Form1.SynEdit1.Lines.Clear;
  Form1.Memo1.Clear;
  SynEditBusy:=false;
 end
 else
 begin
  SynEditBusy:=true;
  Form1.SynEdit1.Font.Color:=clWhite;

  //first, export the tracer to a temporary file
  AssignFile(F,TempFileName);
  rewrite(F);
  if Form1.CheckBox2.Checked then
  begin
    for j:=0 to length(ref_elements)-1 do
      if trim(lowercase(elements[i].name))=trim(lowercase(ref_elements[j].name)) then
        SaveSingleElementRef(F,i,ref_elements[j],false);
  end
  else
    SaveSingleElement(F,i);
  closefile(F);

  //now, load the contents of the exported file to the SynEdit
  Form1.SynEdit1.Lines.Clear;
  Form1.Memo1.Lines.Clear;
  AssignFile(F,TempFileName);
  reset(F);
  while not EOF(F) do
  begin
    readln(F,s);
    if (copy(trim(lowercase(s)),1,4)<>'name') and
       (copy(trim(lowercase(s)),1,7)<>'comment') then
    Form1.SynEdit1.Lines.Add(s);
    if copy(trim(lowercase(s)),1,7)='comment' then
      Form1.Memo1.Lines.Add(AnsiReplaceStr(elements[i].comment,'\\',chr(13)+chr(10)));
  end;
  closefile(F);
  Form1.SynEdit1.Font.Color:=clBlack;
  //apply the painting
  PaintTheWords;

  //put name and comment to their places
  Form1.Edit1.text:=Elements[i].name;

  //write Label3
  with form1 do
  begin
    Label3.caption:='element';
  end;

  //compare with the reference
  Form1.label6.caption := WhatHasChangedElement(i);
  if Form1.Label6.caption='no' then Form1.Label6.Color:=Form1.Color;
  if Form1.Label6.caption='yes' then Form1.Label6.Color:=Form1.RadioButton4.color;
  if Form1.Label6.caption='desc/comm' then Form1.Label6.Color:=Form1.RadioButton3.color;
  if Form1.Label6.caption='new' then Form1.Label6.Color:=Form1.RadioButton1.color;

  if (Form1.Label6.Caption='no') or (Form1.Label6.Caption='new') or (length(ref_tracers)=0) then Form1.Button8.Visible:=false
  else Form1.Button8.Visible:=true;


  //finally, delete the file
  DeleteFileUTF8(tempFileName); { *Converted from DeleteFile*  }
  SynEditBusy:=false;
 end;
end;

procedure LoadTheCElement(i: Integer);
var
  F: TextFile;
  s: String;
  j: Integer;
begin
 if i<0 then
 begin
  SynEditBusy:=true;
  Form1.Edit1.Text:='';
  Form1.SynEdit1.Lines.Clear;
  Form1.Memo1.Clear;
  SynEditBusy:=false;
 end
 else
 begin
  SynEditBusy:=true;
  Form1.SynEdit1.Font.Color:=clWhite;

  //first, export the tracer to a temporary file
  AssignFile(F,TempFileName);
  rewrite(F);
  if Form1.CheckBox2.Checked then
  begin
    for j:=0 to length(ref_celements)-1 do
      if (trim(lowercase(celements[i].element))=trim(lowercase(ref_celements[j].element))) and
         (trim(lowercase(celements[i].color))=trim(lowercase(ref_celements[j].color))) then
        SaveSingleCElementRef(F,i,ref_celements[j],false);
  end
  else
    SaveSingleCelement(F,i);
  closefile(F);

  //now, load the contents of the exported file to the SynEdit
  Form1.SynEdit1.Lines.Clear;
  Form1.Memo1.Lines.Clear;
  AssignFile(F,TempFileName);
  reset(F);
  while not EOF(F) do
  begin
    readln(F,s);
    if (copy(trim(lowercase(s)),1,7)<>'element') and
       (copy(trim(lowercase(s)),1,5)<>'color') and
       (copy(trim(lowercase(s)),1,7)<>'comment') then
    Form1.SynEdit1.Lines.Add(s);
    if copy(trim(lowercase(s)),1,7)='comment' then
      Form1.Memo1.Lines.Add(AnsiReplaceStr(celements[i].comment,'\\',chr(13)+chr(10)));
  end;
  closefile(F);
  Form1.SynEdit1.Font.Color:=clBlack;
  //apply the painting
  PaintTheWords;

  //put name and comment to their places
  Form1.Edit1.text:=CElements[i].color+'_'+CElements[i].element;

  //write Label3
  with form1 do
  begin
    Label3.caption:='colored element';
  end;

  //compare with the reference
  Form1.label6.caption := WhatHasChangedCElement(i);
  if Form1.Label6.caption='no' then Form1.Label6.Color:=Form1.Color;
  if Form1.Label6.caption='yes' then Form1.Label6.Color:=Form1.RadioButton4.color;
  if Form1.Label6.caption='desc/comm' then Form1.Label6.Color:=Form1.RadioButton3.color;
  if Form1.Label6.caption='new' then Form1.Label6.Color:=Form1.RadioButton1.color;

  if (Form1.Label6.Caption='no') or (Form1.Label6.Caption='new') or (length(ref_tracers)=0) then Form1.Button8.Visible:=false
  else Form1.Button8.Visible:=true;


  //finally, delete the file
  DeleteFileUTF8(tempFileName); { *Converted from DeleteFile*  }
  SynEditBusy:=false;
 end;
end;

procedure LoadTheModelinfos;
var
  F: TextFile;
  s: String;
begin
  SynEditBusy:=true;
  Form1.SynEdit1.Font.Color:=clWhite;

  //first, export the modelinfos to a temporary file
  SaveModelInfos(tempfilename);

  //now, load the contents of the exported file to the SynEdit
  Form1.SynEdit1.Lines.Clear;
  Form1.Memo1.Lines.Clear;
  AssignFile(F,TempFileName);
  reset(F);
  while not EOF(F) do
  begin
    readln(F,s);
    if (copy(trim(lowercase(s)),1,1)<>'!') and
       (copy(trim(lowercase(s)),1,1)<>'*') and
       (copy(trim(lowercase(s)),1,7)<>'comment') then
    Form1.SynEdit1.Lines.Add(s);
    if copy(trim(lowercase(s)),1,7)='comment' then
      Form1.Memo1.Lines.Add(AnsiReplaceStr(Modelinfos.comment,'\\',chr(13)+chr(10)));
  end;
  closefile(F);
  Form1.SynEdit1.Font.Color:=clBlack;
  //apply the painting
  PaintTheWords;

  //put name and comment to their places
  Form1.Edit1.text:='';

  //write Label3
  with form1 do
  begin
    Label3.caption:='modelinfos';
  end;

  //finally, delete the file
  DeleteFileUTF8(tempFileName); { *Converted from DeleteFile*  }
  SynEditBusy:=false;
end;

procedure AppendToBackList(s: String);
var i: Integer;
begin
  if BackListPosition>=0 then
    if trim(lowercase(s))= trim(lowercase(BackList[BackListPosition])) then
      exit;
  BackListPosition:=BackListPosition+1;
  for i:=BackList.Count-1 downto BackListPosition do
    BackList.Delete(i);
  BackList.Add(s);
end;

procedure MyListBox1Click(BackButtonPressed: Boolean=false);
begin
 with Form1 do
 begin
  if RadioButton1.checked then //constant selected
  begin
    selConstant:=selectedConstant;
    LoadTheConstant(selConstant);
    if selConstant>=0 then
      if not BackButtonPressed then AppendToBackList(constants[selConstant].name);
  end
  else if RadioButton5.Checked then //element selected
  begin
    selElement:=selectedElement;
    LoadTheElement(selElement);
    if selElement>=0 then
      if not BackButtonPressed then AppendToBackList(elements[selElement].name);
  end
  else if RadioButton6.Checked then //colored element selected
  begin
    selCElement:=selectedCElement;
    LoadTheCElement(selCElement);
    if selCElement>=0 then
      if not BackButtonPressed then AppendToBackList(CElements[selCElement].color+'_'+CElements[selCElement].element);
  end;
 end;
end;

procedure MyCheckListBox1Click(BackButtonPressed: Boolean=false);
begin
 with Form1 do
 begin
  if RadioButton2.checked then //tracer selected
  begin
    selTracer:=selectedTracer;
    LoadTheTracer(selTracer);
    if selTracer>=0 then
      if not BackButtonPressed then AppendToBackList(tracers[selTracer].name);
  end
  else if RadioButton3.Checked then //auxiliary selected
  begin
    selAuxiliary:=selectedAuxiliary;
    LoadTheAuxiliary(selAuxiliary);
    if selAuxiliary>=0 then
      if not BackButtonPressed then AppendToBackList(Auxiliaries[selAuxiliary].name);
  end
  else if RadioButton4.Checked then //process selected
  begin
    selProcess:=selectedProcess;
    LoadTheProcess(selProcess);
    if selProcess>=0 then
      if not BackButtonPressed then AppendToBackList(processes[selProcess].name);
  end;
 end;
end;

procedure AfterRadioButton(BackButtonPressed: Boolean=false);
var
  i: Integer;
  s, s1: String;
  oldSynEditBusy: Boolean;
  compareResult: String;
begin
  oldSynEditBusy:=SynEditBusy;
  SynEditBusy:=true;
  with Form1 do
  begin
    CheckListBox1.Items.Clear;
    ListBox1.Items.Clear;
    Label1.Visible:=true; SpeedButton3.Visible:=true; SpeedButton4.Visible:=true; SpeedButton5.Visible:=true; SpeedButton6.Visible:=true;
    Button3.Visible:=false;
    if selectedProcessType <> '#MANUAL_SELECTED_BY_TRACER' then Panel6.Visible:=true else Panel6.Visible:=false;
    if selectedProcessType =  '#MANUAL_SELECTED_BY_TRACER' then Panel7.visible:=true else Panel7.Visible:=false;
    if selectedProcessType = '' then checkBox3.Visible:=true else checkBox3.Visible:=false;
    if RadioButton1.checked then //Constants selected;
    begin
      CheckListBox1.Visible:=false;
      ListBox1.Visible:=true;
      ListBox1.Color:=RadioButton1.Color; Edit1.Color:=RadioButton1.Color; Button2.Visible:=true;
      Button11.Caption:='show deleted constants';
      Panel4.Visible:=false;
      for i:=0 to length(Constants)-1 do
      begin
        if indexOfConstant(i,false)>=0 then
        begin
          if length(ref_tracers)=0 then
            ListBox1.Items.Add(Constants[i].name)
          else
          begin
            compareResult:=WhatHasChangedConstant(i);
            if compareResult='yes' then ListBox1.Items.Add(Constants[i].name)
            else if compareResult='new' then ListBox1.Items.Add(Constants[i].name)
            else if compareResult='desc/comm' then ListBox1.Items.Add('('+Constants[i].name+')')
            else ListBox1.Items.Add('    ('+Constants[i].name+')');
          end;
        end;
      end;
      ListBox1.ItemIndex:=IndexOfConstant(selConstant);
      MyListBox1Click(BackButtonPressed);
    end
    else if RadioButton2.checked then //tracers selected;
    begin
      Button3.Visible:=true;
      CheckListBox1.Visible:=true;
      ListBox1.Visible:=false;
      CheckListBox1.Color:=RadioButton2.Color; Edit1.Color:=RadioButton2.Color; Button2.Visible:=true;
      Button11.Caption:='show deleted tracers';      
      Panel4.Visible:=false;
      if (selectedProcessType='') and (length(tracers)>0) then Panel7.visible:=true;
      for i:=0 to length(tracers)-1 do
      begin
        if indexOfTracer(i,false)>=0 then
        begin
          if length(ref_tracers)=0 then
            CheckListBox1.Items.Add(tracers[i].name)
          else
          begin
            compareResult:=WhatHasChangedTracer(i);
            if compareResult='yes' then CheckListBox1.Items.Add(Tracers[i].name)
            else if compareResult='new' then CheckListBox1.Items.Add(Tracers[i].name)
            else if compareResult='desc/comm' then CheckListBox1.Items.Add('('+Tracers[i].name+')')
            else CheckListBox1.Items.Add('    ('+Tracers[i].name+')');
          end;
          if tracers[i].isOutput>0 then CheckListBox1.Checked[indexOfTracer(i)]:=true else CheckListBox1.Checked[indexOfTracer(i)]:=false;
          if tracers[i].isActive>0 then CheckListBox1.ItemEnabled[indexOfTracer(i)]:=true else
          begin
            CheckListBox1.ItemEnabled[indexOfTracer(i)]:=false;
            CheckListBox1.Checked[indexOfTracer(i)]:=false;
          end;
        end;
      end;
      CheckListBox1.ItemIndex:=IndexOfTracer(selTracer);
      CheckListBox1.Repaint;
      MyCheckListBox1Click(BackButtonPressed);
    end
    else if RadioButton3.checked then //Auxiliaries selected;
    begin
      CheckListBox1.Visible:=true;
      ListBox1.Visible:=false;
      CheckListBox1.Color:=RadioButton3.Color; Edit1.Color:=RadioButton3.Color; button2.Visible:=true;
      Button11.Caption:='show deleted auxiliary variables';
      Panel4.Visible:=false;
      for i:=0 to length(Auxiliaries)-1 do
      begin
        if indexOfAuxiliary(i,false)>=0 then
        begin
          if length(ref_tracers)=0 then
            CheckListBox1.Items.Add(auxiliaries[i].name)
          else
          begin
            compareResult:=WhatHasChangedAuxiliary(i);
            if compareResult='yes' then CheckListBox1.Items.Add(auxiliaries[i].name)
            else if compareResult='new' then CheckListBox1.Items.Add(auxiliaries[i].name)
            else if compareResult='desc/comm' then CheckListBox1.Items.Add('('+auxiliaries[i].name+')')
            else CheckListBox1.Items.Add('    ('+auxiliaries[i].name+')');
          end;
          if Auxiliaries[i].isOutput>0 then CheckListBox1.Checked[indexOfAuxiliary(i)]:=true else CheckListBox1.Checked[indexOfAuxiliary(i)]:=false;
          CheckListBox1.ItemEnabled[indexOfAuxiliary(i)]:=true;
        end;
      end;
      CheckListBox1.ItemIndex:=IndexOfAuxiliary(selAuxiliary);
      MyCheckListBox1Click(BackButtonPressed);
    end
    else if RadioButton4.checked then //Processes selected;
    begin
      CheckListBox1.Visible:=true;
      ListBox1.Visible:=false;
      CheckListBox1.Color:=RadioButton4.Color; Edit1.Color:=RadioButton4.Color; Button2.Visible:=true;
      Button11.Caption:='show deleted processes';
      Panel4.Visible:=true;
      for i:=0 to length(Processes)-1 do
      begin
        if indexOfProcess(i,false)>=0 then
        begin
          if length(ref_processes)=0 then
            CheckListBox1.Items.Add(processes[i].name)
          else
          begin
            compareResult:=WhatHasChangedProcess(i);
            if compareResult='yes' then CheckListBox1.Items.Add(Processes[i].name)
            else if compareResult='new' then CheckListBox1.Items.Add(Processes[i].name)
            else if compareResult='desc/comm' then CheckListBox1.Items.Add('('+Processes[i].name+')')
            else CheckListBox1.Items.Add('    ('+Processes[i].name+')');
          end;
          if Processes[i].isOutput>0 then CheckListBox1.Checked[indexOfProcess(i)]:=true else CheckListBox1.Checked[indexOfProcess(i)]:=false;
          CheckListBox1.ItemEnabled[indexOfProcess(i)]:=true;
          if Processes[i].isActive=0 then CheckListBox1.ItemEnabled[indexOfProcess(i)]:=false;
          s:=ModelInfos.inactiveProcessTypes;
          while s<>'' do
          begin
            s1:=SemiItem(s);
            if trim(lowercase(s1))=trim(lowercase(Processes[i].processType)) then
            begin
              CheckListBox1.ItemEnabled[indexOfProcess(i)]:=false;
              CheckListBox1.Checked[indexOfProcess(i)]:=false;
            end;
          end;
        end;
      end;
      CheckListBox1.ItemIndex:=IndexOfProcess(selProcess);
      MyCheckListBox1Click(BackButtonPressed);
    end
    else if RadioButton5.checked then //Elements selected;
    begin
      CheckListBox1.Visible:=false;
      ListBox1.Visible:=true;
      ListBox1.Color:=RadioButton5.Color; Edit1.Color:=RadioButton5.Color; Button2.Visible:=true;
      Button11.Caption:='show deleted elements';      
      Panel4.Visible:=false;
      for i:=0 to length(Elements)-1 do
      begin
        if indexOfElement(i,false)>=0 then
        begin
          if length(ref_tracers)=0 then
            ListBox1.Items.Add(elements[i].name)
          else
          begin
            compareResult:=WhatHasChangedElement(i);
            if compareResult='yes' then ListBox1.Items.Add(elements[i].name)
            else if compareResult='new' then ListBox1.Items.Add(elements[i].name)
            else if compareResult='desc/comm' then ListBox1.Items.Add('('+elements[i].name+')')
            else ListBox1.Items.Add('    ('+elements[i].name+')');
          end;
        end;
      end;
      ListBox1.ItemIndex:=IndexOfElement(selElement);
      MyListBox1Click(BackButtonPressed);
    end
    else if RadioButton6.checked then //CElements selected;
    begin
      CheckListBox1.Visible:=false;
      ListBox1.Visible:=true;
      ListBox1.Color:=clWhite; Edit1.Color:=clWhite; Button2.Visible:=false;
      Button11.Caption:='show deleted colored elements';      
      Panel4.Visible:=false;
      for i:=0 to length(CElements)-1 do
      begin
        if indexOfCElement(i,false)>=0 then
        begin
          if length(ref_tracers)=0 then
            ListBox1.Items.Add(CElements[i].color+'_'+CElements[i].element)
          else
          begin
            compareResult:=WhatHasChangedCElement(i);
            if compareResult='yes' then ListBox1.Items.Add(CElements[i].color+'_'+CElements[i].element)
            else if compareResult='new' then ListBox1.Items.Add(CElements[i].color+'_'+CElements[i].element)
            else if compareResult='desc/comm' then ListBox1.Items.Add('('+CElements[i].color+'_'+CElements[i].element+')')
            else ListBox1.Items.Add('    ('+CElements[i].color+'_'+CElements[i].element+')');
          end;
        end;
      end;
      ListBox1.ItemIndex:=IndexOfCElement(selCElement);
      MyListBox1Click(BackButtonPressed);
    end
    else if RadioButton7.checked then //Modelinfos selected;
    begin
      CheckListBox1.Visible:=false;
      ListBox1.Visible:=false;
      Edit1.Color:=clSilver; Button2.Visible:=false;
      Label1.Visible:=false; SpeedButton3.Visible:=false; SpeedButton4.Visible:=false; SpeedButton5.Visible:=false; SpeedButton6.Visible:=false;
      Panel4.Visible:=false;
      LoadTheModelinfos;
            if not BackButtonPressed then AppendToBackList('modelinfos');
    end
  end;
  SynEditBusy:=OldSynEditBusy;
end;

procedure GoToExpression(s: String; BackButtonPressed: Boolean=false);
//will seek if this string is the name of a constant, tracer, ... and load it
var
  i, num: Integer;
begin
  num:=-1;

  with Form1 do
  begin

  for i:=0 to length(elements)-1 do
    if trim(lowercase(elements[i].name))=trim(lowercase(s)) then
      num:=i;
  if num<>-1 then
  begin
    selElement:=num;
    RadioButton1.checked:=false; RadioButton2.checked:=false;RadioButton3.checked:=false; RadioButton4.checked:=false; RadioButton5.checked:=false; RadioButton6.checked:=false; RadioButton7.checked:=false;
    RadioButton5.checked:=true;
    AfterRadioButton(BackButtonPressed);
    exit;
  end;

  for i:=0 to length(processes)-1 do
    if trim(lowercase(processes[i].name))=trim(lowercase(s)) then
      num:=i;
  if num<>-1 then
  begin
    selProcess:=num;
    RadioButton1.checked:=false; RadioButton2.checked:=false;RadioButton3.checked:=false; RadioButton4.checked:=false; RadioButton5.checked:=false; RadioButton6.checked:=false; RadioButton7.checked:=false;
    RadioButton4.checked:=true;
    AfterRadioButton(BackButtonPressed);
    exit;
  end;

  for i:=0 to length(auxiliaries)-1 do
    if trim(lowercase(auxiliaries[i].name))=trim(lowercase(s)) then
      num:=i;
  if num<>-1 then
  begin
    selAuxiliary:=num;
    RadioButton1.checked:=false; RadioButton2.checked:=false;RadioButton3.checked:=false; RadioButton4.checked:=false; RadioButton5.checked:=false; RadioButton6.checked:=false; RadioButton7.checked:=false;
    RadioButton3.checked:=true;
    AfterRadioButton(BackButtonPressed);
    exit;
  end;

  for i:=0 to length(tracers)-1 do
    if trim(lowercase(tracers[i].name))=trim(lowercase(s)) then
      num:=i;
  if num<>-1 then
  begin
    selTracer:=num;
    RadioButton1.checked:=false; RadioButton2.checked:=false;RadioButton3.checked:=false; RadioButton4.checked:=false; RadioButton5.checked:=false; RadioButton6.checked:=false; RadioButton7.checked:=false;
    RadioButton2.checked:=true;
    AfterRadioButton(BackButtonPressed);
    exit;
  end;

  for i:=0 to length(constants)-1 do
    if trim(lowercase(constants[i].name))=trim(lowercase(s)) then
      num:=i;
  if num<>-1 then
  begin
    selConstant:=num;
    RadioButton1.checked:=false; RadioButton2.checked:=false;RadioButton3.checked:=false; RadioButton4.checked:=false; RadioButton5.checked:=false; RadioButton6.checked:=false; RadioButton7.checked:=false;
    RadioButton1.checked:=true;
    AfterRadioButton(BackButtonPressed);
    exit;
  end;

  for i:=0 to length(celements)-1 do
    if trim(lowercase(celements[i].color+'_'+celements[i].element))=trim(lowercase(s)) then
      num:=i;
  if num<>-1 then
  begin
    selCElement:=num;
    RadioButton1.checked:=false; RadioButton2.checked:=false;RadioButton3.checked:=false; RadioButton4.checked:=false; RadioButton5.checked:=false; RadioButton6.checked:=false; RadioButton7.checked:=false;
    RadioButton6.checked:=true;
    AfterRadioButton(BackButtonPressed);
    exit;
  end;

  if trim(lowercase(s))='modelinfos' then
  begin
    RadioButton1.checked:=false; RadioButton2.checked:=false;RadioButton3.checked:=false; RadioButton4.checked:=false; RadioButton5.checked:=false; RadioButton6.checked:=false; RadioButton7.checked:=false;
    RadioButton6.checked:=true;
    AfterRadioButton(BackButtonPressed);
    exit;
  end;

  end;
end;

procedure TForm1.FormShow(Sender: TObject);
var
  s: String;
begin
  if ShowFirstTime then
  begin
    ShowFirstTime:=false;

    Panel3.Left:=0;
    panel4.Left:=640;
    Panel3.Visible:=false;
    Edit2.Color:=RadioButton1.Color;
    Edit3.Color:=RadioButton2.Color;
    Edit4.Color:=RadioButton3.Color;
    Edit5.Color:=RadioButton4.Color;
    Edit6.Color:=RadioButton5.Color;

    Form6.ShowModal;
    If Form6.ModalResult=1 then
    begin
      If OpenDialog1.Execute then
      begin
        selConstant:=0;
        selTracer:=0;
        selAuxiliary:=0;
        selProcess:=0;
        selElement:=0;
        selCElement:=0;
        LoadAllFiles;
        AfterRadioButton;
      end
      else
        Application.Terminate;
    end
    else if Form6.ModalResult=3 then
    begin
      If SaveDialog1.Execute then
      begin
        OpenDialog1.FileName:=SaveDialog1.FileName;
        SaveAllFiles;
        selConstant:=0;
        selTracer:=0;
        selAuxiliary:=0;
        selProcess:=0;
        selElement:=0;
        selCElement:=0;
        LoadAllFiles;
        AfterRadioButton;
      end
      else
        Application.Terminate;
    end
    else if Form6.ModalResult=4 then
    begin
      OpenDialog1.Title:='Load basic model';
      If OpenDialog1.Execute then
      begin
        selConstant:=0;
        selTracer:=0;
        selAuxiliary:=0;
        selProcess:=0;
        selElement:=0;
        selCElement:=0;
        LoadAllFiles;
        AfterRadioButton;
      end
      else
        Application.Terminate;
      OpenDialog1.Title:='Load first add-on';
      If OpenDialog1.Execute then
      begin
        selConstant:=0;
        selTracer:=0;
        selAuxiliary:=0;
        selProcess:=0;
        selElement:=0;
        selCElement:=0;
        LoadAllFiles(true);
        AfterRadioButton;
        s:=erg_base.FinishLoadingAddOn;
        if s<>'' then ShowMessage(s);
      end
      else
        Application.Terminate;
      while MessageDlg('Do you want to load another add-on?',mtCustom,[mbYes,mbNo],0)=mrYes do
      begin
        OpenDialog1.Title:='Load another add-on';
        If OpenDialog1.Execute then
        begin
          selConstant:=0;
          selTracer:=0;
          selAuxiliary:=0;
          selProcess:=0;
          selElement:=0;
          selCElement:=0;
          LoadAllFiles(true);
          AfterRadioButton;
          s:=erg_base.FinishLoadingAddOn;
        if s<>'' then ShowMessage(s);
        end
        else
          Application.Terminate;
      end;
      MessageDlg('You will now be asked to save the combined model.',mtInformation,[mbOk],0);
//        ShowMessage('You just loaded a basic model an an add-on (or possibly more than one). You will be asked now to save the combined model. All the changes you make will be saved to this combined version, which is a standalone version and not an add-on.'+chr(13)+
//                    'Maybe your plan was to save your changes to the add-on, not to a standalone model. Not a problem - just make your modifications. Afterwards, you can make a new version of the add-on.'+chr(13)+
//                    'To do so, click at "load a set of text files as reference to compare to" and load your original model, without the add-on. Then click "save current version as an add-on". The new version of your add-on will be created then.');
      If SaveDialog1.Execute then
      begin
        OpenDialog1.FileName:=SaveDialog1.FileName;
        SaveAllFiles;
        selConstant:=0;
        selTracer:=0;
        selAuxiliary:=0;
        selProcess:=0;
        selElement:=0;
        selCElement:=0;
        LoadAllFiles;
        AfterRadioButton;
      end
      else
        Application.Terminate;
    end
    else
      Application.Terminate;
  end;
  SynEditBusy:=false;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  SynEditBusy:=true;
  ShowFirstTime:=true;
  ChangedCheck:=false;
  BackList:=TStringList.Create;
  BackListPosition:=-1;
  // create highlighter
  Highlighter:=TSynPositionHighlighter.Create(Self);
  SynEdit1.Highlighter:=Highlighter;
  erg_base.initKeywords;
  SelectedProcessType:='';
end;

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
    DropPosition, StartPosition: Integer;
    DropPoint: TPoint;
  c: tErgConstant;
  e: tErgElement;
  ce: tErgCElement;
  i,j: Integer;
begin
    DropPoint.X := X;
    DropPoint.Y := Y;
    with Source as TListBox do
    begin
      StartPosition := ItemAtPos(StartingPoint,True) ;
      DropPosition := ItemAtPos(DropPoint,True) ;

      if (StartPosition >= 0) and (StartPosition < ListBox1.Items.Count) and
         (DropPosition >= 0) and (DropPosition < ListBox1.Items.Count) then
      begin
        //ShowMessage('move '+IntToStr(StartPosition)+' to '+IntToStr(DropPosition)) ;
        if StartPosition < DropPosition then
        begin
          if RadioButton1.Checked then
          begin
            copyErgConstant(constants[StartPosition],c);
            for j:=StartPosition+1 to DropPosition do
              copyErgConstant(constants[j],constants[j-1]);
            copyErgConstant(c,constants[DropPosition]);
          selConstant:=DropPosition;
          end
          else if RadioButton5.Checked then
          begin
            copyErgElement(elements[StartPosition],e);
            for j:=StartPosition+1 to DropPosition do
              copyErgElement(elements[j],elements[j-1]);
            copyErgElement(e,elements[DropPosition]);
            selElement:=DropPosition;
          end
          else if RadioButton6.Checked then
          begin
            copyErgCElement(CElements[StartPosition],ce);
            for j:=StartPosition+1 to DropPosition do
              copyErgCElement(CElements[j],CElements[j-1]);
            copyErgCElement(ce,CElements[DropPosition]);
            selCElement:=DropPosition;
          end;
        end
        else if StartPosition > DropPosition then
        begin
          if RadioButton1.Checked then
          begin
            copyErgConstant(constants[StartPosition],c);
            for j:=StartPosition-1 downto DropPosition do
              copyErgConstant(constants[j],constants[j+1]);
            copyErgConstant(c,constants[DropPosition]);
            selConstant:=DropPosition;
          end
          else if RadioButton5.Checked then
          begin
            copyErgElement(elements[StartPosition],e);
            for j:=StartPosition-1 downto DropPosition do
              copyErgElement(elements[j],elements[j+1]);
            copyErgElement(e,elements[DropPosition]);
            selElement:=DropPosition;
          end
          else if RadioButton6.Checked then
          begin
            copyErgCElement(CElements[StartPosition],ce);
            for j:=StartPosition-1 downto DropPosition do
              copyErgCElement(CElements[j],CElements[j+1]);
            copyErgCElement(ce,CElements[DropPosition]);
            selCElement:=DropPosition;
          end;
        end;
      end;
      CheckBox3.Checked:=false;
    end;
    SaveAllFiles;
    InconsistencyString:=GenerateIndexes;
    if InconsistencyString<>'' then
      Form1.Panel5.Visible:=true
    else
      Form1.Panel5.Visible:=false;

    AfterRadioButton;
end;

procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept := Source = ListBox1;
end;

procedure TForm1.ListBox1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
    StartingPoint.X := X;
    StartingPoint.Y := Y;
end;

procedure TForm1.Panel6Click(Sender: TObject);
var
  myname, myroot: String;
  mynode: TTreeNode;
  i, j: Integer;
begin
  CheckBox3.Checked:=false;

  Form8.TreeView1.Items.Clear;
  Form8.TreeView1.Items.Add(nil,'all');

  //create the required nodes as defined by the processes
  for i:=0 to length(processes)-1 do
  begin
    mynode:=Form8.TreeView1.Items[0];
    myname:=processes[i].processType;
    //first make sure all parent nodes of the desired node exist
    while pos('/',myname) > 0 do
    begin
      myroot:=copy(myname,1,pos('/',myname)-1);
      myname:=copy(myname,pos('/',myname)+1,length(myname));
      for j:=0 to mynode.Count-1 do
        if lowercase(mynode.Items[j].Text)=lowercase(myroot) then
        begin
          myroot:='';
          mynode:=mynode.Items[j];
          break;  //avoid recursing into child nodes with the same name
        end;
      if myroot<>'' then //root not found
        mynode:=Form8.TreeView1.Items.AddChild(mynode,myroot);
    end;
    //now create child node if necessary
    for j:=0 to mynode.Count-1 do
      if lowercase(mynode.Items[j].Text)=lowercase(myname) then
      begin
        myname:='';
        break;
      end;
    if myname<>'' then //root not found
      Form8.TreeView1.Items.AddChild(mynode,myname);
  end;

  //make sure the root node is expanded
  Form8.TreeView1.Items[0].Expanded:=true;

  //now check if we find the node specified by modelinfos.selectedProcessType, then we expand all parent nodes
  myname:=SelectedProcessType;
  mynode:=Form8.TreeView1.Items[0];
  //first seek all parent nodes
  while (pos('/',myname) > 0) and (mynode<>nil) do
  begin
    myroot:=copy(myname,1,pos('/',myname)-1);
    myname:=copy(myname,pos('/',myname)+1,length(myname));
    for j:=0 to mynode.Count-1 do
      if lowercase(mynode.Items[j].Text)=lowercase(myroot) then
      begin
        myroot:='';
        mynode:=mynode.Items[j];
        break;  //avoid recursing into child nodes with the same name
      end;
    if myroot<>'' then //root not found
      mynode:=nil;
  end;
  //if parent node found, seek for child node
  if (mynode<> nil) then
  begin
    for j:=0 to mynode.Count-1 do
      if lowercase(mynode.Items[j].Text)=lowercase(myname) then
      begin
        myname:='';
        mynode:=mynode.Items[j];
        break;
      end;
    if myname<>'' then //child not found
      mynode:=nil;
  end;
  //if child node found, select it and expand all its parents
  if (mynode<> nil) then
  begin
    Form8.TreeView1.Select(mynode);
    while mynode.Parent <> nil do
    begin
      mynode:=mynode.Parent;
      mynode.Expanded:=true;
    end;
  end;

  //show the form for selection, if closed using OK button, update the selection
  Form8.Tag:=0;
  Form8.ShowModal;
  if Form8.Tag=1 then  //workaround, since modalResult does not work
  begin
    //find selected process type
    SelectedProcessType:='';
    mynode:=Form8.TreeView1.Selected;
    while mynode.Parent <> nil do
    begin
      if SelectedProcessType='' then SelectedProcessType:=mynode.Text else selectedProcessType:=mynode.Text+'/'+SelectedProcessType;
      mynode:=mynode.Parent;
    end;
    //change the look of the button if a filter is selected, or change it back otherwise
    if SelectedProcessType='' then
    begin
      Panel6.Caption:='filter';
      Panel6.Color:=clBtnFace;
      Panel6.Font.Style:=[];
    end
    else
    begin
      Panel6.Caption:='FILTER';
      Panel6.Color:=clRed;
      Panel6.Font.Style:=[fsBold];
    end;
    //change the myIsSelected attribute for the processes
    for i:=0 to length(processes)-1 do
      processes[i].myIsSelected:=false;
    if SelectedProcessType <> '' then
      for i:=0 to length(processes)-1 do
        if (lowercase(processes[i].processType)=lowercase(SelectedProcessType)) //exactly this type selected
           or ( (copy(lowercase(processes[i].processType),1,length(SelectedProcessType))=lowercase(SelectedProcessType))
                and (copy(lowercase(processes[i].processType),length(SelectedProcessType)+1,1)='/') ) //parent type selected
        then
          processes[i].myIsSelected:=true;
    //update it for the constants, auxiliaries and tracers as well
    GenerateIndexes;
    //now fill the arrays selectedConstants, ...
    setLength(selectedConstants,0);
    for i:=0 to length(constants)-1 do
      if constants[i].myIsSelected or (SelectedProcessType='') then
      begin
        setLength(selectedConstants,length(selectedConstants)+1);
        selectedConstants[length(selectedConstants)-1]:=i;
      end;
    setLength(selectedtracers,0);
    for i:=0 to length(tracers)-1 do
      if tracers[i].myIsSelected or (SelectedProcessType='') then
      begin
        setLength(selectedtracers,length(selectedtracers)+1);
        selectedtracers[length(selectedtracers)-1]:=i;
      end;
    setLength(selectedauxiliaries,0);
    for i:=0 to length(auxiliaries)-1 do
      if auxiliaries[i].myIsSelected or (SelectedProcessType='') then
      begin
        setLength(selectedauxiliaries,length(selectedauxiliaries)+1);
        selectedauxiliaries[length(selectedauxiliaries)-1]:=i;
      end;
    setLength(selectedprocesses,0);
    for i:=0 to length(processes)-1 do
      if processes[i].myIsSelected or (SelectedProcessType='') then
      begin
        setLength(selectedprocesses,length(selectedprocesses)+1);
        selectedprocesses[length(selectedprocesses)-1]:=i;
      end;
    //now refill ListBox1 / CheckListBox1
    selConstant:=-1; selTracer:=-1; selAuxiliary:=-1; selProcess:=-1;
    AfterRadioButton;
  end;
end;

procedure TForm1.Panel7Click(Sender: TObject);
var
  i, j: Integer;
begin
  CheckBox3.Checked:=false;

  if (Panel7.Caption='filter') then //nothing selected yet, so select the current tracer
  begin
    if selTracer>=0 then
    begin
      Panel7.Caption:='['+tracers[selTracer].name+']';
      Panel7.Color:=clRed;
      Panel7.Font.Style:=[fsBold];
      CheckBox3.Visible:=false;
      SelectedProcessType:='#MANUAL_SELECTED_BY_TRACER';
      //change the myIsSelected attribute for the processes which contain the currently selected tracer
      for i:=0 to length(processes)-1 do
      begin
        processes[i].myIsSelected:=false;
        for j:=0 to length(processes[i].input)-1 do
          if processes[i].input[j].myTracerNum = selTracer then
            processes[i].myIsSelected:=true;
        for j:=0 to length(processes[i].output)-1 do
          if processes[i].output[j].myTracerNum = selTracer then
            processes[i].myIsSelected:=true;
      end;
    end;
  end
  else
  begin
    Panel7.Caption:='filter';
    Panel7.Color:=clBtnFace;
    Panel7.Font.Style:=[];
    selectedProcessType:='';
  end;
  //update it for the constants, auxiliaries and tracers as well
  GenerateIndexes;
  //now fill the arrays selectedConstants, ...
  setLength(selectedConstants,0);
  for i:=0 to length(constants)-1 do
    if constants[i].myIsSelected or (panel7.Caption='filter') then
    begin
      setLength(selectedConstants,length(selectedConstants)+1);
      selectedConstants[length(selectedConstants)-1]:=i;
    end;
  setLength(selectedtracers,0);
  for i:=0 to length(tracers)-1 do
    if tracers[i].myIsSelected or (panel7.Caption='filter') then
    begin
      setLength(selectedtracers,length(selectedtracers)+1);
      selectedtracers[length(selectedtracers)-1]:=i;
    end;
  setLength(selectedauxiliaries,0);
  for i:=0 to length(auxiliaries)-1 do
    if auxiliaries[i].myIsSelected or (panel7.Caption='filter') then
    begin
      setLength(selectedauxiliaries,length(selectedauxiliaries)+1);
      selectedauxiliaries[length(selectedauxiliaries)-1]:=i;
    end;
  setLength(selectedprocesses,0);
  for i:=0 to length(processes)-1 do
    if processes[i].myIsSelected or (panel7.Caption='filter') then
    begin
      setLength(selectedprocesses,length(selectedprocesses)+1);
      selectedprocesses[length(selectedprocesses)-1]:=i;
    end;
  //now refill ListBox1 / CheckListBox1
  selConstant:=-1; selTracer:=-1; selAuxiliary:=-1; selProcess:=-1;
  AfterRadioButton;
end;

procedure TForm1.RadioButton1Click(Sender: TObject);
begin
  AfterRadioButton;
end;

procedure TForm1.RadioButton2Click(Sender: TObject);
begin
  AfterRadioButton;
end;

procedure TForm1.RadioButton3Click(Sender: TObject);
begin
  AfterRadioButton;
end;

procedure TForm1.RadioButton4Change(Sender: TObject);
begin

end;

procedure TForm1.RadioButton4Click(Sender: TObject);
begin
  AfterRadioButton;
end;

procedure TForm1.RadioButton5Click(Sender: TObject);
begin
  AfterRadioButton;
end;

procedure TForm1.RadioButton6Click(Sender: TObject);
begin
  AfterRadioButton;
end;

procedure TForm1.RadioButton7Click(Sender: TObject);
begin
  AfterRadioButton;
end;

procedure TForm1.ListBox1Click(Sender: TObject);
begin
  MyListBox1Click;
end;

procedure TForm1.CheckListBox1Click(Sender: TObject);
begin
  MyCheckListBox1Click;
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
begin
  Panel3.Visible:=false;
  Panel2.Visible:=true;
  ListBox1Click(sender);
  CheckListBox1Click(sender);
end;

procedure TForm1.Edit2Click(Sender: TObject);
begin
  SynEdit1.SelText:='const';
  SynEdit1.SetFocus;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  F: TextFile;
  i: Integer;
  s: String;
  color, element: String;
begin
  AssignFile(F,TempFileName);
  rewrite(F);
  if (RadioButton6.Checked=false) and (RadioButton7.Checked=false) then
    writeln(F,'name='+Edit1.text);
  if RadioButton6.Checked then
  begin
    writeln(F,'element='+cElements[selectedCElement].element);
    writeln(F,'color='+cElements[selectedCElement].color);
  end;
  writeln(F,SynEdit1.text);
  s:='';
  for i:=0 to Memo1.Lines.Count-1 do
  begin
    if Memo1.Lines[i]<>'' then
    begin
      if i>0 then s:=s+'\\';
      s:=s+Memo1.Lines[i];
    end;
  end;
  if RadioButton2.Checked or RadioButton3.Checked or RadioButton4.Checked then
    if CheckListBox1.Checked[CheckListBox1.ItemIndex] then
      writeln(F,'isOutput=1')
    else
      writeln(F,'isOutput=0');
  writeln(F,'comment='+s);
  closefile(F);

  if RadioButton7.Checked=false then
  begin
    AssignFile(F,TempFileName);
    reset(F);
    if RadioButton1.Checked then //constant selected
    begin
      InitErgConstant(constants[selectedConstant]);
      constants[selectedConstant].name:=Edit1.Text;
      LoadSingleConstant(F);
    end
    else if RadioButton2.Checked then //tracer selected
    begin
      InitErgTracer(Tracers[selectedTracer]);
      Tracers[selectedTracer].name:=Edit1.Text;
      LoadSingleTracer(F);
    end
    else if RadioButton3.Checked then //auxiliary selected
    begin
      InitErgAuxiliary(auxiliaries[selectedAuxiliary]);
      Auxiliaries[selectedAuxiliary].name:=Edit1.Text;
      LoadSingleAuxiliary(F);
    end
    else if RadioButton4.Checked then //process selected
    begin
      InitErgProcess(Processes[selectedProcess]);
      Processes[selectedProcess].name:=Edit1.Text;
      LoadSingleProcess(F);
    end
    else if RadioButton5.Checked then //element selected
    begin
      InitErgElement(Elements[selectedElement]);
      Elements[selectedElement].name:=Edit1.Text;
      LoadSingleElement(F);
    end
    else if RadioButton6.Checked then //colored element selected
    begin
      color:=CElements[selectedCElement].color;
      element:=CElements[selectedCElement].element;
      InitErgCElement(CElements[selectedCElement]);
      CElements[selectedCElement].color:=color;
      CElements[selectedCElement].element:=element;
      LoadSingleCElement(F);
    end;
    closefile(F);
  end
  else
    LoadModelInfos(tempFileName);

  SaveAllFiles;
  LoadAllFiles;

  Panel3.Visible:=false;
  Panel2.Visible:=true;

  AfterRadioButton;
end;

procedure TForm1.CheckBox3Click(Sender: TObject);
begin
  if CheckBox3.Checked then
  begin
    ListBox1.DragMode:=dmAutomatic;
    CheckListBox1.DragMode:=dmAutomatic;
  end
  else
  begin
    ListBox1.DragMode:=dmManual;
    CheckListBox1.DragMode:=dmManual;
  end;
end;

procedure TForm1.CheckListBox1ClickCheck(Sender: TObject);
var i: Integer;
begin
   if RadioButton2.Checked then //tracers
      for i:=0 to length(tracers)-1 do
        if indexOfTracer(i)>=0 then
          if CheckListBox1.Checked[indexOfTracer(i)] then tracers[i].isOutput:=1 else tracers[i].isOutput:=0;
    if RadioButton3.Checked then //auxiliaries
      for i:=0 to length(auxiliaries)-1 do
        if indexOfAuxiliary(i)>=0 then
          if CheckListBox1.Checked[indexOfAuxiliary(i)] then auxiliaries[i].isOutput:=1 else auxiliaries[i].isOutput:=0;
    if RadioButton4.Checked then //processes
      for i:=0 to length(processes)-1 do
        if indexOfProcess(i)>=0 then
          if CheckListBox1.Checked[indexOfProcess(i)] then processes[i].isOutput:=1 else processes[i].isOutput:=0;
    SaveAllFiles;
end;

procedure TForm1.CheckListBox1Exit(Sender: TObject);
begin
end;

procedure TForm1.Memo1Change(Sender: TObject);
begin
  if SynEditBusy=false then
  begin
    Panel2.Visible:=false;
    Panel3.Visible:=true;
    Panel4.Visible:=false;
    Panel5.Visible:=false;
    Button2.Visible:=false;
    Button3.Visible:=false;
  end;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  if BackListPosition>0 then
  begin
    BackListPosition:=BackListPosition-1;
    GoToExpression(BackList[BackListPosition],true);
  end;
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
  if BackListPosition<BackList.Count-1 then
  begin
    BackListPosition:=BackListPosition+1;
    GoToExpression(BackList[BackListPosition],true);
  end;
end;

procedure TForm1.SpeedButton3Click(Sender: TObject);
var
  chosenString, newname, newelement: String;
begin
  if RadioButton1.Checked then chosenString:='constant';
  if RadioButton2.Checked then chosenString:='tracer';
  if RadioButton3.Checked then chosenString:='auxiliary variable';
  if RadioButton4.Checked then chosenString:='process';
  if RadioButton5.Checked then chosenString:='element';
  newname:='new_name';

  if RadioButton6.Checked then
  begin
    newelement:='N';
    newname:='white';
    if InputQuery('new colored element','Please enter the name of the element, e.g. N',newelement) then
      if InputQuery('new colored element','Please enter the name of the color',newname) then
        begin
          SetLength(celements,length(celements)+1);
          selCElement:=length(CElements)-1;
          InitErgCElement(CElements[selCElement]);
          CElements[selCElement].element:=newelement;
          CElements[selCElement].color:=newname;
          SaveAllFiles;
          AfterRadioButton;
        end;
  end
  else
  begin
    if InputQuery('new '+chosenString,'Please enter the name for the new '+chosenString,newname) then
    begin
      newname:=trim(newname);
      //check if name exists might be introduced here

      if RadioButton1.checked then //constant
      begin
        SetLength(constants,length(constants)+1);
        selConstant:=length(constants)-1;
        InitErgConstant(constants[selConstant]);
        constants[selConstant].name:=newname;
        SaveAllFiles;
        AfterRadioButton;
      end;

      if RadioButton2.checked then //tracer
      begin
        SetLength(tracers,length(tracers)+1);
        seltracer:=length(tracers)-1;
        InitErgtracer(tracers[seltracer]);
        tracers[seltracer].name:=newname;
        SaveAllFiles;
        AfterRadioButton;
      end;

      if RadioButton3.checked then //auxiliary
      begin
        SetLength(auxiliaries,length(auxiliaries)+1);
        selauxiliary:=length(auxiliaries)-1;
        InitErgauxiliary(auxiliaries[selauxiliary]);
        auxiliaries[selauxiliary].name:=newname;
        SaveAllFiles;
        AfterRadioButton;
      end;

      if RadioButton4.checked then //process
      begin
        SetLength(processes,length(processes)+1);
        selprocess:=length(processes)-1;
        InitErgprocess(processes[selprocess]);
        processes[selprocess].name:=newname;
        SaveAllFiles;
        AfterRadioButton;
      end;

      if RadioButton5.checked then //element
      begin
        SetLength(elements,length(elements)+1);
        selelement:=length(elements)-1;
        InitErgelement(elements[selelement]);
        elements[selelement].name:=newname;
        SaveAllFiles;
        AfterRadioButton;
      end;

    end;
  end;
end;

procedure TForm1.SpeedButton4Click(Sender: TObject);
var i: Integer;
begin
  if MessageDlg('really delete '+BackList[BackListPosition]+'?',mtConfirmation,[mbYes,mbAbort],0)=mrYes then
  begin
    if RadioButton1.Checked then
    begin
      for i:=selConstant to length(constants)-2 do
        copyErgConstant(constants[i+1],constants[i]);
      setLength(constants,length(constants)-1);
      if selConstant>=length(constants) then selConstant:=length(constants)-1;
    end;
    if RadioButton2.Checked then
    begin
      for i:=seltracer to length(tracers)-2 do
        copyErgtracer(tracers[i+1],tracers[i]);
      setLength(tracers,length(tracers)-1);
      if seltracer>=length(tracers) then seltracer:=length(tracers)-1;
    end;
    if RadioButton3.Checked then
    begin
      for i:=selauxiliary to length(auxiliaries)-2 do
        copyErgauxiliary(auxiliaries[i+1],auxiliaries[i]);
      setLength(auxiliaries,length(auxiliaries)-1);
      if selauxiliary>=length(auxiliaries) then selauxiliary:=length(auxiliaries)-1;
    end;
    if RadioButton4.Checked then
    begin
      for i:=selprocess to length(processes)-2 do
        copyErgprocess(processes[i+1],processes[i]);
      setLength(processes,length(processes)-1);
      if selprocess>=length(processes) then selprocess:=length(processes)-1;
    end;
    if RadioButton5.Checked then
    begin
      for i:=selelement to length(elements)-2 do
        copyErgelement(elements[i+1],elements[i]);
      setLength(elements,length(elements)-1);
      if selelement>=length(elements) then selelement:=length(elements)-1;
    end;
    if RadioButton6.Checked then
    begin
      for i:=selcelement to length(celements)-2 do
        copyErgcelement(celements[i+1],celements[i]);
      setLength(celements,length(celements)-1);
      if selcelement>=length(celements) then selcelement:=length(celements)-1;
    end;
    SaveAllFiles;
    AfterRadioButton;
  end;
end;

procedure TForm1.SpeedButton5Click(Sender: TObject);
var
  c: tErgConstant;
  t: tErgTracer;
  a: tErgAuxiliary;
  p: tErgProcess;
  e: tErgElement;
  ce: tErgCElement;
  i: Integer;
begin
  if ((RadioButton1.Checked or RadioButton5.Checked or RadioButton6.Checked) and (ListBox1.ItemIndex>0)) or
     ((RadioButton2.Checked or RadioButton3.Checked or RadioButton4.Checked) and (CheckListBox1.ItemIndex>0)) then
  begin
    if RadioButton1.Checked then
    begin
      i:=selConstant;
      copyErgConstant(constants[i],c);
      copyErgConstant(constants[i-1],constants[i]);
      copyErgConstant(c,constants[i-1]);
      selConstant:=selConstant-1;
    end;
    if RadioButton2.Checked then
    begin
      i:=seltracer;
      copyErgtracer(tracers[i],t);
      copyErgtracer(tracers[i-1],tracers[i]);
      copyErgtracer(t,tracers[i-1]);
      seltracer:=seltracer-1;
    end;
    if RadioButton3.Checked then
    begin
      i:=selauxiliary;
      copyErgauxiliary(auxiliaries[i],a);
      copyErgauxiliary(auxiliaries[i-1],auxiliaries[i]);
      copyErgauxiliary(a,auxiliaries[i-1]);
      selauxiliary:=selauxiliary-1;
    end;
    if RadioButton4.Checked then
    begin
      i:=selprocess;
      copyErgprocess(processes[i],p);
      copyErgprocess(processes[i-1],processes[i]);
      copyErgprocess(p,processes[i-1]);
      selprocess:=selprocess-1;
    end;
    if RadioButton5.Checked then
    begin
      i:=selelement;
      copyErgelement(elements[i],e);
      copyErgelement(elements[i-1],elements[i]);
      copyErgelement(e,elements[i-1]);
      selelement:=selelement-1;
    end;
    if RadioButton6.Checked then
    begin
      i:=selcelement;
      copyErgcelement(celements[i],ce);
      copyErgcelement(celements[i-1],celements[i]);
      copyErgcelement(ce,celements[i-1]);
      selcelement:=selcelement-1;
    end;
    SaveAllFiles;
    InconsistencyString:=GenerateIndexes;
    if InconsistencyString<>'' then
      Form1.Panel5.Visible:=true
    else
      Form1.Panel5.Visible:=false;

    AfterRadioButton;
  end;
end;

procedure TForm1.SpeedButton6Click(Sender: TObject);
var
  c: tErgConstant;
  t: tErgTracer;
  a: tErgAuxiliary;
  p: tErgProcess;
  e: tErgElement;
  ce: tErgCElement;
  i: Integer;
begin
  if ((RadioButton1.Checked or RadioButton5.Checked or RadioButton6.Checked) and (ListBox1.ItemIndex<ListBox1.Items.Count-1)) or
     ((RadioButton2.Checked or RadioButton3.Checked or RadioButton4.Checked) and (CheckListBox1.ItemIndex<CheckListBox1.Items.Count-1)) then
  begin
    if RadioButton1.Checked then
    begin
      i:=selConstant;
      copyErgConstant(constants[i],c);
      copyErgConstant(constants[i+1],constants[i]);
      copyErgConstant(c,constants[i+1]);
      selConstant:=selConstant+1;
    end;
    if RadioButton2.Checked then
    begin
      i:=seltracer;
      copyErgtracer(tracers[i],t);
      copyErgtracer(tracers[i+1],tracers[i]);
      copyErgtracer(t,tracers[i+1]);
      seltracer:=seltracer+1;
    end;
    if RadioButton3.Checked then
    begin
      i:=selauxiliary;
      copyErgauxiliary(auxiliaries[i],a);
      copyErgauxiliary(auxiliaries[i+1],auxiliaries[i]);
      copyErgauxiliary(a,auxiliaries[i+1]);
      selauxiliary:=selauxiliary+1;
    end;
    if RadioButton4.Checked then
    begin
      i:=selprocess;
      copyErgprocess(processes[i],p);
      copyErgprocess(processes[i+1],processes[i]);
      copyErgprocess(p,processes[i+1]);
      selprocess:=selprocess+1;
    end;
    if RadioButton5.Checked then
    begin
      i:=selelement;
      copyErgelement(elements[i],e);
      copyErgelement(elements[i+1],elements[i]);
      copyErgelement(e,elements[i+1]);
      selelement:=selelement+1;
    end;
    if RadioButton6.Checked then
    begin
      i:=selcelement;
      copyErgcelement(celements[i],ce);
      copyErgcelement(celements[i+1],celements[i]);
      copyErgcelement(ce,celements[i+1]);
      selcelement:=selcelement+1;
    end;
    SaveAllFiles;
    InconsistencyString:=GenerateIndexes;
    if InconsistencyString<>'' then
      Form1.Panel5.Visible:=true
    else
      Form1.Panel5.Visible:=false;

    AfterRadioButton;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  i, j, k: Integer;
  totalSource: Double;
begin
  Form3.Edit1.Text:=Edit1.Text;
  Form3.ListBox1.Items.Clear;
  Form3.ListBox2.Items.Clear;
  if tracers[selTracer].isCombined<>0 then
  begin
    for i:=0 to length(processes)-1 do
    begin
      totalSource:=0.0;
      for j:=0 to length(processes[i].input)-1 do
        for k:=0 to length(tracers[selTracer].contents)-1 do
          if (processes[i].input[j].myTracerNum = tracers[selTracer].contents[k].myElementNum) then
            totalSource:=totalSource-tracers[selTracer].contents[k].myAmount*processes[i].input[j].myAmount;
      for j:=0 to length(processes[i].output)-1 do
        for k:=0 to length(tracers[selTracer].contents)-1 do
          if (processes[i].output[j].myTracerNum = tracers[selTracer].contents[k].myElementNum) then
            totalSource:=totalSource+tracers[selTracer].contents[k].myAmount*processes[i].output[j].myAmount;
      if totalSource>1e-10 then
        Form3.ListBox1.Items.Add(processes[i].name+'          +'+FloatToStr(totalSource));
      if totalSource<-1e-10 then
        Form3.ListBox2.Items.Add(processes[i].name+'          -'+FloatToStr(-totalSource));
    end;
    Form3.ShowModal;
  end
  else
  begin
    for i:=0 to length(processes)-1 do
    begin
      totalSource:=0.0;
      for j:=0 to length(processes[i].input)-1 do
      begin
        if tracers[selTracer].dimension<=1 then
          if (trim(lowercase(processes[i].input[j].tracer)) = lowercase(edit1.Text)) then
            totalSource:=totalSource-processes[i].input[j].myamount;
        if tracers[selTracer].dimension>1 then
        begin
          if pos(lowercase(edit1.Text)+'_$',trim(lowercase(processes[i].input[j].tracer)))=1 then
            totalSource:=totalSource-processes[i].input[j].myamount;
          for k:=1 to tracers[selTracer].dimension do
            if (trim(lowercase(processes[i].input[j].tracer)) = lowercase(edit1.Text)+'_'+IntToStr(k)) then
              totalSource:=totalSource-processes[i].input[j].myamount;
        end;
      end;
      for j:=0 to length(processes[i].output)-1 do
      begin
        if tracers[selTracer].dimension<=1 then
          if (trim(lowercase(processes[i].output[j].tracer)) = lowercase(edit1.Text)) then
            totalSource:=totalSource+processes[i].output[j].myamount;
        if tracers[selTracer].dimension>1 then
        begin
          if pos(lowercase(edit1.Text)+'_$',trim(lowercase(processes[i].output[j].tracer)))=1 then
            totalSource:=totalSource+processes[i].output[j].myamount;
          for k:=1 to tracers[selTracer].dimension do
            if (trim(lowercase(processes[i].output[j].tracer)) = lowercase(edit1.Text)+'_'+IntToStr(k)) then
              totalSource:=totalSource+processes[i].output[j].myamount;
        end;
      end;
      if totalSource>1e-10 then
        Form3.ListBox1.Items.Add(processes[i].name+'          +'+FloatToStr(totalSource));
      if totalSource<-1e-10 then
        Form3.ListBox2.Items.Add(processes[i].name+'          -'+FloatToStr(-totalSource));
    end;
    Form3.ShowModal;
  end;
end;

procedure TForm1.SynEdit1Change(Sender: TObject);
begin
  if SynEditBusy=false then
  begin
    Panel2.Visible:=false;
    Panel3.Visible:=true;
    Panel4.Visible:=false;
    Panel5.Visible:=false;
    Button2.Visible:=false;
    Button3.Visible:=false;
    PaintTheWords;
  end;
end;

procedure TForm1.SynEdit1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  myword: String;
  found: Boolean;
  i: Integer;
  x1,y1: Integer;
begin
  if Button=mbRight then
  begin
    x1:=SynEdit1.PixelsToRowColumn(point(x,y)).X;
    y1:=SynEdit1.PixelsToRowColumn(point(x,y)).Y;
    myword:=SynEdit1.GetWordAtRowCol(point(x1,y1));
    found:=false;
    for i:=0 to length(keywords)-1 do
      if myword=keywords[i] then
      begin
        ShowMessage(keywords[i]+chr(13)+keywordDescriptions[i]);
        found:=true;
      end;
    if not found then
      if Panel3.Visible=false then
        GoToExpression(myword);
  end;
end;

procedure renameInString(oldName,newName: String; var myString: String);
var
  i: Integer;
  standsAlone: Boolean;
  s: String;
begin
  i:=1;
  while i <= length(myString)-length(oldName)+1 do
  begin
    if lowercase(copy(myString,i,length(oldName))) = lowercase(oldname) then
    begin
      standsAlone:=true;
      if i>1 then
      begin
        s:=copy(myString,i-1,1);
        if IsStandardChar(s[1]) then standsAlone:=false;
      end;
      if i < length(myString)-length(oldName)+1 then
      begin
        s:=copy(myString,i+length(oldName),1);
        if IsStandardChar(s[1]) then standsAlone:=false;
      end;
      if standsAlone then
      begin
        myString:=copy(myString,1,i-1)+newName+copy(myString,i+length(oldName),length(myString));
        i:=i+length(newName)-1;
      end;
    end;
    i:=i+1;
  end;
end;

function ContainedInString(oldName: String; aString: String):Boolean;
var
  i: Integer;
  standsAlone: Boolean;
  s, mystring: String;
begin
  result:=false;
  myString:=aString;
  i:=1;
  while i <= length(myString)-length(oldName)+1 do
  begin
    if lowercase(copy(myString,i,length(oldName))) = lowercase(oldname) then
    begin
      standsAlone:=true;
      if i>1 then
      begin
        s:=copy(myString,i-1,1);
        if IsStandardChar(s[1]) then standsAlone:=false;
      end;
      if i < length(myString)-length(oldName)+1 then
      begin
        s:=copy(myString,i+length(oldName),1);
        if IsStandardChar(s[1]) then standsAlone:=false;
      end;
      if standsAlone then
      begin
        myString:=copy(myString,1,i-1)+oldName+copy(myString,i+length(oldName),length(myString));
        i:=i+length(oldName)-1;
        result:=true;
      end;
    end;
    i:=i+1;
  end;
end;

function WhatIsTheName(name:String):String;
//returns 'a tracer' if name exists as a tracer, 'an element' if name exists as an element, ...
//returns '' if tracer does not exist
var
  i: Integer;
begin
  result:='';
  for i:=0 to length(constants)-1 do
    if lowercase(name)=lowercase(constants[i].name) then result:='a constant';
  for i:=0 to length(tracers)-1 do
    if lowercase(name)=lowercase(tracers[i].name) then result:='a tracer';
  for i:=0 to length(auxiliaries)-1 do
    if lowercase(name)=lowercase(auxiliaries[i].name) then result:='an auxiliary variable';
  for i:=0 to length(processes)-1 do
    if lowercase(name)=lowercase(processes[i].name) then result:='a process';
  for i:=0 to length(elements)-1 do
    if lowercase(name)=lowercase(elements[i].name) then result:='an element';
  for i:=0 to length(celements)-1 do
    if lowercase(name)=lowercase(celements[i].color+'_'+celements[i].element) then result:='a colored element';
end;

procedure renameInTextfiles(oldName,newName: String);
var
  i, j: Integer;
begin
  for i:=0 to length(constants)-1 do
  begin
    renameInString(oldName,newName,constants[i].name);
  end;
  for i:=0 to length(tracers)-1 do
  begin
    renameInString(oldName,newName,tracers[i].name);
    for j:=0 to length(tracers[i].contents)-1 do
    begin
      renameInString(oldName,newName,tracers[i].contents[j].element);
      renameInString(oldName,newName,tracers[i].contents[j].amount);
    end;
    renameInString(oldName,newName,tracers[i].vertSpeed);
    renameInString(oldName,newName,tracers[i].vertDiff);
    renameInString(oldName,newName,tracers[i].opacity);
    renameInString(oldName,newName,tracers[i].childOf);
    renameInString(oldName,newName,tracers[i].massLimits);
    renameInString(oldName,newName,tracers[i].schmidtNumber);
    renameInString(oldName,newName,tracers[i].solubility);
  end;
  for i:=0 to length(auxiliaries)-1 do
  begin
    renameInString(oldName,newName,auxiliaries[i].name);
    renameInString(oldName,newName,auxiliaries[i].formula);
    for j:=1 to 9 do
      renameInString(oldName,newName,auxiliaries[i].temp[j]);
  end;
  for i:=0 to length(processes)-1 do
  begin
    renameInString(oldName,newName,processes[i].name);
    renameInString(oldName,newName,processes[i].turnover);
    for j:=0 to length(processes[i].input)-1 do
    begin
      renameInString(oldName,newName,processes[i].input[j].tracer);
      renameInString(oldName,newName,processes[i].input[j].amount);
    end;
    for j:=0 to length(processes[i].output)-1 do
    begin
      renameInString(oldName,newName,processes[i].output[j].tracer);
      renameInString(oldName,newName,processes[i].output[j].amount);
    end;
    for j:=0 to length(processes[i].limitations)-1 do
    begin
      renameInString(oldName,newName,processes[i].limitations[j].elseProcess);
      renameInString(oldName,newName,limitations[processes[i].limitations[j].limitationNum].tracer);
      renameInString(oldName,newName,limitations[processes[i].limitations[j].limitationNum].value);
    end;
  end;
  for i:=0 to length(elements)-1 do
  begin
    renameInString(oldName,newName,elements[i].name);
  end;
  for i:=0 to length(celements)-1 do
  begin
    renameInString(oldName,newName,celements[i].element);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  oldName, newName: String;
begin
  oldName:=Edit1.Text;
  newName:=InputBox('rename '+Edit1.text,'Enter a new name for the '+Label3.Caption+' '+Edit1.Text,Edit1.Text);
  if newName <> oldName then
  begin
    if WhatIsTheName(newName)='' then
    begin
      renameInTextfiles(oldName,newName);
      SaveAllFiles;
      GoToExpression(newName);
    end
    else
      ShowMessage('Cannot rename '+oldName+' to '+newName+': '+chr(13)+chr(13)+newName+' is already the name of '+WhatIsTheName(newName)+'.');
  end;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  Form4.Caption := processes[selectedProcess].name+' - checking element conservation';
  Unit4.oldEquation:=GetInputOutputEquation(processes[Form1.CheckListBox1.ItemIndex]);
  Form4.Edit1.Text:=Unit4.oldEquation;
  Unit4.processNum:=Form1.CheckListBox1.ItemIndex;
  Unit4.InitStringGrid;
  Form1.Visible:=false;
  Form4.ShowModal;
  Form1.Visible:=true;
  LoadAllFiles;
  GoToExpression(processes[selectedProcess].name);
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
  ShowMessage(InconsistencyString);
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
  if Edit8.Color <> clWhite then
  begin
    GoToExpression(Edit8.Text);
    Edit8.Text:='';
    Edit8.Color:=clWhite;
  end;
end;

procedure TForm1.Button7Click(Sender: TObject);
var
  s: String;
begin
  s:=CheckAuxiliaryOrder;
  if s='' then
    ShowMessage('All is fine - all auxiliary variables are already sorted in a correct way.')
  else
  begin
    ShowMessage(s);
    if pos('calculated in the wrong order',s)>0 then
    begin
      if MessageDlg('Do you want cgt_edit to automatically sort the auxiliary variables, such that they are calculated in a correct order?'
                    +chr(13)+'Note that the even if it is correct, a new sorting may be somewhat random. To avoid this, click ''no'' and sort manually by using the checkbox ''move'' below the list of auxiliaries.',mtConfirmation,[mbYes,mbNo],0)=mrYes then
      begin
        sortAuxiliaries;
        SaveAllFiles;
        s:=CheckAuxiliaryOrder;
        if s<>'' then
          ShowMessage('Still, some problems remain:'+chr(13)+chr(13)+s);
      end;
    end;
  end;
  AfterRadioButton;
end;

procedure TForm1.Button9Click(Sender: TObject);
var
  myform: newform;
  mymemo: TMemo;
  mylabel: TLabel;
  mylabel2: TLabel;
  myedit: TEdit;
  myBitBtn: TBitBtn;
  i: Integer;
begin
  myform:=newform.CreateNew(self);
  //myform.Parent:=nil;
  //myform.ParentWindow:=GetDesktopWindow;
  //myform.FormStyle:=fsNormal;

  myform.Width:=SynEdit1.Width+32;
  myform.Height:=SynEdit1.Height+132;
  myform.Top:=Form1.Top+32;
  myform.Left:=Form1.Left+SynEdit1.Left+32;
  myform.Caption:=Form1.Caption+' - '+Edit1.Text;
  myform.Color:=clBtnFace;

  mymemo:=TMemo.Create(myform);
  mymemo.Parent:=myform;
  mymemo.Left:=16;
  mymemo.Top:=SynEdit1.Top;
  mymemo.Width:=myform.ClientWidth-32;
  mymemo.Height:=myform.ClientHeight-SynEdit1.Top-48;
  mymemo.Anchors:=[akLeft,akRight,akTop,akBottom];
  mymemo.ReadOnly:=true;
  mymemo.Lines.AddStrings(SynEdit1.Lines);
  mymemo.Font:=SynEdit1.Font;

  mylabel:=TLabel.Create(myform);
  mylabel.parent:=myform;
  mylabel.Caption:=Label3.Caption;
  mylabel.Left:=16;
  mylabel.Top:=Label3.top;

  myEdit:=TEdit.Create(myform);
  myEdit.parent:=myform;
  myEdit.Text:=Edit1.Text;
  myEdit.Left:=16;
  myEdit.Top:=Edit1.Top;
  myEdit.Width:=Edit1.Width;
  myEdit.Height:=Edit1.Height;
  myEdit.Font:=Edit1.Font;
  myEdit.Color:=Edit1.Color;
  myEdit.ReadOnly:=true;

  mylabel2:=TLabel.Create(myform);
  mylabel2.parent:=myform;
  mylabel2.Caption:=' as it was at '+TimeToStr(now);
  mylabel2.Left:=myedit.Left+myedit.Width+16;
  mylabel2.Top:=myedit.Top+6;

  myBitBtn:=TBitBtn.Create(myform);
  myBitBtn.Parent:=myform;
  myBitBtn.Top:=myform.ClientHeight-40;
  myBitBtn.Height:=32;
  myBitBtn.Left:=myform.ClientWidth-88;
  myBitBtn.Width:=72;
  myBitBtn.Kind:=bkOK;
  myBitBtn.Anchors:=[akRight,akBottom];
  myBitBtn.OnClick:=myform.formclose;

  myform.Show;
end;

procedure TForm1.Edit8Change(Sender: TObject);
var
  i: Integer;
  mycolor: Integer;
begin
  mycolor:=clWhite;
  for i:=0 to length(constants)-1 do
    if lowercase(Edit8.Text)=lowercase(constants[i].name) then mycolor:=RadioButton1.Color;
  for i:=0 to length(tracers)-1 do
    if lowercase(Edit8.Text)=lowercase(tracers[i].name) then mycolor:=RadioButton2.Color;
  for i:=0 to length(auxiliaries)-1 do
    if lowercase(Edit8.Text)=lowercase(auxiliaries[i].name) then mycolor:=RadioButton3.Color;
  for i:=0 to length(processes)-1 do
    if lowercase(Edit8.Text)=lowercase(processes[i].name) then mycolor:=RadioButton4.Color;
  for i:=0 to length(elements)-1 do
    if lowercase(Edit8.Text)=lowercase(elements[i].name) then mycolor:=RadioButton5.Color;
  Edit8.Color:=mycolor;
end;

procedure TForm1.Edit8KeyPress(Sender: TObject; var Key: char);
begin
  if key=chr(13) then
  begin
    Button6click(self);
    key:=chr(0);
  end;
end;

procedure TForm1.CheckBox2Click(Sender: TObject);
begin
  AfterRadioButton;
  if CheckBox2.Checked then
  begin
    SynEdit1.Color:=clSilver;
    SynEdit1.Enabled:=false;
    Memo1.Color:=clSilver;
    Memo1.Enabled:=false;
  end
  else
  begin
    SynEdit1.Color:=clWhite;
    SynEdit1.Enabled:=true;
    Memo1.Color:=clWhite;
    Memo1.Enabled:=true;
  end;
end;

procedure TForm1.CheckListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
    DropPosition, StartPosition: Integer;
    DropPoint: TPoint;
  t: tErgTracer;
  a: tErgAuxiliary;
  p: tErgProcess;
  i,j: Integer;
begin
    DropPoint.X := X;
    DropPoint.Y := Y;
    with Source as TCheckListBox do
    begin
      StartPosition := ItemAtPos(StartingPoint,True) ;
      DropPosition := ItemAtPos(DropPoint,True) ;

      if (StartPosition >= 0) and (StartPosition < CheckListBox1.Items.Count) and
         (DropPosition >= 0) and (DropPosition < CheckListBox1.Items.Count) then
      begin
        //ShowMessage('move '+IntToStr(StartPosition)+' to '+IntToStr(DropPosition)) ;
        if StartPosition < DropPosition then
        begin
          if RadioButton2.Checked then
          begin
            copyErgTracer(tracers[StartPosition],t);
            for j:=StartPosition+1 to DropPosition do
              copyErgTracer(tracers[j],tracers[j-1]);
            copyErgTracer(t,tracers[DropPosition]);
            selTracer:=DropPosition;
          end
          else if RadioButton3.Checked then
          begin
            copyErgAuxiliary(auxiliaries[StartPosition],a);
            for j:=StartPosition+1 to DropPosition do
              copyErgAuxiliary(auxiliaries[j],auxiliaries[j-1]);
            copyErgAuxiliary(a,auxiliaries[DropPosition]);
            selAuxiliary:=DropPosition;
          end
          else if RadioButton4.Checked then
          begin
            copyErgProcess(processes[StartPosition],p);
            for j:=StartPosition+1 to DropPosition do
              copyErgProcess(processes[j],processes[j-1]);
            copyErgProcess(p,processes[DropPosition]);
            selProcess:=DropPosition;
          end;
        end
        else if StartPosition > DropPosition then
        begin
          if RadioButton2.Checked then
          begin
            copyErgTracer(tracers[StartPosition],t);
            for j:=StartPosition-1 downto DropPosition do
              copyErgTracer(tracers[j],tracers[j+1]);
            copyErgTracer(t,tracers[DropPosition]);
            selTracer:=DropPosition;
          end
          else if RadioButton3.Checked then
          begin
            copyErgAuxiliary(auxiliaries[StartPosition],a);
            for j:=StartPosition-1 downto DropPosition do
              copyErgAuxiliary(auxiliaries[j],auxiliaries[j+1]);
            copyErgAuxiliary(a,auxiliaries[DropPosition]);
            selAuxiliary:=DropPosition;
          end
          else if RadioButton4.Checked then
          begin
            copyErgProcess(processes[StartPosition],p);
            for j:=StartPosition-1 downto DropPosition do
              copyErgProcess(processes[j],processes[j+1]);
            copyErgProcess(p,processes[DropPosition]);
            selProcess:=DropPosition;
          end;
        end;
      end;
      CheckBox3.Checked:=false;
    end;
    SaveAllFiles;
    InconsistencyString:=GenerateIndexes;
    if InconsistencyString<>'' then
      Form1.Panel5.Visible:=true
    else
      Form1.Panel5.Visible:=false;

    AfterRadioButton;
end;

procedure TForm1.CheckListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
    Accept := Source = CheckListBox1;
end;

procedure TForm1.CheckListBox1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
    StartingPoint.X := X;
    StartingPoint.Y := Y;
end;

procedure SaveConstantsAddOn(filename: String);
var F: TextFile;
    i, j: Integer;
    compareResult: String;
    found: Boolean;
begin
  DecimalSeparator:='.';
  AssignFile(F,FileName);
  rewrite(F);
    WriteConstantsHeader(F);
    for i:=0 to length(Constants)-1 do
    begin
      compareResult:=WhatHasChangedConstant(i);
      if compareResult='yes' then
      begin
        SaveSingleConstantRef(F,i,OriginalConstant(i),false);
        writeln(F,'***********************');
      end
      else if compareResult='new' then
      begin
        SaveSingleConstant(F,i);
        writeln(F,'***********************');
      end
      else if compareResult='desc/comm' then
      begin
        SaveSingleConstantRef(F,i,OriginalConstant(i),false);
        writeln(F,'***********************');
      end;
    end;
    for i:=0 to length(ref_Constants)-1 do
    begin
      found:=false;
      for j:=0 to length(Constants)-1 do
        if trim(lowercase(Constants[j].name))=trim(lowercase(ref_Constants[i].name)) then found:=true;
      if not found then
      begin
        writeln(F,'name=delete_in_add_on_'+trim(lowercase(ref_Constants[i].name)));
        writeln(F,'***********************');
      end;
    end;
  closefile(F);
end;

procedure SaveTracersAddOn(filename: String);
var F: TextFile;
    i, j: Integer;
    compareResult: String;
    found: Boolean;
begin
  DecimalSeparator:='.';
  AssignFile(F,FileName);
  rewrite(F);
    WriteTracersHeader(F);
    for i:=0 to length(Tracers)-1 do
    begin
      compareResult:=WhatHasChangedTracer(i);
      if compareResult='yes' then
      begin
        SaveSingleTracerRef(F,i,OriginalTracer(i),false);
        writeln(F,'***********************');
      end
      else if compareResult='new' then
      begin
        SaveSingleTracer(F,i);
        writeln(F,'***********************');
      end
      else if compareResult='desc/comm' then
      begin
        SaveSingleTracerRef(F,i,OriginalTracer(i),false);
        writeln(F,'***********************');
      end;
    end;
    for i:=0 to length(ref_tracers)-1 do
    begin
      found:=false;
      for j:=0 to length(tracers)-1 do
        if trim(lowercase(tracers[j].name))=trim(lowercase(ref_tracers[i].name)) then found:=true;
      if not found then
      begin
        writeln(F,'name=delete_in_add_on_'+trim(lowercase(ref_tracers[i].name)));
        writeln(F,'***********************');
      end;
    end;
  closefile(F);
end;

procedure SaveAuxiliariesAddOn(filename: String);
var F: TextFile;
    i, j: Integer;
    compareResult: String;
    found: Boolean;
begin
  DecimalSeparator:='.';
  AssignFile(F,FileName);
  rewrite(F);
    WriteAuxiliariesHeader(F);
    for i:=0 to length(Auxiliaries)-1 do
    begin
      compareResult:=WhatHasChangedAuxiliary(i);
      if compareResult='yes' then
      begin
        SaveSingleAuxiliaryRef(F,i,OriginalAuxiliary(i),false);
        writeln(F,'***********************');
      end
      else if compareResult='new' then
      begin
        SaveSingleAuxiliary(F,i);
        writeln(F,'***********************');
      end
      else if compareResult='desc/comm' then
      begin
        SaveSingleAuxiliaryRef(F,i,OriginalAuxiliary(i),false);
        writeln(F,'***********************');
      end;
    end;
    for i:=0 to length(ref_Auxiliaries)-1 do
    begin
      found:=false;
      for j:=0 to length(Auxiliaries)-1 do
        if trim(lowercase(Auxiliaries[j].name))=trim(lowercase(ref_Auxiliaries[i].name)) then found:=true;
      if not found then
      begin
        writeln(F,'name=delete_in_add_on_'+trim(lowercase(ref_Auxiliaries[i].name)));
        writeln(F,'***********************');
      end;
    end;
  closefile(F);
end;

procedure SaveProcessesAddOn(filename: String);
var F: TextFile;
    i, j: Integer;
    compareResult: String;
    found: Boolean;
begin
  DecimalSeparator:='.';
  AssignFile(F,FileName);
  rewrite(F);
    WriteProcessesHeader(F);
    for i:=0 to length(Processes)-1 do
    begin
      compareResult:=WhatHasChangedProcess(i);
      if compareResult='yes' then
      begin
        SaveSingleProcessRef(F,i,OriginalProcess(i),ref_limitations,false);
        writeln(F,'***********************');
      end
      else if compareResult='new' then
      begin
        SaveSingleProcess(F,i);
        writeln(F,'***********************');
      end
      else if compareResult='desc/comm' then
      begin
        SaveSingleProcessRef(F,i,OriginalProcess(i),ref_limitations,false);
        writeln(F,'***********************');
      end;
    end;
    for i:=0 to length(ref_Processes)-1 do
    begin
      found:=false;
      for j:=0 to length(Processes)-1 do
        if trim(lowercase(Processes[j].name))=trim(lowercase(ref_Processes[i].name)) then found:=true;
      if not found then
      begin
        writeln(F,'name=delete_in_add_on_'+trim(lowercase(ref_Processes[i].name)));
        writeln(F,'***********************');
      end;
    end;
  closefile(F);
end;

procedure SaveElementsAddOn(filename: String);
var F: TextFile;
    i, j: Integer;
    compareResult: String;
    found: Boolean;
begin
  DecimalSeparator:='.';
  AssignFile(F,FileName);
  rewrite(F);
    WriteElementsHeader(F);
    for i:=0 to length(Elements)-1 do
    begin
      compareResult:=WhatHasChangedElement(i);
      if compareResult='yes' then
      begin
        SaveSingleElementRef(F,i,OriginalElement(i),false);
        writeln(F,'***********************');
      end
      else if compareResult='new' then
      begin
        SaveSingleElement(F,i);
        writeln(F,'***********************');
      end
      else if compareResult='desc/comm' then
      begin
        SaveSingleElementRef(F,i,OriginalElement(i),false);
        writeln(F,'***********************');
      end;
    end;
    for i:=0 to length(ref_Elements)-1 do
    begin
      found:=false;
      for j:=0 to length(Elements)-1 do
        if trim(lowercase(Elements[j].name))=trim(lowercase(ref_Elements[i].name)) then found:=true;
      if not found then
      begin
        writeln(F,'name=delete_in_add_on_'+trim(lowercase(ref_Elements[i].name)));
        writeln(F,'***********************');
      end;
    end;
  closefile(F);
end;

procedure SaveCElementsAddOn(filename: String);
var F: TextFile;
    i, j: Integer;
    compareResult: String;
    found: Boolean;
begin
  DecimalSeparator:='.';
  AssignFile(F,FileName);
  rewrite(F);
    WriteCElementsHeader(F);
    for i:=0 to length(CElements)-1 do
    begin
      compareResult:=WhatHasChangedCElement(i);
      if compareResult='yes' then
      begin
        SaveSingleCElementRef(F,i,OriginalCElement(i),false);
        writeln(F,'***********************');
      end
      else if compareResult='new' then
      begin
        SaveSingleCElement(F,i);
        writeln(F,'***********************');
      end
      else if compareResult='desc/comm' then
      begin
        SaveSingleCElementRef(F,i,OriginalCElement(i),false);
        writeln(F,'***********************');
      end;
    end;
    for i:=0 to length(ref_CElements)-1 do
    begin
      found:=false;
      for j:=0 to length(CElements)-1 do
        if (trim(lowercase(CElements[j].element))=trim(lowercase(ref_CElements[i].element))) and
           (trim(lowercase(CElements[j].color))=trim(lowercase(ref_CElements[i].color))) then found:=true;
      if not found then
      begin
        writeln(F,'color=delete_in_add_on_'+trim(lowercase(ref_CElements[i].color)));
        writeln(F,'element='+trim(lowercase(ref_CElements[i].element)));
        writeln(F,'***********************');
      end;
    end;
  closefile(F);
end;

procedure SaveAllFilesAddOn;
var
  s: String;
begin
  s:=ExtractFilePath(Form1.SaveDialog1.FileName);
    SaveModelInfos(s+'modelinfos.txt');
    SaveConstantsAddOn(s+'constants.txt');
    SaveElementsAddOn(s+'elements.txt');
    SaveTracersAddOn(s+'tracers.txt');
    SaveAuxiliariesAddOn(s+'auxiliaries.txt');
    SaveProcessesAddOn(s+'processes.txt');
    SaveCElementsAddOn(s+'celements.txt');
end;

procedure TForm1.Button8Click(Sender: TObject);
var
  F: TextFile;
  i, j, llim: Integer;
  s: String;
begin
    AssignFile(F,TempFileName);
    rewrite(F);
    if RadioButton1.Checked then //constant selected
    begin
      for i:=0 to length(ref_constants)-1 do
        if lowercase(ref_constants[i].name)=lowercase(Edit1.Text) then
        begin
          setLength(constants, length(constants)+1);
          copyErgConstant(ref_constants[i],constants[length(constants)-1]);
          SaveSingleConstant(F,length(constants)-1);
          setLength(constants,length(constants)-1);
          break;
        end;
    end
    else if RadioButton2.Checked then //tracer selected
    begin
      for i:=0 to length(ref_Tracers)-1 do
        if lowercase(ref_Tracers[i].name)=lowercase(Edit1.Text) then
        begin
          setLength(Tracers, length(Tracers)+1);
          copyErgTracer(ref_Tracers[i],Tracers[length(Tracers)-1]);
          SaveSingleTracer(F,length(Tracers)-1);
          setLength(Tracers,length(Tracers)-1);
          break;
        end;
    end
    else if RadioButton3.Checked then //auxiliary selected
    begin
      for i:=0 to length(ref_Auxiliaries)-1 do
        if lowercase(ref_Auxiliaries[i].name)=lowercase(Edit1.Text) then
        begin
          setLength(Auxiliaries, length(Auxiliaries)+1);
          copyErgAuxiliary(ref_Auxiliaries[i],Auxiliaries[length(Auxiliaries)-1]);
          SaveSingleAuxiliary(F,length(Auxiliaries)-1);
          setLength(Auxiliaries,length(Auxiliaries)-1);
          break;
        end;
    end
    else if RadioButton4.Checked then //process selected
    begin
      for i:=0 to length(ref_Processes)-1 do
        if lowercase(ref_Processes[i].name)=lowercase(Edit1.Text) then
        begin
          setLength(Processes, length(Processes)+1);
          copyErgProcess(ref_Processes[i],Processes[length(Processes)-1]);
          llim:=length(limitations);
          setLength(limitations,llim+length(ref_limitations));
          for j:=llim-1 downto 0 do
            limitations[j+length(ref_limitations)]:=limitations[j];
          for j:=0 to length(ref_limitations)-1 do
            limitations[j]:=ref_limitations[j];
          SaveSingleProcess(F,length(Processes)-1);
          setLength(Processes,length(Processes)-1);
          for j:=0 to llim-1 do
            limitations[j]:=limitations[j+length(ref_limitations)];
          setLength(limitations,llim);
          break;
        end;
    end
    else if RadioButton5.Checked then //element selected
    begin
      for i:=0 to length(ref_Elements)-1 do
        if lowercase(ref_Elements[i].name)=lowercase(Edit1.Text) then
        begin
          setLength(Elements, length(Elements)+1);
          copyErgElement(ref_Elements[i],Elements[length(Elements)-1]);
          SaveSingleElement(F,length(Elements)-1);
          setLength(Elements,length(Elements)-1);
          break;
        end;
    end
    else if RadioButton6.Checked then //colored element selected
    begin
      for i:=0 to length(ref_CElements)-1 do
        if lowercase(ref_CElements[i].color)+'_'+lowercase(ref_CElements[i].element)=lowercase(Edit1.Text) then
        begin
          setLength(CElements, length(CElements)+1);
          copyErgCElement(ref_CElements[i],CElements[length(CElements)-1]);
          SaveSingleCElement(F,length(CElements)-1);
          setLength(CElements,length(CElements)-1);
          break;
        end;
    end;
    closefile(F);
    Form5.Memo1.Clear;
    AssignFile(F,TempFileName);
    reset(F);
    while not EOF(F) do
    begin
      readln(F,s);
      Form5.Memo1.Lines.Add(s);
    end;
    closefile(F);
    Form5.ShowModal;
end;

procedure TForm1.CheckBox2Change(Sender: TObject);
begin

end;

procedure TForm1.Button11Click(Sender: TObject);
var
  s: String;
  i, j: Integer;
  found: Boolean;
begin
    Form5.Memo1.Clear;
    if RadioButton1.Checked then //constant selected
    begin
      for i:=0 to length(ref_constants)-1 do
      begin
        found:=false;
        for j:=0 to length(constants)-1 do
          if lowercase(ref_constants[i].name)=lowercase(constants[j].name) then
          begin
            found:=true;
            break;
          end;
        if not found then
        begin
          s:=ref_constants[i].name;
          while length(s)<20 do s:=s+' ';
          s:=s+' ('+ref_constants[i].description+')';
          Form5.Memo1.Lines.Add(s);
        end;
      end;
    end
    else if RadioButton2.Checked then //tracer selected
    begin
      for i:=0 to length(ref_Tracers)-1 do
      begin
        found:=false;
        for j:=0 to length(Tracers)-1 do
          if lowercase(ref_Tracers[i].name)=lowercase(Tracers[j].name) then
          begin
            found:=true;
            break;
          end;
        if not found then
        begin
          s:=ref_Tracers[i].name;
          while length(s)<20 do s:=s+' ';
          s:=s+' ('+ref_Tracers[i].description+')';
          Form5.Memo1.Lines.Add(s);
        end;
      end;
    end
    else if RadioButton3.Checked then //auxiliary selected
    begin
      for i:=0 to length(ref_Auxiliaries)-1 do
      begin
        found:=false;
        for j:=0 to length(Auxiliaries)-1 do
          if lowercase(ref_Auxiliaries[i].name)=lowercase(Auxiliaries[j].name) then
          begin
            found:=true;
            break;
          end;
        if not found then
        begin
          s:=ref_Auxiliaries[i].name;
          while length(s)<20 do s:=s+' ';
          s:=s+' ('+ref_Auxiliaries[i].description+')';
          Form5.Memo1.Lines.Add(s);
        end;
      end;
    end
    else if RadioButton4.Checked then //process selected
    begin
      for i:=0 to length(ref_Processes)-1 do
      begin
        found:=false;
        for j:=0 to length(Processes)-1 do
          if lowercase(ref_Processes[i].name)=lowercase(Processes[j].name) then
          begin
            found:=true;
            break;
          end;
        if not found then
        begin
          s:=ref_Processes[i].name;
          while length(s)<20 do s:=s+' ';
          s:=s+' ('+ref_Processes[i].description+')';
          Form5.Memo1.Lines.Add(s);
        end;
      end;
    end
    else if RadioButton5.Checked then //element selected
    begin
      for i:=0 to length(ref_Elements)-1 do
      begin
        found:=false;
        for j:=0 to length(Elements)-1 do
          if lowercase(ref_Elements[i].name)=lowercase(Elements[j].name) then
          begin
            found:=true;
            break;
          end;
        if not found then
        begin
          s:=ref_Elements[i].name;
          while length(s)<20 do s:=s+' ';
          s:=s+' ('+ref_Elements[i].description+')';
          Form5.Memo1.Lines.Add(s);
        end;
      end;
    end
    else if RadioButton6.Checked then //colored element selected
    begin
      for i:=0 to length(ref_CElements)-1 do
      begin
        found:=false;
        for j:=0 to length(CElements)-1 do
          if (lowercase(ref_CElements[i].element)=lowercase(CElements[j].element)) and
             (lowercase(ref_CElements[i].color)=lowercase(CElements[j].color)) then
          begin
            found:=true;
            break;
          end;
        if not found then
        begin
          s:=ref_CElements[i].color+'_'+ref_CElements[i].element;
          while length(s)<20 do s:=s+' ';
          s:=s+' ('+ref_CElements[i].description+')';
          Form5.Memo1.Lines.Add(s);
        end;
      end;
    end;
    Form5.ShowModal;
end;


procedure TForm1.BitBtn3Click(Sender: TObject);
var
  i: Integer;
  s: String;
begin
  s:=OpenDialog1.FileName;
  if OpenDialog1.Execute then
  begin
    LoadAllFiles;
    setLength(ref_constants,length(constants));
    for i:=0 to length(constants)-1 do copyErgConstant(constants[i],ref_constants[i]);
    setLength(ref_elements,length(elements));
    for i:=0 to length(elements)-1 do copyErgElement(elements[i],ref_elements[i]);
    setLength(ref_tracers,length(tracers));
    for i:=0 to length(tracers)-1 do copyErgTracer(tracers[i],ref_tracers[i]);
    setLength(ref_auxiliaries,length(auxiliaries));
    for i:=0 to length(auxiliaries)-1 do copyErgAuxiliary(auxiliaries[i],ref_auxiliaries[i]);
    setLength(ref_limitations,length(limitations));
    for i:=0 to length(limitations)-1 do ref_limitations[i]:=limitations[i];
    setLength(ref_processes,length(processes));
    for i:=0 to length(processes)-1 do copyErgProcess(processes[i],ref_processes[i]);
    setLength(ref_cElements,length(cElements));
    for i:=0 to length(cElements)-1 do copyErgCElement(celements[i],ref_celements[i]);
    ref_modelinfos:=modelinfos;

    label5.visible:=true;
    label6.Visible:=true;
    Button8.Visible:=true;
    BitBtn5.Visible:=true;
    BitBtn4.Visible:=true;
    CheckBox2.Visible:=true;
    BitBtn3.Visible:=false;
    Button11.Visible:=true;

    OpenDialog1.FileName:=s;
    LoadAllFiles;
    AfterRadioButton;
  end;
  OpenDialog1.FileName:=s;
end;

procedure TForm1.BitBtn4Click(Sender: TObject);
begin
  if SaveDialog1.Execute then
  begin
    SaveAllFilesAddOn;
  end;
end;

procedure TForm1.BitBtn5Click(Sender: TObject);
begin
  label5.visible:=false;
  label6.Visible:=false;
  Button8.Visible:=false;
  BitBtn5.Visible:=false;
  BitBtn4.Visible:=false;
  CheckBox2.Visible:=false;
  CheckBox2.Checked:=false;
  BitBtn3.Visible:=true;
  Button11.Visible:=false;

  setLength(ref_constants,0);
  setLength(ref_tracers,0);
  setLength(ref_auxiliaries,0);
  setLength(ref_processes,0);
  setLength(ref_elements,0);
  setLength(ref_celements,0);
  setLength(ref_limitations,0);

  LoadAllFiles;
  AfterRadioButton;
end;

procedure TForm1.BitBtn6Click(Sender: TObject);
begin
  if Edit8.Color <> clWhite then
  begin
    GoToExpression(Edit8.Text);
    Edit8.Text:='';
    Edit8.Color:=clWhite;
  end;
end;

procedure PutIntoStringList(s: String; var s1: TListBox; s2: TListBox=nil);
//will put a string into string list s1, if it is neither contained in s1 nor in s2.
var
  found: Boolean;
  i: Integer;
begin
  found:=false;
  if s2<>nil then
    for i:=0 to s2.items.Count-1 do
      if trim(lowercase(s2.Items[i]))=trim(lowercase(s)) then found:=true;
  for i:=0 to s1.items.Count-1 do
      if trim(lowercase(s1.Items[i]))=trim(lowercase(s)) then found:=true;
  if not found then s1.Items.Add(s);
end;

procedure TForm1.BitBtn7Click(Sender: TObject);
var
  i, j: Integer;
  oldName: String;
begin
  if trim(Edit8.Text)='' then
  begin
    oldName:=Edit1.Text;
    Form7.Label1.Color:=Edit1.Color;
  end
  else
  begin
    oldName:=Edit8.Text;
    Form7.Label1.Color:=Edit8.Color;
  end;
  Form7.ListBox1.Clear; Form7.ListBox2.Clear;
  Form7.ListBox3.Clear; Form7.ListBox4.Clear;
  Form7.ListBox5.Clear; Form7.ListBox6.Clear;
  Form7.ListBox7.Clear; Form7.ListBox8.Clear;
  Form7.Label1.caption:=oldName;
  for i:=0 to length(constants)-1 do
  begin
    if containedInString(oldName,constants[i].name)        then putIntoStringList(constants[i].name,Form7.ListBox1);
    if containedInString(oldName,constants[i].description) then putIntoStringList(constants[i].name,Form7.ListBox2,Form7.ListBox1);
    if containedInString(oldName,constants[i].comment)     then putIntoStringList(constants[i].name,Form7.ListBox2,Form7.ListBox1);
  end;
  for i:=0 to length(tracers)-1 do
  begin
    if containedInString(oldName,tracers[i].name)        then putIntoStringList(tracers[i].name,Form7.ListBox3);
    for j:=0 to length(tracers[i].contents)-1 do
    begin
      if containedInString(oldName,tracers[i].contents[j].element) then putIntoStringList(tracers[i].name,Form7.ListBox3);
      if containedInString(oldName,tracers[i].contents[j].amount)  then putIntoStringList(tracers[i].name,Form7.ListBox3);
    end;
    if containedInString(oldName,tracers[i].vertSpeed)   then putIntoStringList(tracers[i].name,Form7.ListBox3);
    if containedInString(oldName,tracers[i].vertDiff)    then putIntoStringList(tracers[i].name,Form7.ListBox3);
    if containedInString(oldName,tracers[i].opacity)     then putIntoStringList(tracers[i].name,Form7.ListBox3);
    if containedInString(oldName,tracers[i].childOf)     then putIntoStringList(tracers[i].name,Form7.ListBox3);
    if containedInString(oldName,tracers[i].massLimits)  then putIntoStringList(tracers[i].name,Form7.ListBox3);
    if containedInString(oldName,tracers[i].schmidtNumber) then putIntoStringList(tracers[i].name,Form7.ListBox3);
    if containedInString(oldName,tracers[i].solubility)  then putIntoStringList(tracers[i].name,Form7.ListBox3);
    if containedInString(oldName,tracers[i].description) then putIntoStringList(tracers[i].name,Form7.ListBox4,Form7.ListBox3);
    if containedInString(oldName,tracers[i].comment)     then putIntoStringList(tracers[i].name,Form7.ListBox4,Form7.ListBox3);
  end;
  for i:=0 to length(auxiliaries)-1 do
  begin
    if containedInString(oldName,auxiliaries[i].name)        then putIntoStringList(auxiliaries[i].name,Form7.ListBox5);
    if containedInString(oldName,auxiliaries[i].formula)     then putIntoStringList(auxiliaries[i].name,Form7.ListBox5);
    for j:=1 to 9 do
      if containedInString(oldName,auxiliaries[i].temp[j])     then putIntoStringList(auxiliaries[i].name,Form7.ListBox5);
    if containedInString(oldName,auxiliaries[i].description) then putIntoStringList(auxiliaries[i].name,Form7.ListBox6,Form7.ListBox5);
    if containedInString(oldName,auxiliaries[i].comment)     then putIntoStringList(auxiliaries[i].name,Form7.ListBox6,Form7.ListBox5);
  end;
  for i:=0 to length(processes)-1 do
  begin
    if containedInString(oldName,processes[i].name)        then putIntoStringList(processes[i].name,Form7.ListBox7);
    if containedInString(oldName,processes[i].turnover)    then putIntoStringList(processes[i].name,Form7.ListBox7);
    for j:=0 to length(processes[i].input)-1 do
    begin
      if containedInString(oldName,processes[i].input[j].tracer)    then putIntoStringList(processes[i].name,Form7.ListBox7);
      if containedInString(oldName,processes[i].input[j].amount)    then putIntoStringList(processes[i].name,Form7.ListBox7);
    end;
    for j:=0 to length(processes[i].output)-1 do
    begin
      if containedInString(oldName,processes[i].output[j].tracer)    then putIntoStringList(processes[i].name,Form7.ListBox7);
      if containedInString(oldName,processes[i].output[j].amount)    then putIntoStringList(processes[i].name,Form7.ListBox7);
    end;
    for j:=0 to length(processes[i].limitations)-1 do
    begin
      if containedInString(oldName,processes[i].limitations[j].elseProcess)    then putIntoStringList(processes[i].name,Form7.ListBox7);
      if containedInString(oldName,limitations[processes[i].limitations[j].limitationNum].tracer)    then putIntoStringList(processes[i].name,Form7.ListBox7);
      if containedInString(oldName,limitations[processes[i].limitations[j].limitationNum].value)    then putIntoStringList(processes[i].name,Form7.ListBox7);
    end;
    if containedInString(oldName,processes[i].description) then putIntoStringList(processes[i].name,Form7.ListBox8,Form7.ListBox7);
    if containedInString(oldName,processes[i].comment)     then putIntoStringList(processes[i].name,Form7.ListBox8,Form7.ListBox7);
  end;
  Form1.Visible:=false;
  Form7.ShowModal;
  Form1.Visible:=true;
end;

end.
