--  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_Directory.Relations;

with Nomo.Interpreter.Check_Rules.Initialization;

with Nomo.Interpreter.Predictions_Clusters.Loading;

with Nomo.Interpreter.Gen_Rules_Directories.Linking;
pragma Elaborate_All (Nomo.Interpreter.Gen_Rules_Directories.Linking);

with Nomo.Interpreter.Gen_Rules_Directories.Insertion;
pragma Elaborate_All (Nomo.Interpreter.Gen_Rules_Directories.Insertion);

with Nomo.Interpreter.Gen_Rules_Directories.Initialization;
pragma Elaborate_All (Nomo.Interpreter.Gen_Rules_Directories.Initialization);

with Nomo.Internal_Messages.Conclusions.Delayed.Predictive;

package body Nomo.Interpreter.Checks_Clusters.Loading is

   procedure Initialize (This       : in out Checks_Cluster;
                         Check_Type : in Check_Type_Index) is
      package Local_Rules_Directories_Initialization is new Local_Rules_Directories.Initialization;
      use Local_Rules_Directories_Initialization;
      use Types_Directory.Relations;
   begin
      This.Check_Type := Check_Type;
      This.Prediction_Type := Get_Prediction_Type (Check_Type);
      for I in This.Store'Range loop
         Initialize (Rules_Directory (This.Directory), Positive (I), This.Store (I)'Unchecked_Access);
      end loop;
   end Initialize;

   procedure Initialize_Links (This   : in out Checks_Cluster;
                               Target : in Predictions_Clusters.Predictions_Cluster) is
      use Check_Rules.Initialization;
      use Predictions_Clusters.Loading;
      package Local_Linking is new Local_Rules_Directories.Linking (Get_Prediction_Information,
                                                                    Predictions_Clusters.Predictions_Cluster,
                                                                    Internal_Messages.Conclusions.Delayed.Predictive.Predictive_Conclusion,
                                                                    Get_Prediction,
                                                                    Initial.Set_Linked_Prediction);
      use Local_Linking;
   begin
      Initialize_Links (Rules_Directory (This.Directory), Target);
   end Initialize_Links;

   package Local_Insertion is new Local_Rules_Directories.Insertion (Is_Updatable);

   function Has_Space (This : in Checks_Cluster) return Boolean is
   begin
      return Local_Insertion.Has_Space (Rules_Directory (This.Directory));
   end Has_Space;

   procedure Load (This             : in out Checks_Cluster;
                   Rule_Storage_Ptr : not null access constant Storages.Full_Rule_Storage) is
      use Local_Insertion;
      Excitatory_Specificity_Log : Real_Accurately;
      Inhibitory_Specificity_Log : Real_Accurately;
   begin
      This.Last_Loaded := Get_New_Reference (Rules_Directory (This.Directory));
      Check_Rules.Initialization.Initialize (This.Last_Loaded.all,
                                             Rule_Storage_Ptr.all,
                                             This.Matchmaker'Access,
                                             Excitatory_Specificity_Log,
                                             Inhibitory_Specificity_Log,
                                             This.Prediction_Type);
      Insert(Rules_Directory (This.Directory), Excitatory_Specificity_Log, Inhibitory_Specificity_Log);
   end Load;

   procedure Update_Last_Link (This   : in out Checks_Cluster;
                               Target : in out Predictions_Clusters.Predictions_Cluster) is
      use Check_Rules.Initialization;
      use Predictions_Clusters.Loading;
   begin
      Inline.Set_Linked_Prediction (This.Last_Loaded.all, Get_Last_Prediction (Target));
   end Update_Last_Link;

end Nomo.Interpreter.Checks_Clusters.Loading;
