(*----------------------------------------------------------------------*)
(*           Execute_Command --- Execute PibTerm  command               *)
(*----------------------------------------------------------------------*)

PROCEDURE Execute_Command;

(*----------------------------------------------------------------------*)
(*                                                                      *)
(*     Procedure:  Execute_Command                                      *)
(*                                                                      *)
(*     Purpose:    Execute PibTerm Commands                             *)
(*                                                                      *)
(*     Calling Sequence:                                                *)
(*                                                                      *)
(*        Execute_Command( VAR Command    : Pibterm_Command_Type;       *)
(*                         VAR Done       : BOOLEAN;                    *)
(*                             Use_Script : BOOLEAN );                  *)
(*                                                                      *)
(*           Command    --- Command to execute                          *)
(*           Done       --- set TRUE if termination command found       *)
(*           Use_Script --- TRUE if this is a script command execution  *)
(*                                                                      *)
(*      Calls:   Async_Send_String                                      *)
(*               PibDialer                                              *)
(*               Async_Send_Break                                       *)
(*               Async_Carrier_Detect                                   *)
(*               Display_Commands                                       *)
(*               Delay                                                  *)
(*               GetAreaCode                                            *)
(*               PibUpLoad                                              *)
(*               PibDownLoad                                            *)
(*               Save_Screen                                            *)
(*               Restore_Screen                                         *)
(*               Draw_Menu_Frame                                        *)
(*               Fast_Change_Params                                     *)
(*               PibFileManipulation                                    *)
(*               Get_Capture_File                                       *)
(*               Toggle_Option                                          *)
(*               HangUpPhone                                            *)
(*               Send_Function_Key                                      *)
(*               Set_Input_Keys                                         *)
(*               Set_Translate_Table                                    *)
(*               Do_Screen_Dump                                         *)
(*               DosJump                                                *)
(*                                                                      *)
(*----------------------------------------------------------------------*)

VAR
   Flag       : BOOLEAN;
   I          : INTEGER;
   J          : INTEGER;
   T_Type     : Terminal_Type;
   TimeW      : STRING[8];
   TimeN      : STRING[8];
   TimeO      : STRING[8];
   Local_Save : Saved_Screen_Ptr;
   ESC_Found  : BOOLEAN;
   Trans_Type : Transfer_Type;
   Ch         : CHAR;
   Rem_Ch     : CHAR;
   XPos       : INTEGER;
   GotChar    : BOOLEAN;
   S          : AnyStr;
   Echo       : BOOLEAN;

(*----------------------------------------------------------------------*)
(*           Remote_Input --- get remote input in response to prompt    *)
(*----------------------------------------------------------------------*)

PROCEDURE Remote_Input;

(*----------------------------------------------------------------------*)
(*                                                                      *)
(*     Procedure:  Remote_Input                                         *)
(*                                                                      *)
(*     Purpose:    Gets remote input (from host system) in response to  *)
(*                 prompt.                                              *)
(*                                                                      *)
(*     Calling Sequence:                                                *)
(*                                                                      *)
(*        Remote_Input;                                                 *)
(*                                                                      *)
(*           Global string  -Script_Remote_Reply- get the resultant     *)
(*           input.                                                     *)
(*                                                                      *)
(*      Calls:   Async_Send                                             *)
(*               Send_Function_Key                                      *)
(*               Async_Receive                                          *)
(*                                                                      *)
(*----------------------------------------------------------------------*)

VAR
   Rem_Ch     : CHAR;
   XPos       : INTEGER;
   GotChar    : BOOLEAN;
   S          : AnyStr;
   Echo       : BOOLEAN;
   Ch         : CHAR;

BEGIN (* Remote_Input *)
                                   (* Send prompt to remote system *)

   IF LENGTH( Script_String ) > 0 THEN
      Send_Function_Key( Script_String );

   Ch                  := CHR( 0 );
   Script_Remote_Reply := '';
   XPos                := WhereX;
   Echo                := ( Script_Integer_1 > 0 );

                                   (* Get response string        *)
   REPEAT

      GotChar := FALSE;
                                   (* Check for keyboard input   *)
      IF KeyPressed THEN
         BEGIN
            READ( Kbd, Ch );
            GotChar := TRUE;
         END;
                                   (* Check for remote input *)

      IF Async_Receive( Rem_Ch ) THEN
         BEGIN
            Ch      := Rem_Ch;
            GotChar := TRUE;
         END;
                                   (* Process received character *)
      IF GotChar THEN
         IF Ch <> CHR( CR ) THEN
            IF Ch = ^H THEN
               BEGIN  (* Backspace *)
                  IF WhereX > Xpos THEN
                     BEGIN
                        Async_Send( Ch  );
                        WRITE( Ch );
                        Async_Send( ' ' );
                        WRITE( ' ' );
                        Async_Send( Ch  );
                        WRITE( Ch );
                        IF ( LENGTH( Script_Remote_Reply ) > 1 ) THEN
                           Script_Remote_Reply := COPY( Script_Remote_Reply,
                                                  2,
                                                  LENGTH( Script_Remote_Reply ) - 1 )
                        ELSE
                           Script_Remote_Reply := '';
                     END;
               END   (* Backspace *)
            ELSE
               BEGIN
                  Script_Remote_Reply := Script_Remote_Reply + Ch;
                  IF Echo THEN
                     BEGIN
                        Async_Send( Ch );
                        WRITE( Ch );
                     END
                  ELSE
                     BEGIN
                        Async_Send( '.' );
                        WRITE( '.' );
                     END
               END;

   UNTIL ( Ch = CHR( CR ) ) OR ( NOT Async_Carrier_Detect );

   Script_Remote_Reply_Ok := FALSE;

END   (* Remote_Input *);

(*----------------------------------------------------------------------*)

BEGIN (* Execute_Command *)
                                   (* Don't get confused by previous *)
                                   (* script strings if manual entry *)
   IF ( NOT Use_Script ) THEN
      BEGIN
         Script_String    := '';
         Script_String_2  := '';
         Script_Integer_1 := 0;
      END;
                                   (* Execute chosen command *)
   CASE Command Of

      Null_Command,
      Bad_Command :  ;

      AddLFSy     :  Toggle_Option( 'Add line feeds', Add_LF );

      AreaCodeSy  :  GetAreaCode;

      BreakSy     :  Async_Send_Break;

      CaptureSy   :  Get_Capture_File( Script_String );

      ClearSy     :  ClrScr;

      DelaySy     :  DELAY( Delay_Time );

      DialSy      :  BEGIN
                        PibDialer( FALSE , Script_String );
                        Script_String := '';
                     END;

      DosSy       :  BEGIN
                        DosJump( Script_String );
                        Script_String := '';
                     END;

      EchoSy      :  Toggle_Option( 'Local Echo', Local_Echo );

      EditSy      :  Edit_A_Line;

      ExitSy      :  IF Script_File_Mode THEN
                        BEGIN
                           Toggle_Option( 'Script Mode', Script_File_Mode );
                           IF Script_Buffer_Size > 0 THEN
                              FREEMEM( Script_Buffer , Script_Buffer_Size );
                           Script_Buffer      := NIL;
                           Script_Buffer_Size := 0;
                        END;

      FastCSy     :  Fast_Change_Params;

      FileSy      :  PibFileManipulation;

      GossipSy    :  BEGIN
                        Toggle_Option( 'Gossip mode', Gossip_Mode_On );
                        Done := TRUE;
                        IF Gossip_Mode_On THEN
                           BEGIN
                              Saved_Gossip_Term   := Terminal_To_Emulate;
                              Terminal_To_Emulate := Gossip;
                           END
                        ELSE
                           BEGIN
                              Terminal_To_Emulate := Saved_Gossip_Term;
                           END;
                     END;

      GoToSy      :  Script_Buffer_Pos := Script_Integer_1 - 1;

      HangUpSy    :  BEGIN (* Hang-up Phone *)

                        Save_Screen( Saved_Screen );

                        Draw_Menu_Frame( 10, 10, 60, 15, Menu_Frame_Color,
                                         Menu_Text_Color, '' );

                        WRITELN;
                        WRITELN('*** Hanging up the phone ***');

                                   (* Hang up the phone *)

                        HangUpPhone;

                        IF Async_Carrier_Detect THEN
                           WRITELN('*** Phone not hung up, try again ***')
                        ELSE
                           BEGIN
                              WRITELN('*** Phone hung up ***');
                              Flag := Async_Open( Comm_Port, Baud_Rate,
                                                  Parity, Data_Bits,
                                                  Stop_Bits );
                           END;

                        DELAY( Two_Second_Delay );

                        Restore_Screen( Saved_Screen );

                        Reset_Global_Colors;

                     END   (* Hang-up Phone *);

      HostSy      :  BEGIN (* Set host mode *)
                        Done                := TRUE;
                        Saved_Gossip_Term   := Terminal_To_Emulate;
                        Terminal_To_Emulate := HostMode;
                     END   (* Set host mode *);

      IfConSy     :  IF ( Script_Integer_1 = 1 ) THEN
                        IF Async_Carrier_Detect THEN
                           Script_Buffer_Pos := Script_Integer_2 - 1
                        ELSE
                           Script_Buffer_Pos := Script_Integer_3 - 1
                     ELSE
                        IF ( NOT Async_Carrier_Detect ) THEN
                           Script_Buffer_Pos := Script_Integer_2 - 1
                        ELSE
                           Script_Buffer_Pos := Script_Integer_3 - 1;

      IfFoundSy   :  IF ( Script_Integer_1 = 1 ) THEN
                        IF Script_Wait_Found THEN
                           Script_Buffer_Pos := Script_Integer_2 - 1
                        ELSE
                           Script_Buffer_Pos := Script_Integer_3 - 1
                     ELSE
                        IF ( NOT Script_Wait_Found ) THEN
                           Script_Buffer_Pos := Script_Integer_2 - 1
                        ELSE
                           Script_Buffer_Pos := Script_Integer_3 - 1;

      IfLocStrSy  :  BEGIN

                        Script_Reply_Found := FALSE;

                        IF ( LENGTH( Script_Reply ) > 0 ) THEN
                           Script_Reply_Found :=
                              ( POS( Script_Reply , Script_String ) > 0 );

                        IF ( Script_Integer_1 <> 1 ) THEN
                           Script_Reply_Found := NOT Script_Reply_Found;

                        IF Script_Reply_Found THEN
                           Script_Buffer_Pos := Script_Integer_2 - 1
                        ELSE
                           Script_Buffer_Pos := Script_Integer_3 - 1;

                     END;

      IfRemStrSy  :  BEGIN

                        Script_Remote_Reply_OK := FALSE;

                        IF ( LENGTH( Script_Remote_Reply ) > 0 ) THEN
                           Script_Remote_Reply_OK :=
                              ( POS( Script_Remote_Reply , Script_String ) > 0 );

                        IF ( Script_Integer_1 <> 1 ) THEN
                           Script_Remote_Reply_OK := NOT Script_Remote_Reply_OK;

                        IF Script_Remote_Reply_OK THEN
                           Script_Buffer_Pos := Script_Integer_2 - 1
                        ELSE
                           Script_Buffer_Pos := Script_Integer_3 - 1;

                     END;

      InputSy     :  BEGIN
                        WRITE( Script_String );
                        READLN( Script_Reply );
                        Script_Reply_Found := FALSE;
                     END;

      InfoSy      :  Display_Help( FALSE );

      KeySendSy   :  BEGIN

                        IF Key_No IN [F1..F10] THEN
                           Send_Function_Key( Function_Keys[ 1, Key_No - 58 ] )

                        ELSE IF Key_No IN [Shift_F1..Shift_F10] THEN
                           Send_Function_Key( Function_Keys[ 2, Key_No - 83 ] )

                        ELSE IF Key_No IN [Ctrl_F1..Ctrl_F10] THEN
                           Send_Function_Key( Function_Keys[ 3, Key_No - 93 ] )

                       ELSE IF Key_No IN [Alt_F1..Alt_F10] THEN
                           Send_Function_Key( Function_Keys[ 4, Key_No - 103 ] )

                       ELSE IF ( Keypad_Key_Index[ Key_No ] > 0 ) THEN
                          BEGIN
                             J := Keypad_Key_Index[ Key_No ];
                             I := ( J - 1 ) DIV 10 + 1;
                             J := J - ( I - 1 ) * 10;
                             IF LENGTH( Keypad_Keys[ I , J ] ) > 0 THEN
                                Send_Function_Key( Keypad_Keys[ I , J ] );
                          END;

                     END;

      KeySy       :  Set_Input_Keys( Script_String );

      LogSy       :  Toggle_Option('List session on printer', Printer_On );

      MessageSy   :  WRITELN( Script_String );

      MuteSy      :  BEGIN
                        Toggle_Option('Silent Mode', Silent_Mode );
                        Play_Music_On := NOT Silent_Mode;
                        Menu_Set_Beep( NOT Silent_Mode );
                     END;

      ParamSy     :  BEGIN
                        T_Type := Terminal_To_Emulate;
                        Flag   := Set_Params( FALSE , Use_Script );
                        Done   := ( Terminal_To_Emulate <> T_Type );
                        IF Read_In_Script THEN
                           BEGIN
                              Read_In_Script   := FALSE;
                              Script_File_Name := '';
                              Process_Script;
                           END;
                     END;

      QuitSy      :  BEGIN (* Quit *)

                        Save_Screen( Saved_Screen );

                        Draw_Menu_Frame( 10, 10, 51, 13, Menu_Frame_Color,
                                         Menu_Text_Color, '' );

                        IF Script_File_Mode THEN
                           BEGIN
                              Script_File_Mode :=
                                 NOT YesNo('Stop running current script (Y/N) ? ');
                              IF ( NOT Script_File_Mode ) THEN
                                 BEGIN
                                    IF Script_Buffer_Size > 0 THEN
                                       FREEMEM( Script_Buffer , Script_Buffer_Size );
                                    Script_Buffer      := NIL;
                                    Script_Buffer_Size := 0;
                                 END;
                           END
                        ELSE IF When_Mode THEN
                           BEGIN
                              When_Mode :=
                                 NOT YesNo('Stop WHEN string processing (Y/N) ? ');
                              IF ( NOT When_Mode ) THEN
                                 BEGIN
                                    Script_When_Text       := '';
                                    Script_When_Reply_Text := '';
                                 END;
                           END
                        ELSE
                           Done := YesNo('Are you sure you want to quit (Y/N) ? ');

                        Restore_Screen( Saved_Screen );

                        Reset_Global_Colors;

                        PibTerm_Done := Done;

                     END;

      RedialSy    :  BEGIN
                        PibDialer( TRUE , Script_String );
                        Script_String := '';
                     END;

      ReceiveSy   :  BEGIN

                        IF LENGTH( Script_String ) > 0 THEN
                           BEGIN
                              FileName   := Script_String;
                              Trans_Type := Transfers[ Script_Integer_1 ];
                           END
                        ELSE
                           Trans_Type := None;

                        PibDownLoad( Trans_Type );

                     END;

      ResetSy     :  Script_Buffer_Pos := 0;

      RInputSy    :  Remote_Input;

      SDumpSy     :  Do_Screen_Dump;

      SendSy      :  BEGIN

                        IF LENGTH( Script_String ) > 0 THEN
                           BEGIN
                              FileName   := Script_String;
                              Trans_Type := Transfers[ Script_Integer_1 ];
                           END
                        ELSE
                           Trans_Type := None;

                        PibUpLoad( Trans_Type );

                     END;

      STextSy     :  BEGIN
                        Send_Function_Key( Read_Ctrls( Script_String ) );
                        Script_String := '';
                     END;

      TextSy      :  BEGIN
                        Async_Send_String( Script_String );
                        Script_String := '';
                     END;

      TimersSy    :  Display_Timers;

      TranslateSy :  Set_Translate_Table( Script_String );

      ViewSy      :  IF Review_On THEN

                        IF Review_Head > 0 THEN
                           Review_Captured_Text
                        ELSE
                           BEGIN

                              Save_Screen( Saved_Screen );

                              Draw_Menu_Frame( 10, 10, 60, 14, Menu_Frame_Color,
                                               Menu_Text_Color, '' );

                              WRITE('Review buffer empty.');

                              DELAY( Two_Second_Delay );

                              Restore_Screen( Saved_Screen );

                              Reset_Global_Colors;

                           END
                        ELSE
                     BEGIN
                        Save_Screen( Saved_Screen );

                        Draw_Menu_Frame( 10, 10, 60, 14, Menu_Frame_Color,
                                         Menu_Text_Color, '' );

                        WRITE('Review buffer not active.');

                        DELAY( Two_Second_Delay );

                        Restore_Screen( Saved_Screen );

                        Reset_Global_Colors;
                     END;

      WaitSy      : BEGIN

                       TimeW := COPY( Script_String, 1, 8 );

                       Save_Screen( Local_Save );

                       Draw_Menu_Frame( 10, 10, 60, 14, Menu_Frame_Color,
                                        Menu_Text_Color,
                                        'Wait For Specified Time' );

                       WRITELN('Waiting for:  ',TimeW);
                       WRITE  ('Current time: ');

                       I         := WhereY;
                       TimeN     := '';
                       ESC_Found := FALSE;

                       REPEAT
                          TimeO := TimeN;
                          TimeN := TimeString( TimeOfDay );
                          IF ( TimeN <> TimeO ) THEN
                             BEGIN
                                GoToXY( 15 , I );
                                WRITE( TimeN );
                             END;
                          IF KeyPressed THEN
                             BEGIN
                                READ( Kbd, Ch );
                                IF ORD( Ch ) = ESC THEN
                                   BEGIN
                                      ESC_Found := TRUE;
                                      IF KeyPressed THEN
                                         READ( Kbd, Ch );
                                   END;
                             END;
                       UNTIL( TimeN = TimeW ) OR ESC_Found;

                       Restore_Screen( Local_Save );

                       Reset_Global_Colors;

                    END;

      WhenSy      : BEGIN
                       Script_When_Text       := Script_String;
                       Script_When_Reply_Text := Script_String_2;
                       When_Mode              := LENGTH( Script_When_Text ) > 0;
                    END;

      WaitStrSy   : BEGIN
                       Script_Wait_Text       := Script_String;
                       Script_Wait_Reply_Text := Script_String_2;
                       Script_Wait_Time       := Script_Integer_1;
                       IF ( Script_Wait_Time > 0 ) THEN
                          Really_Wait_String := TRUE
                       ELSE
                          BEGIN
                             Really_Wait_String := FALSE;
                             Script_Wait_Time   := -Script_Wait_Time;
                          END;
                       Script_Wait_Failure    := Script_Integer_2;
                       Script_Wait_Start      := TimeOfDay;
                       Script_Wait_Found      := FALSE;
                       WaitString_Mode        := LENGTH( Script_Wait_Text ) > 0;

                    END;

      ELSE        ;

   END (* CASE *);

END   (* Execute_Command *);
