module LiveCoding.Gloss.PictureM (
  module LiveCoding.Gloss.PictureM,
  module X,
) where

-- transformers
import Control.Monad.Trans.Class
import Control.Monad.Trans.Reader as X
import Control.Monad.Trans.Writer.Strict

-- gloss
import Graphics.Gloss
import Graphics.Gloss.Interface.IO.Game

-- essence-of-live-coding
import LiveCoding

{- | The monad transformer that captures the effects of gloss,
which are reading events and writing pictures.

You can call these effects for example by...

* ...using 'ask' to read the events that occurred,
* ...composing a cell with 'addPicture' to paint a picture.
-}
type PictureT m = ReaderT [Event] (WriterT Picture m)

-- | 'PictureT' specialised to the 'IO' monad.
type PictureM = PictureT IO

-- | Run the effects of the gloss monad stack by explicitly passing events and pictures.
runPictureT ::
  Monad m =>
  Cell (PictureT m) a b ->
  Cell m ([Event], a) (Picture, b)
runPictureT :: forall (m :: * -> *) a b.
Monad m =>
Cell (PictureT m) a b -> Cell m ([Event], a) (Picture, b)
runPictureT = forall w (m :: * -> *) a b.
(Monoid w, Monad m) =>
Cell (WriterT w m) a b -> Cell m a (w, b)
runWriterC forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) r a b.
Monad m =>
Cell (ReaderT r m) a b -> Cell m (r, a) b
runReaderC'

addPicture :: Monad m => Cell (PictureT m) Picture ()
addPicture :: forall (m :: * -> *). Monad m => Cell (PictureT m) Picture ()
addPicture = forall a (m :: * -> *) b. (a -> m b) -> Cell m a b
arrM forall a b. (a -> b) -> a -> b
$ forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
tell