with Ada.Wide_Text_Io;
use Ada.Wide_Text_Io;
with Gnat.Sockets;
use Gnat.Sockets;

with Gnat.Cgi;
use Gnat.Cgi;
with Gnat.Cgi.Cookie;

with Ada.Characters.Handling;
use Ada.Characters.Handling;
with Ada.Strings.Fixed;
use Ada.Strings.Fixed;
with Ada.Strings.Wide_Fixed;
use Ada.Strings;

with Gnat.Sha1;
use Gnat;

with Sai;
use Sai;
procedure Webmain is
   
   package Wfixed renames Wide_Fixed;
   
   
   type string_Access is access all Wide_String;
   
   type Arg_Entry is
      record	 
	 Value   : String_Access;
	 Is_Set  : Boolean := False;
      end record;
   
   type Arg_array is array (Id_Range) of Arg_Entry;
   
   
   Add  : Gnat.sockets.Sock_Addr_Type;
   Socket   : Socket_Type;
   Channel  : Gnat.sockets.Stream_Access;
   Logged   : Boolean := False;
   
   
   Enregistrement : Enregistrement_Record;
   Index          : Natural := 0;
   Command        : Command_Record;
   Facture        : Facture_Record;
   Card           : Bank_Info_Type;
   
   Arg_Table : Arg_Array;
   No_Problem : Boolean := True;
   File : File_Type;
   Name_Done : Boolean := False;
   email_Done : Boolean := False;
   Address_Done : Boolean := False;
   Phone_Done : Boolean := False;
   Id_Transaction : Natural := 0;
   Bank_Info      : Bank_Info_Type := Null_Card;
begin     
   if not Ok then
      raise Program_Error;
   end if;
   
   
   if Key_Exists("Id_Transaction") then		
      Add.Addr :=
	Gnat.Sockets.Addresses (Gnat.Sockets.Get_Host_By_Name ("localhost"), 1);
      
      Add.Port := 7051;
      Gnat.sockets.Create_Socket (Socket);
      delay 0.1;
      Gnat.Sockets.Set_Socket_Option
	(Socket,
	 Gnat.Sockets.Socket_Level,
	 (Gnat.Sockets.Reuse_Address, True));      
      delay 0.1;      
      Gnat.sockets.Connect_Socket (Socket, Add);
      delay 0.1;
      Channel := Gnat.sockets.Stream (Socket);
      String'Output (Channel, "saiweb");
      Sha1.Message_Digest'Output (Channel, Sha1.Digest("saiweb"));
      Logged := Boolean'Input(Channel);	 
      if Logged then
	 
	 Command_Enum'Output(Channel, Paiement);
	 Id_Transaction := Natural'Value(Value("Id_Transaction"));
	 Natural'Output(Channel, Id_Transaction);
	 Wfixed.Move(To_Wide_String(Value("Name")), Bank_Info.Name);
	 Wfixed.Move(To_Wide_String(Value("Card_Num")), Bank_Info.Card_Num);
	 Wfixed.Move(To_Wide_String(Value("Exp_Date")), Bank_Info.Exp);
	 Wfixed.Move(To_Wide_String(Value("Sign")), Bank_Info.sign);
	 
	 Put_Header(Default_Header);	 
	 Put_Line("<!Doctype html>");
	 Put_Line("<html>");
	 Put_Line("<head>");
	 Put_Line("<meta charset=""UTF-8"">");
	 Put_Line("<title>Validation</title>");
	 Put_Line("</head>");
	 Put_Line("<body background=""/images/spectre.jpg"">");
         Put_Line("<table align=""center"" width=""66%"">");
   	 Put_Line("<tr><td>");
         Put_Line("<table align=""left"" width=""100%"">");
         Put_Line("<tr><td>");

	 Put_Line("<h2>Validation</h2>");
	 Put_Line("Votre paiement est accepté.");
	 Put_Line("Voici votre facture afin de faire valoir vos droits.");
	 Put_Line("<h3>Programmes(s) commandé(s)</h3>");
	 
	 Index := Natural'Input(Channel);
	 for I in 1..Index loop
	    declare
	       Product : Product_Enum := Product_Enum'Input(Channel);
	       Price   : Price_Type := 0.0;
	    begin
	       if Product /= Null_Item then
		  Price := Price_Type'Input(Channel);
		  Command.Products(Product) := Price;
		  Put_Line("Product : " & To_Wide_String(Product_Enum'Image(Product)) & " := " & To_Wide_String(Price_Type'Image(Command.Products(Product))) & " € ; <br>");
	       end if;
	    end;
	 end loop;
	 Command.HT_Sum := Price_Type'Input(Channel);
	 Command.TVA := Price_Type'Input(Channel);
	 Command.TTC_Sum := Price_Type'Input(Channel);
	 Put_line("Facture N° " & To_Wide_String(Natural'Image(Id_Transaction)) & "<br>");
	 
	 Put_Line("Selon le taux de taxe sur la valeur ajouté, à 20 % <br>");
	 
	 Put_Line("Total HT  : " & To_Wide_String(Price_Type'Image(Command.HT_Sum)) & " € ; <br>");
	 Put_Line("Total TVA : " & To_Wide_String(Price_Type'Image(Command.TVA)) & " € ; <br>");
	 Put_Line("Total TTC : " & To_Wide_String(Price_Type'Image(Command.TTC_Sum)) & " €.");
	 Put_Line("</td></tr></table></td></tr></table>");
	 Put_Line("</body>");
	 Put_Line("</html>");
      end if;
   else
      Put_Header(Default_Header);
      for I in Id_Range loop
	 begin
	    Arg_Table(I).Value := new Wide_String ' (To_Wide_String(Value(To_Lower(Id_Range'Image(I)))));
	    if Arg_Table(I).Value'Length /= 0 then	    
	       Arg_Table(I).Is_Set := True;
	    end if;		  
	 end;
      end loop;
      
      if Arg_Table(name).Is_Set then
	 Name_Done := True;
      end if;
      if Arg_Table(email).Is_Set then
	 Email_Done := True;
      end if;   
      if Arg_Table(address).Is_Set then
	 Address_Done := True;
      end if;
      if Arg_Table(phone).Is_Set then
	 Phone_Done := True;
      end if;
      if (Arg_Table(Skywalker).Is_set or Arg_Table(Skywalker).Is_Set) or
      --if (Arg_Table(Compta).Is_set or Arg_Table(Devel).Is_set or Arg_Table(Chessgame).Is_set or Arg_Table(Dialog).Is_set or Arg_Table(Manager).Is_Set) or
	(Arg_Table(Objectif).Is_Set or Arg_Table(Motivations).Is_Set or Arg_Table(Objet).Is_Set or Arg_Table(Arguments).Is_Set) then	
	 if not Name_Done then
	    Put_Line("<!Doctype html>");
	    Put_Line("<html>");
	    Put_Line("<head>");
	    Put_Line("<meta charset=""UTF-8"">");
	    Put_Line("<title>Nom ?</title>");
	    Put_Line("</head>");
	    Put_Line("<body background=""/images/spectre.jpg"">");
	    Put_Line("indiquer votre nom.");
	    Put_Line("</body>");
	    Put_Line("</html>");
	 else
	    if not (Phone_Done or Email_Done or Address_Done) then
	       Put_Line("<!Doctype html>");
	       Put_Line("<html>");
	       Put_Line("<head>");
	       Put_Line("<meta charset=""UTF-8"">");
	       Put_Line("<title>Contact ?</title>");
	       Put_Line("</head>");
	       Put_Line("<body background=""/images/spectre.jpg"">");
	       Put_Line("indiquer votre contact.");
	       Put_Line("</body>");
	       Put_Line("</html>");
	    else
	       
	       Put_Line("<!Doctype html>");
	       Put_Line("<html>");
	       Put_Line("<head>");
	       Put_Line("<meta charset=""UTF-8"">");
	       Put_Line("<title>Récapitulatif</title>");
	       Put_Line("</head>");
	       Put_Line("<body background=""/images/spectre.jpg"">");
	       Put_Line("<table align=""center"" width=""66%"">");
	       Put_Line("<tr><td>");
               Put_Line("<table align=""left"" width=""100%"">");
               Put_Line("<tr><td>");

	       if (Arg_Table(Skywalker).Is_set or Arg_Table(Skywalker).Is_Set) then
		  --if Arg_Table(Compta).Is_set or Arg_Table(Devel).Is_set or Arg_Table(Chessgame).Is_set or Arg_Table(Dialog).Is_set or Arg_Table(Manager).Is_set then
		  No_Problem := False;
		  if not Address_Done then
		     Put_Line("<h2>Addresse de résidence requise</h2>");
		     Put_Line("<B>Vous</B> devez indiquer votre adresse de résidence afin que nous vous fassions parvenir les programmes commandés.");
		     --  else		  
		     --  	  for I in Compta..Manager loop
		     --  	     if Arg_Table(I).Is_Set then
		     --  		Put_Line(Arg_Table(I).Value.all & "<br>");
		     --  	     end if;
		     --  	  end loop;		  
		  end if;	       
	       end if;
	       
	       if Arg_Table(Objectif).Is_Set or Arg_Table(Motivations).Is_Set or Arg_Table(Objet).Is_Set or Arg_Table(Arguments).Is_Set then	       
		  No_Problem := False;
		  if not (Arg_Table(Objectif).Is_Set and Arg_Table(Motivations).Is_Set and Arg_Table(Objet).Is_Set and Arg_Table(Arguments).Is_Set) then
		     Put_Line("<h2>Commande de logiciel incomplète</h2>");
		     Put_Line("Pour une commande de logiciel <B>vous</B> devez remplir chacun des champs prévu à cet effet.");		 		  
		  else
		     
		     if not Email_Done then
			Put_Line("<h2>Commande de logiciel</h2>");
			Put_Line("Pour une commande de logicial <B>vous</B> devez nous communiquer votre adresse email.");		 
		     elsif not Address_done then
			Put_Line("<h2>Commande de logiciel</h2>");
			Put_Line("Pour une commande de logicial <B>vous</B> devez nous communiquer votre adresse de résidence."); 
			--  else
			
			--  for I in objectif..Arguments loop
			--  	if Arg_Table(I).Is_Set then
			--  	   Put_Line(Arg_Table(I).Value.all & "<br>");
			--  	end if;
			--  end loop;
		     end if;		  
		  end if;	       
	       end if;
	       
	       
	       Wfixed.Move(Arg_Table(Name).Value.all, Enregistrement.Coordonates.Name);
	       fixed.Move(To_String(Arg_Table(email).Value.all), Enregistrement.Coordonates.email);
	       Wfixed.Move(Arg_Table(address).Value.all, Enregistrement.Coordonates.address);
	       fixed.Move(To_String(Arg_Table(Phone).Value.all), Enregistrement.Coordonates.phone);
	       fixed.Move(To_String(Arg_Table(Skywalker).Value.all), Enregistrement.Programs(1));
	       --fixed.Move(To_String(Arg_Table(Compta).Value.all), Enregistrement.Programs(1));
	       --fixed.Move(To_String(Arg_Table(Devel).Value.all), Enregistrement.Programs(2));
	       --fixed.Move(To_String(Arg_Table(Chessgame).Value.all), Enregistrement.Programs(3));
	       --fixed.Move(To_String(Arg_Table(Dialog).Value.all), Enregistrement.Programs(4));
	       --fixed.Move(To_String(Arg_Table(Manager).Value.all), Enregistrement.Programs(5));
	       Wfixed.Move(Arg_Table(Objectif).Value.all, Enregistrement.Logicial.Objectif);
	       Wfixed.Move(Arg_Table(Motivations).Value.all, Enregistrement.Logicial.Motivations);
	       Wfixed.Move(Arg_Table(Objet).Value.all, Enregistrement.Logicial.Objet);
	       Wfixed.Move(Arg_Table(Arguments).Value.all, Enregistrement.Logicial.arguments);
	       
	       ---------------------------------------
	       -- Connection :
	       ---------------------------------------
	       Add.Addr :=
		 Gnat.Sockets.Addresses (Gnat.Sockets.Get_Host_By_Name ("localhost"), 1);
	       
	       Add.Port := 7051;
	       Gnat.sockets.Create_Socket (Socket);
	       delay 0.1;
	       Gnat.Sockets.Set_Socket_Option
		 (Socket,
		  Gnat.Sockets.Socket_Level,
		  (Gnat.Sockets.Reuse_Address, True));      
	       delay 0.1;      
	       Gnat.sockets.Connect_Socket (Socket, Add);
	       delay 0.1;
	       Channel := Gnat.sockets.Stream (Socket);
	       String'Output (Channel, "webmain");
	       Sha1.Message_Digest'Output (Channel, Sha1.Digest("webmain"));
	       Logged := Boolean'Input(Channel);	 
	       if Logged then
		  
		  Command_Enum'Output(Channel, Cmd);
		  
		  Wide_String'Output(Channel, Enregistrement.Coordonates.name);
		  String'Output(Channel, Enregistrement.Coordonates.email);
		  Wide_String'Output(Channel, Enregistrement.Coordonates.address);
		  String'Output(Channel, Enregistrement.Coordonates.phone);
		  String'Output(Channel, Enregistrement.Programs(1));
		  String'Output(Channel, Enregistrement.Programs(2));
		  String'Output(Channel, Enregistrement.Programs(3));
		  String'Output(Channel, Enregistrement.Programs(4));
		  String'Output(Channel, Enregistrement.Programs(5));
		  Wide_String'Output(Channel, Enregistrement.Logicial.objectif);
		  Wide_String'Output(Channel, Enregistrement.Logicial.motivations);
		  Wide_String'Output(Channel, Enregistrement.Logicial.objet);
		  Wide_String'Output(Channel, Enregistrement.Logicial.arguments);
		  
		  -- Recapitulatif --
		  Put_Line("<h1>Confirmation</h1>");	       
		  Put_Line("Nous avons enregistré votre demande.");
		  
		  if (Arg_Table(Objectif).Is_Set and Arg_Table(Motivations).Is_Set and Arg_Table(Objet).Is_Set and Arg_Table(Arguments).Is_Set) then		       
		     -- Prise en charge du projet logiciel
		     Put_Line("<h2>Prise en charge de votre dossier logiciel</h2>");
		     Put_Line("<h3>Objectif</h3>"); 
		     Put_Line("Le résultat attendu : " & Arg_Table(objectif).Value.all); 
		     Put_Line("<h3>Motivations</h3>"); 
		     Put_Line("Les avantages du dit logiciel : " & Arg_Table(Motivations).Value.all ); 
		     Put_Line("<h3>Objet</h3>"); 
		     Put_Line("Le but du logiciel : " & Arg_Table(objet).Value.all); 
		     Put_Line("<h3>Arguments</h3>"); 
		     Put_Line("Le context d'utilisation : " & Arg_Table(Arguments).Value.all); 
		     
		  end if;
		  -- Aquisition de Programmes :
		  Put_Line("<h2>Programmes(s) commandé(s)</h2>");
		  Index := Natural'Input(Channel);
		  for I in 1..Index loop
		     declare
			Product : Product_Enum := Product_Enum'Input(Channel);
			Price   : Price_Type := 0.0;
		     begin
			if Product /= Null_Item then
			   Price := Price_Type'Input(Channel);
			   Command.Products(Product) := Price;
			end if;
		     end;
		  end loop;
		  Command.HT_Sum := Price_Type'Input(Channel);
		  Command.TVA := Price_Type'Input(Channel);
		  Command.TTC_Sum := Price_Type'Input(Channel);
		  
		  Id_Transaction := Natural'Input(Channel);
		  
		  
		  Put_Line("Selon le taux de taxe sur la valeur ajouté, voici nos prix : <br>");
		  for Product in Product_enum loop
		     if Command.Products(Product) /= 0.0 then
			Put_Line("Product : " & To_Wide_String(Product_Enum'Image(Product)) & " := " & To_Wide_String(Price_Type'Image(Command.Products(Product))) & " € ; <br>");
		     end if;
		  end loop;
		  Put_Line("Total HT  : " & To_Wide_String(Price_Type'Image(Command.HT_Sum)) & " € ; <br>");
		  Put_Line("Total TVA : " & To_Wide_String(Price_Type'Image(Command.TVA)) & " € ; <br>");
		  Put_Line("Total TTC : " & To_Wide_String(Price_Type'Image(Command.TTC_Sum)) & " €.");
		  Put_Line("<br>");
		  Put_Line("Votre demande sera traité dans un delay de 48 à 72 heures");
		  Put_Line("<br>");
		  Put_Line("Merci de votre compréhension !");	       
		  
		  
		  ----------------------------------------------------------------------
		  -- Paiement form :
		  -----------------------------------------------------------------------
		  Put_Line("<Form Action=""webmain"" Method=""POST"">");
		  Put_Line("Name : <Input type=""Textarea"" cols=""32"" name=""Name"" id=""Name"" /><br>");
		  Put_Line("Card Number : <Input type=""Textarea"" cols=""14"" name=""Card_Num"" id=""Card_Num"" /><br>");
		  Put_Line("Expiration date : <Input type=""Textarea"" cols=""6"" name=""Exp_Date"" id=""Exp_Date"" /><br>");
		  Put_Line("Code : <Input type=""Textarea"" cols=""3"" name=""Sign"" id=""Sign"" /><br>");
		  Put_Line("<Input type=""hidden"" name=""Id_Transaction"" id=""Id_Transaction"" value=""" & To_Wide_String(Natural'Image(Id_Transaction)(2..Natural'Image(Id_Transaction)'last))& """/>");
		  Put_Line("<input type=""submit"" name=""submit"" id=""submit"" value=""Envoyer"" /> ");
		  Put_Line("<input type=""reset"" name=""reset"" id=""reset"" value=""Effacer"" />");		     
		  Put_Line("</Form>");
		  
		  
		  
		  
		  
	       end if;	 
	       Put_Line("</td></tr></table></td></tr></table>");	       
	       Put_Line("</body>");
	       Put_Line("</html>");
	       
	       
	       
	       
	       
	       
	       
	       
	    end if;
	    
	    
	 end if;
      else
	 if No_Problem then 
	    Put_Line("<!Doctype html>");
	    Put_Line("<html>");
	    Put_Line("<head>");
	    Put_Line("<meta charset=""UTF-8"">");
	    Put_Line("<title>Récapitulatif</title>");
	    Put_Line("</head>");
	    Put_Line("<body> background=""/images/spectre.jpg""");		    
	    Put_Line("<h2>Vérification</h2>");
	    Put_Line("Malgrès notre attention, notre formulaire reste inutilisé.<br>");
	    Put_Line("Vous pouvez retourner à l'adresse précédente.");
	    Put_Line("</body>");
	    Put_Line("</html>");      	 
	 end if;
      end if;
   end if;
   
exception
   when Program_Error =>
      Put_Header(Default_Header);
      Put_Line("<!Doctype html>");
      Put_Line("<html>");
      Put_Line("<head>");
      Put_Line("<meta charset=""UTF-8"">");
      Put_Line("<title>HTTP Error ?</title>");
      Put_Line("</head>");
      Put_Line("<body>");
      Put_Line("This program is an CGI"); 
      Put_Line("</body>");
      Put_Line("</html>");

end Webmain;
