{- |
Copyright  : Will Thompson, Iñaki García Etxebarria and Jonas Platte
License    : LGPL-2.1
Maintainer : Iñaki García Etxebarria (inaki@blueleaf.cc)

Virtual table for a JSCClass. This can be optionally used when registering a 'GI.JavaScriptCore.Objects.Class.Class' in a 'GI.JavaScriptCore.Objects.Context.Context'
to provide a custom implementation for the class. All virtual functions are optional and can be set to
'Nothing' to fallback to the default implementation.
-}

#define ENABLE_OVERLOADING (MIN_VERSION_haskell_gi_overloading(1,0,0) \
       && !defined(__HADDOCK_VERSION__))

module GI.JavaScriptCore.Structs.ClassVTable
    (

-- * Exported types
    ClassVTable(..)                         ,
    newZeroClassVTable                      ,
    noClassVTable                           ,


 -- * Properties
-- ** deleteProperty #attr:deleteProperty#
{- | a 'GI.JavaScriptCore.Callbacks.ClassDeletePropertyFunction' for deleting a property.
-}
#if ENABLE_OVERLOADING
    classVTable_deleteProperty              ,
#endif
    clearClassVTableDeleteProperty          ,
    getClassVTableDeleteProperty            ,
    setClassVTableDeleteProperty            ,


-- ** enumerateProperties #attr:enumerateProperties#
{- | a 'GI.JavaScriptCore.Callbacks.ClassEnumeratePropertiesFunction' for enumerating properties.
-}
#if ENABLE_OVERLOADING
    classVTable_enumerateProperties         ,
#endif
    clearClassVTableEnumerateProperties     ,
    getClassVTableEnumerateProperties       ,
    setClassVTableEnumerateProperties       ,


-- ** getProperty #attr:getProperty#
{- | a 'GI.JavaScriptCore.Callbacks.ClassGetPropertyFunction' for getting a property.
-}
#if ENABLE_OVERLOADING
    classVTable_getProperty                 ,
#endif
    clearClassVTableGetProperty             ,
    getClassVTableGetProperty               ,
    setClassVTableGetProperty               ,


-- ** hasProperty #attr:hasProperty#
{- | a 'GI.JavaScriptCore.Callbacks.ClassHasPropertyFunction' for querying a property.
-}
#if ENABLE_OVERLOADING
    classVTable_hasProperty                 ,
#endif
    clearClassVTableHasProperty             ,
    getClassVTableHasProperty               ,
    setClassVTableHasProperty               ,


-- ** setProperty #attr:setProperty#
{- | a 'GI.JavaScriptCore.Callbacks.ClassSetPropertyFunction' for setting a property.
-}
#if ENABLE_OVERLOADING
    classVTable_setProperty                 ,
#endif
    clearClassVTableSetProperty             ,
    getClassVTableSetProperty               ,
    setClassVTableSetProperty               ,




    ) where

import Data.GI.Base.ShortPrelude
import qualified Data.GI.Base.ShortPrelude as SP
import qualified Data.GI.Base.Overloading as O
import qualified Prelude as P

import qualified Data.GI.Base.Attributes as GI.Attributes
import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr
import qualified Data.GI.Base.GClosure as B.GClosure
import qualified Data.GI.Base.GError as B.GError
import qualified Data.GI.Base.GVariant as B.GVariant
import qualified Data.GI.Base.GValue as B.GValue
import qualified Data.GI.Base.GParamSpec as B.GParamSpec
import qualified Data.GI.Base.CallStack as B.CallStack
import qualified Data.GI.Base.Properties as B.Properties
import qualified Data.Text as T
import qualified Data.ByteString.Char8 as B
import qualified Data.Map as Map
import qualified Foreign.Ptr as FP
import qualified GHC.OverloadedLabels as OL

import qualified GI.JavaScriptCore.Callbacks as JavaScriptCore.Callbacks

-- | Memory-managed wrapper type.
newtype ClassVTable = ClassVTable (ManagedPtr ClassVTable)
instance WrappedPtr ClassVTable where
    wrappedPtrCalloc = callocBytes 72
    wrappedPtrCopy = \p -> withManagedPtr p (copyBytes 72 >=> wrapPtr ClassVTable)
    wrappedPtrFree = Just ptr_to_g_free

-- | Construct a `ClassVTable` struct initialized to zero.
newZeroClassVTable :: MonadIO m => m ClassVTable
newZeroClassVTable = liftIO $ wrappedPtrCalloc >>= wrapPtr ClassVTable

instance tag ~ 'AttrSet => Constructible ClassVTable tag where
    new _ attrs = do
        o <- newZeroClassVTable
        GI.Attributes.set o attrs
        return o


-- | A convenience alias for `Nothing` :: `Maybe` `ClassVTable`.
noClassVTable :: Maybe ClassVTable
noClassVTable = Nothing

{- |
Get the value of the “@get_property@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' classVTable #getProperty
@
-}
getClassVTableGetProperty :: MonadIO m => ClassVTable -> m (Maybe JavaScriptCore.Callbacks.ClassGetPropertyFunction)
getClassVTableGetProperty s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 0) :: IO (FunPtr JavaScriptCore.Callbacks.C_ClassGetPropertyFunction)
    result <- SP.convertFunPtrIfNonNull val $ \val' -> do
        let val'' = JavaScriptCore.Callbacks.dynamic_ClassGetPropertyFunction val'
        return val''
    return result

{- |
Set the value of the “@get_property@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' classVTable [ #getProperty 'Data.GI.Base.Attributes.:=' value ]
@
-}
setClassVTableGetProperty :: MonadIO m => ClassVTable -> FunPtr JavaScriptCore.Callbacks.C_ClassGetPropertyFunction -> m ()
setClassVTableGetProperty s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 0) (val :: FunPtr JavaScriptCore.Callbacks.C_ClassGetPropertyFunction)

{- |
Set the value of the “@get_property@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #getProperty
@
-}
clearClassVTableGetProperty :: MonadIO m => ClassVTable -> m ()
clearClassVTableGetProperty s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 0) (FP.nullFunPtr :: FunPtr JavaScriptCore.Callbacks.C_ClassGetPropertyFunction)

#if ENABLE_OVERLOADING
data ClassVTableGetPropertyFieldInfo
instance AttrInfo ClassVTableGetPropertyFieldInfo where
    type AttrAllowedOps ClassVTableGetPropertyFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint ClassVTableGetPropertyFieldInfo = (~) (FunPtr JavaScriptCore.Callbacks.C_ClassGetPropertyFunction)
    type AttrBaseTypeConstraint ClassVTableGetPropertyFieldInfo = (~) ClassVTable
    type AttrGetType ClassVTableGetPropertyFieldInfo = Maybe JavaScriptCore.Callbacks.ClassGetPropertyFunction
    type AttrLabel ClassVTableGetPropertyFieldInfo = "get_property"
    type AttrOrigin ClassVTableGetPropertyFieldInfo = ClassVTable
    attrGet _ = getClassVTableGetProperty
    attrSet _ = setClassVTableGetProperty
    attrConstruct = undefined
    attrClear _ = clearClassVTableGetProperty

classVTable_getProperty :: AttrLabelProxy "getProperty"
classVTable_getProperty = AttrLabelProxy

#endif


{- |
Get the value of the “@set_property@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' classVTable #setProperty
@
-}
getClassVTableSetProperty :: MonadIO m => ClassVTable -> m (Maybe JavaScriptCore.Callbacks.ClassSetPropertyFunction)
getClassVTableSetProperty s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 8) :: IO (FunPtr JavaScriptCore.Callbacks.C_ClassSetPropertyFunction)
    result <- SP.convertFunPtrIfNonNull val $ \val' -> do
        let val'' = JavaScriptCore.Callbacks.dynamic_ClassSetPropertyFunction val'
        return val''
    return result

{- |
Set the value of the “@set_property@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' classVTable [ #setProperty 'Data.GI.Base.Attributes.:=' value ]
@
-}
setClassVTableSetProperty :: MonadIO m => ClassVTable -> FunPtr JavaScriptCore.Callbacks.C_ClassSetPropertyFunction -> m ()
setClassVTableSetProperty s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 8) (val :: FunPtr JavaScriptCore.Callbacks.C_ClassSetPropertyFunction)

{- |
Set the value of the “@set_property@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #setProperty
@
-}
clearClassVTableSetProperty :: MonadIO m => ClassVTable -> m ()
clearClassVTableSetProperty s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 8) (FP.nullFunPtr :: FunPtr JavaScriptCore.Callbacks.C_ClassSetPropertyFunction)

#if ENABLE_OVERLOADING
data ClassVTableSetPropertyFieldInfo
instance AttrInfo ClassVTableSetPropertyFieldInfo where
    type AttrAllowedOps ClassVTableSetPropertyFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint ClassVTableSetPropertyFieldInfo = (~) (FunPtr JavaScriptCore.Callbacks.C_ClassSetPropertyFunction)
    type AttrBaseTypeConstraint ClassVTableSetPropertyFieldInfo = (~) ClassVTable
    type AttrGetType ClassVTableSetPropertyFieldInfo = Maybe JavaScriptCore.Callbacks.ClassSetPropertyFunction
    type AttrLabel ClassVTableSetPropertyFieldInfo = "set_property"
    type AttrOrigin ClassVTableSetPropertyFieldInfo = ClassVTable
    attrGet _ = getClassVTableSetProperty
    attrSet _ = setClassVTableSetProperty
    attrConstruct = undefined
    attrClear _ = clearClassVTableSetProperty

classVTable_setProperty :: AttrLabelProxy "setProperty"
classVTable_setProperty = AttrLabelProxy

#endif


{- |
Get the value of the “@has_property@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' classVTable #hasProperty
@
-}
getClassVTableHasProperty :: MonadIO m => ClassVTable -> m (Maybe JavaScriptCore.Callbacks.ClassHasPropertyFunction)
getClassVTableHasProperty s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 16) :: IO (FunPtr JavaScriptCore.Callbacks.C_ClassHasPropertyFunction)
    result <- SP.convertFunPtrIfNonNull val $ \val' -> do
        let val'' = JavaScriptCore.Callbacks.dynamic_ClassHasPropertyFunction val'
        return val''
    return result

{- |
Set the value of the “@has_property@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' classVTable [ #hasProperty 'Data.GI.Base.Attributes.:=' value ]
@
-}
setClassVTableHasProperty :: MonadIO m => ClassVTable -> FunPtr JavaScriptCore.Callbacks.C_ClassHasPropertyFunction -> m ()
setClassVTableHasProperty s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 16) (val :: FunPtr JavaScriptCore.Callbacks.C_ClassHasPropertyFunction)

{- |
Set the value of the “@has_property@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #hasProperty
@
-}
clearClassVTableHasProperty :: MonadIO m => ClassVTable -> m ()
clearClassVTableHasProperty s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 16) (FP.nullFunPtr :: FunPtr JavaScriptCore.Callbacks.C_ClassHasPropertyFunction)

#if ENABLE_OVERLOADING
data ClassVTableHasPropertyFieldInfo
instance AttrInfo ClassVTableHasPropertyFieldInfo where
    type AttrAllowedOps ClassVTableHasPropertyFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint ClassVTableHasPropertyFieldInfo = (~) (FunPtr JavaScriptCore.Callbacks.C_ClassHasPropertyFunction)
    type AttrBaseTypeConstraint ClassVTableHasPropertyFieldInfo = (~) ClassVTable
    type AttrGetType ClassVTableHasPropertyFieldInfo = Maybe JavaScriptCore.Callbacks.ClassHasPropertyFunction
    type AttrLabel ClassVTableHasPropertyFieldInfo = "has_property"
    type AttrOrigin ClassVTableHasPropertyFieldInfo = ClassVTable
    attrGet _ = getClassVTableHasProperty
    attrSet _ = setClassVTableHasProperty
    attrConstruct = undefined
    attrClear _ = clearClassVTableHasProperty

classVTable_hasProperty :: AttrLabelProxy "hasProperty"
classVTable_hasProperty = AttrLabelProxy

#endif


{- |
Get the value of the “@delete_property@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' classVTable #deleteProperty
@
-}
getClassVTableDeleteProperty :: MonadIO m => ClassVTable -> m (Maybe JavaScriptCore.Callbacks.ClassDeletePropertyFunction)
getClassVTableDeleteProperty s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 24) :: IO (FunPtr JavaScriptCore.Callbacks.C_ClassDeletePropertyFunction)
    result <- SP.convertFunPtrIfNonNull val $ \val' -> do
        let val'' = JavaScriptCore.Callbacks.dynamic_ClassDeletePropertyFunction val'
        return val''
    return result

{- |
Set the value of the “@delete_property@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' classVTable [ #deleteProperty 'Data.GI.Base.Attributes.:=' value ]
@
-}
setClassVTableDeleteProperty :: MonadIO m => ClassVTable -> FunPtr JavaScriptCore.Callbacks.C_ClassDeletePropertyFunction -> m ()
setClassVTableDeleteProperty s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 24) (val :: FunPtr JavaScriptCore.Callbacks.C_ClassDeletePropertyFunction)

{- |
Set the value of the “@delete_property@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #deleteProperty
@
-}
clearClassVTableDeleteProperty :: MonadIO m => ClassVTable -> m ()
clearClassVTableDeleteProperty s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 24) (FP.nullFunPtr :: FunPtr JavaScriptCore.Callbacks.C_ClassDeletePropertyFunction)

#if ENABLE_OVERLOADING
data ClassVTableDeletePropertyFieldInfo
instance AttrInfo ClassVTableDeletePropertyFieldInfo where
    type AttrAllowedOps ClassVTableDeletePropertyFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint ClassVTableDeletePropertyFieldInfo = (~) (FunPtr JavaScriptCore.Callbacks.C_ClassDeletePropertyFunction)
    type AttrBaseTypeConstraint ClassVTableDeletePropertyFieldInfo = (~) ClassVTable
    type AttrGetType ClassVTableDeletePropertyFieldInfo = Maybe JavaScriptCore.Callbacks.ClassDeletePropertyFunction
    type AttrLabel ClassVTableDeletePropertyFieldInfo = "delete_property"
    type AttrOrigin ClassVTableDeletePropertyFieldInfo = ClassVTable
    attrGet _ = getClassVTableDeleteProperty
    attrSet _ = setClassVTableDeleteProperty
    attrConstruct = undefined
    attrClear _ = clearClassVTableDeleteProperty

classVTable_deleteProperty :: AttrLabelProxy "deleteProperty"
classVTable_deleteProperty = AttrLabelProxy

#endif


{- |
Get the value of the “@enumerate_properties@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' classVTable #enumerateProperties
@
-}
getClassVTableEnumerateProperties :: MonadIO m => ClassVTable -> m (Maybe JavaScriptCore.Callbacks.ClassEnumeratePropertiesFunction)
getClassVTableEnumerateProperties s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 32) :: IO (FunPtr JavaScriptCore.Callbacks.C_ClassEnumeratePropertiesFunction)
    result <- SP.convertFunPtrIfNonNull val $ \val' -> do
        let val'' = JavaScriptCore.Callbacks.dynamic_ClassEnumeratePropertiesFunction val'
        return val''
    return result

{- |
Set the value of the “@enumerate_properties@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' classVTable [ #enumerateProperties 'Data.GI.Base.Attributes.:=' value ]
@
-}
setClassVTableEnumerateProperties :: MonadIO m => ClassVTable -> FunPtr JavaScriptCore.Callbacks.C_ClassEnumeratePropertiesFunction -> m ()
setClassVTableEnumerateProperties s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 32) (val :: FunPtr JavaScriptCore.Callbacks.C_ClassEnumeratePropertiesFunction)

{- |
Set the value of the “@enumerate_properties@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #enumerateProperties
@
-}
clearClassVTableEnumerateProperties :: MonadIO m => ClassVTable -> m ()
clearClassVTableEnumerateProperties s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 32) (FP.nullFunPtr :: FunPtr JavaScriptCore.Callbacks.C_ClassEnumeratePropertiesFunction)

#if ENABLE_OVERLOADING
data ClassVTableEnumeratePropertiesFieldInfo
instance AttrInfo ClassVTableEnumeratePropertiesFieldInfo where
    type AttrAllowedOps ClassVTableEnumeratePropertiesFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint ClassVTableEnumeratePropertiesFieldInfo = (~) (FunPtr JavaScriptCore.Callbacks.C_ClassEnumeratePropertiesFunction)
    type AttrBaseTypeConstraint ClassVTableEnumeratePropertiesFieldInfo = (~) ClassVTable
    type AttrGetType ClassVTableEnumeratePropertiesFieldInfo = Maybe JavaScriptCore.Callbacks.ClassEnumeratePropertiesFunction
    type AttrLabel ClassVTableEnumeratePropertiesFieldInfo = "enumerate_properties"
    type AttrOrigin ClassVTableEnumeratePropertiesFieldInfo = ClassVTable
    attrGet _ = getClassVTableEnumerateProperties
    attrSet _ = setClassVTableEnumerateProperties
    attrConstruct = undefined
    attrClear _ = clearClassVTableEnumerateProperties

classVTable_enumerateProperties :: AttrLabelProxy "enumerateProperties"
classVTable_enumerateProperties = AttrLabelProxy

#endif



#if ENABLE_OVERLOADING
instance O.HasAttributeList ClassVTable
type instance O.AttributeList ClassVTable = ClassVTableAttributeList
type ClassVTableAttributeList = ('[ '("getProperty", ClassVTableGetPropertyFieldInfo), '("setProperty", ClassVTableSetPropertyFieldInfo), '("hasProperty", ClassVTableHasPropertyFieldInfo), '("deleteProperty", ClassVTableDeletePropertyFieldInfo), '("enumerateProperties", ClassVTableEnumeratePropertiesFieldInfo)] :: [(Symbol, *)])
#endif

#if ENABLE_OVERLOADING
type family ResolveClassVTableMethod (t :: Symbol) (o :: *) :: * where
    ResolveClassVTableMethod l o = O.MethodResolutionFailed l o

instance (info ~ ResolveClassVTableMethod t ClassVTable, O.MethodInfo info ClassVTable p) => OL.IsLabel t (ClassVTable -> p) where
#if MIN_VERSION_base(4,10,0)
    fromLabel = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#else
    fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#endif

#endif