module Duration(Duration,toticksandrest,quantize) where

import qualified Midi
import Data.Ratio

class (RealFrac d) => Duration d where
    toticksandrest::Midi.DeltaTime->d->(Midi.DeltaTime,d)

instance (Integral i) => Duration (Ratio i) where
    toticksandrest ticksperunit duration =
        let factor = (fromIntegral ticksperunit) % 1
            scaled = factor * duration
            ticks = fromIntegral (floor scaled)
            rest = (scaled - (fromIntegral ticks % 1)) / factor
        in (ticks,rest)


quantize::Duration d => Midi.DeltaTime -> [(d,a)]->[(Midi.DeltaTime,a)]
quantize unitstep stream = fst (quantize' unitstep stream 0)

quantize'::Duration d => Midi.DeltaTime ->[(d,a)]->d->([(Midi.DeltaTime,a)],d)
quantize' unitstep stream remainder =
    case stream of
      [] -> ([],remainder)
      ((d,x):xs) -> let (d',remainder') = toticksandrest unitstep (d+remainder)
                        (tail,remainder'') = quantize' unitstep xs remainder'
                    in ((d',x):tail,remainder'')
