-- #hide
--------------------------------------------------------------------------------
-- |
-- Module      :  Graphics.Rendering.OpenGL.GL.DataType
-- 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 for (un-)marshaling DataType.
--
--------------------------------------------------------------------------------

module Graphics.Rendering.OpenGL.GL.DataType (
   DataType(..), marshalDataType, unmarshalDataType,
   DataTypeType(..), marshalDataTypeType, unmarshalDataTypeType
) where

import Graphics.Rendering.OpenGL.Raw.ARB.Compatibility (
   gl_2_BYTES, gl_3_BYTES, gl_4_BYTES, gl_BITMAP )
import Graphics.Rendering.OpenGL.Raw.Core31

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

-- basically table 3.2 (pixel data type parameter) plus a few additions
data DataType =
     UnsignedByte
   | Byte
   | UnsignedShort
   | Short
   | UnsignedInt
   | Int
   | HalfFloat
   | Float
   | UnsignedByte332
   | UnsignedByte233Rev
   | UnsignedShort565
   | UnsignedShort565Rev
   | UnsignedShort4444
   | UnsignedShort4444Rev
   | UnsignedShort5551
   | UnsignedShort1555Rev
   | UnsignedInt8888
   | UnsignedInt8888Rev
   | UnsignedInt1010102
   | UnsignedInt2101010Rev
   | UnsignedInt248
   | UnsignedInt10f11f11fRev
   | UnsignedInt5999Rev
   | Float32UnsignedInt248Rev
   | Bitmap                    -- pixel data, deprecated in 3.1
   | UnsignedShort88           -- MESA_ycbcr_texture/APPLE_ycbcr_422
   | UnsignedShort88Rev        -- MESA_ycbcr_texture/APPLE_ycbcr_422
   | Double                    -- vertex arrays (EXT_vertex_array, now core)
   | TwoBytes                  -- CallLists
   | ThreeBytes                -- CallLists
   | FourBytes                 -- CallLists
   deriving ( Eq, Ord, Show )

marshalDataType :: DataType -> GLenum
marshalDataType x = case x of
   UnsignedByte -> gl_UNSIGNED_BYTE
   Byte -> gl_BYTE
   UnsignedShort -> gl_UNSIGNED_SHORT
   Short -> gl_SHORT
   UnsignedInt -> gl_UNSIGNED_INT
   Int -> gl_INT
   HalfFloat -> gl_HALF_FLOAT
   Float -> gl_FLOAT
   UnsignedByte332 -> gl_UNSIGNED_BYTE_3_3_2
   UnsignedByte233Rev -> gl_UNSIGNED_BYTE_2_3_3_REV
   UnsignedShort565 -> gl_UNSIGNED_SHORT_5_6_5
   UnsignedShort565Rev -> gl_UNSIGNED_SHORT_5_6_5_REV
   UnsignedShort4444 -> gl_UNSIGNED_SHORT_4_4_4_4
   UnsignedShort4444Rev -> gl_UNSIGNED_SHORT_4_4_4_4_REV
   UnsignedShort5551 -> gl_UNSIGNED_SHORT_5_5_5_1
   UnsignedShort1555Rev -> gl_UNSIGNED_SHORT_1_5_5_5_REV
   UnsignedInt8888 -> gl_UNSIGNED_INT_8_8_8_8
   UnsignedInt8888Rev -> gl_UNSIGNED_INT_8_8_8_8_REV
   UnsignedInt1010102 -> gl_UNSIGNED_INT_10_10_10_2
   UnsignedInt2101010Rev -> gl_UNSIGNED_INT_2_10_10_10_REV
   UnsignedInt248 -> gl_UNSIGNED_INT_24_8
   UnsignedInt10f11f11fRev -> gl_UNSIGNED_INT_10F_11F_11F_REV
   UnsignedInt5999Rev -> gl_UNSIGNED_INT_5_9_9_9_REV
   Float32UnsignedInt248Rev -> gl_FLOAT_32_UNSIGNED_INT_24_8_REV
   Bitmap -> gl_BITMAP
   -- TODO: Use UNSIGNED_SHORT_8_8_APPLE from APPLE_ycbcr_422 extension
   UnsignedShort88 -> 0x85ba
   -- TODO: Use UNSIGNED_SHORT_8_8_REV_APPLE from APPLE_ycbcr_422 extension
   UnsignedShort88Rev -> 0x85bb
   Double -> gl_DOUBLE
   TwoBytes -> gl_2_BYTES
   ThreeBytes -> gl_3_BYTES
   FourBytes -> gl_4_BYTES

unmarshalDataType :: GLenum -> DataType
unmarshalDataType x
   | x == gl_UNSIGNED_BYTE = UnsignedByte
   | x == gl_BYTE = Byte
   | x == gl_UNSIGNED_SHORT = UnsignedShort
   | x == gl_SHORT = Short
   | x == gl_UNSIGNED_INT = UnsignedInt
   | x == gl_INT = Int
   | x == gl_HALF_FLOAT = HalfFloat
   | x == gl_FLOAT = Float
   | x == gl_UNSIGNED_BYTE_3_3_2 = UnsignedByte332
   | x == gl_UNSIGNED_BYTE_2_3_3_REV = UnsignedByte233Rev
   | x == gl_UNSIGNED_SHORT_5_6_5 = UnsignedShort565
   | x == gl_UNSIGNED_SHORT_5_6_5_REV = UnsignedShort565Rev
   | x == gl_UNSIGNED_SHORT_4_4_4_4 = UnsignedShort4444
   | x == gl_UNSIGNED_SHORT_4_4_4_4_REV = UnsignedShort4444Rev
   | x == gl_UNSIGNED_SHORT_5_5_5_1 = UnsignedShort5551
   | x == gl_UNSIGNED_SHORT_1_5_5_5_REV = UnsignedShort1555Rev
   | x == gl_UNSIGNED_INT_8_8_8_8 = UnsignedInt8888
   | x == gl_UNSIGNED_INT_8_8_8_8_REV = UnsignedInt8888Rev
   | x == gl_UNSIGNED_INT_10_10_10_2 = UnsignedInt1010102
   | x == gl_UNSIGNED_INT_2_10_10_10_REV = UnsignedInt2101010Rev
   | x == gl_UNSIGNED_INT_24_8 = UnsignedInt248
   | x == gl_UNSIGNED_INT_10F_11F_11F_REV = UnsignedInt10f11f11fRev
   | x == gl_UNSIGNED_INT_5_9_9_9_REV = UnsignedInt5999Rev
   | x == gl_FLOAT_32_UNSIGNED_INT_24_8_REV = Float32UnsignedInt248Rev
   | x == gl_BITMAP = Bitmap
   -- TODO: Use UNSIGNED_SHORT_8_8_APPLE from APPLE_ycbcr_422 extension
   | x == 0x85ba = UnsignedShort88
   -- TODO: Use UNSIGNED_SHORT_8_8_REV_APPLE from APPLE_ycbcr_422 extension
   | x == 0x85bb = UnsignedShort88Rev
   | x == gl_DOUBLE = Double
   | x == gl_2_BYTES = TwoBytes
   | x == gl_3_BYTES = ThreeBytes
   | x == gl_4_BYTES = FourBytes
   | otherwise = error ("unmarshalDataType: illegal value " ++ show x)

data DataTypeType
   = TNone
   | TSignedNormalized
   | TUnsignedNormalized
   | TFloat
   | TInt
   | TUnsignedInt

marshalDataTypeType :: DataTypeType -> GLenum
marshalDataTypeType x = case x of
   TNone -> gl_NONE
   TSignedNormalized -> gl_SIGNED_NORMALIZED
   TUnsignedNormalized -> gl_UNSIGNED_NORMALIZED
   TFloat -> gl_FLOAT
   TInt -> gl_INT
   TUnsignedInt -> gl_UNSIGNED_INT

unmarshalDataTypeType :: GLenum -> DataTypeType
unmarshalDataTypeType x
   | x == gl_NONE = TNone
   | x == gl_SIGNED_NORMALIZED = TSignedNormalized
   | x == gl_UNSIGNED_NORMALIZED = TUnsignedNormalized
   | x == gl_FLOAT = TFloat
   | x == gl_INT = TInt
   | x == gl_UNSIGNED_INT = TUnsignedInt
   | otherwise = error $ "unmarshalDataTypeType: illegal value " ++ show x
