{-# LANGUAGE DeriveDataTypeable #-}
{- |
Module      : Graphics.V4L2.Field.Internal
Maintainer  : claude@mathr.co.uk
Stability   : no
Portability : no
-}
module Graphics.V4L2.Field.Internal
  ( Field(..)
  , fieldHasTop
  , fieldHasBottom
  , fieldHasBoth
  , fromField
  , toField
  ) where

import Data.Data (Data)
import Data.Typeable (Typeable)
import Data.Word (Word32)
import System.IO.Unsafe (unsafePerformIO)
import Foreign.Marshal.Utils (toBool)

import Bindings.Linux.VideoDev2

import Foreign.Extra.CEnum (toCEnum, fromCEnum)

{- |  Interlacing modes. -}
data Field
  = FieldAny
  | FieldNone
  | FieldTop
  | FieldBottom
  | FieldInterlaced
  | FieldSeqTB
  | FieldSeqBT
  | FieldAlternate
  | FieldInterlacedTB
  | FieldInterlacedBT
  | FieldUnknown Word32
  deriving (Eq, Ord, Read, Show, Data, Typeable)

{- |  internal -}
fromField :: C'v4l2_field -> Field
{- |  internal -}
toField :: Field -> C'v4l2_field

(fromField, toField) = (fromCEnum spec (FieldUnknown . fromIntegral), toCEnum spec isUnknown unUnknown) where
  spec =
    [ ( FieldAny          , c'V4L2_FIELD_ANY           )
    , ( FieldNone         , c'V4L2_FIELD_NONE          )
    , ( FieldTop          , c'V4L2_FIELD_TOP           )
    , ( FieldBottom       , c'V4L2_FIELD_BOTTOM        )
    , ( FieldInterlaced   , c'V4L2_FIELD_INTERLACED    )
    , ( FieldSeqTB        , c'V4L2_FIELD_SEQ_TB        )
    , ( FieldSeqBT        , c'V4L2_FIELD_SEQ_BT        )
    , ( FieldAlternate    , c'V4L2_FIELD_ALTERNATE     )
    , ( FieldInterlacedTB , c'V4L2_FIELD_INTERLACED_TB )
    , ( FieldInterlacedBT , c'V4L2_FIELD_INTERLACED_BT )
    ]
  isUnknown (FieldUnknown _) = True
  isUnknown _ = False
  unUnknown (FieldUnknown f) = fromIntegral f
  unUnknown _ = error "Graphice.V4L2.Field.Internal.toField"

{- |  Inspect field interlacing. -}
fieldHasTop :: Field -> Bool
fieldHasTop    f = unsafePerformIO $ toBool `fmap` c'V4L2_FIELD_HAS_TOP    (toField f)

{- |  Inspect field interlacing. -}
fieldHasBottom :: Field -> Bool
fieldHasBottom f = unsafePerformIO $ toBool `fmap` c'V4L2_FIELD_HAS_BOTTOM (toField f)

{- |  Inspect field interlacing. -}
fieldHasBoth :: Field -> Bool
fieldHasBoth   f = unsafePerformIO $ toBool `fmap` c'V4L2_FIELD_HAS_BOTH   (toField f)