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

    Contains the public fields of a pointer array.
    -}

    #define ENABLE_OVERLOADING \
           (!defined(__HADDOCK_VERSION__))

    module GI.GLib.Structs.PtrArray
        (

    -- * Exported types
        PtrArray(..)                            ,
        newZeroPtrArray                         ,
        noPtrArray                              ,

     -- * Properties
    -- ** len #attr:len#
    {- | number of pointers in the array
    -}
        getPtrArrayLen                          ,
    #if ENABLE_OVERLOADING
        ptrArray_len                            ,
    #endif
        setPtrArrayLen                          ,

    -- ** pdata #attr:pdata#
    {- | points to the array of pointers, which may be moved when the
        array grows
    -}
        clearPtrArrayPdata                      ,
        getPtrArrayPdata                        ,
    #if ENABLE_OVERLOADING
        ptrArray_pdata                          ,
    #endif
        setPtrArrayPdata                        ,

        ) 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.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.Text as T
    import qualified Data.ByteString.Char8 as B
    import qualified Data.Map as Map
    import qualified Foreign.Ptr as FP

    -- | Memory-managed wrapper type.
    newtype PtrArray = PtrArray (ManagedPtr PtrArray)
    foreign import ccall "g_ptr_array_get_type" c_g_ptr_array_get_type ::
        IO GType

    instance BoxedObject PtrArray where
        boxedType _ = c_g_ptr_array_get_type

    -- | Construct a `PtrArray` struct initialized to zero.
    newZeroPtrArray :: MonadIO m => m PtrArray
    newZeroPtrArray = liftIO $ callocBoxedBytes 16 >>= wrapBoxed PtrArray

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

    -- | A convenience alias for `Nothing` :: `Maybe` `PtrArray`.
    noPtrArray :: Maybe PtrArray
    noPtrArray = Nothing

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

    @
    'Data.GI.Base.Attributes.get' ptrArray #pdata
    @
    -}
    getPtrArrayPdata :: MonadIO m => PtrArray -> m (Ptr ())
    getPtrArrayPdata s = liftIO $ withManagedPtr s $ \ptr -> do
        val <- peek (ptr `plusPtr` 0) :: IO (Ptr ())
        return val

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

    @
    'Data.GI.Base.Attributes.set' ptrArray [ #pdata 'Data.GI.Base.Attributes.:=' value ]
    @
    -}
    setPtrArrayPdata :: MonadIO m => PtrArray -> Ptr () -> m ()
    setPtrArrayPdata s val = liftIO $ withManagedPtr s $ \ptr -> do
        poke (ptr `plusPtr` 0) (val :: Ptr ())

    {- |
    Set the value of the “@pdata@” 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' #pdata
    @
    -}
    clearPtrArrayPdata :: MonadIO m => PtrArray -> m ()
    clearPtrArrayPdata s = liftIO $ withManagedPtr s $ \ptr -> do
        poke (ptr `plusPtr` 0) (FP.nullPtr :: Ptr ())

    #if ENABLE_OVERLOADING
    data PtrArrayPdataFieldInfo
    instance AttrInfo PtrArrayPdataFieldInfo where
        type AttrAllowedOps PtrArrayPdataFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
        type AttrSetTypeConstraint PtrArrayPdataFieldInfo = (~) (Ptr ())
        type AttrBaseTypeConstraint PtrArrayPdataFieldInfo = (~) PtrArray
        type AttrGetType PtrArrayPdataFieldInfo = Ptr ()
        type AttrLabel PtrArrayPdataFieldInfo = "pdata"
        type AttrOrigin PtrArrayPdataFieldInfo = PtrArray
        attrGet _ = getPtrArrayPdata
        attrSet _ = setPtrArrayPdata
        attrConstruct = undefined
        attrClear _ = clearPtrArrayPdata

    ptrArray_pdata :: AttrLabelProxy "pdata"
    ptrArray_pdata = AttrLabelProxy

    #endif

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

    @
    'Data.GI.Base.Attributes.get' ptrArray #len
    @
    -}
    getPtrArrayLen :: MonadIO m => PtrArray -> m Word32
    getPtrArrayLen s = liftIO $ withManagedPtr s $ \ptr -> do
        val <- peek (ptr `plusPtr` 8) :: IO Word32
        return val

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

    @
    'Data.GI.Base.Attributes.set' ptrArray [ #len 'Data.GI.Base.Attributes.:=' value ]
    @
    -}
    setPtrArrayLen :: MonadIO m => PtrArray -> Word32 -> m ()
    setPtrArrayLen s val = liftIO $ withManagedPtr s $ \ptr -> do
        poke (ptr `plusPtr` 8) (val :: Word32)

    #if ENABLE_OVERLOADING
    data PtrArrayLenFieldInfo
    instance AttrInfo PtrArrayLenFieldInfo where
        type AttrAllowedOps PtrArrayLenFieldInfo = '[ 'AttrSet, 'AttrGet]
        type AttrSetTypeConstraint PtrArrayLenFieldInfo = (~) Word32
        type AttrBaseTypeConstraint PtrArrayLenFieldInfo = (~) PtrArray
        type AttrGetType PtrArrayLenFieldInfo = Word32
        type AttrLabel PtrArrayLenFieldInfo = "len"
        type AttrOrigin PtrArrayLenFieldInfo = PtrArray
        attrGet _ = getPtrArrayLen
        attrSet _ = setPtrArrayLen
        attrConstruct = undefined
        attrClear _ = undefined

    ptrArray_len :: AttrLabelProxy "len"
    ptrArray_len = AttrLabelProxy

    #endif

    #if ENABLE_OVERLOADING
    instance O.HasAttributeList PtrArray
    type instance O.AttributeList PtrArray = PtrArrayAttributeList
    type PtrArrayAttributeList = ('[ '("pdata", PtrArrayPdataFieldInfo), '("len", PtrArrayLenFieldInfo)] :: [(Symbol, *)])
    #endif

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

    instance (info ~ ResolvePtrArrayMethod t PtrArray, O.MethodInfo info PtrArray p) => O.IsLabelProxy t (PtrArray -> p) where
        fromLabelProxy _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)

    #if MIN_VERSION_base(4,9,0)
    instance (info ~ ResolvePtrArrayMethod t PtrArray, O.MethodInfo info PtrArray p) => O.IsLabel t (PtrArray -> 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

    #endif