-- aish is another attempt of A. i. written with Ada.
-- Aish is Copyright (C) 2024  ; 
--
--   This program is free software; you can redistribute it and/or modify
--   it under the terms of the GNU General Public License as published by
--   the Free Software Foundation; either version 2 of the License, or
--   (at your option) any later version.
--
--   This program is distributed in the hope that it will be useful,
--   but WITHOUT ANY WARRANTY; without even the implied warranty of
--   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--   GNU General Public License for more details.
--
--   You should have received a copy of the GNU General Public License
--   along with this program; if not, write to the Free Software
--   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
--
-- Date := "2024-04-29 20:25:34"
-- Version := "1.1.0r"
with Ai ; 
with Ai.Errors ; 
with Ai.Parameters ; 
with Ai.Options ; 
with Ai.Versions ; 
with Ai.Versions.Version_io ; 
with Ai.Interfaces ; 
with Ai.Shared ; 
with Ai.Shell ; 

use Ai;
use Ai.Interfaces;
use Ai.Versions;
use Ai.Versions.Version_Io;
use Ai.Shared;
use Ai.Shell;

with Ada.Wide_Text_Io;
with Ada.Strings.Fixed;
with Gnat.Os_Lib;
with Text_Io;

with Ada.Characters.Handling;
with Gnat.Semaphores;
with Ada.Calendar;
with Ada.Calendar.Formatting;

with Gnat.Directory_Operations;
with Ada.Wide_Characters.Handling;
use Ada.Wide_Characters.Handling;


procedure Aish is
   
   
   function System(Cmd : in String) return Integer;
   pragma Import (C, System, "system");
   
   
   
   use Ada.Strings.Fixed;
   use Gnat.Os_Lib;
   use Text_Io;
   use Gnat.Semaphores;
   use Ada.Calendar;
   use Ada.Strings;
   use Ada.Characters;
   use Gnat.Directory_Operations;
   use Ada.Wide_Characters.Handling;
   
   
   package W_Io renames Ada.Wide_Text_Io;
   
      
   type Terminal_Type;
   task type Terminal_Process (Terminal : access Terminal_Type) is
      entry Halt;
      entry Receive (Wchar : in Wide_Character);
      entry Refresh;
      entry Page_Down;
      entry Page_Up;
      entry Up_Arrow;
      entry Down_Arrow;
      entry Left_Arrow;
      entry Right_Arrow;
      entry Full_Screen;
      entry Del;
      entry Begin_Of;
      entry End_Of;
      entry Overwrite;
      entry Screen_Print;
   end Terminal_Process;
   
   type Terminal_Type is limited
     record
	Term_Name : Term_Enum := None;
	Proc      : Terminal_Process(Terminal_Type'Access);
	Old_Pwd   : String_Access;
     end record;
      
   
   
   task body Terminal_Process is
      
      Lock : Binary_Semaphore(True, Default_Ceiling);
      
      Text : Wide_String_Access := new Wide_String ' ("");
      Old_Length    : Natural := 0; -- save text'length
      Old_Total_Length    : Natural := 0; -- save total_type'image(total_sum)'length
      
      
      subtype Cpu_String is String (1..6);
      Cpu_Cmd : constant String := "sh -c ""./bin/cpu_usage > .cpu_usage.txt""" & Character'Val(0);
      Cpu_Error : Integer := 0;
      Cpu_File : Text_Io.File_Type;
      Args_List : Argument_List_Access := Argument_String_To_List(Cpu_Cmd);
      Spawn_Err : Integer := 0;
      Success : Boolean := False;
      
      task Screen is
	 entry Refresh;
	 entry Halt;
      end Screen;
      
      task body Screen is
	 Prompt : String_Access;
	 Cpu    : Cpu_String := (others => ' ');
      begin

	 loop
	    Cpu_Error := System(Cpu_Cmd);

	    if Is_Regular_File(".cpu_usage.txt") then
	       Cpu := (others => ' ');

	       Text_Io.Open(Cpu_File, Text_Io.In_File, ".cpu_usage.txt");
	       declare
		  Line : constant String := Get_Line(Cpu_File);
		  Pos  : Natural := Line'Length + ((Cpu_String'Length-1) - Line'Length) ;
	       begin
		  
		  for I in reverse Line'Range loop
		     Cpu(Pos) := Line(I);
		     Pos := Pos - 1;
		  end loop;
		  Cpu(Cpu'Length) := '%';
	    end;
	    Text_Io.Close(Cpu_File);

	       Delete_File(".cpu_usage.txt", Success);
	    end if;
		  
	    
	    select
	       accept Halt;
	       exit;
	    or
	       accept Refresh do
		  Lock.Seize;
		  Free(Prompt);
		  
		  --Prompt := new String ' (Term_Enum'Image(Terminal.Term_Name) & ": " & Formatting.Image(Clock)(12..Formatting.Image(Clock)'Length) & ":" & Total_Type'Image(Total_Sum)  & "$ ");
		  Prompt := new String ' (Term_Enum'Image(Terminal.Term_Name) & ':' & cpu & ": " & Formatting.Image(Clock)(12..Formatting.Image(Clock)'Length) & ":" & Total_Type'Image(Total_Sum)  & "$ ");
		  if Text /= null then		     
		     
		     Text_Io.Put(Character'Val (13) & Prompt.all);
		     Put((Old_Length+Old_Total_Length) * ' ');
		     Text_Io.Put(Character'Val (13) & Prompt.all);
		     W_Io.Put(Text.all);
		  else
		     Text_Io.Put(Character'Val (13) & Prompt.all);
		     Put((Old_Length+Old_Total_Length) * ' ');
		     Text_Io.Put(Character'Val (13) & Prompt.all);
		  end if;
		  Old_Total_Length := Total_Type'Image(Total_Sum)'Length;
		  Old_Length := 0;
		  Lock.Release;
	       end Refresh;	      
	    end select;
	 end loop;
      end Screen;
      
      
      task Deamon is
      entry Halt;
      entry Lock;
      entry Unlock;
   end Deamon;
   task body Deamon is
      End_Of_Task : Boolean := False;
   begin
      while not End_Of_Task loop
	 loop
	    select
	       accept Halt;
	       End_Of_Task := True;	    
	       exit;
	    or
	       accept Lock;
	       exit;
	    or
	       accept Unlock;
	    or
	       delay 0.5;
	       screen.Refresh;
	    end select;	    
	 end loop;
	 while not End_Of_Task loop
	    select
	       accept Halt;
	       End_Of_Task := True;
	       exit;
	    or
	       accept Lock;
	    or
	       accept Unlock;
	       exit;
	    end select;
	 end loop;
      end loop;
   end Deamon;
   
   
   Alias_Set         : Attributs(2048);
   Var_Set           : Attributs(2048);
   Internal_Cmd : Int_Cmd_Enum := None;
   Is_Internal_Cmd : Boolean := False;
   Buffer : Wide_String_Access;
   
   Completion_Result : Wide_Result_Access;      
   History_Set   : Wide_String_Set(2048);
   History_Last  : Natural := 0;
   History_Index : Natural := 0;
   
   Errno : Integer := 0;  
   
   Arguments : Wide_String_Access;
   Args_Index : Natural := 0;
   
   begin
      loop
	 select
	    accept Halt do
	       Deamon.Halt;
	       Screen.Halt;
	       end Halt;
	    exit;
	 or
	    accept Receive (Wchar : in Wide_Character) do
	       
	       if Is_Control(Wchar) then
		     
		  case Wchar is
		     when Wide_Character'Val(9) =>
			if Text /= null and then
			  Text'Length /= 0 then
			   Lock.Seize;
			   declare
			      Line : constant String_Access := 
				new String ' (Handling.To_String(Text.all));
			      
			      Path_On_Line : Wide_String_Access;
			      buffer : String_Access := new String ' ("");
			   begin
			      if Completion_Result /= null then
				 U_Array_Free(Completion_Result.Wlines);
			      end if;
			      Completion(Line.all, Path_On_Line, Completion_Result);				    
			      if Path_On_Line /= null then
				 Buffer := new String ' (Handling.To_String(Path_On_Line.all));
				 Wide_Free(Path_On_Line);					  
				 Wide_Free(Text);
				 Text := new Wide_String ' (Handling.To_Wide_String(Buffer.all));
				 Free(Buffer);
				 U_Array_Free(Completion_Result.Wlines);
				 Wide_Result_Free(Completion_Result);
			      else
				 for I in Completion_Result.Wlines'Range loop
				    Text_Io.Put_Line(Delete_Local_Prefix(Handling.To_String((-Completion_Result.Wlines(I)))));
				 end loop;
			      end if;
			      
			   end;
			   Lock.Release;
			end if;
		     when Wide_Character'Val(10) | Wide_Character'Val(13) =>			
			if Text /= null and then
			  Text'Length > 0 then
			   
			   Lock.Seize;
			   Text_Io.New_Line;
			   Deamon.Lock;
			   
			   if Text(1) = '-' or Text(1) = '+' then
			      if Text'Length > 1 then
				 declare
				    Val : Total_Type := 0.0;
				 begin
				    Val := Total_Type'Value(Handling.To_String(Text.all));
				    Total_Sum := Total_Sum + Val;
				    Wide_Free(Text);
				    Text := new Wide_String ' ("");

				 exception
				    when Constraint_error =>
				       Text_Io.Put("-: error");
				       Text_Io.New_Line;
				 end;
			      end if;
			      
			   else
			   
			   
			   
			      Internal_Cmd := Internal_Cmd_Value(Handling.To_String(Text.all));
			      Is_Internal_Cmd := True;
			      case Internal_Cmd is
				 when none =>
				    Is_Internal_Cmd := False;
				 when Alias =>
				    
				    Alias(Handling.To_String(Text.all), Alias_Set);
				    
				 when Unalias =>
				    
				    Unalias(Handling.To_String(Text.all), Alias_Set);
				    
				 when Cd =>
				    begin
				       Change_Directory(Handling.To_String(Text.all), Terminal.Old_Pwd);
				       
				    exception
				       when Directory_Error =>

					  Text_Io.Put("Directory not found");
					  Text_Io.New_Line;
				    end;
				 when Set =>

				    Set(Handling.To_String(Text.all), Var_Set);
				    
				 when Unset =>

				    Unset(Handling.To_String(Text.all), Var_Set);
				    
				 when Put =>

				    Args_Index := Index(Handling.To_String(Text.all), " ")+1;
				    if Args_Index /= 0 then
				       Arguments := new Wide_String ' (Text(Args_Index..Text'Length));
				       Shell.Put(Handling.To_String(Arguments.all), Var_Set);
				    end if;
				    Text_Io.New_Line;
				 when Put_Line =>

				    Args_Index := Index(Handling.To_String(Text.all), " ")+1;
				    if Args_Index /= 0 then
				       Arguments := new Wide_String ' (Text(Args_Index..Text'length));
				       Shell.Put_Line(Handling.To_String(Arguments.all), Var_Set);
				    end if;
				    
			      end case;
			      
			      
			      if not Is_Internal_Cmd then
				 

				 declare
				    Alias_Ptr   : String_Access;
				    Buffer      : String_Access;
				    Normal      : String_Access;				 
				 begin

				    for Iter in 1..Alias_Set.Index loop
				       declare
					  Alias : constant Attribut_Record := Alias_Set.List(Iter);
					  First_Space : Natural := 
					    Index(Handling.To_String(Text.all), " ");
					  Non_Blank   : constant Natural :=
					    Index_Non_Blank(Handling.To_String(Text.all), Backward);
				       begin	
					  if Non_Blank < First_Space then
					     First_Space := 0;
					  end if;
					  if First_Space /= 0 then
					     if Names(Alias) =
					       Handling.To_String(Text(Text'First..First_Space - 1)) then
						Alias_Ptr := new String ' (Images(Alias));
						exit;
					     end if;
					  else
					     if Names(Alias) = Handling.To_String(Text(Text'First..Index_Non_Blank(Handling.To_String(Text.all), Backward))) then
						Alias_Ptr := new String ' (Images(Alias));
						exit;
					     end if;
					  end if;
				       end;
				    end loop;

				    if Alias_Ptr /= null then
				       declare
					  First_Space : constant Natural := 
					    Index(Handling.To_String(Text.all), " ");
				       begin

					  if First_Space /= 0 then
					     Buffer := new String ' 
					       (Alias_Ptr.all & ' ' & Handling.To_String(Text(First_Space+1..Text ' Last)));

					  else
					     Buffer := new String ' (Alias_Ptr.all);
					  end if;
				       end;
				       Wide_Free(Text);

				       Normal := new String ' (Normalize_Quoted_Argument(Buffer.all));
				       Text := new Wide_String ' (Handling.To_Wide_String(Normal.all));
				       
				    end if;
				 end;
				 
				 
				 
				 if Locate_Exec_On_path(Command_Name(Handling.To_String(Text.all))) /= null then
				    
				    
				    if Command_Name(Handling.To_String(Text.all))'Length = Text'Length then
				       
				       declare
					  
					  Args : constant Argument_List_Access := Argument_String_To_List
					    (
					     "-c " &
					       Locate_Exec_On_path(Command_Name(Handling.To_String(Text.all))).all);
				       begin
					  if Locate_Exec_On_path(Command_Name(Handling.To_String(Text.all))).all'Length /= 0 then
					     Errno := Spawn("/usr/bin/sh", Args.all);
					  end if;
				       end;
				       
				    else
				       
				       declare
					  
					  Args : constant Argument_List_Access := new Argument_List ' (new String ' ("-c"), 
											      new String ' (Locate_Exec_On_path(Command_Name(Handling.To_String(Text.all))).all & " " & 
													      Handling.To_String(Text.all)(Command_Name(Handling.To_String(Text.all))'Length+2..Text'Last)
													   )
											     );
					  
				       begin
					  Normalize_Arguments(Args.all);
					  Errno := Spawn("/usr/bin/sh", Args.all);
				       end;
				       
				       
				    end if;
				 else
				    New_Line;
				    Text_Io.Put("Command not found");
				    Text_Io.New_Line;
				 end if;
			      end if;
			      if Errno /= 0 then	    
				 Text_Io.Put("Error: errno = " & Integer'Image(Errno));
			      end if;
			      Old_Length := Text'Length;
			      Add_Line(History_Set, History_Last, Text.all);
			      History_Index := 0;
			      Wide_Free(Text);
			      Text := new Wide_String ' ("");			   
			   end if;
			   Deamon.Unlock;
			   
			   Lock.Release;
			end if;
		     when Wide_Character'Val(12) =>
			Errno := System("clear" & Character'Val(0));
			Screen.Refresh;
		     when Wide_Character'Val(127) =>
			Old_Length := Text'Length;
			Screen.Refresh;
			Buffer := new Wide_String ' (Text.all(Text'First..Text'Last-1));
			Wide_Free(Text);
			Text := new Wide_String ' (Buffer.all);
			Wide_Free(Buffer);			
		     when others =>
			null;
		  end case;
	       else
		  Lock.Seize;
		  Buffer := new Wide_String ' (Text.all & Wchar);
		  Wide_Free(Text);
		  Text := new Wide_String ' (buffer.all);
		  Wide_Free(Buffer);
		  Old_Length := Text'Length;
		  Lock.Release;
	       end if;
	       
	    end Receive;
	    Screen.Refresh;
	 or
	    accept Refresh;
	    Screen.Refresh;
	 or
	    accept Page_Down;
	 or
	    accept Page_Up;
	 or
	    accept Up_Arrow do
	       
	       if (History_Last > 0) and then
		 (History_Last - History_Index) > 0 then		  
		  Old_Length := Text'Length;
		  Screen.Refresh;
		  Wide_Free(Text);		  
		  Text := new Wide_String ' (History_Set.Lines(History_Last - (History_Index)).all);
		  History_Index := History_Index + 1;		  
		  Screen.Refresh;
	       else
		  Text_Io.Put(Character'Val(7));
	       end if;
	    end up_arrow;
	 or
	    accept Down_Arrow do
	       
	       if (History_Index > 1) then		  
		  Old_Length := Text'Length;
		  Wide_Free(Text);
		  
		  Text := new Wide_String ' (History_Set.Lines(History_Last - (History_Index - 2)).all);
		  
		  History_Index := History_Index - 1;
		  Screen.Refresh;
	       elsif History_Index = 1 then
		  Old_Length := Text'Length;
		  Wide_Free(Text);		  
		  Text := new Wide_String ' ("");
		  
		  History_Index := History_Index - 1;
		  Screen.Refresh;
	       else
		  Text_Io.Put(Character'Val(7));
	       end if;
	    end Down_Arrow;
	 or
	    accept Left_Arrow;
	 or
	    accept Right_Arrow;
	 or
	    accept Full_Screen;
	 or
	    accept Del;
	 or
	    accept Begin_Of;
	 or
	    accept End_Of;
	 or
	    accept Overwrite;
	 or
	    accept Screen_Print;
	 end select;
      end loop;
      
   end Terminal_Process;
   
   
   
   procedure Term_Init (Terminal : in out Terminal_Type) is
      Env : constant String_Access := Getenv("TERM");
   begin
      
      Terminal.Term_Name := Term_Enum'Value(Env.all);
      Terminal.Old_Pwd := new String ' ("");
   exception
      when Constraint_Error =>
	 Terminal.Term_Name := None;
   end Term_Init;
   
   Terminal : Terminal_Type;

   Errno : Integer := 0;
   
   Interf : Interface_Record;
   
begin
   Term_Init(Terminal);
   Interfaces.Initialize(Interf);
   declare
      Help_Parameter : constant Parameters.Parameter_Record :=
	Get_Parameter(Interf, Help);
      Version_Parameter : constant Parameters.Parameter_Record :=
	Get_Parameter(Interf, Ai.Version);
      Term_Name_Parameter : constant Parameters.Parameter_Record :=
	Get_Parameter(Interf, Term_Name);
      Initialize_Parameter : constant Parameters.Parameter_Record :=
	Get_Parameter(Interf, Initialize);
      Add_Parameter : constant Parameters.Parameter_Record :=
	Get_Parameter(Interf, Add);
      Remove_Parameter : constant Parameters.Parameter_Record :=
	Get_Parameter(Interf, Remove);
      Total_Parameter : constant Parameters.Parameter_Record :=
	Get_Parameter(Interf, Total);
   begin
      
      if Help_Parameter.Is_Setted then
	 Interfaces.Parameters_Descriptions(Interf);
	 Terminal.Proc.Halt;
	 return;
      else
	 if Version_Parameter.Is_Setted then
	    Text_Io.Put_Line(To_String(Versions.Version));
	    Terminal.Proc.Halt;
	    return;
	 end if;	    
      end if;
      --Interfaces.Print_Parameters(Interf);
      if Term_Name_Parameter.Is_Setted then
	 begin
	    Terminal.Term_Name := Term_Enum'Value(Handling.To_String(Term_Name_Parameter.Value.all));
	 exception
	    when Constraint_Error =>
	       Text_Io.Put_Line("Uncknow terminal name : " & Handling.To_String(Term_Name_Parameter.Value.all));
	       Terminal.Proc.Halt;
	       return;
	 end;
      end if;
      if Initialize_Parameter.Is_Setted then
	 Total_Sum := Total_Type'Value(Handling.To_String(Initialize_Parameter.Value.all));
	 Terminal.Proc.Halt;
	 return;
      end if;
      
      if Add_Parameter.Is_Setted then
	 Total_Sum := Total_Sum + Total_Type'Value(Handling.To_String(Add_Parameter.Value.all));
	 Terminal.Proc.Halt;
	 return;
      end if;
      
      if Remove_Parameter.Is_Setted then
	 Total_Sum := Total_Sum + Total_Type'Value(Handling.To_String(Remove_Parameter.Value.all));
	 Terminal.Proc.Halt;
	 return;
      end if;
      
      if Total_Parameter.Is_Setted then
	 Put_Line(Total_Type'Image(Total_Sum));
	 Terminal.Proc.Halt;
	 return;
      end if;
      
      
   end;
      
   
   Put_Line("Greetings " & Getenv("USER").all & "!");   
   
   loop
      Terminal.Proc.Refresh;
      declare
	 Wchar : Wide_Character := ' ';
      begin
	 W_Io.Get_Immediate(Wchar);
	 case Terminal.Term_Name is
	    when Linux =>
	       case Wchar is
		  when Wide_Character'Val(27) =>
		     --Terminal.Proc.Set_On_Esc(True);
		     
		     W_Io.Get_Immediate(Wchar);
		     
		     case Wchar is
			when Wide_Character'Val(27) =>                             
			   
			   Terminal.Proc.Halt;
			   exit;
			   
			   
			   --  if Center.Full_Screen then
			   --     Terminal.Proc.Reset;
			   --  else                               
			   --  case Center.Current_Mode is                                                            
			   --  	 when Devel_Mode..Help_Mode =>
			   --  	    Terminal.Proc.Reset;
			   --  	 when Null_Mode =>
			   
			   --  	    Terminal.Proc.Lock;
			   --  	    --Terminal.Proc.Set_On_Esc(False);
			   --  	    Terminal.Proc.Switch(Quit_Mode);                               
			   --  	    End_Of_Program := True;
			   --  	 when Auth_Mode =>
			   --  	    if End_Of_Program then                                             
			   --  	       Terminal.Proc.Switch(Quit_Mode);                                          
			   --  	    else
			   --  	       --Terminal.Proc.Set_On_Esc(False);
			   --  	       Terminal.Proc.Switch(Quit_Mode);
			   --  	       End_Of_Program := True;
			   --  	    end if;
			   --  	 when others =>
			   --  	    if End_Of_Program then
			   --  	       Terminal.Proc.Switch(Null_Mode);
			   --  	       Terminal.Proc.Set_On_Esc(False);
			   --  	       End_Of_Program := False;
			   
			   --  	    else
			   --  	       Terminal.Proc.Switch(Quit_mode);
			   --  	       --Terminal.Proc.Set_On_Esc(False);
			   --  	       End_Of_Program := True;
			   --  	    end if;
			   --     end case;       
			   
			   -- end if;				 
			   
			when others =>
			   null;
			   --  case Center.Current_Mode is
			   --     when Quit_Mode =>
			   --  	 if End_Of_Program then         
			   
			   --  	    Terminal.Proc.Switch(Quit_Mode);                                  
			   --  	 end if;
			   --     when others =>
			   
			   --  	 Terminal.Proc.Set_On_Esc(False);
			   --  	 End_Of_Program := False;
			   --  end case;
		     end case;                     
		     
		     case Wchar is
			when Wide_Character'Val(91) =>                           
			   W_Io.Get_Immediate(Wchar);
			   --  case Center.Current_Mode is
			   --     when Auth_Mode =>
			   --  	 null;
			   --     when others =>
			   --Terminal.Proc.Set_On_Esc(False);
			   case Wchar is
			      when Wide_Character'Val(49) =>
				 W_Io.Get_Immediate(Wchar);
				 case Wchar is
				    when Wide_Character'Val(55) =>
				       null;--  W_Io.Put_Line(" -- F6");

				       --Terminal.Proc.Switch(Execut_Mode);
				       --Center.Current_Mode := Execut_Mode;
				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(56) =>
				       null;--  W_Io.Put_Line(" -- F7");
					    --Terminal.Proc.Switch(Shell_Mode);
					    --Center.Current_Mode := Shell_Mode;
				       
				       --Terminal.Proc.Switch(Execut_mode);
				       --   Center.Current_Mode := Execut_Mode;
				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(57) =>
				       --W_Io.Put_Line(" -- F8");
				       --  case Center.Current_Mode is
				       --  	when Devel_Mode =>
				       --  	   Terminal.Proc.Multi_Switch(Devel_Mode);
				       --  	when Multi_Mode =>
				       --  	   Terminal.Proc.Multi_Switch(Multi_Mode);
				       --  	when others =>
				       --  	   null;
				       --  end case;
				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(126) =>                     
				       null;--  W_Io.Put_Line(" -- begin");
				       Terminal.Proc.Begin_Of;
				    when others =>
				       null;
				 end case;                      
			      when Wide_Character'Val(50) =>                    
				 W_Io.Get_Immediate(Wchar);
				 case Wchar is
				    when Wide_Character'Val(48) =>
				       null;--  W_Io.Put_Line(" -- F9");
				       --Terminal.Proc.F9;
				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(49) =>
				       null;--  W_Io.Put_Line(" -- F10");
				       --Terminal.Proc.F10;
				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(51) =>
				       null;--  W_Io.Put_Line(" -- F11");
				       --Terminal.Proc.F11;
				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(52) =>
				       null;--  W_Io.Put_Line(" -- F12");
				       Terminal.Proc.Full_Screen;
				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(53) =>                            
				       null;--  W_Io.Put_Line(" -- Maj+F1");
				    when Wide_Character'Val(54) =>                            
				       null;--  W_Io.Put_Line(" -- Maj+F2");
				    when Wide_Character'Val(56) =>                            
				       null;--  W_Io.Put_Line(" -- Maj+F3");
				    when Wide_Character'Val(57) =>
				       null;--  W_Io.Put_Line(" -- Maj+F4");
				    when Wide_Character'Val(126) =>
				       null;--  W_Io.Put_Line(" -- insert");
				       Terminal.Proc.Overwrite;
				    when others =>
				       null;
				 end case;                               
			      when Wide_Character'Val(51) =>                    
				 null;--  W_Io.Put_Line(" -- del");
				 W_Io.Get_Immediate(Wchar);
				 Terminal.Proc.Del;
			      when Wide_Character'Val(52) =>
				 null;--  W_Io.Put_Line(" -- end");
				 W_Io.Get_Immediate(Wchar);
				 Terminal.Proc.End_Of;
			      when Wide_Character'Val(53) =>
				 null;--  W_Io.Put_Line(" -- page up");
				 Terminal.Proc.Page_Up;
				 W_Io.Get_Immediate(Wchar);
			      when Wide_Character'Val(54) =>
				 null;--  W_Io.Put_Line(" -- page down");
				 Terminal.Proc.Page_Down;
				 W_Io.Get_Immediate(Wchar);
			      when Wide_Character'Val(65) =>
				 null;--  W_Io.Put_Line(" -- up");
				 Terminal.Proc.Up_Arrow;
				 
			      when Wide_Character'Val(66) =>
				 null;--  W_Io.Put_Line(" -- down");
				 Terminal.Proc.Down_Arrow;
				 
			      when Wide_Character'Val(67) =>
				 null;--  W_Io.Put_Line(" -- right");
				 Terminal.Proc.Right_Arrow;
				 
			      when Wide_Character'Val(68) =>
				 null;--  W_Io.Put_Line(" -- left");
				 Terminal.Proc.Left_Arrow;
				 
			      when Wide_Character'Val(91) =>
				 W_Io.Get_Immediate(Wchar);
				 case Wchar is
				    when Wide_Character'Val(65) =>
				       null;--  W_Io.Put_Line(" -- F1");
					    --  Terminal.Proc.Switch(Dialog_Mode);
					    --  Center.Current_Mode := Dialog_Mode;
				    when Wide_Character'Val(66) =>
				       null;--  W_Io.Put_Line(" -- F2");
					    --  Terminal.Proc.Switch(Devel_Mode);
					    --  Center.Current_Mode := Devel_Mode;
				    when Wide_Character'Val(67) =>
				       null;--  W_Io.Put_Line(" -- F3");
					    --  Terminal.Proc.Switch(Organizer_Mode);
					    --  Center.Current_Mode := Organizer_Mode;
				    when Wide_Character'Val(68) =>
				       null;--  W_Io.Put_Line(" -- F4");
					    --  Terminal.Proc.Switch(Multi_Mode);
					    --  Center.Current_Mode := Multi_Mode;
				    when Wide_Character'Val(69) =>
				       null;--  W_Io.Put_Line(" -- F5");
				       
				    when others =>
				       null;
				 end case;
				 
			      when others =>
				 
				 --Terminal.Proc.Reset;            
				 
				 --End_Of_Program := False;
				 --Terminal.Proc.Unlock;
				 Terminal.Proc.Receive(Wchar);
				 
			   end case;
			when others =>
			   Terminal.Proc.Receive(Wchar);
		     end case;
		     --  when others =>
		     --  	   Terminal.Proc.Set_On_Esc(False);
		     --  	   --Terminal.Proc.Unlock; 
		     --     end case;              
		     
		  when Wide_Character'Val(197) =>
		     W_Io.Get_Immediate(Wchar);
		  when others =>                    
		     Terminal.Proc.Receive(Wchar);
	       end case;
	       
	    when Xterm =>
	       
	       case Wchar is
		  when Wide_Character'Val(27) =>
		     --Terminal.Proc.Set_On_Esc(True);		     	      
		     W_Io.Get_Immediate(Wchar);			      
		     case Wchar is
			when Wide_Character'Val(27) =>                             
			   
			   Terminal.Proc.Halt;
			   exit;
			   
			   
			   --  if Center.Full_Screen then
			   --     Terminal.Proc.Reset;
			   --  else                               
			   --     case Center.Current_Mode is                                                            
			   --  	 when Devel_Mode..Help_Mode =>
			   --  	    Terminal.Proc.Reset;
			   --  	 when Null_Mode =>
				    
			   --  	    Terminal.Proc.Lock;
			   --  	    Terminal.Proc.Set_On_Esc(False);
			   --  	    Terminal.Proc.Switch(Quit_Mode);                               
			   --  	    End_Of_Program := True;
			   --  	 when Auth_Mode =>
			   --  	    if End_Of_Program then                                             
			   --  	       Terminal.Proc.Switch(Quit_Mode);                                          
			   --  	    else
			   --  	       Terminal.Proc.Set_On_Esc(False);
			   --  	       Terminal.Proc.Switch(Quit_Mode);
			   --  	       End_Of_Program := True;
			   --  	    end if;
			   --  	 when others =>
			   --  	    if End_Of_Program then
			   --  	       Terminal.Proc.Switch(Null_Mode);
			   --  	       Terminal.Proc.Set_On_Esc(False);
			   --  	       End_Of_Program := False;
				       
			   --  	    else
			   --  	       Terminal.Proc.Switch(Quit_mode);
			   --  	       Terminal.Proc.Set_On_Esc(False);
			   --  	       End_Of_Program := True;
			   --  	    end if;
			   --     end case;
			   --  end if;
			   
			when Wide_Character'Val(79) =>
			   W_Io.Get_Immediate(Wchar);
			   case Wchar is
			      when Wide_Character'Val(80) =>
				 null;--  W_Io.Put_Line(" -- F1");
				 --  Terminal.Proc.Switch(Dialog_Mode);
				 --  Center.Current_Mode := Dialog_Mode;
			      when Wide_Character'Val(81) =>
				 null;--  W_Io.Put_Line(" -- F2");
				 --  Terminal.Proc.Switch(Devel_Mode);
				 --  Center.Current_Mode := Devel_Mode;
			      when Wide_Character'Val(82) =>
				 null;--  W_Io.Put_Line(" -- F3");
				 --  Terminal.Proc.Switch(Organizer_Mode);
				 --  Center.Current_Mode := Organizer_Mode;
			      when Wide_Character'Val(83) =>
				 null;--  W_Io.Put_Line(" -- F4");
				 --  Terminal.Proc.Switch(Multi_Mode);
				 --  Center.Current_Mode := Multi_Mode;				       
			      when others =>
				 null;
			   end case;
			   
			when Wide_Character'Val(91) =>				    
			   
			   W_Io.Get_Immediate(Wchar);
			   
			   case Wchar is
			      when Wide_Character'Val(53) =>					  
				 null;--  W_Io.Put_Line(" -- page up");
				 Terminal.Proc.Page_Up;
				 W_Io.Get_Immediate(Wchar);
			      when Wide_Character'Val(54) =>
				 null;--  W_Io.Put_Line(" -- page down");
				 Terminal.Proc.Page_Down;
				 W_Io.Get_Immediate(Wchar);
			      when Wide_Character'Val(65) =>
				 null;--  W_Io.Put_Line(" -- up");
				 Terminal.Proc.Up_Arrow;
				 
			      when Wide_Character'Val(66) =>
				 null;--  W_Io.Put_Line(" -- down");
				 Terminal.Proc.Down_Arrow;
				 
			      when Wide_Character'Val(67) =>
				 null;--  W_Io.Put_Line(" -- right");
				 Terminal.Proc.Right_Arrow;
				 
			      when Wide_Character'Val(68) =>
				 null;--  W_Io.Put_Line(" -- left");
				 Terminal.Proc.Left_Arrow;
				 
			      when Wide_Character'Val(51) =>                    
				 
				 null;--  W_Io.Put_Line(" -- del");
				 W_Io.Get_Immediate(Wchar);
				 Terminal.Proc.Del;
			      when Wide_Character'Val(70) =>
				 null;--  W_Io.Put_Line(" -- end");
				 
				 Terminal.Proc.End_Of;
			      when Wide_Character'Val(72) =>
				 null;--  W_Io.Put_Line(" -- begin");
				 Terminal.Proc.Begin_Of;				       
			      when Wide_Character'Val(49) =>
				 
				 W_Io.Get_Immediate(Wchar);
				 case Wchar is
				    when Wide_Character'Val(53) =>
				       -- F5
				       
				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(55) =>
				       null;--  W_Io.Put_Line(" -- F6");
				       
				       --  Terminal.Proc.Switch(Execut_Mode);
				       --  Center.Current_Mode := Execut_Mode;
				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(56) =>
				       null;--  W_Io.Put_Line(" -- F7");
				       --  Terminal.Proc.Switch(Shell_Mode);
				       --  Center.Current_Mode := Shell_Mode;

				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(57) =>
				       --W_Io.Put_Line(" -- F8");
				       --  case Center.Current_Mode is
				       --  	  when Devel_Mode =>
				       --  	     Terminal.Proc.Multi_Switch(Devel_Mode);
				       --  	  when Multi_Mode =>
				       --  	     Terminal.Proc.Multi_Switch(Multi_Mode);
				       --  	  when others =>
				       --  	     null;
				       --  end case;
				       W_Io.Get_Immediate(Wchar);
				       
				    when others =>
				       null;
				 end case;                 
			      when Wide_Character'Val(50) =>                    
				 null;--  W_Io.Put_Line(" -- insert");
				 Terminal.Proc.Overwrite;
				 
				 W_Io.Get_Immediate(Wchar);
				 case Wchar is
				    
				    when Wide_Character'Val(48) =>
				       null;--  W_Io.Put_Line(" -- F9");
				       
				       --Terminal.Proc.F9;
				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(49) =>
				       null;--  W_Io.Put_Line(" -- F10");
				       
				       --Terminal.Proc.F10;
				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(51) =>
				       null;--  W_Io.Put_Line(" -- F11");
				       
				       --Terminal.Proc.F11;
				       W_Io.Get_Immediate(Wchar);
				       
				    when Wide_Character'Val(50) =>
				       null;--                        inst
				       Terminal.Proc.Overwrite;
				       
				       W_Io.Get_Immediate(Wchar);
				       
				    when Wide_Character'Val(52) =>
				       null;--  W_Io.Put_Line(" -- F12");
				       
				       --Terminal.Proc.Full_Screen;
				       
				       W_Io.Get_Immediate(Wchar);
				       --  when Wide_Character'Val(53) =>                            
				       --     null;--  W_Io.Put_Line(" -- Maj+F1");
				       --     W_Io.Get_Immediate(Wchar);
				       --  when Wide_Character'Val(54) =>                            
				       --     null;--  W_Io.Put_Line(" -- Maj+F2");
				       --     W_Io.Get_Immediate(Wchar);
				       --  when Wide_Character'Val(56) =>                            
				       --     null;--  W_Io.Put_Line(" -- Maj+F3");
				       --     W_Io.Get_Immediate(Wchar);
				       --  when Wide_Character'Val(57) =>
				       --     null;--  W_Io.Put_Line(" -- Maj+F4");
				       --     W_Io.Get_Immediate(Wchar);							 
				    when others =>
				       null;
				 end case;
				 
			      when others =>	
				 
				 W_Io.Get_Immediate(Wchar);
				 --End_Of_Program := False;
				 
			   end case;
			   
			   
			when Wide_Character'Val(197) =>
			   W_Io.Get_Immediate(Wchar);
			when others =>
			   null;
		     end case;
		     
		  when others =>
		     
		     Terminal.Proc.Receive(Wchar);
		     
	       end case;

	    when others =>
	       null;
	 end case;
      end;
      
   end loop;

exception
   when End_Error =>
      
      Terminal.Proc.Halt;

      
end Aish ;