-- $Date: 2004/03/08 10:57:31 $
-- $Revision: 1.13 $
-- $Author: jcrocholl $
-- $Hash: 681e6d36a96164871f56ee25fc701ae0 $

-- This file was automatically created with ado.php.
-- Manual changes will be lost when it is updated.

with Ada.Tags; use Ada.Tags;
with Music; use Music;
with Pitches; use Pitches;
with Lyrics; use Lyrics;
with Lists;
with Notations;
with Notations.Slurs; use Notations.Slurs;
with Enum_Strings; use Enum_Strings;

package Music.Notes is

   type Filled_Enum is (Auto, Yes, No);
   function To_Filled_Enum is new To_Enum(Filled_Enum);

   type Note_Type_Enum is (Long, Breve, Whole, Half, Quarter, Eighth,
     N_16th, N_32nd, N_64th, N_128th, N_256th);
   function To_Note_Type_Enum is new To_Enum(Note_Type_Enum);

   type Natural_Array is array(Note_Type_Enum) of Natural;
   Note_Numbers : constant Natural_Array := (0, 0, 1, 2, 4, 8, 16, 32, 64, 128, 256);
   Flag_Counts  : constant Natural_Array := (0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6);

   type Stem_Enum is (Auto, Down, Up, None, Double);
   function To_Stem_Enum is new To_Enum(Stem_Enum);

   package Notation_Lists is new Lists(Notations.Notation_Access);
   subtype Notation_List is Notation_Lists.List;
   subtype Notation_List_Access is Notation_Lists.List_Access;

   type Note_Head_Enum is (Slash, Triangle, Diamond, Square, Cross, X,
     Circle_X, Normal, None);

   type Beam_State_Enum is (None, N_Begin, N_End, Continue);
   function To_Beam_State_Enum is new To_Enum(Beam_State_Enum);

   subtype Beam_Range is Positive range 1 .. 6;
   type Beam_Array is Array(Beam_Range) of Beam_State_Enum;

   -- Public representation.
   type Note is new Music_Data with private;

   -- Work-around for GNAT bug.
   Note_Tag : constant String;

   -- Pointer to representation data.
   type Note_Access is access all Note;

   -- Constructor for instances.
   function Create
     return Note_Access-- The newly created note.

   -- Mutator to update the note head of a note.
   procedure Set_Note_Head
     (This      : access Note;                  -- The note to be updated.
      Note_Head : in Note_Head_Enum := Normal); -- The new note head of that note.

   -- Accessor to read the note head of a note.
   function Get_Note_Head
     (This : access Note)   -- The note to read from.
     return Note_Head_Enum-- The note head of that note.

   -- Mutator to update the filled of a note.
   procedure Set_Filled
     (This   : access Note;             -- The note to be updated.
      Filled : in Filled_Enum := Auto); -- The new filled of that note.

   -- Mutator to update the grace of a note.
   procedure Set_Grace
     (This  : access Note;          -- The note to be updated.
      Grace : in Boolean := False); -- The new grace of that note.

   -- Accessor to read the grace of a note.
   function Get_Grace
     (This : access Note-- The note to read from.
     return Boolean;      -- The grace of that note.

   -- Mutator to update the chord of a note.
   procedure Set_Chord
     (This  : access Note;          -- The note to be updated.
      Chord : in Boolean := False); -- The new chord of that note.

   -- Accessor to read the chord of a note.
   function Get_Chord
     (This : access Note-- The note to read from.
     return Boolean;      -- The chord of that note.

   -- Mutator to update the pitch of a note.
   procedure Set_Pitch
     (This  : access Note;      -- The note to be updated.
      Pitch : in Pitch_Access); -- The new pitch of that note.

   -- Accessor to read the pitch of a note.
   function Get_Pitch
     (This : access Note-- The note to read from.
     return Pitch_Access-- The pitch of that note.

   -- Mutator to update the duration of a note.
   procedure Set_Duration
     (This     : access Note;       -- The note to be updated.
      Duration : in Positive := 1); -- The new duration of that note.

   -- Accessor to read the duration of a note.
   function Get_Duration
     (This : access Note-- The note to read from.
     return Positive;     -- The duration of that note.

   -- Mutator to update the voice of a note.
   procedure Set_Voice
     (This  : access Note;      -- The note to be updated.
      Voice : in Natural := 0); -- The new voice of that note.

   -- Accessor to read the voice of a note.
   function Get_Voice
     (This : access Note-- The note to read from.
     return Natural;      -- The voice of that note.

   -- Mutator to update the note type of a note.
   procedure Set_Note_Type
     (This      : access Note;                 -- The note to be updated.
      Note_Type : in Note_Type_Enum := Whole); -- The new note type of that note.

   -- Accessor to read the note type of a note.
   function Get_Note_Type
     (This : access Note)   -- The note to read from.
     return Note_Type_Enum-- The note type of that note.

   -- Accessor to read the dots of a note.
   function Get_Dots
     (This : access Note-- The note to read from.
     return Natural;      -- The dots of that note.

   -- Mutator to update the stem of a note.
   procedure Set_Stem
     (This : access Note;           -- The note to be updated.
      Stem : in Stem_Enum := Auto); -- The new stem of that note.

   -- Accessor to read the stem of a note.
   function Get_Stem
     (This : access Note-- The note to read from.
     return Stem_Enum;    -- The stem of that note.

   -- Mutator to update the staff of a note.
   procedure Set_Staff
     (This  : access Note;      -- The note to be updated.
      Staff : in Natural := 0); -- The new staff of that note.

   -- Accessor to read the staff of a note.
   function Get_Staff
     (This : access Note-- The note to read from.
     return Natural;      -- The staff of that note.

   -- Accessor to read the beams of a note.
   function Get_Beams
     (This : access Note-- The note to read from.
     return Beam_Array;   -- The beams of that note.

   -- Accessor to read the notations of a note.
   function Get_Notations
     (This : access Note)         -- The note to read from.
     return Notation_List_Access-- The notations of that note.

   -- Mutator to update the lyric of a note.
   procedure Set_Lyric
     (This  : access Note;      -- The note to be updated.
      Lyric : in Lyric_Access); -- The new lyric of that note.

   -- Accessor to read the lyric of a note.
   function Get_Lyric
     (This : access Note-- The note to read from.
     return Lyric_Access-- The lyric of that note.

   function Get_Filled
     (This : access Note-- The note object instance.
     return Boolean;      -- The note head fill.

   -- Add another dot.
   procedure Add_Dot
     (This : access Note); -- The note object instance.

   -- Set a beam to start, stop, continue.
   procedure Set_Beam_State
     (This  : access Note;         -- The note object instance.
      Index : in Beam_Range;       -- Set this beam.
      State : in Beam_State_Enum); -- Set beam to this state.

   -- Get a beam state.
   function Get_Beam_State
     (This  : access Note;   -- The note object instance.
      Index : in Beam_Range-- Get this beam.
     return Beam_State_Enum-- The beam's state.

   -- Add a notation element to a note.
   procedure Add_Notation
     (This : access Note;                           -- The note object instance.
      Add  : access Notations.Notation'Class); -- Add this notation.

   -- Return the pitch position relative to middle C.
   function Get_Position
     (This : access Note-- The note object instance.
     return Integer;      -- Up or down from middle C.

private

   -- Private representation.
   type Note is
     new Music_Data with
      record
         Note_Head : Note_Head_Enum := Normal;       -- Type of the note head.
         Filled    : Filled_Enum := Auto;            -- Explicitly filled or hollow.
         Grace     : Boolean := False;               -- This is a grace note.
         Chord     : Boolean := False;               -- Constitutes a chord with previous note.
         Pitch     : Pitch_Access;                   -- Vertical offset and sound frequency.
         Duration  : Positive := 1;                  -- Timing.
         Voice     : Natural := 0;                   -- For multiple voices in one staff.
         Note_Type : Note_Type_Enum := Whole;        -- Fraction type of the note.
         Dots      : Natural := 0;                   -- Count of dots extending the duration.
         Stem      : Stem_Enum := Auto;              -- Direction of the stem.
         Staff     : Natural := 0;                   -- For multiple staves in one part.
         Beams     : Beam_Array := (others => none); -- Connect stems with other chords.
         Notations : Notation_List_Access;           -- Additional symbols.
         Lyric     : Lyric_Access;                   -- Associated text.
      end record;

   -- Work-around for GNAT bug.
   Note_Tag : constant String := "music.notes.note";

end Music.Notes;