    module Lambdabot.Plugin.Social.Seen.StopWatch where

    import Lambdabot.Compat.AltTime

    import Data.Binary

    data StopWatch
        = Stopped !TimeDiff
        | Running !ClockTime
        deriving (Int -> StopWatch -> ShowS
    [StopWatch] -> ShowS
    StopWatch -> String
    (Int -> StopWatch -> ShowS)
    -> (StopWatch -> String)
    -> ([StopWatch] -> ShowS)
    -> Show StopWatch
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [StopWatch] -> ShowS
    $cshowList :: [StopWatch] -> ShowS
    show :: StopWatch -> String
    $cshow :: StopWatch -> String
    showsPrec :: Int -> StopWatch -> ShowS
    $cshowsPrec :: Int -> StopWatch -> ShowS
    Show,ReadPrec [StopWatch]
    ReadPrec StopWatch
    Int -> ReadS StopWatch
    ReadS [StopWatch]
    (Int -> ReadS StopWatch)
    -> ReadS [StopWatch]
    -> ReadPrec StopWatch
    -> ReadPrec [StopWatch]
    -> Read StopWatch
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [StopWatch]
    $creadListPrec :: ReadPrec [StopWatch]
    readPrec :: ReadPrec StopWatch
    $creadPrec :: ReadPrec StopWatch
    readList :: ReadS [StopWatch]
    $creadList :: ReadS [StopWatch]
    readsPrec :: Int -> ReadS StopWatch
    $creadsPrec :: Int -> ReadS StopWatch
    Read)

    instance Binary StopWatch where
        put :: StopWatch -> Put
    put (Stopped td :: TimeDiff
    td) = Word8 -> Put
    putWord8 0 Put -> Put -> Put
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TimeDiff -> Put
    forall t. Binary t => t -> Put
    put TimeDiff
    td
        put (Running ct :: ClockTime
    ct) = Word8 -> Put
    putWord8 1 Put -> Put -> Put
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ClockTime -> Put
    forall t. Binary t => t -> Put
    put ClockTime
    ct

        get :: Get StopWatch
    get = Get Word8
    getWord8 Get Word8 -> (Word8 -> Get StopWatch) -> Get StopWatch
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \h :: Word8
    h -> case Word8
    h of
            0 -> (TimeDiff -> StopWatch) -> Get TimeDiff -> Get StopWatch
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap TimeDiff -> StopWatch
    Stopped Get TimeDiff
    forall t. Binary t => Get t
    get
            1 -> (ClockTime -> StopWatch) -> Get ClockTime -> Get StopWatch
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ClockTime -> StopWatch
    Running Get ClockTime
    forall t. Binary t => Get t
    get
            _ -> String -> Get StopWatch
    forall a. HasCallStack => String -> a
    error "Seen.StopWatch.get"

    zeroWatch :: StopWatch
    zeroWatch :: StopWatch
    zeroWatch = TimeDiff -> StopWatch
    Stopped TimeDiff
    noTimeDiff

    startWatch :: ClockTime -> StopWatch -> StopWatch
    startWatch :: ClockTime -> StopWatch -> StopWatch
    startWatch now :: ClockTime
    now (Stopped td :: TimeDiff
    td) = ClockTime -> StopWatch
    Running (TimeDiff
    td TimeDiff -> ClockTime -> ClockTime
    `addToClockTime` ClockTime
    now)
    startWatch _ alreadyStarted :: StopWatch
    alreadyStarted = StopWatch
    alreadyStarted

    stopWatch :: ClockTime -> StopWatch -> StopWatch
    stopWatch :: ClockTime -> StopWatch -> StopWatch
    stopWatch now :: ClockTime
    now (Running t :: ClockTime
    t)  = TimeDiff -> StopWatch
    Stopped (ClockTime
    t ClockTime -> ClockTime -> TimeDiff
    `diffClockTimes` ClockTime
    now)
    stopWatch _ alreadyStopped :: StopWatch
    alreadyStopped = StopWatch
    alreadyStopped