-- 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-13 06:51:20"
-- Version := "0.0.10r"
with Ada.Calendar;
use Ada.Calendar;
with Sky.Balance;
use Sky.Balance;
package Sky.Accountant is
   subtype Account_Line_range is Natural range Natural'First..Natural'Last;
   
   
   
   type Account_Line_Type is
      record
	 Line_Num      : Account_Line_Range := 0;
	 Date          : Time := Clock;
	 Elaps         : Time := Clock;
	 Description   : Wstring_32 := (others => ' ');
	 Account_num   : Account_Num_Range := 10;
	 Unit_Ht_Price : Fixed_Unit_Ht := 0.0;	 
	 TVA_Rate    : Fixed_Factor := 0.0;
	 Quantity      : Quantity_Range := 0.0;
	 Total_Ht      : Fixed_Total := 0.0;
	 Total_TVA     : Fixed_Total := 0.0;
	 Total_Ttc     : Fixed_Total := 0.0;
	 Delays        : Payment_Delay := 0;
	 Peer_name     : Wstring_32 := (others => ' ');	 
      end record;
   
   type Abstracted_Voice(Lines_Max : Account_Line_Range);
   
   
   
   
   
   Null_Line : constant Account_Line_Type :=
     (0,
      Time_Of(1970, 01, 01, 0.0),
      Time_Of(1970, 01, 01, 0.0),
      (others => Wide_Character'Val(32)),
      10,
      0.0,
      0.0,
      0.0,
      0.0,
      0.0,
      0.0,
      0,
      (others => Wide_Character'Val(32))
     );
   
   
   type Account_Line_Array is array (Account_Line_Range range <>) of Account_Line_Type;
   
   
   type Abstracted_Voice(Lines_Max : Account_Line_Range) is tagged
      record
	 Accounting     : Account_Line_Array(1..Lines_Max) := (others => Null_Line);	 
	 Line_Last      : Account_Line_Range := 0;
	 Account_Num    : Account_Num_Range := 10;
	 Voice_Num      : Voice_Num_Range := 0;
	 Total_Ht       : Fixed_Total := 0.0;
	 Total_TVA      : Fixed_Total := 0.0;
	 Total_TTC      : Fixed_Total := 0.0;
	 Peer_Name      : Wstring_32 := (others => ' ');
	 Date           : Time := Time_Of(1970, 1, 1, 0.0);
	 Line_Count     : Account_Line_Range := 0;
      end record;
   
   procedure Line_Add (To : in out Abstracted_Voice;
		       Line : in Account_Line_Type);
   procedure Line_Remove (To : in out Abstracted_Voice;
			  Line_Num : in Account_Line_Range);
   
   
   function Save(voice : in Abstracted_Voice'Class; File_Name : in String) return Boolean is abstract;
   function Is_Payed(voice : in Abstracted_Voice'Class) return Boolean is abstract;
   
   
   
   
   
   type Invoice_record is new Abstracted_Voice(256) with null record;
   function Save(voice : in Invoice_Record; Filename : in String) return Boolean;
   
   
   type Outvoice_Record is new Abstracted_Voice(256) with null record;
   function Save(voice : in Outvoice_Record; Filename : in String) return Boolean;   
   
   type Invoice_Array is array (Voice_Num_Range range <>) of Invoice_Record;
   type Outvoice_Array is array (Voice_Num_Range range <>) of Outvoice_Record;
     
   type Accounting_Record(Deal_Max : Positive) is
      record
	 Billed  : Invoice_Array(1..Deal_Max);
	 Invoice_Last : Natural := 0;
	 Charges : outvoice_Array(1..Deal_Max);
	 Outvoice_Last : Natural := 0;
      end record;
   
   
   procedure Add(To : in out Accounting_Record;
		 Invoice : in Invoice_Record);
   procedure Add(To : in out Accounting_Record;
		 Outvoice : in Outvoice_Record);
   
   procedure Invoice_Remove(To : in out Accounting_Record;
			    Invoice_num : in Voice_Num_Range);
   procedure Outvoice_Remove(To : in out Accounting_Record;
			    Outvoice_num : in Voice_Num_range);
   
   
   function Is_Payed(voice : in Invoice_Record'Class) return Boolean;
   
   function Is_Payed(voice : in Outvoice_Record'Class) return Boolean;
   
   procedure Create(Activity : out Balance_Record;
		    From : in Outvoice_Record);
   -- Write all account_line to States.
   -- Check Outvoice with accounting.
   
   procedure billed(Activity : in out Balance_Record;
		    Invoice : in Invoice_Record;
		    
		    Payed : out Boolean);
   -- if Is_Payed(Invoice) then must be added to to account num
   
   procedure Charge(Activity : in out Balance_Record;
		    Outvoice : in Outvoice_Record;

		    Payed : out Boolean);
   -- if Is_Payed(Outvoice) then must be added to to account num
   
   
   Null_Invoice : constant Invoice_Record :=
     (256,
      (others => Null_Line),
      0,
      607,      
      0,      
      0.0,
      0.0,
      0.0,
      (others => ' '),      
      Time_Of(1970, 1, 1, 0.0),
      0
     );
   
   Null_Outvoice : constant Outvoice_Record :=
     (256, (others => Null_Line),
      0,
      707,
      0,
      0.0,
      0.0,
      0.0,
      (others => ' '),
      Time_Of(1970, 1, 1, 0.0),
      0
      );
   
   
   
   
   procedure Open(Activity : in out Balance_Record;
		  Accounting_States : in Accounting_Record);
   
   procedure Close(Activity : in out Balance_Record;
		   Accounting_States : in Accounting_Record);
   
   
   procedure Invoices_Restore(Invoices : out Invoice_Array; Last : out Natural; Filename : in String);
   procedure OutVoices_Restore(Outvoices : out Outvoice_Array; Last : out Natural; Filename : in String);
   
   
   Accounts        : Accounting_Record(8092);

end Sky.Accountant ;