{-# LANGUAGE TypeApplications #-}


-- | Copyright  : Will Thompson and Iñaki García Etxebarria
-- License    : LGPL-2.1
-- Maintainer : Iñaki García Etxebarria
-- 
-- An object used to store the GType of the
-- factories used to create an accessible object for an object of a
-- particular GType.
-- 
-- The AtkRegistry is normally used to create appropriate ATK \"peers\"
-- for user interface components.  Application developers usually need
-- only interact with the AtkRegistry by associating appropriate ATK
-- implementation classes with GObject classes via the
-- atk_registry_set_factory_type call, passing the appropriate GType
-- for application custom widget classes.

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

module GI.Atk.Objects.Registry
    ( 

-- * Exported types
    Registry(..)                            ,
    IsRegistry                              ,
    toRegistry                              ,


 -- * Methods
-- | 
-- 
--  === __Click to display all available methods, including inherited ones__
-- ==== Methods
-- [bindProperty]("GI.GObject.Objects.Object#g:method:bindProperty"), [bindPropertyFull]("GI.GObject.Objects.Object#g:method:bindPropertyFull"), [forceFloating]("GI.GObject.Objects.Object#g:method:forceFloating"), [freezeNotify]("GI.GObject.Objects.Object#g:method:freezeNotify"), [getv]("GI.GObject.Objects.Object#g:method:getv"), [isFloating]("GI.GObject.Objects.Object#g:method:isFloating"), [notify]("GI.GObject.Objects.Object#g:method:notify"), [notifyByPspec]("GI.GObject.Objects.Object#g:method:notifyByPspec"), [ref]("GI.GObject.Objects.Object#g:method:ref"), [refSink]("GI.GObject.Objects.Object#g:method:refSink"), [runDispose]("GI.GObject.Objects.Object#g:method:runDispose"), [stealData]("GI.GObject.Objects.Object#g:method:stealData"), [stealQdata]("GI.GObject.Objects.Object#g:method:stealQdata"), [thawNotify]("GI.GObject.Objects.Object#g:method:thawNotify"), [unref]("GI.GObject.Objects.Object#g:method:unref"), [watchClosure]("GI.GObject.Objects.Object#g:method:watchClosure").
-- 
-- ==== Getters
-- [getData]("GI.GObject.Objects.Object#g:method:getData"), [getFactory]("GI.Atk.Objects.Registry#g:method:getFactory"), [getFactoryType]("GI.Atk.Objects.Registry#g:method:getFactoryType"), [getProperty]("GI.GObject.Objects.Object#g:method:getProperty"), [getQdata]("GI.GObject.Objects.Object#g:method:getQdata").
-- 
-- ==== Setters
-- [setData]("GI.GObject.Objects.Object#g:method:setData"), [setDataFull]("GI.GObject.Objects.Object#g:method:setDataFull"), [setFactoryType]("GI.Atk.Objects.Registry#g:method:setFactoryType"), [setProperty]("GI.GObject.Objects.Object#g:method:setProperty").

#if defined(ENABLE_OVERLOADING)
    ResolveRegistryMethod                   ,
#endif

-- ** getFactory #method:getFactory#

#if defined(ENABLE_OVERLOADING)
    RegistryGetFactoryMethodInfo            ,
#endif
    registryGetFactory                      ,


-- ** getFactoryType #method:getFactoryType#

#if defined(ENABLE_OVERLOADING)
    RegistryGetFactoryTypeMethodInfo        ,
#endif
    registryGetFactoryType                  ,


-- ** setFactoryType #method:setFactoryType#

#if defined(ENABLE_OVERLOADING)
    RegistrySetFactoryTypeMethodInfo        ,
#endif
    registrySetFactoryType                  ,




    ) 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 {-# SOURCE #-} qualified GI.Atk.Enums as Atk.Enums
import {-# SOURCE #-} qualified GI.Atk.Objects.Object as Atk.Object
import {-# SOURCE #-} qualified GI.Atk.Objects.ObjectFactory as Atk.ObjectFactory
import {-# SOURCE #-} qualified GI.Atk.Objects.Relation as Atk.Relation
import {-# SOURCE #-} qualified GI.Atk.Objects.RelationSet as Atk.RelationSet
import {-# SOURCE #-} qualified GI.Atk.Objects.StateSet as Atk.StateSet
import {-# SOURCE #-} qualified GI.Atk.Structs.PropertyValues as Atk.PropertyValues
import qualified GI.GObject.Objects.Object as GObject.Object
import qualified GI.GObject.Structs.ValueArray as GObject.ValueArray

#else
import {-# SOURCE #-} qualified GI.Atk.Objects.ObjectFactory as Atk.ObjectFactory
import qualified GI.GObject.Objects.Object as GObject.Object

#endif

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

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

foreign import ccall "atk_registry_get_type"
    c_atk_registry_get_type :: IO B.Types.GType

instance B.Types.TypedObject Registry where
    glibType = c_atk_registry_get_type

instance B.Types.GObject Registry

-- | Type class for types which can be safely cast to t'Registry', for instance with `toRegistry`.
class (SP.GObject o, O.IsDescendantOf Registry o) => IsRegistry o
instance (SP.GObject o, O.IsDescendantOf Registry o) => IsRegistry o

instance O.HasParentTypes Registry
type instance O.ParentTypes Registry = '[GObject.Object.Object]

-- | Cast to t'Registry', for types for which this is known to be safe. For general casts, use 'Data.GI.Base.ManagedPtr.castTo'.
toRegistry :: (MIO.MonadIO m, IsRegistry o) => o -> m Registry
toRegistry = MIO.liftIO . B.ManagedPtr.unsafeCastTo Registry

-- | Convert t'Registry' to and from t'Data.GI.Base.GValue.GValue'. See 'Data.GI.Base.GValue.toGValue' and 'Data.GI.Base.GValue.fromGValue'.
instance B.GValue.IsGValue (Maybe Registry) where
    gvalueGType_ = c_atk_registry_get_type
    gvalueSet_ gv P.Nothing = B.GValue.set_object gv (FP.nullPtr :: FP.Ptr Registry)
    gvalueSet_ gv (P.Just obj) = B.ManagedPtr.withManagedPtr obj (B.GValue.set_object gv)
    gvalueGet_ gv = do
        ptr <- B.GValue.get_object gv :: IO (FP.Ptr Registry)
        if ptr /= FP.nullPtr
        then P.Just <$> B.ManagedPtr.newObject Registry ptr
        else return P.Nothing
        
    

#if defined(ENABLE_OVERLOADING)
type family ResolveRegistryMethod (t :: Symbol) (o :: DK.Type) :: DK.Type where
    ResolveRegistryMethod "bindProperty" o = GObject.Object.ObjectBindPropertyMethodInfo
    ResolveRegistryMethod "bindPropertyFull" o = GObject.Object.ObjectBindPropertyFullMethodInfo
    ResolveRegistryMethod "forceFloating" o = GObject.Object.ObjectForceFloatingMethodInfo
    ResolveRegistryMethod "freezeNotify" o = GObject.Object.ObjectFreezeNotifyMethodInfo
    ResolveRegistryMethod "getv" o = GObject.Object.ObjectGetvMethodInfo
    ResolveRegistryMethod "isFloating" o = GObject.Object.ObjectIsFloatingMethodInfo
    ResolveRegistryMethod "notify" o = GObject.Object.ObjectNotifyMethodInfo
    ResolveRegistryMethod "notifyByPspec" o = GObject.Object.ObjectNotifyByPspecMethodInfo
    ResolveRegistryMethod "ref" o = GObject.Object.ObjectRefMethodInfo
    ResolveRegistryMethod "refSink" o = GObject.Object.ObjectRefSinkMethodInfo
    ResolveRegistryMethod "runDispose" o = GObject.Object.ObjectRunDisposeMethodInfo
    ResolveRegistryMethod "stealData" o = GObject.Object.ObjectStealDataMethodInfo
    ResolveRegistryMethod "stealQdata" o = GObject.Object.ObjectStealQdataMethodInfo
    ResolveRegistryMethod "thawNotify" o = GObject.Object.ObjectThawNotifyMethodInfo
    ResolveRegistryMethod "unref" o = GObject.Object.ObjectUnrefMethodInfo
    ResolveRegistryMethod "watchClosure" o = GObject.Object.ObjectWatchClosureMethodInfo
    ResolveRegistryMethod "getData" o = GObject.Object.ObjectGetDataMethodInfo
    ResolveRegistryMethod "getFactory" o = RegistryGetFactoryMethodInfo
    ResolveRegistryMethod "getFactoryType" o = RegistryGetFactoryTypeMethodInfo
    ResolveRegistryMethod "getProperty" o = GObject.Object.ObjectGetPropertyMethodInfo
    ResolveRegistryMethod "getQdata" o = GObject.Object.ObjectGetQdataMethodInfo
    ResolveRegistryMethod "setData" o = GObject.Object.ObjectSetDataMethodInfo
    ResolveRegistryMethod "setDataFull" o = GObject.Object.ObjectSetDataFullMethodInfo
    ResolveRegistryMethod "setFactoryType" o = RegistrySetFactoryTypeMethodInfo
    ResolveRegistryMethod "setProperty" o = GObject.Object.ObjectSetPropertyMethodInfo
    ResolveRegistryMethod l o = O.MethodResolutionFailed l o

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

#endif

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

#endif

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

#if defined(ENABLE_OVERLOADING)
#endif

#if defined(ENABLE_OVERLOADING)
type instance O.SignalList Registry = RegistrySignalList
type RegistrySignalList = ('[ '("notify", GObject.Object.ObjectNotifySignalInfo)] :: [(Symbol, DK.Type)])

#endif

-- method Registry::get_factory
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "registry"
--           , argType =
--               TInterface Name { namespace = "Atk" , name = "Registry" }
--           , argCType = Just "AtkRegistry*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "an #AtkRegistry" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "type"
--           , argType = TBasicType TGType
--           , argCType = Just "GType"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText =
--                     Just
--                       "a #GType with which to look up the associated #AtkObjectFactory"
--                 , sinceVersion = Nothing
--                 }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       ]
-- Lengths: []
-- returnType: Just
--               (TInterface Name { namespace = "Atk" , name = "ObjectFactory" })
-- throws : False
-- Skip return : False

foreign import ccall "atk_registry_get_factory" atk_registry_get_factory :: 
    Ptr Registry ->                         -- registry : TInterface (Name {namespace = "Atk", name = "Registry"})
    CGType ->                               -- type : TBasicType TGType
    IO (Ptr Atk.ObjectFactory.ObjectFactory)

-- | Gets an t'GI.Atk.Objects.ObjectFactory.ObjectFactory' appropriate for creating @/AtkObjects/@
-- appropriate for /@type@/.
registryGetFactory ::
    (B.CallStack.HasCallStack, MonadIO m, IsRegistry a) =>
    a
    -- ^ /@registry@/: an t'GI.Atk.Objects.Registry.Registry'
    -> GType
    -- ^ /@type@/: a t'GType' with which to look up the associated t'GI.Atk.Objects.ObjectFactory.ObjectFactory'
    -> m Atk.ObjectFactory.ObjectFactory
    -- ^ __Returns:__ an t'GI.Atk.Objects.ObjectFactory.ObjectFactory' appropriate for creating
    -- @/AtkObjects/@ appropriate for /@type@/.
registryGetFactory registry type_ = liftIO $ do
    registry' <- unsafeManagedPtrCastPtr registry
    let type_' = gtypeToCGType type_
    result <- atk_registry_get_factory registry' type_'
    checkUnexpectedReturnNULL "registryGetFactory" result
    result' <- (newObject Atk.ObjectFactory.ObjectFactory) result
    touchManagedPtr registry
    return result'

#if defined(ENABLE_OVERLOADING)
data RegistryGetFactoryMethodInfo
instance (signature ~ (GType -> m Atk.ObjectFactory.ObjectFactory), MonadIO m, IsRegistry a) => O.OverloadedMethod RegistryGetFactoryMethodInfo a signature where
    overloadedMethod = registryGetFactory

instance O.OverloadedMethodInfo RegistryGetFactoryMethodInfo a where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.Atk.Objects.Registry.registryGetFactory",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-atk-2.0.28/docs/GI-Atk-Objects-Registry.html#v:registryGetFactory"
        })


#endif

-- method Registry::get_factory_type
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "registry"
--           , argType =
--               TInterface Name { namespace = "Atk" , name = "Registry" }
--           , argCType = Just "AtkRegistry*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "an #AtkRegistry" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "type"
--           , argType = TBasicType TGType
--           , argCType = Just "GType"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText =
--                     Just
--                       "a #GType with which to look up the associated #AtkObjectFactory\nsubclass"
--                 , sinceVersion = Nothing
--                 }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       ]
-- Lengths: []
-- returnType: Just (TBasicType TGType)
-- throws : False
-- Skip return : False

foreign import ccall "atk_registry_get_factory_type" atk_registry_get_factory_type :: 
    Ptr Registry ->                         -- registry : TInterface (Name {namespace = "Atk", name = "Registry"})
    CGType ->                               -- type : TBasicType TGType
    IO CGType

-- | Provides a t'GType' indicating the t'GI.Atk.Objects.ObjectFactory.ObjectFactory' subclass
-- associated with /@type@/.
registryGetFactoryType ::
    (B.CallStack.HasCallStack, MonadIO m, IsRegistry a) =>
    a
    -- ^ /@registry@/: an t'GI.Atk.Objects.Registry.Registry'
    -> GType
    -- ^ /@type@/: a t'GType' with which to look up the associated t'GI.Atk.Objects.ObjectFactory.ObjectFactory'
    -- subclass
    -> m GType
    -- ^ __Returns:__ a t'GType' associated with type /@type@/
registryGetFactoryType registry type_ = liftIO $ do
    registry' <- unsafeManagedPtrCastPtr registry
    let type_' = gtypeToCGType type_
    result <- atk_registry_get_factory_type registry' type_'
    let result' = GType result
    touchManagedPtr registry
    return result'

#if defined(ENABLE_OVERLOADING)
data RegistryGetFactoryTypeMethodInfo
instance (signature ~ (GType -> m GType), MonadIO m, IsRegistry a) => O.OverloadedMethod RegistryGetFactoryTypeMethodInfo a signature where
    overloadedMethod = registryGetFactoryType

instance O.OverloadedMethodInfo RegistryGetFactoryTypeMethodInfo a where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.Atk.Objects.Registry.registryGetFactoryType",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-atk-2.0.28/docs/GI-Atk-Objects-Registry.html#v:registryGetFactoryType"
        })


#endif

-- method Registry::set_factory_type
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "registry"
--           , argType =
--               TInterface Name { namespace = "Atk" , name = "Registry" }
--           , argCType = Just "AtkRegistry*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText =
--                     Just "the #AtkRegistry in which to register the type association"
--                 , sinceVersion = Nothing
--                 }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "type"
--           , argType = TBasicType TGType
--           , argCType = Just "GType"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "an #AtkObject type" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "factory_type"
--           , argType = TBasicType TGType
--           , argCType = Just "GType"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText =
--                     Just
--                       "an #AtkObjectFactory type to associate with @type.  Must\nimplement AtkObject appropriate for @type."
--                 , 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 "atk_registry_set_factory_type" atk_registry_set_factory_type :: 
    Ptr Registry ->                         -- registry : TInterface (Name {namespace = "Atk", name = "Registry"})
    CGType ->                               -- type : TBasicType TGType
    CGType ->                               -- factory_type : TBasicType TGType
    IO ()

-- | Associate an t'GI.Atk.Objects.ObjectFactory.ObjectFactory' subclass with a t'GType'. Note:
-- The associated /@factoryType@/ will thereafter be responsible for
-- the creation of new t'GI.Atk.Objects.Object.Object' implementations for instances
-- appropriate for /@type@/.
registrySetFactoryType ::
    (B.CallStack.HasCallStack, MonadIO m, IsRegistry a) =>
    a
    -- ^ /@registry@/: the t'GI.Atk.Objects.Registry.Registry' in which to register the type association
    -> GType
    -- ^ /@type@/: an t'GI.Atk.Objects.Object.Object' type
    -> GType
    -- ^ /@factoryType@/: an t'GI.Atk.Objects.ObjectFactory.ObjectFactory' type to associate with /@type@/.  Must
    -- implement AtkObject appropriate for /@type@/.
    -> m ()
registrySetFactoryType registry type_ factoryType = liftIO $ do
    registry' <- unsafeManagedPtrCastPtr registry
    let type_' = gtypeToCGType type_
    let factoryType' = gtypeToCGType factoryType
    atk_registry_set_factory_type registry' type_' factoryType'
    touchManagedPtr registry
    return ()

#if defined(ENABLE_OVERLOADING)
data RegistrySetFactoryTypeMethodInfo
instance (signature ~ (GType -> GType -> m ()), MonadIO m, IsRegistry a) => O.OverloadedMethod RegistrySetFactoryTypeMethodInfo a signature where
    overloadedMethod = registrySetFactoryType

instance O.OverloadedMethodInfo RegistrySetFactoryTypeMethodInfo a where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.Atk.Objects.Registry.registrySetFactoryType",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-atk-2.0.28/docs/GI-Atk-Objects-Registry.html#v:registrySetFactoryType"
        })


#endif


