
with Adam.Abstracts;
use Adam.Abstracts;
with Adam.Results;
use Adam.Results;
with Gnat.Os_Lib;
use Gnat.Os_Lib;
with Adam.Values;
use Gnat;
with Adam.Operating_System;
use Adam.Operating_System;

with ANSI_Console;

with Adam.Terminal.Ansi_Consoles;
with Adam.Versions.Version_Io;
with Ada.Characters.Handling;
use Ada.Characters.Handling;
use Ada.Characters;
with Ada.Strings.Fixed;
with Ada.Strings.Wide_Fixed;
with Ada.Strings.Unbounded;
use Ada.Strings;
with Ada.Wide_Characters;
with Ada.Wide_Characters.Handling;

with Ada.Calendar;
use Ada.Calendar;

with Ada.Calendar.Formatting;

with Adam.Shared_Times;
use Adam.Shared_Times;

with Adam.Manuals;
use Adam.Manuals;

with Adam.Tools;
use Adam.Tools;

with GNAT.Directory_Operations;
use GNAT.Directory_Operations;
with Adam.Shells;
use Adam.Shells;
with Adam.Linux;
with Adam.Computing;
use Adam.Computing;
with Adam.Web;
with Gnat.Regexp;

with Ada.Wide_Text_Io;
with Ada.Numerics.Discrete_Random;
with Ada.Numerics.Float_Random;


with PragmARC.Ansi_Tty_Control;
use PragmARC.Ansi_Tty_Control;

with Ada.Text_Io;

with Ada.Strings.UTF_Encoding.Strings;
with Ada.Strings.UTF_Encoding.Wide_Strings;

with Aws.Client;
with Gnat.Sockets;
use Gnat.Sockets;

with Gnat.MD5;
with Adam.Abstracts.Objects.Environments;
use Adam.Abstracts.Objects.Environments;


with Adam.Common;
use Adam.Common;
with Adam.abstracts.Objects;
use Adam.abstracts.Objects;
with Adam.Classified.Classes;
use Adam.Classified.Classes;
use Adam.Classified;
with Adam.Classified.Text_Object;
use Adam.Classified.Text_Object;
with Adam.Classified.Date_Object;
use Adam.Classified.Date_Object;
with Adam.Classified.Real_Object;
use Adam.Classified.Real_Object;

with Adam.Human_Interface;
use Adam.Human_Interface;

with Adam.Completion;

with Adam.Accounting;
use Adam.Accounting;

use Ada;

package body Adam.Terminal.Main is   
   
   
   package Text_Io renames Ada.Wide_Text_Io;
   use Text_Io;
         
   
   use type Results.U_String;
   
   
   type Command_Line_History_Type is array (Positive range <>) of Wide_String_Access;
   
   
   procedure Main (Shell_Interface : in Main_Interface_access;
		   Quiet : in Boolean; Lines : in Positive; Columns : in Positive; Errno : out Integer) is
            
      User_Name : constant Common.String_Access := new Wide_String ' 
	(Human_Interface_Type
	   (Shell_Interface.Interfaces(Human_Class).all).User_Name.all);
      Host_addr : constant String := 
	(Human_Interface_Type
	   (Shell_Interface.Interfaces(Human_Class).all).Host_Addr.all);
      
      
      Env : Environment_Access;	 
      
	 
      Cyborg_Data_Max  : Natural := 0;	 	 
      Data_Buffer_Index : Natural := 0;	 
      Data_Buffer : Common.Response_Type;
      
      Cyborg_Line : Common.String_Access := new Wide_String ' ("");
      
      
      Human_Line : Common.String_Access := new Wide_String ' ("");	 
      Buffer : Common.String_Access := new Wide_String ' ("");
      
      --
      ------------------------------------------------------------------------
      
      
      
      
      
      
      -----------------------------------------
      --         Screen Saver 1.2.0          --
      -----------------------------------------
      -- Matrix style.
      
      subtype SubGraphical_Char_Type is Character range Character'Val(32) .. Character'Val(126);
      
      subtype Color_Type is Positive range 31..37;
      
      
      
      package Color_Random is new Ada.Numerics.Discrete_Random(Color_Type);
      package SGCT_Random is new Ada.Numerics.Discrete_Random(SubGraphical_Char_Type);
      package Bool_Random is new Ada.Numerics.Discrete_Random(boolean);

      
      type Matrix_Type is array (Positive range <>, Positive range <>) of Os_Lib.String_Access;
      
      
      The_Matrix : Matrix_Type(1..lines, 1..columns) := (others => (others => new String ' (Space & "")));
      
      Matrix_Buffer : Matrix_Type(1..1, The_Matrix'Range(2));
      
      
      SGCT_Gen : SGCT_Random.Generator;
      
      Bool_Gen : Bool_Random.Generator;
      
      Color_Gen : Color_Random.Generator;
      
      
      Matrix_Switch : array (The_Matrix'Range(2)) of Boolean;
      

      
      task type Screen_Saver_Type is
	 entry Start;
	 entry Stop;
	 entry Suspend;
      end Screen_Saver_Type;
      
      task body Screen_Saver_Type is
	 
	 Screen_Saver_Dateout : Time := Clock;
	 
	 -- Ten minutes.
	 Saver_Delay : Duration := 168000.0;
	 
      begin
	 
	 
	 
	 loop
	    
	    loop
	       select
		  accept Start;
		  exit;
	       or
		  accept Stop;
	       or
		  accept Suspend;
	       end select;
	    end loop;
	    
	    begin Saver_Loop : 
		
		loop
		   
		   -- Reset The matrix when restart ;
		   
		   for Lines in The_Matrix'Range(1) loop
		      for Columns in The_Matrix'Range(2) loop			    
		   	 Os_Lib.Free(The_Matrix(Lines, Columns));
		      end loop;
		   end loop;
		   The_Matrix := (others => (others => new String ' (Space & "")));
		   
		   Screen_Saver_Dateout := Clock + Saver_Delay;
		   
		   loop
		      select
			 accept Start;
		      or
			 accept Stop;
			 exit Saver_Loop;
		      or
			 
			 accept Suspend;
			 Screen_Saver_Dateout := Clock + Saver_delay;
		      or
			 delay until Screen_Saver_Dateout;
			 Color_Random.Reset(Color_Gen);
			 exit;
		      end select;
		   end loop;
		   
		   
		   loop
		      select
			 accept Start;
		      or
			 accept Stop;
			 exit Saver_Loop;
		      or
			 accept Suspend;
			 exit;
		      or delay 0.075;
		      end select;
		      
		      for Columns in The_Matrix'Range(2) loop			 
			 Matrix_Switch(Columns) := Bool_Random.Random(Bool_Gen); 
		      end loop;
		      
		      
		      
		      for Columns in The_Matrix'Range(2) loop
			 
			 for Lines in reverse The_Matrix'First+1..The_Matrix'last loop
			    if Matrix_Switch(Columns) then			       
			       The_Matrix(Lines, Columns) := The_Matrix(Lines - 1, Columns);
			       
			    end if;
			    
			 end loop;
			 
		      end loop;
		      
		      
		      for Columns in The_Matrix'Range(2) loop
			 if Matrix_Switch(Columns) then
			    
			    The_Matrix(1, Columns) := 
			      
			      new String ' 
			      
			      (
			       
			       Character'Val(27) & "[0" 
				 & 
				 Integer_Image(Color_Random.Random(Color_Gen)) & "m"
				 & 	 
				 SGCT_Random.Random(SGCT_Gen)				    
			      );
			 else
			    Os_Lib.Free(The_Matrix(1, Columns));
			    The_Matrix(1, Columns) := 
			      
			      new String ' 
			      
			      (Space & "");
			    
			    
			 end if;
		      end loop;
		      		      
		      for Columns in The_Matrix'Range(2) loop
			 for Lines in The_Matrix'Range(1) loop
			    if The_Matrix(Lines, Columns) /= null then
			       
			       Ada.Text_Io.Put(Position(Lines, Columns) & The_Matrix(Lines, Columns).all);
			       
			    end if;			    
			    
			 end loop;
			 Os_Lib.Free(The_Matrix(The_Matrix'Last, Columns));
		      end loop;
		   end loop;
		   
		   
		end loop Saver_Loop;
	    end;
	 end loop;
	 
      end Screen_Saver_Type;
      
      
      Matrix_Saver : Screen_Saver_Type;
      
      
      
      package My_Ansi_Consoles is new Adam.Terminal.Ansi_Consoles(Lines, Columns);
      use My_Ansi_Consoles;
      
      Term_Width : constant Positive := Columns - 2;
      Command_Max_Lines  : constant Positive := Lines - (11 + 9); -- instead 11 + 8
      Result_Max_Lines   : constant Positive := Lines - (9 + 9);-- instead 9 + 8
      Computation_Max_Lines : constant Positive := Lines - (4 + 9);-- instead 9 + 8
      
      Chars_Max : constant Positive := Term_Width-10;
      Lines_Max  : constant Ada.Wide_Text_Io.Count := Ada.Wide_Text_Io.Count(Lines-22);
      Left_Lines : Text_Io.Count := Ada.Wide_Text_Io.Count(Lines-23);
      
      Plain_Line : constant Wide_String(1..Chars_Max) := Wide_Fixed."*"(Chars_Max, ' ');
      border_line : constant Wide_String(1..Chars_Max) := (Wide_Fixed."*"(3,' ') & 
							     Wide_Fixed."*"(Chars_Max-6, ' ') & 
							     Wide_Fixed."*"(3, ' '));      
      
      subtype Mode_Index_Type is natural range 0..8;

      Header_Lines : constant array (Mode_Index_Type) of access Wide_String := 
        (new Wide_String ' ("Adamanborg " & 
			      To_Wide_String(Adam.Versions.Version_Io.To_String(Adam.Versions.version))),
         new Wide_String ' ("A.i. management"),
         new Wide_String ' ("Data technologies"),
         new Wide_String ' ("All manuals"),
         new Wide_String ' ("Gnu/Linux interfaces"),
         new Wide_String ' ("Environment parameters"),
         new Wide_String ' ("Self-Programming process"),
         new Wide_String ' ("Plans administration"),
         new Wide_String ' ("Adamanborg call")
	);
      
      
      
      W1 : constant Window_Type := ( -- Header of Program.
				     L =>  1,
				     C =>  2,
				     H =>  3,
				     W => Term_Width,
				     Frame_Type      => Single_Line_Frame,
				     Frame_Color     => Ansi_Console.Yellow,
				     Close_Box_Color => Ansi_Console.Red);

      W2 : constant Window_Type := ( -- Command_line and text.
				     L => 11,
				     C =>  2,
				     H =>  Command_Max_Lines,
				     W => Term_Width,
				     Frame_Type      => Double_Line_Frame,
				     Frame_Color     => Ansi_Console.Yellow,
				     Close_Box_Color => Ansi_Console.Red);

      W3 : constant Window_Type := ( -- Quit (exit program) window information.
				     L => Lines-5,
				     C =>  2,
				     H =>  3,
				     W => Term_Width,
				     Frame_Type      => Single_Line_Frame,
				     Frame_Color     => Ansi_Console.Yellow,
				     Close_Box_Color => Ansi_Console.Red);
      
      W4 : constant Window_Type := ( -- Status message Window.
				     L =>  4,
				     C =>  2,
				     H =>  7,
				     W => Term_Width,
				     Frame_Type      => Single_Line_Frame,
				     Frame_Color     => Ansi_Console.Yellow,
				     Close_Box_Color => Ansi_Console.Red);

      
      W5 : constant Window_Type := ( -- Search & command process info Window
				     L =>  4,
				     C =>  2,
				     H =>  4,
				     W => Term_Width,
				     Frame_Type      => Single_Line_Frame,
				     Frame_Color     => Ansi_Console.Yellow,
				     Close_Box_Color => Ansi_Console.Red);
      
      
      W6 : constant Window_Type := ( -- Search window
				     L =>  4,
				     C =>  2,
				     H =>  5,
				     W => Term_Width,
				     Frame_Type      => Single_Line_Frame,
				     Frame_Color     => Ansi_Console.Yellow,
				     Close_Box_Color => Ansi_Console.Red);

      W7 : constant Window_Type := ( -- Search result info Window
				     L =>  4,
				     C =>  2,
				     H =>  5,
				     W => Term_Width,
				     Frame_Type      => Single_Line_Frame,
				     Frame_Color     => Ansi_Console.Yellow,
				     Close_Box_Color => Ansi_Console.Red);


      W8 : constant Window_Type := ( -- Alarm and Timer.
				     L =>  Lines-2,
				     C =>  2,
				     H =>  3,
				     W => Term_Width,
				     Frame_Type      => Single_Line_Frame,
				     Frame_Color     => Ansi_Console.Yellow,
				     Close_Box_Color => Ansi_Console.Red);

      W9 : constant Window_Type := ( -- Current date and time.
				     L =>  Lines-8,
				     C =>  2,
				     H =>  3,
				     W => Term_Width,
				     Frame_Type      => Single_Line_Frame,
				     Frame_Color     => Ansi_Console.Yellow,
				     Close_Box_Color => Ansi_Console.Red);
      
      W10 : constant Window_Type := ( -- Command result : out_file.txt.
				      L =>  9,
				      C =>  2,
				      H =>  Result_Max_lines,
				      W => Term_Width,
				      Frame_Type      => Single_Line_Frame,
				      Frame_Color     => Ansi_Console.Yellow,
				      Close_Box_Color => Ansi_Console.Red);
      
      
      W11 : constant Window_Type := ( -- Command info status
				      L =>  4,
				      C =>  2,
				      H =>  5,
				      W => Term_Width,
				      Frame_Type      => Single_Line_Frame,
				      Frame_Color     => Ansi_Console.Yellow,
				      Close_Box_Color => Ansi_Console.Red);
      
      
      W12 : constant Window_Type := ( -- OS environnement
				      L =>  4,
				      C =>  2,
				      H =>  Lines-12,
				      W => Term_Width,
				      Frame_Type      => Single_Line_Frame,
				      Frame_Color     => Ansi_Console.Yellow,
				      Close_Box_Color => Ansi_Console.Red);
      
      W13 : constant Window_Type := ( -- OS others Directives.
				      L =>  10,
				      C =>  2,
				      H =>  Result_Max_Lines - 1,
				      W => Term_Width,
				      Frame_Type      => Single_Line_Frame,
				      Frame_Color     => Ansi_Console.Yellow,
				      Close_Box_Color => Ansi_Console.Red);
      
      W14 : constant Window_Type := ( -- Command_line and text.
				      L => 4,
				      C =>  2,
				      H =>  6,
				      W => Term_Width,
				      Frame_Type      => Double_Line_Frame,
				      Frame_Color     => Ansi_Console.Yellow,
				      Close_Box_Color => Ansi_Console.Red);
      
      
      W15 : constant Window_Type := ( -- Computation Window
				      L => 4,
				      C =>  2,
				      H =>  Computation_Max_Lines,
				      W => Term_Width,
				      Frame_Type      => Double_Line_Frame,
				      Frame_Color     => Ansi_Console.Yellow,
				      Close_Box_Color => Ansi_Console.Red);

      
      
      procedure Mode_Info_Status (Window : in Window_Type; Mode : in Command_Type) is
      begin
         case Mode is
            when Null_Item .. Adamanborg_Call =>
               My_Ansi_Consoles.Draw_Window (Window);      
               My_Ansi_Consoles.Draw_Centered (Window, 1, Ansi_Console.White, (Header_Lines(Command_Type'Pos(Mode)).all));
	    when Gnushell =>
	       My_Ansi_Consoles.Draw_Window (Window);      
               My_Ansi_Consoles.Draw_Centered (Window, 1, Ansi_Console.White, "GnuShell mode : ");
            when others =>
	    
               My_Ansi_Consoles.Draw_Window (Window);      
               My_Ansi_Consoles.Draw_Centered (Window, 1, Ansi_Console.White, To_Wide_String(Command_Type'Image(Mode)));
               null;
         end case;
      end Mode_Info_Status;
      
      -- Messages pour que l'utilisateur(rice) ne se sente pas perdu(e).
      procedure Main_Quit_Info_Status(Window : in Window_Type; On_Esc : Boolean) is

      begin
         if On_Esc then

            My_Ansi_Consoles.Draw_Window (Window);      
            My_Ansi_Consoles.Draw_Centered (Window, 1, Ansi_Console.White, "press one Escape character to Quit !");
         else

            My_Ansi_Consoles.Draw_Window (Window);      
            My_Ansi_Consoles.Draw_Centered (Window, 1, Ansi_Console.White, "press two Escape character to Quit !");
         end if;
      end Main_Quit_Info_Status;

      -- Functions availables :
      procedure Main_Info_Status (Window : in Window_Type) is
      begin

         My_Ansi_Consoles.Draw_Window (Window);
         My_Ansi_Consoles.Draw (Window, 1, 3, Ansi_Console.White, "F1 : A.i. management; F2 : Data technologies; F3 : All manuals;");                   
         My_Ansi_Consoles.Draw (Window, 2, 3, Ansi_Console.White, "F4 : Gnu/Linux interface; F5 : Environment parameters;");
         My_Ansi_Consoles.Draw (Window, 3, 3, Ansi_Console.White, "F6 : Self-Programming process; F7 : Plans Administration;");
         --My_Ansi_Consoles.Draw (Window, 4, 3, Ansi_Console.White, "F8 : Adamanborg call; 'Search' with Argument(s) string; 'Alarm' with string;");
	 My_Ansi_Consoles.Draw (Window, 4, 3, Ansi_Console.White, "F8 : not used; 'Search' with Argument(s) string; 'Alarm' with string;");
         My_Ansi_Consoles.Draw (Window, 5, 3, Ansi_Console.White, "F9 : Start or Stop Timer; F10 : Set or Unset Alarm; F11 : Stop Alarm;");                 
      end Main_Info_Status;
      
      
      procedure Man_Info (Window : in Window_Type) is
      begin
         My_Ansi_Consoles.Draw (Window, 1, 3, Ansi_Console.White, "1 General Commands ; 2 System Calls ;");
         My_Ansi_Consoles.Draw (Window, 2, 3, Ansi_Console.White, "3 Library functions, covering in particular the C standard Library ;");
         My_Ansi_Consoles.Draw (Window, 3, 3, Ansi_Console.White, "4 Special files (usually devices, those found in /dev) and Drivers ;");
         My_Ansi_Consoles.Draw (Window, 4, 3, Ansi_Console.White, "5 File formats and Conventions ; 6 Games and Screensavers ;");
         My_Ansi_Consoles.Draw (Window, 5, 3, Ansi_Console.White, "7 Miscellanea ; 8 System administration commands and Daemons.");         
      end Man_Info;                                                                             
      
      -- Timer info status
      procedure Timer_Info_Status (Window : in Window_Type; Message : in String) is
      begin
         My_Ansi_Consoles.Draw_Window (Window);
         My_Ansi_Consoles.Draw (Window, 1, 3, Ansi_Console.White, To_Wide_String(Message));
      end Timer_Info_Status;

      

      -- Date and alarm info printing.
      procedure Date_And_Alarm_Info_Status (Window : in Window_Type; Message : in String) is
      begin
         My_Ansi_Consoles.Draw_Window (Window);      
         My_Ansi_Consoles.Draw (Window, 1, 3, Ansi_Console.White, To_Wide_String(Message));
      end Date_And_Alarm_Info_Status;


      procedure Run_Gtk (Window : in Window_Type; Shell_Interface : in Main_Interface_access; Errno : out Integer) is
         
         Arguments : access Gnat.Os_Lib.Argument_List;

         Command   : constant access String := new String ' ("/usr/bin/xterm" & Character'Val(0));

      begin

         if Gnat.Os_Lib.Getenv("DISPLAY").all = "" then
            
            My_Ansi_Consoles.Draw_Window (Window);      
            My_Ansi_Consoles.Draw_Centered (Window, 2, Ansi_Console.White, "X not running on this session.");
            My_Ansi_Consoles.Draw_Centered (Window, 3, Ansi_Console.White, "Please, start X and try again.");
            Move_Cursor_To(Window, 3, 5);


            
            delay 2.5;
            Errno := -1;
            return;
         else
            if Quiet then
	       if Lines = 25 and Columns = 80 then
		  Arguments := 
		    new Gnat.Os_Lib.Argument_List ' (1 => new string ' ("-geometry" & Character'Val(0)),
						     2 => new string ' (Integer_Image(80) & "x" & Integer_Image(25) & Character'Val(0)),
						     3 => new string ' ("-e" & Character'Val(0)),
						     4 => new string ' ("Adamanborg/bin/Adamanborg" & Character'Val(0)),
						     5 => new string ' ("-x" & Character'Val(0)),
						     6 => new String ' ("-q"));
	       elsif Lines = 64 and Columns = 160 then
		  
		  
		  Arguments := 
		    new Gnat.Os_Lib.Argument_List ' (1 => new string ' ("-geometry" & Character'Val(0)),
						     2 => new string ' (Integer_Image(80) & "x" & Integer_Image(25) & Character'Val(0)),
						     3 => new string ' ("-e" & Character'Val(0)),
						     4 => new string ' ("Adamanborg/bin/Adamanborg" & Character'Val(0)),
						     5 => new string ' ("-wx" & Character'Val(0)),
						     6 => new String ' ("-q"));
		  
	       elsif Lines = 78 and Columns = 211 then
		  
		  Arguments := 
		    new Gnat.Os_Lib.Argument_List ' (1 => new string ' ("-geometry" & Character'Val(0)),
						     2 => new string ' (Integer_Image(80) & "x" & Integer_Image(25) & Character'Val(0)),
						     3 => new string ' ("-e" & Character'Val(0)),
						     4 => new string ' ("Adamanborg/bin/Adamanborg" & Character'Val(0)),
						     5 => new string ' ("-Wx" & Character'Val(0)),
						     6 => new String ' ("-q"));
		  
	       end if;
	    else
	       if Lines = 25 and Columns = 80 then
		  
		  Arguments := 
		    new Gnat.Os_Lib.Argument_List ' (1 => new string ' ("-geometry" & Character'Val(0)),
						     2 => new string ' (Integer_Image(80) & "x" & Integer_Image(25) & Character'Val(0)),
						     3 => new string ' ("-e" & Character'Val(0)),
						     4 => new string ' ("Adamanborg/bin/Adamanborg" & Character'Val(0)),
						     5 => new string ' ("-x" & Character'Val(0))                                          
						    );
		 
	       elsif Lines = 64 and Columns = 160 then
		  
		  
		  Arguments := 
		    new Gnat.Os_Lib.Argument_List ' (1 => new string ' ("-geometry" & Character'Val(0)),
						     2 => new string ' (Integer_Image(80) & "x" & Integer_Image(25) & Character'Val(0)),
						     3 => new string ' ("-e" & Character'Val(0)),
						     4 => new string ' ("Adamanborg/bin/Adamanborg" & Character'Val(0)),
						     5 => new string ' ("-wx" & Character'Val(0))                                          
						    );
		  
	       elsif Lines = 78 and Columns = 211 then
		  
		  Arguments := 
		    new Gnat.Os_Lib.Argument_List ' (1 => new string ' ("-geometry" & Character'Val(0)),
						     2 => new string ' (Integer_Image(80) & "x" & Integer_Image(25) & Character'Val(0)),
						     3 => new string ' ("-e" & Character'Val(0)),
						     4 => new string ' ("Adamanborg/bin/Adamanborg" & Character'Val(0)),
						     5 => new string ' ("-Wx" & Character'Val(0))                                          
						    );
		  
	       end if;
	       
            end if;            
            

            My_Ansi_Consoles.Draw_Window (Window);      
            My_Ansi_Consoles.Draw_Centered (Window, 2, Ansi_Console.White, "X is running...");
            My_Ansi_Consoles.Draw_Centered (Window, 3, Ansi_Console.White, "Going to start Adamanborg (graphical mode)");
            Move_Cursor_To(Window, 3, 5);
            delay 2.5;
         end if;
         if Arguments'Last < 1 then
            Text_Io.Put_Line("Run Adamanborg : error : Arguments = null.");
            return;
         end if;      
         Gnat.Os_Lib.Normalize_Arguments(Arguments.all);
	 Shell_Interface.Spawn_Result.Process_Id := Gnat.Os_Lib.Non_Blocking_Spawn (Command.all, Arguments.all);               
         Errno := 0;

      end Run_Gtk;            
      
      subtype Seg_Type is Natural range 1..16;
      
      package Seg_Rand is new Ada.Numerics.Discrete_Random(Seg_Type);
      
      Seg_Gen : Seg_Rand.Generator;      
      
      
      type Code_Type is
	 record
	    Prefix : Strings.Unbounded.Unbounded_String;
	    Radix  : Strings.Unbounded.Unbounded_String;
	    Suffix : Strings.Unbounded.Unbounded_String;
	 end record;
      
      
      
      package Code_Random is
	 function Random(Length : in Positive) return String;
	 procedure  Reset;
      end Code_Random;
      
      package body Code_Random is
	 
	 Alphabet : constant String := "0123456789-abcdefghijklmnopqrstuvwxyz.";
	 
	 subtype Digit_Type is Positive range 1..Alphabet'Length;
	 
	 package Digit_Random is new Ada.Numerics.Discrete_Random(Digit_Type);
	 use Digit_Random;
	 Digit_Gen : Digit_Random.Generator;
	 
	 procedure  Reset is
	 begin
	    Reset(Digit_Gen);
	 end Reset;
	 
	 function Random(Length : in Positive) return String is
	    
	    Code : String(1..Length);
	    Lock : Boolean := True;
	    Char : Character;
	    Index : natural := 0;
	 begin	    
	    while Index + 1 <= Length loop	       
	       char := Alphabet(Random(Digit_Gen));
	       if Index + 1 = Length then
		  Lock := True;
	       end if;
	       if not Lock then
		  if char = '.' or char = '-' then
		     Lock := True;
		  end if;
		  Code(Index + 1) := Char;
		  Index := Index + 1;
	       elsif char /= '.' and char /= '-' then		  
		  Code(Index + 1) := Char;
		  Index := Index + 1;		  		  
		  Lock := False;	       
	       end if;
	    end loop;	    
	    return Code;
	 end Random;
      end Code_Random;

      use Code_Random;

      type Top_Level_Type is (Org, Net, Edu, Fr, En, Us, Ca, Be);
      
      package Top_Level_Rand is new Ada.Numerics.Discrete_Random(Top_Level_Type);
      Top_Level_Gen : Top_Level_Rand.Generator;
      
      
      
      task type Web_Search_Type (Window : access Window_Type; Search_Result : access Search_Result_Type; Pattern : access Wide_String; Errno : access Integer) is	
	 entry Suspend;
	 entry Start;
	 entry Halt;
      end Web_Search_Type;
      
      task body Web_Search_Type is
	 
	 End_Of_Task, Done, Suspended : Boolean := False;
	 
         Current_Address : OS_Lib.String_Access := new String ' (Host_Addr);
	 Current_Path : OS_Lib.String_Access := new String ' ("");
	 Buffer_Path : OS_Lib.String_Access := new String ' ("");
	 
	 protocol : OS_Lib.String_Access := new String ' ("http://");
	 
         Current_Document_Name : Wide_String_Access := new Wide_String ' ("");
	 Regular_Exp : Regexp.Regexp;
	 Sub_Regular_Exp : Regexp.Regexp;
	 
	 -- HTTP 1.1.
	 Code : Code_Type;
	 
	 
	 Timeouts : Duration := 10.0;
	       
	 IP_Address : Sockets.Inet_Addr_Type;
	 
	 Sub_Top : Natural := Pattern'First;
	 Sub_Index : Natural := Wide_Fixed.Index(Pattern.all, "*", Sub_Top + 1);	 
      begin	 
     First_Loop :
	 loop
	    
	    declare
	       Host_Entry  : constant Sockets.Host_Entry_Type  := Sockets.Get_Host_By_Name(Current_Address.all);
	    begin	       
	       
	       Regular_Exp := Regexp.Compile(To_String(Pattern.all), True, True);
	       Free(Search_Result.Pattern);
	       Search_Result.Pattern := new Wide_String ' ((Pattern.all));
	       
	       IP_Address := Sockets.Addresses(Host_Entry);
	       
	       Sub_Regular_Exp := Regexp.Compile(To_String(Pattern(Sub_Top..Sub_Index)), True, True);
	       
	       Web.Web_Search(Current_Address.all, Protocol.all & Image(Ip_Address) & Current_Path.All, Timeouts, Search_Result.all);
	       
	       Os_Lib.Free(Search_Result.Address);
	       Search_Result.Address := new String ' (Protocol.all & Current_Address.all & Current_Path.all);
	       Free(Current_Document_Name);
	       Current_Document_Name := new Wide_String ' (Search_Result.Doc_Name.all);         
	       My_Ansi_Consoles.Draw_Window (Window.all);
	       My_Ansi_Consoles.Draw (Window.all, 1, 2, Ansi_Console.White, "Searching for : " & (Pattern.all));
	       My_Ansi_Consoles.Draw (Window.all, 2, 2, Ansi_Console.White, "look at : " & 
					Handling.To_Wide_String(Search_Result.Address.all));
	       My_Ansi_Consoles.Draw (Window.all, 3, 2, Ansi_Console.White, "Document name : " & (Current_Document_Name.all));
	       
	       for Line_Index in Search_Result.File_Content'Range loop
		  declare
		     
		     Line : constant String := To_String(-Search_Result.File_Content(Line_Index));		     
		  begin
		     
		     if Regexp.Match(Line, Regular_Exp) then
			Ada.Text_Io.Put(Character'Val(7));
			Errno.all := 0;
			Done := True;
			exit First_Loop;
		     elsif Regexp.Match(Line, Sub_Regular_Exp) then
			Ada.Text_Io.Put(Character'Val(7));
			Errno.all := 0;	
			Free(Search_Result.Pattern);
			Search_Result.Pattern := new Wide_String ' (Pattern(Sub_Top..Sub_Index));
			Done := True;
			declare
			   Top_Href : constant Natural := Fixed.Index(Line, "href=") + 6;
			   Href_Index  : constant Natural := Fixed.Index(Line, """", Top_Href+1) - 1;
			   Protocol_Index  : constant Natural := Fixed.Index(Line, "http", Top_Href);
			   
			begin			   
			   if Top_Href > 6  then
			      if Protocol_Index /= 0 then
				 Os_Lib.Free(protocol);				 
				 Protocol := new String ' (Line(Protocol_Index..Fixed.Index(Line, ":", Protocol_Index)) & "//");
				 declare
				    Top_Domain    : constant Natural := Fixed.Index(Line, "//", Protocol_Index + 1) + 2;
				    Domain_Index  : constant Natural := Fixed.Index(Line, "/", Top_domain + 1) - 1;
				 begin
				    if Top_Domain > 2 and then (Domain_Index > 0 and Domain_Index <= Href_Index) then
				       Os_Lib.Free(Current_Address);
				       Current_Address := new String ' (Line(Top_Domain .. Domain_Index));
				       if Domain_Index + 1 < Href_Index then
					  Os_Lib.Free(Current_Path);
					  Current_Path := new String ' (Line(Domain_Index + 1 .. Href_index));
				       end if;
				       Done := False;
				    elsif Top_Domain > 2 then
				       Os_Lib.Free(Current_Address);
				       Current_Address := new String ' (Line(Top_domain .. Href_index));
				       Os_Lib.Free(Current_Path);
				       Current_Path := new String ' ("");
				       Done := False;
				       
				    else
				       Done := True;				       
				    end if;
				    exit First_Loop;
				 end;
			      else
				 
				 Os_Lib.Free(Buffer_Path);
				 Buffer_Path := new String ' (Current_Path.all & '/' & Line(Top_Href..Href_Index));
				 Os_Lib.Free(Current_Path);
				 Current_Path := new String ' (Buffer_Path.all);
				 Done := False;
			      end if;
			      exit;
			   else
			      Done := True;
			      exit First_Loop;
			   end if;
			end;
		     end if;
		  end;
	       end loop;	    
	       Sub_Top := Sub_Index;
	       Sub_Index := Wide_Fixed.Index(Pattern.all, "*", Sub_Top + 1);	       
	       if Sub_Index <= Sub_Top then		  
		  Done := False;		  
	       end if;	       
	       exit when Sub_Index <= Sub_Top;
	       
	       
	    exception
	       when others =>
		  exit;
	       
	    end;
	    
	 end loop First_Loop;
	 
	 My_Ansi_Consoles.Clear_Screen;
	 
	 Code_Random.Reset;
	 Top_Level_Rand.Reset(Top_Level_Gen);
	 
     Main_Search : 
	 while not Done loop	    	    	    	    		    	    
	    begin
	       while Suspended loop
		  select
		     accept Halt;
		     End_Of_Task := True;
		     exit Main_Search;		  
		  or
		     accept Start;
		     Suspended := False;
		     
		     exit;
		  end select;
	       end loop;
	       
	       
	       
	       
	   Second_Loop :
	       loop		  		  
		  
		  
		  declare
		     
		     Host_Entry  : constant Sockets.Host_Entry_Type  := Sockets.Get_Host_By_Name(Current_Address.all);
		  begin Domain :
		      
		      for I in 1..Sockets.Addresses_Length(Host_Entry) loop
			 						 
			 begin
			    
			    IP_Address := Sockets.Addresses(Host_Entry, I);
			    -------------------
			    -- Random timeouts :
			    Timeouts := 10.0;
			    Free(Search_Result.File_Content);
			    Web.Web_Search(Current_Address.all, Protocol.all & Image(Ip_Address)  & Current_Path.all, Timeouts, Search_Result.all);
			    OS_Lib.Free(Search_Result.Address);
			    Free(Current_Document_Name);
			    
			    Search_Result.Address := new String ' (Protocol.all & Current_Address.all & Current_Path.all);
			    Current_Document_Name := new Wide_String ' (Search_Result.Doc_Name.all);
			    
			    My_Ansi_Consoles.Clear_Screen;
			    My_Ansi_Consoles.Draw_Window (Window.all);
			    My_Ansi_Consoles.Draw (Window.all, 1, 2, Ansi_Console.White, "Searching for : " & (Pattern.all));
			    My_Ansi_Consoles.Draw (Window.all, 2, 2, Ansi_Console.White, "look at : " & 
						     To_Wide_String(Search_Result.Address.all));
			    My_Ansi_Consoles.Draw (Window.all, 3, 2, Ansi_Console.White, "Document name : " & (Current_Document_Name.all));
			    
			    for Line_Index in Search_Result.File_Content'Range loop
			       
			       declare
				  
				  Line : constant String := To_String(-Search_Result.File_Content(Line_Index));
				  
			       begin	 
				  
				  if Regexp.Match(Line, Regular_Exp) then
				     Ada.Text_Io.Put(Character'Val(7));
				     Errno.all := 0;
				     Done := True;
				     exit Domain;
				  elsif Regexp.Match(Line, Sub_Regular_Exp) then
				     Ada.Text_Io.Put(Character'Val(7));
				     Errno.all := 0;

				     Free(Search_Result.Pattern);
				     Search_Result.Pattern := new Wide_String ' (Pattern(Sub_Top..Sub_Index));
				     declare
					Top_Href : constant Natural := Fixed.Index(Line, "href=") + 6;
					Href_Index  : constant Natural := Fixed.Index(Line, """", Top_Href + 1) - 1;
					Protocol_Index  : constant Natural := Fixed.Index(Line, "http://", Top_Href);					
				     begin
					
					if Top_Href > 6 then
					   
					   if Protocol_Index /= 0 then
					      
					      Os_Lib.Free(protocol);
					      Protocol := new String ' (Line(Protocol_Index..Fixed.Index(Line, ":", Protocol_Index)) & "//");
					      
					      declare
						 
						 Top_Domain    : constant Natural := Fixed.Index(Line, "//", Protocol_Index + 1) + 2;
						 Domain_Index  : constant Natural := Fixed.Index(Line, "/", Top_domain + 1) - 1;
					      begin
						 
						 if Top_Domain > 2 and then (Domain_Index > 0 and Domain_Index <= Href_Index) then
						    
						    Os_Lib.Free(Current_Address);
						    Current_Address := new String ' (Line(Top_Domain .. Domain_Index));
						    
						    if Domain_Index + 1 < Href_Index then
						       Os_Lib.Free(Current_Path);
						       Current_Path := new String ' (Line(Domain_Index + 1 .. Href_index));
						    end if;
						    
						 elsif Top_Domain > 2 then
						    
						    Os_Lib.Free(Current_Address);
						    Current_Address := new String ' (Line(Top_domain .. Href_index));
						    Os_Lib.Free(Current_Path);
						    Current_Path := new String ' ("");
						    
						 else
						    Done := True;
						    exit Second_Loop;
						 end if;
					      end;
					      
					   else
					      
					      Os_Lib.Free(Buffer_Path);
					      Buffer_Path := new String ' (Current_Path.all & '/' & Line(Top_Href..Href_Index));
					      Os_Lib.Free(Current_Path);
					      Current_Path := new String ' (Buffer_Path.all);
					      
					      
					   end if;
					   
					   exit domain;
					else
					   Done := True;
					   exit Second_Loop;
					end if;
				     end;
				  end if;
			       end;
			    end loop;
			    
			    select
			       accept Halt;
			       exit Main_Search;
			    or
			       accept Suspend;			       
			       Suspended := True;	       		     
			       --My_Ansi_Consoles.Clear_Screen;
			       exit Second_loop;
			    or
			       delay 0.1;
			    end select;
			    My_Ansi_Consoles.Clear_Screen;
			 exception
			    when Aws.Client.Connection_Error =>
			       null;
			    when Aws.Client.Protocol_Error =>
			       null;
			    when others =>
			       null;
			 end;
		      end loop Domain;		   
		      
		      select
			 accept Halt;
			 exit Main_Search;
		      or
			 accept Suspend;
			 --My_Ansi_Consoles.Clear_Screen;
			 Suspended := True;	       		     
		      or
			 delay 0.1;
		      end select;		   
		  exception
		     when others =>
			exit;
		  end;	     
		  Sub_Top := Sub_Index;
		  Sub_Index := Wide_Fixed.Index(Pattern.all, "*", Sub_Top + 1);	       
		  exit when Sub_Index <= Sub_Top;
	       end loop Second_Loop;
	       My_Ansi_Consoles.Clear_Screen;
	    exception	       
	       when Sockets.Host_Error =>
		  		  
		  select
		     accept Halt;
		     exit Main_Search;
		  or
		     accept Suspend;
		     Suspended := True;	       
		  or
		     delay 0.1;
		  end select;		  
	       when others =>
		  select
		     accept Halt;
		     exit Main_Search;
		  or
		     accept Suspend;
		     Suspended := True;	       
		  or
		     delay 0.1;
		  end select;		  
	    end;
	    
	    
	    --Code.Prefix := Strings.Unbounded.To_Unbounded_String(Random(Seg_Rand.Random(Seg_Gen)));
	    Code.Radix := Strings.Unbounded.To_Unbounded_String(Random(Seg_Rand.Random(Seg_Gen)));
	    Code.suffix := Strings.Unbounded.To_Unbounded_String(To_Lower(Top_Level_Type'Image(Top_Level_Rand.Random(Top_Level_Gen))));
	    
	    OS_Lib.Free(Current_Address);
	    Current_Address := new String ' ("www." & --Strings.Unbounded.To_String(Code.Prefix) & '-' &
					       Strings.Unbounded.To_String(Code.Radix) & '.' &
					       Strings.Unbounded.To_String(Code.Suffix));	       
	    
	    Os_Lib.Free(Current_Path);
	    
	    Current_Path := new String ' ("");
	    
	    Sub_Top := Pattern'First;
	    Sub_Index := Wide_Fixed.Index(Pattern.all, "*", Sub_Top + 1);	 	       
	    
	       
	 end loop Main_Search;
	 while not End_Of_Task loop
	    select
	       accept Suspend;
	    or
	       accept Start;	       
	    or
	       accept Halt;
	       exit;
	    end select;
	 end loop;
	 Errno.all := 0;	 
	 
      exception
	 when Sockets.Socket_Error =>
	    Errno.all := 128;
	    loop
	       select
		  accept Suspend;
	       or
		  accept Start;		  
	       or
		  accept Halt;
		  exit;
	       or
		  delay 0.1;
		  My_Ansi_Consoles.Draw_Window (Window.all);
		  My_Ansi_Consoles.Draw (Window.all, 1, 2, Ansi_Console.White, "Socket error");
	       end select;	       
	    end loop;
	 when Sockets.Host_Error =>
	    Errno.all := 128;
	    loop
	       select
		  accept Suspend;
	       or
		  accept Start;		  
	       or
		  accept Halt;
		  exit;
	       or
		  delay 0.1;
		  My_Ansi_Consoles.Draw_Window (Window.all);
		  My_Ansi_Consoles.Draw (Window.all, 1, 2, Ansi_Console.White, To_Wide_String("Host error :" & Current_Address.all));
	       end select;	       
	    end loop;
	 when others =>
	    Errno.all := 128;
	    loop
	       select
		  accept Suspend;
	       or
		  accept Start;		  
	       or
		  accept Halt;
		  exit;
	       or
		  delay 0.1;
		  My_Ansi_Consoles.Draw_Window (Window.all);
		  My_Ansi_Consoles.Draw (Window.all, 1, 2, Ansi_Console.White, "Others error");
	       end select;	       
	    end loop;
	    
	    
      end Web_Search_Type;
      
      Web_Search : access Web_Search_Type;
      
      
      procedure Search_Result_Info (Window : in Window_Type; Shell_Interface : in Main_Interface_Access; Errno : out Integer) is
      begin
	 
         My_Ansi_Consoles.Draw_Window (Window);      
         My_Ansi_Consoles.Draw (Window, 1, 2, Ansi_Console.White, "Search result for " & Shell_Interface.Search_Result.Pattern.all);
         My_Ansi_Consoles.Draw (Window, 2, 2, Ansi_Console.White, "Address : " & To_Wide_String(Shell_Interface.Search_Result.Address.all));
         My_Ansi_Consoles.Draw (Window, 3, 2, Ansi_Console.White, "Document name : " & (Shell_Interface.Search_Result.Doc_Name.all));
         Errno := 0;
      end Search_Result_Info;
      
      procedure Command_Info_Status (Window : in Window_Type; Shell_Interface : in Main_Interface_Access) is
         
      begin
         
         My_Ansi_Consoles.Draw_Window (Window);      

         My_Ansi_Consoles.Draw (Window, 1, 2, Ansi_Console.White, "Program Name   : " & (-Shell_Interface.Spawn_Result.Program_Name));
                  
         My_Ansi_Consoles.Draw (Window, 2, 2, Ansi_Console.White, "Success  : " & To_Wide_String(Boolean'Image(Shell_Interface.Spawn_Result.success)));
                           
         My_Ansi_Consoles.Draw (Window, 3, 2, Ansi_Console.White, "Errno    : " & To_Wide_String(Integer'Image(Shell_Interface.Spawn_Result.Return_Code)));
      end Command_Info_Status;            
      
      
      
      procedure GnuShell_Command (Window : in Window_Type; Shell_Interface : in Main_Interface_Access; Pattern : in Wide_String; Errno : out Integer) is
	 
      begin
	 if Wide_Fixed.Index(Pattern, " ") /= 0 and then Wide_Fixed.Index(Pattern, " ") < Pattern'last then
	    
	    declare
	       
	       Expanded_Line : constant Wide_String := Pattern(Wide_Fixed.Index(Pattern, " ")+1..Pattern'Last);
	       
	    begin	       
	       --Text_Io.Put_Line("Expanded line : " & Expanded_Line);
	       declare
		  
		  Command_Line  : constant Wide_String := Pattern(Pattern'First..Wide_Fixed.Index(Pattern, " ")-1) & ' ' & Expanded_Line;
	       begin
		  --Text_Io.Put_Line("Ok !");
		  Shell_Interface.Spawn_Result := Operating_System.Shell_Spawn(UTF_Encoding.Wide_Strings.Encode((Command_Line)));
		  --Text_Io.Put_Line("Ok !");
	       end;
	    end;
		
	 else
	  
	    Shell_Interface.Spawn_Result := Operating_System.Shell_Spawn(UTF_Encoding.Wide_Strings.Encode(Pattern));   

	 end if;

         Errno := Shell_Interface.Spawn_Result.Return_Code;
      end GnuShell_Command;
      

      procedure System (Window : in Window_Type; Shell_Interface : in Main_Interface_Access; Pattern : in Wide_String; Errno : out Integer) is
         
         
      begin
         
         -- Messages pour que l'utilisateur(rice) ne se sente pas perdu(e).
         My_Ansi_Consoles.Draw_Window (Window);      
         My_Ansi_Consoles.Draw_Centered (Window, 1, Ansi_Console.White, "waitting process...");
         Move_Cursor_To(Window, 1, 3);
	 if Wide_Fixed.Index(Pattern, " ") /= 0 and then Wide_Fixed.Index(Pattern, " ") < Pattern'last then
	    
	    declare
	       
	       Expanded_Line : constant Wide_String := To_Wide_String(Linux.Expand_Filename(UTF_Encoding.Wide_Strings.Encode(Pattern(Wide_Fixed.Index(Pattern, " ")+1..Pattern'Last))));
	       
	    begin	       
	       --Put_Line("Expanded line : " & Expanded_Line);
	       declare
		  
		  Command_Line  : constant Wide_String := Pattern(Pattern'First..Wide_Fixed.Index(Pattern, " ")-1) & ' ' & Expanded_Line;
	       begin
		  --Text_Io.Put_Line("Ok !");
		  Shell_Interface.Spawn_Result := Operating_System.spawn(UTF_Encoding.Wide_Strings.Encode(Command_Line));
		  --Text_Io.Put_Line("Ok !");
	       end;
	    end;
		
	 else
	  
	    Shell_Interface.Spawn_Result := Operating_System.spawn(UTF_Encoding.Wide_Strings.Encode(Pattern));   

	 end if;

         Errno := Shell_Interface.Spawn_Result.Return_Code;
      end System;
      
      
      
      Adamanborg_Shell_Response : Shells.Response_Type := (others => null);
      
      
      
      procedure Shell_Info (Window : in Window_Type; Shell_Command : in Command_Type; Shell_Interface : in Main_Interface_Access; Errno : out Integer) is
	 	 
	 
	 Result : Results.Result_Access;
      begin
	 
	 case Shell_Command is
	    when AllManuals | GnuLinuxInterface =>
	       null;
	    when others =>
	       My_Ansi_Consoles.Draw_Centered
		 (Window, 1, Ansi_Console.White, To_Wide_String(Shells.Shell_Command_Type'Image(Shell_Command)));
	       if Shells."/="(Adamanborg_Shell_Response(Shell_Command), null) then
		  Shells.To_Result(Adamanborg_Shell_Response(Shell_Command).all, Result);
		  if Result /= null then
		     if Result.all in Results.Search_Result_Type'class then		  
			My_Ansi_Consoles.Draw_Centered
			  (Window, 3, Ansi_Console.Red, "Search");
			Shell_Interface.Search_Result := Results.Search_Result_Type(Result.all);
			
		     elsif Result.all in Results.Spawn_Result_Type then
			My_Ansi_Consoles.Draw_Centered
		       (Window, 3, Ansi_Console.Red, "Spawn");
			Shell_Interface.Spawn_Result := Results.Spawn_Result_Type(Result.all);
			
		     end if;
		  end if;
	       end if;
	 end case;
	 
         Move_Cursor_To(Window, 4, 3);
         Errno := 0;
      end Shell_info;
      
      
      procedure Builtin_Info (Window : in Window_Type; Sub_Command : in Sub_Command_Type; Shell_Interface : in Main_Interface_Access; Pattern : in Wide_String; Errno : in Integer) is
      begin
	 My_Ansi_Consoles.Draw_Window (Window);
	 case Sub_Command is
	    when Getenv | Setenv | Chdir | Mkdir =>
	       
	       
	       My_Ansi_Consoles.Draw (Window, 1, 3, Ansi_Console.White, To_Wide_String(Sub_Command_Type'Image(Sub_Command)));
	       if Errno = 0 then
		  My_Ansi_Consoles.Draw (Window, 2, 3, Ansi_Console.White, "Success : TRUE");
		  My_Ansi_Consoles.Draw (Window, 3, 3, Ansi_Console.White, "Result : ");
	       else
		  My_Ansi_Consoles.Draw (Window, 2, 3, Ansi_Console.White, "Success : FALSE");
		  --if Errno = -1 then
		     My_Ansi_Consoles.Draw (Window, 3, 3, Ansi_Console.White, "Errno : " & To_Wide_String(Sub_Command_Type'Image(Sub_Command) & " : "));
		  --else
		  --   My_Ansi_Consoles.Draw (Window, 3, 3, Ansi_Console.White, "Errno : " & To_Wide_String(Errno_Message(Errno, Sub_Command_Type'Image(Sub_Command))));
		  --end if;
	       end if;
	       
	       
	       
	    when others =>
	       null;
	 end case;
      end Builtin_Info;
      
      
      
      procedure Builtin_Sub_Command (Window : in Window_Type; Sub_Command : in Sub_Command_Type; Shell_Interface : in Main_Interface_Access; Pattern : in Wide_String; Errno : out Integer) is
	 
	 
	
      begin
	 if Wide_Fixed.Index
	   ((Pattern(Wide_Fixed.Index_Non_Blank
		      ((Pattern))..Pattern'Last)),
	    " ") /= 0 then
	    Errno := 0;
	 else
	    Shell_Interface.Pattern := new String ' ("Missing argument.");
	    Errno := -1;
	    return;
	 end if;
	 case Sub_Command is
	    when Getenv =>
	       
	       declare
		  Value : OS_Lib.String_Access;
	       begin
		  
		  
		  Value := Os_Lib.Getenv(To_String(UTF_Encoding.Wide_Strings.Encode((Pattern(Wide_Fixed.Index((Pattern(Wide_Fixed.Index_Non_Blank((Pattern))..Pattern'Last)), " ")+1..
											  Wide_Fixed.Index_Non_Blank((Pattern), Backward))))));
					 
		  
		  My_Ansi_Consoles.Draw_Window (Window);      
		  if Value /= null then
		     Shell_Interface.Pattern := Value;
		  end if;
		  
	       end;
	    when Setenv =>	    	       
	       declare
		  
		  Name : constant Wide_String := 
		    (Pattern(Wide_Fixed.Index((Pattern(Wide_Fixed.Index_Non_Blank((Pattern))..Pattern'Last)), " ")+1..
					Wide_Fixed.Index((Pattern(Wide_Fixed.Index_Non_Blank((Pattern))..Pattern'Last)), "=")-1));
		  
		  Value : constant Wide_String := (Pattern(Wide_Fixed.Index((Pattern(Wide_Fixed.Index_Non_Blank
											       ((Pattern))..Pattern'Last)),
									   "=")+1..
								 Wide_Fixed.Index_Non_Blank((Pattern), Backward)));
	       begin
		  Os_Lib.Setenv(To_String(UTF_Encoding.Wide_Strings.Encode(Name)), To_String(UTF_Encoding.Wide_Strings.Encode(Value)));
		  Shell_Interface.Pattern := Os_Lib.Getenv(To_String(Name));
	       end;
	       
	    when Chdir =>
	       declare
		  Path_Name : constant Wide_String := 
		    
		    (Pattern
		       (Wide_Fixed.Index((Pattern(Wide_Fixed.Index_Non_Blank((Pattern))..Pattern'Last)), " ")+1..Wide_Fixed.Index_Non_Blank((Pattern), Backward)));
		  
	       begin
		  Change_Dir(UTF_Encoding.Strings.Encode(Expand_Path(To_String(Path_Name))));
		  Shell_Interface.Pattern := new String ' (Expand_Path(To_String(Path_Name)));
	       end;
	    when Mkdir =>
	       
	       declare
		  Path_Name : constant Wide_String := 
		    
		    (Pattern
		       (Wide_Fixed.Index((Pattern(Wide_Fixed.Index_Non_Blank((Pattern))..Pattern'Last)), " ")+1..Wide_Fixed.Index_Non_Blank((Pattern), Backward)));
		  
	       begin
		  Make_Dir(UTF_Encoding.Strings.Encode(Expand_Path(To_String(Path_Name))));
		  Shell_Interface.Pattern := new String ' (Expand_Path(To_String(Path_Name)));
	       end;
	    when others =>
	       null;
	 end case;
	 Errno := 0;
      exception
	 when others =>
	    Shell_Interface.Pattern := new String ' ("");
	    Errno := 
	      Os_Lib.Errno;
      end  Builtin_Sub_Command;
      
      
      
      
      
      procedure Bell(Quiet : in boolean) is
      begin
         if not Quiet then
            Ansi_Console.Beep;
         end if;
      end Bell;
      
      
      procedure Main_Quit(Window : in Window_Type) is
      begin
         
	 
         My_Ansi_Consoles.Draw_Window (Window);
         My_Ansi_Consoles.Draw_Centered (Window, 2, Ansi_Console.White, "End of Adamanborg.");

         My_Ansi_Consoles.Draw (Window, 3, 3, Ansi_Console.White, "Byby !");

         delay 1.5;
         My_Ansi_Consoles.Clear_Screen;
         My_Ansi_Consoles.Leave_And_Restore_Defaults;                                                               
         
      end Main_Quit;
      
      procedure Quit_Info_Status (Window : in Window_Type) is
      begin
         
	 My_Ansi_Consoles.Initialize;
	 My_Ansi_Consoles.Clear_Screen;
            
	 -- Comme avec Windows, on commence par mettre en place le fond du bureau.
	 My_Ansi_Consoles.Draw_Desktop_Background (1, 1, Lines, Columns, Ansi_Console.Black);
	 
         My_Ansi_Consoles.Draw_Window (Window);      
         My_Ansi_Consoles.Draw_Centered (Window, 2, Ansi_Console.White, "Voulez vous réellement mettre fin au programme ? (Press 'Return' else.)");
         Move_Cursor_To(Window, 2, 3);                  
      end Quit_Info_Status;
      
      
      procedure Read_Quit_Info_Status (Window : in Window_Type; On_Esc : Boolean := False) is
      begin
         if On_Esc then

            My_Ansi_Consoles.Draw_Window (Window);      
            My_Ansi_Consoles.Draw_Centered (Window, 1, Ansi_Console.White, "Use Page Up and Down or arrow keys or one Escape character to Quit.");
         else

            My_Ansi_Consoles.Draw_Window (Window);      
            My_Ansi_Consoles.Draw_Centered (Window, 1, Ansi_Console.White, "Use Page Up and Down or arrow keys or two Escape character to Quit.");
         end if;
         
      end Read_Quit_Info_Status;
      
      
      
      procedure Mode_Initialization (Main_Window : in Window_Type; Mode : in Command_Type;On_Esc : in Boolean; Message : in Wide_string) is
      begin
	 Ada.Text_Io.Put(PragmARC.Ansi_Tty_Control.Clear_Screen);
	 Mode_Info_Status(W1, Mode);	 
	 My_Ansi_Consoles.Draw_Window (Main_Window);
	 Main_Quit_Info_Status(W3, On_Esc);					     	 
	 My_Ansi_Consoles.Draw_Centered (Main_Window, 1, Ansi_Console.White, Message);
      end Mode_Initialization;
	 
      
      procedure On_Alarm(Window : in Window_Type; Message : in String) is
      begin
         My_Ansi_Consoles.Draw_Window (Window);      
         My_Ansi_Consoles.Draw (Window, 1, 3, Ansi_Console.White, To_Wide_String(Message));         
      end On_Alarm;
      -----------------------------------------------------------------------------
      -- Have and know love and peace in freedom and reason with power and will. --
      -----------------------------------------------------------------------------
      -----------------------------------------------------------------------------
      --               initializing the works spaces  Adage SP.P                  --
      --                                                                          --
      ------------------------------------------------------------------------------
      --
      -- F1,      "A.i. management";
      -- F2,      "Data technologies";
      -- F3,      "All manuals";
      -- F4,      "Gnu/Linux interface";
      -- F5,      "Environment parameters";      
      -- F6,      "Self-Programming process";
      -- F7,      "Plans administration";
      -- F8,      "Adamanborg call" (graphical mode);
      -- F9,       Start or Stop Timer; 
      -- F10,      Set or Unset Alarm;
      -- F11,      Stop Alarm;
      
      Current_Command : Command_Type := Null_Item;
      -- La commande utilisateur.
      
      
      task type Adam_Console(Channel      : Gnat.sockets.Stream_Access) is
         entry Receive (Char : in Wide_Character);
         entry Mode(Command : out Command_Type);
         entry Reset;
         entry Switch (Command : in Command_Type);
         entry Lock;
         entry Unlock;
         entry Set_On_Esc(Is_Escape : in Boolean);
         entry Timer_Switch;
         entry Page_Down;
         entry Page_Up;
         entry Up_Arrow;
         entry Down_Arrow;
	 entry Left_Arrow;
	 entry Right_Arrow;
         entry Halt;
         entry Switch_Alarm;
         entry Stop_Alarm;
      private    
         entry Date_Refresh (Date : in Time);
         entry Timer_Refresh (Years         : in     Years_Count;
                              Months        : in     Months_Count;
                              Days          : in     Days_Count;
                              Houres        : in     Ada.Calendar.Day_Duration); 
         
         entry Alarm_Refresh (Start         : in     Time;
                              Years         : in     Natural;
                              Months        : in     Natural;
                              Days          : in     Natural;
                              remaining     : in     Ada.Calendar.Day_Duration;
                              Stop          : in     Time);
         entry Alarm_Elapsed;
      end Adam_Console ;
      
      
      task body Adam_Console is
         
	 
	 -------------------------------------------------------
         -- Dater, Timer and Alarm...                         --
         -------------------------------------------------------
         --                                                   --
         -------------------------------------------------------
         -- Dater :
         task Adam_Dater is         
            entry Date_Speed (Wait          : in     Duration);
            --  entry Date_info (Date          :     out Time;
            --                   Wait          :     out Duration);
         end Adam_Dater;
         
         -------------------------------------------------------
         -- Timer :
         task Adam_Timer is
            
            entry Timer_Speed (Wait         : in     Duration);
            entry Timer_Start (Date         : in     Time);
            entry Timer_stop;
         end Adam_Timer;
         
         --------------------------------------------------------
         -- Alarm :
         task Adam_Alarm is
            
            entry Alarm_Speed (Wait         : in     Duration);
            entry Alarm_start (Start_Date   : in     Time;
                               Stop_Date    : in     Time);
            entry Alarm_Set;
            entry Alarm_Unset;
            entry Alarm_Stop;
         end Adam_Alarm;
         
         
         task body Adam_Dater is
            Dater_Wait : Duration := 1.0;
         begin
            loop
               select
                  
                  accept Date_Speed (Wait          : in     Duration) do
                     Dater_wait := Wait;
                  end Date_Speed;
                  
               or
                  delay Dater_Wait;
                  select
                     Adam_Console.Date_Refresh(Clock);
                  or
                     delay Dater_Wait;
                  end select;
               end select;
            end loop;
         end Adam_Dater;

         task body Adam_Timer is                    
            
            Timer_Wait : Duration := 0.1;
	    -- delay when timer is started.
	    
            Real_Wait  : Duration := 1.0;
            -- delay when timer is halted.
	    
	    
            Timer_Started  : Boolean := False;
            
            Timer_Years        : Years_Count  := 0;
            Timer_Months       : Months_Count := 0;         
            Timer_Days         : Days_Count   := 0;         
            Timer_Houres       :  Duration    := 0.0;
            
            Years    : Natural;
            Months   : Natural;
            Days     : Natural;
            Houres   : Natural;
            Minutes  : Natural;
            Second   : Natural;
            Rest     : Duration;
                        
            Timer_Start_date  : Time          := Clock;
            Timer_Stop_Date   : Time          := Clock;
            
         begin
            
            loop               
               
               select
                  
                  accept Timer_Speed (Wait         : in     Duration) do
                     Timer_Wait := Wait;
                  end Timer_Speed;
                  
               or
                  accept Timer_Start (Date         : in     Time) do
                     
                     Timer_Started := True;
                     Timer_Start_date := Date;
                     Real_Wait := Timer_Wait;
                  end Timer_Start;
               or
                  accept Timer_Stop do
                     Timer_Started := False;
                     Timer_Stop_Date := Clock;               
                     Real_Wait := 1.0;
                  end Timer_Stop;
                  
               or
                  delay Real_Wait;
                  if Timer_Started then
                     Tools.Difference_In_Years(Timer_Start_Date, 
                                               clock,
                                               Years, 
                                               Months,
                                               Days,
                                               Houres,
                                               Minutes,
                                               Second,
                                               Rest);
                     Timer_Years := Years;
                     Timer_Months := Months;                     
                     Timer_Days := Days;
                     Timer_Houres := Formatting.Seconds_Of(Houres, Minutes, Second, Rest);
                  else
                     Tools.Difference_In_Years (Timer_Start_Date, 
                                                Timer_Stop_Date,
                                                Years, 
                                                Months,
                                                Days,
                                                Houres,
                                                Minutes,
                                                Second,
                                                Rest);
                     Timer_Years := Years;
                     Timer_Months := Months;                     
                     Timer_Days := Days;
                     Timer_Houres := Formatting.Seconds_Of(Houres, Minutes, Second, Rest);
                  end if;
                  Adam_Console.Timer_Refresh(Timer_Years,
                                             Timer_Months,
                                             Timer_Days,
                                             Timer_Houres);               
                  
               end select;
            end loop;
         end Adam_Timer;
         
         
         
         
         task body Adam_Alarm is
            
            
            Alarm_Wait     : Duration := 0.1;
            
            Alarm_Time_Start     : Time := clock;            
            Alarm_Time_Stop      : Time := clock;
            
            
            Delays_Repeat : Duration := 0.0;
            
            Years    : Natural := 0;
            Months   : Natural := 0;
            Days     : Natural := 0;
            Houres   : Natural := 0;
            Minutes  : Natural := 0;
            Second   : Natural := 0;
            Rest     : Duration := 0.0;                    
            Alarm_Houres : Ada.Calendar.Day_Duration := 0.0;                        
            
            Is_Set : Boolean := False;
            
         begin
            loop
               select

                  accept Alarm_Speed (Wait         : in     Duration) do
                     Alarm_Wait := Wait;
                  end Alarm_Speed;
               or
                  accept Alarm_start (Start_Date   : in     Time;
                                      Stop_Date    : in     Time) do
                     Alarm_Time_Start := Start_Date;
                     Alarm_Time_Stop := Stop_Date;
                     Delays_Repeat := Alarm_Time_Stop - Alarm_Time_Start;
                     Is_Set := True;
                  end Alarm_Start;
               or
                  accept Alarm_Set do
                     Alarm_Time_Start := Clock;
                     Alarm_Time_Stop := Alarm_Time_Start + Delays_Repeat;
                     Is_Set := True;
                     
                  end Alarm_Set;
               or
                  accept Alarm_Stop do
                     Is_Set := False;
                  end Alarm_Stop;
               or
                  accept Alarm_Unset do
                     Is_Set := False;                     
                  end Alarm_Unset;
                  
               or                  
                  delay Alarm_Wait;        
                  begin
                     if Is_Set then
                        if Clock <= Alarm_Time_Stop then
                           Tools.Difference_In_Years(Clock, 
                                                     Alarm_Time_Stop,
                                                     Years, 
                                                     Months,
                                                     Days,
                                                     Houres,
                                                     Minutes,
                                                     Second,
                                                     Rest);                        
                           Alarm_Houres := Formatting.Seconds_Of(Houres, Minutes, Second, Rest);                     
                           select
                              Adam_Console.Alarm_Refresh(Alarm_Time_Start,
                                                         Years,
                                                         Months,
                                                         Days,
                                                         Alarm_Houres,
                                                         Alarm_Time_Stop);                  
                           or
                              delay 1.0;
                           end select;
                        else
                           Adam_Console.Alarm_Elapsed;                           
                           select
                              accept Alarm_Stop do
                                 Is_Set := False;
                              end Alarm_Stop;
                           or
                              accept Alarm_Unset do
                                 Is_Set := False;                     
                              end Alarm_Unset;
                           or
                              delay 1.0;                              
                           end select;
                        end if;
                     end if;
                  end;
                  
               end select;
            end loop;
         end Adam_Alarm;
         
         
         --Dater_Wait         : Duration     := 1.0;
         Date               : Time         := Clock;
         
         --Timer_Wait         : Duration     := 0.05;         
         
         Timer_Years        : Years_Count  := 0;
         Timer_Months       : Months_Count := 0;         
         Timer_Days         : Days_Count   := 0;                     
         Timer_Houres       : Ada.Calendar.Day_Duration := 0.0;
         Timer_Started      : Boolean      := False;
         Timer_Start        : Time         := Date;
         Timer_Stop         : Time         := Date;
         
         
         --Alarm_Wait           : Duration     := 0.1;                  
         Alarm_Time_Start     : Time         := Date;
         Alarm_Time_Remaining : Duration     := 0.0;
         Alarm_Time_Stop      : Time         := Date;

         Alarm_Years          : Natural := 0;
         Alarm_Months         : Natural := 0;
         Alarm_Days           : Natural := 0;
         Alarm_Is_Set         : Boolean := False;
         Alarm_On             : Boolean := False;
         
         -- When attempt to Quit the program.
         Locked             : Boolean      := False;
         
         -------------------------------------------------
         -- Main Task.
         -------------------------------------------------
         --
         Previsious_Mode : Command_Type := Null_Item;
         Current_Mode    : Command_Type := Null_Item;         
         
	 Sub_Command : Sub_Command_Type := Null_Command;
	 
	 

         Line : Common.String_Access;
         
         History_Max : constant Positive := 100;
         Command_Line_History : Command_Line_History_Type(1..History_Max);
         History_Index        : Natural := 1;
         Command_Line_Index   : Natural := 0;
                  
         --Repeat_Line_Index    : Natural := 0;
         --On_Repeat            : Boolean := False;
         
         
         
         On_Esc : Boolean := False;
         
         End_Of_This_Task : Boolean := False;
         
         
         File_Index : natural := 0;         
         Line_Index : Natural := 0;
	 
	  
	 -----------------------------
	 -- for computing mode      --
	 Computing_Line : Natural := 0;
	 Computing_Col  : Natural := 0;
	 Success        : Boolean := False;
	 
	 
         
	 
	 ----------------------------
	 -- for GnuShell mode only --
	 Chars_Max : constant Positive := Term_Width-7;
	 Lines_Max : constant Positive := Command_Max_Lines-2;
	 

	 Line_Count : Natural := 0;
	 

         Wait_Refresh   : constant Duration := 0.025;                           
         
         Errno : Integer := 0;
	 
	 GnuShell_Prompt_Line : Positive := 1;
	
         
	 ----------------------------
	 -- Result for Completion. --
	 ----------------------------
	 Completion_Result : Results.Result_Access;
	    
	 
      begin
         
         Text_Io.Put_Line("Console start...");
         if Shared_Timer.Is_Set then            
            Timer_Started := True;            
            date := Time_Of(Shared_Timer.Start_Date.Year,
                            Shared_Timer.Start_Date.Month,
                            Shared_Timer.Start_Date.Day,
                            Shared_Timer.Start_Date.Hours);
            Adam_Timer.Timer_Start(date);            
            Timer_Start := Date;
         end if;
         
         if Shared_Alarm.Is_Set then            
            Alarm_Is_Set := True;
            Alarm_Time_Start := Time_Of(Shared_Alarm.Start_Date.Year,
                                        Shared_Alarm.Start_Date.Month,
                                        Shared_Alarm.Start_Date.Day,
                                        Shared_Alarm.Start_Date.Hours);
            
            
            Alarm_Time_Stop := Time_Of(Shared_Alarm.Stop_Date.Year,
                                       Shared_Alarm.Stop_Date.Month,
                                       Shared_Alarm.Stop_Date.Day,
                                       Shared_Alarm.Stop_Date.Hours);
            
            
            Adam_Alarm.Alarm_Start(Alarm_Time_Start, Alarm_Time_Stop);            
         end if;
         
         
         
         declare
            
            
         begin
            
            
            
            -- initialize Interface;
            My_Ansi_Consoles.Initialize;
            My_Ansi_Consoles.Clear_Screen;
            
            -- Comme avec Windows, on commence par mettre en place le fond du bureau.
            My_Ansi_Consoles.Draw_Desktop_Background (1, 1, Lines, Columns, Ansi_Console.Black);	    
            Mode_Info_Status(W1, Null_Item);	 
	    My_Ansi_Consoles.Draw_Window (W2);
	    Main_Quit_Info_Status(W3, On_Esc);
	    My_Ansi_Consoles.Draw_Centered (W2, 1, Ansi_Console.White, "Enter your text or command here (Ctrl+L to clear line).");
            Main_Info_Status(W4);
	    
	    
	    Matrix_Saver.Start;
	    
	    loop                                       
	       
	       declare
		  
		  
	       begin
		  
		  select
		     accept Switch_Alarm;
		     if Alarm_Is_Set then
			Adam_Alarm.Alarm_Unset;
			Alarm_Is_Set := False;
			Shared_Alarm.Is_Set := False;
		     else
			Adam_Alarm.Alarm_Set;
			Alarm_Is_Set := True;
			Shared_Alarm.Is_Set := True;
		     end if;
		  or
		     accept Stop_Alarm;
		     Adam_Alarm.Alarm_Stop;
		     Adam_Alarm.Alarm_Unset;
		     Alarm_On := False;
		     Alarm_Is_Set := False;
		     Shared_Alarm.Is_Set := False;
		     
		  or
		     
		     accept Halt;
		     exit;
		     
		     
		  or
		     
		     when Current_Mode in 
		       EnvironmentParameters |
		       SelfProgrammingProcess |
		       AiManagment |
		       DataTechnologie =>
			accept Page_Down;
			
			
		  or
		     when Current_Mode in 
		       EnvironmentParameters |
		       SelfProgrammingProcess |
		       AiManagment |
		       DataTechnologie =>
			accept Page_Up;
		  or
		     when Current_Mode in 
		       EnvironmentParameters |
		       SelfProgrammingProcess |		       
		       AiManagment |
		       DataTechnologie =>
			accept Up_Arrow;
		  or
		     when Current_Mode in 
		       EnvironmentParameters |
		       SelfProgrammingProcess |		       
		       AiManagment |
		       DataTechnologie =>
			accept Down_Arrow;
			
		  or
		     when Current_Mode in PlansAdministration | Plans_Print =>
			accept Page_Down do
			   if Line_Index+Command_Max_lines < Shell_Interface.Zbank.Operation_Set'Last then
			      Line_Index := Line_Index + Command_Max_Lines;
			   end if;
			end Page_Down;
			My_Ansi_Consoles.Clear_screen;
			Previsious_Mode := Current_Mode;
			Current_Mode := Plans_Print;
			Mode_Initialization(W14, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
		  or
		     when Current_Mode in PlansAdministration | Plans_Print =>
			accept Page_Up do
			   if Line_Index > Command_Max_lines then
			      Line_Index := Line_Index-Command_Max_Lines;
			   else
			      Line_Index := 0;
			   end if;
			end Page_Up;
			My_Ansi_Consoles.Clear_screen;
			Previsious_Mode := Current_Mode;
			Current_Mode := Plans_Print;
			Mode_Initialization(W14, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
		  or
		     when Current_Mode in PlansAdministration | Plans_Print =>
			accept Up_Arrow do
			   if Line_Index > 0 then
			      Line_Index := Line_Index - 1;
			   end if;
			end Up_Arrow;
			My_Ansi_Consoles.Clear_screen;
			Previsious_Mode := Current_Mode;
			Current_Mode := Plans_Print;
			Mode_Initialization(W14, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
		  or
		     
		     when Current_Mode in PlansAdministration | Plans_Print =>
			accept Down_Arrow do
			   if Line_Index < Shell_Interface.Zbank.Operation_Set'Last then
			      Line_Index := Line_Index + 1;
			   end if;
			end Down_Arrow;
			My_Ansi_Consoles.Clear_screen;
			Previsious_Mode := Current_Mode;
			Current_Mode := Plans_Print;
			Mode_Initialization(W14, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
			
		  or
			   		     
		     when Current_Mode in Builtin | Chess =>
			accept Page_Down;
		  or
		     
		     when Current_Mode in Builtin | Chess =>
			accept Page_Up;
			
		  or
		     when Current_Mode in Builtin | Chess =>
			accept Up_Arrow;                     
		  or
		     when Current_Mode in Builtin | Chess =>
			accept Down_Arrow;
			
		  or
		     when Current_Mode in AllManuals =>
			accept Page_Down;
		  or
		     
		     when Current_Mode in AllManuals =>
			accept Page_Up;
			
		  or
		     when Current_Mode in AllManuals =>
			accept Up_Arrow;                     
		  or
		     when Current_Mode in AllManuals =>
			accept Down_Arrow;
			
		  or
		     when Current_Mode in Null_Item | GnuLinuxInterface =>
			accept Page_Down;
		  or
		     
		     when Current_Mode in Null_Item | GnuLinuxInterface =>
			accept Page_Up;
			
		  or
		     when Current_Mode in Null_Item | GnuLinuxInterface =>
			accept Up_Arrow do
			   if History_Index > 1 and then Command_Line_Index < (History_Index - 1) then
			      Command_Line_Index := Command_Line_Index + 1;
			      Free(Line);
			      Line := new Wide_String ' (Command_Line_History(Command_Line_Index).all);
			   end if;
			end Up_Arrow;
			
			Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
			Main_Info_Status(W4);
		  or
		     when Current_Mode in Null_Item | GnuLinuxInterface =>
			accept Down_Arrow do
			   if History_Index > 1 and then Command_Line_Index > 1 then
			      Command_Line_Index := Command_Line_Index - 1;
			      Free(Line);
			      Line := new Wide_String ' (Command_Line_History(Command_Line_Index).all);
			   end if;
			end Down_Arrow;
			
			Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
			Main_Info_Status(W4);
		  or
		     when Current_Mode in Print =>
			accept Page_Down do
			   if File_Index+(Result_Max_Lines-1) < Shell_Interface.Spawn_Result.File_Content'Length  then
			      File_Index := Positive'Min(File_Index+(Result_Max_Lines-1), Shell_Interface.Spawn_Result.File_Content'Length );
			   end if;
			end Page_Down;		     
			Mode_Initialization(W2, Previsious_Mode, On_Esc, Message => "");
			Command_Info_Status(W11, Shell_Interface);
			
		  or
		     when Current_Mode in Print =>
			accept Page_Up do
			   if File_Index > (Result_Max_Lines-1) then
			      File_Index := File_Index - (Result_Max_Lines-1);
			   else
			      File_Index := 0;
			   end if;
			end Page_Up;
			Mode_Initialization(W2, Previsious_Mode, On_Esc, Message => "");
			Command_Info_Status(W11, Shell_Interface);
			
		  or
		     when Current_Mode in Print =>
			accept Up_Arrow do
			   if File_Index > 0 then
			      File_Index := File_Index - 1;
			   end if;
			end Up_Arrow;
			Mode_Initialization(W2, Previsious_Mode, On_Esc, Message => "");
			Command_Info_Status(W11, Shell_Interface);
		  or
		     when Current_Mode in Print =>
			accept Down_Arrow do
			   if File_Index + 1 < Shell_Interface.Spawn_Result.File_Content'Length  then
			      File_Index := Positive'Min(File_Index+1, Shell_Interface.Spawn_Result.File_Content'Length );
			   end if;
			end Down_Arrow;
			Mode_Initialization(W2, Previsious_Mode, On_Esc, Message => "");
			Command_Info_Status(W11, Shell_Interface);
		  or
		     when Current_Mode in Search =>
			accept Page_Down do
			   if File_Index+(Result_Max_Lines-1) < Shell_Interface.Search_Result.File_Content'Length  then
			      File_Index := Positive'Min(File_Index+(Result_Max_Lines-1), Shell_Interface.Search_Result.File_Content'Length );
			   end if;
			end Page_Down;
			My_Ansi_Consoles.Clear_Screen;
		  or
		     when Current_Mode in Search =>
			accept Page_Up do
			   if File_Index > (Result_Max_Lines-1) then
			      File_Index := File_Index - (Result_Max_Lines-1);
			   else
			      File_Index := 0;
			   end if;
			end Page_Up;
			My_Ansi_Consoles.Clear_Screen;
		  or
		     when Current_Mode in Search =>
			accept Up_Arrow do
			   if File_Index > 0 then
			      File_Index := File_Index - 1;
			   end if;
			end Up_Arrow;
			My_Ansi_Consoles.Clear_Screen;
		  or
		     when Current_Mode in Search =>
			accept Down_Arrow do
			   if File_Index < Shell_Interface.Search_Result.File_Content'Length  then
			      File_Index := Positive'Min(File_Index+1, Shell_Interface.Search_Result.File_Content'Length );			   
			   end if;
			end Down_Arrow;
			My_Ansi_Consoles.Clear_Screen;
		  or
		     when Current_Mode in Computation =>
			accept Page_Down do
			   if Shell_Interface.Search_Result.File_Content /= null and then
			     File_Index+(Computation_Max_Lines-3) < Shell_Interface.Search_Result.File_Content'Length  then
			      File_Index := Positive'Min(File_Index+(Computation_Max_Lines-2), Shell_Interface.Search_Result.File_Content'Length );
			      Computing_Col := 0;
			   end if;
			end Page_Down;
			My_Ansi_Consoles.Clear_screen;
			Mode_Info_Status(W1, Current_Mode);
			--Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to load file).");
			
			
		  or
		     when Current_Mode in Computation =>
			accept Page_Up do
			   if Shell_Interface.Search_Result.File_Content /= null and then
			     File_Index > (Computation_Max_Lines-2) then
			      File_Index := File_Index - (Computation_Max_Lines-2);
			      Computing_Col := 0;
			   else
			      File_Index := 0;
			      Computing_Col := 0;
			   end if;
			end Page_Up;
			My_Ansi_Consoles.Clear_screen;
			Mode_Info_Status(W1, Current_Mode);
			--Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to load file).");
			
		  or
		     when Current_Mode in Computation =>
			accept Up_Arrow do
			   if Shell_Interface.Search_Result.File_Content /= null and then
			     File_Index > 1 then
			      File_Index := File_Index - 1;
			      Computing_Col := Wide_String((-Shell_Interface.Search_Result.File_Content(File_Index)))'Length;
			   end if;
			end Up_Arrow;
			My_Ansi_Consoles.Clear_screen;
			Mode_Info_Status(W1, Current_Mode);
			--Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to load file).");
		  or
		     when Current_Mode in Computation =>
			accept Down_Arrow do
			   if Shell_Interface.Search_Result.File_Content /= null and then
			     File_Index < Shell_Interface.Search_Result.File_Content'Length  then
			      File_Index := Positive'Min(File_Index+1, Shell_Interface.Search_Result.File_Content'Length );
			      Computing_Col := 0;
			   end if;
			end Down_Arrow;
			My_Ansi_Consoles.Clear_screen;
			Mode_Info_Status(W1, Current_Mode);
			--Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to load file).");
			
			
		  or
		     when Current_Mode = GnuShell =>
			accept Page_Down do
			   if File_Index+(Result_Max_Lines-1) < Shell_Interface.Spawn_Result.File_Content'Length  then
			      File_Index := Positive'Min(File_Index+(Result_Max_Lines-1), Shell_Interface.Spawn_Result.File_Content'Length );
			   end if;
			end Page_Down;
			Mode_Initialization(W10, Current_Mode, On_Esc, Message => "");
			
		  or
		     when Current_Mode = GnuShell =>
			accept Page_Up do
			   if File_Index > (Result_Max_Lines-1) then
			      File_Index := File_Index - (Result_Max_Lines-1);
			   else
			      File_Index := 0;
			   end if;
			end Page_Up;
			Mode_Initialization(W10, Current_Mode, On_Esc, Message => "");
		  or
		     when Current_Mode = GnuShell =>
			accept Up_Arrow do
			   if File_Index > 0 then
			      File_Index := File_Index - 1;
			   end if;
			end Up_Arrow;
			Mode_Initialization(W10, Current_Mode, On_Esc, Message => "");
		  or
		     when Current_Mode = GnuShell =>
			accept Down_Arrow do
			   if File_Index + 1 < Shell_Interface.Spawn_Result.File_Content'Length  then
			      File_Index := Positive'Min(File_Index+1, Shell_Interface.Spawn_Result.File_Content'Length );
			   end if;
			end Down_Arrow;
			Mode_Initialization(W10, Current_Mode, On_Esc, Message => "");

			
		  or
		     when Current_Mode = Shell_Print  =>
			accept Page_Down do
			   if File_Index+(Lines-1) < Shell_Interface.Search_Result.File_Content'Length  then
			      File_Index := Positive'Min(File_Index+(Lines-1), Shell_Interface.Search_Result.File_Content'Length );
			   end if;
			end Page_Down;
		  or
		     when Current_Mode =  Shell_Print  =>
			accept Page_Up do
			   if File_Index > (Lines-1) then
			      File_Index := File_Index - (Lines-1);
			   else
			      File_Index := 0;
			   end if;
			end Page_Up;
		  or
		     when Current_Mode =  Shell_Print  =>
			accept Up_Arrow do
			   if File_Index > 0 then
			      File_Index := File_Index - 1;
			   end if;
			end Up_Arrow;
		  or
		     when Current_Mode =  Shell_Print  =>
			accept Down_Arrow do
			   if File_Index + 1 < Shell_Interface.Search_Result.File_Content'Length  then
			      File_Index := Positive'Min(File_Index+1, Shell_Interface.Search_Result.File_Content'Length );
			   end if;
			end Down_Arrow;
			
		  or
		     when Current_Mode in Print | Shell_Print | EnvironmentParameters | Builtin | Search =>
			accept Receive (Char : in Wide_Character);
		  or
		     
		     
		     when Current_Mode = Computation =>
			accept Receive (Char : in Wide_Character) do
			   if Is_Control(To_Character(Char)) then
			      
			      case Char is
				 when Wide_Character'Val(10) =>				 

				    Compute(Shell_Interface.Search_Result'Access, Char, Computing_Line+File_Index, Computing_Col+1, Success);
				    
				    Computing_Col := 0;				 
				    
				    File_Index := File_Index + 1;
				    
				 when Wide_Character'Val(127) =>				 				 
				    if Computing_Col > 0 then				 
				       
				       Compute(Shell_Interface.Search_Result'Access, Char, Computing_Line+File_Index, Computing_Col+1, Success);
				       
				       Computing_Col := Computing_Col - 1;
				       
				    elsif File_Index > 1 then
				       
				       Compute(Shell_Interface.Search_Result'Access, Char, Computing_Line+File_Index, Computing_Col+1, Success);
				       
				       File_Index := File_Index - 1;				   
				    else
				       
				       Ada.Text_Io.Put(Character'Val(7));

				    end if;				 
				 when Wide_Character'Val(12) =>
				    Load(Shell_Interface.Search_Result'Access, Success);
				 when others =>
				    
				    Compute(Shell_Interface.Search_Result'Access, Char, Computing_Line+File_Index, Computing_Col+1, Success);
				    
			      end case;
			      
			   elsif Line'Length < (Term_width-5)*(Result_Max_lines-3) then
			      
			      Compute(Shell_Interface.Search_Result'Access, Char, Computing_Line+File_Index, Computing_Col+1, Success);

			      if Success then
				 case Char is				 
				    when others =>
				       Computing_Col := Computing_Col + 1;
				 end case;
			      end if;
			   else
			      Ada.Text_Io.Put(Character'Val(7));
			   end if;
			end Receive;
			My_Ansi_Consoles.Clear_screen;
			Mode_Info_Status(W1, Current_Mode);
			--Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to load file).");
			
		  or
		     when Current_Mode not in Computation =>
			accept Right_Arrow;
		  or
		     when Current_Mode not in Computation =>
			accept Left_Arrow;
			
		  or
		     when Current_Mode = Computation =>
			accept Left_Arrow do
			   
			   if Computing_Col > 0 then
			      Computing_Col := Computing_Col - 1;
			   elsif File_Index > 1 then
			      File_Index := File_Index - 1;
			      Computing_Col := Wide_String((-Shell_Interface.Search_Result.File_Content(File_Index)))'Length;
			   else
			      Ada.Text_Io.Put(Character'Val(7));
			   end if;			   			   
			end Left_Arrow;
			My_Ansi_Consoles.Clear_screen;
			Mode_Info_Status(W1, Current_Mode);
			--Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to load file).");
		  or
		     when Current_Mode = Computation =>
			accept Right_Arrow do
			   if Shell_Interface.Search_Result.File_Content /= null and then
			     Computing_Col + 1 <= Wide_String((-Shell_Interface.Search_Result.File_Content(File_Index)))'Length then
			      Computing_Col := Computing_Col + 1;
			   elsif Shell_Interface.Search_Result.File_Content /= null and then
			     Computing_Col + 1 > Wide_String(-Shell_Interface.Search_Result.File_Content(File_Index))'Length then
			      if File_Index + 1 <= Shell_Interface.Search_Result.File_Content'Length then
				 File_Index := Positive'Min(File_Index+1, Shell_Interface.Search_Result.File_Content'Length);
				 Computing_Col := 0;			
			      else
				 Ada.Text_Io.Put(Character'Val(7));
			      end if;	
			      
			   else			   
			      Ada.Text_Io.Put(Character'Val(7));
			   end if;
			end Right_Arrow;    
			My_Ansi_Consoles.Clear_screen;
			Mode_Info_Status(W1, Current_Mode);
			--Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to load file).");
		  or
		     when Current_Mode = GnuShell =>
			accept Receive (Char : in Wide_Character) do
			   case Char is
			      when Wide_Character'Val(127) =>
				 if Line /= null and then Line'Length > 0 then
				    Buffer := new Wide_String ' (Line(Line'First..Line'Last-1));
				    Free(Line);
				    Line := new Wide_String ' (Buffer.all);
				    Free(Buffer);                     
				 end if;                           
			      when Wide_Character'Val(10) =>
				 Matrix_Saver.Stop;
				 declare
				    Echo_Error : Integer := 0;
				 begin                           
				    if Line /= null then
				       if Line'Length > 0 and Wide_Fixed.Index_Non_Blank(Line.all) /= 0 then
					  Current_Command := Values.Value(Null_Item, To_String(Line.all));				       
				       else
					  Line := new Wide_String ' ("sh -c ""echo Hello World : """);
				       end if;
				       Gnushell_command(W3, Shell_Interface, (Line.all), Echo_Error);
				       --My_Ansi_Consoles.Clear_screen;
				       
				       if Echo_Error = 0 then
					  if Shell_Interface.Spawn_Result.Args /= null then
					     for Arg in Shell_Interface.Spawn_Result.Args'Range loop
						Free(Shell_Interface.Spawn_Result.Args(Arg));
					     end loop;
					  end if;
				       end if;                                                                                    
				       
				       if Shell_Interface.Spawn_Result.File_content'Length > Result_Max_Lines-4 then
					  
					  File_Index := (Shell_Interface.Spawn_Result.File_content'Length-((Result_Max_Lines-4)-Line'Length/Chars_Max) + 1);
				       else
					  
					  File_Index := 0;
				       end if;
				       Line_Index := 0;
				       
				       
				       --  Line := new Wide_String ' ("sh -c ""echo Hello World : """);
				       --  Gnushell_command(W3, Shell_Interface, Line.all, errno);
				       --  My_Ansi_Consoles.Clear_screen;                                                                                 
				       
				       --  if Errno = 0 then
				       --     if Shell_Interface.Spawn_Result.Args /= null then
				       --  	  for Arg in Shell_Interface.Spawn_Result.Args'Range loop
				       --  	     Free(Shell_Interface.Spawn_Result.Args(Arg));
				       --  	  end loop;
				       --     end if;
				       --  end if;                                                                                    
				       if Echo_Error = 0 then
					  Free(Line);
					  Line := new Wide_String ' ("");
				       end if;
				       
				    end if;
				 end;
				 Matrix_Saver.Start;
			      when Wide_Character'Val(12) =>
				 Free(line);                        
				 Line := new Wide_String ' ("");
			      when Wide_Character'Val(20) =>
				 
				 Mode_Info_Status(W1, Adamanborg_Call);
				 Run_Gtk(W4, Shell_Interface, Errno);
				 My_Ansi_Consoles.Clear_screen;                           
				 Mode_Info_Status(W1, Null_Item);
				 
				 Main_Info_Status(W4);
				 
				 Current_Mode := Null_Item;
			      when others =>
				 if Is_Control(To_Character(Char)) then
				    null;
				 else
				    case Current_Mode is				    
				       when others =>
					  if Line /= null then
					     if Line'Length < (columns-10)*(Lines_Max-3) then
						Buffer := new Wide_String ' (Line.all & Char);
						Free(Line);
						Line := new Wide_String ' (Buffer.all);
						Free(Buffer);                             
					     end if;
					  else
					     Line := new Wide_String ' ("" & Char);
					  end if;
				    end case;
				 end if;
			   end case;         
			end Receive;
			case Current_Mode is
			   when Gnushell =>			   
			      Mode_Initialization(W10, Current_Mode, On_Esc, Message => "");
			   when others =>
			      null;
			end case;
		  or
		     
		     when Current_Mode = AiManagment =>
			accept Receive (Char : in Wide_Character) do
			   if Is_Control(To_Character(Char)) then
			      
			      declare
				 The_Control : constant Character := To_Character(Char); 
				 Local_Env : Environment_Access;
				 Environment_Size : Natural := 0;
			      begin
				 case The_Control is
				    when Ascii.EOT =>
				       null;
				    when Ascii.DEL =>
				       if Human_Line'Length > 0 then
					  Free(Buffer);
					  Buffer := new Wide_String ' (Human_Line.all(Human_Line'First..Human_Line'Last-1));
					  Common.Free(Human_Line);
					  Human_Line := new Wide_String ' (Buffer.all);
				       else
					  Ada.Text_Io.Put(Ascii.BEL);
				       end if;  
				    when Ascii.LF =>
				       
				       
				       
				       Wide_String'Output (Channel, Human_Line.all);			   
				       
				       ------------------------------------------------
				       -- Request to server...                       --
				       Cyborg_Data_Max := Natural'Input(Channel);
				       
				       if Cyborg_Data_Max > 0 then
					  for I in 1..Cyborg_Data_Max loop
					     Cyborg_line := new Wide_String ' (Wide_String'Input(Channel));
					     
					     Common.Free(Data_Buffer(I));
					     Data_Buffer(I) := Cyborg_Line;
					     
					  end loop;
				       end if;
				       
				       -- Empty left buffer.
				       if Cyborg_Data_Max + 1 <= Data_Buffer'last then
					  for I in Cyborg_Data_Max+1..Data_Buffer'Last loop
					     Common.Free(Data_Buffer(I));
					     
					  end loop;
				       end if;
				       Data_Buffer_Index := Data_Buffer'last;

				       --                                             --
				       -------------------------------------------------
				       
				       
				       --------------------------------------------------
				       --               Environment                    --
				       Text_Io.Put_Line("Receive environment...");
				       Environment_Size := Natural'Input(Channel);
				       Wide_Text_Io.Put_Line("Local_Env := new Environment_Type(Environment_Size) received.");
				       if Environment_Size /= 0 then
					  Wide_Text_Io.Put_Line("Env_Size /= 0.");
					  Local_Env := new Environment_Type(Environment_Size);
					  Wide_Text_Io.Put_Line("New local env...");
					  for Element_Id in Local_Env.Elements'Range loop			
					     declare
						Object_Size : constant Natural := Positive'Input(Channel);
						Parameters  : constant Variadic_Array_Access :=
						  new Variadic_Array_Type(1..Object_Size);
					     begin
						for Attribut_Id in Parameters'Range loop
						   
						   declare
						      Classified_Object : Classified_Access;
						      Class             : constant Class_Type := Class_Type'Input(Channel);
						   begin
						      case Class is
							 when Classes.Text =>
							    Wide_Text_Io.Put_Line("Cyborg environment receive Text");
							    Classified_Object := new Text_Object_Type;
							    Classified_Object.Initialize
							      (From => Wide_String'Input(Channel));

							 when Classes.Date =>
							    Wide_Text_Io.Put_Line("Cyborg environment receive Date");
							    Classified_Object := new Date_Object_Type;
							    Classified_Object.Initialize
							      (From => To_Wide_String((Formatting.Image(Date_Object_Type'Input(Channel).Date))));

							 when Classes.Floatting =>
							    Wide_Text_Io.Put_Line("Cyborg environment receive Floatting");
							    Classified_Object := new Real_Object_Type;
							    Classified_Object.Initialize
							      (From => To_Wide_String(Float'image(Float'input(Channel))));
							    
						      end case;

						      Parameters(Attribut_Id) := Classified_Object;

						   exception
						      when others =>
							 Wide_Text_Io.Put_Line("Data_input demaon Exception when receive data...");
							 raise;
						   end;
						end loop;
						Local_Env.Elements(Element_Id) := Parameters;
					     exception
						when others =>
						   Wide_Text_Io.Put_Line("Data_input demaon on others error");
						   raise;
					     end;
					  end loop;
					  Wide_Text_Io.Put_Line("Local_Env := new Environment_Type(Environment_Size) : done");
					  Env := Local_Env;
				       end if;
				       
				       Text_Io.Put_Line("Environment received !");
				       
				       
				       
				       Common.Free(Buffer);
				       Buffer := new Wide_String ' ("");
				       Common.Free(Human_Line);
				       Human_Line := new Wide_String ' (Buffer.all);

				    when Ascii.FF =>
				       Common.Free(Buffer);
				       Buffer := new Wide_String ' ("");
				       Common.Free(Human_Line);
				       Human_Line := new Wide_String ' (Buffer.all);
				    when others =>
				       
				       
				       Wide_String'Output (Channel, "hello");			   
				       
				       ------------------------------------------------
				       -- Request to server...                       --
				       Cyborg_Data_Max := Natural'Input(Channel);
				       
				       if Cyborg_Data_Max > 0 then
					  for I in 1..Cyborg_Data_Max loop
					     Cyborg_line := new Wide_String ' (Wide_String'Input(Channel));
					     
					     Common.Free(Data_Buffer(I));
					     Data_Buffer(I) := Cyborg_Line;				 
					  end loop;
				       end if;
				       
				       -- Empty left buffer.
				       if Cyborg_Data_Max + 1 <= Data_Buffer'last then
					  for I in Cyborg_Data_Max+1..Data_Buffer'Last loop
					     Common.Free(Data_Buffer(I));				 
					  end loop;
				       end if;
				       Data_Buffer_Index := Data_Buffer'last;
				       --                                             --
				       -------------------------------------------------
				       
				       
				       --------------------------------------------------
				       --               Environment                    --
				       Text_Io.Put_Line("Receive environment...");
				       Environment_Size := Natural'Input(Channel);
				       Wide_Text_Io.Put_Line("Local_Env := new Environment_Type(Environment_Size) received.");
				       if Environment_Size /= 0 then
					  Wide_Text_Io.Put_Line("Env_Size /= 0.");
					  Local_Env := new Environment_Type(Environment_Size);
					  Wide_Text_Io.Put_Line("New local env...");
					  for Element_Id in Local_Env.Elements'Range loop			
					     declare
						Object_Size : constant Natural := Positive'Input(Channel);
						Parameters  : constant Variadic_Array_Access :=
						  new Variadic_Array_Type(1..Object_Size);
					     begin
						for Attribut_Id in Parameters'Range loop
						   
						   declare
						      Classified_Object : Classified_Access;
						      Class             : constant Class_Type := Class_Type'Input(Channel);
						   begin
						      case Class is
							 when Classes.Text =>
							    Wide_Text_Io.Put_Line("Cyborg environment receive Text");
							    Classified_Object := new Text_Object_Type;
							    Classified_Object.Initialize
							      (From => Wide_String'Input(Channel));

							 when Classes.Date =>
							    Wide_Text_Io.Put_Line("Cyborg environment receive Date");
							    Classified_Object := new Date_Object_Type;
							    Classified_Object.Initialize
							      (From => To_Wide_String((Formatting.Image(Date_Object_Type'Input(Channel).Date))));

							 when Classes.Floatting =>
							    Wide_Text_Io.Put_Line("Cyborg environment receive Floatting");
							    Classified_Object := new Real_Object_Type;
							    Classified_Object.Initialize
							      (From => To_Wide_String(Float'image(Float'input(Channel))));
							    
						      end case;

						      Parameters(Attribut_Id) := Classified_Object;

						   exception
						      when others =>
							 Wide_Text_Io.Put_Line("Data_input demaon Exception when receive data...");
							 raise;
						   end;
						end loop;
						Local_Env.Elements(Element_Id) := Parameters;
					     exception
						when others =>
						   Wide_Text_Io.Put_Line("Data_input demaon on others error");
						   raise;
					     end;
					  end loop;
					  Wide_Text_Io.Put_Line("Local_Env := new Environment_Type(Environment_Size) : done");
					  Env := Local_Env;
				       end if;

				       Text_Io.Put_Line("Environment received !");
				       
				       
				       
				       Common.Free(Buffer);
				       Buffer := new Wide_String ' ("");
				       Common.Free(Human_Line);
				       Human_Line := new Wide_String ' (Buffer.all);
				 end case;
			      end;
			   else
			      if Human_Line'Length < 3*Chars_Max then
				 Common.Free(Buffer);
				 Buffer := new Wide_String ' (Human_Line.all & Char);
				 Common.Free(Human_Line);
				 Human_Line := new Wide_String ' (Buffer.all);
			      else
				 Ada.Text_Io.Put(Ascii.BEL);
			      end if;
			   end if;
			   
			end Receive;
			
			Previsious_Mode := Aimanagment;
			Current_Mode := Aimanagment_Print;
			
		  or
		     
		     when Current_Mode in Null_Item | GnuLinuxInterface | Allmanuals =>
			accept Receive (Char : in Wide_Character) do
			   
			   case Char is
			      when Wide_Character'Val(9) =>
				 declare
				    Path_On_Line : Common.String_Access;
				 begin
				    Completion.Completion(To_String(Line.all), Path_On_Line, Completion_Result);
				    if Path_On_Line /= null then
				       Buffer := new Wide_String ' (Path_On_Line.all);
				       Free(Line);
				       Line := new Wide_String ' (Buffer.all);
				       Free(Buffer);
				    else
				       Previsious_Mode := Current_Mode;
				       Current_Mode := Completion_Print;				       
				    end if;
				 end;
			      when Wide_Character'Val(127) =>
				 if Line /= null and then Line'Length > 0 then
				    Buffer := new Wide_String ' (Line(Line'First..Line'Last-1));
				    Free(Line);
				    Line := new Wide_String ' (Buffer.all);
				    Free(Buffer);                     
				 end if;                           
			      when Wide_Character'Val(10) =>
				 Matrix_Saver.Stop;
				 begin                           
				    if Line /= null then
				       if Line'Length > 0 and Wide_Fixed.Index_Non_Blank(Line.all) /= 0 then
					  Current_Command := Values.Value(Null_Item, (To_String(Line.all)));
					  case Current_Command is
					     when Computation =>
						
						
						if Wide_Fixed.Index((Line.all(Wide_Fixed.Index_Non_Blank((Line.all))..Line'Last)), " ") /= 0 and then
						  Wide_Fixed.Index_Non_Blank((Line.all), Backward) /= 
						  Wide_Fixed.Index((Line.all(Wide_Fixed.Index_Non_Blank((Line.all))..Line'Last)), " ") then
						   begin
						      declare
							 What : constant Wide_String := Line.all(Wide_Fixed.Index
												   ((Line.all(Wide_Fixed.Index_Non_Blank
														((Line.all))..Line'Last)),
												    " ")+1..Wide_Fixed.Index_Non_Blank((Line.all), Backward));
						      begin
							 
							 Shell_Interface.Search_Result.Doc_Name := new Wide_String ' ((What));
							 
							 
						      end;
						   end;
						   
						   File_Index := 1;
						   Line_Index := 0;
						   Computing_Line := 0;
						   Computing_Col := 0;
						   Previsious_Mode := Current_Mode;
						   Current_Mode := Computation;
						   Mode_Info_Status(W1, Current_Mode);						
						elsif Shell_Interface.Search_Result.Doc_Name /= null then
						   
						   Previsious_Mode := Current_Mode;
						   Current_Mode := Computation;
						   
						   File_Index := 1;
						   Line_Index := 0;
						   Computing_Line := 0;
						   Computing_Col := 0;
						end if;										  
						
						My_Ansi_Consoles.Clear_screen;
					     when GnuShell =>
						Previsious_Mode := Current_Mode;
						Current_Mode := GnuShell;
					     when Chess =>
						null;
					     when Alarm =>
						if Wide_Fixed.Index((Line.all(Wide_Fixed.Index_Non_Blank((Line.all))..Line'Last)), " ") /= 0 and then
						  Wide_Fixed.Index_Non_Blank((Line.all), Backward) /= 
						  Wide_Fixed.Index((Line.all(Wide_Fixed.Index_Non_Blank((Line.all))..Line'Last)), " ") then
						   begin
						      
						      declare
							 Alarm_Line : constant String := To_string(Line.all(Wide_Fixed.Index
													      (((Line.all(Wide_Fixed.Index_Non_Blank
															    ((Line.all))..Line'Last))),
													       " ")+1..Wide_Fixed.Index_Non_Blank((Line.all), Backward)));
							 Current_Date : constant Time := Clock;
							 Alarm_Delay : Duration := 0.0;
						      begin
							 
							 begin
							    Alarm_Delay := Formatting.Value(Alarm_Line);
							    Alarm_Time_Stop := Current_Date + Alarm_Delay;
							 exception
							    when Constraint_Error =>
							       Alarm_Time_Stop := Formatting.Value(Alarm_Line);-- Time_Zones.UTC_Time_Offset(Current_date));
							 end;
							 Alarm_Time_Start := Current_Date;
							 if Alarm_Time_Stop > Alarm_Time_Start then
							    Adam_Alarm.Alarm_Start(Alarm_Time_Start, Alarm_Time_Stop);

							    Alarm_Is_Set := True;
							    
							    
							    split(Alarm_Time_Start,
								  Shared_Alarm.Start_Date.Year,
								  Shared_Alarm.Start_Date.Month,
								  Shared_Alarm.Start_Date.Day,
								  Shared_Alarm.Start_Date.Hours);
							    
							    
							    
							    Split(Alarm_Time_Stop,
								  Shared_Alarm.Stop_Date.Year,
								  Shared_Alarm.Stop_Date.Month,
								  Shared_Alarm.Stop_Date.Day,
								  Shared_Alarm.Stop_Date.Hours);

							    
							    
							    Shared_Alarm.Is_Set := True;
							    
							    My_Ansi_Consoles.Clear_screen;
							    
							    Errno := 0;
							 else
							    Errno := -1;
							 end if;
						      exception
							 when others =>
							    Errno := -1;
							    
						      end;

						   exception
						      when others =>
							 Errno := -1;
						   end;
						end if;
						
					     when Adamanborg_Call =>
						Previsious_mode := Current_Mode;
						Current_Mode := Current_Command;
						My_Ansi_Consoles.Clear_screen;
						Mode_Info_Status(W1, Adamanborg_Call);
						Run_Gtk(W4, Shell_Interface, Errno);                                          
					     when Search =>
						begin
						   if Wide_Fixed.Index((Line.all(Wide_Fixed.Index_Non_Blank((Line.all))..Line'Last)), " ") /= 0 and then
						     Wide_Fixed.Index_Non_Blank((Line.all), Backward) /= 
						     Wide_Fixed.Index((Line.all(Wide_Fixed.Index_Non_Blank((Line.all))..Line'Last)), " ") then
						      declare
							 Search_String : constant Wide_String := 
							   Line.all(Wide_Fixed.Index
								      ((Line.all(Wide_Fixed.Index_Non_Blank
										   ((Line.all))..Line'Last)),
								       " ")+1..Wide_Fixed.Index_Non_Blank((Line.all), Backward));
						      begin
							 
							 
							 if Search_String'Length /= 0 then							 
							    if Web_Search /= null then
							       select
								  Web_Search.Halt;
							       else
								  abort Web_Search.all;
							       end select;							 
							    end if;
							    My_Ansi_Consoles.Clear_screen;
							    Mode_Info_Status(W1, Null_Item);                                             
							    
							    Web_Search := 
							      new Web_Search_Type
							      (new Window_Type '(W6), 
							       Shell_Interface.Search_Result'access, 
							       new Wide_String ' (Search_String), new Integer ' (Errno));
							    Previsious_mode := Current_Mode;
							    Current_Mode := Current_Command;
							    File_Index := 0;
							    Line_Index := 0;
							 else
							    if Web_Search /= null then
							       Web_Search.Start;
							       Previsious_mode := Current_Mode;
							       Current_Mode := Current_Command;							 
							    end if;
							 end if;
							 
						      end;
						   else
						      if Web_Search /= null then
							 Web_Search.Start;
							 Previsious_mode := Current_Mode;
							 Current_Mode := Current_Command;						   
						      end if;
						   end if;					  
						exception
						   when others =>
						      Errno := -1;
						end;
						
					     when Howto =>
						
						
						if Wide_Fixed.Index((Line.all(Wide_Fixed.Index_Non_Blank((Line.all))..Line'Last)), " ") /= 0 and then
						  Wide_Fixed.Index_Non_Blank((Line.all), Backward) /= 
						  Wide_Fixed.Index((Line.all(Wide_Fixed.Index_Non_Blank((Line.all))..Line'Last)), " ") then
						   begin
						      declare
							 What : constant Wide_String := Line.all(Wide_Fixed.Index
												   ((Line.all(Wide_Fixed.Index_Non_Blank
														((Line.all))..Line'Last)),
												    " ")+1..Wide_Fixed.Index_Non_Blank((Line.all), Backward));
						      begin
							 
							 
							 
							 Linux.Howto((To_String(What)), 
								     To_Lower(Getenv("LANG").all(1..2)), 
								     Shell_Interface.Spawn_Result);
						      end;
						   end;
						   Previsious_Mode := Current_Mode;
						   Current_Mode := Print;
						   
						   My_Ansi_Consoles.Clear_screen;
						   Command_Info_Status(W11, Shell_Interface);
						   Mode_Info_Status(W1, Previsious_Mode);
						   Read_Quit_Info_Status(W3, On_Esc);					     
						   My_Ansi_Consoles.Draw_Window (W10);
						   
						   
						   File_Index := 0;
						   Line_Index := 0;
						end if;
						
					     when Null_item =>
						case Current_Mode is 
						   when Null_Item | GnuLinuxInterface =>
						      
						      My_Ansi_Consoles.Clear_screen;
						      Mode_Info_Status(W1, Null_Item);
						      
						      My_Ansi_Consoles.Draw_Window (W5);
						      My_Ansi_Consoles.Draw (W5, 1, 3, Ansi_Console.White, "Command line   : " & (Line.all));         
						      
						      
						      Sub_Command := Adam.Values.Sub_Value(Null_Command, To_String(Line.all));
						      
						      declare   
							 
							 
							 Argv : constant Wide_String := Line.all;
							 
						      begin
							 case Sub_Command is
							    when Getenv | Setenv | Chdir | Mkdir =>
							       Builtin_Sub_Command(W11, Sub_Command, Shell_Interface, Argv, errno);
							       Previsious_Mode := Current_Mode;
							       Current_Mode := BuiltIn;							
							       My_Ansi_Consoles.Clear_screen;
							    when others =>
							       
							       System(W3, Shell_Interface, (Line.all), errno);
							       My_Ansi_Consoles.Clear_Screen;            
							       
							       if Errno = 0 then
								  if Shell_Interface.Spawn_Result.Args /= null then
								     for Arg in Shell_Interface.Spawn_Result.Args'Range loop
									Free(Shell_Interface.Spawn_Result.Args(Arg));
								     end loop;
								  end if;
							       end if;                                                                                    
							       
							       My_Ansi_Consoles.Clear_screen;
							       Previsious_Mode := Current_Mode;
							       Current_Mode := Print;
							       
							       Command_Info_Status(W11, Shell_Interface);
							       Mode_Info_Status(W1, Previsious_Mode);
							       Read_Quit_Info_Status(W3, On_Esc);
							       
							       My_Ansi_Consoles.Draw_Window (W10);
							       
							       
							       File_Index := 0;
							       Line_Index := 0;
							 end case;
						      end;
						      
						   when AllManuals =>
						      declare
							 Man_Line : constant Wide_String := To_Wide_String(Parse_Man_Command(To_String(Line.all)));
						      begin                                                  
							 My_Ansi_Consoles.Clear_screen;
							 Mode_Info_Status(W1, AllManuals);                                                   
							 My_Ansi_Consoles.Draw_Window (W5);
							 My_Ansi_Consoles.Draw (W5, 1, 3, Ansi_Console.White, "Command line   : " & (Man_Line));
							 if Man_Line'Length > 0 then
							    System(W3, Shell_Interface, (Man_Line), errno);
							    My_Ansi_Consoles.Clear_screen;
							    if Errno = 0 then
							       if Shell_Interface.Spawn_Result.Args /= null then
								  for Arg in Shell_Interface.Spawn_Result.Args'Range loop
								     Free(Shell_Interface.Spawn_Result.Args(Arg));
								  end loop;
							       end if;                                                         
							    end if;
							    Previsious_Mode := AllManuals;
							    Current_Mode := Print;
							    
							    
							    Command_Info_Status(W11, Shell_Interface);
							    Mode_Info_Status(W1, Previsious_Mode);
							    Read_Quit_Info_Status(W3, On_Esc);						      
							    My_Ansi_Consoles.Draw_Window (W10);
							    
							    
							    File_Index := 0;
							    Line_Index := 0;                                                      
							 end if;
						      end;						
						   when others =>
						      null;
						end case;
					     when others =>
						null;
					  end case;
				       end if;
				       if History_Index <= History_Max then 
					  Command_Line_History(History_Index) := new Wide_String ' (Line.all);
					  History_Index := History_Index + 1;
				       else
					  Free(Command_Line_History(1));
					  for I in 1..History_Max-1 loop
					     Command_Line_History(I) := Command_Line_History(I + 1);
					  end loop;
					  Command_Line_History(History_Max) := new Wide_String ' (Line.all);
				       end if;
				       Command_Line_Index := 0;                                 
				       
				       if Errno = 0 then
					  Free(Line);
					  Line := new Wide_String ' ("");
				       end if;
				       
				    end if;
				 end;
				 Matrix_Saver.Start;
			      when Wide_Character'Val(12) =>
				 Free(line);                        
				 Line := new Wide_String ' ("");
			      when Wide_Character'Val(20) =>
				 
				 Mode_Info_Status(W1, Adamanborg_Call);
				 Run_Gtk(W4, Shell_Interface, Errno);
				 My_Ansi_Consoles.Clear_screen;                           
				 Mode_Info_Status(W1, Null_Item);
				 
				 Main_Info_Status(W4);
				 
				 Current_Mode := Null_Item;
			      when others =>
				 if Is_Control(To_Character(Char)) then
				    null;
				 else
				    case Current_Mode is
				       when SelfProgrammingProcess |
					 PlansAdministration |
					 AiManagment |
					 DataTechnologie =>
					  if Line /= null then
					     if Line'Length < (columns-10)*2 then
						Buffer := new Wide_String ' (Line.all & Char);
						Free(Line);
						Line := new Wide_String ' (Buffer.all);
						Free(Buffer);                             
					     end if;
					  else
					     Line := new Wide_String ' ("" & char);
					  end if;
				       when others =>
					  if Line /= null then
					     if Line'Length < (columns-10)*(Command_Max_Lines-4) then
						Buffer := new Wide_String ' (Line.all & Char);
						Free(Line);
						Line := new Wide_String ' (Buffer.all);
						Free(Buffer);                             
					     end if;
					  else
					     Line := new Wide_String ' ("" & char);
					  end if;
				    end case;
				 end if;
			   end case;            
			end Receive;    		     
			
			case Current_Mode is
			   when Null_Item =>			   
			      
			      Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
			      Main_Info_Status(W4);
			      
			   when Computation =>
			      
			      null;
			      
			      
			   when AllManuals =>
			      
			      Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
			      Man_Info(W4);

			   when Gnushell =>			   
			      Mode_Initialization(W10, Current_Mode, On_Esc, Message => "");
			      
			   when GnuLinuxInterface =>   
			      
			      Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
			      
			   when others =>
			      null;
			end case;
		  or
		     
		     when Current_Mode = PlansAdministration =>
			accept Receive (Char : in Wide_Character) do
			   case Char is
			      when Wide_Character'Val(127) =>
				 if Line /= null and then Line'Length > 0 then
				    Buffer := new Wide_String ' (Line(Line'First..Line'Last-1));
				    Free(Line);
				    Line := new Wide_String ' (Buffer.all);
				    Free(Buffer);                     
				 end if;                           
				 when Wide_Character'Val(12) =>
				 Free(line);                        
				 Line := new Wide_String ' ("");
				 
			      when Wide_Character'Val(9) =>
				 
				 if Shell_Interface.Zbank.Operation_Set /= null then
				    Sort_By_Operation(Shell_Interface.Zbank.Operation_Set);
				 end if;
				 
			      when Wide_Character'Val(10) =>
				 if Line /= null and then Line'Length > 0 then
				    Shell_Interface.Zbank.Line := new Wide_String ' (Line.all);
				    begin
				       
				       Split (Shell_Interface.Zbank.Line.all,
					      Shell_Interface.Zbank.Operator,
					      Shell_Interface.Zbank.Sum,
					      Shell_Interface.Zbank.Delay_Op,
					      Shell_Interface.Zbank.Tag );
				       

				       Shell_Interface.Zbank.All_Operation := Get_Operation ( Shell_Interface.Zbank.Operator,
											      Shell_Interface.Zbank.Sum,
											      Clock,
											      Shell_Interface.Zbank.Delay_Op,
											      Shell_Interface.Zbank.Tag.all );
				       Operation ( Shell_Interface.Zbank.Account,
						   Shell_Interface.Zbank.All_Operation.all,
						   Shell_Interface.Zbank.Filename.all );
				       List ( Shell_Interface.Zbank.Account, Shell_Interface.Zbank.Operation_Set, Shell_Interface.Zbank.Filename.all );
				       
				       Free(line);                        
				       Line := new Wide_String ' ("");
				       Line_Index := 0;
				    exception
				       when others =>
					  null;
				       
				    end;
				 else
				    begin
				       List ( Shell_Interface.Zbank.Account, Shell_Interface.Zbank.Operation_Set, Shell_Interface.Zbank.Filename.all );
				       Line_Index := 0;
				    exception
				       when others =>
					  null;
					  
				    end;
				 end if;
			      when Wide_Character'Val(20) =>
				 
				 Mode_Info_Status(W1, Adamanborg_Call);
				 Run_Gtk(W4, Shell_Interface, Errno);
				 My_Ansi_Consoles.Clear_screen;                           
				 Mode_Info_Status(W1, Null_Item);
				 
				 Main_Info_Status(W4);
				 
				 Current_Mode := Null_Item;
			      when others =>
				 if Is_Control(To_Character(Char)) then
				    null;
				 else
				    if Line /= null then
				       if Line'Length < (columns-10)*2 then
					  Buffer := new Wide_String ' (Line.all & Char);
					  Free(Line);
					  Line := new Wide_String ' (Buffer.all);
					  Free(Buffer);                             
				       end if;
				    else
				       Line := new Wide_String ' ("" & char);
				    end if;
				 end if;
			   end case;
			end Receive;
			
			My_Ansi_Consoles.Clear_screen;
			Previsious_Mode := Current_Mode;
			Current_Mode := Plans_Print;
			Mode_Initialization(W14, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");	
		  or
		     when Current_Mode in 
		       SelfProgrammingProcess |		       
		       DataTechnologie =>
			accept Receive (Char : in Wide_Character) do
			   
			   case Char is
			      when Wide_Character'Val(127) =>
				 if Line /= null and then Line'Length > 0 then
				    Buffer := new Wide_String ' (Line(Line'First..Line'Last-1));
				    Free(Line);
				    Line := new Wide_String ' (Buffer.all);
				    Free(Buffer);                     
				 end if;                           
			      when Wide_Character'Val(10) =>
				 Matrix_Saver.Stop;
				 begin                           
				    if Line /= null then
				       if Line'Length > 0 and Wide_Fixed.Index_Non_Blank((Line.all)) /= 0 then
					  Current_Command := Values.Value(Null_item, To_String(Line.all));
					  case Current_Command is
					     when Alarm =>
						if Wide_Fixed.Index((Line.all(Wide_Fixed.Index_Non_Blank((Line.all))..Line'Last)), " ") /= 0 and then
						  Wide_Fixed.Index_Non_Blank((Line.all), Backward) /= 
						  Wide_Fixed.Index((Line.all(Wide_Fixed.Index_Non_Blank((Line.all))..Line'Last)), " ") then
						   begin
						      declare
							 Alarm_Line : constant String := To_String(Line.all(Wide_Fixed.Index
													      (((Line.all(Wide_Fixed.Index_Non_Blank
															    ((Line.all))..Line'Last))),
													       " ")+1..Wide_Fixed.Index_Non_Blank((Line.all), Backward)));
							 Current_Date : constant Time := Clock;
							 Alarm_Delay : Duration := 0.0;
						      begin
							 
							 begin
							    Alarm_Delay := Formatting.Value(Alarm_Line);
							    Alarm_Time_Stop := Current_Date + Alarm_Delay;
							 exception
							    when Constraint_Error =>
							       Alarm_Time_Stop := Formatting.Value(Alarm_Line);-- Time_Zones.UTC_Time_Offset(Current_date));
							 end;
							 Alarm_Time_Start := Current_Date;
							 if Alarm_Time_Stop > Alarm_Time_Start then
							    Adam_Alarm.Alarm_Start(Alarm_Time_Start, Alarm_Time_Stop);

							    Alarm_Is_Set := True;
							    
							    
							    split(Alarm_Time_Start,
								  Shared_Alarm.Start_Date.Year,
								  Shared_Alarm.Start_Date.Month,
								  Shared_Alarm.Start_Date.Day,
								  Shared_Alarm.Start_Date.Hours);
							    
							    
							    
							    Split(Alarm_Time_Stop,
								  Shared_Alarm.Stop_Date.Year,
								  Shared_Alarm.Stop_Date.Month,
								  Shared_Alarm.Stop_Date.Day,
								  Shared_Alarm.Stop_Date.Hours);

							    
							    
							    Shared_Alarm.Is_Set := True;
							    
							    Errno := 0;
							 else
							    Errno := -1;
							 end if;
						      exception
							 when others =>
							    Errno := -1;
							    
						      end;
						   exception
						      when others =>
							 Errno := -1;
						   end;
						end if;
						
					     when Adamanborg_Call =>
						Previsious_mode := Current_Mode;
						Current_Mode := Current_Command;
						My_Ansi_Consoles.Clear_screen;
						Mode_Info_Status(W1, Adamanborg_Call);
						Run_Gtk(W4, Shell_Interface, Errno);                                          
					     when Search =>
						begin
						   if Wide_Fixed.Index((Line.all(Wide_Fixed.Index_Non_Blank((Line.all))..Line'Last)), " ") /= 0 and then
						     Wide_Fixed.Index_Non_Blank((Line.all), Backward) /= 
						     Wide_Fixed.Index((Line.all(Wide_Fixed.Index_Non_Blank((Line.all))..Line'Last)), " ") then
						      declare
							 Search_String : constant Wide_String := 
							   Line.all(Wide_Fixed.Index
								      ((Line.all(Wide_Fixed.Index_Non_Blank
										   ((Line.all))..Line'Last)),
								       " ")+1..Wide_Fixed.Index_Non_Blank((Line.all), Backward));
						      begin
							 if Search_String'Length /= 0 then							 
							    if Web_Search /= null then
							       select
								  Web_Search.halt;
							       else
								  abort Web_Search.all;
							       end select;							    
							    end if;
							    My_Ansi_Consoles.Clear_screen;
							    Mode_Info_Status(W1, Null_Item);                                             
							    Web_Search := 
							      new Web_Search_Type
							      (new Window_Type '(W6), 
							       Shell_Interface.Search_Result'access, 
							       new Wide_String ' (Search_String), new Integer ' (Errno));
							    Previsious_mode := Current_Mode;
							    Current_Mode := Current_Command;
							    File_Index := 0;
							    Line_Index := 0;
							 else
							    if Web_Search /= null then
							       Web_Search.Start;
							       Previsious_mode := Current_Mode;
							       Current_Mode := Current_Command;
							    end if;
							 end if;						      
						      end;
						   else
						      if Web_Search /= null then
							 Web_Search.Start;
							 Previsious_mode := Current_Mode;
							 Current_Mode := Current_Command;
						      end if;						   
						   end if;
						exception
						   when others =>
						      Errno := -1;
						end;
						
					     when Null_item =>
						case Current_Mode is 
						   when SelfProgrammingProcess |						     
						     
						     DataTechnologie =>
						      
						      select
							 Shells.Adam_Shell.Respond(Current_Mode, "");
						      or 
							 delay 0.1;
							 My_Ansi_Consoles.Draw_Window (W2);
							 My_Ansi_Consoles.Draw_Centered (W2, 3, Ansi_Console.White, "Shell built-in...");
						      end select;
						      select
							 Shells.Adam_Shell.Response(Adamanborg_Shell_Response);
							 Shell_Info(W13, Current_Mode, Shell_Interface, errno);
							 Previsious_Mode := Current_Mode;
							 Current_Mode := Shell_Print;
							 File_Index := 0;
							 Line_Index := 0;
						      or 
							 delay 0.1;			   
							 
							 My_Ansi_Consoles.Draw_Window (W2);
							 My_Ansi_Consoles.Draw_Centered (W2, 3, Ansi_Console.White, "Shell response not available...");
							 
						      end select;
						      
						   when others =>
						      null;
						end case;
					     when others =>
						null;
					  end case;
				       end if;
				       if History_Index <= History_Max then 
					  Command_Line_History(History_Index) := new Wide_String ' (Line.all);
					  History_Index := History_Index + 1;
				       else
					  Free(Command_Line_History(1));
					  for I in 1..History_Max-1 loop
					     Command_Line_History(I) := Command_Line_History(I + 1);
					  end loop;
					  Command_Line_History(History_Max) := new Wide_String ' (Line.all);
				       end if;
				       Command_Line_Index := 0;                                 
				       
				       if Errno = 0 then
					  Free(Line);
					  Line := new Wide_String ' ("");
				       end if;
				       
				    end if;
				 end;
				 Matrix_Saver.Start;
			      when Wide_Character'Val(12) =>
				 Free(line);                        
				 Line := new Wide_String ' ("");
			      when Wide_Character'Val(20) =>
				 
				 Mode_Info_Status(W1, Adamanborg_Call);
				 Run_Gtk(W4, Shell_Interface, Errno);
				 My_Ansi_Consoles.Clear_screen;                           
				 Mode_Info_Status(W1, Null_Item);
				 
				 Main_Info_Status(W4);
				 
				 Current_Mode := Null_Item;
			      when others =>
				 if Is_Control(To_Character(Char)) then
				    null;
				 else
				    case Current_Mode is
				       when SelfProgrammingProcess |
					 PlansAdministration |
					 AiManagment |
					 DataTechnologie =>
					  if Line /= null then
					     if Line'Length < (columns-10)*2 then
						Buffer := new Wide_String ' (Line.all & Char);
						Free(Line);
						Line := new Wide_String ' (Buffer.all);
						Free(Buffer);                             
					     end if;
					  else
					     Line := new Wide_String ' ("" & char);
					  end if;
				       when others =>
					  if Line /= null then
					     if Line'Length < (columns-10)*(Command_Max_Lines-4) then
						Buffer := new Wide_String ' (Line.all & Char);
						Free(Line);
						Line := new Wide_String ' (Buffer.all);
						Free(Buffer);                             
					     end if;
					  else
					     Line := new Wide_String ' ("" & char);
					  end if;
				    end case;
				 end if;
			   end case;            
			end Receive;    
			
			Mode_Initialization(W14, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
			
			My_Ansi_Consoles.Draw_Window (W13);		     
			
			case Current_Mode is
			   when Null_Item =>
			      Main_Info_Status(W4);
			   when AllManuals =>
			      Mode_Info_Status(W1, Current_Mode);
			      Man_Info(W4);
			      Main_Quit_Info_Status(W3, On_Esc);                        
			   when others =>
			      null;
			end case;
			
		  or
		     accept Mode (Command : out Command_Type) do
			Command := Current_Mode;
		     end Mode;
		     
		  or
		     accept Reset;
		     
		     case Current_Mode is
			when Print =>
			   Current_Mode := Previsious_mode;
			   Previsious_Mode := Null_Item;
			when Shell_Print =>
			   Current_Mode := Previsious_Mode;
			   Previsious_Mode := Null_Item;
			when Search =>
			   Web_Search.Suspend;
			   Current_Mode := Previsious_Mode;
			   Previsious_Mode := Null_Item;
			when Builtin =>
			   Current_Mode := Previsious_Mode;
			   Previsious_Mode := Null_Item;
			   
			   
			when AiManagment | 
			  PlansAdministration | SelfProgrammingProcess |
			  DataTechnologie =>
			   Previsious_Mode := Null_Item;
			   Current_Mode := Null_Item;		      
			   
			when others =>			
			   Previsious_Mode := Null_Item;
			   Current_Mode := Null_Item;
			   
		     end case;
		     On_Esc := False;
		     My_Ansi_Consoles.Clear_Screen;
		     End_Of_This_Task := False;
		     
		     case Current_Mode is
			when Null_Item  =>
			   
			   
			   Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
			   Main_Info_Status(W4);
			when EnvironmentParameters =>
			   Mode_Info_Status(W1, Current_Mode);
			   
			   Main_Quit_Info_Status(W3, On_Esc);
			   
			when SelfProgrammingProcess |
			  PlansAdministration |
			  AiManagment |
			  DataTechnologie =>
			   
			   Mode_Initialization(W14, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
			   My_Ansi_Consoles.Draw_Window (W13);
			   
			when AllManuals =>
			   
			   Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
			   Man_Info(W4);
			   
			when GnuLinuxinterface =>						
			   
			   Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
			   Main_Info_Status(W4);
			   
			when others =>
			   Main_Quit_Info_Status(W3, On_Esc);
		     end case;                  
		     
		     
		  or
		     when Current_Mode = Chess =>
			accept Switch (Command : in Command_Type);
		  or
		     when Current_Mode = Search =>
			accept Switch (Command : in Command_Type);
			
		  or
		     
		     when Current_Mode not in Chess | Search =>
			accept Switch (Command : in Command_Type) do
			   Previsious_Mode := Null_Item;
			   Current_Mode := Command;
			end Switch; 
			My_Ansi_Consoles.Clear_Screen;
			

			
			case Current_Mode is
			   when Adamanborg_Call =>
			      Mode_Info_Status(W1, Adamanborg_Call);
			      Run_Gtk(W4, Shell_Interface, Errno);
			      My_Ansi_Consoles.Clear_screen;
			      Current_Mode := Previsious_Mode;
			      Previsious_Mode := Null_Item;                
			      End_Of_This_Task := False;                    
			   when Quit =>
			      My_Ansi_Consoles.Clear_screen;
			      Mode_Info_Status(W1, Null_Item);
			      Main_Quit_Info_Status(W3, On_Esc);
			      Quit_Info_Status(W4);
			      if End_Of_This_Task then
				 My_Ansi_Consoles.Clear_screen;
				 Main_Quit(W4);
				 accept Halt;
				 exit;
			      end if;
			      End_Of_This_Task := True;
			   when Null_Item =>                                          
			      End_Of_This_Task := False;
			      
			   when EnvironmentParameters =>
			      select
				 Shells.Adam_Shell.Respond(Current_Mode, "");
			      or 
				 delay 0.1;
				 My_Ansi_Consoles.Draw_Window (W2);
				 My_Ansi_Consoles.Draw_Centered (W2, 3, Ansi_Console.White, "Shell built-in...");
			      end select;
			      select
				 Shells.Adam_Shell.Response(Adamanborg_Shell_Response);			   
				 Shell_Info(W12, Current_Mode, Shell_Interface, errno);			   
				 Previsious_Mode := Current_Mode;
				 Current_Mode := Print;			   
				 File_Index := 0;
				 Line_Index := 0;
			      or 
				 delay 0.1;			   
				 
				 My_Ansi_Consoles.Draw_Window (W2);
				 My_Ansi_Consoles.Draw_Centered (W2, 3, Ansi_Console.White, "Shell response not available...");
				 
			      end select;
			      Command_Info_Status(W11, Shell_Interface);
			   when SelfProgrammingProcess |
			     PlansAdministration |
			     
			     DataTechnologie =>
			      
			      
			      End_Of_This_Task := False;                     
			   when Aimanagment =>
			      Current_Mode := AiManagment_Print;
			      Previsious_Mode := AiManagment;
			   when others =>
			      End_Of_This_Task := False;                     
			end case;
			
			case Current_Mode is
			   when Null_Item =>
			      Mode_Initialization(W2, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
			      Main_Info_Status(W4);
			   when AllManuals =>
			      
			      
			      Man_Info(W4);
			      
			      
			      Main_Quit_Info_Status(W3, On_Esc);
			      Mode_Info_Status(W1, Current_Mode);
			      ----------------------------------------------
			      -- Command Line manager :
			      
			      My_Ansi_Consoles.Draw_Window (W2);
			      My_Ansi_Consoles.Draw_Centered (W2, 1, Ansi_Console.White, "Enter your text or command here (Ctrl+L to clear line).");
			      
			      
			   when EnvironmentParameters =>
			      
			      Mode_Info_Status(W1, Current_Mode);
			      Main_Quit_Info_Status(W3, On_Esc);
			      Main_Info_Status(W4);
			      
			   when DataTechnologie |			  
			     SelfProgrammingProcess |
			     PlansAdministration =>
			      
			      
			      Mode_Initialization(W14, Current_Mode, On_Esc, Message => "Enter your text or command here (Ctrl+L to clear line).");
			      My_Ansi_Consoles.Draw_Window (W13);
			      Shell_Info(W13, Current_Mode, Shell_Interface, errno);
			      
			      
			   when Builtin =>
			      null;
			      
			   when Gnulinuxinterface =>
			      Mode_Info_Status(W1, Current_mode);
			      Main_Quit_Info_Status(W3, On_Esc);
			      Mode_Info_Status(W1, Current_Mode);
			      ----------------------------------------------
			      -- Command Line manager :
			      
			      My_Ansi_Consoles.Draw_Window (W2);
			      My_Ansi_Consoles.Draw_Centered (W2, 1, Ansi_Console.White, "Enter your text or command here (Ctrl+L to clear line).");
			      
			      
			   when AiManagment =>
			      null;
			      
			   when others =>
			      Mode_Info_Status(W1, Current_mode);
			      Main_Quit_Info_Status(W3, On_Esc);
			      
			      
			      
			end case;
			
			
		  or 
		     
		     					 
		     accept Alarm_Elapsed do
			Alarm_On := True;
		     end Alarm_Elapsed;
		     
		     On_Alarm(W8, "Date UTC " & 
				Formatting.Image
				(Date, False)
				-- Time_Zones.UTC_Time_Offset(Date))
				& ";  !! Alarm Elapsed !!");
		     if not Quiet then                     
			Text_Io.Put(Wide_Character'Val(7));
		     end if;         
		     
		  or
		     accept Lock do
			Locked := True;
		     end Lock;
		  or
		     accept Unlock do
			Locked := False;
		     end Unlock;

		  or
		     accept Timer_Switch do
			if Timer_Started then
			   Timer_Started := False;
			   Timer_Stop := Date;                  
			   Adam_Timer.Timer_Stop;      
			   Shared_Timer.Is_Set := False;
			else
			   Timer_Started := True;
			   Timer_Start := Clock;
			   Split(Timer_Start,
				 Shared_Timer.Start_Date.Year,
				 Shared_Timer.Start_Date.Month,
				 Shared_Timer.Start_Date.Day,
				 Duration(Shared_Timer.Start_Date.Hours));
			   Shared_Timer.Is_Set := True;
			   Adam_Timer.Timer_Start(Timer_Start);
			   
			end if;
		     end Timer_Switch;

		     
		  or
		     accept Set_On_Esc(Is_Escape : in Boolean) do            
			On_Esc := Is_Escape;
		     end Set_On_Esc;

		     case Current_Mode is
			when Quit =>
			   My_Ansi_Consoles.Clear_Screen;			
			   Mode_Info_Status(W1, Current_Mode);
			   Quit_Info_Status(W4);
			   Main_Quit_Info_Status(W3, On_Esc);
			when Print =>
			   Main_Quit_Info_Status(W3, On_Esc);
			when Shell_Print =>
			   Read_Quit_Info_Status(W3, On_Esc);			
			when Environmentparameters =>
			   Main_Quit_Info_Status(W3, On_Esc);
			when others =>
			   Main_Quit_Info_Status(W3, On_Esc);
		     end case;
		     
		  or 
		     delay 0.02;
		     select
			----------------------------------------------------
		     -- Times Managment : 
		     ----------------------------------------------------                       
		     
		     when (not Locked) =>
			accept Date_Refresh (Date : in Time) do
			   Adam_Console.Date := Date;
			end Date_Refresh;           
			
			if Alarm_Is_set and (not Alarm_On) then

			   Date_And_Alarm_Info_Status(W8, "Date UTC " & 
							Formatting.Image
							(Date, False)
							-- Time_Zones.UTC_Time_Offset(Date)) 
							& "; Alarm remaining : " &
							Integer_Image(Alarm_Years) & "y, " &
							Integer_Image(Alarm_Months) & "m, " &
							Integer_Image(Alarm_Days) & "d, " &
							Formatting.Image(Alarm_Time_Remaining));
			   
			elsif (not Alarm_On) then
			   Date_And_Alarm_Info_Status(W8, "Date UTC " & 
							Formatting.Image
							(Date, False) 
							-- Time_Zones.UTC_Time_Offset(Date)) 
							& "; Alarm off");
			   
			else
			   On_Alarm(W8, "Date UTC " & 
				      Formatting.Image
				      (Date, False)
				      -- Time_Zones.UTC_Time_Offset(Date))
				      & ";  !! Alarm Elapsed !!");
			end if;
			
		  or
		     when (not Locked) =>
			accept Timer_Refresh (Years         : in     Years_Count;
					      Months        : in     Months_Count;
					      Days          : in     Days_Count;
					      Houres        : in     Ada.Calendar.Day_Duration) do
			   Timer_Years := Years;
			   Timer_Months := Months;
			   Timer_Days := Days;
			   Timer_Houres := Houres;
			   
			   
			   
			end Timer_Refresh;
			
			if Timer_Started then
			   Timer_Info_Status(W9, "Timer UTC " & 
                                               Formatting.Image
                                               (Timer_Start, False)
                                               -- Time_Zones.UTC_Time_Offset(Timer_start))
                                               & ", Elaps: " &  
                                               Integer_Image(Timer_Years) & "y, " &
                                               Integer_Image(Timer_Months) & "m, " &
                                               Integer_Image(Timer_Days) & "d, " &
                                               Formatting.Image(Timer_Houres, True) & "s.");
                        else
                           Timer_Info_Status(W9, "Timer UTC " & 
                                               Formatting.Image
                                               (Date, False) 
                                               --Time_Zones.UTC_Time_Offset(Timer_start)) 
                                               & ", Elaps: " &  
                                               Integer_Image(Timer_Years) & "y, " &
                                               Integer_Image(Timer_Months) & "m, " &
                                               Integer_Image(Timer_Days) & "d, " &
                                               Formatting.Image(Timer_Houres, True) & "s.");
                        end if;
                        
			
		  or
		     when (not Locked) => 
			accept Alarm_Refresh (Start           :  in     Time;
					      Years           :  in     Natural;
					      Months          :  in     Natural;
					      Days            :  in     Natural;
					      Remaining       :  in     Ada.Calendar.Day_Duration;                                           
					      Stop            :  in     Time) do
			   
			   Alarm_Time_Remaining := Remaining;
			   Alarm_Years    := Years;
			   Alarm_Months   := Months;
			   Alarm_Days     := Days;
			   Alarm_Time_Stop := Stop;
			end Alarm_Refresh;
			
			if Alarm_Is_Set and Alarm_On then
			   On_Alarm(W8, "Date UTC " & 
				      Formatting.Image
				      (Date, False)
				      -- Time_Zones.UTC_Time_Offset(Date))
				      & ";  !! Alarm Elapsed !!");                                                
			   
			else 
			   if Alarm_Is_Set then
			      
			      Date_And_Alarm_Info_Status(W8, "Date UTC " & 
							   Formatting.Image
							   (Date, False)
							   -- Time_Zones.UTC_Time_Offset(Date))
							   & "; Alarm remaining : " &
							   Integer_Image(Alarm_Years) & "y, " &
							   Integer_Image(Alarm_Months) & "m, " &
							   Integer_Image(Alarm_Days) & "d, " &
							   Formatting.Image(Alarm_Time_Remaining));
			      
			   else
			      Date_And_Alarm_Info_Status(W8, "Date UTC " & 
							   Formatting.Image
							   (Date, False)
							   -- Time_Zones.UTC_Time_Offset(Date))
							   & "; Alarm off");
			   end if;
			end if;
                        
		     or
			delay 0.01;
		     end select;
		  end select;
		  if not Locked then                  
		     case Current_Mode is
			when Plans_Print =>
			   
			   Shell_Interface.Zbank.New_Solde := Position ( Shell_Interface.Zbank.Account ); 
			   
			   Text_Io.Put_Line(
				       To_Wide_String(PragmARC.Ansi_Tty_Control.Position(W13.L + 1, 3)) & "   New total : " &
					 To_Wide_String(Float'Image ( Shell_Interface.Zbank.New_Solde) ));
			   New_Line;
			   Line_Count := Command_Max_lines;
			   if Shell_Interface.Zbank.Operation_Set /= null then
			      for I in reverse Shell_Interface.Zbank.Operation_Set'First .. Shell_Interface.Zbank.Operation_Set'Last - Line_Index Loop
				 if Shell_Interface.Zbank.Operation_Set(I) /= null then
				    Print_Operation(Shell_Interface.Zbank.Operation_Set(I).all);
				    Line_Count := Line_Count - 1;
				    exit when Line_Count = 0;
				 end if;
			      end loop;
			   end if;
			   
			   Current_Mode := Previsious_Mode;
			   Previsious_Mode := Plansadministration;
			when Computation =>			   
			   begin
			      
			      Line_Count := 3;
			      
			      if Shell_Interface.Search_Result.File_Content /= null then

			     Computation_Loop:
				 for I in File_Index..Positive'min((File_Index-1)+((Computation_Max_Lines-3)), 
								   Shell_Interface.Search_Result.File_Content'Length) loop

				    declare
				       tmp : constant Wide_String := (-Shell_Interface.Search_Result.File_Content(I));
				       Line : constant Wide_String := Tmp(Tmp'First..Wide_Fixed.Index_Non_Blank((Tmp), Backward));
				       
				       Chars_Max : constant Positive := Term_Width-5;
				       Lines_Max : constant Positive := (Computation_Max_Lines-2);
				    begin

				       if Real_Length(Line) > 0 and Real_Length(Line) < (Chars_Max * Lines_Max) then				  

					  for Line_Window in Line_Index..Integer'min(Real_Length(Line)/(Chars_Max+1), Lines_Max) loop
					     
					     declare
						B_Inf : constant Positive := Line_Window*Chars_Max + 1;
						B_Sup : constant Positive := Integer'min((Line_Window + 1)*Chars_Max, Real_Length(Line));
						
						subtype Range_Type is Positive range B_Inf..B_Sup;
						
					     begin
						if (Real_length(Line) <= Chars_Max) then
						   
						   
						   My_Ansi_Consoles.Draw (W15, Line_Count + 1, 2, Ansi_Console.White, (Line));
						   Move_Cursor_To(W15, Line_Count + 1, ((Computing_Col + 2) mod (Chars_Max + 3)));
						   
						   ----------------------------------------------
						   --                                          --
						   -- Highlight the previsious character       --
						   -- of current position.                     --
						   if File_Index = I then
						      if Computing_Col in Range_type then
							 
							 Ada.Text_Io.Put(PragmARC.Ansi_Tty_Control.Position(Line_Count + W15.L + 1,
													    ((Computing_Col) mod (Chars_Max+1))+3));
							 Text_Io.Put((Wide_Character'Val(27) & "[32m"));
							 Text_Io.Put((Line(Computing_Col)));
							 Text_Io.Put((Wide_Character'Val(27) & "[37m"));
							 
						      end if;						   
						   end if;
						   
						else
						   
						   My_Ansi_Consoles.Draw 
						     (W15, 
						      Line_Window+3+(Line_Count-(3+Line_Window))+1 ,
						      2, 
						      Ansi_Console.White, 
						      (Line(B_Inf..B_sup))
						     );		
						   
						   ----------------------------------------------
						   --                                          --
						   -- Highlight the previsious character       --
						   -- of current position.                     --
						   if File_Index = I then
						      
						      if Computing_Col in Range_type then
							 Ada.Text_Io.Put(PragmARC.Ansi_Tty_control.Position(Line_Count + W15.L + 1,
													    ((Computing_Col - 1) mod (Chars_Max))+4));
							 Text_Io.Put((Wide_Character'Val(27) & "[31m"));
							 Text_Io.Put((Line(Computing_Col)));
							 Text_Io.Put((Wide_Character'Val(27) & "[37m"));
						      end if;
						      
						   end if;						   
						   
						end if;						
					     end;
					     Move_Cursor_To(W15, 3+(Computing_Col)/(Chars_Max)+1 , ((Computing_Col) mod (Chars_Max))+2);
					     Line_Count := Line_Count + 1;
					     exit Computation_Loop When not (Line_Count < (Computation_Max_Lines - 4));
					     
					  end loop;
				       else

					  Line_Count := Line_Count + 1;
					  exit Computation_Loop when not (Line_Count < (Computation_Max_Lines - 4));
					  
				       end if;                           
				    end;				    
				    exit Computation_Loop when not (Line_Count < (Computation_Max_Lines - 4));				    

				 end loop Computation_Loop;
			      end if;
			      
			   exception
			      
			      when others =>
				 null;
				 
			   end;
			   

			when Plansadministration =>    
			   			   Line_Count := 0;
			   if Line /= null then
			      declare
				 
				 Command_Line : constant Wide_String := Line.all;
				 Chars_Max : constant Positive := Term_Width-7;
				 Lines_Max : constant Positive := 4;
				 Local_Line_Count : Natural := 0;
			      begin
				 
				 if Real_Length(Command_Line) > 0 and Real_Length(Command_Line) < (Chars_Max * Lines_Max) then
				    for Line_Window in 0..Integer'min(Real_Length(Command_Line)/(Chars_Max+1), Lines_Max) loop
				       
				       declare
					  B_Inf : constant Positive := Line_Window*Chars_Max + 1;
					  B_Sup : constant Positive := Integer'min((Line_Window+1)*Chars_max, Command_Line'last);
				       begin
					  
					  if Command_Line'last <= Chars_Max then
					     My_Ansi_Consoles.Draw (W14, Line_window + 3, 3, Ansi_Console.White, "# " & (Command_Line));
					     Move_Cursor_To(W14, Line_Window+3, Command_Line'Last+5);
					  elsif Line_Window = 0 then
					     
					     My_Ansi_Consoles.Draw 
					       (W14, 
						Line_Window + 3, 
						3, 
						Ansi_Console.White, 
						"# " & (Command_Line(B_inf..B_sup))
					       );
					     Move_Cursor_To(W14, Line_Window+3, B_Sup+5);                                          
					     Local_Line_Count := Local_Line_Count + 1;
					  else
					     My_Ansi_Consoles.Draw 
					       (W14, 
						Line_Window + 3, 
						3, 
						Ansi_Console.White, 
						(Command_Line(B_inf..B_sup))
					       );
					     Move_Cursor_To(W14, Line_Window+3, (B_Sup-B_Inf)+4);
					     Local_Line_Count := Local_Line_Count + 1;
					  end if;                                       
				       end;
				       
				       exit when Local_Line_Count > (Lines_max-1);
				       
				    end loop;   
				 else
				    My_Ansi_Consoles.Draw (W14, 3, 3, Ansi_Console.White, "# ");
				    Move_Cursor_To(W14, 3, 5);
				 end if;                              
			      end;                        
			   else
			      My_Ansi_Consoles.Draw (W14, 3, 3, Ansi_Console.White, "# ");
			      Move_Cursor_To(W14, 3, 5);
			   end if;			   
			   

			when Datatechnologie |
			  Selfprogrammingprocess =>
			  
			   
			   
			   Line_Count := 0;
			   if Line /= null then
			      declare
				 
				 Command_Line : constant Wide_String := Line.all;
				 Chars_Max : constant Positive := Term_Width-7;
				 Lines_Max : constant Positive := 4;
				 Local_Line_Count : Natural := 0;
			      begin
				 
				 if Real_Length(Command_Line) > 0 and Real_Length(Command_Line) < (Chars_Max * Lines_Max) then
				    for Line_Window in 0..Integer'min(Real_Length(Command_Line)/(Chars_Max+1), Lines_Max) loop
				       
				       declare
					  B_Inf : constant Positive := Line_Window*Chars_Max + 1;
					  B_Sup : constant Positive := Integer'min((Line_Window+1)*Chars_max, Command_Line'last);
				       begin
					  
					  if Command_Line'last <= Chars_Max then
					     My_Ansi_Consoles.Draw (W14, Line_window + 3, 3, Ansi_Console.White, "# " & (Command_Line));
					     Move_Cursor_To(W14, Line_Window+3, Command_Line'Last+5);
					  elsif Line_Window = 0 then
					     
					     My_Ansi_Consoles.Draw 
					       (W14, 
						Line_Window + 3, 
						3, 
						Ansi_Console.White, 
						"# " & (Command_Line(B_inf..B_sup))
					       );
					     Move_Cursor_To(W14, Line_Window+3, B_Sup+5);                                          
					     Local_Line_Count := Local_Line_Count + 1;
					  else
					     My_Ansi_Consoles.Draw 
					       (W14, 
						Line_Window + 3, 
						3, 
						Ansi_Console.White, 
						(Command_Line(B_inf..B_sup))
					       );
					     Move_Cursor_To(W14, Line_Window+3, (B_Sup-B_Inf)+4);
					     Local_Line_Count := Local_Line_Count + 1;
					  end if;                                       
				       end;
				       
				       exit when Local_Line_Count > (Lines_max-1);
				       
				    end loop;   
				 else
				    My_Ansi_Consoles.Draw (W14, 3, 3, Ansi_Console.White, "# ");
				    Move_Cursor_To(W14, 3, 5);
				 end if;                              
			      end;                        
			   else
			      My_Ansi_Consoles.Draw (W14, 3, 3, Ansi_Console.White, "# ");
			      Move_Cursor_To(W14, 3, 5);
			   end if;			   
			   
			   
			   --  Previsious_Mode := Current_Mode;
			   --  Current_Mode := Shell_Print;
			   --  File_Index := 0;
			   --  Line_Index := 0;
			when others =>
			   null;
		     end case;
		     -- Input and output section.
		     case Current_Mode is
			when Quit =>
			   null;
			when Print =>
			   
			   Line_Count := 0;
			   if Shell_Interface.Spawn_Result.File_Content /= null then
			  Print_Loop:
			      for I in File_Index+1..Positive'min(File_Index+((Result_Max_Lines-2)), 
								  Shell_Interface.Spawn_Result.File_Content'Length) loop
				 declare
				    tmp : constant Wide_String := 
				      Ada.Strings.UTF_Encoding.Wide_Strings.encode(-Shell_Interface.Spawn_Result.File_Content(I));
				    Line : constant Wide_String := Tmp(Tmp'First..Wide_Fixed.Index_Non_Blank((Tmp), Backward));
				    
				    Chars_Max : constant Positive := Term_Width-4;
				    Lines_Max : constant Positive := (Result_Max_Lines-2);
				 begin
				    if Real_Length(Line) > 0 and Real_Length(Line) < (Chars_Max * Lines_Max) then
				       for Line_Window in Line_Index..Integer'min(Real_Length(Line)/Chars_Max, Lines_Max) loop
					  
					  declare
					     B_Inf : constant Positive := Line_Window*Chars_Max + 1;
					     B_Sup : constant Positive := Integer'min((Line_Window + 1)*Chars_Max, Real_Length(Line));
					  begin
					     if Real_length(Line) < Chars_max then
						
						My_Ansi_Consoles.Draw (W10, Line_Count + 1, 2, Ansi_Console.White, (Line));
						
					     else
																		
						My_Ansi_Consoles.Draw 
						  (W10, 
						   Line_count + 1,
						   2, 
						   Ansi_Console.White, 
						   (Line(B_inf..B_sup))
						  );
						
					     end if;                 
					  end;
					  Line_Count := Line_Count + 1;
					  exit Print_Loop When Line_Count > (Result_Max_lines - 3);
				       end loop;
				    else
				       Line_Count := Line_Count + 1;
				    end if;                           
				 end;
				 exit Print_Loop when Line_Count > (Result_Max_Lines - 3);
			      end loop Print_Loop;
			   end if;
			   Move_Cursor_To(W10, 1, 2);
			when Adamanborg_Call =>
			   null;
			when Search =>
			   
			   Web_Search.Suspend;
			   Mode_Info_Status(W1, Null_Item);
			   Main_Quit_Info_Status(W3, On_Esc);
			   Search_Result_Info(W7, Shell_Interface, errno);			      
			   
			   
			   declare
			      Pattern_Exp : constant Regexp.Regexp := Regexp.Compile
				(To_String(Shell_Interface.Search_Result.Pattern.all),
				 True, True);
			      
			   begin
			      
			      Line_Count := 0;
			      if Shell_Interface.Search_Result.File_Content /= null then
			     Search_Loop:
				 for I in File_Index+1..Positive'min(File_Index+((Result_Max_Lines-2)), 
								     Shell_Interface.Search_Result.File_Content'Length) loop
				    declare
				       tmp : constant Wide_String := 
					 Ada.Strings.UTF_Encoding.Wide_Strings.Decode(-Shell_Interface.Search_Result.File_Content(I));
				       Line : constant Wide_String := Tmp(Tmp'First..Wide_Fixed.Index_Non_Blank((Tmp), Backward));
				       
				       Chars_Max : constant Positive := Term_Width-5;
				       Lines_Max : constant Positive := (Result_Max_Lines-3);
				    begin
				       if Real_Length(Line) > 0 and Real_Length(Line) < (Chars_Max * Lines_Max) then				  
					  
					  for Line_Window in Line_Index..Integer'min(Real_Length(Line)/(Chars_Max+1), Lines_Max) loop
					     
					     declare
						B_Inf : constant Positive := Line_Window*Chars_Max + 1;
						B_Sup : constant Positive := Integer'min((Line_Window + 1)*Chars_Max, Real_Length(Line));
					     begin
						if Real_length(Line) < Chars_max then
						   
						   if Regexp.Match
						     (To_String(Line), 
						      Pattern_Exp) then
						      
						      My_Ansi_Consoles.Draw (W10, Line_Count + 1, 2, Ansi_Console.Red, (Line));
						   else
						      My_Ansi_Consoles.Draw (W10, Line_Count + 1, 2, Ansi_Console.White, (Line));
						   end if;
						else
						   if Regexp.Match
						     (To_String(Line), 
						      Pattern_Exp) then
						      My_Ansi_Consoles.Draw 
							(W10, 
							 Line_count + 1,
							 2, 
							 Ansi_Console.Red, 
							 (Line(B_inf..B_sup))
							);
						   else
						      My_Ansi_Consoles.Draw 
							(W10, 
							 Line_count + 1,
							 2, 
							 Ansi_Console.White, 
							 (Line(B_inf..B_sup))
							);						      
						   end if;
						end if;                 
					     end;
					     Line_Count := Line_Count + 1;
					     exit Search_Loop When Line_Count > (Result_Max_lines - 3);                                          
					  end loop;
				       else
					  Line_Count := Line_Count + 1;
				       end if;                           
				    end;
				    exit Search_Loop when Line_Count > (Result_Max_Lines - 3);
				 end loop Search_Loop;
			      end if;
			   exception
			      
			      when others =>
				 null;
				 
			   end;
			   
			   Web_Search.Start;
			   
			when Null_Item | GnuLinuxInterface | AllManuals =>
			   
			   
			   Line_Count := 0;
			   if Line /= null then
			      declare
				 
				 Command_Line : constant Wide_String := Line.all;
				 Chars_Max : constant Positive := Term_Width-7;
				 Lines_Max : constant Positive := Command_Max_Lines-2;
				 Local_Line_Count : Natural := 0;
			      begin
				 
				 if Real_Length(Command_Line) > 0 and Real_Length(Command_Line) < (Chars_Max * Lines_Max) then
				    for Line_Window in 0..Integer'min(Real_Length(Command_line)/(Chars_Max + 1), Lines_Max) loop
				       
				       declare
					  
					  B_Inf : constant Positive := Line_Window*Chars_Max + 1;
					  B_Sup : constant Positive := Integer'min((Line_Window+1)*Chars_max, Command_Line'last);
				       begin
					  
					  if Command_Line'last < Chars_Max then
					     My_Ansi_Consoles.Draw (W2, Line_window + 3, 3, Ansi_Console.White, "# " & (Command_Line));
					     Move_Cursor_To(W2, Line_Window+3, Command_Line'Last+5);
					  elsif Line_Window = 0 then
					     
					     My_Ansi_Consoles.Draw 
					       (W2, 
						Line_Window + 3, 
						3, 
						Ansi_Console.White, 
						"# " & (Command_Line(B_inf..B_sup))
					       );
					     Move_Cursor_To(W2, Line_Window+3, B_Sup+5);                                          
					     Local_Line_Count := Local_Line_Count + 1;
					  else
					     My_Ansi_Consoles.Draw 
					       (W2, 
						Line_Window + 3, 
						3, 
						Ansi_Console.White, 
						(Command_Line(B_inf..B_sup))
					       );
					     Move_Cursor_To(W2, Line_Window+3, (B_Sup-B_Inf)+4);
					     Local_Line_Count := Local_Line_Count + 1;
					  end if;                                       
				       end;
				       
				       exit when Local_Line_Count > (Lines_max-1);
				       
				    end loop;
				 else
				    My_Ansi_Consoles.Draw (W2, 3, 3, Ansi_Console.White, "# ");
				    Move_Cursor_To(W2, 3, 5);
				 end if;                              
			      end;                        
			   else
			      My_Ansi_Consoles.Draw (W2, 3, 3, Ansi_Console.White, "# ");
			      Move_Cursor_To(W2, 3, 5);
			   end if;			   
			   
			when Alarm | Other =>
			   null;  
			when Shell_Print =>
			   
			   
			   declare
			      Pattern_Exp : constant Regexp.Regexp := Regexp.Compile
				(To_String(Shell_Interface.Search_Result.Pattern.all),
				 True, True);
			   begin
			      
			      Line_Count := 0;
			      if Shell_Interface.Search_Result.File_Content /= null then
				 begin shell_Loop:
				     
				     for I in File_Index+1..Positive'min(File_Index+((Result_Max_Lines-3)), 
									 Shell_Interface.Search_Result.File_Content'Length) loop
					declare
					   tmp : constant Wide_String := 
					     Ada.Strings.UTF_Encoding.Wide_Strings.Decode(-Shell_Interface.Search_Result.File_Content(I));
					   Line : constant Wide_String := Tmp(Tmp'First..Wide_Fixed.Index_Non_Blank((Tmp), Backward));
					   
					   Chars_Max : constant Positive := Term_Width-5;
					   Lines_Max : constant Positive := (Result_Max_Lines-3);
					begin
					   if Real_Length(Line) > 0 and Real_Length(Line) < (Chars_Max * Lines_Max) then				  
					      
					      for Line_Window in Line_Index..Integer'min(Real_Length((Line))/Chars_Max, Lines_Max) loop
						 
						 declare
						    B_Inf : constant Positive := Line_Window*Chars_Max + 1;
						    B_Sup : constant Positive := Integer'min((Line_Window + 1)*Chars_Max, Real_Length((Line)));
						 begin
						    if Real_length((Line)) < Chars_max then
						       
						       if Regexp.Match(To_String(Line), 
								       Pattern_exp) then
							  
							  My_Ansi_Consoles.Draw (W13, Line_Count + 1, 2, Ansi_Console.Red, (Line));
						       else
							  My_Ansi_Consoles.Draw (W13, Line_Count + 1, 2, Ansi_Console.White, (Line));
						       end if;
						    else
						       if Regexp.Match(To_String(Line), 
								       Pattern_Exp) then
							  My_Ansi_Consoles.Draw 
							    (W13, 
							     Line_count + 1,
							     2, 
							     Ansi_Console.Red, 
							     (Line(B_inf..B_sup))
							    );
						       else
							  My_Ansi_Consoles.Draw 
							    (W13, 
							     Line_count + 1,
							     2, 
							     Ansi_Console.White, 
							     (Line(B_inf..B_sup))
							    );						      
						       end if;
						    end if;                 
						 end;
						 Line_Count := Line_Count + 1;
						 exit Shell_Loop When Line_Count > (Result_Max_lines - 3);                                          
					      end loop;
					   else
					      Line_Count := Line_Count + 1;
					   end if;                           
					end;
					exit Shell_Loop when Line_Count > (Result_Max_Lines - 3);
				     end loop Shell_Loop;			      
				 exception
				    
				    when others =>
				       null;
				       
				 end;
			      end if;
			   end;
			   Move_Cursor_To(W13, 1, 1);					  
			   
			   Current_Mode := Previsious_Mode;
			   Previsious_Mode := Null_Item;
			when Completion_Print =>
			   
			   
			   begin
			      
			      Line_Count := 4;
			      if Completion_Result.File_Content /= null then
				 begin Completion_Loop:
				     
				     for I in File_Index+1..Positive'min(File_Index+((Result_Max_Lines-3)), 
									 Completion_Result.File_Content'Length) loop
					declare
					   tmp : constant Wide_String := 
					     Ada.Strings.UTF_Encoding.Wide_Strings.Decode(-Completion_Result.File_Content(I));
					   Line : constant Wide_String := Tmp(Tmp'First..Wide_Fixed.Index_Non_Blank((Tmp), Backward));
					   
					   Chars_Max : constant Positive := Term_Width-5;
					   Lines_Max : constant Positive := (Result_Max_Lines-3);
					begin
					   if Real_Length(Line) > 0 and Real_Length(Line) < (Chars_Max * Lines_Max) then				  
					      
					      for Line_Window in Line_Index..Integer'min(Real_Length((Line))/Chars_Max, Lines_Max) loop
						 
						 declare
						    B_Inf : constant Positive := Line_Window*Chars_Max + 1;
						    B_Sup : constant Positive := Integer'min((Line_Window + 1)*Chars_Max, Real_Length((Line)));
						 begin
						    if Real_length((Line)) < Chars_max then
						       
						       
							  My_Ansi_Consoles.Draw (W13, Line_Count + 1, 2, Ansi_Console.White, (Line));
						       
						    else
						       
						       My_Ansi_Consoles.Draw 
							 (W13, 
							  Line_count + 1,
							  2, 
							  Ansi_Console.White, 
							  (Line(B_inf..B_sup))
							 );						      
						    end if;

						 end;
						 Line_Count := Line_Count + 1;
						 exit Completion_Loop When Line_Count > (Result_Max_lines - 3);                                          
					      end loop;
					   else
					      Line_Count := Line_Count + 1;
					   end if;                           
					end;
					exit Completion_Loop when Line_Count > (Result_Max_Lines - 3);
				     end loop Completion_Loop;			      
				 exception
				    
				    when others =>
				       null;
				       
				 end;
			      end if;
			   end;
			   
			   Current_Mode := Previsious_Mode;
			   Previsious_Mode := Null_Item;
			when Builtin =>
			   
			   Builtin_Info(W11, Sub_command, Shell_Interface, 
					To_Wide_String(Shell_Interface.Pattern.all), errno);			   
			   Mode_Info_Status(W1, Previsious_Mode);
			   Main_Quit_Info_Status(W3, On_Esc);                        
			   
			   
			   ---------------------------------------
			   -- Draw W10 to print builtin result. --
			   ---------------------------------------
			   --
			   
			   My_Ansi_Consoles.Draw_Window (W2);
			   ----------------------------------------
			   -- Printing Builtin pattern.
			   
			   
			   Line_Count := 0;
			   if Shell_Interface.Pattern /= null then
			      declare
				 
				 Command_Line : constant Wide_String := 
				   Ada.Strings.UTF_Encoding.Wide_Strings.Decode((Shell_Interface.Pattern.all));
				 Chars_Max : constant Positive := Term_Width-7;
				 Lines_Max : constant Positive := Result_Max_Lines-2;
				 Local_Line_Count : Natural := 0;
			      begin
				 
				 if Real_Length(Command_Line) > 0 and 
				   Real_Length(Command_Line) < (Chars_Max * Lines_Max) then
				    for Line_Window in 0..Integer'min(Real_Length(Command_Line)/(Chars_Max + 1), Lines_Max) loop
				       
				       declare
					  B_Inf : constant Positive := Line_Window*Chars_Max + 1;
					  B_Sup : constant Positive := Integer'min((Line_Window+1)*Chars_max, Command_Line'last);
				       begin
					  
					  if Command_Line'last <= Chars_Max then
					     My_Ansi_Consoles.Draw (W2, Line_window + 3, 3, Ansi_Console.White, (Command_Line));
					     Move_Cursor_To(W2, Line_Window+3, Command_Line'Last+5);
					  elsif Line_Window = 0 then
					     
					     My_Ansi_Consoles.Draw 
					       (W2, 
						Line_Window + 3, 
						3, 
						Ansi_Console.White, 
						"# " & (Command_Line(B_inf..B_sup))
					       );
					     Move_Cursor_To(W2, Line_Window+3, B_Sup+5);                                          
					     Local_Line_Count := Local_Line_Count + 1;
					  else
					     My_Ansi_Consoles.Draw 
					       (W2, 
						Line_Window + 3, 
						3, 
						Ansi_Console.White, 
						(Command_Line(B_inf..B_Sup))
					       );
					     Move_Cursor_To(W2, Line_Window+3, (B_Sup-B_Inf)+4);
					     Local_Line_Count := Local_Line_Count + 1;
					  end if;                                       
				       end;
				       
				       exit when Local_Line_Count > (Lines_max-1);
				       
				    end loop;                                 
				 end if;                              
			      end;                        
			      
			   end if;			   
			   
			   
			   ----------------------------------------
			   -- This is the Shell mode sub section --
			   --
			when GnuShell =>
			   Command_Info_Status(W11, Shell_Interface);
			   
			   Line_Count := 0;
			   
			   
			   ----------------------------------------
			   -- Printing GnuShell Spawn buffer.
			   
			   
			   if Shell_Interface.Spawn_Result.File_Content /= null then

			  GnuShell_Loop:
			      for I in File_Index+1..Positive'min(File_Index+((Result_Max_Lines-2)), 
								  Shell_Interface.Spawn_Result.File_Content'Length) loop
				 declare
				    tmp : constant Wide_String := (-Shell_Interface.Spawn_Result.File_Content(I));
				    Line : constant Wide_String := Tmp(Tmp'First..Wide_Fixed.Index_Non_Blank((Tmp), Backward));
				    
				    Chars_Max : constant Positive := Term_Width-5;
				    Lines_Max : constant Positive := (Result_Max_Lines-2);
				 begin
				    if Real_Length(Line) > 0 and Real_Length(Line) < (Chars_Max * Lines_Max) then				  
				       
				       for Line_Window in Line_Index..Integer'min(Real_Length((Line))/Chars_Max, Lines_Max) loop
					  
					  declare
					     B_Inf : constant Positive := Line_Window*Chars_Max + 1;
					     B_Sup : constant Positive := Integer'min((Line_Window + 1)*Chars_Max, Real_Length((Line)));
					  begin
					     if Real_length((Line)) < Chars_max then
						
						
						
						
						My_Ansi_Consoles.Draw (W10, Line_Count + 1, 2, Ansi_Console.White, (Line));
						
					     else
						
						My_Ansi_Consoles.Draw 
						  (W10, 
						   Line_count + 1,
						   2, 
						   Ansi_Console.White, 
						   (Line(B_inf..B_sup))
						  );						      
						
					     end if;                 
					  end;
					  Line_Count := Line_Count + 1;
					  exit GnuShell_Loop When Line_Count > (Result_Max_lines - 6 - Integer'min(Real_Length(Line)/Chars_Max, Lines_Max));
				       end loop;
				    else
				       Line_Count := Line_Count + 1;
				    end if;                           
				    exit GnuShell_Loop when Line_Count > (Result_Max_lines - 6 - Integer'min(Real_Length(Line)/Chars_Max, Lines_Max));
				 end;
				 
			      end loop GnuShell_Loop;
			      
			   end if;
			   Move_Cursor_To(W10, 1, 2);

			   
			   -------------------------------------------
			   -- Printing the user command line.
			   --
			   
			   if Shell_Interface.Spawn_Result.File_Content /= null then
			      
			      GnuShell_Prompt_Line := Integer'Min (Line_Count + 1,
								   (Command_Max_Lines - 5))+1;
			   end if;
			   if Line /= null then
			      declare
				 
				 Command_Line : constant Wide_String := Line.all;                                 
				 Local_Line_Count : Natural := 0;
				 
				 Total_Lines_Of_Command : constant Natural := Real_Length(Command_Line)/Chars_Max;
				 
			      begin
				 
				 if Real_Length(Command_Line) > 0 then
				    for Line_Window in 0..Integer'min(Real_Length(Command_Line)/Chars_Max, Lines_Max) loop
				       
				       
				       if Local_Line_Count + (Local_Line_Count+Line_Window+2) >= (Command_Max_Lines - 4)  then
					  GnuShell_Prompt_Line := (Command_Max_Lines - Total_Lines_Of_Command) - (Local_Line_Count + 4);
				       end if;
				       

				       
				       declare
					  B_Inf : constant Positive := Line_Window*Chars_Max+1;
					  B_Sup : constant Positive := Integer'min((Line_Window+1)*Chars_max, Command_Line'last);
				       begin
					  
					  if Command_Line'last <= Chars_Max then					     
					     My_Ansi_Consoles.Draw (W2, GnuShell_Prompt_Line, 2, Ansi_Console.White, "# " & (Command_Line));
					     Move_Cursor_To(W2, GnuShell_Prompt_Line, Command_Line'Last+4);

					  elsif Line_Window = 0 then

					     My_Ansi_Consoles.Draw 
					       (W2, 
						GnuShell_Prompt_Line, 
						2, 
						Ansi_Console.White, 
						"# " & (Command_Line(B_inf..B_sup))
					       );
					     Move_Cursor_To(W2, GnuShell_Prompt_Line, B_Sup+4);                                          
					     Local_Line_Count := Local_Line_Count + 1;

					  else

					     My_Ansi_Consoles.Draw 
					       (W2, 
						GnuShell_Prompt_Line + (Line_Window) + 1 + (Local_Line_Count - 1),
						2, 
						Ansi_Console.White, 
						(Command_Line(B_inf..B_sup))
					       );
					     Move_Cursor_To(W2, GnuShell_Prompt_Line + (Line_Window) + 1 + (Local_Line_Count -1), (B_Sup-B_Inf)+3);
					     Local_Line_Count := Local_Line_Count + 1;

					  end if;                                       
				       end;
				       
				       exit when Local_Line_Count > (Lines_Max-1);
				       
				    end loop;
				 else

				    My_Ansi_Consoles.Draw (W2, GnuShell_Prompt_Line, 2, Ansi_Console.White, "# ");
				    Move_Cursor_To(W2, GnuShell_Prompt_Line, 4);

				 end if;                              
			      end;                        
			   else

			      My_Ansi_Consoles.Draw (W2, GnuShell_Prompt_Line, 2, Ansi_Console.White, "# ");
			      Move_Cursor_To(W2, GnuShell_Prompt_Line, 4);

			   end if;			   
			   
			when Aimanagment_Print =>
			   Errno := System("clear" & Ascii.Nul);			   
			   
			   Wide_Fixed.Move(Border_Line, Empty_Line, Strings.Error, left);
			   Wide_Fixed.Replace_Slice(Empty_Line, (Chars_Max/2)-22, (Chars_Max/2)+21, "-- Adamanborg is an cybernetic organism.  --", Strings.Error, Center);
			   Put_line(Empty_Line(Empty_Line'First..Wide_Fixed.Index_Non_Blank(Empty_Line, Backward)));
			   Wide_Fixed.Move(Border_Line, Empty_Line, Strings.Error, Left);			   
			   Wide_Fixed.Replace_Slice(Empty_Line, (Chars_Max/2)-22, (Chars_Max/2)+21, "-- Adamanborg (C) Copyright 2016 E. Sens. --", Strings.Error, Center);
			   Put_line(Empty_Line(Empty_Line'First..Wide_Fixed.Index_Non_Blank(Empty_Line, Backward)));
			   
			   Wide_Fixed.Move(Border_Line, Empty_Line, Strings.Error, Left);
			   Wide_Fixed.Replace_Slice(Empty_Line, 6, User_Name'Length+11, "User: " & User_Name.all, Strings.Error, Center);
			   Text_Io.Put_Line(Empty_Line(Empty_Line'First..Wide_Fixed.Index_Non_Blank(Empty_Line, Backward)));
			   Wide_Fixed.Move(Border_Line, Empty_Line, Strings.Error, Left);
			   
			   
			   
			   if Addresses (Get_Host_By_Name (Host_Name), 1) = Get_Address(Channel).addr then
			      
			      Wide_Fixed.Replace_Slice
				(Empty_Line, 6, Host_Addr'Length+25, "Host: " & To_Wide_String(Host_Addr) & " is localhost.", 
				 Strings.Error, Center);
			      
			   else
			      
			      Wide_Fixed.Replace_Slice
				(Empty_Line, 6, Host_Addr'Length+36, "Host: " & To_Wide_String(Host_Addr) & " is Internet remote host.", 
				 Strings.Error, Center);
			      
			   end if;

			   

			   Wide_Text_Io.Put_Line(Empty_Line(Empty_Line'First..Wide_Fixed.Index_Non_Blank(Empty_Line, Backward)));	    
			   
			   
			   Wide_Text_Io.Put_Line(Plain_Line);	    	    
			   
			   ----------------------------------------------------------------------------------------------
			   --                                    outputs print                                         --
			   Left_Lines := Ada.Wide_Text_Io.Count(Lines-23);
			   if Data_Buffer_Index > 0 then	       
			  Data :
			      for I in 1..Data_Buffer_Index loop
				 if Data_Buffer(I) /= null then
				    declare
				       Line : constant Wide_String := Data_Buffer(I).all;
				    begin
				       
				       if Real_Length(Line) > 0 and Real_Length(Line) < (Chars_Max * Natural(Lines_Max)) then
					  
					  for Line_Window in 0..Integer'min(Real_Length(Line)/Chars_Max, Natural(Lines_Max)) loop
					     
					     declare
						
						B_Inf : constant Positive := Line_Window*Chars_Max + 1;
						B_Sup : constant Positive := Integer'min((Line_Window + 1)*Chars_Max, Real_Length(Line));
					     begin
						
						if Real_Length(Line) > 0 and then Real_Length(Line) < Chars_max then
						   
						   Wide_Fixed.Move(Border_Line, Empty_Line, Strings.Error, left);
						   Wide_Fixed.Replace_Slice(Empty_Line, 5, 4+(Real_Length(Line)), Line, Strings.Error, Left);
						   Text_Io.Put_Line(Empty_Line(Empty_Line'First..Wide_Fixed.Index_Non_Blank(Empty_Line, Backward)));
						   Left_Lines := Left_Lines - 1;
						elsif Real_Length(Line) > 0 then
						   
						   Wide_Fixed.Move(Border_Line, Empty_Line, Strings.Error, left);
						   Wide_Fixed.Replace_Slice(Empty_Line, 5,  4+(B_Sup-(B_Inf-1)), Line(B_inf..B_sup), Strings.Error, Left);
						   Text_Io.Put_Line(Empty_Line(Empty_Line'First..Wide_Fixed.Index_Non_Blank(Empty_Line, Backward)));
						   Left_Lines := Left_Lines - 1;
						end if;
						
					     end;
					     exit Data when Left_Lines = 0;
					  end loop;		     			
				       end if;
				    end;		     
				 end if;
				 exit Data when Left_Lines = 0;
			      end loop Data;
			   end if;
			   for I in 1..Left_Lines loop
			      Wide_Fixed.Move(Border_Line, Empty_Line, Strings.Error, left);	       
			      Text_Io.Put_Line(Empty_Line(Empty_Line'First..Wide_Fixed.Index_Non_Blank(Empty_Line, Backward)));
			   end loop;
			   
			   
			   Wide_Text_Io.Put_Line(Plain_Line);
			   
			   ----------------------------------------------------------------------------------------------
			   --                                      environment print                                   --
			   Left_Lines := 5;
			   if Env /= null then
			      for Object_Id in Env.Elements'Range loop
				 
				 declare
				    Element : constant Variadic_Array_Access := Env.Elements(Object_Id);
				    Image   : Common.String_Access := new Wide_String ' ("");
				    Buffer  : Common.String_Access;
				 begin
				    if Element /= null then
				       for Attribut_Id in Element'Range loop

					  if Element(Attribut_Id) /= null and then
					    Element(Attribut_Id).Initialized then

					     Free(Buffer);
					     Buffer := new Wide_String ' (Image.all & ' ' & Element(Attribut_Id).To_Wide_String);

					     Free(Image);
					     Image := new Wide_String ' (Buffer.all);			
					  end if;
				       end loop;

				       Wide_Fixed.Move(Border_Line, Empty_Line, Strings.Error, left);
				       Wide_Fixed.Replace_Slice(Empty_Line, 5,  4+Image'length, Image.all, Strings.Error, Left);			   
				       
				       Text_Io.Put_Line(Empty_Line(Empty_Line'First..Wide_Fixed.Index_Non_Blank(Empty_Line, Backward)));

				       Left_Lines := Left_Lines - 1;
				    end if;
				 end;		  
			      end loop;	    
			   end if;
			   
			   for I in 1..Left_Lines loop
			      Wide_Fixed.Move(Border_Line, Empty_Line, Strings.Error, left);	       
			      Text_Io.Put_Line(Empty_Line(Empty_Line'First..Wide_Fixed.Index_Non_Blank(Empty_Line, Backward)));
			   end loop;
			   --
			   ----------------------------------------------------------------------------------------------
			   
			   Wide_Text_Io.Put_Line(Plain_Line);			   
			   ----------------------------------------------------------------------------------------------
			   --                                       inputs print                                       --
			   
			   Left_Lines := 2;
			   
			   Wide_Fixed.Move(Border_Line, Empty_Line, Strings.Error, Left);
			   Wide_Fixed.Replace_Slice(Empty_Line, (Chars_Max/2)-6, (Chars_Max/2)+5, "[Input Line]", Strings.Error, Center);
			   Text_Io.Put_Line(Empty_Line(Empty_Line'First..Wide_Fixed.Index_Non_Blank(Empty_Line, Backward)));
			   
			   declare
			      Line : constant Wide_String := Human_Line.all;
			      Lines_Max : constant Positive := 3;
			      Bot       : constant Positive := 60;
			   begin	        
			      if Real_Length(Line) > 0 and Real_Length(Line) < (Chars_Max * Lines_Max) then
				 for Line_Window in 0..Integer'min(Real_Length(Line)/Chars_Max, Lines_Max) loop
				    
				    declare
				       B_Inf : constant Positive := Line_Window*Chars_Max + 1;
				       B_Sup : constant Positive := Integer'min((Line_Window + 1)*Chars_Max, Real_Length(Line));
				    begin
				       if Real_Length(Line) < Chars_max then
					  Wide_Fixed.Move("", Empty_Line, Strings.Error, Left);
					  Wide_Fixed.Replace_Slice(Empty_Line, 5, 4+(Real_Length(Line)), Line, Strings.Error, Left);
					  Text_Io.Put_Line(Empty_Line(Empty_Line'First..Wide_Fixed.Index_Non_Blank(Empty_Line, Backward)));
				       else
					  Wide_Fixed.Move("", Empty_Line, Strings.Error, Left);
					  Wide_Fixed.Replace_Slice(Empty_Line, 5,  4+(B_Sup-(B_Inf-1)), Line(B_inf..B_sup), Strings.Error, Left);
					  Text_Io.Put_Line(Empty_Line(Empty_Line'First..Wide_Fixed.Index_Non_Blank(Empty_Line, Backward)));
					  
				       end if;
				       Left_Lines := Left_Lines - 1;
				    end;
				 end loop;
				 Ada.Text_Io.Put(Position((Bot+(2-Integer(Left_Lines))), ((Real_Length(Line) rem Chars_Max)+5)));
			      else		  
				 
				 Ada.Text_Io.Put(Position((Bot+(3-Integer(Left_Lines))), (Real_Length(Line)+5)));
			      end if;
			   end;
			   
			   Current_Mode := Aimanagment;			   
			   Previsious_Mode := Null_Item;
			when others =>
			   
			   
			   null;
			   
			   
			   
			   
		     end case;

		     
		  else
		     case Current_Mode is                                    
			when Quit =>
			   Quit_Info_Status(W4);
			when others =>
			   null;
		     end case;         
		  end if;

	       end;
	       
	    end loop;
	    
	    
	    
            abort Adam_Dater;
            abort Adam_Timer;
            abort Adam_Alarm;
	    
	    
	    if Web_Search /=  null then
	       select
		  Web_Search.Halt;
	       else
		  abort Web_Search.all;
	       end select;
	    end if;
	    
	    
	    
         end;
      end Adam_Console;
      
      
      
      End_Of_Program : Boolean := False;
      Mode : Command_Type := Null_Item;      
      
      -----------------------------------------------
      -- Accepted function Key from F1 to F8       --
      -----------------------------------------------
      -- F1,      "A.i. management";
      -- F2,      "Data technologies";
      -- F3,      "All manuals";
      -- F4,      "Gnu/Linux interface";
      -- F5,      "Environment parameters";      
      -- F6,      "Self-Programming process";
      -- F7,      "Plans administration";
      -- F8,      "Adamanborg call" (graphical mode);
      -- F9,       Start or Stop Timer; 
      -- F10,      Set or Unset Alarm;
      -- F11,      Stop Alarm;
      
      End_Of_Task : Boolean := False;
      
      
      Address  : Gnat.sockets.Sock_Addr_Type;
      Socket   : constant Socket_Access := new Socket_Type;
      Channel  : Gnat.sockets.Stream_Access;
      Logged   : Boolean := False;
      
   begin
      delay 2.0;
      Text_Io.Put_Line("Main init address");
      Address.Addr :=
	Gnat.Sockets.Addresses (Gnat.Sockets.Get_Host_By_Name (Host_Addr), 1);
      Text_Io.Put_Line("Main init port");
      Address.Port := 7851;
      Gnat.sockets.Create_Socket (Socket.all);
      delay 0.1;
      Text_Io.Put_Line("Socket created...");
      Gnat.Sockets.Set_Socket_Option
	(Socket.all,
	 Gnat.Sockets.Socket_Level,
	 (Gnat.Sockets.Reuse_Address, True));      
      delay 0.1;      
      Text_Io.Put_Line("Connect to server...");
      Gnat.sockets.Connect_Socket (Socket.all, Address);
      Text_Io.Put_Line("Connected to server !!!!");
      delay 0.1;
      Channel := Gnat.sockets.Stream (Socket.all);
      Text_Io.Put_Line("Channel initialized...");
      Wide_String'Output (Channel, User_Name.all);
      Text_Io.Put_Line("User name sended...");
      
      MD5.Message_Digest'Output (Channel, Human_Interface_Type
				   (Shell_Interface.Interfaces(Human_Class).all).Password.all);
      Text_Io.Put_Line("Passwd sended...");
      Logged := Boolean'Input(Channel);
      Text_Io.Put_Line("Logged received...");
      if Logged then
	 
	 Text_Io.Put_Line("Login accepted...");
	 declare
	    
	    
	 begin
	    

	    Ada.Text_Io.Put_Line("Strating console thread...");
	    declare
	       Console : Adam_Console(Channel);	    
	       	       
	    begin
	       
	       if not (Shell_Interface.all in Textual_Interface_Type) then
		  Console.Halt;
		  End_Of_Task := True;       
		  Errno := -1;      
	       else
		  Console.Reset;
		  -- Solution for bug of printing for first line.
	       end if;
	       

	       
	       if Gnat.Os_Lib.Getenv("DISPLAY").all = "" then
		  --Text_Io.Put_Line("-- Si l'interface n'est en mode graphic :");
		  while not End_Of_Task loop
		     
		     
		     
		     declare
			Char : Wide_Character;
			
		     begin
			Console.Mode(Mode);
			Text_Io.Get_Immediate(Char);
			Matrix_Saver.Suspend;
			case Char is
			   when Wide_Character'Val(27) =>                                       
			      Console.Set_On_Esc(True);
			      Text_Io.Get_Immediate(Char);         
			      case Char is
				 when Wide_Character'Val(27) =>                             
				    

				    case Mode is                                                            
				       when AiManagment .. Computation =>
					  Console.Reset;                                 
				       when Null_Item =>
					  Console.Lock;                                 
					  Console.Set_On_Esc(False);                                 
					  Console.Switch(Quit);                                 
					  End_Of_Program := True;
					  
				       when others =>
					  if End_Of_Program then         
					     
					     Console.Switch(Quit);
					     
					     exit;
					  end if;
				    end case;                          
				 when others =>
				    Console.Mode(Mode);
				    case Mode is
				       when Print | Search | Shell_Print =>
					  Console.Set_On_Esc(False);
					  End_Of_Program := False;

				       when Quit =>
					  if End_Of_Program then         
					     
					     Console.Switch(Quit);
					     
					     exit;
					  end if;
				       
				       when others =>

					  Console.Set_On_Esc(False);
					  Console.Switch(mode);
					  End_Of_Program := False;
				    end case;
			      end case;                     
			      
			      case Char is
				 when Wide_Character'Val(91) =>                           
				    Text_Io.Get_Immediate(Char);                           
				    Console.Set_On_Esc(False);                           
				    case Char is
				       when Wide_Character'Val(49) =>
					  Text_Io.Get_Immediate(Char);                
					  case Char is
					     when Wide_Character'Val(55) =>
						null;--  Text_Io.Put_Line(" -- F6");
						Console.Switch(SelfProgrammingProcess);
						Mode := SelfProgrammingProcess;
						Text_Io.Get_Immediate(Char);                  
					     when Wide_Character'Val(56) =>
						null;--  Text_Io.Put_Line(" -- F7");
						Console.Switch(PlansAdministration);
						Mode := PlansAdministration;
						Text_Io.Get_Immediate(Char);                  
					     when Wide_Character'Val(57) =>
						null;--  Text_Io.Put_Line(" -- F8");
						Console.Switch(Adamanborg_Call);
						Mode := PlansAdministration;
						Text_Io.Get_Immediate(Char);                  
					     when Wide_Character'Val(126) =>                     
						null;--  Text_Io.Put_Line(" -- begin");
					     when others =>
						null;
					  end case;                      
				       when Wide_Character'Val(50) =>                    
					  Text_Io.Get_Immediate(Char);
					  case Char is
					     when Wide_Character'Val(48) =>
						null;--  Text_Io.Put_Line(" -- F9");
						Console.Timer_Switch;
						Text_Io.Get_Immediate(Char);
					     when Wide_Character'Val(49) =>
						null;--  Text_Io.Put_Line(" -- F10");
						Console.Switch_Alarm;
						Text_Io.Get_Immediate(Char);                                       
					     when Wide_Character'Val(51) =>                                  
						null;--  Text_Io.Put_Line(" -- F11");
						Console.Stop_Alarm;
						Text_Io.Get_Immediate(Char);
					     when Wide_Character'Val(52) =>
						null;--  Text_Io.Put_Line(" -- F12");
						Text_Io.Get_Immediate(Char);
					     when Wide_Character'Val(53) =>                            
						null;--  Text_Io.Put_Line(" -- Maj+F1");
					     when Wide_Character'Val(54) =>                            
						null;--  Text_Io.Put_Line(" -- Maj+F2");
					     when Wide_Character'Val(56) =>                            
						null;--  Text_Io.Put_Line(" -- Maj+F3");
					     when Wide_Character'Val(57) =>
						null;--  Text_Io.Put_Line(" -- Maj+F4");
					     when Wide_Character'Val(126) =>
						null;--  Text_Io.Put_Line(" -- insert");                                
					     when others =>
						null;                             
					  end case;                               
				       when Wide_Character'Val(51) =>                    
					  null;--  Text_Io.Put_Line(" -- del");                     
					  Text_Io.Get_Immediate(Char);   
				       when Wide_Character'Val(52) =>                    
					  null;--  Text_Io.Put_Line(" -- end");                     
					  Text_Io.Get_Immediate(Char);   
				       when Wide_Character'Val(53) =>
					  null;--  Text_Io.Put_Line(" -- page up");
					  Console.Page_Up;
					  Text_Io.Get_Immediate(Char);   
				       when Wide_Character'Val(54) =>
					  null;--  Text_Io.Put_Line(" -- page down");
					  Console.Page_Down;
					  Text_Io.Get_Immediate(Char);   
				       when Wide_Character'Val(65) =>
					  null;--  Text_Io.Put_Line(" -- up");
					  Console.Up_Arrow;
				       when Wide_Character'Val(66) =>
					  null;--  Text_Io.Put_Line(" -- down");
					  Console.Down_Arrow;
				       when Wide_Character'Val(67) =>
					  null;--  Text_Io.Put_Line(" -- right");
					  Console.Right_Arrow;
				       when Wide_Character'Val(68) =>
					  null;--  Text_Io.Put_Line(" -- left");
					  Console.Left_Arrow;
				       when Wide_Character'Val(91) =>
					  Text_Io.Get_Immediate(Char);                
					  case Char is                               
					     when Wide_Character'Val(65) =>
						null;--  Text_Io.Put_Line(" -- F1");                                 
						Console.Switch(AiManagment);
						Mode := AiManagment;						
						Console.Receive(To_Wide_Character(Ascii.nul));
												
					     when Wide_Character'Val(66) =>
						null;--  Text_Io.Put_Line(" -- F2");
						Console.Switch(DataTechnologie);
						Mode := DataTechnologie;
					     when Wide_Character'Val(67) =>
						null;--  Text_Io.Put_Line(" -- F3");                                 
						Console.Switch(AllManuals);
						Mode := AllManuals;
					     when Wide_Character'Val(68) =>
						null;--  Text_Io.Put_Line(" -- F4");
						Console.Switch(GnuLinuxInterface);
						Mode := GnuLinuxInterface;
					     when Wide_Character'Val(69) =>
						null;--  Text_Io.Put_Line(" -- F5");
						Console.Switch(EnvironmentParameters);
						Mode := EnvironmentParameters;
					     when others =>
						null;
					  end case;
					  
				       when others =>
					  
					  Console.Reset;            
					  
					  End_Of_Program := False;
					  Console.Unlock;
					  Console.Receive(Char);
					  
				    end case;

				 when others =>
				    Console.Set_On_Esc(False);
				    Console.Unlock; 
			      end case;                                       
			      
			   when others =>                    
			      case Mode is
				 when Quit =>
				    Console.Switch(Null_Item);				 
				 when others =>
				    null;
			      end case;
			      
			      Console.Set_On_Esc(False);
			      
			      End_Of_Program := False;
			      
			      Console.Receive(Char);
			      
			end case;
			
		     exception
			
			-- A la saisie de Ctrl+D l'exception End_Error est levée.
			
			when Text_Io.End_Error =>
			   
			   -- On arrête la console.
			   Console.Lock;
			   
			   My_Ansi_Consoles.Clear_Screen;
			   
			   Mode_Info_Status(W1, Null_Item);
			   
			   My_Ansi_Consoles.Draw_Window (W4);
			   My_Ansi_Consoles.Draw_Centered (W4, 1, Ansi_Console.White, "End of program.");
			   My_Ansi_Consoles.Draw (W4, 3, 3, Ansi_Console.White, "Going to halt architecture...");
			   
			   Bell(Quiet);
			   
			   delay 2.5;
			   -- On arrête la console.
			   
			   My_Ansi_Consoles.Clear_screen;

			   
			   
			   Mode_Info_Status(W1, Null_Item);
			   
			   My_Ansi_Consoles.Draw_Window (W4);
			   My_Ansi_Consoles.Draw_Centered (W4, 2, Ansi_Console.White, "Je plaisante.");
			   Move_Cursor_To(W4, 3, 5);
			   Bell(Quiet);
			   delay 2.5;                   
			   Console.reset;
			   Console.Unlock;
		     end;
		     
		  end loop;
	       else
		  
		  -- Si l'interface est en mode graphic :
		  
		  while not End_Of_Task loop
		     
		     
		     
		     declare
			Char : Wide_Character;

		     begin
			Console.Mode(Mode);
			Text_Io.Get_Immediate(Char);
			Matrix_Saver.Suspend;
			case Char is
			   when Wide_Character'Val(27) =>                                       
			      Console.Set_On_Esc(True);
			      Text_Io.Get_Immediate(Char);         
			      case Char is
				 when Wide_Character'Val(27) =>				    

				    case Mode is                                                            
				       when AiManagment .. Computation =>
					  Console.Reset;                                 
				       when Null_Item =>
					  Console.Lock;                                 
					  Console.Set_On_Esc(False);                                 
					  Console.Switch(Quit);                                 
					  End_Of_Program := True;

				       when others =>
					  if End_Of_Program then         
					     
					     Console.Switch(Quit);

					     exit;
					  end if;
				    end case;                          
				 when others =>
				    Console.Mode(Mode);
				    case Mode is
				       when Print | Search | Shell_Print =>
					  Console.Set_On_Esc(False);
					  End_Of_Program := False;

				       when Quit =>
					  if End_Of_Program then         
					     
					     Console.Switch(Quit);
					     
					     exit;
					  end if;
					  
				       when others =>
					  Console.Set_On_Esc(False);
					  Console.Switch(mode);
					  End_Of_Program := False;
				    end case;
			      end case;                     
			      
			      case Char is
				 when Wide_Character'Val(79) =>                           
				    
				    Text_Io.Get_Immediate(Char);
				    Console.Set_On_Esc(False);
				    case Char is
				       when Wide_Character'Val(80) =>
					  null;--  Text_Io.Put_Line(" -- F1");                               
					  Console.Switch(AiManagment);
					  Mode := AiManagment;
					  Console.Receive(To_Wide_Character(Ascii.Nul));
				       when Wide_Character'Val(81) =>
					  null;--  Text_Io.Put_Line(" -- F2");
					  Console.Switch(DataTechnologie);
					  Mode := DataTechnologie;
				       when Wide_Character'Val(82) =>
					  null;--  Text_Io.Put_Line(" -- F3");                               
					  Console.Switch(AllManuals);
					  Mode := AllManuals;
				       when Wide_Character'Val(83) =>
					  null;--  Text_Io.Put_Line(" -- F4");
					  Console.Switch(GnuLinuxInterface);
					  Mode := GnuLinuxInterface;
				       when others =>
					  null;
				    end case;
				    
				 when Wide_Character'Val(91) =>

				    Console.Set_On_Esc(False);
				    Text_Io.Get_Immediate(Char);              
				    case Char is
				       when Wide_Character'Val(49) =>
					  Text_Io.Get_Immediate(Char);
					  case Char is
					     when Wide_Character'Val(53) =>
						null;--  Text_Io.Put_Line(" -- F5");                                                                    
						Console.Switch(EnvironmentParameters);
						Mode := EnvironmentParameters;

					     when Wide_Character'Val(55) =>
						null;--  Text_Io.Put_Line(" -- F6");
						Console.Switch(SelfProgrammingProcess);
						Mode := SelfProgrammingProcess;
					     when Wide_Character'Val(56) =>
						null;--  Text_Io.Put_Line(" -- F7");
						Console.Switch(PlansAdministration);
						Mode := PlansAdministration;
					     when Wide_Character'Val(57) =>
						null;--  Text_Io.Put_Line(" -- F8");
						Console.Switch(Adamanborg_Call);
						Mode := PlansAdministration;
						
					     when others =>
						null;
					  end case;
					  Text_Io.Get_Immediate(Char);
				       when Wide_Character'Val(50) =>
					  Text_Io.Get_Immediate(Char);
					  case Char is
					     when Wide_Character'Val(48) =>                                  
						null;--  Text_Io.Put_Line(" -- F9");
						Console.Timer_Switch;
						Text_Io.Get_Immediate(Char);
					     when Wide_Character'Val(49) =>
						null;--  Text_Io.Put_Line(" -- F10");
						Console.Switch_Alarm;
						Text_Io.Get_Immediate(Char);
					     when Wide_Character'Val(51) =>
						null;--  Text_Io.Put_Line(" -- F11");
						Console.Stop_Alarm;
						Text_Io.Get_Immediate(Char);
					     when Wide_Character'Val(52) =>
						null;Text_Io.Put_Line(" -- F12");
						Text_Io.Get_Immediate(Char);
					     when Wide_Character'Val(53) =>
						null;Text_Io.Put_Line(" -- Maj+F1");                                 
					     when Wide_Character'Val(54) =>                            
						null;Text_Io.Put_Line(" -- Maj+F2");
					     when Wide_Character'Val(56) =>                            
						null;Text_Io.Put_Line(" -- Maj+F3");
					     when Wide_Character'Val(57) =>
						null;Text_Io.Put_Line(" -- Maj+F4");
					     when Wide_Character'Val(126) =>
						null;--  Text_Io.Put_Line(" -- insert");
						
					     when others =>
						null;                             
					  end case;                               
					  
				       when Wide_Character'Val(51) =>                    
					  null;--  Text_Io.Put_Line(" -- del");                           
					  Text_Io.Get_Immediate(Char);                            
				       when Wide_Character'Val(53) =>
					  null;--  Text_Io.Put_Line(" -- page up");
					  Console.Page_Up;
					  Text_Io.Get_Immediate(Char);
				       when Wide_Character'Val(54) =>
					  null;--  Text_Io.Put_Line(" -- page down");
					  Console.Page_Down;
					  Text_Io.Get_Immediate(Char);
				       when Wide_Character'Val(65) =>
					  null;--  Text_Io.Put_Line(" -- up");
					  Console.Up_Arrow;
				       when Wide_Character'Val(66) =>
					  null;--  Text_Io.Put_Line(" -- down");
					  Console.Down_Arrow;
				       when Wide_Character'Val(67) =>
					  null;--  Text_Io.Put_Line(" -- right");
					  Console.Right_Arrow;
				       when Wide_Character'Val(68) =>                          
					  null;--  Text_Io.Put_Line(" -- left");
					  Console.Left_Arrow;
				       when Wide_Character'Val(70) =>
					  null;--  Text_Io.Put_Line(" -- end");
				       when Wide_Character'Val(72) =>
					  null;--  Text_Io.Put_Line(" -- begin");                                                              
				       when Wide_Character'Val(91) =>
					  Text_Io.Get_Immediate(Char);                
					  case Char is                               
					     when Wide_Character'Val(69) =>
						null;--  Text_Io.Put_Line(" -- F5");
						Console.Switch(EnvironmentParameters);
						Mode := EnvironmentParameters;
						Text_Io.Get_Immediate(Char);                  
					     when others =>
						null;
					  end case;
					  
				       when others =>
					  
					  Console.Reset;            
					  
					  End_Of_Program := False;
					  Console.Unlock;
					  Console.Receive(Char);
					  
				    end case;

				 when others =>


				    Console.Set_On_Esc(False);

				    Console.Unlock; 

				    
			      end case;                                       

			   when others =>                    
			      case Mode is
				 when Quit =>
				    Console.Switch(Null_Item);
				 when others =>
				    null;
			      end case;
			      
			      Console.Set_On_Esc(False);
			      
			      End_Of_Program := False;
			      
			      Console.Receive(Char);
			      
			end case;

		     exception
			
			-- A la saisie de Ctrl+D l'exception End_Error est levée.
			
			when Text_Io.End_Error =>
			   
			   -- On arrête la console.
			   Console.Lock;
			   My_Ansi_Consoles.Clear_screen;

			   
			   Mode_Info_Status(W1, Null_Item);
			   
			   
			   
			   My_Ansi_Consoles.Draw_Window (W4);
			   My_Ansi_Consoles.Draw_Centered (W4, 1, Ansi_Console.White, "End of program.");
			   My_Ansi_Consoles.Draw (W4, 3, 3, Ansi_Console.White, "Going to halt architecture...");
			   
			   Bell(Quiet);
			   
			   delay 2.5;
			   -- On arrête la console.
			   My_Ansi_Consoles.Clear_screen;
			   
			   Mode_Info_Status(W1, Null_Item);
			   
			   My_Ansi_Consoles.Draw_Window (W4);
			   My_Ansi_Consoles.Draw_Centered (W4, 2, Ansi_Console.White, "Je plaisante.");
			   Move_Cursor_To(W4, 3, 5);
			   Bell(Quiet);
			   delay 2.5;                   
			   Console.reset;
			   Console.Unlock;
		     end;            
		  end loop;
	       end if;
	       Text_Io.Put_Line("Halting console...");
	       Console.Halt;      
	       Text_Io.Put_Line("Console halted...");

	       Text_Io.Put_Line("Cyborg client thread : Environment thread halted...");
	       Errno := 0;      
	       null;
	       
	       
	    exception    	       
	       when Socket_Exception : Socket_Error =>
		  Wide_Text_Io.Put_Line("Cyborg terminal on socket error.");
		  Ada.Text_Io.Put_Line(Error_Type'Image(Resolve_Exception(Socket_Exception)));
		  Console.Halt;

		  raise;
	       when Host_Exception : Host_Error =>
		  Wide_Text_Io.Put_Line("Cyborg terminal on Host error.");
		  Ada.Text_Io.Put_Line(Error_Type'Image(Resolve_Exception(Host_Exception)));		  		  
		  Console.Halt;

		  raise;
	       	       

		  
		  
	       when Constraint_Error =>
		  
		  Wide_Text_Io.Put_Line("Cyborg terminal on constraint error.");
		  
	       when others =>
		  Wide_Text_Io.Put_Line("Cyborg terminal on others error.");
		  
		  Text_Io.Put_Line("Cyborg Terminal thread : abort Timer and Console.");
		  
		  Console.Halt;
		  Text_Io.Put_Line("Cyborg Terminal thread : Halting Environment thread...");
		  

		  Text_Io.Put_Line("Cyborg Terminal thread : Environment thread halted...");
		  
		  Gnat.Sockets.Close_Socket(Socket.all);
		  
		  Text_Io.Put_Line("Cyborg client thread : Socket closed !");
		  
		  raise;
	    end;
	 end;
	 Gnat.Sockets.Close_Socket(Socket.all);
	 Text_Io.Put_Line("Cyborg client thread : Socket closed !");
      else
	 Text_Io.Put_Line("User name already in use or bad password !");
	 delay 2.0;

	 Gnat.Sockets.Close_Socket(Socket.all);      
	 Text_Io.Put_Line("Cyborg client thread : Socket closed !");
      end if;
      abort Matrix_Saver;
   end Main;
end Adam.Terminal.Main;

