{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}
-- | Special case of "Temporal.Media". Time is @Double@
module Temporal.Media.Double (
	-- * Time classes
	Dur, none, dur, stretch, ToMaybe(..), tmap,
	-- * Transformers
	Reversible(..), slice, take, drop, cut, 
	-- * Structure 
	Construct(..), Arrangeable(..), Controlable(..),
	sequent, parallel, loop, delay, temp,
	-- * Media
	Media(..), fold, fromMedia,
	-- * Simple interperetation
	-- ** Event list
	Event, EventList(..), 
	mapEvent, toEvent, toEventList,
	-- ** Unit Media
	MediaUnit(..), unMediaUnit, foldU, fromMediaUnit,
	Unit(..)
) 
where

import Prelude hiding (take, drop, reverse)
import Control.Applicative

import qualified Temporal.Media as M
import Temporal.Media (
	ToMaybe(..),
	Reversible(..), 
	Construct(..), Arrangeable(..), Controlable(..), 
	sequent, parallel, loop,
	Media(..), fold, fromMedia)

----------------------------------------
-- Time 
--

type Dur = Double

none :: M.Temporal Dur a => Dur -> a
none = M.none

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

stretch :: M.Stretchable Dur a => Dur -> a -> a
stretch = M.stretch

tmap :: M.TemporalFunctor Dur f => (Dur -> a -> b) -> (f a -> f b)
tmap = M.tmap

--------------------------------------------
-- transformers

slice :: M.Sliceable Dur a => Dur -> Dur -> a -> a
slice = M.slice

take :: M.Sliceable Dur a => Dur -> a -> a
take = M.take

drop :: M.Sliceable Dur a => Dur -> a -> a
drop = M.drop

cut :: (Reversible a, M.Sliceable Dur a) => Dur -> Dur -> a -> a
cut = M.cut

--------------------------------------------
-- Structure

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

temp :: (Construct m, M.Temporal Dur (m a), M.Stretchable Dur (m a)) 
	=> Dur -> a -> m a
temp = M.temp
	

--------------------------------------------
-- EventList

type Event a     = M.Event Dur a
type EventList a = M.EventList Dur a

mapEvent :: (a -> b) -> Event a -> Event b
mapEvent = M.mapEvent

toEvent :: (M.Temporal Dur (m a), ToMaybe m) => m a -> EventList a
toEvent = M.toEvent

toEventList :: (M.Temporal Dur (m a), ToMaybe m) 
	=> (c -> EventList a -> EventList a) 
	-> Media c (m a) -> EventList a
toEventList = M.toEventList

--------------------------------------------
-- MediaUnit

type MediaUnit c a = M.MediaUnit Dur c a

unMediaUnit :: MediaUnit c a -> Media c (Unit a)
unMediaUnit = M.unMediaUnit

foldU :: (Dur -> a -> b) -> (b -> b -> b) -> (b -> b -> b) -> (c -> b -> b)
	-> MediaUnit c a -> Maybe b
foldU = M.foldU

fromMediaUnit :: (c -> EventList a -> EventList a) -> MediaUnit c a -> EventList a
fromMediaUnit = M.fromMediaUnit

--------------------------------------------
-- Temp

type Unit a = M.Unit Dur a