--  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/>

package body Nomo.Interpreter.Types_Directory.Relations is

   function Get_Data_Size (I : in Type_Index) return Component_Index is
   begin
      return Component_Index (This (I).Data_Size);
   end Get_Data_Size;

   function Get_Feedback (I : in Command_Type_Index) return Perception_Type_Index is
   begin
      return This(I).Perception_Associated;
   end Get_Feedback;

   function Has_Feedback (I : in Command_Type_Index) return Boolean is
   begin
      pragma Assert (This (I).Perception_Associated = 0 or This (I).Perception_Associated in Perception_Type_Index);
      return This (I).Perception_Associated /= 0;
   end Has_Feedback;

   function Has_Target (I : in Check_Type_Index) return Boolean is
      pragma Unreferenced (I);
   begin
      return True;
   end Has_Target;

   function Get_Input_Type (I : in Perception_Type_Index) return Input_Type_Index is
   begin
      return This (I).Input_Associated;
   end Get_Input_Type;

   function Get_Perception_Type (I : in Input_Type_Index) return Perception_Type_Index is
   begin
      return This (I).Perception_Associated;
   end Get_Perception_Type;

   function Get_Command_Type (I : in Perception_Type_Index) return Command_Type_Index is
   begin
      return This (I).Command_Associated;
   end Get_Command_Type;

   function Has_Command_Type (I : in Perception_Type_Index) return Boolean is
   begin
      return This (I).Command_Associated /= 0;
   end Has_Command_Type;

   function Has_Reward_Type (I : in Internal_Type_Index) return Boolean is
   begin
      return This (I).Rewarded_By /= 0;
   end Has_Reward_Type;

   function Get_Reward_Type (I : in Internal_Type_Index) return Reward_Type_Index is
   begin
      return This (I).Rewarded_By;
   end Get_Reward_Type;

   function Get_Check_Type (I : in Prediction_Type_Index) return Check_Type_Index is
   begin
      return This (I).Check_Associated;
   end Get_Check_Type;

   function Get_Landmark_Type (I : in Prediction_Type_Index) return Landmark_Type_Index is
   begin
      return This (I).Landmark_Associated;
   end Get_Landmark_Type;

   function Has_Prediction_Linked (I : in Landmark_Type_Index) return Boolean is
   begin
      for J in Prediction_Type_Index'Range loop
         if This (J).Landmark_Associated = I then
            return True;
         end if;
      end loop;
      return False;
   end Has_Prediction_Linked;

   function Has_Prediction_Type (I : in Internal_Type_Index) return Boolean is
   begin
      return This (I).Predicted_By /= 0;
   end Has_Prediction_Type;

   function Get_Prediction_Type (I : in Internal_Type_Index) return Prediction_Type_Index is
   begin
      if I in Check_Type_Index then
         for J in Prediction_Type_Index'Range loop
            if This (J).Check_Associated = I then
               return J;
            end if;
         end loop;
         raise Constraint_Error;
      elsif I in Landmark_Type_Index then
         for J in Prediction_Type_Index'Range loop
            if This (J).Landmark_Associated = I then
               return J;
            end if;
         end loop;
         raise Constraint_Error;
      else
         return This (I).Predicted_By;
      end if;
   end Get_Prediction_Type;

   function Get_Twin_Type (I : in Internal_Type_Index) return Conception_Type_Index is
   begin
      return This (I).Twined_With;
   end Get_Twin_Type;

   function Has_Twin_Type (I : in Internal_Type_Index) return Boolean is
   begin
      return This (I).Twined_With /= 0;
   end Has_Twin_Type;

   function Is_Rewardable (I           : in Internal_Type_Index;
                           Reward_Type : in Reward_Type_Index) return Boolean is
   begin
      return This (I).Rewarded_By = Reward_Type;
   end Is_Rewardable;

   function Has_Check_Type (I : in Landmark_Type_Index) return Boolean is
   begin
      for J in Prediction_Type_Index'Range loop
         if This (J).Landmark_Associated = I then
            return True;
         end if;
      end loop;
      return False;
   end Has_Check_Type;

end Nomo.Interpreter.Types_Directory.Relations;
