unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    RichEdit1: TRichEdit;
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    Memo1: TMemo;
    Button2: TButton;
    Button3: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Label2: TLabel;
    Memo3: TMemo;
    Button4: TButton;
    Button5: TButton;
    SaveDialog1: TSaveDialog;
    memo4: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    var
      _1str: string;                  //first character of line
      _2str: string;                  //second character of line
      _3str: string;                  //third character of line
      _4str: string;                  //forth character of line
      _str: string;                   //Z UP???? in edit2.text
      _string: string;                //strings of a record
      vez: integer;
      vez2: integer;
      X_value: extended;
      Y_value: extended;
      Sum_max: extended;
      rec_no_next: integer;
      rec_no_num: integer;
      rec_no_uni: integer;
      _record: array [1..1000 ] of record
        rec_no: integer;
        X_value: extended;
        Y_value: extended;
        _string: string;
      end;
    procedure BasePoint();
    procedure OneLineMove();          //one line move (copy and delete)
    procedure GcodeSelect();          //G00 or G01 or other G code
    procedure G00();                  //if the first command G00
    procedure G01();                  //if the first command G01
    procedure CircleBegin();          //when the value of the line "Z UP"
    procedure CircleContinue();       //when G00 the first command, but no "Z UP"
    procedure CreatNewRecord();       //creat a new record
    procedure MoveToRecord();         //the line move to record
    procedure CloseRecord();          //Close the record
    procedure ReadCoordinate();       //read the coordinate an write to record
    procedure GcodeOptimiser();       //optimiser the Gcode and move the record
    procedure MoveRecord();           //move and delete the record
    procedure Clear_();
    procedure SearchVector();
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.BasePoint;
  var
    i:integer;
  begin
    memo1.Clear;
//    memo2.Clear;
    edit1.Clear;
    edit2.Clear;
    richedit1.Clear;
    memo4.Clear;
    vez2:=0;
    vez:=0;
    rec_no_uni:=0;
    rec_no_next:=0;
    rec_no_num:=0;
    for I := 1 to 1000 do
      begin
        _record[i].rec_no:=0;
        _record[i]._string:='';
        _record[i].X_value:=0;
        _record[i].Y_value:=0;
      end;
  end;

procedure TForm1.OneLineMove();        //egy sor átírása és az eredetibõl törlés
  begin
    Form1.memo4.Lines.Append(Form1.richedit1.Lines.Strings[0]);
    Form1.richedit1.Lines.Delete(0);
  end;

procedure TForm1.GcodeSelect;
  begin
    if _2str<>'0' then OneLineMove()
    else if _3str='0' then G00()
         else if _3str='1' then G01()
              else OneLineMove();
  end;

procedure TForm1.G00;
  begin
    if edit2.Text='G00X0.0000Y0.0000' then begin OneLineMove(); X_value:=strtofloat('0,0000'); Y_value:=strtofloat('0,0000'); end
    else if edit3.Text=_str then CircleBegin()
         else if _4str='Z' then begin CloseRecord(); GcodeOptimiser(); OneLineMove(); end
              else if vez>0 then CircleContinue()
                   else begin vez2:=1; messagebox(0,'GOO modulban vez=0','Hiba',mb_ok); end;
  end;

procedure TForm1.G01;
  begin
    vez:=vez+1;
    MoveToRecord();
  end;

procedure TForm1.CircleBegin;
  begin
    if vez>0 then CloseRecord();
    vez:=1;
    CreatNewRecord();
    MoveToRecord();
  end;

procedure TForm1.CircleContinue;
  begin
    vez:=vez+1;
    ReadCoordinate();
    MoveToRecord();
  end;

procedure TForm1.CreatNewRecord;
  begin
    memo3.Clear;
    rec_no_uni:= rec_no_uni+1;
    _record[rec_no_uni].rec_no:=rec_no_uni;
    _record[rec_no_uni].X_value:=10000;
    _record[rec_no_uni].Y_value:=10000;
//    memo3.Lines.Append('(_record.rec_no= '+ inttostr(rec_no_uni)+' )');
    //memo2.Lines.Append('NewRecordCreated ***** rec_no_uni:'+ inttostr(rec_no_uni));
  end;

procedure TForm1.MoveToRecord;
  begin
    memo3.Lines.Append(edit1.Text);
    richedit1.Lines.Delete(0);
  end;

procedure TForm1.CloseRecord;
  begin
    _record[rec_no_uni]._string:=memo3.Lines.Text;
    //memo2.Lines.Append('rec_no: '+inttostr(_record[rec_no_uni].rec_no));
    //memo2.Lines.Append('X_value: '+floattostr(_record[rec_no_uni].X_value));
    //memo2.Lines.Append('Y_value: '+floattostr(_record[rec_no_uni].Y_value));
    //memo2.Lines.Append('_string:');
//    memo2.Lines.Append(_record[rec_no_uni]._string);
    //memo2.Lines.Append('RecordClosed');
  end;

procedure TForm1.ReadCoordinate;
  var
    i: integer;
    _vez: integer;
    _vez2: integer;
    _x_value: string;
    _y_value: string;
    var_char: char;
  begin
    _vez:=0;
    _x_value:='';
    _y_value:='';
    for I := 1 to 1000 do
      begin
        _vez2:=0;
        var_char:=edit2.Text[i];
        if var_char=char(0) then break;
        if edit2.Text[i]='X' then begin _vez:=1; _vez2:=1; end;
        if edit2.Text[i]='Y' then begin _vez:=2; _vez2:=1; end;
        if (_vez=1) and (_vez2=0) then if edit2.Text[i]='.' then _x_value:=_x_value+',' else _x_value:=_x_value+edit2.Text[i];
        if (_vez=2) and (_vez2=0) then if edit2.Text[i]='.' then _y_value:=_y_value+',' else _y_value:=_y_value+edit2.Text[i];
      end;
    _record[rec_no_uni].X_value:=strtofloat(_x_value);
    _record[rec_no_uni].Y_value:=strtofloat(_y_value);

    //memo2.Lines.Append('*** X='+floattostr(X_value)+'***Y='+floattostr(Y_value));

  end;

procedure TForm1.GcodeOptimiser;
  var
    i : integer;
  begin
    vez:=0;
    rec_no_num:=0;
    for I := 1 to 1000 do
      begin
        if _record[i].rec_no>0 then rec_no_num:=rec_no_num+1;
      end;
    //memo4.Lines.Append('(***********************************)'+char(13)+'(RecordsOptimised *** Found records: '+inttostr(rec_no_num)+')'+char(13)+'(***********************************)');

    SearchVector();

  end;

procedure TForm1.SearchVector;
  var
    i, j: integer;
    _x_, _y_, _sum: extended;
  begin
    rec_no_next:=0;
    Sum_max:=0;
    for i := 1 to rec_no_num do
      begin
        for j := 1 to rec_no_num do
          begin
            if _record[j].rec_no<>0 then
              begin
                _x_:=_record[j].X_value-X_value;
                _y_:=_record[j].Y_value-Y_value;
                _x_:=_x_*_x_;
                _y_:=_y_*_y_;
                _sum:=_x_+_y_;
                if (Sum_max>_sum) or (Sum_max=0) then
                  begin
                    Sum_max:=_sum;
                    rec_no_next:=_record[j].rec_no;
                  end;
              end;
          end;
        if rec_no_next<>0 then MoveRecord() else break;
      end;

  end;

procedure TForm1.MoveRecord;
{  var
    i:integer;
  begin
    for I := 1 to 1000 do
      begin
        if _record[i]._string<>'' then memo4.Lines.Append(_record[i]._string);
      end;
    //memo4.Lines.Append(memo2.Lines.Text);
    //memo2.Clear;
  end;


{ TODO -onyarfa -cnext_step : A kiírást majd ezzel }
  begin
    memo4.Lines.Append(_record[rec_no_next]._string);
    _record[rec_no_next].rec_no:=0;
    X_value:=_record[rec_no_next].X_value;
    Y_value:=_record[rec_no_next].Y_value;
    rec_no_next:=0;
    Sum_max:=0;
  end;

procedure TForm1.Clear_;
  var
    i:integer;
    j: integer;
    str: string;
  begin
    j:=0;
    for I := 0 to 10000000 do
      begin
        str:= memo4.Lines.Strings[i];
        if str='' then begin memo4.Lines.Delete(i); j:=j+1; end else j:=0;
        if j>20 then break;
      end;
    memo3.Clear;
    memo3.Lines.Append('Full optimization'+char(13)+char(13));
    memo3.Lines.Append('numbers of recors: '+inttostr(rec_no_num))
  end;

procedure TForm1.Button1Click(Sender: TObject);
  begin
    BasePoint();
    opendialog1.Execute();
    memo1.Lines.Text:=opendialog1.Files.Text;
    richedit1.Lines.LoadFromFile(memo1.Lines.Strings[0]);
  end;

procedure TForm1.Button2Click(Sender: TObject);
  var
    i: integer;
  begin
    for I := 1 to richedit1.Lines.Count do
      begin
        if vez2=1 then break;        
        button3.OnClick(button3.NewInstance);
      end;
  end;

procedure TForm1.Button3Click(Sender: TObject);
  var
    i: integer;
    var_char: char;
  begin
    edit1.Text:=richedit1.Lines.Strings[0];
    edit2.Text:='';
    for I := 1 to 1000 do
      begin
        var_char:=edit1.Text[i];
        if var_char=char(0) then break;          //ha vége azaz nulla karakter érkezik akkor kilép a ciklusból
        if (var_char>char(32)) and (var_char<char(127)) then edit2.Text:= edit2.Text + edit1.Text[i];    //csak az angol ABC a szóköz nélkül
      end;
    _1str:= edit2.Text[1];
    _2str:= edit2.Text[2];
    _3str:= edit2.Text[3];
    _4str:= edit2.Text[4];
    edit2.SelStart:=4;
    edit2.SelLength:=6;
    _str:=edit2.SelText;
    if _1str='G' then GcodeSelect() else if vez=0 then OneLineMove() else GcodeOptimiser();
  end;

procedure TForm1.Button4Click(Sender: TObject);
  begin
    Clear_();
  end;

procedure TForm1.Button5Click(Sender: TObject);
  begin
    Savedialog1.Files.Text:=memo1.Lines.Text;
    Savedialog1.Execute();
    memo4.Lines.SaveToFile(Savedialog1.FileName);
  end;

procedure TForm1.FormCreate(Sender: TObject);
  begin
    BasePoint();
  end;

end.
