--  Copyright (2008-2014) 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 Ada.Real_Time;
use Ada.Real_Time;

with Ada.Text_IO;

with Ada.Exceptions;

with Interfaces.C.Strings;

with Nomo_Interpreter;

package body Commands is

   Number_Of_Initilizations : constant Positive := 1000;

   Number_Of_Measures : constant Positive := 1000;

   Number_Of_Steps : constant Positive := Number_Of_Initilizations + Number_Of_Measures;

   type Data is array (1 .. 1000) of Nomo_Interpreter.Real;
   pragma Convention (C, Data);

   Triggers_Time : array (1 .. Number_Of_Steps) of Time;
   Command_Time  : array (1 .. Number_Of_Steps) of Time;
   Command_Index : Natural;

   function Get_Max return Duration;

   function Get_Mean return Duration;

   procedure Test (Actions      : in Command_Callback;
                   Input_Number : in Natural) is
      Perceptions : array (1 .. Input_Number) of Data := (others => (others => 0.0));
   begin
      Command_Index := 0;
      Nomo_Interpreter.Initialize (Actions, Interfaces.C.Strings.New_String(""), 0);
      for I in Triggers_Time'Range loop
         for J in 1 .. Input_Number loop
            Nomo_Interpreter.Input (Interfaces.C.short (J), Perceptions (J)'Address);
         end loop;
         Triggers_Time (I) := Clock;
         Nomo_Interpreter.Triggers;
      end loop;
      Nomo_Interpreter.Finalize (Nomo_Interpreter.Any_Modification);
      Ada.Text_IO.Put_Line("Max  :" & Duration'Image(Get_Max * 1000) & " ms");
      Ada.Text_IO.Put_Line("Mean :" & Duration'Image(Get_Mean * 1000) & " ms");
   end Test;

   procedure Command (Intensity : in Nomo_Interpreter.Real_0_To_1;
                      Data      : in System.Address) is
      use Ada.Real_Time;
   begin
      Command_Index := Command_Index + 1;
      Command_Time (Command_Index) := Clock;
   end Command;

   function Get_Max return Duration is
      Max : Time_Span := Command_Time (Number_Of_Initilizations + 1) - Triggers_Time (Number_Of_Initilizations + 1);
   begin
      for I in Number_Of_Initilizations + 2 .. Triggers_Time'Last  loop
         if Max < Command_Time (I) - Triggers_Time (I) then
            Max := Command_Time (I) - Triggers_Time (I);
         end if;
      end loop;
      return To_Duration (Max);
   end Get_Max;

   function Get_Mean return Duration is
      Sum : Duration := 0.0;
   begin
      for I in Number_Of_Initilizations + 1 .. Triggers_Time'Last loop
         Sum := Sum + To_Duration (Command_Time (I) - Triggers_Time (I));
      end loop;
      return Sum / (Triggers_Time'Length);
   end Get_Mean;

end Commands;
