-- #hide
--------------------------------------------------------------------------------
-- |
-- Module      :  Graphics.Rendering.OpenGL.GL.ControlPoint
-- 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 is a purely internal module for handling control points.
--
--------------------------------------------------------------------------------

module Graphics.Rendering.OpenGL.GL.ControlPoint (
   ControlPoint(..)
) where

import Foreign.Ptr ( Ptr )
import Foreign.Storable ( Storable(peek,poke) )
import Graphics.Rendering.OpenGL.GL.BasicTypes ( GLenum )
import Graphics.Rendering.OpenGL.GL.Capability ( EnableCap(..) )
import Graphics.Rendering.OpenGL.GL.Domain ( Domain )
import Graphics.Rendering.OpenGL.GL.VertexArrays ( Stride )
import Graphics.Rendering.OpenGL.GL.VertexSpec (
   Vertex3, Vertex4, Index1, Color4, Normal3, TexCoord1, TexCoord2, TexCoord3,
   TexCoord4 )

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

class ControlPoint c where
   map1Target       :: Domain d => c d -> GLenum
   map2Target       :: Domain d => c d -> GLenum
   enableCap1       :: Domain d => c d -> EnableCap
   enableCap2       :: Domain d => c d -> EnableCap
   numComponents    :: Domain d => c d -> Stride
   peekControlPoint :: Domain d => Ptr (c d) -> IO (c d)
   pokeControlPoint :: Domain d => Ptr (c d) -> (c d) -> IO ()

instance ControlPoint Vertex3 where
   map1Target       = marshalMapTarget . const Map1Vertex3
   map2Target       = marshalMapTarget . const Map2Vertex3
   enableCap1       = const CapMap1Vertex3
   enableCap2       = const CapMap2Vertex3
   numComponents    = const 3
   peekControlPoint = peek
   pokeControlPoint = poke

instance ControlPoint Vertex4 where
   map1Target       = marshalMapTarget . const Map1Vertex4
   map2Target       = marshalMapTarget . const Map2Vertex4
   enableCap1       = const CapMap1Vertex4
   enableCap2       = const CapMap2Vertex4
   numComponents    = const 4
   peekControlPoint = peek
   pokeControlPoint = poke

instance ControlPoint Index1 where
   map1Target       = marshalMapTarget . const Map1Index
   map2Target       = marshalMapTarget . const Map2Index
   enableCap1       = const CapMap1Index
   enableCap2       = const CapMap2Index
   numComponents    = const 1
   peekControlPoint = peek
   pokeControlPoint = poke

instance ControlPoint Color4 where
   map1Target       = marshalMapTarget . const Map1Color4
   map2Target       = marshalMapTarget . const Map2Color4
   enableCap1       = const CapMap1Color4
   enableCap2       = const CapMap2Color4
   numComponents    = const 4
   peekControlPoint = peek
   pokeControlPoint = poke

instance ControlPoint Normal3 where
   map1Target       = marshalMapTarget . const Map1Normal
   map2Target       = marshalMapTarget . const Map2Normal
   enableCap1       = const CapMap1Normal
   enableCap2       = const CapMap2Normal
   numComponents    = const 3
   peekControlPoint = peek
   pokeControlPoint = poke

instance ControlPoint TexCoord1 where
   map1Target       = marshalMapTarget . const Map1TextureCoord1
   map2Target       = marshalMapTarget . const Map2TextureCoord1
   enableCap1       = const CapMap1TextureCoord1
   enableCap2       = const CapMap2TextureCoord1
   numComponents    = const 1
   peekControlPoint = peek
   pokeControlPoint = poke

instance ControlPoint TexCoord2 where
   map1Target       = marshalMapTarget . const Map1TextureCoord2
   map2Target       = marshalMapTarget . const Map2TextureCoord2
   enableCap1       = const CapMap1TextureCoord2
   enableCap2       = const CapMap2TextureCoord2
   numComponents    = const 2
   peekControlPoint = peek
   pokeControlPoint = poke

instance ControlPoint TexCoord3 where
   map1Target       = marshalMapTarget . const Map1TextureCoord3
   map2Target       = marshalMapTarget . const Map2TextureCoord3
   enableCap1       = const CapMap1TextureCoord3
   enableCap2       = const CapMap2TextureCoord3
   numComponents    = const 3
   peekControlPoint = peek
   pokeControlPoint = poke

instance ControlPoint TexCoord4 where
   map1Target       = marshalMapTarget . const Map1TextureCoord4
   map2Target       = marshalMapTarget . const Map2TextureCoord4
   enableCap1       = const CapMap1TextureCoord4
   enableCap2       = const CapMap2TextureCoord4
   numComponents    = const 4
   peekControlPoint = peek
   pokeControlPoint = poke

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

data MapTarget =
     Map1Color4
   | Map1Index
   | Map1Normal
   | Map1TextureCoord1
   | Map1TextureCoord2
   | Map1TextureCoord3
   | Map1TextureCoord4
   | Map1Vertex3
   | Map1Vertex4
   | Map2Color4
   | Map2Index
   | Map2Normal
   | Map2TextureCoord1
   | Map2TextureCoord2
   | Map2TextureCoord3
   | Map2TextureCoord4
   | Map2Vertex3
   | Map2Vertex4

marshalMapTarget :: MapTarget -> GLenum
marshalMapTarget x = case x of
   Map1Color4 -> 0xd90
   Map1Index -> 0xd91
   Map1Normal -> 0xd92
   Map1TextureCoord1 -> 0xd93
   Map1TextureCoord2 -> 0xd94
   Map1TextureCoord3 -> 0xd95
   Map1TextureCoord4 -> 0xd96
   Map1Vertex3 -> 0xd97
   Map1Vertex4 -> 0xd98
   Map2Color4 -> 0xdb0
   Map2Index -> 0xdb1
   Map2Normal -> 0xdb2
   Map2TextureCoord1 -> 0xdb3
   Map2TextureCoord2 -> 0xdb4
   Map2TextureCoord3 -> 0xdb5
   Map2TextureCoord4 -> 0xdb6
   Map2Vertex3 -> 0xdb7
   Map2Vertex4 -> 0xdb8