module Graphics.LambdaCube.TextureUnitState where

import Graphics.LambdaCube.BlendMode
import Graphics.LambdaCube.Common
import Graphics.LambdaCube.PixelFormat
import Graphics.LambdaCube.Texture
import Graphics.LambdaCube.Types

data TextureEffectType
    = ET_ENVIRONMENT_MAP    -- ^ Generate all texture coords based on angle between camera and vertex
    | ET_PROJECTIVE_TEXTURE -- ^ Generate texture coords based on a frustum
    | ET_UVSCROLL           -- ^ Constant u/v scrolling effect
    | ET_USCROLL            -- ^ Constant u scrolling effect
    | ET_VSCROLL            -- ^ Constant u/v scrolling effect
    | ET_ROTATE             -- ^ Constant rotation
    | ET_TRANSFORM          -- ^ More complex transform
    deriving (Eq,Ord)

data EnvMapType
    = ENV_PLANAR     -- ^ Envmap based on vector from camera to vertex position, good for planar geometry
    | ENV_CURVED     -- ^ Envmap based on dot of vector from camera to vertex and vertex normal, good for curves
    | ENV_REFLECTION -- ^ Envmap intended to supply reflection vectors for cube mapping
    | ENV_NORMAL     -- ^ Envmap intended to supply normal vectors for cube mapping

data TextureTransformType
    = TT_TRANSLATE_U
    | TT_TRANSLATE_V
    | TT_SCALE_U
    | TT_SCALE_V
    | TT_ROTATE

data TextureAddressingMode
    = TAM_WRAP   -- ^ Texture wraps at values over 1.0
    | TAM_MIRROR -- ^ Texture mirrors (flips) at joins over 1.0
    | TAM_CLAMP  -- ^ Texture clamps at 1.0
    | TAM_BORDER -- ^ Texture coordinates outside the range [0.0, 1.0] are set to the border colour
    deriving (Eq,Ord)

data UVWAddressingMode
    = UVWAddressingMode
    { amU :: TextureAddressingMode
    , amV :: TextureAddressingMode
    , amW :: TextureAddressingMode
    }
    deriving (Eq,Ord)

data TextureCubeFace
    = CUBE_FRONT
    | CUBE_BACK
    | CUBE_LEFT
    | CUBE_RIGHT
    | CUBE_UP
    | CUBE_DOWN

{-
    = ET_ENVIRONMENT_MAP    -- ^ Generate all texture coords based on angle between camera and vertex
        -- EnvMapType
    | ET_PROJECTIVE_TEXTURE -- ^ Generate texture coords based on a frustum
    | ET_UVSCROLL           -- ^ Constant u/v scrolling effect
        -- speedX speedY
    | ET_ROTATE             -- ^ Constant rotation
        -- speed
    | ET_TRANSFORM          -- ^ More complex transform

xform info:
    - anim type (scroll,rotate,scale)
    - wave type (sine,triangle,square,sawtooth,inversesawtooth)
    - base
    - frequency
    - phase
    - amplitude
-}

data TextureEffect
    = TextureEffect
    { teType        :: TextureEffectType
    , teSubType     :: Int
    , teArg1        :: FloatType
    , teArg2        :: FloatType
    , teWaveType    :: WaveformType
    , teBase        :: FloatType
    , teFrequency   :: FloatType
    , tePhase       :: FloatType
    , teAmplitude   :: FloatType
    }
    deriving (Eq,Ord)

data BindingType
    = BT_FRAGMENT   -- ^ Regular fragment processing unit - the default.
    | BT_VERTEX     -- ^ Vertex processing unit - indicates this unit will be used for
                    --   a vertex texture fetch.
    deriving (Eq,Ord)

data ContentType
    = CONTENT_NAMED  -- ^ Normal texture identified by name
    | CONTENT_SHADOW -- ^ A shadow texture, automatically bound by engine
    deriving (Eq,Ord)

data Texture t => TextureUnitState t
    = TextureUnitState
    { tusAnimDuration            :: Maybe FloatType     -- ^ Duration of animation in seconds
    , tusCubic                   :: Bool                -- ^ is this a series of 6 2D textures to make up a cube?

    , tusTextureType             :: TextureType
    , tusDesiredFormat           :: PixelFormat
    , tusTextureSrcMipmaps       :: TextureMipmap       -- ^ Request number of mipmaps

    , tusTextureCoordSetIndex    :: Int
    , tusAddressMode             :: UVWAddressingMode
    , tusBorderColour            :: ColourValue

    , tusColourBlendMode         :: LayerBlendModeEx
    , tusColourBlendFallbackSrc  :: SceneBlendFactor
    , tusColourBlendFallbackDest :: SceneBlendFactor

    , tusAlphaBlendMode          :: LayerBlendModeEx

    , tusIsAlpha                 :: Bool
    , tusHwGamma                 :: Bool

    , tusUMod                    :: FloatType
    , tusVMod                    :: FloatType
    , tusUScale                  :: FloatType
    , tusVScale                  :: FloatType
    , tusRotate                  :: FloatType

    , tusMinFilter               :: FilterOptions       -- ^ Texture filtering - minification
    , tusMagFilter               :: FilterOptions       -- ^ Texture filtering - magnification
    , tusMipFilter               :: FilterOptions       -- ^ Texture filtering - mipmapping

    , tusMaxAniso                :: Int             -- ^ Texture anisotropy
    , tusMipmapBias              :: FloatType       -- ^ Mipmap bias

    , tusBindingType             :: BindingType      -- ^ Binding type (fragment or vertex pipeline)
    , tusContentType             :: ContentType      -- ^ Content type of texture (normal loaded texture, auto-texture)

    , tusFrameNames              :: [String]
    , tusFrames                  :: Maybe [t]
    , tusName                    :: String          -- ^ optional name for the TUS
    , tusTextureAlias            :: String          -- ^ optional alias for texture frames
    , tusEffects                 :: [TextureEffect]
    }
    deriving (Eq,Ord)