-- computerman is multiway user tools.
-- Computerman is Copyright (C) 2024 Manuel De Girardi ; 
--
--   This program is free software; you can redistribute it and/or modify
--   it under the terms of the GNU General Public License as published by
--   the Free Software Foundation; either version 2 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 General Public License for more details.
--
--   You should have received a copy of the GNU General Public License
--   along with this program; if not, write to the Free Software
--   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
--
-- Date := "2024-05-11 15:51:39"
-- Version := "0.0.2a"
with Ada.Numerics.Discrete_Random;
use Ada.Numerics;

package Computer.Frame is
   
   Max_B_Inf : constant Positive := 1;
   Max_B_Sup : constant Positive := 4;
   Min_Class_Id : constant Positive := 48;
   Min_Value_Id : constant Positive := 67; 
   Min_Data_ID  : constant Positive := 4; 
   Max_Class_Id : constant Positive := 127;
   Max_Value_Id : constant Positive := 127;
   Max_Data_ID  : constant Positive := 32;
   
   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 Computer.Frame ;