{-# LANGUAGE TypeApplications #-}


-- | Copyright  : Will Thompson and Iñaki García Etxebarria
-- License    : LGPL-2.1
-- Maintainer : Iñaki García Etxebarria
-- 
-- A t'GI.GObject.Structs.ParamSpecPool.ParamSpecPool' maintains a collection of @/GParamSpecs/@ which can be
-- quickly accessed by owner and name.
-- 
-- The implementation of the t'GI.GObject.Objects.Object.Object' property system uses such a pool to
-- store the @/GParamSpecs/@ of the properties all object types.

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

module GI.GObject.Structs.ParamSpecPool
    ( 

-- * Exported types
    ParamSpecPool(..)                       ,


 -- * Methods
-- | 
-- 
--  === __Click to display all available methods, including inherited ones__
-- ==== Methods
-- [insert]("GI.GObject.Structs.ParamSpecPool#g:method:insert"), [listOwned]("GI.GObject.Structs.ParamSpecPool#g:method:listOwned"), [lookup]("GI.GObject.Structs.ParamSpecPool#g:method:lookup"), [remove]("GI.GObject.Structs.ParamSpecPool#g:method:remove").
-- 
-- ==== Getters
-- /None/.
-- 
-- ==== Setters
-- /None/.

#if defined(ENABLE_OVERLOADING)
    ResolveParamSpecPoolMethod              ,
#endif

-- ** insert #method:insert#

#if defined(ENABLE_OVERLOADING)
    ParamSpecPoolInsertMethodInfo           ,
#endif
    paramSpecPoolInsert                     ,


-- ** listOwned #method:listOwned#

#if defined(ENABLE_OVERLOADING)
    ParamSpecPoolListOwnedMethodInfo        ,
#endif
    paramSpecPoolListOwned                  ,


-- ** lookup #method:lookup#

#if defined(ENABLE_OVERLOADING)
    ParamSpecPoolLookupMethodInfo           ,
#endif
    paramSpecPoolLookup                     ,


-- ** remove #method:remove#

#if defined(ENABLE_OVERLOADING)
    ParamSpecPoolRemoveMethodInfo           ,
#endif
    paramSpecPoolRemove                     ,




    ) 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)

#else

#endif

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

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

-- XXX Wrapping a foreign struct/union with no known destructor or size, leak?
instance BoxedPtr ParamSpecPool where
    boxedPtrCopy = return
    boxedPtrFree = \_x -> return ()


#if defined(ENABLE_OVERLOADING)
instance O.HasAttributeList ParamSpecPool
type instance O.AttributeList ParamSpecPool = ParamSpecPoolAttributeList
type ParamSpecPoolAttributeList = ('[ ] :: [(Symbol, DK.Type)])
#endif

-- XXX Could not generate method ParamSpecPool::free
-- Bad introspection data: Transferring a non-boxed struct with unknown size!
-- method ParamSpecPool::insert
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "pool"
--           , argType =
--               TInterface Name { namespace = "GObject" , name = "ParamSpecPool" }
--           , argCType = Just "GParamSpecPool*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "a #GParamSpecPool." , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "pspec"
--           , argType = TParamSpec
--           , argCType = Just "GParamSpec*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "the #GParamSpec to insert"
--                 , sinceVersion = Nothing
--                 }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "owner_type"
--           , argType = TBasicType TGType
--           , argCType = Just "GType"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "a #GType identifying the owner of @pspec"
--                 , sinceVersion = Nothing
--                 }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       ]
-- Lengths: []
-- returnType: Nothing
-- throws : False
-- Skip return : False

foreign import ccall "g_param_spec_pool_insert" g_param_spec_pool_insert :: 
    Ptr ParamSpecPool ->                    -- pool : TInterface (Name {namespace = "GObject", name = "ParamSpecPool"})
    Ptr GParamSpec ->                       -- pspec : TParamSpec
    CGType ->                               -- owner_type : TBasicType TGType
    IO ()

-- | Inserts a t'GI.GObject.Objects.ParamSpec.ParamSpec' in the pool.
paramSpecPoolInsert ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    ParamSpecPool
    -- ^ /@pool@/: a t'GI.GObject.Structs.ParamSpecPool.ParamSpecPool'.
    -> GParamSpec
    -- ^ /@pspec@/: the t'GI.GObject.Objects.ParamSpec.ParamSpec' to insert
    -> GType
    -- ^ /@ownerType@/: a t'GType' identifying the owner of /@pspec@/
    -> m ()
paramSpecPoolInsert pool pspec ownerType = liftIO $ do
    pool' <- unsafeManagedPtrGetPtr pool
    pspec' <- unsafeManagedPtrGetPtr pspec
    let ownerType' = gtypeToCGType ownerType
    g_param_spec_pool_insert pool' pspec' ownerType'
    touchManagedPtr pool
    touchManagedPtr pspec
    return ()

#if defined(ENABLE_OVERLOADING)
data ParamSpecPoolInsertMethodInfo
instance (signature ~ (GParamSpec -> GType -> m ()), MonadIO m) => O.OverloadedMethod ParamSpecPoolInsertMethodInfo ParamSpecPool signature where
    overloadedMethod = paramSpecPoolInsert

instance O.OverloadedMethodInfo ParamSpecPoolInsertMethodInfo ParamSpecPool where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.GObject.Structs.ParamSpecPool.paramSpecPoolInsert",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-gobject-2.0.31/docs/GI-GObject-Structs-ParamSpecPool.html#v:paramSpecPoolInsert"
        })


#endif

-- XXX Could not generate method ParamSpecPool::list
-- Not implemented: unpackCArray : Don't know how to unpack C Array of type TParamSpec
-- method ParamSpecPool::list_owned
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "pool"
--           , argType =
--               TInterface Name { namespace = "GObject" , name = "ParamSpecPool" }
--           , argCType = Just "GParamSpecPool*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "a #GParamSpecPool" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "owner_type"
--           , argType = TBasicType TGType
--           , argCType = Just "GType"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "the owner to look for"
--                 , sinceVersion = Nothing
--                 }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       ]
-- Lengths: []
-- returnType: Just (TGList TParamSpec)
-- throws : False
-- Skip return : False

foreign import ccall "g_param_spec_pool_list_owned" g_param_spec_pool_list_owned :: 
    Ptr ParamSpecPool ->                    -- pool : TInterface (Name {namespace = "GObject", name = "ParamSpecPool"})
    CGType ->                               -- owner_type : TBasicType TGType
    IO (Ptr (GList (Ptr GParamSpec)))

-- | Gets an t'GI.GLib.Structs.List.List' of all @/GParamSpecs/@ owned by /@ownerType@/ in
-- the pool.
paramSpecPoolListOwned ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    ParamSpecPool
    -- ^ /@pool@/: a t'GI.GObject.Structs.ParamSpecPool.ParamSpecPool'
    -> GType
    -- ^ /@ownerType@/: the owner to look for
    -> m [GParamSpec]
    -- ^ __Returns:__ a
    --          t'GI.GLib.Structs.List.List' of all @/GParamSpecs/@ owned by /@ownerType@/ in
    --          the pool@/GParamSpecs/@.
paramSpecPoolListOwned pool ownerType = liftIO $ do
    pool' <- unsafeManagedPtrGetPtr pool
    let ownerType' = gtypeToCGType ownerType
    result <- g_param_spec_pool_list_owned pool' ownerType'
    result' <- unpackGList result
    result'' <- mapM B.GParamSpec.newGParamSpecFromPtr result'
    g_list_free result
    touchManagedPtr pool
    return result''

#if defined(ENABLE_OVERLOADING)
data ParamSpecPoolListOwnedMethodInfo
instance (signature ~ (GType -> m [GParamSpec]), MonadIO m) => O.OverloadedMethod ParamSpecPoolListOwnedMethodInfo ParamSpecPool signature where
    overloadedMethod = paramSpecPoolListOwned

instance O.OverloadedMethodInfo ParamSpecPoolListOwnedMethodInfo ParamSpecPool where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.GObject.Structs.ParamSpecPool.paramSpecPoolListOwned",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-gobject-2.0.31/docs/GI-GObject-Structs-ParamSpecPool.html#v:paramSpecPoolListOwned"
        })


#endif

-- method ParamSpecPool::lookup
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "pool"
--           , argType =
--               TInterface Name { namespace = "GObject" , name = "ParamSpecPool" }
--           , argCType = Just "GParamSpecPool*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "a #GParamSpecPool" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "param_name"
--           , argType = TBasicType TUTF8
--           , argCType = Just "const gchar*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "the name to look for"
--                 , sinceVersion = Nothing
--                 }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "owner_type"
--           , argType = TBasicType TGType
--           , argCType = Just "GType"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "the owner to look for"
--                 , sinceVersion = Nothing
--                 }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "walk_ancestors"
--           , argType = TBasicType TBoolean
--           , argCType = Just "gboolean"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText =
--                     Just
--                       "If %TRUE, also try to find a #GParamSpec with @param_name\n owned by an ancestor of @owner_type."
--                 , sinceVersion = Nothing
--                 }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       ]
-- Lengths: []
-- returnType: Just TParamSpec
-- throws : False
-- Skip return : False

foreign import ccall "g_param_spec_pool_lookup" g_param_spec_pool_lookup :: 
    Ptr ParamSpecPool ->                    -- pool : TInterface (Name {namespace = "GObject", name = "ParamSpecPool"})
    CString ->                              -- param_name : TBasicType TUTF8
    CGType ->                               -- owner_type : TBasicType TGType
    CInt ->                                 -- walk_ancestors : TBasicType TBoolean
    IO (Ptr GParamSpec)

-- | Looks up a t'GI.GObject.Objects.ParamSpec.ParamSpec' in the pool.
paramSpecPoolLookup ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    ParamSpecPool
    -- ^ /@pool@/: a t'GI.GObject.Structs.ParamSpecPool.ParamSpecPool'
    -> T.Text
    -- ^ /@paramName@/: the name to look for
    -> GType
    -- ^ /@ownerType@/: the owner to look for
    -> Bool
    -- ^ /@walkAncestors@/: If 'P.True', also try to find a t'GI.GObject.Objects.ParamSpec.ParamSpec' with /@paramName@/
    --  owned by an ancestor of /@ownerType@/.
    -> m (Maybe GParamSpec)
    -- ^ __Returns:__ The found t'GI.GObject.Objects.ParamSpec.ParamSpec', or 'P.Nothing' if no
    -- matching t'GI.GObject.Objects.ParamSpec.ParamSpec' was found.
paramSpecPoolLookup pool paramName ownerType walkAncestors = liftIO $ do
    pool' <- unsafeManagedPtrGetPtr pool
    paramName' <- textToCString paramName
    let ownerType' = gtypeToCGType ownerType
    let walkAncestors' = (P.fromIntegral . P.fromEnum) walkAncestors
    result <- g_param_spec_pool_lookup pool' paramName' ownerType' walkAncestors'
    maybeResult <- convertIfNonNull result $ \result' -> do
        result'' <- B.GParamSpec.newGParamSpecFromPtr result'
        return result''
    touchManagedPtr pool
    freeMem paramName'
    return maybeResult

#if defined(ENABLE_OVERLOADING)
data ParamSpecPoolLookupMethodInfo
instance (signature ~ (T.Text -> GType -> Bool -> m (Maybe GParamSpec)), MonadIO m) => O.OverloadedMethod ParamSpecPoolLookupMethodInfo ParamSpecPool signature where
    overloadedMethod = paramSpecPoolLookup

instance O.OverloadedMethodInfo ParamSpecPoolLookupMethodInfo ParamSpecPool where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.GObject.Structs.ParamSpecPool.paramSpecPoolLookup",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-gobject-2.0.31/docs/GI-GObject-Structs-ParamSpecPool.html#v:paramSpecPoolLookup"
        })


#endif

-- method ParamSpecPool::remove
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "pool"
--           , argType =
--               TInterface Name { namespace = "GObject" , name = "ParamSpecPool" }
--           , argCType = Just "GParamSpecPool*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "a #GParamSpecPool" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "pspec"
--           , argType = TParamSpec
--           , argCType = Just "GParamSpec*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "the #GParamSpec to remove"
--                 , sinceVersion = Nothing
--                 }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       ]
-- Lengths: []
-- returnType: Nothing
-- throws : False
-- Skip return : False

foreign import ccall "g_param_spec_pool_remove" g_param_spec_pool_remove :: 
    Ptr ParamSpecPool ->                    -- pool : TInterface (Name {namespace = "GObject", name = "ParamSpecPool"})
    Ptr GParamSpec ->                       -- pspec : TParamSpec
    IO ()

-- | Removes a t'GI.GObject.Objects.ParamSpec.ParamSpec' from the pool.
paramSpecPoolRemove ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    ParamSpecPool
    -- ^ /@pool@/: a t'GI.GObject.Structs.ParamSpecPool.ParamSpecPool'
    -> GParamSpec
    -- ^ /@pspec@/: the t'GI.GObject.Objects.ParamSpec.ParamSpec' to remove
    -> m ()
paramSpecPoolRemove pool pspec = liftIO $ do
    pool' <- unsafeManagedPtrGetPtr pool
    pspec' <- unsafeManagedPtrGetPtr pspec
    g_param_spec_pool_remove pool' pspec'
    touchManagedPtr pool
    touchManagedPtr pspec
    return ()

#if defined(ENABLE_OVERLOADING)
data ParamSpecPoolRemoveMethodInfo
instance (signature ~ (GParamSpec -> m ()), MonadIO m) => O.OverloadedMethod ParamSpecPoolRemoveMethodInfo ParamSpecPool signature where
    overloadedMethod = paramSpecPoolRemove

instance O.OverloadedMethodInfo ParamSpecPoolRemoveMethodInfo ParamSpecPool where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.GObject.Structs.ParamSpecPool.paramSpecPoolRemove",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-gobject-2.0.31/docs/GI-GObject-Structs-ParamSpecPool.html#v:paramSpecPoolRemove"
        })


#endif

#if defined(ENABLE_OVERLOADING)
type family ResolveParamSpecPoolMethod (t :: Symbol) (o :: DK.Type) :: DK.Type where
    ResolveParamSpecPoolMethod "insert" o = ParamSpecPoolInsertMethodInfo
    ResolveParamSpecPoolMethod "listOwned" o = ParamSpecPoolListOwnedMethodInfo
    ResolveParamSpecPoolMethod "lookup" o = ParamSpecPoolLookupMethodInfo
    ResolveParamSpecPoolMethod "remove" o = ParamSpecPoolRemoveMethodInfo
    ResolveParamSpecPoolMethod l o = O.MethodResolutionFailed l o

instance (info ~ ResolveParamSpecPoolMethod t ParamSpecPool, O.OverloadedMethod info ParamSpecPool p) => OL.IsLabel t (ParamSpecPool -> 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 ~ ResolveParamSpecPoolMethod t ParamSpecPool, O.OverloadedMethod info ParamSpecPool p, R.HasField t ParamSpecPool p) => R.HasField t ParamSpecPool p where
    getField = O.overloadedMethod @info

#endif

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

#endif


