-- elhoim is full object organizer with editor and command interpreter.
-- Elhoim is Copyright (C) 2023 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 := "2023-05-26 17:40:38"
-- Version := "0.6.6b"
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;

with El.Outils;



package body El.Classe.Deallines_class is
   
   use Outils;
   
   function denom_Value(Line : in Wide_String) return Wstring_16 is
      Description : Wstring_16 := (others => Wide_Character'Val(32));
      
      Index : Natural := Wide_Fixed.Index(Line, " "); 
      
      Next  : Natural := Wide_Fixed.Index(Line(Index+1..Line'Last), " "); 
      
      Last  : Natural := Wide_Fixed.Index(Line(Next+1..Line'Last), " ");
      
      Last_2 : Natural := Wide_Fixed.Index(Line(Last+1..Line'Last), """");
      Last_3 : Natural := Wide_Fixed.Index(Line(Last_2+1..Line'Last), """");
      
   begin
      if Next /= 0 then
	 Wide_Fixed.Move(Line(Last_2+1..Last_3-1), Description);
      end if;      
      return Description;
   exception
      when others =>
	 return Description;
   end Denom_Value;
   
   
   function Acc_name_Value(Line : in Wide_String) return Name_type is
      Name : Name_type := (others => Wide_Character'Val(32));
      
      Index : Natural := Wide_Fixed.Index(Line, " "); 
      
      Next  : Natural := Wide_Fixed.Index(Line(Index+1..Line'Last), " "); 
      
      Last  : Natural := Wide_Fixed.Index(Line(Next+1..Line'Last), " ");
            
   begin
      if Next /= 0 then
	 Wide_Fixed.Move(Line(next+1..Last-1), name);
      end if;      
      return name;
   exception
      when others =>
	 return name;
   end Acc_name_Value;
   
   
   function Peer_name(Line : in Wide_String) return Wstring_48 is
      Peer: Wstring_48 := (others => Wide_Character'Val(32));
      
      
      Last_2 : Natural := Wide_Fixed.Index(Line, """", backward);
      Last_3 : Natural := Wide_Fixed.Index(Line(Line'first..Last_2-1), """", backward);
      
   begin
      if Last_3 /= 0 then
	 Wide_Fixed.Move(Line(Last_3+1..Last_2-1), Peer);
      end if;      
      return Peer;
   exception
      when others =>
	 return Peer;
   end Peer_name;
   
   
   function Account_num_value(Line : in Wide_String) return Account_Num_range is
      Acc_Num : Account_Num_range := 10;
      
      Index : Natural := Wide_Fixed.Index(Line, """"); 
      
      Next  : Natural := Wide_Fixed.Index(Line(Index+1..Line'Last), """"); 
      
      Last  : Natural := Wide_Fixed.Index(Line(Next+1..Line'Last), " ");
      
      Last_2 : Natural := Wide_Fixed.Index(Line(Last+1..Line'Last), " ");
      
      
   begin
      if Last_2 /= 0 then
	 Acc_Num := Account_Num_Range'Value(To_String(Line(Last+1..Last_2-1)));
      end if;      
      return Acc_num;
   exception
      when others =>
	 return Acc_num;
   end Account_Num_value;
   
      
   
   function quantity_value(Line : in Wide_String) return quantity_range is
      Acc_Num : quantity_range := 1;
      
      Index : Natural := Wide_Fixed.Index(Line, """"); 
      
      Next  : Natural := Wide_Fixed.Index(Line(Index+1..Line'Last), """"); 
      
      Last  : Natural := Wide_Fixed.Index(Line(Next+1..Line'Last), " ");
      
      Last_2 : Natural := Wide_Fixed.Index(Line(Last+1..Line'Last), " ");
      Last_3 : Natural := Wide_Fixed.Index(Line(Last_2+1..Line'Last), " ");
      Last_4 : Natural := Wide_Fixed.Index(Line(Last_3+1..Line'Last), " ");
      Last_5 : Natural := Wide_Fixed.Index(Line(Last_4+1..Line'Last), " ");
   begin
      if Last_5 /= 0 then
	 Acc_Num := Account_Num_Range'Value(To_String(Line(Last_4+1..Last_5-1)));
      end if;      
      return Acc_num;
   exception
      when others =>
	 return Acc_num;
   end quantity_value;
   
   function Payment_Delays_Value(Line : in Wide_String) return Payment_delay is
      delays : Payment_delay := 0;
      
      Index : Natural := Wide_Fixed.Index(Line, """", backward); 
      
      Next  : Natural := Wide_Fixed.Index(Line(Line'First..Index-1), """", backward); 
      
      Last  : Natural := Wide_Fixed.Index(Line(Line'first..Next-2), " ", backward);
            
   begin
      if Last /= 0 then
	 delays := Payment_delay'Value(To_String(Line(Last+1..next-2)));
      end if;      
      return delays;
   exception
      when others =>
	 return delays;
   end Payment_Delays_Value;
   
   
   function U_Ht_value(Line : in Wide_String) return Fixed_Unit_ht is
      Price : Fixed_Unit_HT := 0.0;
      
      Index : Natural := Wide_Fixed.Index(Line, """"); 
      
      Next  : Natural := Wide_Fixed.Index(Line(Index+1..Line'Last), """"); 
      
      Last  : Natural := Wide_Fixed.Index(Line(Next+1..Line'Last), " ");
      
      Last_2 : Natural := Wide_Fixed.Index(Line(Last+1..Line'Last), " ");
      Last_3 : Natural := Wide_Fixed.Index(Line(Last_2+1..Line'Last), " ");
      
   begin
      if Last_2 /= 0 then
	 Price := Fixed_Unit_HT'Value(To_String(Line(Last_2+1..Last_3-1)));
      end if;      
      return Price;
   exception
      when others =>
	 return Price;
   end U_HT_value;
   
   
   function TVA_value(Line : in Wide_String) return Fixed_factor is
      Factor : Fixed_factor:= 0.0;
      
      Index : Natural := Wide_Fixed.Index(Line, """"); 
      
      Next  : Natural := Wide_Fixed.Index(Line(Index+1..Line'Last), """"); 
      
      Last  : Natural := Wide_Fixed.Index(Line(Next+1..Line'Last), " ");
      
      Last_2 : Natural := Wide_Fixed.Index(Line(Last+1..Line'Last), " ");
      Last_3 : Natural := Wide_Fixed.Index(Line(Last_2+1..Line'Last), " ");
      Last_4 : Natural := Wide_Fixed.Index(Line(Last_3+1..Line'Last), " ");
      
   begin
      if Last_4 /= 0 then
	 Factor := Fixed_factor'Value(To_String(Line(Last_3+1..Last_4-1)));
      end if;      
      return Factor;
   exception
      when others =>
	 return Factor;
   end TVA_value;
   
   
   
   procedure Account_Line_draw(Wins : in Accounting_Windows_Type'Class;
			       Index_Line : in Index_Line_Range;
			       Account_Line : in Account_Line_Type) is
      
      WStr_Date          : constant Wide_String := To_Wide_String(Formatting.Image(Account_Line.Date));
      WStr_elaps         : constant Wide_String := To_Wide_String(Formatting.Image(Account_Line.Elaps));
      Tag                : constant Wide_String := Account_Line.Description;
      WStr_Acc_num       : constant Wide_String := To_Wide_String(Account_Num_Range'Image(Account_Line.Account_Num));
      WStr_Unit_Ht_Price : constant Wide_String := To_Wide_String(Fixed_Unit_Ht'Image(Account_Line.Unit_Ht_Price));
      WStr_TVA_Factor    : constant Wide_String := To_Wide_String(Fixed_factor'Image(Account_Line.TVA_Factor));
      WStr_Quantity      : constant Wide_String := To_Wide_String(Quantity_Range'Image(Account_Line.Quantity));
      WStr_Total_Ht      : constant Wide_String := To_Wide_String(Fixed_total'Image(Account_Line.Total_ht));
      WStr_Total_TTC     : constant Wide_String := To_Wide_String(Fixed_total'Image(Account_Line.Total_TTC));
      Peer               : constant Wide_String := Account_Line.Peer_Name;
      
   begin
      Draw(Wins.Tags_Win, Index_Line, 1, White, Tag);
      Draw(Wins.Acc_num_Win, Index_Line, 1, White, Wstr_Acc_num);
      Draw(Wins.Unit_Ht_Price_Win, Index_Line, 1, White, Wstr_Unit_Ht_price);
      Draw(Wins.Tva_Factor_Win, Index_Line, 1, White, Wstr_Tva_factor);
      Draw(Wins.Qt_Win, Index_Line, 1, White, Wstr_quantity);
      Draw(Wins.Total_HT_Win, Index_Line, 1, White, Wstr_Total_Ht);
      Draw(Wins.Total_TTC_Win, Index_Line, 1, White, Wstr_Total_Ttc);
      if Cols <= 240 then
	 Draw(Wins.Peer_Win, Index_Line, 1, White, Peer(1..16));
      else
	 Draw(Wins.Peer_Win, Index_Line, 1, White, Troncate(Peer, Cols-((Cols)/2+6+96)));
      end if;
      
      
   end Account_Line_Draw;
   
   
   
   
   
   -----------------------------------------------------------------------------
   --                  Dealline                                                 --
   
   procedure Help(Dealline    : in out Deal_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 deal : help");
      Draw(Win, Win_Index+2, 3, Cyan,
	   "Tag is string.");
      Draw(Win, Win_Index+3, 3, Cyan,
	   "Account num is between 10 to 89999");
      Draw(Win, Win_Index+4, 3, Cyan,
	   "Unit HT price between 0.0 to 99_999.99");
      Draw(Win, Win_Index+5, 3, Cyan,
	   "TVA factor is between 0.0 to 49.999");
      Draw(Win, Win_Index+6, 3, Cyan,
	   "Quantity is between 1 to 100 000");      
      
      Draw(Win, Win_Index+7, 3, Cyan,
	   "Days is payment delay from -120 to 120");      
      Draw(Win, Win_Index+8, 3, Cyan,
	   "Peer is wide string lenght max 48 ");
      
      Draw(Win, Win_Index+9, 1, Cyan,
	   "Create DEAL Name ""Desc"" acc UnitHT TVA qte days ""Peer""");
      Win_Index := Win_Index + 10;
      Wide_Fixed.Move("help", Name, Error, Left, ' ');
   end Help;
   
   
   procedure Print (Object : Deal_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, "Name       : " & Object.Name);
      Draw(Win, Win_Index+3, 3, Cyan, "Created    : "
	     & To_Wide_String(Image(Object.Create_Date)));      
      
      Draw(Win, Win_Index+4, 3, Cyan, "Date opp   : "
	     & To_Wide_String(Image(Object.Line.Date)));      
      Draw(Win, Win_Index+5, 3, Cyan, "Date val   : "
	     & To_Wide_String(Image(Object.Line.Elaps)));      
      
      Draw(Win, Win_Index+6, 3, Cyan, "Tag        : " & Object.Line.Description);
      
      Draw(Win, Win_Index+7, 3, Cyan, "Acc_Num    : "
	     & To_Wide_String(Account_Num_Range'Image(Object.Line.Account_Num)));
      
      Draw(Win, Win_Index+8, 3, Cyan, "Unit ht    : "
	     & To_Wide_String(Fixed_Unit_Ht'Image(Object.Line.Unit_Ht_Price)));
      
      Draw(Win, Win_Index+9,  3, Cyan, "TVA        : "
	     & To_Wide_String(Fixed_Factor'Image(Object.Line.Tva_factor)));
      
      Draw(Win, Win_Index+10,  3, Cyan, "Quantity   : "
	     & To_Wide_String(Quantity_Range'Image(Object.Line.Quantity)));
      
      Draw(Win, Win_Index+11,  3, Cyan, "Total Ht   : "
	     & To_Wide_String(Fixed_total'Image(Object.Line.Total_ht)));
      Draw(Win, Win_Index+12,  3, Cyan, "Total TTC  : "
	     & To_Wide_String(Fixed_total'Image(Object.Line.Total_TTC)));
      
      
      
      Draw(Win, Win_Index+13,  3, Cyan, "Peer       : "
	     & Object.Line.Peer_name);
      
      Win_Index := Win_Index + 14;
      
      
      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 Print;
   
   function Create(Win       : in Window_Type;
		   Win_Index : in out Positive;
		   Name      : in Name_Type;
		   description   : in Wstring_16;
		   Account_num   : in Account_Num_Range;
		   Unit_Ht_Price : in Fixed_Unit_Ht;	 
		   TVA_Factor    : in Fixed_Factor;
		   Quantity      : in Quantity_Range;
		   Delays        : in Payment_Delay;
		   Peer_name     : in Wstring_48
		   ) return Abstracted_Access is
      
      O : Abstracted_Access := new Deal_Class;
      Label : Name_Type;
   begin
      if O /= null then
	 Wide_Fixed.Move(Name, O.Name, Error, Left, ' ');
	 
	 Deal_Class(O.all).Line.description := Description;
	 Deal_Class(O.all).Line.Account_num := Account_Num;
	 Deal_Class(O.all).Line.Unit_Ht_price := Unit_Ht_price;
	 Deal_Class(O.all).Line.TVA_Factor := Tva_Factor;
	 Deal_Class(O.all).Line.Quantity := Quantity;
	 Deal_Class(O.all).Line.Total_Ht := Fixed_Total(Deal_Class(O.all).Line.Unit_Ht_Price *
							  Deal_Class(O.all).Line.Quantity);
	 Deal_Class(O.all).Line.Delays :=Delays;
	 Deal_Class(O.all).Line.Peer_name := Peer_name;	 
	 Deal_Class(O.all).Line.Total_Ttc :=Deal_Class(O.all).Line.Total_Ht +
	   Fixed_Total(Deal_Class(O.all).Line.Total_ht/100.0)*Fixed_total(Deal_Class(O.all).Line.TVA_Factor);
	 Deal_Class(O.all).Line.Date := Clock;
	 Deal_Class(O.all).Line.Elaps := Deal_Class(O.all).Line.Date + (86400.0 * Delays);
	 Deal_Class(O.all).Print(Win, Win_Index, Label);
	 
	 return O;
      else
	 return null;
      end if;
   end Create;
   procedure Write (O : in Deal_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);
      W_Io.Put_Line(File, O.Line.Description);
      W_Io.Put_Line(File, To_Wide_String(Account_Num_Range'Image(O.Line.Account_num)));
      W_Io.Put_Line(File, To_Wide_String(Fixed_Unit_ht'Image(O.Line.Unit_Ht_price)));
      W_Io.Put_Line(File, To_Wide_String(Fixed_factor'Image(O.Line.TVA_factor)));
      W_Io.Put_Line(File, To_Wide_String(Quantity_range'Image(O.Line.Quantity)));
      W_Io.Put_Line(File, To_Wide_String(Payment_delay'Image(O.Line.delays)));
      W_Io.Put_Line(File, O.Line.Peer_name);
      
      W_Io.Put_Line(File, To_Wide_String(Natural'Image(O.Def.Index)));
      for I in 1..O.Def.Index loop
	 W_Io.Put_Line(File, To_Wide_String(O.Def.List(I).Names) & '=' & To_Wide_String(O.Def.List(I).Image));
      end loop;
      
   end Write;
   procedure Read (O : in out Deal_Class;File : in W_Io.File_Type) is
      Name_Last : Natural := 0;
      Empty : Wide_String (1..80);
      Empty_Last : natural := 0;
      
      
      Att_Index : Natural := 0;
   begin
      
      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);      
      declare
	 Empty_1 : Wide_String := W_Io.Get_Line(File);
      begin
	 null;
      end;
      
      W_Io.Get_Line(File, O.Line.Description, Name_Last);
      
      declare
	 Empty_1 : Wide_String := W_Io.Get_Line(File);
      begin
	 null;
      end;
      
      O.Line.Account_Num := Account_Num_Range'Value(To_String(W_Io.Get_line(File)));
      
      O.Line.Unit_Ht_Price := Fixed_Unit_Ht'Value(To_String(W_Io.Get_line(File)));
      
      O.Line.Tva_Factor := fixed_factor'Value(To_String(W_Io.Get_line(File)));
      
      O.Line.Quantity := Quantity_Range'Value(To_String(W_Io.Get_line(File)));
      
      O.Line.Total_Ht := Fixed_Total(O.Line.Unit_Ht_Price *
				       O.Line.Quantity);
      
	O.Line.delays := Payment_delay'Value(To_String(W_Io.Get_line(File)));
      
	O.Line.Total_Ttc :=Fixed_Total((O.Line.Total_Ht + ((Fixed_Total(O.Line.Total_ht/100.0))* Fixed_total(O.Line.TVA_Factor))));
      
	O.Line.Elaps := O.Line.Date + 
	86400.0*O.Line.Delays;
      
      W_Io.Get_Line(File, O.Line.Peer_name, Name_last);            
      
      declare
	 Empty_1 : Wide_String := W_Io.Get_Line(File);
      begin
	 null;
      end;
      
      Att_Index := Natural'Value(To_String(W_Io.Get_Line(File)));
      
      for I in 1..Att_Index loop
	 declare
	    Tags      : String_Access;
	    Image     : String_Access;
	 begin
	    Parse(W_Io.Get_Line(File), Tags, Image);
	    O.Def.List(I) := Make (Tags.all, Image.all);
	    O.Def.Index := O.Def.Index + 1;
	 end;
      end loop;

   end Read;
   
   
   procedure Random (O : in out Deal_Class) is
   begin
      null;
   end Random;
   --
   -----------------------------------------------------------------------------

end El.Classe.Deallines_class ;