with Adam.Abstracts;
use Adam.Abstracts;
with Adam.Terminal.Main;
use Adam.Terminal;
with Adam.Get_Password;
--with Adam.Human_Interface;
--use Adam.Human_Interface;

with Adam.Tools;
use Adam.Tools;

with Ada.Text_Io;

with Ada.Wide_Text_Io;
use Ada.Wide_Text_Io;

with Ada.Strings.Wide_Fixed;
use Ada.Strings.Wide_Fixed;
use Ada.Strings;
use Ada;

with Gnat.MD5;
use Gnat;

with Ada.Characters.Handling;
use Ada.Characters.Handling;
package body Adam.Textual.Main is
   
   procedure Initialize (Textual_Interface : in Main_Interface_access) is
      Errno : Integer := 0;
   begin      
      null;
   end Initialize;
   
   procedure Interaction (Textual_Interface : in Main_Interface_access) is
      Errno : Integer := 0;
      
      Help_Parameter : constant Parameter_Tagged_Record_Type :=
	Get_Parameter(Textual_Interface.all, Help);
      
      
      Lexic_name : access String := new String ' ("");
      Train_name : access String := new String ' ("");
      L1_Name : access String := new String ' ("");
      L2_Name : access String := new String ' ("");
      L1_Reuse : Boolean := True;
      L2_Reuse : Boolean := True;
      L1_Max_epocs : Positive := 1;
      L2_Max_epocs : Positive := 1;
      L1_Max_sampl : Positive := 36;
      L2_Max_Sampl : Positive := 1;
      L1_Conv : Float := 0.0125;
      L2_Conv : Float := 0.0;
      Max_Iter : Positive := 18;
   begin
      if Help_Parameter.Is_Setted then
	 Parameters_Descriptions(Textual_Interface.all);
	 return;
      end if;      
      if Textual_Interface.Get_Parameter(Lexic_Filename).Is_Setted then
	 Lexic_Name := new String ' (To_String(Textual_Interface.Get_Parameter(Lexic_Filename).Value.all));
      end if;
      if Textual_Interface.Get_Parameter(Train_Filename).Is_Setted then
	 Train_Name := new String ' (To_String(Textual_Interface.Get_Parameter(Train_Filename).Value.all));
      end if;
      
      if Textual_Interface.Get_Parameter(L1_Network_Filename).Is_Setted then
	 L1_Name := new String ' (To_String(Textual_Interface.Get_Parameter(L1_Network_Filename).Value.all));
      end if;
      
      L1_Reuse := Textual_Interface.Get_Parameter(L1_Reuse_network).Is_Setted;
      -- pass to rewrite default in human_object.Neurolog
      if Textual_Interface.Get_Parameter(L1_Max_Epochs).Is_Setted then
	 L1_Max_Epocs := Positive'Value(To_String(Textual_Interface.Get_Parameter(L1_Max_Epochs).Value.all));
      end if;
      if Textual_Interface.Get_Parameter(L1_Max_Samples).Is_Setted then
	 L1_Max_Sampl := Positive'Value(To_String(Textual_Interface.Get_Parameter(L1_Max_Samples).Value.all));
      end if;
      if Textual_Interface.Get_Parameter(L1_Converged).Is_Setted then
	 L1_Conv := Float'Value(To_String(Textual_Interface.Get_Parameter(L1_Converged).Value.all));
      end if;
      if Textual_Interface.Get_Parameter(L1_Max_Iteration).Is_Setted then
	 Max_Iter := positive'Value(To_String(Textual_Interface.Get_Parameter(L1_Max_Iteration).Value.all));
      end if;
      declare
	 Started : Boolean := False;
	 Char   : Character;	 
	 Errno : Integer;
	 
      begin    
	 Errno := System("clear" & Ascii.Nul);
	 Put_Line(Plain_Line);
	 Put_Line(border_Line);
	 Move(Border_Line, Empty_Line, Strings.Error, Left);
	 Replace_slice(Empty_Line, 59, 102, "--------------------------------------------", Strings.Error, Center);
	 Put_line(Empty_Line(Empty_Line'First..Index_Non_Blank(Empty_Line, Backward)));
	 Replace_Slice(Empty_Line, 59, 102, "-- Adamanborg is an cybernetic organism.  --", Strings.Error, Center);
	 Put_line(Empty_Line(Empty_Line'First..Index_Non_Blank(Empty_Line, Backward)));
	 Move(Border_Line, Empty_Line, Strings.Error, Left);
	 Replace_Slice(Empty_Line, 59, 102, "-- Adamanborg (C) Copyright 2016 E. Sens. --", Strings.Error, Center);
	 Put_line(Empty_Line(Empty_Line'First..Index_Non_Blank(Empty_Line, Backward)));
	 Replace_slice(Empty_Line, 59, 102, "--------------------------------------------", Strings.Error, Center);
	 Put_line(Empty_Line(Empty_Line'First..Index_Non_Blank(Empty_Line, Backward)));
	 Put_Line(Border_Line);
	 Put_Line(Plain_Line);
	 Put_line("Initialize Adamanborg...");

	 delay 1.5;
	 New_Line;
	 Put_line("Adamanborg initialized.");
	 New_Line;   
	 loop
	    	
	    begin
	       Errno := System("clear" & Ascii.Nul);
	       Put_Line(Plain_Line);	 
	       Put_Line(border_Line);
	       Move(Border_Line, Empty_Line, Strings.Error, Left);	 
	       Replace_slice(Empty_Line, 59, 102, "--------------------------------------------", Strings.Error, Center);
	       Put_line(Empty_Line(Empty_Line'First..Index_Non_Blank(Empty_Line, Backward)));
	       Replace_Slice(Empty_Line, 59, 102, "-- Adamanborg is an cybernetic organism.  --", Strings.Error, Center);
	       Put_line(Empty_Line(Empty_Line'First..Index_Non_Blank(Empty_Line, Backward)));
	       Move(Border_Line, Empty_Line, Strings.Error, Left);
	       Replace_Slice(Empty_Line, 59, 102, "-- Adamanborg (C) Copyright 2016 E. Sens. --", Strings.Error, Center);
	       Put_line(Empty_Line(Empty_Line'First..Index_Non_Blank(Empty_Line, Backward)));
	       Replace_slice(Empty_Line, 59, 102, "--------------------------------------------", Strings.Error, Center);
	       Put_line(Empty_Line(Empty_Line'First..Index_Non_Blank(Empty_Line, Backward)));   	 
	       Put_Line(border_Line);
	       Put_Line(Plain_Line);
	       if not Started then      
		  Put_line("Adamanborg suspended.");
	       else		  
		  Put_line("Adamanborg started.");      
	       end if; 
	       declare
		  Username_Parameter : constant Parameter_Tagged_Record_Type :=
		    Textual_Interface.Get_Parameter(Username);
		  hostname_Parameter : constant Parameter_Tagged_Record_Type :=
		    Textual_Interface.Get_Parameter(Hostname);
		  
		  
		  Host : access String := new String ' (To_String(Hostname_Parameter.Value.all));
		  Log  : access Wide_String := new Wide_String ' (Username_Parameter.Value.all);
		  Passwd   : Gnat.MD5.Message_Digest;
		  
	       begin
		  if (Username_Parameter.Is_Setted and
			
			Hostname_Parameter.Is_Setted) then
		     New_Line;
		     Put_line("Press 'Ctrl+D' to exit.");
		     Put_Line("Enter host address  : ");		    
		     Put_Line("Enter your logname  : ");
		     ---------------------------
		     -- Self logon            --
		     
		     Put("Enter your password : ");
		     Get_Password(Passwd);
		     Started := True;
		     --                       --
		     ---------------------------		     
		     New_Line;
		     begin
			
			Textual_Interface.Interfaces(Human_Class) := 
			  new Human_Interface_Type
			  (
			   Log,
			   Host,
			   new MD5.Message_Digest ' (Passwd)
			  );
			
			Human_Interface.Initialize(Human_Interface_Type(Textual_Interface.Interfaces(Human_Class).all),
						   
						   Lexic_Name,
						   Train_Name,
						   L1_Name,
						   L2_Name,
						   L1_Reuse,
						   L2_Reuse,
						   L1_Max_Epocs,
						   L2_Max_Epocs,
						   L1_Max_Sampl,
						   L2_Max_Sampl,
						   L1_Conv,
						   L2_Conv,
						   Max_iter
						  );
			Human_Interface.Run(Human_Interface_Type(Textual_Interface.Interfaces(Human_Class).all));
			
			Put_Line("Human Interface initialized.");
			
			if Textual_Interface.Parameters_Kit.All_Parameters(Wide_Geometry).Is_Setted then
			   Put_Line("Interface in Textual mode : 211x78 chars");
			   delay 2.0;
			   Terminal.Main.Main(Textual_Interface,
					      Textual_Interface.Parameters_Kit.All_Parameters(Quiet).Is_Setted,
					      78, 211, 
					      Errno);
			elsif Textual_Interface.Parameters_Kit.All_Parameters(Linux_Geometry).Is_Setted then
			   Put_Line("Interface in Textual mode : 160x64 chars");
			   delay 2.0;
			   Terminal.Main.Main(Textual_Interface,
					      Textual_Interface.Parameters_Kit.All_Parameters(Quiet).Is_Setted,
					      64, 160,
					      Errno);	 
			else
			   Put_Line("Interface in Textual mode : 80x25 chars");
			   delay 2.0;
			   Terminal.Main.Main(Textual_Interface,
					      Textual_Interface.Parameters_Kit.All_Parameters(Quiet).Is_Setted,
					      25, 80, 
					      Errno);
			end if;
			
			Put_Line("Going to halt Human interface...");
			Human_Interface.Halt(Human_Interface_Type(Textual_Interface.Interfaces(Human_Class).all));
			Human_Interface.Finalize(Human_Interface_Type(Textual_Interface.Interfaces(Human_Class).all));
			Put_Line("Human interface halted and finalized !");
		     end;
		  else
		     New_Line;
		     Put_Line("Adamanborg menu");
		     New_Line;
		     Put_Line(" Ctrl+A   => Start and Stop Adamanborg...");
		     Put_Line(" Ctrl+B   => connect to Adamanborg...");
		     Put_Line(" Ctrl+D  => Halt Adamanborg and exit.");
		     Text_Io.Get_Immediate(Char);		  
		     case Char is
			when Character'Val(1) =>
			   
			   loop
			      
			      Errno := System("clear" & Ascii.Nul);		  
			      Put_Line(Plain_Line);	 
			      Put_Line(border_Line);
			      Move(Border_Line, Empty_Line, Strings.Error, Left);		  
			      Replace_slice(Empty_Line, 59, 102, "--------------------------------------------", Strings.Error, Center);
			      Put_line(Empty_Line(Empty_Line'First..Index_Non_Blank(Empty_Line, Backward)));
			      Replace_Slice(Empty_Line, 59, 102, "-- Adamanborg is an cybernetic organism.  --", Strings.Error, Center);
			      Put_line(Empty_Line(Empty_Line'First..Index_Non_Blank(Empty_Line, Backward)));
			      Move(Border_Line, Empty_Line, Strings.Error, Left);
			      Replace_Slice(Empty_Line, 59, 102, "-- Adamanborg (C) Copyright 2016 E. Sens. --", Strings.Error, Center);
			      Put_line(Empty_Line(Empty_Line'First..Index_Non_Blank(Empty_Line, Backward)));
			      Replace_slice(Empty_Line, 59, 102, "--------------------------------------------", Strings.Error, Center);
			      Put_line(Empty_Line(Empty_Line'First..Index_Non_Blank(Empty_Line, Backward)));
			      Put_Line(border_Line);
			      Put_Line(Plain_Line);		  
			      if not Started then      
				 Put_line("Adamanborg suspended.");
			      else		  
				 Put_line("Adamanborg started.");      
			      end if;   		  		  
			      New_Line;
			      begin
				 
				 Put_line("Press 'Ctrl+M' to start and stop Adamanborg.");
				 Put_line("Press 'Ctrl+D' to return to Adamanborg menu.");
				 Text_Io.Get_Immediate(Char);
				 case Char is
				    when Character'Val(10) =>
				       if Started then
					  --Adam.Cybernetic.Organism.Stop(Org.all);
					  Put_line("Adamanborg suspended.");
					  Started := False;
				       else		  
					  --Adam.Cybernetic.Organism.Run(Org.all);
					  Put_line("Adamanborg started.");
					  Started := True;
				       end if;
				    when others =>
				       null;
				 end case;
			      exception
				 when End_Error =>			
				    exit;
			      end;
			   end loop;
			when Character'Val(2) =>
			   if Started then
			      begin
				 if not (Username_Parameter.Is_Setted and
					   
					   Hostname_Parameter.Is_Setted) then
				    Put("Enter host address  : ");
				    Host := new String ' (Text_Io.Get_Line);
				    Put("Enter your logname  : ");
				    Log := new Wide_String ' (Get_Line);
				    Put("Enter your password : ");
				    Get_Password(Passwd);
				    New_Line;
				 end if;
				 begin
				    
				    Textual_Interface.Interfaces(Human_Class) := 
				      new Human_Interface_Type
				      (
				       Log,
				       Host,
				       new MD5.Message_Digest ' (Passwd)
				      );
				    
				    Human_Interface.Initialize(Human_Interface_Type(Textual_Interface.Interfaces(Human_Class).all),
							       
							       Lexic_Name,
							       Train_Name,
							       L1_Name,
							       L2_Name,
							       L1_Reuse,
							       L2_Reuse,
							       L1_Max_Epocs,
							       L2_Max_Epocs,
							       L1_Max_Sampl,
							       L2_Max_Sampl,
							       L1_Conv,
							       L2_Conv,
							       Max_iter
							      );
				    Human_Interface.Run(Human_Interface_Type(Textual_Interface.Interfaces(Human_Class).all));
				    
				    Put_Line("Human Interface initialized.");
				    
				    if Textual_Interface.Parameters_Kit.All_Parameters(Wide_Geometry).Is_Setted then
				       Put_Line("Interface in Textual mode : 211x78 chars");
				       delay 2.0;
				       Terminal.Main.Main(Textual_Interface,
							  Textual_Interface.Parameters_Kit.All_Parameters(Quiet).Is_Setted,
							  78, 211, 
							  Errno);
				    elsif Textual_Interface.Parameters_Kit.All_Parameters(Linux_Geometry).Is_Setted then
				       Put_Line("Interface in Textual mode : 160x64 chars");
				       delay 2.0;
				       Terminal.Main.Main(Textual_Interface,
							  Textual_Interface.Parameters_Kit.All_Parameters(Quiet).Is_Setted,
							  64, 160,
							  Errno);	 
				    else
				       Put_Line("Interface in Textual mode : 80x25 chars");
				       delay 2.0;
				       Terminal.Main.Main(Textual_Interface,
							  Textual_Interface.Parameters_Kit.All_Parameters(Quiet).Is_Setted,
							  25, 80, 
							  Errno);
				    end if;
				    
				    Put_Line("Going to halt Human interface...");
				    Human_Interface.Halt(Human_Interface_Type(Textual_Interface.Interfaces(Human_Class).all));
				    Human_Interface.Finalize(Human_Interface_Type(Textual_Interface.Interfaces(Human_Class).all));
				    Put_Line("Human interface halted and finalized !");
				 end;
			      exception
				 when End_Error =>
				    New_Line;
				    exit;
			      end;
			   end if;
			when others =>
			   null;
		     end case;		  		     
		  end if;
	       exception
		  when End_Error =>
		     New_Line;
		     exit;
	       end;
	    end;
	 end loop;
	 
      end;            
      
   end Interaction;
   
end Adam.Textual.Main;
