{-# LANGUAGE ExplicitForAll #-}

-- We export this stuff separately so we don't clutter up the
-- API of the Graphics.Gloss module.

-- | This game mode lets you manage your own input. Pressing ESC will still abort the program,
--   but you don't get automatic pan and zoom controls like with `displayInWindow`.
module Graphics.Gloss.Interface.Pure.Game
        ( module Graphics.Gloss.Data.Display
        , module Graphics.Gloss.Data.Picture
        , module Graphics.Gloss.Data.Color
        , play
        , Event(..), Key(..), SpecialKey(..), MouseButton(..), KeyState(..), Modifiers(..))
where
import Graphics.Gloss.Data.Display
import Graphics.Gloss.Data.Picture
import Graphics.Gloss.Data.Color
import Graphics.Gloss.Internals.Interface.Game
import Graphics.Gloss.Internals.Interface.Backend


-- | Play a game in a window. Like `simulate`, but you manage your own input events.
play    :: Display              -- ^ Display mode.
        -> Color                -- ^ Background color.
        -> Int                  -- ^ Number of simulation steps to take for each second of real time.
        -> world                -- ^ The initial world.
        -> (world -> Picture)   -- ^ A function to convert the world a picture.
        -> (Event -> world -> world)
                -- ^ A function to handle input events.
        -> (Float -> world -> world)
                -- ^ A function to step the world one iteration.
                --   It is passed the period of time (in seconds) needing to be advanced.
        -> IO ()

play :: Display
-> Color
-> Int
-> world
-> (world -> Picture)
-> (Event -> world -> world)
-> (Float -> world -> world)
-> IO ()
play    Display
display Color
backColor Int
simResolution
        world
worldStart world -> Picture
worldToPicture Event -> world -> world
worldHandleEvent Float -> world -> world
worldAdvance

 = do   ()
_       <- GLUTState
-> Display
-> Color
-> Int
-> world
-> (world -> IO Picture)
-> (Event -> world -> IO world)
-> (Float -> world -> IO world)
-> Bool
-> IO ()
forall world a.
Backend a =>
a
-> Display
-> Color
-> Int
-> world
-> (world -> IO Picture)
-> (Event -> world -> IO world)
-> (Float -> world -> IO world)
-> Bool
-> IO ()
playWithBackendIO GLUTState
defaultBackendState
                        Display
display Color
backColor Int
simResolution
                        world
worldStart
                        (Picture -> IO Picture
forall (m :: * -> *) a. Monad m => a -> m a
return (Picture -> IO Picture)
-> (world -> Picture) -> world -> IO Picture
forall b c a. (b -> c) -> (a -> b) -> a -> c
. world -> Picture
worldToPicture)
                        (\Event
event world
world -> world -> IO world
forall (m :: * -> *) a. Monad m => a -> m a
return (world -> IO world) -> world -> IO world
forall a b. (a -> b) -> a -> b
$ Event -> world -> world
worldHandleEvent Event
event world
world)
                        (\Float
time  world
world -> world -> IO world
forall (m :: * -> *) a. Monad m => a -> m a
return (world -> IO world) -> world -> IO world
forall a b. (a -> b) -> a -> b
$ Float -> world -> world
worldAdvance     Float
time  world
world)
                        Bool
True
        () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()