--------------------------------------------------------------------------------
-- |
-- Module      :  Graphics.Rendering.OpenGL.GL.StringQueries
-- Copyright   :  (c) Sven Panne 2002-2006
-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
-- 
-- Maintainer  :  sven.panne@aedion.de
-- Stability   :  stable
-- Portability :  portable
--
-- This module corresponds to parts of section 6.1.11 (Pointer and String
-- Queries) of the OpenGL 2.1 specs.
--
--------------------------------------------------------------------------------

module Graphics.Rendering.OpenGL.GL.StringQueries (
   vendor, renderer, glVersion, glExtensions, shadingLanguageVersion, majorMinor
) where

import Data.Char ( isDigit )
import Foreign.C.String ( peekCString )
import Foreign.Ptr ( Ptr, nullPtr, castPtr )
import Graphics.Rendering.OpenGL.GL.BasicTypes ( GLenum, GLubyte )
import Graphics.Rendering.OpenGL.GL.StateVar (
   HasGetter(get), GettableStateVar, makeGettableStateVar )

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

vendor :: GettableStateVar String
vendor = makeGettableStateVar (getString Vendor)

renderer :: GettableStateVar String
renderer = makeGettableStateVar (getString Renderer)

glVersion :: GettableStateVar String
glVersion = makeGettableStateVar (getString Version)

glExtensions :: GettableStateVar [String]
glExtensions = makeGettableStateVar (fmap words $ getString Extensions)

shadingLanguageVersion :: GettableStateVar String
shadingLanguageVersion = makeGettableStateVar (getString ShadingLanguageVersion)

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

data StringName =
     Vendor
   | Renderer
   | Version
   | Extensions
   | ShadingLanguageVersion

marshalStringName :: StringName -> GLenum
marshalStringName x = case x of
   Vendor -> 0x1f00
   Renderer -> 0x1f01
   Version -> 0x1f02
   Extensions -> 0x1f03
   ShadingLanguageVersion -> 0x8b8c

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

getString :: StringName -> IO String
getString n = do
   ptr <- glGetString (marshalStringName n)
   if ptr == nullPtr
      then return ""
      else peekCString (castPtr ptr)

foreign import CALLCONV unsafe "glGetString" glGetString ::
   GLenum -> IO (Ptr GLubyte)

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

-- | A utility function to be used with e.g. 'glVersion' or
-- 'shadingLanguageVersion', transforming a variable containing a string of the
-- form /major.minor[optional rest]/ into a variable containing a numeric
-- major\/minor version. If the string is malformed, which should never happen
-- with a sane OpenGL implementation, it is transformed to @(-1,-1)@.

majorMinor :: GettableStateVar String -> GettableStateVar (Int, Int)
majorMinor = makeGettableStateVar . fmap parse . get
   where defaultVersion = (-1, -1)
         parse str =
            case span isDigit str of
               (major@(_:_), '.':rest) ->
                  case span isDigit rest of
                     (minor@(_:_), _) -> (read major, read minor)
                     _ -> defaultVersion
               _ -> defaultVersion