-- Skywalker is another attempt of A. i. written with Ada.
-- Skywalker is Copyright (C) 2024 Manuel De Girardi ; 
--
--   This program is free software; you can redistribute it and/or modify
--   it under the terms of the GNU General Public License as published by
--   the Free Software Foundation; either version 2 of the License, or
--   (at your option) any later version.
--
--   This program is distributed in the hope that it will be useful,
--   but WITHOUT ANY WARRANTY; without even the implied warranty of
--   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--   GNU General Public License for more details.
--
--   You should have received a copy of the GNU General Public License
--   along with this program; if not, write to the Free Software
--   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
--
-- Date := 2024-11-17 09:31:39 ; 
-- Version := 0.2.0r ; 
with Sky ; 
use Sky;
with Sky.Walk;

with Gnat.Os_Lib;
use Gnat.Os_Lib;

with Gnat.Directory_Operations;
use Gnat.Directory_Operations;

with Sky.Project;
use Sky.Project;
with Sky.Projects_Manager;

with Text_Io;

with Sky.Ansi.Windows;

with Sky.Windows;

with Sky.Parameters;
with Sky.Interfaces;
use Sky.Parameters;
use Sky.Interfaces;

with Sky.Shared;
use Sky.Shared;

with Sky.Versions;
with Sky.Versions.Version_Io;
with Ada.Characters.Handling;
use Ada.Characters;

with Sky.Balance;
with Sky.Accountant;
use Sky.Accountant;
with Sky.Stocks_Manager;
use Sky.Stocks_Manager;
with Sky.Logs;
procedure Skywalker is
   
   Lines : Line_Range := 67;
   Columns : Column_Range := 240;
   
   use Projects_Manager.Projects_Dll;

   Errno : Integer := 0;
   
   

   End_Of_Program : Boolean := False;
   
   
   Mode : Mode_Enum := None;
   
   Int : Interface_Record;
   
   The_Style : Style_Enum := Color_And_Color;
   
begin
   
   Initialize(Int);
   
   declare
      Help_Parameter : constant Parameters.Parameter_Record :=
	Get_Parameter(Int, Help);
      Version_Parameter : constant Parameters.Parameter_Record :=
	Get_Parameter(Int, sky.Version);
      
      Initialize_Parameter : constant Parameters.Parameter_Record :=
	Get_Parameter(Int, Initialize);
      
      Geometry_Parameter : constant Parameters.Parameter_Record :=
      	Get_Parameter(Int, Geometry);
      
      Style_Parameter : constant Parameters.Parameter_Record :=
      	Get_Parameter(Int, Style);
      
      Total_Parameter : constant Parameters.Parameter_Record :=
	Get_Parameter(Int, Total);
   begin
      

      if Help_Parameter.Is_Setted then
	 Interfaces.Parameters_Descriptions(Int);
	 
	 return;
      else
	 if Version_Parameter.Is_Setted then
	    Text_Io.Put_Line(Versions.Version_Io.To_String(Versions.Version));
	    return;
	 end if;	    
      end if;

      --Interfaces.Print_Parameters(Interf);
      
      if Initialize_Parameter.Is_Setted then
	 Total_Sum := Total_Type'Value(Handling.To_String(Initialize_Parameter.Value.all));
	 
	 return;
      end if;


      if Total_Parameter.Is_Setted then
	 Text_Io.Put_Line(Total_Type'Image(Total_Sum));
	 
	 return;
      end if;
      
      if Geometry_Parameter.Is_Setted then
	 Lines := Lines_Number(Geometry_Parameter.Value.all);
	 Columns := Columns_Number(Geometry_Parameter.Value.all);
      end if;
      
      if Style_Parameter.Is_Setted then
	 begin
	    The_style := Style_Enum'value(Handling.To_String(Style_Parameter.Value.all));
	 exception
	    when others =>
	       Text_Io.Put_Line("Style error : not an style");
	       raise;
	 end;
      end if;
      
      
      
      
   end;
   declare
      package Ansi_Windows is new Sky.Ansi.Windows (Lines, Columns);
      package Windows is new Sky.Windows (Lines, Columns, The_Style, Ansi_Windows);
      
      package My_Walker is new Sky.Walk(Windows);
      use My_Walker;
      
      
   begin
      
      App.Lines := Lines;
      App.Columns := Columns;
      
      begin
	 App.Term := Term_Enum'Value(Getenv("TERM").all);
      exception
	 when Constraint_Error =>	 
	    App.Term := Xterm;
      end;
      
      Machines := (0 => new None_Record(App'Access),
		  1 => new Organizer_Record(App'Access),
		  2 => new Editor_Record(App'Access),
		  3 => new Planning_Record(App'Access),
		  4 => new Manager_Record(App'Access),
		  5 => new Moneybox_Record(App'Access),
		  6 => new Activity_Record(App'Access),
		  7 => new Stocks_Record(App'Access),
		  8 => new Bank_Record(App'Access),
		  9 => new Log_Record(App'Access),
		  10 => new Menu_Record(App'Access),
		  11 => new Contacts_Record(App'Access),
		  12 => new Library_Record(App'Access), others => null);
      
   
      begin
	 Make_Dir("Archives");
      exception
	 when others =>
	    begin
	       Change_Dir("Archives");
	       Change_Dir("..");
	    exception
	       when others =>
		  raise Spec_Error;
	    end;
	    
      end;
      
      if Is_Regular_File(Organizer_Filename) then
	 Restore(App.Terminal, Organizer_Filename);
      end if;
      
      
      if Balance.Initialized or (Balance.Balance.Capital > 0.0) then
	 App.Initialized := True;
      end if;
      --Text_Io.Put_Line("initialized");
      if Is_Regular_File("billed.txt") then
	 Invoices_Restore(Accounts.Billed, Accounts.Invoice_Last, "billed.txt");
      end if;
      if Is_Regular_File("charged.txt") then
	 Outvoices_Restore(Accounts.Charges, Accounts.Outvoice_Last, "charged.txt");
      end if;
      
      
      begin
	 Make_Dir("Archives");
      exception
	 when others =>
	    begin
	       Change_Dir("Archives");
	       Change_Dir("..");
	    exception
	       when others =>
		  raise Spec_Error;
	    end;
		  
      end;
      Text_Io.Put("Loading stocks...");
      Stocks_Restore;
      Text_Io.Put("Done.");
      
      if Is_Regular_File("Projects.lst") then
	 Projects_Manager.Manager_Load(App.Projects, "Projects.lst");
      end if;
      if Is_Regular_File("Archives/Projects.lst") then
	 Projects_Manager.Archives_Load(App.Archives, "Archives/Projects.lst");      
      end if;
      
      ------------------------------------------------
      --  Logs
      if Is_Regular_File(Sky.Logs.Log_Filename) then
	 Sky.Logs.Restore(App.logs, Sky.Logs.Log_Filename);
      end if;
      
      
      
      
      Append(App.Projects.List, new Project_Record ' (Null_Project));
      
      Cpu_Process.Initialize;
      
      App.Console.Initialize;

      App.Console.Switch(None);

      
      loop
	 
	 declare
	    Wchar : Wide_Character := ' ';
	 begin
	    
	    case App.Term is
	       when Linux =>

		  begin
		     App.Console.Mode(Mode);
		     W_Io.Get_Immediate(Wchar);
		     --Matrix_Saver.Suspend;
		     case Wchar is
			when Wide_Character'Val(27) =>                                       
			   App.Console.Set_On_Esc(True);
			   W_Io.Get_Immediate(Wchar);         
			   case Wchar is
			      when Wide_Character'Val(27) =>                             
				 
				 
				 case Mode is                                                            
				    when Organizer .. Log =>
				       
				       App.Console.Reset;      

				    when None =>
				       
				       App.Console.Set_On_Esc(False);

				       App.Console.Switch(Quit);  


				       End_Of_Program := True;
				       
				       
				    when Menu =>
				       
				       App.Console.Set_On_Esc(False);
				       Errno := System("clear" & Character'Val(0));
				       App.Console.Switch(none);


				       End_Of_Program := True;
				       
				       
				    when others =>
				       if End_Of_Program then         
					  
					  --App.Console.Switch(Quit);

					  App.Console.Halt;

					  exit;
				       end if;
				 end case;                          
			      when others =>
				 App.Console.Mode(Mode);
				 case Mode is
				    
				    when Quit =>
				       if End_Of_Program then         
					  
					  --App.Console.Switch(Quit);

					  App.Console.Halt;

					  exit;
				       end if;
				       
				    when others =>
				       
				       App.Console.Set_On_Esc(False);
				       
				       --App.Console.Switch(mode);
				       End_Of_Program := False;

				 end case;
			   end case;                     
			   
			   case Wchar is
			      when Wide_Character'Val(91) =>                           
				 W_Io.Get_Immediate(Wchar);                           
				 App.Console.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;--  Text_Io.Put_Line(" -- F6");
					     App.Console.Switch(Activity);
					     W_Io.Get_Immediate(Wchar);                  
					  when Wide_Character'Val(56) =>
					     null;--  Text_Io.Put_Line(" -- F7");
					     App.Console.Switch(Stocks);
					     W_Io.Get_Immediate(Wchar);                  
					  when Wide_Character'Val(57) =>
					     null;--  Text_Io.Put_Line(" -- F8");
					     App.Console.Switch(Bank);
					     W_Io.Get_Immediate(Wchar);                  
					  when Wide_Character'Val(126) =>                     
					     null;--  Text_Io.Put_Line(" -- begin");
					     App.Console.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;--  Text_Io.Put_Line(" -- F9");
					     App.Console.Switch(Log);
					     W_Io.Get_Immediate(Wchar);
					  when Wide_Character'Val(49) =>
					     null;--  Text_Io.Put_Line(" -- F10");
					     App.Console.Switch(Menu);

					     W_Io.Get_Immediate(Wchar);                                       
					  when Wide_Character'Val(51) =>                                  
					     null;--  Text_Io.Put_Line(" -- F11");
					     App.Console.Switch(Contacts);
					     W_Io.Get_Immediate(Wchar);
					  when Wide_Character'Val(52) =>
					     null;--  Text_Io.Put_Line(" -- F12");
					     App.Console.Switch(Library);
					     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;--  Text_Io.Put_Line(" -- insert");                                
					  when others =>
					     null;                             
				       end case;                               
				    when Wide_Character'Val(51) =>                    
				       null;--  Text_Io.Put_Line(" -- del");                     
				       W_Io.Get_Immediate(Wchar);   
				    when Wide_Character'Val(52) =>                    
				       null;--  Text_Io.Put_Line(" -- end");                     
				       W_Io.Get_Immediate(Wchar);   
				       App.Console.End_Of;
				    when Wide_Character'Val(53) =>
				       null;--  Text_Io.Put_Line(" -- page up");
				       App.Console.Page_Up;
				       W_Io.Get_Immediate(Wchar);   
				    when Wide_Character'Val(54) =>
				       null;--  Text_Io.Put_Line(" -- page down");
				       App.Console.Page_Down;
				       W_Io.Get_Immediate(Wchar);   
				    when Wide_Character'Val(65) =>
				       null;--  Text_Io.Put_Line(" -- up");
				       App.Console.Up_Arrow;
				    when Wide_Character'Val(66) =>
				       null;--  Text_Io.Put_Line(" -- down");
				       App.Console.Down_Arrow;
				    when Wide_Character'Val(67) =>
				       null;--  Text_Io.Put_Line(" -- right");
				       App.Console.Right_Arrow;
				    when Wide_Character'Val(68) =>
				       null;--  Text_Io.Put_Line(" -- left");
				       App.Console.Left_Arrow;
				    when Wide_Character'Val(91) =>
				       W_Io.Get_Immediate(Wchar);                
				       case Wchar is                               
					  when Wide_Character'Val(65) =>
					     null;--  Text_Io.Put_Line(" -- F1");                                 
					     App.Console.Switch(Organizer);
					  when Wide_Character'Val(66) =>
					     null;--  Text_Io.Put_Line(" -- F2");
					     App.Console.Switch(Editor  );
					  when Wide_Character'Val(67) =>
					     null;--  Text_Io.Put_Line(" -- F3");                                 
					     App.Console.Switch(Planning);
					  when Wide_Character'Val(68) =>
					     null;--  Text_Io.Put_Line(" -- F4");
					     App.Console.Switch(Manager);
					  when Wide_Character'Val(69) =>
					     null;--  Text_Io.Put_Line(" -- F5");
					     App.Console.Switch(Moneybox);
					     
					  when others =>
					     null;
				       end case;
				       
				    when others =>
				       
				       App.Console.Reset;            
				       
				       End_Of_Program := False;

				       App.Console.Receive(Wchar);
				       
				 end case;

			      when others =>

				 App.Console.Set_On_Esc(False);

			   end case;                                       
			   
			when others =>                    
			   case Mode is
			      when Quit =>

				 App.Console.Switch(none);

			      when others =>
				 null;
			   end case;

			   App.Console.Set_On_Esc(False);

			   
			   End_Of_Program := False;
			   
			   App.Console.Receive(Wchar);

		     end case;
		     
		  exception
		     
		     
		     
		     when W_Io.End_Error =>
			

			--Bell(Quiet);
			delay 0.5;                   
			App.Console.reset;

		  end;

	       when Xterm =>
		  
		  begin
		     App.Console.Mode(Mode);
		     W_Io.Get_Immediate(Wchar);
		     --Matrix_Saver.Suspend;
		     case Wchar is
			when Wide_Character'Val(27) =>                                       
			   App.Console.Set_On_Esc(True);
			   W_Io.Get_Immediate(Wchar);         
			   case Wchar is
			      when Wide_Character'Val(27) =>				    

				 case Mode is                                                            
				    when Organizer .. Log =>
				       App.Console.Reset;                                 
				    when None =>

				       App.Console.Set_On_Esc(False);                                 
				       App.Console.Switch(Quit);                                 
				       End_Of_Program := True;
				    when Menu =>
				       
				       App.Console.Set_On_Esc(False);
				       Errno := System("clear" & Character'Val(0));
				       App.Console.Switch(none);


				       End_Of_Program := True;
				       
				       --when Shell =>
				       --   null;
				    when others =>
				       if End_Of_Program then         
					  
					  --App.Console.Switch(Quit);
					  App.Console.Halt;
					  exit;
				       end if;
				 end case;                          
			      when others =>
			         App.Console.Mode(Mode);
				 case Mode is
				    
				    when Quit =>
				       if End_Of_Program then         
					  
					  --App.Console.Switch(Quit);

					  App.Console.Halt;

					  exit;
				       end if;
				       
				    when others =>
				       
				       App.Console.Set_On_Esc(False);
				       
				       --App.Console.Switch(mode);
				       End_Of_Program := False;

				 end case;
				 
			   end case;                     
			   
			   case Wchar is
			      when Wide_Character'Val(79) =>                           
				 
				 W_Io.Get_Immediate(Wchar);
				 App.Console.Set_On_Esc(False);
				 case Wchar is
				    when Wide_Character'Val(80) =>
				       null;--  Text_Io.Put_Line(" -- F1");                               
				       App.Console.Switch(Organizer);
				    when Wide_Character'Val(81) =>
				       null;--  Text_Io.Put_Line(" -- F2");
				       App.Console.Switch(Editor);
				    when Wide_Character'Val(82) =>
				       null;--  Text_Io.Put_Line(" -- F3");                               
				       App.Console.Switch(Planning);
				    when Wide_Character'Val(83) =>
				       null;--  Text_Io.Put_Line(" -- F4");
				       App.Console.Switch(Manager);

				    when others =>
				       null;
				 end case;
				 
			      when Wide_Character'Val(91) =>

				 App.Console.Set_On_Esc(False);
				 W_Io.Get_Immediate(Wchar);              
				 case Wchar is
				    when Wide_Character'Val(49) =>
				       W_Io.Get_Immediate(Wchar);
				       case Wchar is
					  when Wide_Character'Val(53) =>
					     null;--  Text_Io.Put_Line(" -- F5");                                                                    
					     App.Console.Switch(Moneybox);
					  when Wide_Character'Val(55) =>
					     null;--  Text_Io.Put_Line(" -- F6");
					     App.Console.Switch(Activity);
					  when Wide_Character'Val(56) =>
					     null;--  Text_Io.Put_Line(" -- F7");
					     App.Console.Switch(Stocks);
					  when Wide_Character'Val(57) =>
					     null;--  Text_Io.Put_Line(" -- F8");
					     App.Console.Switch(Bank);
					  when others =>
					     null;
				       end case;
				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(50) =>
				       W_Io.Get_Immediate(Wchar);
				       case Wchar is
					  when Wide_Character'Val(48) =>       
					     null;--  Text_Io.Put_Line(" -- F9");
					     App.Console.Switch(Log);

					     W_Io.Get_Immediate(Wchar);
					  when Wide_Character'Val(49) =>
					     null;--  Text_Io.Put_Line(" -- F10");
					     App.Console.Switch(Menu);

					     W_Io.Get_Immediate(Wchar);
					  when Wide_Character'Val(51) =>
					     null;--  Text_Io.Put_Line(" -- F11");
					     App.Console.Switch(Contacts);
					     W_Io.Get_Immediate(Wchar);
					  when Wide_Character'Val(52) =>
					     --null;Text_Io.Put_Line(" -- F12");
					     App.Console.Switch(Library);
					     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;--  Text_Io.Put_Line(" -- insert");
					     
					  when others =>
					     null;                             
				       end case;                               
				       
				    when Wide_Character'Val(51) =>                    
				       null;--  Text_Io.Put_Line(" -- del");                           
				       W_Io.Get_Immediate(Wchar);                            
				    when Wide_Character'Val(53) =>
				       null;--  Text_Io.Put_Line(" -- page up");
				       App.Console.Page_Up;
				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(54) =>
				       null;--  Text_Io.Put_Line(" -- page down");
				       App.Console.Page_Down;
				       W_Io.Get_Immediate(Wchar);
				    when Wide_Character'Val(65) =>
				       null;--  Text_Io.Put_Line(" -- up");
				       App.Console.Up_Arrow;
				    when Wide_Character'Val(66) =>
				       null;--  Text_Io.Put_Line(" -- down");
				       App.Console.Down_Arrow;
				    when Wide_Character'Val(67) =>
				       null;--  Text_Io.Put_Line(" -- right");
				       App.Console.Right_Arrow;
				    when Wide_Character'Val(68) =>                          
				       null;--  Text_Io.Put_Line(" -- left");
				       App.Console.Left_Arrow;
				    when Wide_Character'Val(70) =>
				       null;--  Text_Io.Put_Line(" -- end");
				       App.Console.End_Of;
				    when Wide_Character'Val(72) =>
				       null;--  Text_Io.Put_Line(" -- begin");                                                              
				       App.Console.Begin_Of;
				    when Wide_Character'Val(91) =>
				       W_Io.Get_Immediate(Wchar);                
				       case Wchar is                               
					  when Wide_Character'Val(69) =>
					     
					     -- screen print ?
					     
					     W_Io.Get_Immediate(Wchar);                  
					  when others =>
					     null;
				       end case;
				       
				    when others =>
				       
				       App.Console.Reset;            
				       
				       End_Of_Program := False;

				       App.Console.Receive(Wchar);
				       
				 end case;

			      when others =>


				 App.Console.Set_On_Esc(False);



				 
			   end case;                                       

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

		  exception
		     
		     -- A la saisie de Ctrl+D End Error is raised.
		     
		     when W_Io.End_Error =>
			
			--Bell(Quiet);
			delay 0.5;                   
			App.Console.reset;
			
		  end;            
	    end case;
	 end;
	 
      end loop;
      
      Projects_Manager.Manager_Save(App.Projects, "Projects.lst");
      Projects_Manager.Archives_Save(App.Archives, "Archives/Projects.lst");
      Stocks_Save;
      Sky.Logs.save(App.logs, Sky.Logs.Log_Filename);
      --W_Io.Put_Line("Halting CPU process...");
      Cpu_Process.Halt;
      --W_Io.Put_Line("CPU process halted.");
   exception
      when W_Io.End_Error =>
	 Cpu_Process.Halt;
   end;
end Skywalker ;