-- This program is the last attempt of artificial intelligency with Ada.
-- Elhoim is Copyright (C) 2023 Manuel ; 
--
--   This program is free software; you can redistribute it and/or modify
--   it under the terms of the GNU General Public License as published by
--   the Free Software Foundation; either version 2 of the License, or
--   (at your option) any later version.
--
--   This program is distributed in the hope that it will be useful,
--   but WITHOUT ANY WARRANTY; without even the implied warranty of
--   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--   GNU General Public License for more details.
--
--   You should have received a copy of the GNU General Public License
--   along with this program; if not, write to the Free Software
--   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
--
-- Date := "2023-05-03 13:14:19"
-- Version := "1.0.0b"
with ANSI_Console;
use ANSI_Console;
with Ada.Calendar.Formatting;
use Ada.Calendar.Formatting;
with Ada.Characters.Handling;
use Ada.Characters.Handling;
with Ada.Strings.Wide_Fixed;
use Ada.Strings;


package body Lib.Classe.Accounting is
   function Account_name(Line : in Wide_String) return Wide_string is
      Name : Wide_String(1..Name_Type'length) := (others => Wide_Character'Val(32));
      
      Index : Natural := Wide_Fixed.Index(Line, " "); 
      
      Next  : Natural := Wide_Fixed.Index(Line(Index+1..Line'Last), " "); 
            
   begin
      if Next /= 0 then
	 Wide_Fixed.Move(Line(next+1..Line'last), Name);
      end if;      
      return Name;
   exception
      when others =>
	 return Name;
   end Account_name;
   
      
   function Create(Win       : in Window_Type;
		   Win_Index : in out Positive;
		   Min : Saving_Account_Range := 10.0;
		   Max : Saving_Account_Range := Saving_Account_Range'Last;	 
		   Name      : in Name_Type) return Abstracted_Access is
      
      Acc : Abstracted_Access := new Saving_Account_Class;
      
   begin
      if Acc /= null then
	 Wide_Fixed.Move(Name, Acc.Name, Error, Left, ' ');
	 
	 Draw(Win, Win_Index+1, 3, Cyan, "Created : " &
		To_Wide_String(Image(Saving_Account_Class(Acc.all).Create_Date)));
	 Draw(Win, Win_Index+2, 3, Cyan, "Name    : " &
		Saving_Account_Class(Acc.all).Name);	 
	 return Acc;
      else
	 return null;
      end if;
      
   end;
   
   
   function Create(Win       : in Window_Type;
		   Win_Index : in out Positive;
		   Min : Personal_Account_Range := Personal_Account_Range'First;
		   Max : Personal_Account_Range := Personal_Account_Range'Last;
		   Name      : in Name_Type) return Abstracted_Access is
      Acc : Abstracted_Access := new Personal_Account_Class;
      
   begin
      if Acc /= null then
	 Wide_Fixed.Move(Name, Acc.Name, Error, Left, ' ');
	 
	 Draw(Win, Win_Index+1, 3, Cyan, "Created : " &
		To_Wide_String(Image(Personal_Account_Class(Acc.all).Create_Date)));
	 Draw(Win, Win_Index+2, 3, Cyan, "Name    : " &
		Personal_Account_Class(Acc.all).Name);
	 return Acc;
      else
	 return null;
      end if;
      
   end;
   
   
   function Create(Win       : in Window_Type;
		   Win_Index : in out Positive;
		   Min : Enteprise_Account_Range := Enteprise_Account_Range'First;
		   Max : Enteprise_Account_Range := Enteprise_Account_Range'Last;
		   Name      : in Name_Type) return Abstracted_Access is
      Acc : Abstracted_Access := new Enteprise_Account_Class;
      
   begin
      if Acc /= null then
	 Wide_Fixed.Move(Name, Acc.Name, Error, Left, ' ');
	 
	 Draw(Win, Win_Index+1, 3, Cyan, "Created : " &
		To_Wide_String(Image(Enteprise_Account_Class(Acc.all).Create_Date)));
	 Draw(Win, Win_Index+2, 3, Cyan, "Name    : " &
		Enteprise_Account_Class(Acc.all).Name);
	 return Acc;
      else
	 return null;
      end if;
      
      
   end;

   
   procedure Print (Object    : in Saving_Account_Class'Class;
		    Win       : in Window_Type;
		    Win_Index : in out Positive;
		    Name      : out Name_Type) is
   begin
      Draw(Win, Win_Index+1, 3, Cyan, "Index   : " &
	     To_Wide_String(Abstracted_Index'Image(Object.Index)));
      Draw(Win, Win_Index+2, 3, Cyan, "Created : "
	     & To_Wide_String(Image(Object.Create_Date)));      

      Draw(Win, Win_Index+3, 3, Cyan, "Min     : "
	     & To_Wide_String(Saving_Account_Range'Image(Object.Min)));      
      Draw(Win, Win_Index+4, 3, Cyan, "Max     : "	     
	     & To_Wide_String(Saving_Account_Range'Image(Object.Max)));      
      
      Draw(Win, Win_Index+5, 3, Cyan, "Name    : " & Object.Name);
      Win_Index := Win_Index + 5;
      
      Draw(Win, Win_Index+1, 3, Cyan, "Definition " & Object.Name);
      Win_Index := Win_Index + 1;
      for I in 1..Object.Def.Index loop
	 Draw(Win, Win_Index+1, 3, Cyan, "Attr " & To_Wide_String(Natural'Image(I)) & " : " &
		To_Wide_String(Object.Def.List(I).Names) & '=' & To_Wide_String(Object.Def.List(I).Image));
	 Win_Index := Win_Index + 1;
      end loop;
      
      
      Name := Object.Name;
   end;
   
   
   procedure Print (Object    : in Personal_Account_Class'Class;
		    Win       : in Window_Type;
		    Win_Index : in out Positive;
		    Name      : out Name_Type) is
   begin
      Draw(Win, Win_Index+1, 3, Cyan, "Index   : " &
	     To_Wide_String(Abstracted_Index'Image(Object.Index)));
      Draw(Win, Win_Index+2, 3, Cyan, "Created : "
	     & To_Wide_String(Image(Object.Create_Date)));      
      Draw(Win, Win_Index+3, 3, Cyan, "Min     : "
	     & To_Wide_String(Personal_Account_Range'Image(Object.Min)));      
      Draw(Win, Win_Index+4, 3, Cyan, "Max     : "	     
	     & To_Wide_String(Personal_Account_Range'Image(Object.Max)));      
      Draw(Win, Win_Index+5, 3, Cyan, "Name    : " & Object.Name);
      Win_Index := Win_Index + 5;
      
      Draw(Win, Win_Index+1, 3, Cyan, "Definition " & Object.Name);
      Win_Index := Win_Index + 1;
      for I in 1..Object.Def.Index loop
	 Draw(Win, Win_Index+1, 3, Cyan, "Attr " & To_Wide_String(Natural'Image(I)) & " : " &
		To_Wide_String(Object.Def.List(I).Names) & '=' & To_Wide_String(Object.Def.List(I).Image));
	 Win_Index := Win_Index + 1;
      end loop;
      
      
      Name := Object.Name;
   end;
   
   procedure Print (Object    : in Enteprise_Account_Class'Class;
		    Win       : in Window_Type;
		    Win_Index : in out Positive;
		    Name      : out Name_Type) is
   begin
      Draw(Win, Win_Index+1, 3, Cyan, "Index   : " &
	     To_Wide_String(Abstracted_Index'Image(Object.Index)));
      Draw(Win, Win_Index+2, 3, Cyan, "Created : "
	     & To_Wide_String(Image(Object.Create_Date)));      
      Draw(Win, Win_Index+3, 3, Cyan, "Min     : "
	     & To_Wide_String(Enteprise_Account_Range'Image(Object.Min)));      
      Draw(Win, Win_Index+4, 3, Cyan, "Max     : "	     
	     & To_Wide_String(Enteprise_Account_Range'Image(Object.Max)));      
      Draw(Win, Win_Index+5, 3, Cyan, "Name    : " & Object.Name);
      Win_Index := Win_Index + 5;
      
      Draw(Win, Win_Index+1, 3, Cyan, "Definition " & Object.Name);
      Win_Index := Win_Index + 1;
      for I in 1..Object.Def.Index loop
	 Draw(Win, Win_Index+1, 3, Cyan, "Attr " & To_Wide_String(Natural'Image(I)) & " : " &
		To_Wide_String(Object.Def.List(I).Names) & '=' & To_Wide_String(Object.Def.List(I).Image));
	 Win_Index := Win_Index + 1;
      end loop;
      
      
      Name := Object.Name;
   end;
   
   procedure Help(Account    : in out Saving_Account_Class'Class;
		  Win       : in Window_Type;
		  Win_Index : in out Positive;
		  Name      : out Name_Type) is
   begin
      Draw(Win, Win_Index+1, 3, Red, "create Account : help");
      Draw(Win, Win_Index+2, 3, Cyan, "Min : " & To_Wide_String(Saving_Account_range'Image(Saving_Account_Range'first)));
      Draw(Win, Win_Index+3, 3, Cyan, "Max : " & To_Wide_String(Saving_Account_range'Image(Saving_Account_Range'Last)));      
      
      Draw(Win, Win_Index+4, 3, Cyan,
	   "Name is string.");
      Draw(Win, Win_Index+5, 3, Cyan,
	   "create Saved_Ac NAME");
      Win_Index := Win_Index + 7;
      Wide_Fixed.Move("help", Name, Error, Left, ' ');
      
   end;            
   
   procedure Help(Account    : in out Personal_Account_Class'Class;
		  Win       : in Window_Type;
		  Win_Index : in out Positive;
		  Name      : out Name_Type) is
   begin
      Draw(Win, Win_Index+1, 3, Red, "create Account : help");
      Draw(Win, Win_Index+2, 3, Cyan, "Min : " & To_Wide_String(Saving_Account_range'Image(Saving_Account_Range'first)));
      Draw(Win, Win_Index+3, 3, Cyan, "Max : " & To_Wide_String(Saving_Account_range'Image(Saving_Account_Range'Last)));      
      
      Draw(Win, Win_Index+4, 3, Cyan,
	   "Name is string.");
      Draw(Win, Win_Index+5, 3, Cyan,
	   "create Perso_Ac NAME");
      Win_Index := Win_Index + 7;
      Wide_Fixed.Move("help", Name, Error, Left, ' ');

   end;            
   
   procedure Help(Account    : in out Enteprise_Account_Class'Class;
		  Win       : in Window_Type;
		  Win_Index : in out Positive;
		  Name      : out Name_Type) is
   begin
      Draw(Win, Win_Index+1, 3, Red, "create Account : help");
      Draw(Win, Win_Index+2, 3, Cyan, "Min : " & To_Wide_String(Saving_Account_range'Image(Saving_Account_Range'first)));
      Draw(Win, Win_Index+3, 3, Cyan, "Max : " & To_Wide_String(Saving_Account_range'Image(Saving_Account_Range'Last)));      
      
      Draw(Win, Win_Index+4, 3, Cyan,
	   "Name is string.");
      Draw(Win, Win_Index+5, 3, Cyan,
	   "create Entep_Ac min max NAME");
      Win_Index := Win_Index + 7;
      Wide_Fixed.Move("help", Name, Error, Left, ' ');
   end;
   
   
   
   procedure Write (O : in Saving_Account_Class;File : in W_Io.File_Type) is
   begin
      W_Io.Put_Line(File, To_Wide_String(Tag_Name'Image(Abstracted_Class(O).Tag)));
      W_Io.Put_Line(File, To_Wide_String(Abstracted_Index'Image(O.Index)));
      W_Io.Put_Line(File, To_Wide_String(Image(O.Create_Date)));      
      W_Io.Put_Line(File, O.Name);
   end;
   
   procedure Read (O : in out Saving_Account_Class;File : in W_Io.File_Type) is
      
      Name_Last : Natural := 0;
   begin
      
      
      declare
	 Empty_1 : Wide_String := W_Io.Get_Line(File);

      begin
	 
	 null;
      end;

      
      O.Index := Integer'Value(To_String(W_Io.Get_Line(File)));

      O.Create_Date := Value(To_String(W_Io.Get_Line(File)));            
      
      W_Io.Get_Line(File, O.Name, Name_last);            
      
   end;
      
   procedure Write (O : in Personal_Account_Class;File : in W_Io.File_Type) is
   begin
      W_Io.Put_Line(File, To_Wide_String(Tag_Name'Image(Abstracted_Class(O).Tag)));
      W_Io.Put_Line(File, To_Wide_String(Abstracted_Index'Image(O.Index)));
      W_Io.Put_Line(File, To_Wide_String(Image(O.Create_Date)));      
      W_Io.Put_Line(File, O.Name);
   end;
   procedure Read (O : in out Personal_Account_Class;File : in W_Io.File_Type) is
      
      Name_Last : Natural := 0;
   begin
      
      declare
	 Empty_1 : Wide_String := W_Io.Get_Line(File);

      begin
	 
	 null;
      end;

      
      O.Index := Integer'Value(To_String(W_Io.Get_Line(File)));

      O.Create_Date := Value(To_String(W_Io.Get_Line(File)));            
      
      W_Io.Get_Line(File, O.Name, Name_last);            
      
   end;
   
   procedure Write (O : in Enteprise_Account_Class;File : in W_Io.File_Type) is
   begin
      W_Io.Put_Line(File, To_Wide_String(Tag_Name'Image(Abstracted_Class(O).Tag)));
      W_Io.Put_Line(File, To_Wide_String(Abstracted_Index'Image(O.Index)));
      W_Io.Put_Line(File, To_Wide_String(Image(O.Create_Date)));      
      W_Io.Put_Line(File, O.Name);
   end;
   
   procedure Read (O : in out Enteprise_Account_Class;File : in W_Io.File_Type) is
      
      Name_Last : Natural := 0;
   begin
      
      
      declare
	 Empty_1 : Wide_String := W_Io.Get_Line(File);

      begin
	 
	 null;
      end;

      
      O.Index := Integer'Value(To_String(W_Io.Get_Line(File)));

      O.Create_Date := Value(To_String(W_Io.Get_Line(File)));            
      
      W_Io.Get_Line(File, O.Name, Name_last);            
      
   end;
   
   
   procedure Random (O : in out Saving_Account_Class) is
   begin
      null;
   end Random;
   
   procedure Random (O : in out Personal_Account_Class) is
   begin
      null;
   end Random;
   
   procedure Random (O : in out Enteprise_Account_Class) is
   begin
      null;
   end Random;
   
end Lib.Classe.Accounting ;