-- play_again4.adb
--      purpose: ask if user wants another transaction
--       method: set tty into char-by-char and no-echo mode,
--               set tty into no-delay mode,
--               read char, return result
--      returns: yes     => 0
--               no      => 1
--               timeout => 2
--               Ctrl-C  => 3
--       better: reset terminal mode on interrupt

with
  Ada.Text_IO,
  POSIX.IO,
  POSIX.Process_Primitives,
  POSIX.Terminal_Functions;

with
  C_Signals,
  EUP.Text_IO.Direct_Character_IO,
  TTY_Memory;

use
  POSIX.IO,
  POSIX.Process_Primitives,
  POSIX.Terminal_Functions;

with Clean_Up_And_Stop;

procedure Play_Again is
   Question  : constant String := "Do you want another transaction";
   Max_Times : constant Positive := 60;
   Pause     : constant Duration := 0.1;

   procedure Beep is
   begin
      EUP.Text_IO.Direct_Character_IO.Put (POSIX.BEL);
   end Beep;

   function Get_Response return Exit_Status is
      use
        Ada.Text_IO,
        EUP.Text_IO.Direct_Character_IO;
      Input : Character_Or_EOF;
      Times : Natural := 0;
   begin
      Put (Item => Question & " (y/n)? ");
      loop
         Input := EUP.Text_IO.Direct_Character_IO.Get;

         if End_Of_File (Input) then
            Times := Times + 1;
            exit when Times >= Max_Times;
            delay Pause;
         else
            case To_Character (Input) is
               when 'y' | 'Y' =>
                  Put_Line ("Yes");
                  return 0;
               when 'n' | 'N' =>
                  Put_Line ("No");
                  return 1;
               when others =>
                  Beep;
            end case;
         end if;
      end loop;
      Put_Line ("(timeout)");
      return 2;
   end Get_Response;

   procedure Set_Character_By_Character_And_No_Echo_Mode is
      Info  : Terminal_Characteristics;
      Modes : Terminal_Modes_Set;
   begin
      Info := Get_Terminal_Characteristics (File => Standard_Input);
      Modes := Terminal_Modes_Of (Info);
      Modes (Canonical_Input) := False;
      Modes (Echo) := False;
      Define_Terminal_Modes (Characteristics => Info,
                             Modes           => Modes);
      Define_Minimum_Input_Count (Characteristics     => Info,
                                  Minimum_Input_Count => 1);
      Set_Terminal_Characteristics (File            => POSIX.IO.Standard_Input,
                                    Characteristics => Info);
   end Set_Character_By_Character_And_No_Echo_Mode;

   procedure Set_No_Delay_mode is
      Mode    : File_Mode;
      Options : Open_Option_Set;
   begin
      Get_File_Control (File    => Standard_Input,
                        Mode    => Mode,
                        Options => Options);
      Set_File_Control (File    => Standard_Input,
                        Options => Options + Non_Blocking);
   end Set_No_Delay_Mode;

   Answer : Exit_Status;
begin
   TTY_Memory.Save;
   Set_Character_By_Character_And_No_Echo_Mode;
   Set_No_Delay_Mode;
   C_Signals.Attach (Handler => Clean_Up_And_Stop'Access,
		     To      => C_Signals.Signal_Interrupt);
   Answer := Get_Response;
   TTY_Memory.Restore;
   Exit_Process (Status => Answer);
end Play_Again;

