module Music.Typesetting.Model where

import Music.Theory.Clef
import Music.Theory.Duration
import Music.Theory.Dynamic_Mark
import Music.Theory.Key
import Music.Theory.Pitch
import Music.Theory.Tempo_Marking
import Music.Theory.Time_Signature

type Font_Family_T = String

data Font_Style_T = Font_Style_Normal
                  | Font_Style_Italic
                    deriving (Eq,Ord,Enum,Show)

type Font_Size_T = Int

data Font_Weight_T = Font_Weight_Normal
                   | Font_Weight_Bold
                     deriving (Eq,Ord,Enum,Show)

data Font_T = Font Font_Family_T Font_Style_T Font_Size_T Font_Weight_T
              deriving (Eq,Ord,Show)

data Articulation_T = Accent
                    | Staccato
                    | Strong_Accent
                    | Tenuto
                      deriving (Eq,Ord,Enum,Show)

data Ornament_T = Trill_Mark
                  deriving (Eq,Ord,Enum,Show)

data Harmonic_T = Natural_Harmonic
                | Artifical_Harmonic
                  deriving (Eq,Ord,Enum,Show)

data Technical_T = Up_Bow
                 | Down_Bow
                 | Harmonic Harmonic_T
                 | Open_String
                 | Stopped
                 | Snap_Pizzicato
                 | Other_Technical (Maybe Font_T) String
                  deriving (Eq,Ord,Show)

data Placement_T = Above | Below
                   deriving (Eq,Ord,Enum,Show)

type Tuplet_T = (Integer,Duration,Integer,Duration)

data Pedal_T = Pedal_Start | Pedal_Stop | Pedal_Continue | Pedal_Change
               deriving (Eq,Ord,Enum,Show)

data Sound_T = Sound_Tempo Double -- q = mm
             | Sound_Dynamics Double -- % of F (where F=90)
               deriving (Eq,Ord,Show)

data Direction_T = D_Dynamic_Mark Dynamic_Mark_T
                 | D_Hairpin Hairpin_T
                 | D_Laissez_Vibrer
                 | D_Tempo_Marking Tempo_Marking
                 | D_Pedal {pedal_type :: Pedal_T
                           ,pedal_line :: Bool
                           ,pedal_sign :: Bool}
                    deriving (Eq,Ord,Show)

data Beam_T = Beam_Begin | Beam_Continue | Beam_End
               deriving (Eq,Ord,Enum,Show)

data Notehead_T = Notehead_Triangle
                | Notehead_Diamond
                | Notehead_Square
                | Notehead_Cross
                  deriving (Eq,Ord,Enum,Show)

-- | Ordered to meet musicxml requirements.
data N_Annotation = N_Grace | N_Chord
                  | N_Pitch Pitch | N_Unpitched
                  | N_Rest
                  | N_Notehead Notehead_T
                  | N_Staff Integer
                  | N_Beam Integer Beam_T
                    -- BEGIN NOTATIONS
                  | N_Begin_Tied | N_End_Tied
                  | N_Begin_Slur | N_End_Slur
                  | N_Begin_Tuplet (Maybe Tuplet_T) | N_End_Tuplet
                  | N_Begin_Glissando | N_End_Glissando
                  | N_Begin_Slide | N_End_Slide
                  | N_Stem_Tremolo Integer
                  | N_Ornament Ornament_T
                  | N_Technical Technical_T
                  | N_Articulation Articulation_T
                  | N_Fermata
                  | N_Arpeggiate
                    -- END NOTATIONS
                  | N_Direction Direction_T
                  | N_Voice Integer
                  | N_Backup [Duration]
                    deriving (Eq,Ord,Show)

data Note = Note {n_duration :: Duration
                 ,n_annotations :: [N_Annotation]}
            deriving (Eq,Show)

data M_Annotation = M_Division Integer
                  | M_Key Note_T (Maybe Alteration_T) Mode_T
                  | M_Time_Signature Time_Signature
                  | M_Staves Integer
                  | M_Clef (Clef Integer) Integer
                  | M_Direction Direction_T
                    deriving (Eq,Ord,Show)

data Measure = Measure { m_annotations :: [M_Annotation]
                       , m_notes :: [Note] }
               deriving (Eq,Show)

type Name = (String,String)

data Group_Symbol_T = None
                    | Brace
                    | Line
                    | Bracket
                      deriving (Eq,Show)

data P_Annotation = P_Name Name
                    deriving (Eq,Show)

data G_Annotation = G_Name Name
                  | G_Symbol Group_Symbol_T
                    deriving (Eq,Show)

type ID = Integer

data Part = Part (Maybe ID) [P_Annotation] [Measure]
          | Group (Maybe ID) [G_Annotation] [Part]
            deriving (Eq,Show)

data Score = Score [Part]
             deriving (Eq,Show)