    --------------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.Rendering.OpenGL.GL.PixelRectangles.Minmax
    -- Copyright   :  (c) Sven Panne 2002-2019
    -- License     :  BSD3
    --
    -- Maintainer  :  Sven Panne <svenpanne@gmail.com>
    -- Stability   :  stable
    -- Portability :  portable
    --
    -- This module corresponds to a part of section 3.6.1 (Pixel Storage Modes) of
    -- the OpenGL 2.1 specs.
    --
    --------------------------------------------------------------------------------

    module Graphics.Rendering.OpenGL.GL.PixelRectangles.Minmax (
       minmax, getMinmax, resetMinmax
    ) where

    import Data.StateVar
    import Foreign.Marshal.Utils
    import Graphics.Rendering.OpenGL.GL.Capability
    import Graphics.Rendering.OpenGL.GL.PeekPoke
    import Graphics.Rendering.OpenGL.GL.PixelData
    import Graphics.Rendering.OpenGL.GL.PixelRectangles.Reset
    import Graphics.Rendering.OpenGL.GL.PixelRectangles.Sink
    import Graphics.Rendering.OpenGL.GL.Texturing.PixelInternalFormat
    import Graphics.GL

    --------------------------------------------------------------------------------

    data MinmaxTarget =
         Minmax

    marshalMinmaxTarget :: MinmaxTarget -> GLenum
    marshalMinmaxTarget :: MinmaxTarget -> GLenum
    marshalMinmaxTarget MinmaxTarget
    x = case MinmaxTarget
    x of
       MinmaxTarget
    Minmax -> GLenum
    GL_MINMAX

    --------------------------------------------------------------------------------

    minmax :: StateVar (Maybe (PixelInternalFormat, Sink))
    minmax :: StateVar (Maybe (PixelInternalFormat, Sink))
    minmax = IO EnableCap
    -> IO (PixelInternalFormat, Sink)
    -> ((PixelInternalFormat, Sink) -> IO ())
    -> StateVar (Maybe (PixelInternalFormat, Sink))
    forall a.
    IO EnableCap -> IO a -> (a -> IO ()) -> StateVar (Maybe a)
    makeStateVarMaybe (EnableCap -> IO EnableCap
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return EnableCap
    CapMinmax) IO (PixelInternalFormat, Sink)
    getMinmax' (PixelInternalFormat, Sink) -> IO ()
    setMinmax

    getMinmax' :: IO (PixelInternalFormat, Sink)
    getMinmax' :: IO (PixelInternalFormat, Sink)
    getMinmax' = do
       f <- (GLint -> PixelInternalFormat)
    -> GetMinmaxParameterPName -> IO PixelInternalFormat
    forall a. (GLint -> a) -> GetMinmaxParameterPName -> IO a
    getMinmaxParameteri GLint -> PixelInternalFormat
    unmarshalPixelInternalFormat GetMinmaxParameterPName
    MinmaxFormat
       s <- getMinmaxParameteri unmarshalSink MinmaxSink
       return (f, s)

    setMinmax :: (PixelInternalFormat, Sink) -> IO ()
    setMinmax :: (PixelInternalFormat, Sink) -> IO ()
    setMinmax (PixelInternalFormat
    int, Sink
    sink) =
       GLenum -> GLenum -> GLboolean -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLenum -> GLenum -> GLboolean -> m ()
    glMinmax
          (MinmaxTarget -> GLenum
    marshalMinmaxTarget MinmaxTarget
    Minmax)
          (PixelInternalFormat -> GLenum
    marshalPixelInternalFormat' PixelInternalFormat
    int)
          (Sink -> GLboolean
    marshalSink Sink
    sink)

    --------------------------------------------------------------------------------

    getMinmax :: Reset -> PixelData a -> IO ()
    getMinmax :: forall a. Reset -> PixelData a -> IO ()
    getMinmax Reset
    reset PixelData a
    pd =
       PixelData a -> (GLenum -> GLenum -> Ptr a -> IO ()) -> IO ()
    forall a b. PixelData a -> (GLenum -> GLenum -> Ptr a -> b) -> b
    withPixelData PixelData a
    pd ((GLenum -> GLenum -> Ptr a -> IO ()) -> IO ())
    -> (GLenum -> GLenum -> Ptr a -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          GLenum -> GLboolean -> GLenum -> GLenum -> Ptr a -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLenum -> GLboolean -> GLenum -> GLenum -> Ptr a -> m ()
    glGetMinmax (MinmaxTarget -> GLenum
    marshalMinmaxTarget MinmaxTarget
    Minmax) (Reset -> GLboolean
    marshalReset Reset
    reset)

    --------------------------------------------------------------------------------

    resetMinmax :: IO ()
    resetMinmax :: IO ()
    resetMinmax = GLenum -> IO ()
    forall (m :: * -> *). MonadIO m => GLenum -> m ()
    glResetMinmax (MinmaxTarget -> GLenum
    marshalMinmaxTarget MinmaxTarget
    Minmax)

    --------------------------------------------------------------------------------

    data GetMinmaxParameterPName =
         MinmaxFormat
       | MinmaxSink

    marshalGetMinmaxParameterPName :: GetMinmaxParameterPName -> GLenum
    marshalGetMinmaxParameterPName :: GetMinmaxParameterPName -> GLenum
    marshalGetMinmaxParameterPName GetMinmaxParameterPName
    x = case GetMinmaxParameterPName
    x of
       GetMinmaxParameterPName
    MinmaxFormat -> GLenum
    GL_MINMAX_FORMAT
       GetMinmaxParameterPName
    MinmaxSink -> GLenum
    GL_MINMAX_SINK

    --------------------------------------------------------------------------------

    getMinmaxParameteri :: (GLint -> a) -> GetMinmaxParameterPName -> IO a
    getMinmaxParameteri :: forall a. (GLint -> a) -> GetMinmaxParameterPName -> IO a
    getMinmaxParameteri GLint -> a
    f GetMinmaxParameterPName
    p =
       GLint -> (Ptr GLint -> IO a) -> IO a
    forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
    with GLint
    0 ((Ptr GLint -> IO a) -> IO a) -> (Ptr GLint -> IO a) -> IO a
    forall a b. (a -> b) -> a -> b
    $ \Ptr GLint
    buf -> do
          GLenum -> GLenum -> Ptr GLint -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLenum -> GLenum -> Ptr GLint -> m ()
    glGetMinmaxParameteriv
             (MinmaxTarget -> GLenum
    marshalMinmaxTarget MinmaxTarget
    Minmax)
             (GetMinmaxParameterPName -> GLenum
    marshalGetMinmaxParameterPName GetMinmaxParameterPName
    p)
             Ptr GLint
    buf
          (GLint -> a) -> Ptr GLint -> IO a
    forall a b. Storable a => (a -> b) -> Ptr a -> IO b
    peek1 GLint -> a
    f Ptr GLint
    buf