-- | Have you ever wondered why, when using a microwave, pressing \"60\" is the same as pressing \"100\"? Well wonder no longer! I, through epic trials and hardships, have tamed the vexacious wiles of that most enigmatic appliance.
--
--   @
--     λ> let n = 200 :: Microwave
--     λ> n
--        2:00
--     λ> n > 150
--        True
--     λ> n > 170
--        False
--     λ> n \`quotRem\` 7
--        (0:17,0:01)
--   @
module Data.Microwave (Microwave) where

newtype Microwave = Microwave {fromMicrowave :: Integer}

instance Show Microwave where
  show (Microwave n) = let (mins, secs) = n `quotRem` 100
                           secs' = case (show secs) of
                                     [c] -> '0':[c]
                                     s -> s
                       in show mins ++ ":" ++ secs'

instance Read Microwave where
  readsPrec n s = let s' = filter (/= ':') s in map (\(n, r) -> (fixSecs n, r)) $ readsPrec n s'

fixSecs n = let (mins, secs) = n `quotRem` 100
                (carry, secs') = secs `quotRem` 60
            in Microwave (100 * (mins + carry) + secs')

-- turn display time into raw seconds
normalize (Microwave n) = let (mins, secs) = n `quotRem` 100 in 60 * mins + secs

-- turn raw seconds into display time
denormalize n = let (mins, secs) = n `quotRem` 60 in Microwave (100 * mins + secs)

instance Eq Microwave where
  n == m = normalize n == normalize m

instance Ord Microwave where
  n `compare` m = normalize n `compare` normalize m

instance Enum Microwave where
  fromEnum = fromInteger . normalize
  toEnum = denormalize . toInteger

instance Num Microwave where
  fromInteger = fixSecs
  n + m = denormalize (normalize n + normalize m)
  n * m = denormalize (normalize n * normalize m)
  abs = Microwave . abs . fromMicrowave
  signum = Microwave . signum . fromMicrowave

instance Real Microwave where
  toRational = toRational . normalize

instance Integral Microwave where
  toInteger = normalize
  quotRem n m = let (q, r) = quotRem (normalize n) (normalize m) in (denormalize q, denormalize r)