{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
module Classes.Graphics.Buffer where

import qualified Graphics.Rendering.OpenGL as GL

import SDL (($=), get)

import Foreign.Storable

-- internal imports

import Classes.Graphics.Bindable

-- | this aims to be a typeclass for all used buffer objects throughout the
--   game. all buffer objects have to instanciate the Bindable typeclass.
--   think of it as some kind of interface in the object oriented context
class (Bindable a, Storable (StoreType a)) =>
  Buffer a where

    -- | datatype inside the buffer
    type StoreType a :: *

    -- | container datatype for 'StoreType's
    type StoreContainer a :: * -> *

    -- | what buffer target does the buffer bind to
    target :: a -> GL.BufferTarget

    -- | retrieve ID from buffer object
    glId :: a -> IO (GL.BufferObject)

    -- | bind the buffer object and fill it with null data
    initialize :: a -> IO ()

    -- | fill the buffer with actual data
    write
      :: a
      -> Word
        -- ^ write offset from beginning of buffer in number of data elements
      -> StoreContainer a (StoreType a)
        -- ^ Data to write
      -> IO ()

    -- | expand the buffer to double of it's previous size.
    expand :: a -> IO ()

    -- | free resources and delete the object
    delete :: a -> IO ()
