-- | Module for handling processing with GEGL
module GEGL.Process
  ( gegl_node_process
  , gegl_node_blit
  ) where

import Data.Bits

import Foreign.Marshal (free)
import Foreign.Marshal.Utils (new)
import Foreign.Ptr (Ptr)
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.C.Types (CInt(..), CDouble(..))

import GEGL.Enums (GeglBlitFlag)

import qualified GEGL.FFI.Process as FFI
import GEGL.FFI.Node (GeglNode(..))
import GEGL.FFI.Rectangle (GeglRectangle)

import BABL.FFI.Format (BablFormatPtr(..))

-- | Render a composition as a blocking operation.
--   See 'gegl_processor_work' for a non-blocking operation.
gegl_node_process
  :: GeglNode -- ^ A node without outputs
  -> IO ()
gegl_node_process (GeglNode fnode) = withForeignPtr fnode (\node ->
  FFI.c_gegl_node_process node)

-- | Render a rectangular region of a node
gegl_node_blit
  :: GeglNode       -- ^ Node to blit
  -> Double         -- ^ Scale
  -> GeglRectangle  -- ^ Area of Interest
  -> BablFormatPtr  -- ^ Pixel format
  -> Ptr a          -- ^ Pointer to destination buffer
  -> Int            -- ^ Row stride in bytes. If set to '0', stride will be
                    -- computed automatically from width and color format.
  -> [GeglBlitFlag] -- ^ GEGL blit flags
  -> IO ()
gegl_node_blit (GeglNode fnode) scale rect (BablFormatPtr babl) buf stride flags = do
  crect <- new rect
  let cscale  = CDouble scale
      cstride = CInt (fromIntegral stride)
      cflags  = CInt $ fromIntegral $
        foldl (\acc arg -> acc .|. fromEnum arg) 0 flags
  withForeignPtr fnode (\node ->
    FFI.c_gegl_node_blit node cscale crect babl buf cstride cflags)
  free crect