module Reflex.Host.Class where
import Reflex.Class
import Control.Applicative
import Control.Monad
import Control.Monad.Fix
import Control.Monad.Identity
import Control.Monad.Trans
import Control.Monad.Trans.Reader (ReaderT())
import Control.Monad.Trans.Writer (WriterT())
import Control.Monad.Trans.Cont   (ContT())
import Control.Monad.Trans.Except (ExceptT())
import Control.Monad.Trans.RWS    (RWST())
import Control.Monad.Trans.State  (StateT())
import qualified Control.Monad.Trans.State.Strict as Strict
import Data.Dependent.Sum (DSum (..))
import Data.Monoid
import Data.GADT.Compare
import Control.Monad.Ref
import Prelude hiding (mapM, mapM_, sequence, sequence_, foldl)
class (Reflex t, MonadReflexCreateTrigger t (HostFrame t), MonadSample t (HostFrame t), MonadHold t (HostFrame t), MonadFix (HostFrame t), MonadSubscribeEvent t (HostFrame t)) => ReflexHost t where
  type EventTrigger t :: * -> *
  type EventHandle t :: * -> *
  type HostFrame t :: * -> *
class (Reflex t, Monad m) => MonadSubscribeEvent t m | m -> t where
  
  
  
  
  
  
  
  
  
  
  subscribeEvent :: Event t a -> m (EventHandle t a)
class (ReflexHost t, Applicative m, Monad m) => MonadReadEvent t m | m -> t where
  
  
  
  
  
  
  
  readEvent :: EventHandle t a -> m (Maybe (m a))
class (Applicative m, Monad m) => MonadReflexCreateTrigger t m | m -> t where
  
  
  
  
  
  
  
  
  
  
  
  newEventWithTrigger :: (EventTrigger t a -> IO (IO ())) -> m (Event t a)
  newFanEventWithTrigger :: GCompare k => (forall a. k a -> EventTrigger t a -> IO (IO ())) -> m (EventSelector t k)
class (ReflexHost t, MonadReflexCreateTrigger t m, MonadSubscribeEvent t m, MonadReadEvent t (ReadPhase m), MonadSample t (ReadPhase m), MonadHold t (ReadPhase m)) => MonadReflexHost t m | m -> t where
  type ReadPhase m :: * -> *
  
  
  
  
  
  
  
  
  
  
  
  
  
  fireEventsAndRead :: [DSum (EventTrigger t) Identity] -> (ReadPhase m a) -> m a
  
  
  
  
  
  
  
  runHostFrame :: HostFrame t a -> m a
fireEvents :: MonadReflexHost t m => [DSum (EventTrigger t) Identity] -> m ()
fireEvents dm = fireEventsAndRead dm $ return ()
newEventWithTriggerRef :: (MonadReflexCreateTrigger t m, MonadRef m, Ref m ~ Ref IO) => m (Event t a, Ref m (Maybe (EventTrigger t a)))
newEventWithTriggerRef = do
  rt <- newRef Nothing
  e <- newEventWithTrigger $ \t -> do
    writeRef rt $ Just t
    return $ writeRef rt Nothing
  return (e, rt)
fireEventRef :: (MonadReflexHost t m, MonadRef m, Ref m ~ Ref IO) => Ref m (Maybe (EventTrigger t a)) -> a -> m ()
fireEventRef mtRef input = do
  mt <- readRef mtRef
  case mt of
    Nothing -> return ()
    Just trigger -> fireEvents [trigger :=> Identity input]
fireEventRefAndRead :: (MonadReflexHost t m, MonadRef m, Ref m ~ Ref IO) => Ref m (Maybe (EventTrigger t a)) -> a -> EventHandle t b -> m (Maybe b)
fireEventRefAndRead mtRef input e = do
  mt <- readRef mtRef
  case mt of
    Nothing -> return Nothing 
    Just trigger -> fireEventsAndRead [trigger :=> Identity input] $ do
      mGetValue <- readEvent e
      case mGetValue of
        Nothing -> return Nothing
        Just getValue -> liftM Just getValue
instance MonadReflexCreateTrigger t m => MonadReflexCreateTrigger t (ReaderT r m) where
  newEventWithTrigger = lift . newEventWithTrigger
  newFanEventWithTrigger initializer = lift $ newFanEventWithTrigger initializer
instance MonadSubscribeEvent t m => MonadSubscribeEvent t (ReaderT r m) where
  subscribeEvent = lift . subscribeEvent
instance MonadReflexHost t m => MonadReflexHost t (ReaderT r m) where
  type ReadPhase (ReaderT r m) = ReadPhase m
  fireEventsAndRead dm a = lift $ fireEventsAndRead dm a
  runHostFrame = lift . runHostFrame
instance (MonadReflexCreateTrigger t m, Monoid w) => MonadReflexCreateTrigger t (WriterT w m) where
  newEventWithTrigger = lift . newEventWithTrigger
  newFanEventWithTrigger initializer = lift $ newFanEventWithTrigger initializer
instance (MonadSubscribeEvent t m, Monoid w) => MonadSubscribeEvent t (WriterT w m) where
  subscribeEvent = lift . subscribeEvent
instance (MonadReflexHost t m, Monoid w) => MonadReflexHost t (WriterT w m) where
  type ReadPhase (WriterT w m) = ReadPhase m
  fireEventsAndRead dm a = lift $ fireEventsAndRead dm a
  runHostFrame = lift . runHostFrame
instance MonadReflexCreateTrigger t m => MonadReflexCreateTrigger t (StateT s m) where
  newEventWithTrigger = lift . newEventWithTrigger
  newFanEventWithTrigger initializer = lift $ newFanEventWithTrigger initializer
instance MonadSubscribeEvent t m => MonadSubscribeEvent t (StateT r m) where
  subscribeEvent = lift . subscribeEvent
instance MonadReflexHost t m => MonadReflexHost t (StateT s m) where
  type ReadPhase (StateT s m) = ReadPhase m
  fireEventsAndRead dm a = lift $ fireEventsAndRead dm a
  runHostFrame = lift . runHostFrame
  
  
instance MonadReflexCreateTrigger t m => MonadReflexCreateTrigger t (Strict.StateT s m) where
  newEventWithTrigger = lift . newEventWithTrigger
  newFanEventWithTrigger initializer = lift $ newFanEventWithTrigger initializer
instance MonadSubscribeEvent t m => MonadSubscribeEvent t (Strict.StateT r m) where
  subscribeEvent = lift . subscribeEvent
instance MonadReflexHost t m => MonadReflexHost t (Strict.StateT s m) where
  type ReadPhase (Strict.StateT s m) = ReadPhase m
  fireEventsAndRead dm a = lift $ fireEventsAndRead dm a
  runHostFrame = lift . runHostFrame  
  
  
instance MonadReflexCreateTrigger t m => MonadReflexCreateTrigger t (ContT r m) where
  newEventWithTrigger = lift . newEventWithTrigger
  newFanEventWithTrigger initializer = lift $ newFanEventWithTrigger initializer
instance MonadSubscribeEvent t m => MonadSubscribeEvent t (ContT r m) where
  subscribeEvent = lift . subscribeEvent
instance MonadReflexHost t m => MonadReflexHost t (ContT r m) where
  type ReadPhase (ContT r m) = ReadPhase m
  fireEventsAndRead dm a = lift $ fireEventsAndRead dm a
  runHostFrame = lift . runHostFrame
instance MonadReflexCreateTrigger t m => MonadReflexCreateTrigger t (ExceptT e m) where
  newEventWithTrigger = lift . newEventWithTrigger
  newFanEventWithTrigger initializer = lift $ newFanEventWithTrigger initializer
instance MonadSubscribeEvent t m => MonadSubscribeEvent t (ExceptT r m) where
  subscribeEvent = lift . subscribeEvent
instance MonadReflexHost t m => MonadReflexHost t (ExceptT e m) where
  type ReadPhase (ExceptT e m) = ReadPhase m
  fireEventsAndRead dm a = lift $ fireEventsAndRead dm a
  runHostFrame = lift . runHostFrame
instance (MonadReflexCreateTrigger t m, Monoid w) => MonadReflexCreateTrigger t (RWST r w s m) where
  newEventWithTrigger = lift . newEventWithTrigger
  newFanEventWithTrigger initializer = lift $ newFanEventWithTrigger initializer
instance (MonadSubscribeEvent t m, Monoid w) => MonadSubscribeEvent t (RWST r w s m) where
  subscribeEvent = lift . subscribeEvent
instance (MonadReflexHost t m, Monoid w) => MonadReflexHost t (RWST r w s m) where
  type ReadPhase (RWST r w s m) = ReadPhase m
  fireEventsAndRead dm a = lift $ fireEventsAndRead dm a
  runHostFrame = lift . runHostFrame