-- #hide
--------------------------------------------------------------------------------
-- |
-- Module      :  Graphics.Rendering.OpenGL.GL.QueryUtils
-- Copyright   :  (c) Sven Panne 2002-2009
-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
--
-- Maintainer  :  sven.panne@aedion.de
-- Stability   :  stable
-- Portability :  portable
--
-- This is a purely internal module with utilities to query OpenGL state.
--
--------------------------------------------------------------------------------

module Graphics.Rendering.OpenGL.GL.QueryUtils (
   module Graphics.Rendering.OpenGL.GL.QueryUtils.PName,
   module Graphics.Rendering.OpenGL.GL.QueryUtils.VertexAttrib,

   lightIndexToEnum,
   modelviewIndexToEnum, modelviewEnumToIndex,

   maybeNullPtr,
) where

import Foreign.Ptr
import Graphics.Rendering.OpenGL.Raw.ARB.Compatibility (
   gl_LIGHT0, gl_MODELVIEW)
import Graphics.Rendering.OpenGL.Raw.ARB.VertexBlend (
   gl_MODELVIEW1, gl_MODELVIEW2, gl_MODELVIEW31 )
import Graphics.Rendering.OpenGL.Raw.Core32

import Graphics.Rendering.OpenGL.GL.QueryUtils.PName
import Graphics.Rendering.OpenGL.GL.QueryUtils.VertexAttrib

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

--data GetPNameO =
--     GetCurrentMatrixIndex
--   | GetPointSmooth
--   | GetPointSizeRange
--   | GetPointSizeGranularity
--   | GetLineSmooth
--   | GetLineWidthRange
--   | GetLineWidthGranularity
--   | GetLineStipple
--   | GetPolygonSmooth
--   | GetPolygonStipple
--   | GetCullFace
--   | GetLighting
--   | GetFog
--   | GetDepthTest
--   | GetStencilTest
--   | GetNormalize
--   | GetAttribStackDepth
--   | GetClientAttribStackDepth
--   | GetAlphaTest
--   | GetDither
--   | GetBlend
--   | GetIndexLogicOp
--   | GetLogicOp
--   | GetColorLogicOp
--   | GetScissorTest
--   | GetIndexMode
--   | GetTextureGenS
--   | GetTextureGenT
--   | GetTextureGenR
--   | GetTextureGenQ
--   | GetMaxClipDistances
--   | GetMaxAttribStackDepth
--   | GetMaxClientAttribStackDepth
--   | GetIndexBits
--   | GetAutoNormal
--   | GetMap1Color4
--   | GetMap1Index
--   | GetMap1Normal
--   | GetMap1TextureCoord1
--   | GetMap1TextureCoord2
--   | GetMap1TextureCoord3
--   | GetMap1TextureCoord4
--   | GetMap1Vertex3
--   | GetMap1Vertex4
--   | GetMap2Color4
--   | GetMap2Index
--   | GetMap2Normal
--   | GetMap2TextureCoord1
--   | GetMap2TextureCoord2
--   | GetMap2TextureCoord3
--   | GetMap2TextureCoord4
--   | GetMap2Vertex3
--   | GetMap2Vertex4
--   | GetTexture1D
--   | GetTexture2D
--   | GetFeedbackBufferSize
--   | GetFeedbackBufferType
--   | GetSelectionBufferSize
--   | GetPolygonOffsetPoint
--   | GetPolygonOffsetLine
--   | GetPolygonOffsetFill
--   | GetVertexArray
--   | GetNormalArray
--   | GetColorArray
--   | GetIndexArray
--   | GetTextureCoordArray
--   | GetEdgeFlagArray
--   | GetFogCoordArray
--   | GetSecondaryColorArray
--   | GetMatrixIndexArray
--   | GetMatrixIndexArraySize
--   | GetMatrixIndexArrayType
--   | GetMatrixIndexArrayStride
--   | GetClipDistance GLsizei
--   | GetLight GLsizei
--   | GetTransposeModelviewMatrix
--   | GetTransposeProjectionMatrix
--   | GetTransposeTextureMatrix
--   | GetTransposeColorMatrix
--   | GetColorTable
--   | GetPostConvolutionColorTable
--   | GetPostColorMatrixColorTable
--   | GetConvolution1D
--   | GetConvolution2D
--   | GetSeparable2D
--   | GetMaxConvolutionWidth
--   | GetMaxConvolutionHeight
--   | GetHistogram
--   | GetMinmax
--   | GetColorSum
--   | GetRescaleNormal
--   | GetSharedTexturePalette
--   | GetTexture3DBinding
--   | GetTexture3D
--   | GetMultisample
--   | GetSampleAlphaToCoverage
--   | GetSampleAlphaToOne
--   | GetSampleCoverage
--   | GetTextureCubeMap
--   | GetMaxVertexUnits
--   | GetActiveVertexUnits
--   | GetWeightSumUnity
--   | GetVertexBlend
--   | GetModelview GLsizei
--   | GetCurrentWeight
--   | GetWeightArrayType
--   | GetWeightArrayStride
--   | GetWeightArraySize
--   | GetWeightArray
--   | GetMaxPaletteMatrices
--   | GetCurrentPaletteMatrix
--   | GetCurrentMatrix
--   | GetMaxVaryingComponents
--   | GetColorMaterial
--   -- GetWeightArrayBufferBinding
--   -- transform feedback stuff
--   -- FramebufferObject
--   -- RenderbufferObject
--   -- Color clamping
--   -- VertexArrayObject
--
--_marshalGetPNameO :: GetPNameO -> Maybe GLenum
--_marshalGetPNameO x = case x of
--   GetCurrentMatrixIndex -> Just gl_CURRENT_MATRIX_INDEX
--   GetPointSmooth -> Just gl_POINT_SMOOTH
--   GetPointSizeRange -> Just gl_POINT_SIZE_RANGE
--   GetPointSizeGranularity -> Just gl_POINT_SIZE_GRANULARITY
--   GetLineSmooth -> Just gl_LINE_SMOOTH
--   GetLineWidthRange -> Just gl_SMOOTH_LINE_WIDTH_RANGE
--   GetLineWidthGranularity -> Just gl_SMOOTH_LINE_WIDTH_GRANULARITY
--   GetLineStipple -> Just gl_LINE_STIPPLE
--   GetPolygonSmooth -> Just gl_POLYGON_SMOOTH
--   GetPolygonStipple -> Just gl_POLYGON_STIPPLE
--   GetCullFace -> Just gl_CULL_FACE
--   GetLighting -> Just gl_LIGHTING
--   GetFog -> Just gl_FOG
--   GetDepthTest -> Just gl_DEPTH_TEST
--   GetStencilTest -> Just gl_STENCIL_TEST
--   GetPolygonOffsetPoint -> Just gl_POLYGON_OFFSET_POINT
--   GetNormalize -> Just gl_NORMALIZE
--   GetAttribStackDepth -> Just gl_ATTRIB_STACK_DEPTH
--   GetClientAttribStackDepth -> Just gl_CLIENT_ATTRIB_STACK_DEPTH
--   GetAlphaTest -> Just gl_ALPHA_TEST
--   GetDither -> Just gl_DITHER
--   GetBlend -> Just gl_BLEND
--   GetIndexLogicOp -> Just gl_INDEX_LOGIC_OP
--   GetLogicOp -> Just gl_INDEX_LOGIC_OP
--   GetColorLogicOp -> Just gl_COLOR_LOGIC_OP
--   GetScissorTest -> Just gl_SCISSOR_TEST
--   GetIndexMode -> Just gl_INDEX_MODE
--   GetTextureGenS -> Just gl_TEXTURE_GEN_S
--   GetTextureGenT -> Just gl_TEXTURE_GEN_T
--   GetTextureGenR -> Just gl_TEXTURE_GEN_R
--   GetTextureGenQ -> Just gl_TEXTURE_GEN_Q
--   GetMaxClipDistances -> Just gl_MAX_CLIP_DISTANCES
--   GetMaxAttribStackDepth -> Just gl_MAX_ATTRIB_STACK_DEPTH
--   GetMaxClientAttribStackDepth -> Just gl_MAX_CLIENT_ATTRIB_STACK_DEPTH
--   GetIndexBits -> Just gl_INDEX_BITS
--   GetAutoNormal -> Just gl_AUTO_NORMAL
--   GetMap1Color4 -> Just gl_MAP1_COLOR_4
--   GetMap1Index -> Just gl_MAP1_INDEX
--   GetMap1Normal -> Just gl_MAP1_NORMAL
--   GetMap1TextureCoord1 -> Just gl_MAP1_TEXTURE_COORD_1
--   GetMap1TextureCoord2 -> Just gl_MAP1_TEXTURE_COORD_2
--   GetMap1TextureCoord3 -> Just gl_MAP1_TEXTURE_COORD_3
--   GetMap1TextureCoord4 -> Just gl_MAP1_TEXTURE_COORD_4
--   GetMap1Vertex3 -> Just gl_MAP1_VERTEX_3
--   GetMap1Vertex4 -> Just gl_MAP1_VERTEX_4
--   GetMap2Color4 -> Just gl_MAP2_COLOR_4
--   GetMap2Index -> Just gl_MAP2_INDEX
--   GetMap2Normal -> Just gl_MAP2_NORMAL
--   GetMap2TextureCoord1 -> Just gl_MAP2_TEXTURE_COORD_1
--   GetMap2TextureCoord2 -> Just gl_MAP2_TEXTURE_COORD_2
--   GetMap2TextureCoord3 -> Just gl_MAP2_TEXTURE_COORD_3
--   GetMap2TextureCoord4 -> Just gl_MAP2_TEXTURE_COORD_4
--   GetMap2Vertex3 -> Just gl_MAP2_VERTEX_3
--   GetMap2Vertex4 -> Just gl_MAP2_VERTEX_4
--   GetTexture1D -> Just gl_TEXTURE_1D
--   GetTexture2D -> Just gl_TEXTURE_2D
--   GetFeedbackBufferSize -> Just gl_FEEDBACK_BUFFER_SIZE
--   GetFeedbackBufferType -> Just gl_FEEDBACK_BUFFER_TYPE
--   GetSelectionBufferSize -> Just gl_SELECTION_BUFFER_SIZE
--   GetPolygonOffsetLine -> Just gl_POLYGON_OFFSET_LINE
--   GetPolygonOffsetFill -> Just gl_POLYGON_OFFSET_FILL
--   GetVertexArray -> Just gl_VERTEX_ARRAY
--   GetNormalArray -> Just gl_NORMAL_ARRAY
--   GetColorArray -> Just gl_COLOR_ARRAY
--   GetIndexArray -> Just gl_INDEX_ARRAY
--   GetTextureCoordArray -> Just gl_TEXTURE_COORD_ARRAY
--   GetEdgeFlagArray -> Just gl_EDGE_FLAG_ARRAY
--   GetFogCoordArray -> Just gl_FOG_COORD_ARRAY
--   GetSecondaryColorArray -> Just gl_SECONDARY_COLOR_ARRAY
--   GetMatrixIndexArray -> Just gl_MATRIX_INDEX_ARRAY
--   GetMatrixIndexArraySize -> Just gl_MATRIX_INDEX_ARRAY_SIZE
--   GetMatrixIndexArrayType -> Just gl_MATRIX_INDEX_ARRAY_TYPE
--   GetMatrixIndexArrayStride -> Just gl_MATRIX_INDEX_ARRAY_STRIDE
--   GetClipDistance i -> clipPlaneIndexToEnum i
--   GetLight i -> lightIndexToEnum i
--   GetTransposeModelviewMatrix -> Just gl_TRANSPOSE_MODELVIEW_MATRIX
--   GetTransposeProjectionMatrix -> Just gl_TRANSPOSE_PROJECTION_MATRIX
--   GetTransposeTextureMatrix -> Just gl_TRANSPOSE_TEXTURE_MATRIX
--   GetTransposeColorMatrix -> Just gl_TRANSPOSE_COLOR_MATRIX
--   GetColorTable -> Just gl_COLOR_TABLE
--   GetPostConvolutionColorTable -> Just gl_POST_CONVOLUTION_COLOR_TABLE
--   GetPostColorMatrixColorTable -> Just gl_POST_COLOR_MATRIX_COLOR_TABLE
--   GetConvolution1D -> Just gl_CONVOLUTION_1D
--   GetConvolution2D -> Just gl_CONVOLUTION_2D
--   GetSeparable2D -> Just gl_SEPARABLE_2D
--   GetMaxConvolutionWidth -> Just gl_MAX_CONVOLUTION_WIDTH
--   GetMaxConvolutionHeight -> Just gl_MAX_CONVOLUTION_HEIGHT
--   GetHistogram -> Just gl_HISTOGRAM
--   GetMinmax -> Just gl_MINMAX
--   GetColorSum -> Just gl_COLOR_SUM
--   GetRescaleNormal -> Just gl_RESCALE_NORMAL
--   GetSharedTexturePalette -> Just gl_SHARED_TEXTURE_PALETTE
--   GetTexture3DBinding -> Just gl_TEXTURE_BINDING_3D
--   GetTexture3D -> Just gl_TEXTURE_3D
--   GetMultisample -> Just gl_MULTISAMPLE
--   GetSampleAlphaToCoverage -> Just gl_SAMPLE_ALPHA_TO_COVERAGE
--   GetSampleAlphaToOne -> Just gl_SAMPLE_ALPHA_TO_ONE
--   GetSampleCoverage -> Just gl_SAMPLE_COVERAGE
--   GetColorMaterial -> Just gl_COLOR_MATERIAL
--   GetTextureCubeMap -> Just gl_TEXTURE_CUBE_MAP
--
--   GetMaxVertexUnits -> Just gl_MAX_VERTEX_UNITS
--   GetActiveVertexUnits -> Just gl_ACTIVE_VERTEX_UNITS
--   GetWeightSumUnity -> Just gl_WEIGHT_SUM_UNITY
--   GetVertexBlend -> Just gl_VERTEX_BLEND
--   GetModelview i -> modelviewIndexToEnum i
--   GetCurrentWeight -> Just gl_CURRENT_WEIGHT
--   GetWeightArrayType -> Just gl_WEIGHT_ARRAY_TYPE
--   GetWeightArrayStride -> Just gl_WEIGHT_ARRAY_STRIDE
--   GetWeightArraySize -> Just gl_WEIGHT_ARRAY_SIZE
--   GetWeightArray -> Just gl_WEIGHT_ARRAY
--   GetMaxPaletteMatrices -> Just gl_MAX_PALETTE_MATRICES
--   GetCurrentPaletteMatrix -> Just gl_CURRENT_PALETTE_MATRIX
--   GetCurrentMatrix -> Just gl_CURRENT_MATRIX
--   GetMaxVaryingComponents -> Just gl_MAX_VARYING_COMPONENTS

   -- GetWeightArrayBufferBinding -> Just gl_WEIGHT_ARRAY_BUFFER_BINDING
   -- transform feedback
   -- FramebufferObject
   -- RenderbufferObject
   -- Color clamping
     -- VertexArrayObject

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

--data GetIndexedPName =
--     GetTransformFeedbackBuffer
--   | GetTransformFeedbackBufferStart
--   | GetTransformFeedbackBufferSize
--
--marshalGetIndexedPName :: GetIndexedPName -> GLenum
--marshalGetIndexedPName x = case x of
--   GetTransformFeedbackBuffer -> gl_TRANSFORM_FEEDBACK_BUFFER
--   GetTransformFeedbackBufferSize -> gl_TRANSFORM_FEEDBACK_BUFFER_SIZE
--   GetTransformFeedbackBufferStart -> gl_TRANSFORM_FEEDBACK_BUFFER_START

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

-- 0x4000 through 0x4FFF are reserved for light numbers

lightIndexToEnum :: GLsizei -> Maybe GLenum
lightIndexToEnum i
   | 0 <= i && i <= maxLightIndex = Just (gl_LIGHT0 + fromIntegral i)
   | otherwise = Nothing

maxLightIndex :: GLsizei
maxLightIndex = 0xFFF

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

-- 0x1700, 0x850a, and 0x8722 through 0x873f are reserved for modelview matrices

modelviewIndexToEnum :: GLsizei -> Maybe GLenum
modelviewIndexToEnum 0 = Just gl_MODELVIEW
modelviewIndexToEnum 1 = Just gl_MODELVIEW1
modelviewIndexToEnum i
   | 2 <= i && i <= 31 = Just (gl_MODELVIEW2 - 2 + fromIntegral i)
   | otherwise = Nothing

modelviewEnumToIndex :: GLenum -> Maybe GLsizei
modelviewEnumToIndex x
   | x == gl_MODELVIEW = Just 0
   | x == gl_MODELVIEW1 = Just 1
   | gl_MODELVIEW2 <= x && x <= gl_MODELVIEW31 = Just (fromIntegral (x - (gl_MODELVIEW2 - 2)))
   | otherwise = Nothing



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

maybeNullPtr :: b -> (Ptr a -> b) -> Ptr a -> b
maybeNullPtr n f ptr | ptr == nullPtr = n
                     | otherwise      = f ptr
--------------------------------------------------------------------------------