module Codec.GlTF.BufferView
  ( BufferViewIx(..)
  , BufferView(..)
  , BufferViewTarget(..)
  , pattern ARRAY_BUFFER
  , pattern ELEMENT_ARRAY_BUFFER
  ) where

import Codec.GlTF.Prelude

import Codec.GlTF.Buffer (BufferIx)

newtype BufferViewIx = BufferViewIx { unBufferViewIx :: Int }
  deriving (Eq, Ord, Show, FromJSON, ToJSON, Generic)

-- | A view into a buffer generally representing a subset of the buffer.
data BufferView = BufferView
  { buffer     :: BufferIx
  , byteOffset :: Size
  , byteLength :: Size
  , byteStride :: Maybe Size -- [4-252]
    -- ^ The stride, in bytes, between vertex attributes.
    -- When this is not defined, data is tightly packed.
    -- When two or more accessors use the same bufferView, this field must be defined.
  , target     :: Maybe BufferViewTarget
    -- ^ The target that the GPU buffer should be bound to.
  , name       :: Maybe Text
  , extensions :: Maybe Object
  , extras     :: Maybe Value
  } deriving (Eq, Show, Generic)

instance FromJSON BufferView where
  parseJSON = withObject "BufferView" \o -> do
    buffer     <- o .:  "buffer"
    byteOffset <- o .:? "byteOffset" .!= 0
    byteLength <- o .:  "byteLength"
    byteStride <- o .:? "byteStride"
    target     <- o .:? "target"
    name       <- o .:? "name"
    extensions <- o .:? "extensions"
    extras     <- o .:? "extras"
    pure BufferView{..}

instance ToJSON BufferView

newtype BufferViewTarget = BufferViewTarget { unBufferViewTarget :: Int }
  deriving (Eq, Ord, Show, FromJSON, ToJSON, Generic)

pattern ARRAY_BUFFER :: BufferViewTarget
pattern ARRAY_BUFFER = BufferViewTarget 34962

pattern ELEMENT_ARRAY_BUFFER :: BufferViewTarget
pattern ELEMENT_ARRAY_BUFFER = BufferViewTarget 34963