-- 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 09:44:21"
-- Version := "0.0.1a"
with Computer.MIDI.Drivers;              use Computer.MIDI.Drivers;
with Computer.Midi.Messages;             use Computer.Midi.Messages;
with Ada.Containers.Vectors;
use Ada.Containers;
with Interfaces.C;                      use Interfaces.C;
use Interfaces;


with Ada.Calendar;
use Ada.Calendar;
package Computer.Midi.Sequencer is
   Time_Unit_Max : constant Positive := 64;
   
   Time_Number_Max : constant Positive := 32;
   
   Time_Index_Max : constant Positive := Time_Unit_Max * Time_Number_Max;
   
   subtype Time_Index_Type is
     Positive range Positive'First .. Time_Index_Max;
   
   subtype Extended_Time_Index_Type is
     Natural range 0 .. Time_Index_Max;
   
   subtype Time_Unit_Type is
     Time_Index_Type range Time_Index_Type'First .. Time_Unit_Max;
   
   Unit_Default : constant Time_Unit_Type := Time_Unit_Type'Last / 4;
   
   subtype Time_Number_Type is
     Time_Index_Type range Time_Index_Type'First..Time_Number_Max;
   
   Number_Default : constant Time_Number_Type := Time_Number_Type'Last / 2;
   
   
   type Time_Signature_Type is
      record
	 Number   : Time_Number_Type;
	 Unit     : Time_Unit_Type;
      end record;
   
   function image(Signature : in Time_Signature_Type) return String;
   
   type Bar_Beat_Type is
     tagged record
      Bar         : Positive := Positive'First;
      Time_Number : Time_Number_Type := Time_Number_Type'First;
      Time_Unit   : Time_Unit_Type := Time_Unit_Type'First;
   end record;
   
   function Image(Bar_Beat : in Bar_Beat_Type) return String;
   
   procedure Next(Bar_Beat    : in out Bar_Beat_Type;
		  Bar         : in Natural;
		  Number      : in Time_Number_Type;
		  Unit        : in Time_Unit_Type);
   
   
   
   
   subtype Den_Type is natural range 0..6;      
   
   subtype Step_Beat_Type is Positive range 1..2**6 + 1;
  
   subtype Numerator_Type is Positive range 1..32;    
   
   type T_Figure is (Quadruple, Triple, Double, Simple, Noire, Blanche, Ronde);
   
   type MIDI_Instrument_Record;
   task type Tempo_Sync_Type(Instrument : access Device_Driver_Record'class) is      
      entry Start(Start_Time : in Time; Tempo : in Tempo_Type; Signature : in Time_Signature_type);	 
      entry Stop;
      entry Halt;
   end Tempo_Sync_Type;	       

   ----------------------------------------------------
   -- Modulation sequencer :                         --   
   
   task type Mod_Sequencer_Type(Instrument : access Device_Driver_Record'class) is      
      entry Start(Tempo : in Tempo_Type; Signature : in Time_Signature_type);
      entry Stop;
      entry Rec(In_Rec : in Boolean);
      entry Play(In_Play : in Boolean);
      entry Reset;
      entry Halt;
   end Mod_Sequencer_Type;

   
   type MIDI_Instrument_Record is new Device_Driver_Record with
      record
	 
	 Tempo_Sync : Tempo_Sync_Type(MIDI_Instrument_Record'Access);
	 Mod_Seq    : Mod_Sequencer_Type(MIDI_Instrument_Record'Access);
	 Printed        : Boolean := True;
	 Mutted         : Boolean := False;
	 Have_Drums_Kit : Boolean := False;
      end record;
   
   type MIDI_Instrument_Access is access all MIDI_Instrument_Record'Class;
   
   type Instrument_Id is new Positive range 1..128;
   
   type Orchester_Array is array (Instrument_Id range <>) of MIDI_Instrument_Access;
   
   type Bandmaster_Record(Device_Max : Instrument_Id) is tagged
      record
	 Orchester : Orchester_Array(1..Device_Max);
	 Inst_Last      : natural := 0;
      end record;
   
   type Bandmaster_Access is access all Bandmaster_Record;
   
   function Nb_Of_Instrument return Natural;
   
   procedure Initialize(Master : in out Bandmaster_Record; Ignore : in boolean);
   
   procedure Finalize(Master : in out Bandmaster_Record);
   
   Message_Max : constant Positive := 1024;
   
   subtype Message_Index is Positive range 1..Message_Max;
   
   
   
   package Step_Vectors is new Ada.Containers.Vectors(Message_Index, C.Long, C."=");
   
   subtype Step_Vector is Step_Vectors.Vector; 
   
   use Step_Vectors;
   
   type Step_Seq_Array is array (Positive range <>) of Step_Vectors.Vector;

   
end Computer.Midi.Sequencer ;