module Mensam.Client.Application.Event.Class where

import Mensam.Client.UI.Brick.Events

import Brick.BChan
import Control.Monad.Trans
import Control.Monad.Trans.Compose
import Control.Monad.Trans.Elevator
import Data.Kind

type MonadEvent :: (Type -> Type) -> Constraint
class Monad m => MonadEvent m where
  sendEvent :: ClientEvent -> m ()
  eventChannel :: m (BChan ClientEvent)

instance
  ( Monad (t m)
  , MonadTrans t
  , MonadEvent m
  ) =>
  MonadEvent (Elevator t m)
  where
  sendEvent :: ClientEvent -> Elevator t m ()
sendEvent = m () -> Elevator t m ()
forall (m :: * -> *) a. Monad m => m a -> Elevator t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> Elevator t m ())
-> (ClientEvent -> m ()) -> ClientEvent -> Elevator t m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ClientEvent -> m ()
forall (m :: * -> *). MonadEvent m => ClientEvent -> m ()
sendEvent
  eventChannel :: Elevator t m (BChan ClientEvent)
eventChannel = m (BChan ClientEvent) -> Elevator t m (BChan ClientEvent)
forall (m :: * -> *) a. Monad m => m a -> Elevator t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (BChan ClientEvent)
forall (m :: * -> *). MonadEvent m => m (BChan ClientEvent)
eventChannel

deriving via
  Elevator t1 ((t2 :: (Type -> Type) -> Type -> Type) m)
  instance
  {-# OVERLAPPABLE #-}
    ( Monad (t1 (t2 m))
    , MonadTrans t1
    , MonadEvent (t2 m)
    ) =>
    MonadEvent (ComposeT t1 t2 m)