with Ada.Numerics.Discrete_Random;
use Ada.Numerics;
generic
   
   Max_B_Inf : Positive;
   Max_B_Sup : Positive;
   Min_Class_Id : Positive;
   Min_Value_Id : Positive;
   Min_Data_ID  : Positive;
   Max_Class_Id : Positive;
   Max_Value_Id : Positive;
   Max_Data_ID  : Positive;
package Libsens.Frame is
      
   subtype Class_Id_Type is Natural range Min_Class_Id..Max_Class_Id;
   
   package Random_Class_Id is new Ada.Numerics.Discrete_Random(Class_Id_Type);   
   
   subtype Value_Id_Type is Natural range Min_value_Id..Max_Value_Id;
   
   package Random_Value_Id is new Ada.Numerics.Discrete_Random(Value_Id_Type);
   
   
   subtype Data_Id_Type is Natural range Min_Data_Id..Max_Data_Id;
   
   package Random_Data_Id is new Ada.Numerics.Discrete_Random(Data_Id_Type);
   
   
   
   -- Element : Description of Object
   type Digit_Type is
      record
	 Class_Id : Class_Id_Type := Class_Id_Type'First;
	 Value_Id : Value_Id_Type := Value_Id_Type'First;
	 Data_Id  : Data_Id_Type := Data_Id_Type'First;
      end record;      
   
   Digit_Default : constant Digit_Type := (Class_Id_Type'First, Value_Id_Type'First, Data_Id_Type'First);
      
   type Digit_Random_Generator_Type is
      record
	 Class_Id_Gen : Random_Class_Id.Generator;
	 Value_Id_Gen : Random_Value_Id.Generator;
	 Data_Id_Gen : Random_Data_Id.Generator;
      end record;
   
   function Digit_Random(Digit_Random_Generator : in Digit_Random_Generator_Type) return Digit_Type;
         
   -- knot of series.
   type Position_Type is
      record
	 Digit : Digit_Type;
	 Temp  : Digit_Type;
      end record;
   
   --  Use case : "to succed"
   function To_Succed (Old_Position : in Position_Type;
   		       Successor    : in Digit_Type) return Position_Type;
   
   
   type Digital_Gap_Buffer_Type is
      record
	 Position  : Position_Type;
	 Successor : Digit_Type;
      end record;	  
   		
   type Digital_Series_Gap_Buffer_Type is array (Natural range <>) of Digital_Gap_Buffer_Type;
   
   
   type Frame_Type is
      record	 
	 Digital_Series : Digital_Series_Gap_Buffer_Type(Max_B_Inf..Max_B_Sup);
	 B_Inf   : Natural := Max_B_Inf;
	 B_Sup   : Natural := Max_B_inf;
      end record;   
   
   package Frame_Rand is
      
      function Frame_Random return Frame_Type;
      procedure Reset;
   private
      
      
      
      Digit_Generator : Digit_Random_Generator_Type;
      
      
      subtype Frame_Range_Type is Positive range Max_B_Inf..Max_B_Sup;
      
      package Frame_Range_Rand is new Ada.Numerics.Discrete_Random(Frame_Range_Type);
      
      Frame_Range_Gen : Frame_Range_Rand.Generator;
      
      procedure Random (B_Inf           : in Natural;
			B_Sup           : in Natural;
			Digit_Generator : in Digit_Random_Generator_Type;
			Frame           :    out Frame_type);
   
      
   end Frame_Rand;
   
   
   function Frame_Fitness (Frame : in Frame_Type) return Float;
   
   function Frame_Mate (Left_Frame : in Frame_Type;
			Right_Frame : in Frame_Type) return Frame_Type;
   
   procedure Frame_Mutate (Old_Frame : in out Frame_Type);
         
end Libsens.Frame;