--  Copyright (2008-2013) Cédric Coussinet (cedric.coussinet@nomoseed.net)
--
--  This program is free software: you can redistribute it and/or modify
--  it under the terms of the GNU Affero General Public License as published
--  by the Free Software Foundation, either version 3 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 Affero General Public License for more details.

--  You should have received a copy of the GNU Affero General Public License
--  along with this program. If not, see <http://www.gnu.org/licenses/>

with Nomo.Numerics.Reals.Long;

with Nomo.Printing;

package body Nomo.Gen_External_Messages.Premises.Printing is

   package body CVS is

      procedure Put_Header (File : in out File_Type) is
      begin
         Put (File, ", ep_specificity_log");
         for I in Component_Index'Range loop
            declare
               Index : constant String := Component_Index'Image (I) (2 .. Component_Index'Image (I)'Last);
            begin
               Put (File, ", ep_" & Index & "_input");
               Put (File, ", ep_" & Index & "_actuator");
               Put (File, ", ep_" & Index & "_tolerance");
            end;
         end loop;
      end Put_Header;

      procedure Put_NA (File : in out File_Type) is
         use Nomo.Printing;
      begin
         Put (File, ", " & NA);
         for I in Component_Index'Range loop
            for I in 1 .. 3 loop
               Put (File, ", " & NA);
            end loop;
         end loop;
      end Put_NA;

      procedure Put (File : in out File_Type;
                     This : in External_Premise) is
         use Nomo.Printing;
         Tag : Boolean := True;

         procedure Put_Component (I : in Component_Index);

         procedure Put_Component (I : in Component_Index) is
            use Numerics.Reals.Long;
         begin
            Put (File, "," & Real'Image (This.Information (I)));
            Put (File, "," & Real'Image (This.Actuator (I)));
            if This.Tolerance (I) = Zero_Plus then
               Put (File, ", 0.0");
            elsif This.Tolerance (I) = Positive_Infinity then
               Put (File, ", INF");
            else
               Put (File, "," & Real'Image (This.Tolerance (I) / 2.0));
            end if;
         end Put_Component;

      begin
         Put (File, "," & Real_Accurately'Image (This.Specificity_Log));
         for I in Component_Index'Range loop
            if Tag then
               Put_Component (I);
               if I = This.Size then
                  Tag := False;
               end if;
            else
               for I in 1 .. 3 loop
                  Put (File, ", " & NA);
               end loop;
            end if;
         end loop;
      end Put;

   end CVS;

   package body XML is

      procedure Put (File    : in out File_Type;
                     This    : in External_Premise;
                     Type_Id : in Positive) is
         use Numerics.Reals.Long;
      begin
         Put (File, "<premise category=""input"" type=""" & Positive'Image (Type_Id) & """");
         Put (File, " specificity_log=""" & Real_Accurately'Image (This.Specificity_Log) & """>");
         for I in Component_Index'Range loop
            Put (File, "<information value=""" & Real'Image(This.Information (I)) & " ");
            if This.Tolerance (I) = Zero_Plus then
               Put (File, " tolerance =""0.0""");
            elsif This.Tolerance (I) = Positive_Infinity then
               Put (File, " tolerance =""INF""");
            else
               Put (File, " tolerance =""" & Real'Image (This.Tolerance (I) / 2.0) & """");
               Put (File, " values_sum ="""  & Long_Real'Image (This.Trend (I).Values_Sum) & """");
               Put (File, " squares_sum ="""  & Long_Real'Image (This.Trend (I).Squares_Sum) & """");
            end if;
            Put (File, " actuator =""" & Real'Image (This.Actuator (I)) & """ />");
            exit when I = This.Size;
         end loop;
         Put (File, "</premise>");
      end Put;

   end XML;

   package body DB is

      use Numerics.Times;

      procedure Put (File    : in out File_Type;
                     T       : in Time;
                     Rule_Id : in Positive;
                     This    : in External_Premise) is

      begin
         for I in Component_Index'First..This.Size loop
            Put (File, Time'Image (T));
            Put (File, "," & Positive'Image (Rule_Id));
            Put (File, "," & Component_Index'Image (I));
            Put (File, "," & Real'Image (This.Information (I)));
            Put (File, "," & Real'Image (This.Actuator (I)));
            if This.Tolerance (I) = Zero_Plus then
               Put (File, ", 0.0");
            elsif This.Tolerance (I) = Positive_Infinity then
               Put (File, ", INF");
            else
               Put (File, "," & Real'Image (This.Tolerance (I) / 2.0));
            end if;
            Put_Line (File, "," & Real_Accurately'Image (This.Specificity_Log));
         end loop;
      end Put;

   end DB;

end Nomo.Gen_External_Messages.Premises.Printing;
