{-# LANGUAGE FlexibleContexts #-}
module CsoundExpr.Base.Score (
	Arrangeable(..),
	Time, Dur, Score, toList,
	dur, rest, stretch, note, delay,
	line, chord, loop, cut, tmap)
where

import CsoundExpr.Translator.Types(Time, Dur)
import qualified Temporal.Media as M
import Temporal.Media(Arrangeable(..))

-- | representing score
type Score a = M.MediaUnit Dur () a


-- | duration
dur :: M.Temporal Dur a => a -> Dur
dur = M.dur

-- | pause
rest :: M.Temporal Dur a => Dur -> a
rest = M.none

-- | stretch in time domain
stretch :: M.Stretchable Dur a => Dur -> a -> a
stretch = M.stretch

-- | constructor of score
note :: Dur -> a -> Score a
note = M.temp

delay :: (M.Temporal Dur a, Arrangeable a) => Dur -> a -> a
delay = M.delay

-- | sequential composition
line :: Arrangeable a => [a] -> a
line = M.sequent

-- | parallel composition
chord :: Arrangeable a => [a] -> a
chord = M.parallel

loop :: Arrangeable a => Int -> a -> a
loop = M.loop

-- | extracting score parts in some time interval.
-- it reverses output if @t1 < t0@.
cut :: Dur -> Dur -> Score a -> Score a
cut = M.cut

-- | temporal functor
tmap :: (Dur -> a -> b) -> Score a -> Score b
tmap = M.tmap

-- | transform 'Score' to 'EventList'
toList :: Score a -> M.EventList Dur a
toList = M.fromMediaUnit (const id)