with Ada.Characters.Latin_1;
with Ada.Command_Line;
with Ada.Text_IO;

-- ANSI terminal control: http://www.termsys.demon.co.uk/vtansi.htm

procedure More is
   Page_Length : constant Positive := 24;
   Line_Length : constant Positive := 512;
   Line_Count  : Natural := 0;
   Terminal    : Ada.Text_IO.File_Type;

   function See_More_Lines return Natural is
      --  Special case: 0 = quit
      use Ada.Text_IO;
      package Latin_1 renames Ada.Characters.Latin_1;
      Key : Character;
   begin
      Put (Latin_1.ESC & "[7m more? " & Latin_1.ESC & "[m");
      loop
         Get_Immediate (File => Terminal,
                        Item => Key);
         Put (Latin_1.CR & Latin_1.ESC & "[K");
         case Key is
            when 'q' =>
               return 0;
            when ' ' =>
               return Page_Length;
            when Latin_1.LF =>
               return 1;
            when others =>
               null;
         end case;
      end loop;
   end See_More_Lines;

   procedure Do_More (File : in     Ada.Text_IO.File_Type) is
      use Ada.Text_IO;
      More_Lines : Natural := 0;
      Line       : String (1 .. Line_Length);
      Read       : Natural := 0;
   begin
      while not End_Of_File (File) loop
         Get_Line (File => File,
                   Item => Line,
                   Last => Read);
         Put_Line (Item => Line (1 .. Read));
         Line_Count := Line_Count + 1;

         if Line_Count >= Page_Length then
            More_Lines := See_More_Lines;
            if More_Lines = 0 then
               return;
            else
               Line_Count := Line_Count - More_Lines;
            end if;
         end if;
      end loop;
   end Do_More;
begin
   Ada.Text_IO.Open (File => Terminal,
                     Name => "/dev/tty",
                     Mode => Ada.Text_IO.In_File);

   if Ada.Command_Line.Argument_Count = 0 then
      Do_More (File => Ada.Text_IO.Standard_Input);
   else
      for Index in 1 .. Ada.Command_Line.Argument_Count loop
         declare
            use Ada.Text_IO;
            Input : File_Type;
         begin
            Put_Line (Item => "::::::::::::::");
            Put_Line (Item => Ada.Command_Line.Argument (Index));
            Put_Line (Item => "::::::::::::::");
            Line_Count := Line_Count + 3;
            Open (File => Input,
                  Name => Ada.Command_Line.Argument (Index),
                  Mode => In_File);
            Do_More (File => Input);
            Close (File => Input);
         end;
      end loop;
   end if;

   Ada.Text_IO.Close (File => Terminal);
end More;

