--Constants
package Constants is

   Lowest_Value  : constant := 100;
   Highest_Value : constant := 999;
   Maximum_Count : constant := 10;
   subtype Integer_T is Integer
      range Lowest_Value .. Highest_Value;

end Constants;
--Constants

--Input
with Constants;
package Input is
   function Get_Value (Prompt : String) return Constants.Integer_T;
end Input;

with Ada.Text_IO; use Ada.Text_IO;
package body Input is

   function Get_Value (Prompt : String) return Constants.Integer_T is
      Ret_Val : Integer;
   begin
      Put (Prompt & "> ");
      loop
         Ret_Val := Integer'Value (Get_Line);
         exit when Ret_Val >= Constants.Lowest_Value
           and then Ret_Val <= Constants.Highest_Value;
         Put ("Invalid. Try Again >");
      end loop;
      return Ret_Val;
   end Get_Value;

end Input;
--Input

--List
package List is
   procedure Add (Value : Integer);
   procedure Remove (Value : Integer);
   function Length return Natural;
   procedure Print;
end List;

with Ada.Text_IO; use Ada.Text_IO;
with Constants;
package body List is
   Content : array (1 .. Constants.Maximum_Count) of Integer;
   Last    : Natural := 0;

   procedure Add (Value : Integer) is
   begin
      if Last < Content'Last then
         Last           := Last + 1;
         Content (Last) := Value;
      else
         Put_Line ("Full");
      end if;
   end Add;

   procedure Remove (Value : Integer) is
      I : Natural := 1;
   begin
      while I <= Last loop
         if Content (I) = Value then
            Content (I .. Last - 1) := Content (I + 1 .. Last);
            Last                    := Last - 1;
         else
            I := I + 1;
         end if;
      end loop;
   end Remove;

   procedure Print is
   begin
      for I in 1 .. Last loop
         Put_Line (Integer'Image (Content (I)));
      end loop;
   end Print;

   function Length return Natural is (Last);
end List;
--List

--Main
with Ada.Text_IO; use Ada.Text_IO;
with Input;
with List;
procedure Main is

begin

   loop
      Put ("(A)dd | (R)emove | (P)rint | (Q)uit : ");
      declare
         Str : constant String := Get_Line;
      begin
         exit when Str'Length = 0;
         case Str (Str'First) is
            when 'A' =>
               List.Add (Input.Get_Value ("Value to add"));
            when 'R' =>
               List.Remove (Input.Get_Value ("Value to remove"));
            when 'P' =>
               List.Print;
            when 'Q' =>
               exit;
            when others =>
               Put_Line ("Illegal entry");
         end case;
      end;
   end loop;

end Main;
--Main
