{-# LANGUAGE ExplicitForAll #-}

-- We export this stuff separately so we don't clutter up the
-- API of the Brillo 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 Brillo.Interface.Pure.Game (
  module Brillo.Data.Display,
  module Brillo.Data.Picture,
  module Brillo.Data.Color,
  play,
  Event (..),
  Key (..),
  SpecialKey (..),
  MouseButton (..),
  KeyState (..),
  Modifiers (..),
)
where

import Brillo.Data.Color
import Brillo.Data.Display
import Brillo.Data.Picture
import Brillo.Internals.Interface.Backend
import Brillo.Internals.Interface.Game


-- | 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 :: forall world.
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
      ()
_ <-
        GLFWState
-> 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
          GLFWState
defaultBackendState
          Display
display
          Color
backColor
          Int
simResolution
          world
worldStart
          (Picture -> IO Picture
forall a. a -> IO a
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 a. a -> IO a
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 a. a -> IO a
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 a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()