-- #hide
--------------------------------------------------------------------------------
-- |
-- Module      :  Graphics.Rendering.OpenGL.GL.Texturing.PixelInternalFormat
-- 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 PixelInternalFormat.
--
--------------------------------------------------------------------------------

module Graphics.Rendering.OpenGL.GL.Texturing.PixelInternalFormat (
   PixelInternalFormat(..), marshalPixelInternalFormat,
   marshalPixelInternalFormat', unmarshalPixelInternalFormat,
) where

import Graphics.Rendering.OpenGL.Raw.ARB.Compatibility (
   gl_ALPHA12, gl_ALPHA16, gl_ALPHA4, gl_ALPHA8, gl_COMPRESSED_ALPHA,
   gl_COMPRESSED_INTENSITY, gl_COMPRESSED_LUMINANCE,
   gl_COMPRESSED_LUMINANCE_ALPHA, gl_COMPRESSED_SLUMINANCE,
   gl_COMPRESSED_SLUMINANCE_ALPHA, gl_INTENSITY, gl_INTENSITY12, gl_INTENSITY16,
   gl_INTENSITY4, gl_INTENSITY8, gl_LUMINANCE, gl_LUMINANCE12,
   gl_LUMINANCE12_ALPHA12, gl_LUMINANCE12_ALPHA4, gl_LUMINANCE16,
   gl_LUMINANCE16_ALPHA16, gl_LUMINANCE4, gl_LUMINANCE4_ALPHA4,
   gl_LUMINANCE6_ALPHA2, gl_LUMINANCE8, gl_LUMINANCE8_ALPHA8,
   gl_LUMINANCE_ALPHA, gl_SLUMINANCE, gl_SLUMINANCE8, gl_SLUMINANCE8_ALPHA8,
   gl_SLUMINANCE_ALPHA )
import Graphics.Rendering.OpenGL.Raw.Core31

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

data PixelInternalFormat =
     Alpha'
   | DepthComponent'
   | Luminance'
   | LuminanceAlpha'
   | Intensity
   | RGB'
   | RGBA'
   | SRGB
   | SRGBAlpha
   | SLuminance
   | SLuminanceAlpha
   | Alpha4
   | Alpha8
   | Alpha12
   | Alpha16
   | DepthComponent16
   | DepthComponent24
   | DepthComponent32
   | Luminance4
   | Luminance8
   | Luminance12
   | Luminance16
   | Luminance4Alpha4
   | Luminance6Alpha2
   | Luminance8Alpha8
   | Luminance12Alpha4
   | Luminance12Alpha12
   | Luminance16Alpha16
   | Intensity4
   | Intensity8
   | Intensity12
   | Intensity16
   | R3G3B2
   | RGB4
   | RGB5
   | RGB8
   | RGB10
   | RGB12
   | RGB16
   | RGBA2
   | RGBA4
   | RGB5A1
   | RGBA8
   | RGB10A2
   | RGBA12
   | RGBA16
   | SRGB8
   | SRGB8Alpha8
   | SLuminance8
   | SLuminance8Alpha8
   | CompressedAlpha
   | CompressedLuminance
   | CompressedLuminanceAlpha
   | CompressedIntensity
   | CompressedRGB
   | CompressedRGBA
   | CompressedSRGB
   | CompressedSRGBAlpha
   | CompressedSLuminance
   | CompressedSLuminanceAlpha
   | DepthComponent32f
   | Depth32fStencil8
   | RGB9E5
   | R11fG11fB10f
   deriving ( Eq, Ord, Show )

marshalPixelInternalFormat :: PixelInternalFormat -> GLint
marshalPixelInternalFormat x = fromIntegral $ case x of
   Alpha' -> gl_ALPHA
   DepthComponent' -> gl_DEPTH_COMPONENT
   Luminance' -> gl_LUMINANCE
   LuminanceAlpha' -> gl_LUMINANCE_ALPHA
   RGB' -> gl_RGB
   RGBA' -> gl_RGBA
   SRGB -> gl_SRGB
   SRGBAlpha -> gl_SRGB_ALPHA
   SLuminance -> gl_SLUMINANCE
   SLuminanceAlpha -> gl_SLUMINANCE_ALPHA
   Alpha4 -> gl_ALPHA4
   Alpha8 -> gl_ALPHA8
   Alpha12 -> gl_ALPHA12
   Alpha16 -> gl_ALPHA16
   DepthComponent16 -> gl_DEPTH_COMPONENT16
   DepthComponent24 -> gl_DEPTH_COMPONENT24
   DepthComponent32 -> gl_DEPTH_COMPONENT32
   Luminance4 -> gl_LUMINANCE4
   Luminance8 -> gl_LUMINANCE8
   Luminance12 -> gl_LUMINANCE12
   Luminance16 -> gl_LUMINANCE16
   Luminance4Alpha4 -> gl_LUMINANCE4_ALPHA4
   Luminance6Alpha2 -> gl_LUMINANCE6_ALPHA2
   Luminance8Alpha8 -> gl_LUMINANCE8_ALPHA8
   Luminance12Alpha4 -> gl_LUMINANCE12_ALPHA4
   Luminance12Alpha12 -> gl_LUMINANCE12_ALPHA12
   Luminance16Alpha16 -> gl_LUMINANCE16_ALPHA16
   Intensity -> gl_INTENSITY
   Intensity4 -> gl_INTENSITY4
   Intensity8 -> gl_INTENSITY8
   Intensity12 -> gl_INTENSITY12
   Intensity16 -> gl_INTENSITY16
   R3G3B2 -> gl_R3_G3_B2
   RGB4 -> gl_RGB4
   RGB5 -> gl_RGB5
   RGB8 -> gl_RGB8
   RGB10 -> gl_RGB10
   RGB12 -> gl_RGB12
   RGB16 -> gl_RGB16
   RGBA2 -> gl_RGBA2
   RGBA4 -> gl_RGBA4
   RGB5A1 -> gl_RGB5_A1
   RGBA8 -> gl_RGBA8
   RGB10A2 -> gl_RGB10_A2
   RGBA12 -> gl_RGBA12
   RGBA16 -> gl_RGBA16
   SRGB8 -> gl_SRGB8
   SRGB8Alpha8 -> gl_SRGB8_ALPHA8
   SLuminance8 -> gl_SLUMINANCE8
   SLuminance8Alpha8 -> gl_SLUMINANCE8_ALPHA8
   CompressedAlpha -> gl_COMPRESSED_ALPHA
   CompressedLuminance -> gl_COMPRESSED_LUMINANCE
   CompressedLuminanceAlpha -> gl_COMPRESSED_LUMINANCE_ALPHA
   CompressedIntensity -> gl_COMPRESSED_INTENSITY
   CompressedRGB -> gl_COMPRESSED_RGB
   CompressedRGBA -> gl_COMPRESSED_RGBA
   CompressedSRGB -> gl_COMPRESSED_SRGB
   CompressedSRGBAlpha -> gl_COMPRESSED_SRGB_ALPHA
   CompressedSLuminance -> gl_COMPRESSED_SLUMINANCE
   CompressedSLuminanceAlpha -> gl_COMPRESSED_SLUMINANCE_ALPHA
   DepthComponent32f -> gl_DEPTH_COMPONENT32F
   Depth32fStencil8 -> gl_DEPTH32F_STENCIL8
   RGB9E5 -> gl_RGB9_E5
   R11fG11fB10f -> gl_R11F_G11F_B10F

-- *sigh* The OpenGL API is sometimes a bit creative in its usage of types...
marshalPixelInternalFormat' :: PixelInternalFormat -> GLenum
marshalPixelInternalFormat' = fromIntegral . marshalPixelInternalFormat

unmarshalPixelInternalFormat :: GLint -> PixelInternalFormat
unmarshalPixelInternalFormat x
   | y == gl_ALPHA = Alpha'
   | y == gl_DEPTH_COMPONENT = DepthComponent'
   | y == gl_LUMINANCE = Luminance'
   | y == gl_LUMINANCE_ALPHA = LuminanceAlpha'
   | y == gl_RGB = RGB'
   | y == gl_RGBA = RGBA'
   | y == gl_SRGB = SRGB
   | y == gl_SRGB_ALPHA = SRGBAlpha
   | y == gl_SLUMINANCE = SLuminance
   | y == gl_SLUMINANCE_ALPHA = SLuminanceAlpha
   | y == gl_ALPHA4 = Alpha4
   | y == gl_ALPHA8 = Alpha8
   | y == gl_ALPHA12 = Alpha12
   | y == gl_ALPHA16 = Alpha16
   | y == gl_DEPTH_COMPONENT16 = DepthComponent16
   | y == gl_DEPTH_COMPONENT24 = DepthComponent24
   | y == gl_DEPTH_COMPONENT32 = DepthComponent32
   | y == gl_LUMINANCE4 = Luminance4
   | y == gl_LUMINANCE8 = Luminance8
   | y == gl_LUMINANCE12 = Luminance12
   | y == gl_LUMINANCE16 = Luminance16
   | y == gl_LUMINANCE4_ALPHA4 = Luminance4Alpha4
   | y == gl_LUMINANCE6_ALPHA2 = Luminance6Alpha2
   | y == gl_LUMINANCE8_ALPHA8 = Luminance8Alpha8
   | y == gl_LUMINANCE12_ALPHA4 = Luminance12Alpha4
   | y == gl_LUMINANCE12_ALPHA12 = Luminance12Alpha12
   | y == gl_LUMINANCE16_ALPHA16 = Luminance16Alpha16
   | y == gl_INTENSITY = Intensity
   | y == gl_INTENSITY4 = Intensity4
   | y == gl_INTENSITY8 = Intensity8
   | y == gl_INTENSITY12 = Intensity12
   | y == gl_INTENSITY16 = Intensity16
   | y == gl_R3_G3_B2 = R3G3B2
   | y == gl_RGB4 = RGB4
   | y == gl_RGB5 = RGB5
   | y == gl_RGB8 = RGB8
   | y == gl_RGB10 = RGB10
   | y == gl_RGB12 = RGB12
   | y == gl_RGB16 = RGB16
   | y == gl_RGBA2 = RGBA2
   | y == gl_RGBA4 = RGBA4
   | y == gl_RGB5_A1 = RGB5A1
   | y == gl_RGBA8 = RGBA8
   | y == gl_RGB10_A2 = RGB10A2
   | y == gl_RGBA12 = RGBA12
   | y == gl_RGBA16 = RGBA16
   | y == gl_SRGB8 = SRGB8
   | y == gl_SRGB8_ALPHA8 = SRGB8Alpha8
   | y == gl_SLUMINANCE8 = SLuminance8
   | y == gl_SLUMINANCE8_ALPHA8 = SLuminance8Alpha8
   | y == gl_COMPRESSED_ALPHA = CompressedAlpha
   | y == gl_COMPRESSED_LUMINANCE = CompressedLuminance
   | y == gl_COMPRESSED_LUMINANCE_ALPHA = CompressedLuminanceAlpha
   | y == gl_COMPRESSED_INTENSITY = CompressedIntensity
   | y == gl_COMPRESSED_RGB = CompressedRGB
   | y == gl_COMPRESSED_RGBA = CompressedRGBA
   | y == gl_COMPRESSED_SRGB = CompressedSRGB
   | y == gl_COMPRESSED_SRGB_ALPHA = CompressedSRGBAlpha
   | y == gl_COMPRESSED_SLUMINANCE = CompressedSLuminance
   | y == gl_COMPRESSED_SLUMINANCE_ALPHA = CompressedSLuminanceAlpha
   | y == gl_DEPTH_COMPONENT32F = DepthComponent32f
   | y == gl_DEPTH32F_STENCIL8 = Depth32fStencil8
   | y == gl_RGB9_E5 = RGB9E5
   -- legacy values
   | y == 1 = Luminance'
   | y == 2 = LuminanceAlpha'
   | y == 3 = RGB'
   | y == 4 = RGBA'
   | otherwise = error ("unmarshalPixelInternalFormat: illegal value " ++ show x)
   where y = fromIntegral x

-- Note: The following formats are still missing, it's a bit unclear how to
-- handle these nicely. From the EXT_texture_sRGB spec:
--
--    Accepted by the <internalformat> parameter of TexImage2D, CopyTexImage2D,
--    and CompressedTexImage2DARB and the <format> parameter of
--    CompressedTexSubImage2DARB:
--
--       COMPRESSED_SRGB_S3TC_DXT1_EXT                  0x8C4C
--       COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT            0x8C4D
--       COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT            0x8C4E
--       COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT            0x8C4F