{-# OPTIONS_HADDOCK hide #-}

-- |    The main display function.
module  Graphics.Gloss.Internals.Interface.Window
        ( createWindow )
where
import Graphics.Gloss.Data.Color
import Graphics.Gloss.Internals.Color
import Graphics.Gloss.Internals.Interface.Backend
import Graphics.Gloss.Internals.Interface.Debug
import Graphics.Rendering.OpenGL                        (($=))
import qualified Graphics.Rendering.OpenGL.GL           as GL
import Data.IORef (newIORef)
import Control.Monad

-- | Open a window and use the supplied callbacks to handle window events.
createWindow
        :: Backend a
        => a
        -> Display
        -> Color                -- ^ Color to use when clearing.
        -> [Callback]           -- ^ Callbacks to use
        -> IO ()

createWindow
        backend
        display
        clearColor
        callbacks
 = do
        -- Turn this on to spew debugging info to stdout
        let debug       = False

        -- Initialize backend state
        backendStateRef <- newIORef backend

        when debug
         $ do   putStr  $ "* displayInWindow\n"

        -- Intialize backend
        initializeBackend backendStateRef debug

        -- Here we go!
        when debug
         $ do   putStr  $ "* c window\n\n"

        -- Open window
        openWindow backendStateRef display

        -- Setup callbacks
        installDisplayCallback     backendStateRef callbacks
        installWindowCloseCallback backendStateRef
        installReshapeCallback     backendStateRef callbacks
        installKeyMouseCallback    backendStateRef callbacks
        installMotionCallback      backendStateRef callbacks
        installIdleCallback        backendStateRef callbacks

        -- we don't need the depth buffer for 2d.
        GL.depthFunc    $= Just GL.Always

        -- always clear the buffer to white
        GL.clearColor   $= glColor4OfColor clearColor

        -- Dump some debugging info
        when debug
         $ do   dumpBackendState backendStateRef
                dumpFramebufferState
                dumpFragmentState

        when debug
         $ do   putStr  $ "* entering mainloop..\n"

        -- Start the main backend loop
        runMainLoop backendStateRef

        when debug
         $      putStr  $ "* all done\n"

        return ()
