-- elhoim is full object organizer with editor and command interpreter.
-- Elhoim is Copyright (C) 2023 Manuel De Girardi ; 
--
--   This program is free software; you can redistribute it and/or modify
--   it under the terms of the GNU General Public License as published by
--   the Free Software Foundation; either version 2 of the License, or
--   (at your option) any later version.
--
--   This program is distributed in the hope that it will be useful,
--   but WITHOUT ANY WARRANTY; without even the implied warranty of
--   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--   GNU General Public License for more details.
--
--   You should have received a copy of the GNU General Public License
--   along with this program; if not, write to the Free Software
--   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
--
-- Date := "2023-05-26 17:40:38"
-- Version := "0.6.6b"
with Ada.Wide_Text_Io;
with Ada.Strings.Wide_Fixed;
with Ada.Characters.Handling;
use Ada.Characters;
use Ada;
with Gnat.Command_Line;
use Gnat;

package body El.Interf is
      use Params;
   use Option;
   use Ada.Strings.Wide_Fixed;
   
   
   
   
   function Get_Parameter
     (From : in Interf_Record;
      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 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 Null_Option =>	       
	       null;
	    when others =>	       
	       Parameters.All_Parameters		 
		 (		  
				  Parameters_Flags_Enum_Type'Value
				    (		     
						     Optionals_Flags_Enum_Type'Image(Option_Flag) 
				    )		    
		 ).Is_Setted := Options_Kit(Option_Flag).Is_Setted;	       
	       if Options_Kit(Option_Flag).Is_Setted and		 
		 Options_Kit(Option_Flag).Requiered_Parameter  then		  
		  Parameters.All_Parameters		    
		    (		     
				     Parameters_Flags_Enum_Type'Value
				       (			
								Optionals_Flags_Enum_Type'image(Option_Flag)
				       )		       
		    ).Value := new Wide_String ' (Options_Kit(Option_Flag).Value.all);
	       end if;	       
	 end case;	 
      end loop;      
   end Set_Parameters;
   
   procedure Initialize (Interf : in out Interf_Record'Class) is
      
      Options_Kit : access Options_Kit_Array_Type;	   
   begin
      Options_Kit := new Options_Kit_Array_Type ' (Get_Options_From_Command_Line);
      
      case Options_Kit(Config_Filename).Is_Setted is
	 when False =>
	    Interf.Parameters_Kit := Set_Parameters_from("Config_File.txt").all;
	 when True =>
	    Interf.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) .. Parameters_Flags_Enum_Type'Last loop
	    if Parameters_Kit.All_Parameters(Parameter_Id).Is_Setted then
	       Interf.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 Interface.");
	 raise;	 
      when others =>
	 Wide_Text_Io.Put_Line("Exception in initialization of Interface.");
	 raise;
   end Initialize;
   
   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);            
      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;
   
   procedure Print_Parameters (Interf : in Interf_Record'class) is
   begin
      for Option_Flag in Optionals_Flags_Enum_Type'range loop	 
	 case Option_Flag is	    
	    when Null_option =>
	       null;
	    when others =>	       
	       if Interf.Parameters_Kit.All_Parameters(Parameters_Flags_Enum_Type'Value(Optionals_Flags_Enum_Type'Image(Option_Flag))).Is_Setted and		 
		 Interf.Parameters_Kit.All_Parameters(Parameters_Flags_Enum_Type'Value(Optionals_Flags_Enum_Type'Image(Option_Flag))).Requiered_Parameter then
		  declare
		     Parameter : constant Wide_String := 
		       Interf.Parameters_Kit.All_Parameters
		       (Parameters_Flags_Enum_Type'Val(Parameters_Flags_Enum_Type'Pos(Parameters_Flags_Enum_Type'Value(Optionals_Flags_Enum_Type'Image(Option_Flag))))).Value.all;
		  begin
		     Wide_Text_Io.Put_Line
		       (Handling.To_Wide_String
			  (
			   Parameters_Flags_Enum_Type'Image(Parameters_Flags_Enum_Type'Value(Optionals_Flags_Enum_Type'Image(Option_Flag)))) &
			  " setted with parameter : " & 
			  "" & Parameter & "" & " ; ");
		  end;
	       elsif  Interf.Parameters_Kit.All_Parameters(Parameters_Flags_Enum_Type'Value(Optionals_Flags_Enum_Type'Image(Option_Flag))).Is_Setted then		  
		  Wide_Text_Io.Put_Line
		    (Handling.To_Wide_String(Parameters_Flags_Enum_Type'Image(Parameters_Flags_Enum_Type'Value(Optionals_Flags_Enum_Type'Image(Option_Flag)))) &
		       " setted without parameter.");		  
	       end if;
	 end case;
	 
      end loop;
   end Print_Parameters;
   
   procedure Parameters_Descriptions
     (From : in Interf_Record) is
   begin
      Wide_Text_Io.Put_Line("Help: manuel [ 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 Initialize (Int : in out Interf_Record) is
      Options_Kit : access Options_Kit_Array_Type;	   
   begin
      Options_Kit := new Options_Kit_Array_Type ' (Get_Options_From_Command_Line);
      
      case Options_Kit(Config_Filename).Is_Setted is
	 when False =>
	    Int.Parameters_Kit := Set_Parameters_from("Config_File.txt").all;
	 when True =>
	    Int.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) .. Parameters_Flags_Enum_Type'Last loop
	    if Parameters_Kit.All_Parameters(Parameter_Id).Is_Setted then
	       Int.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 Interface.");
	 raise;	 
      when others =>
	 Wide_Text_Io.Put_Line("Exception in initialization of Interface.");
	 raise;
   end Initialize;
   
   
   
   function Lines_Number (Line : in Wide_String) return Positive is
      Number : Positive := 56;
      Pos    : Natural := Index (Line, "x");
   begin
      if Pos /= 0 then
	 Number := Positive'Value(Handling.To_String(Line(1..Pos - 1)));
      end if;
      return Number;
   end Lines_Number;
   
   function Columns_Number (Line : in Wide_String) return Positive is
      Number : Positive := 160;
      Pos    : Natural := Index (Line, "x");
   begin
      if Pos /= 0 then
	 Number := Positive'Value(Handling.To_String(Line(Pos + 1..Line'last)));
      end if;
      return Number;
   end Columns_Number;
   
   
   
   function Get_Lines (Int : in Interf_Record) return Positive is
      Geometry_Parameter : constant Params.Parameter_Tagged_Record_Type :=
	Interf.Get_Parameter(Int, Params.Geometry);
      Lines : Line_Range := 67;
      
   begin
      if Geometry_Parameter.Is_Setted then
	 Lines := Lines_Number(Geometry_Parameter.Value.all);	 
      end if;
      return Lines;
   end Get_Lines;
   
   function Get_Cols (Int : in Interf_Record) return Positive is
      Geometry_Parameter : constant Params.Parameter_Tagged_Record_Type :=
	Interf.Get_Parameter(Int, Params.Geometry);
      Cols  : Column_Range := 240;
      
   begin
      if Geometry_Parameter.Is_Setted then
	 Cols := Columns_Number(Geometry_Parameter.Value.all);     
      end if;
      return Cols;
   end Get_Cols;

end El.Interf ;