--  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.Interpreter.Types_Index.Ranges;

with Nomo.Interpreter.Maximums_Register;
pragma Elaborate_All (Nomo.Interpreter.Maximums_Register);

with Nomo.Interpreter.Beginning.Parameters;

with Nomo.Interpreter.Beginning.Rules;

with Nomo.Interpreter.Storages.Reading;
pragma Elaborate_All (Nomo.Interpreter.Storages.Reading);

with Nomo.Interpreter.Epistemic_Memory.Checking.Loading;

with Nomo.Interpreter.Epistemic_Memory.Conceptive.Loading;

with Nomo.Interpreter.Epistemic_Memory.Landmarking.Loading;

with Nomo.Interpreter.Epistemic_Memory.Commanding.Loading;

with Nomo.Interpreter.Epistemic_Memory.Perceptive.Loading;

with Nomo.Interpreter.Epistemic_Memory.Predictive.Loading;

with Nomo.Interpreter.Epistemic_Memory.Reflective.Loading;

with Nomo.Interpreter.Epistemic_Memory.Rewarding.Loading;

separate (Nomo.Interpreter.Epistemic_Memory.Interpretation)
procedure Initialize is
   use Beginning.Rules;
   use Beginning.Parameters;
   use Storages;
   use Storages.Reading;
   use Types_Index.Ranges;
   Counts : array (Internal_Type_Index'Range) of Natural := (others => 0);
   Rule : aliased Full_Rule_Storage;
   Rule_Type : Internal_Type_Index;
   Maximum_Of_Rules_By_Cluster : constant Positive := Get_Maximum_Of_Rules_By_Type;
begin
   for I in Storage_Index'Range loop
      Get_Storage(I, Rule);
      Rule_Type := Get_Conclusion_Type (Rule);
      Counts (Rule_Type) := Counts (Rule_Type) + 1;
      if Counts (Rule_Type) > Maximum_Of_Rules_By_Cluster then
         raise Constraint_Error;
      end if;
      Maximums_Register.Initialization.Set_New_Rule_Id (Get_Id (Rule));
      Maximums_Register.Initialization.Set_New_Information (Rule_Type, Get_Internal_Conclusion (Rule).all.Get_Information);
      if Rule_Type in Check_Type_Index'Range then
         Epistemic_Memory.Checking.Loading.Load (Rule_Type, Rule'Unchecked_Access);
      elsif Rule_Type in Conception_Type_Index'Range then
         Epistemic_Memory.Conceptive.Loading.Load (Rule_Type, Rule'Unchecked_Access);
      elsif Rule_Type in Landmark_Type_Index'Range then
         Epistemic_Memory.Landmarking.Loading.Load (Rule_Type, Rule'Unchecked_Access);
      elsif Rule_Type in Command_Type_Index'Range then
         Epistemic_Memory.Commanding.Loading.Load (Rule_Type, Rule'Unchecked_Access);
      elsif Rule_Type in Perception_Type_Index'Range then
         Epistemic_Memory.Perceptive.Loading.Load (Rule_Type, Rule'Unchecked_Access);
      elsif Rule_Type in Prediction_Type_Index'Range then
         Epistemic_Memory.Predictive.Loading.Load (Rule_Type, Rule'Unchecked_Access);
      elsif Rule_Type in Reflective_Type_Index'Range then
         Epistemic_Memory.Reflective.Loading.Load (Rule_Type, Rule'Unchecked_Access);
      elsif Rule_Type in Reward_Type_Index'Range then
         Epistemic_Memory.Rewarding.Loading.Load (Rule_Type, Rule'Unchecked_Access);
      else
         raise Constraint_Error;
      end if;
   end loop;
   Maximums_Register.Initialization.Adjust_Information_Perceptive_Max;
   Epistemic_Memory.Checking.Loading.Initialize_Links;
   Epistemic_Memory.Commanding.Loading.Initialize_Links;
end Initialize;
