--with Adam.Shells;
with Ada.Wide_Text_Io;
with Ada.Text_Io;
use Ada;
with Ada.Characters.Handling;
use Ada.Characters.Handling;
with Gnat.Command_Line;
use Gnat;
--with Adam.Versions.Version_Io;
package body Adam.Interfaces is
   
   task body Textual_Thread_Type is
      
      End_Of_Task : Boolean := False;
   begin
      
      --  accept Initialize (Errno : out Integer) do
	 
      --  	 Errno := 0;
      --  end Initialize;
      
      while not End_Of_Task Loop
	 accept Halt do
	    End_Of_Task := True;
	 end Halt;
      end loop;
   end Textual_Thread_Type;
   
   
   task body Graphical_Thread_Type is
      
      End_Of_Task : Boolean := False;
            
      Running : Boolean := False;      
      
      Inputs_Buffer : array (1..12) of String_Access;
      Inputs_Buffer_Last : Natural := 0;
      
      Outputs_Buffer : array (1..12) of String_Access;
      Outputs_Buffer_Last : Natural := 0;
      
      
      
   begin            
      --  accept Initialize (Errno : out Integer) do
	 
      --  	 Errno := 0;
      --  end Initialize;
      Running := True;               
      Text_Io.Put(" OS Starting... ");	       		              
      Text_Io.New_Line;
      --The_Glossary.Initialize("data/lexics/Lexique-355.txt");
      Text_Io.New_Line;            
      loop
	 select	             
	    accept Halt;
	    Running := False;	       
            Text_Io.Put(" OS Stopping... ");	       
	    exit;
      	 or
	    accept Receive(Text : in String) do
	       Text_Io.Put(" OS Receive text from : " & Text);
	       if Inputs_Buffer_Last = Inputs_Buffer'Length then
		  Free(Inputs_Buffer(1));
		  for I in 2..Inputs_Buffer_Last loop
		     
		     Inputs_Buffer(I-1) := Inputs_Buffer(I);
		  end loop;
		  Inputs_Buffer_Last := Inputs_Buffer_Last - 1;
	       end if;
	       --Free_String(Inputs_Buffer(Inputs_Buffer_Last+1));
	       Inputs_Buffer(Inputs_Buffer_Last+1) := new String ' (Text);
	       Inputs_Buffer_Last := Inputs_Buffer_Last + 1;
	       
	    end Receive;
	 or
	    when Outputs_Buffer_Last > 0 =>
	       accept Send(Text : out String_Access) do
		  Text := new String ' (Outputs_Buffer(1).all);		  
		  
		  if Outputs_Buffer_Last > 0 then
		     Free(Outputs_Buffer(1));
	    	     for I in 2..Outputs_Buffer_Last loop
	    		Outputs_Buffer(I-1) := Outputs_Buffer(I);
	    	     end loop;
	    	     Outputs_Buffer_Last := Outputs_Buffer_Last - 1;	    	     
	    	  end if;		  	    	  		  
		  
	       end Send;	       	    
	       
         or
	    when Outputs_Buffer_Last = 0 =>
	       accept Send(Text : out String_Access) do
		  Text := null;
	       end Send;	       	    
         or
	    
	    when Running and (Inputs_Buffer_Last > 0) =>
	       accept Exhauste(Text : out String_Access) do
	    	  Text := Inputs_Buffer(1);	    	  		  
		  
		  if Inputs_Buffer_Last > 0 then
		     
		     for I in 1..Inputs_Buffer_Last-1 loop
			
			Inputs_Buffer(I) := Inputs_Buffer(I+1);
		     end loop;
		     Inputs_Buffer_Last := Inputs_Buffer_Last - 1;
		  end if;
		  
		  if Outputs_Buffer_Last > 0 then
		     Free(outputs_Buffer(1));
	    	     for I in 1..Outputs_Buffer_Last-1 loop
	    	  	Outputs_Buffer(I) := Outputs_Buffer(I+1);
	    	     end loop;
	    	     Outputs_Buffer_Last := Outputs_Buffer_Last - 1;	    	     
	    	  end if;		  
		  Free(outputs_Buffer(Outputs_Buffer_Last+1));
		  Outputs_Buffer(Outputs_Buffer_Last+1) := new String ' (Text.all);
	    	  Outputs_Buffer_Last := Outputs_Buffer_Last + 1;		  		  
	       end Exhauste;
	 end select;
	 
      end loop;      
   end Graphical_Thread_Type;

   
   function New_Interface return Main_Interface_Access is
      
      --  Options_Kit : constant Options_Kit_Array_Type :=
      --  	Get_Options_From_Command_Line;      	       	
      
      Main_Interface : Main_Interface_Access := new Textual_Interface_Type;
   begin
      --  case Options_Kit(Version).Is_Setted is
      --  	 when False =>
      --  	    null;
      --  	 when True =>	    
      --  	    Text_Io.Put_Line(Adam.Versions.Version_Io.To_String(Adam.Versions.Version));
      --  	    return null;
      --  end case;

      --  case Options_Kit(Graph_Geometry).Is_Setted is
      --  	 when False =>
      --  	    Main_Interface := new Textual_Interface_Type;	    
	    
      --  	 when True =>
      --  	    Main_Interface := new Graphical_Interface_Type;
      --  end case;
      
      return Main_Interface;
 
   end New_Interface;
   
   procedure Initialize (Main_Interface : in out Main_Interface_Type'Class) is
      
      --  Options_Kit : access Options_Kit_Array_Type;	   
   begin
      null;
   --     Options_Kit := new Options_Kit_Array_Type ' (Get_Options_From_Command_Line);
      
   --     case Options_Kit(Config_Filename).Is_Setted is
   --  	 when False =>
   --  	    Main_Interface.Parameters_Kit := Set_Parameters_from("Config_File.txt").all;
   --  	 when True =>
   --  	    Main_Interface.Parameters_Kit := Set_Parameters_from(Options_Kit(Config_Filename).Value.all).all;
   --     end case;
   --     declare
   --  	 Parameters_Kit : Parameters_Kit_Record_Type := (All_Parameters => Line_Parameters);
   --     begin
   --  	 Set_Parameters(Parameters_Kit, Options_Kit.all);
   --  	 for Parameter_Id in Parameters_Flags_Enum_Type'Val(1) .. Input_text loop
   --  	    if Parameters_Kit.All_Parameters(Parameter_Id).Is_Setted then
   --  	       Main_Interface.Parameters_Kit.All_Parameters(Parameter_Id).all := 
   --  		 Parameters_Kit.All_Parameters(Parameter_Id).all;
   --  	    end if;
   --  	 end loop;
   --     end;
   exception      
      when Command_Line.Invalid_Parameter =>
	 Wide_Text_Io.Put_Line("Exception in initialization of Main_Interface.");
	 raise;	 
      when others =>
	 Wide_Text_Io.Put_Line("Exception in initialization of Main_Interface.");
	 raise;
   end Initialize;
   
   
   procedure Print_Parameters (Main_Interface : in Main_Interface_Type'class) is
   begin
      for Parameter_Flag in Parameters_Flags_Enum_Type'range loop
	 
	 case Parameter_Flag is
	    
	    when Nul_Parameter =>
	       
	       null;
	    when others =>
	       
	       if Main_Interface.Parameters_Kit.All_Parameters(Parameter_Flag).Is_Setted and
		 
		 Main_Interface.Parameters_Kit.All_Parameters(Parameter_Flag).Requiered_Parameter  then
		  
		  
		  declare
		     Parameter : constant Wide_String := 
		       Main_Interface.Parameters_Kit.All_Parameters(Parameters_Flags_Enum_Type'Val(Parameters_Flags_Enum_Type'Pos(Parameter_Flag))).Value.all;
		  begin
		     Wide_Text_Io.Put_Line
		       (To_Wide_String
			  (
			   Parameters_Flags_Enum_Type'Image(Parameter_Flag)) &
			  " setted with parameter : " & 
			  "" & Parameter & "" & " ; ");
		  end;
	       elsif  Main_Interface.Parameters_Kit.All_Parameters(Parameter_Flag).Is_Setted then		  
		  Wide_Text_Io.Put_Line
		    (To_Wide_String(Parameters_Flags_Enum_Type'Image(Parameter_Flag)) &
		       " setted without parameter.");		  
	       end if;
	 end case;
	 
      end loop;
   end Print_Parameters;
   
   procedure Finalize (Main_Interface : in out Main_Interface_Type'class) is
   begin
      null;
   end Finalize;      
   
   procedure Shell_Halt is
   begin
      null;
      --Shells.Adam_Shell.Halt;
   end Shell_Halt;
   
   
   --  function Get_Parameter
   --    (From : in Main_Interface_Type;
   --     Flag : in Parameters_Flags_Enum_Type)
   --    return Parameter_Tagged_Record_Type is
   --  begin
   --     return From.Parameters_Kit.All_Parameters(Flag).all;
   --  end Get_Parameter;
   
   
   
   --  procedure Parameters_Descriptions
   --    (From : in Main_Interface_Type) is
   --  begin
   --     Wide_Text_Io.Put_Line("Help: Adamanborg [ Options [ Parameters ] ]");
   --     Wide_Text_Io.Put_Line("Help: Options : ");
   --     for Parameter_Flag in Config_Filename..Parameters_Flags_Enum_Type'Last loop
   --  	 declare
   --  	    Parameter : constant Parameter_Tagged_Record_Type :=
   --  	      Get_Parameter(From, Parameter_flag);
   --  	 begin	    
   --  	    if Parameter.Switch /= null then
   --  	       Wide_Text_Io.Put('-' & Parameter.Switch.all & " : ");
   --  	    end if;
   --  	    if Parameter.Descr /= null then
   --  	       Wide_Text_Io.Put(Parameter.Descr.all & " => ");
   --  	    end if;
   --  	    if Parameter.Requiered_Parameter then
   --  	      if Parameter.param /= null then
   --  	       Wide_Text_Io.Put(Parameter.Param.all);
   --  	      end if;
   --  	    end if;
   --  	 end;
   --  	 Wide_Text_Io.New_Line;
   --     end loop;
   --  end Parameters_Descriptions;
   
   --  procedure Set_Parameters(Parameters : out Parameters_Kit_Record_Type;			    
   --  			    Options_Kit : in Options_Kit_Array_Type) is
     

     
      
   --  begin
            
   --     ------------------------------------------------------------------
   --     --                                                              --
   --     -- Initilaisation des parametres depuis les options.            --
   --     --                                                              --
   --     ------------------------------------------------------------------
   --     for Option_Flag in Optionals_Flags_Enum_Type'range loop
	 
   --  	 case Option_Flag is
	    
   --  	    when Nul_Option =>
	       
   --  	       null;
   --  	    when others =>
	       
   --  	       Parameters.All_Parameters
		 
   --  		 (
		  
   --  		  Parameters_Flags_Enum_Type'Val
		    
   --  		    (
		     
   --  		     Optionals_Flags_Enum_Type'Pos(Option_Flag)
		       
   --  		    )
		    
   --  		 ).Is_Setted := 
		 
   --  		 Options_Kit(Option_Flag).Is_Setted;
	       
	       
   --  	       if Options_Kit(Option_Flag).Is_Setted then
   --  		  case Option_Flag is
   --  		     when Graph_Geometry =>
   --  			Options_Kit(Old_Geometry).Is_Setted := False;
   --  			Options_Kit(Linux_Geometry).Is_Setted := False;
   --  			Options_Kit(Wide_Geometry).Is_Setted := False;
   --  		     when Linux_Geometry =>
   --  			Options_Kit(Old_Geometry).Is_Setted := False;
   --  		     when Wide_Geometry =>
   --  			Options_Kit(Old_Geometry).Is_Setted := False;
   --  			Options_Kit(Linux_Geometry).Is_Setted := False;
   --  		     when others =>
   --  			null;
   --  		  end case;
   --  	       end if;
	       
   --  	       if Options_Kit(Option_Flag).Is_Setted and
		 
   --  		 Options_Kit(Option_Flag).Requiered_Parameter  then
		  
   --  		  Parameters.All_Parameters
		    
   --  		    (
		     
   --  		     Parameters_Flags_Enum_Type'Val
		       
   --  		       (
			
   --  			Optionals_Flags_Enum_Type'Pos(Option_Flag)
			  
   --  		       )
		       
   --  		    ).Value :=
		    
   --  		    new Wide_String ' 
		    
   --  		    (
		     
   --  		     Options_Kit(Option_Flag).Value.all
		       
   --  		    );
   --  	       end if;
	       
   --  	 end case;
	 
   --     end loop;
                 
   --  end Set_Parameters;
         
   --  function Set_Parameters_From
     
   --    (Filename : in Wide_String) 
     
   --    return access Parameters_Kit_Record_Type is
      
   --     Parameters_Kit : constant access Parameters_Kit_Record_Type :=
   --  	new Parameters_Kit_Record_Type ' 
   --  	(All_Parameters => File_Parameters);
   --     --(All_Parameters => Set_Parameters_From(Get_Options_From_File(Filename)).All_parameters);
      
   --     Options_Kit : access Options_Kit_Array_Type;	   
                  
   --  begin
   --     Options_Kit := new Options_Kit_Array_Type ' (Get_Options_From_File(filename));      
   --     Set_Parameters(Parameters_Kit.all, Options_Kit.All);
   --     return Parameters_Kit;
   --  end Set_Parameters_From;
end Adam.Interfaces;
