{-|
Module      : Timestamp
Description : A little module on timestamps
Copyright   : (c) David Janin, 2016
License     : see the LICENSE file in the distribution
Maintainer  : janin@labri.fr
Stability   : experimental

-}

{-# OPTIONS_GHC -Wall -fno-warn-name-shadowing #-}

module Reactive.TimeStamp where

-- | Time stamps
data TimeStamp d = TimeStamp {getTimeStamp :: !d} deriving (Show)

-- | Computes the difference between two timestamps
timeStampDelta :: Num d => TimeStamp d -> TimeStamp d -> d
timeStampDelta (TimeStamp d1) (TimeStamp d2) = d1 - d2


-- | Shifts a time stamp
shiftTimeStamp :: Num d => d -> TimeStamp d -> TimeStamp d
shiftTimeStamp d (TimeStamp d1) = TimeStamp (d1 + d)

-- | Equality on timestamps
instance (Eq d) => Eq (TimeStamp d) where
     (==) (TimeStamp d1) (TimeStamp d2) = d1 == d2

-- |  Total on times stamp
instance (Ord d) => Ord (TimeStamp d) where
     (<=) (TimeStamp d1) (TimeStamp d2) = d1 <= d2

-- | Constant delay wake order
data WakeUpOrder d = WakeUp (TimeStamp d) | NoWakeUp deriving (Show)

wakeToTime :: WakeUpOrder d -> Maybe (TimeStamp d)
wakeToTime (NoWakeUp) = Nothing
wakeToTime (WakeUp ts)  = Just ts
                        
-- | Equality on wake up order
instance (Eq d) => Eq (WakeUpOrder d) where
    (==) w1 w2 = case (w1,w2) of
                   (NoWakeUp, NoWakeUp) -> True
                   (WakeUp d1,WakeUp d2) -> d1 == d2
                   _ -> False

-- | Total order on wake up order
instance (Ord d) => Ord (WakeUpOrder d) where
    (<=) _ NoWakeUp = True
    (<=) NoWakeUp _ = False
                      -- NoWakeUp means wake up infty
    (<=) (WakeUp d1) (WakeUp d2) = d1 <= d2