{-# LANGUAGE ForeignFunctionInterface #-}

module Graphics.QML.DataModel.Internal.FFI (
    module Graphics.QML.DataModel.Internal.FFI
  , module Graphics.QML.DataModel.Internal.FFI.Types
) where

import Graphics.QML.DataModel.Internal.FFI.Types

import Control.Exception
import Foreign.C.String
import Foreign.C.Types
import Foreign.Marshal.Alloc
import Foreign.Ptr

-- Interface bindings.
foreign import ccall unsafe "registerHaskellModel" 
  c_registerHaskellModel :: IO ()

foreign import ccall unsafe "registerHaskellModelDelegate"
  c_registerHaskellModelDelegate :: IO HmDelegateHandle

foreign import ccall unsafe "unregisterHaskellModelDelegate"
  c_unregisterHaskellModelDelegate :: HmDelegateHandle -> IO ()

-- Set delegate properties

foreign import ccall unsafe "setHaskellModelCallbacks"
  c_setHaskellModelCallbacks :: HmDelegateHandle -> Ptr HmCallbacks -> IO ()

foreign import ccall unsafe "addHaskellModelRole"
  c_addHaskellModelRole :: HmDelegateHandle -> CInt -> CString -> IO ()

addHaskellModelRole :: HmDelegateHandle -> Int -> String -> IO ()
addHaskellModelRole h i s = c_addHaskellModelRole h (fromIntegral i) =<< newCString s

-- QtVariant creation and destruction

foreign import ccall unsafe "newQtInt"
  c_newQtInt :: CInt -> IO QtVariant

foreign import ccall unsafe "newQtDouble"
  c_newQtDouble :: CDouble -> IO QtVariant

foreign import ccall unsafe "newQtText"
  c_newQtText :: CString -> IO QtVariant

newQtString :: String -> IO QtVariant
newQtString s = bracket (newCString s) free c_newQtText

foreign import ccall unsafe "newQtBool"
  c_newQtBool :: CInt -> IO QtVariant

foreign import ccall unsafe "newQtNull"
  c_newQtNull :: IO QtVariant

-- Function pointers for use within C.
foreign import ccall "wrapper"
  c_createRowCountCallback
    :: RowCountCallback -> IO (FunPtr RowCountCallback)

emptyRowCountCallback :: IO (FunPtr RowCountCallback)
emptyRowCountCallback = c_createRowCountCallback $ return 0

foreign import ccall "wrapper"
  c_createColumnCountCallback
    :: ColumnCountCallback -> IO (FunPtr ColumnCountCallback)

emptyColumnCountCallback :: IO (FunPtr RowCountCallback)
emptyColumnCountCallback = c_createColumnCountCallback $ return 0

foreign import ccall "wrapper" 
  c_createDataCallback
    :: DataCallback -> IO (FunPtr DataCallback)

emptyDataCallback :: IO (FunPtr DataCallback)
emptyDataCallback = c_createDataCallback $ \_ _ -> c_newQtNull

foreign import ccall "wrapper"
  c_createHeaderDataCallback 
    :: HeaderDataCallback -> IO (FunPtr HeaderDataCallback)

emptyHeaderDataCallback :: IO (FunPtr HeaderDataCallback)
emptyHeaderDataCallback = c_createHeaderDataCallback $ const c_newQtNull