content: {-# language CPP #-}
  {-# language MultiParamTypeClasses #-}
  
  #ifndef ENABLE_INTERNAL_DOCUMENTATION
  {-# OPTIONS_HADDOCK hide #-}
  #endif
  
  module OpenCV.Internal.Core.Types.Vec
      ( Vec(..)
      , VecDim
      , IsVec(..)
      ) where
  
  import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr )
  import "base" GHC.TypeLits
  import "linear" Linear ( V2, V3, V4 )
  import "this" OpenCV.Internal.C.Types
  
  --------------------------------------------------------------------------------
  
  newtype Vec (dim :: Nat) (depth :: *)
        = Vec {unVec :: ForeignPtr (C'Vec dim depth)}
  
  type instance C (Vec dim depth) = C'Vec dim depth
  
  instance WithPtr (Vec dim depth) where
      withPtr = withForeignPtr . unVec
  
  type family VecDim (v :: * -> *) :: Nat
  
  type instance VecDim (Vec dim) = dim
  
  type instance VecDim V2 = 2
  type instance VecDim V3 = 3
  type instance VecDim V4 = 4
  
  class IsVec (v :: * -> *) (depth :: *)  where
      toVec   :: v depth -> Vec (VecDim v) depth
      fromVec :: Vec (VecDim v) depth -> v depth
  
      toVecIO :: v depth -> IO (Vec (VecDim v) depth)
      toVecIO = pure . toVec
  
  --------------------------------------------------------------------------------
  
  instance (IsVec V2 a, Show a)
        => Show (Vec 2 a) where
      showsPrec prec vec =
          showParen (prec >= 10)
          $ showString "toVec "
          . showParen True (shows v2)
        where
          v2 :: V2 a
          v2 = fromVec vec
  
  instance (IsVec V3 a, Show a)
        => Show (Vec 3 a) where
      showsPrec prec vec =
          showParen (prec >= 10)
          $ showString "toVec "
          . showParen True (shows v3)
        where
          v3 :: V3 a
          v3 = fromVec vec
  
  instance (IsVec V4 a, Show a)
        => Show (Vec 4 a) where
      showsPrec prec vec =
          showParen (prec >= 10)
          $ showString "toVec "
          . showParen True (shows v4)
        where
          v4 :: V4 a
          v4 = fromVec vec
  