{-# LANGUAGE TypeApplications #-}


-- | Copyright  : Will Thompson and Iñaki García Etxebarria
-- License    : LGPL-2.1
-- Maintainer : Iñaki García Etxebarria
-- 
-- The @GSourceFuncs@ struct contains a table of
-- functions used to handle event sources in a generic manner.
-- 
-- For idle sources, the prepare and check functions always return 'P.True'
-- to indicate that the source is always ready to be processed. The prepare
-- function also returns a timeout value of 0 to ensure that the @/poll()/@ call
-- doesn\'t block (since that would be time wasted which could have been spent
-- running the idle function).
-- 
-- For timeout sources, the prepare and check functions both return 'P.True'
-- if the timeout interval has expired. The prepare function also returns
-- a timeout value to ensure that the @/poll()/@ call doesn\'t block too long
-- and miss the next timeout.
-- 
-- For file descriptor sources, the prepare function typically returns 'P.False',
-- since it must wait until @/poll()/@ has been called before it knows whether
-- any events need to be processed. It sets the returned timeout to -1 to
-- indicate that it doesn\'t mind how long the @/poll()/@ call blocks. In the
-- check function, it tests the results of the @/poll()/@ call to see if the
-- required condition has been met, and returns 'P.True' if so.

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

module GI.GLib.Structs.SourceFuncs
    ( 

-- * Exported types
    SourceFuncs(..)                         ,
    newZeroSourceFuncs                      ,


 -- * Methods

#if defined(ENABLE_OVERLOADING)
    ResolveSourceFuncsMethod                ,
#endif



 -- * Properties


-- ** check #attr:check#
-- | Called after all the file descriptors are polled. The
--     source should return 'P.True' if it is ready to be dispatched. Note that
--     some time may have passed since the previous prepare function was called,
--     so the source should be checked again here.  Since 2.36 this may
--     be 'P.Nothing', in which case the effect is as if the function always returns
--     'P.False'.

    clearSourceFuncsCheck                   ,
    getSourceFuncsCheck                     ,
    setSourceFuncsCheck                     ,
#if defined(ENABLE_OVERLOADING)
    sourceFuncs_check                       ,
#endif


-- ** finalize #attr:finalize#
-- | Called when the source is finalized. At this point,
--     the source will have been destroyed, had its callback cleared, and have
--     been removed from its t'GI.GLib.Structs.MainContext.MainContext', but it will still have
--     its final reference count, so methods can be called on it from within
--     this function. This may be 'P.Nothing', in which case the effect is as if the
--     function does nothing and returns.

    clearSourceFuncsFinalize                ,
    getSourceFuncsFinalize                  ,
    setSourceFuncsFinalize                  ,
#if defined(ENABLE_OVERLOADING)
    sourceFuncs_finalize                    ,
#endif


-- ** prepare #attr:prepare#
-- | Called before all the file descriptors are polled. If
--     the source can determine that it is ready here (without waiting for the
--     results of the @/poll()/@ call) it should return 'P.True'. It can also return
--     a /@timeout_@/ value which should be the maximum timeout (in milliseconds)
--     which should be passed to the @/poll()/@ call. The actual timeout used will
--     be -1 if all sources returned -1, or it will be the minimum of all
--     the /@timeout_@/ values returned which were >= 0.  Since 2.36 this may
--     be 'P.Nothing', in which case the effect is as if the function always returns
--     'P.False' with a timeout of -1.  If /@prepare@/ returns a
--     timeout and the source also has a ready time set, then the
--     lower of the two will be used.

    clearSourceFuncsPrepare                 ,
    getSourceFuncsPrepare                   ,
    setSourceFuncsPrepare                   ,
#if defined(ENABLE_OVERLOADING)
    sourceFuncs_prepare                     ,
#endif




    ) 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.BasicTypes as B.Types
import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr
import qualified Data.GI.Base.GArray as B.GArray
import qualified Data.GI.Base.GClosure as B.GClosure
import qualified Data.GI.Base.GError as B.GError
import qualified Data.GI.Base.GHashTable as B.GHT
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.GI.Base.Signals as B.Signals
import qualified Control.Monad.IO.Class as MIO
import qualified Data.Coerce as Coerce
import qualified Data.Text as T
import qualified Data.Kind as DK
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 GHC.Records as R
import qualified Data.Word as DW
import qualified Data.Int as DI
import qualified System.Posix.Types as SPT
import qualified Foreign.C.Types as FCT

-- Workaround for https://gitlab.haskell.org/ghc/ghc/-/issues/23392
#if MIN_VERSION_base(4,18,0)
import qualified GI.GLib.Callbacks as GLib.Callbacks

#else
import qualified GI.GLib.Callbacks as GLib.Callbacks

#endif

-- | Memory-managed wrapper type.
newtype SourceFuncs = SourceFuncs (SP.ManagedPtr SourceFuncs)
    deriving (Eq)

instance SP.ManagedPtrNewtype SourceFuncs where
    toManagedPtr (SourceFuncs p) = p

instance BoxedPtr SourceFuncs where
    boxedPtrCopy = \p -> B.ManagedPtr.withManagedPtr p (copyBytes 48 >=> B.ManagedPtr.wrapPtr SourceFuncs)
    boxedPtrFree = \x -> SP.withManagedPtr x SP.freeMem
instance CallocPtr SourceFuncs where
    boxedPtrCalloc = callocBytes 48


-- | Construct a t'SourceFuncs' struct initialized to zero.
newZeroSourceFuncs :: MonadIO m => m SourceFuncs
newZeroSourceFuncs = liftIO $ boxedPtrCalloc >>= wrapPtr SourceFuncs

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


-- | Get the value of the “@prepare@” field.
-- When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to
-- 
-- @
-- 'Data.GI.Base.Attributes.get' sourceFuncs #prepare
-- @
getSourceFuncsPrepare :: MonadIO m => SourceFuncs -> m (Maybe GLib.Callbacks.SourceFuncsPrepareFunc)
getSourceFuncsPrepare s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 0) :: IO (FunPtr GLib.Callbacks.C_SourceFuncsPrepareFunc)
    result <- SP.convertFunPtrIfNonNull val $ \val' -> do
        let val'' = GLib.Callbacks.dynamic_SourceFuncsPrepareFunc val'
        return val''
    return result

-- | Set the value of the “@prepare@” field.
-- When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to
-- 
-- @
-- 'Data.GI.Base.Attributes.set' sourceFuncs [ #prepare 'Data.GI.Base.Attributes.:=' value ]
-- @
setSourceFuncsPrepare :: MonadIO m => SourceFuncs -> FunPtr GLib.Callbacks.C_SourceFuncsPrepareFunc -> m ()
setSourceFuncsPrepare s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 0) (val :: FunPtr GLib.Callbacks.C_SourceFuncsPrepareFunc)

-- | Set the value of the “@prepare@” 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' #prepare
-- @
clearSourceFuncsPrepare :: MonadIO m => SourceFuncs -> m ()
clearSourceFuncsPrepare s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 0) (FP.nullFunPtr :: FunPtr GLib.Callbacks.C_SourceFuncsPrepareFunc)

#if defined(ENABLE_OVERLOADING)
data SourceFuncsPrepareFieldInfo
instance AttrInfo SourceFuncsPrepareFieldInfo where
    type AttrBaseTypeConstraint SourceFuncsPrepareFieldInfo = (~) SourceFuncs
    type AttrAllowedOps SourceFuncsPrepareFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint SourceFuncsPrepareFieldInfo = (~) (FunPtr GLib.Callbacks.C_SourceFuncsPrepareFunc)
    type AttrTransferTypeConstraint SourceFuncsPrepareFieldInfo = (~)GLib.Callbacks.SourceFuncsPrepareFunc
    type AttrTransferType SourceFuncsPrepareFieldInfo = (FunPtr GLib.Callbacks.C_SourceFuncsPrepareFunc)
    type AttrGetType SourceFuncsPrepareFieldInfo = Maybe GLib.Callbacks.SourceFuncsPrepareFunc
    type AttrLabel SourceFuncsPrepareFieldInfo = "prepare"
    type AttrOrigin SourceFuncsPrepareFieldInfo = SourceFuncs
    attrGet = getSourceFuncsPrepare
    attrSet = setSourceFuncsPrepare
    attrConstruct = undefined
    attrClear = clearSourceFuncsPrepare
    attrTransfer _ v = do
        GLib.Callbacks.mk_SourceFuncsPrepareFunc (GLib.Callbacks.wrap_SourceFuncsPrepareFunc Nothing v)
    dbgAttrInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.GLib.Structs.SourceFuncs.prepare"
        , O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-glib-2.0.30/docs/GI-GLib-Structs-SourceFuncs.html#g:attr:prepare"
        })

sourceFuncs_prepare :: AttrLabelProxy "prepare"
sourceFuncs_prepare = AttrLabelProxy

#endif


-- | Get the value of the “@check@” field.
-- When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to
-- 
-- @
-- 'Data.GI.Base.Attributes.get' sourceFuncs #check
-- @
getSourceFuncsCheck :: MonadIO m => SourceFuncs -> m (Maybe GLib.Callbacks.SourceFuncsCheckFunc)
getSourceFuncsCheck s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 8) :: IO (FunPtr GLib.Callbacks.C_SourceFuncsCheckFunc)
    result <- SP.convertFunPtrIfNonNull val $ \val' -> do
        let val'' = GLib.Callbacks.dynamic_SourceFuncsCheckFunc val'
        return val''
    return result

-- | Set the value of the “@check@” field.
-- When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to
-- 
-- @
-- 'Data.GI.Base.Attributes.set' sourceFuncs [ #check 'Data.GI.Base.Attributes.:=' value ]
-- @
setSourceFuncsCheck :: MonadIO m => SourceFuncs -> FunPtr GLib.Callbacks.C_SourceFuncsCheckFunc -> m ()
setSourceFuncsCheck s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 8) (val :: FunPtr GLib.Callbacks.C_SourceFuncsCheckFunc)

-- | Set the value of the “@check@” 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' #check
-- @
clearSourceFuncsCheck :: MonadIO m => SourceFuncs -> m ()
clearSourceFuncsCheck s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 8) (FP.nullFunPtr :: FunPtr GLib.Callbacks.C_SourceFuncsCheckFunc)

#if defined(ENABLE_OVERLOADING)
data SourceFuncsCheckFieldInfo
instance AttrInfo SourceFuncsCheckFieldInfo where
    type AttrBaseTypeConstraint SourceFuncsCheckFieldInfo = (~) SourceFuncs
    type AttrAllowedOps SourceFuncsCheckFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint SourceFuncsCheckFieldInfo = (~) (FunPtr GLib.Callbacks.C_SourceFuncsCheckFunc)
    type AttrTransferTypeConstraint SourceFuncsCheckFieldInfo = (~)GLib.Callbacks.SourceFuncsCheckFunc
    type AttrTransferType SourceFuncsCheckFieldInfo = (FunPtr GLib.Callbacks.C_SourceFuncsCheckFunc)
    type AttrGetType SourceFuncsCheckFieldInfo = Maybe GLib.Callbacks.SourceFuncsCheckFunc
    type AttrLabel SourceFuncsCheckFieldInfo = "check"
    type AttrOrigin SourceFuncsCheckFieldInfo = SourceFuncs
    attrGet = getSourceFuncsCheck
    attrSet = setSourceFuncsCheck
    attrConstruct = undefined
    attrClear = clearSourceFuncsCheck
    attrTransfer _ v = do
        GLib.Callbacks.mk_SourceFuncsCheckFunc (GLib.Callbacks.wrap_SourceFuncsCheckFunc Nothing v)
    dbgAttrInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.GLib.Structs.SourceFuncs.check"
        , O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-glib-2.0.30/docs/GI-GLib-Structs-SourceFuncs.html#g:attr:check"
        })

sourceFuncs_check :: AttrLabelProxy "check"
sourceFuncs_check = AttrLabelProxy

#endif


-- | Get the value of the “@finalize@” field.
-- When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to
-- 
-- @
-- 'Data.GI.Base.Attributes.get' sourceFuncs #finalize
-- @
getSourceFuncsFinalize :: MonadIO m => SourceFuncs -> m (Maybe GLib.Callbacks.SourceFuncsFinalizeFunc)
getSourceFuncsFinalize s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 24) :: IO (FunPtr GLib.Callbacks.C_SourceFuncsFinalizeFunc)
    result <- SP.convertFunPtrIfNonNull val $ \val' -> do
        let val'' = GLib.Callbacks.dynamic_SourceFuncsFinalizeFunc val'
        return val''
    return result

-- | Set the value of the “@finalize@” field.
-- When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to
-- 
-- @
-- 'Data.GI.Base.Attributes.set' sourceFuncs [ #finalize 'Data.GI.Base.Attributes.:=' value ]
-- @
setSourceFuncsFinalize :: MonadIO m => SourceFuncs -> FunPtr GLib.Callbacks.C_SourceFuncsFinalizeFunc -> m ()
setSourceFuncsFinalize s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 24) (val :: FunPtr GLib.Callbacks.C_SourceFuncsFinalizeFunc)

-- | Set the value of the “@finalize@” 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' #finalize
-- @
clearSourceFuncsFinalize :: MonadIO m => SourceFuncs -> m ()
clearSourceFuncsFinalize s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 24) (FP.nullFunPtr :: FunPtr GLib.Callbacks.C_SourceFuncsFinalizeFunc)

#if defined(ENABLE_OVERLOADING)
data SourceFuncsFinalizeFieldInfo
instance AttrInfo SourceFuncsFinalizeFieldInfo where
    type AttrBaseTypeConstraint SourceFuncsFinalizeFieldInfo = (~) SourceFuncs
    type AttrAllowedOps SourceFuncsFinalizeFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint SourceFuncsFinalizeFieldInfo = (~) (FunPtr GLib.Callbacks.C_SourceFuncsFinalizeFunc)
    type AttrTransferTypeConstraint SourceFuncsFinalizeFieldInfo = (~)GLib.Callbacks.SourceFuncsFinalizeFunc
    type AttrTransferType SourceFuncsFinalizeFieldInfo = (FunPtr GLib.Callbacks.C_SourceFuncsFinalizeFunc)
    type AttrGetType SourceFuncsFinalizeFieldInfo = Maybe GLib.Callbacks.SourceFuncsFinalizeFunc
    type AttrLabel SourceFuncsFinalizeFieldInfo = "finalize"
    type AttrOrigin SourceFuncsFinalizeFieldInfo = SourceFuncs
    attrGet = getSourceFuncsFinalize
    attrSet = setSourceFuncsFinalize
    attrConstruct = undefined
    attrClear = clearSourceFuncsFinalize
    attrTransfer _ v = do
        GLib.Callbacks.mk_SourceFuncsFinalizeFunc (GLib.Callbacks.wrap_SourceFuncsFinalizeFunc Nothing v)
    dbgAttrInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.GLib.Structs.SourceFuncs.finalize"
        , O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-glib-2.0.30/docs/GI-GLib-Structs-SourceFuncs.html#g:attr:finalize"
        })

sourceFuncs_finalize :: AttrLabelProxy "finalize"
sourceFuncs_finalize = AttrLabelProxy

#endif



#if defined(ENABLE_OVERLOADING)
instance O.HasAttributeList SourceFuncs
type instance O.AttributeList SourceFuncs = SourceFuncsAttributeList
type SourceFuncsAttributeList = ('[ '("prepare", SourceFuncsPrepareFieldInfo), '("check", SourceFuncsCheckFieldInfo), '("finalize", SourceFuncsFinalizeFieldInfo)] :: [(Symbol, DK.Type)])
#endif

#if defined(ENABLE_OVERLOADING)
type family ResolveSourceFuncsMethod (t :: Symbol) (o :: DK.Type) :: DK.Type where
    ResolveSourceFuncsMethod l o = O.MethodResolutionFailed l o

instance (info ~ ResolveSourceFuncsMethod t SourceFuncs, O.OverloadedMethod info SourceFuncs p) => OL.IsLabel t (SourceFuncs -> p) where
#if MIN_VERSION_base(4,10,0)
    fromLabel = O.overloadedMethod @info
#else
    fromLabel _ = O.overloadedMethod @info
#endif

#if MIN_VERSION_base(4,13,0)
instance (info ~ ResolveSourceFuncsMethod t SourceFuncs, O.OverloadedMethod info SourceFuncs p, R.HasField t SourceFuncs p) => R.HasField t SourceFuncs p where
    getField = O.overloadedMethod @info

#endif

instance (info ~ ResolveSourceFuncsMethod t SourceFuncs, O.OverloadedMethodInfo info SourceFuncs) => OL.IsLabel t (O.MethodProxy info SourceFuncs) where
#if MIN_VERSION_base(4,10,0)
    fromLabel = O.MethodProxy
#else
    fromLabel _ = O.MethodProxy
#endif

#endif


