unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    PrCode_txt: TEdit;
    Amount_txt: TEdit;
    Curr_txt: TEdit;
    r1_txt: TEdit;
    Label4: TLabel;
    r2_txt: TEdit;
    Label5: TLabel;
    t1_txt: TEdit;
    t2_txt: TEdit;
    sv_txt: TEdit;
    svGrp_txt: TEdit;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    stlment_txt: TEdit;
    Label11: TLabel;
    Label12: TLabel;
    kv_txt: TEdit;
    Button1: TButton;
    Edit1: TEdit;
    Label14: TLabel;
    IdTCPClient1: TIdTCPClient;
    Button2: TButton;
    Label15: TLabel;
    raw_resp_txt: TMemo;
    Label16: TLabel;
    rqStr_txt: TMemo;
    Label10: TLabel;
    resp_txt: TMemo;
    Edit2: TEdit;
    Label13: TLabel;
    Warehoff1: TEdit;
    Warehoff2: TEdit;
    Label17: TLabel;
    Label18: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TListener = class(TThread)
  private
    receivedData: string;
  protected
    procedure Execute; override;
  end;

const
  PORT = 1010;//The default port for the communication

var
  Form1: TForm1;
  ComFile: THandle;
  reqStr :String;
implementation

{$R *.dfm}
//------------------------------------------------

function LeftPad(S: string; Ch: Char; Len: Integer): string;
var
   RestLen: Integer;
begin
   Result  := S;
   RestLen := Len - Length(s);
   if RestLen < 1 then Exit;
   Result := StringOfChar(Ch, RestLen) + S;
end;
//------------------------------------------------

function AddEntry(tag: string; value: String): string;
var
   RestLen: Integer;
begin
   reqStr := reqStr + tag + LeftPad(IntToStr(Length(value)),'0',3 ) + value;
   Result:=reqStr;
end;
//------------------------------------------------


// ------------------------------------------------

// this function uses for building msg format for request msg to send to pos
// ------------------------------------------------
function ParsReceiveMsg(value: String): string;
var
  RestLen: Integer;
  temp : String;
begin
  if Length(value) > 22 then
    begin
      temp := '';
      temp := temp + 'RS = ' + Copy(value,15,2) + sLineBreak  ;
      temp := temp + 'TR = ' + Copy(value,Pos('TR',value) + 5,strtoint(Copy(value,(Pos('TR',value) + 2),3))) + sLineBreak  ;
      temp := temp + 'RN = ' + Copy(value,Pos('RN',value) + 5,strtoint(Copy(value,(Pos('RN',value) + 2),3))) + sLineBreak ;
      temp := temp + 'TM = ' + Copy(value,Pos('TM',value) + 5,strtoint(Copy(value,(Pos('TM',value) + 2),3))) + sLineBreak ;
      temp := temp + 'AM = ' + Copy(value,Pos('AM',value) + 5,strtoint(Copy(value,(Pos('AM',value) + 2),3))) + sLineBreak ;
      temp := temp + 'AF = ' + Copy(value,Pos('AF',value) + 5,strtoint(Copy(value,(Pos('AF',value) + 2),3))) + sLineBreak ;
      temp := temp + 'PN = ' + Copy(value,Pos('PN',value) + 5,strtoint(Copy(value,(Pos('PN',value) + 2),3))) + sLineBreak ;
      temp := temp + 'TI = ' + Copy(value,Pos('TI',value) + 5,strtoint(Copy(value,(Pos('TI',value) + 2),3))) + sLineBreak ;
      temp := temp + 'SR = ' + Copy(value,Pos('SR',value) + 5,strtoint(Copy(value,(Pos('SR',value) + 2),3))) + sLineBreak ;
      temp := temp + 'PD = ' + Copy(value,Pos('PD',value) + 5,strtoint(Copy(value,(Pos('PD',value) + 2),3))) + sLineBreak ;

    end
    else
    begin
         if Length(value) <= 22 then
    begin
      temp := '';
      temp := temp + 'RS = ' + Copy(value,15,2) + sLineBreak  ;
      temp := temp + 'PD = ' + Copy(value,Pos('PD',value) + 5,strtoint(Copy(value,(Pos('PD',value) + 2),3))) + sLineBreak ;
    end;
    end;
  Result := temp;
end;
//-------------------------------
procedure TForm1.Button2Click(Sender: TObject);
begin
  if IdTCPClient1.Connected then IdTCPClient1.Disconnect;
  IdTCPClient1.Host:=Edit1.Text;
  IdTCPClient1.Port:=1362;
  IdTCPClient1.Connect;
  if(IdTCPClient1.Connected) then
    raw_resp_txt.Text :=   'Connected to ' + Edit1.Text
  else
    showmessage('an exception is occured');
end;

procedure TForm1.Button1Click(Sender: TObject);

var
NumberOfBytesRead : Cardinal;
NumberWritten, BytesRead, BytesToRead: LongWord;
Data ,InputBuffer: String;
Buffer: PChar;
d: array[1..256] of Char;
s: string;
i: Integer;
comPort : String;
TimeoutBuffer: PCOMMTIMEOUTS;


begin
resp_txt.Text := '';
reqStr:='';
    if(IdTCPClient1.Connected) then
    begin
      AddEntry('PR',PrCode_txt.Text);
      AddEntry('AM',Amount_txt.Text);
      AddEntry('CU',Curr_txt.Text);
      AddEntry('R1',r1_txt.Text);
      AddEntry('R2',r2_txt.Text);
      AddEntry('T2',t1_txt.Text);
      AddEntry('T2',t2_txt.Text);
      AddEntry('SV',sv_txt.Text);
      AddEntry('SG',svGrp_txt.Text);
      if (Length( Warehoff1.Text ) = 15) then
      begin
        if (Length(Warehoff2.Text) = 15) then
            AddEntry('BI',Warehoff1.Text);
            AddEntry('PI',Warehoff2.Text);
        end;
      end ;

      AddEntry('AD','');
      AddEntry('PD','1');

      reqStr := 'RQ' + (LeftPad(IntToStr(Length(reqStr)), '0', 3)) + reqStr;

      rqStr_txt.Text:=LeftPad(IntToStr(Length(reqStr)), '0', 4) + reqStr;
      Data:= LeftPad(IntToStr(Length(reqStr)), '0', 4) + reqStr;
      //Data:='0074RQ069PR006000000AM0041000CU003364R1000R2000T1000T2000SV000SG000AD000PD0011';      //Sample Request String
      IdTCPClient1.WriteLn(Data);
      TListener.Create(false);
    end
  else
    ShowMessage('No Connection!!')

end;

procedure TListener.Execute;
var
  responseLenght: string;
  hasData: boolean;
begin
    Form1.raw_resp_txt.Lines.Clear;
    Sleep(100);
    responseLenght := Form1.IdTCPClient1.ReadString(4);
    receivedData   :=  responseLenght;
    receivedData   := receivedData + Form1.IdTCPClient1.ReadString(StrToInt(responseLenght));

    if Length ( receivedData ) >= 22 then
    begin
        Form1.raw_resp_txt.Text := receivedData;
        Form1.resp_txt.Text :=  ParsReceiveMsg(receivedData);
    end;
end;



end.
//if WriteFile(ComFile, PChar(Data)^, Length(Data), NumberWritten, nil) = False then
//Read Module  Comes Here

 // GetMem(TimeoutBuffer, sizeof(COMMTIMEOUTS));

 // GetCommTimeouts (comFile, TimeoutBuffer^);
 //  TimeoutBuffer.ReadIntervalTimeout        := 500;
 //  TimeoutBuffer.ReadTotalTimeoutMultiplier := 500;
 //  TimeoutBuffer.ReadTotalTimeoutConstant   := 2000;
 // SetCommTimeouts (comFile, TimeoutBuffer^);

 // FreeMem(TimeoutBuffer, sizeof(COMMTIMEOUTS));
 //  BytesToRead := 80;
 //  BytesRead:=0;
 // if ReadFile(comFile, d, SizeOf(d), BytesRead, nil) = false then
  //  begin
  //   ShowMessage('Unable to read from comport');
  //   exit;
//    end;
//  InputBuffer := '';

//  for i := 1 to BytesRead  - 1 do
 //     InputBuffer := InputBuffer + d[i];
//resp_txt.Text := InputBuffer;
//ShowMessage('Response String: '+InputBuffer);
//closehandle(ComFile);
