-- 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-10 09:03:04"
-- Version := "0.0.0r"

package body Computer.Midi.Messages is
   use Interfaces.C;
   
   function To_Long(Message : in Message_Type) return C.Long is
      The_long: Unsigned_32 := 0;
      Low     : constant Unsigned_32 := Unsigned_32(Message.Data2);
      Middle  : constant Unsigned_32 := Unsigned_32(Message.Data1);
      High    : constant Unsigned_32 := Unsigned_32(Message.Status);                       
   begin      
      The_Long := ((Shift_Left(Low, 16) and 16#FF0000#) or
		     (Shift_Left(middle, 8) and 16#FF00#) or
		     (high and 16#FF#));
		    
      return Interfaces.C.Long(The_Long);	 
   end;
   
   function Message(Status, Data1, data2 : in C.Long) return Message_Type is
      Message : constant Message_Type := (Status, Data1, Data2);
   begin
      return Message;
   end Message;
   
   function Note_On(Channel : in Channel_Type;
                    Note : in Value_Type;
                    Sens : in Value_Type) return Message_Type is

      Message : constant Message_Type := (16#90# + Channel, Note, Sens);
   begin

      return Message;
   end;
   function Note_Off (Channel : in Channel_Type;
                     Note : in Value_Type) return Message_Type is
      Message : constant Message_Type := (16#80# + Channel, Note, 0);
   begin
      
      return Message;
   end;

   function All_Note_Off(Channel : in Channel_Type) return Message_Type is
      Message : constant Message_Type := (16#B0# + Channel, 16#7B#, 0);
   begin
      return Message;
   end All_Note_Off;

   function Bank_Select_MSB(Channel : in Channel_Type;
                            Bank : in Bank_Type) return Message_Type is

      Message : constant Message_Type := (16#B0# + channel,  0, Bank);
   begin

      return Message;
   end;

   function Bank_Select_LSB(Channel : in Channel_Type;
                            Bank : in Bank_Type) return Message_Type is

      Message : constant Message_Type := (16#B0# + channel, 32 , Bank);
   begin

      return Message;
   end;

   function Program_Change(Channel : in Channel_Type;
                           Program : in Program_Type) return Message_Type is

      Message : constant Message_Type := (16#C0# + channel, program, 0);
   begin

      return Message;
   end;         
   
   
   function NRPM_MSB (Channel : in Channel_Type;
                      Value : in Value_Type) return Message_Type is

      Message : constant Message_Type := (16#B0# + Channel, 99, Value);
   begin

      return Message;
   end;

   function NRPM_LSB (Channel : in Channel_Type;
                      Value : in Value_Type) return Message_Type is

      Message : constant Message_Type := (16#B0# + Channel, 98, Value);
   begin

      return Message;
   end;
   function Data_Entry_MSB (Channel : in Channel_Type;
                            Value : in Value_Type) return Message_Type is

      Message : constant Message_Type := (16#B0# + Channel, 6, Value);
   begin

      return Message;
   end;


   function Aftertouch(Channel : in Channel_Type;
                       Value : in Value_Type) return Message_Type is
      Message : constant Message_Type := (16#D0# + Channel, Value, 0);
   begin

      return Message;
   end;


   function PitchBend(Channel : in Channel_Type;
                      Data1 : in Value_Type;
                      Data2 : in Value_Type) return Message_Type is
      Message : constant Message_Type := (16#E0# + Channel, data1, data2);
   begin

      return Message;
   end;

   function ControlCommand(Channel : in Channel_Type;
                           Data1 : in Value_Type;
                           Data2 : in Value_Type) return Message_Type is
      Message : constant Message_Type := (16#B0# + Channel, Data1, data2);
   begin
      return Message;
   end;


   function Arp_Type_Switch(Channel : in Channel_Type;
                            Switch : in Natural) return Message_Type is

      Message : Message_Type;
   begin


      return Message;
   end;
   function Arp_Gate(Channel : in Channel_Type;
                     Gate : in T_Arp_Gate) return Message_Type is

      Message : Message_Type;
   begin


      return Message;
   end;
   function Arp_Select(Channel : in Channel_Type;
                       Switch : in Natural) return Message_Type is

      Message : Message_Type;
   begin


      return Message;
   end;
   function Step_Seq_1_Latch_Off return Message_Type is

      Message : Message_Type;
   begin


      return Message;
   end;
   function Step_Seq_1_Latch_On return Message_Type is

      Message : Message_Type;
   begin


      return Message;
   end;
   function Step_Seq_1_Gate(Gate : in T_Step_Seq_1_Gate) return Message_Type is

      Message : Message_Type;
   begin


      return Message;
   end;
   function Step_Seq_2_Gate(Gate : in T_Step_Seq_2_Gate) return Message_Type is

      Message : Message_Type;
   begin


      return Message;
   end;
end Computer.Midi.Messages ;