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

    Together with 'GI.Atk.Objects.Plug.Plug', 'GI.Atk.Objects.Socket.Socket' provides the ability to embed
    accessibles from one process into another in a fashion that is
    transparent to assistive technologies. 'GI.Atk.Objects.Socket.Socket' works as the
    container of 'GI.Atk.Objects.Plug.Plug', embedding it using the method
    'GI.Atk.Objects.Socket.socketEmbed'. Any accessible contained in the 'GI.Atk.Objects.Plug.Plug' will
    appear to the assistive technologies as being inside the
    application that created the 'GI.Atk.Objects.Socket.Socket'.

    The communication between a 'GI.Atk.Objects.Socket.Socket' and a 'GI.Atk.Objects.Plug.Plug' is done by
    the IPC layer of the accessibility framework, normally implemented
    by the D-Bus based implementation of AT-SPI (at-spi2). If that is
    the case, at-spi-atk2 is the responsible to implement the abstract
    methods 'GI.Atk.Objects.Plug.plugGetId' and 'GI.Atk.Objects.Socket.socketEmbed', so an ATK
    implementor shouldn\'t reimplement them. The process that contains
    the 'GI.Atk.Objects.Plug.Plug' is responsible to send the ID returned by
    @/atk_plug_id()/@ to the process that contains the 'GI.Atk.Objects.Socket.Socket', so it
    could call the method 'GI.Atk.Objects.Socket.socketEmbed' in order to embed it.

    For the same reasons, an implementor doesn\'t need to implement
    'GI.Atk.Objects.Object.objectGetNAccessibleChildren' and
    'GI.Atk.Objects.Object.objectRefAccessibleChild'. All the logic related to those
    functions will be implemented by the IPC layer.
    -}

    #define ENABLE_OVERLOADING \
           (!defined(__HADDOCK_VERSION__))

    module GI.Atk.Objects.Socket
        (

    -- * Exported types
        Socket(..)                              ,
        IsSocket                                ,
        toSocket                                ,
        noSocket                                ,

     -- * Methods
    -- ** embed #method:embed#

    #if ENABLE_OVERLOADING
        SocketEmbedMethodInfo                   ,
    #endif
        socketEmbed                             ,

    -- ** isOccupied #method:isOccupied#

    #if ENABLE_OVERLOADING
        SocketIsOccupiedMethodInfo              ,
    #endif
        socketIsOccupied                        ,

    -- ** new #method:new#

        socketNew                               ,

        ) 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

    import {-# SOURCE #-} qualified GI.Atk.Interfaces.Component as Atk.Component
    import {-# SOURCE #-} qualified GI.Atk.Objects.Object as Atk.Object
    import qualified GI.GObject.Objects.Object as GObject.Object

    -- | Memory-managed wrapper type.
    newtype Socket = Socket (ManagedPtr Socket)
    foreign import ccall "atk_socket_get_type"
        c_atk_socket_get_type :: IO GType

    instance GObject Socket where
        gobjectType _ = c_atk_socket_get_type

    -- | Type class for types which can be safely cast to `Socket`, for instance with `toSocket`.
    class GObject o => IsSocket o
    #if MIN_VERSION_base(4,9,0)
    instance {-# OVERLAPPABLE #-} (GObject a, O.UnknownAncestorError Socket a) =>
        IsSocket a
    #endif
    instance IsSocket Socket
    instance Atk.Object.IsObject Socket
    instance GObject.Object.IsObject Socket
    instance Atk.Component.IsComponent Socket

    -- | Cast to `Socket`, for types for which this is known to be safe. For general casts, use `Data.GI.Base.ManagedPtr.castTo`.
    toSocket :: (MonadIO m, IsSocket o) => o -> m Socket
    toSocket = liftIO . unsafeCastTo Socket

    -- | A convenience alias for `Nothing` :: `Maybe` `Socket`.
    noSocket :: Maybe Socket
    noSocket = Nothing

    #if ENABLE_OVERLOADING
    type family ResolveSocketMethod (t :: Symbol) (o :: *) :: * where
        ResolveSocketMethod "addRelationship" o = Atk.Object.ObjectAddRelationshipMethodInfo
        ResolveSocketMethod "bindProperty" o = GObject.Object.ObjectBindPropertyMethodInfo
        ResolveSocketMethod "bindPropertyFull" o = GObject.Object.ObjectBindPropertyFullMethodInfo
        ResolveSocketMethod "contains" o = Atk.Component.ComponentContainsMethodInfo
        ResolveSocketMethod "embed" o = SocketEmbedMethodInfo
        ResolveSocketMethod "forceFloating" o = GObject.Object.ObjectForceFloatingMethodInfo
        ResolveSocketMethod "freezeNotify" o = GObject.Object.ObjectFreezeNotifyMethodInfo
        ResolveSocketMethod "getv" o = GObject.Object.ObjectGetvMethodInfo
        ResolveSocketMethod "grabFocus" o = Atk.Component.ComponentGrabFocusMethodInfo
        ResolveSocketMethod "initialize" o = Atk.Object.ObjectInitializeMethodInfo
        ResolveSocketMethod "isFloating" o = GObject.Object.ObjectIsFloatingMethodInfo
        ResolveSocketMethod "isOccupied" o = SocketIsOccupiedMethodInfo
        ResolveSocketMethod "notify" o = GObject.Object.ObjectNotifyMethodInfo
        ResolveSocketMethod "notifyByPspec" o = GObject.Object.ObjectNotifyByPspecMethodInfo
        ResolveSocketMethod "notifyStateChange" o = Atk.Object.ObjectNotifyStateChangeMethodInfo
        ResolveSocketMethod "peekParent" o = Atk.Object.ObjectPeekParentMethodInfo
        ResolveSocketMethod "ref" o = GObject.Object.ObjectRefMethodInfo
        ResolveSocketMethod "refAccessibleAtPoint" o = Atk.Component.ComponentRefAccessibleAtPointMethodInfo
        ResolveSocketMethod "refAccessibleChild" o = Atk.Object.ObjectRefAccessibleChildMethodInfo
        ResolveSocketMethod "refRelationSet" o = Atk.Object.ObjectRefRelationSetMethodInfo
        ResolveSocketMethod "refSink" o = GObject.Object.ObjectRefSinkMethodInfo
        ResolveSocketMethod "refStateSet" o = Atk.Object.ObjectRefStateSetMethodInfo
        ResolveSocketMethod "removeFocusHandler" o = Atk.Component.ComponentRemoveFocusHandlerMethodInfo
        ResolveSocketMethod "removePropertyChangeHandler" o = Atk.Object.ObjectRemovePropertyChangeHandlerMethodInfo
        ResolveSocketMethod "removeRelationship" o = Atk.Object.ObjectRemoveRelationshipMethodInfo
        ResolveSocketMethod "runDispose" o = GObject.Object.ObjectRunDisposeMethodInfo
        ResolveSocketMethod "scrollTo" o = Atk.Component.ComponentScrollToMethodInfo
        ResolveSocketMethod "scrollToPoint" o = Atk.Component.ComponentScrollToPointMethodInfo
        ResolveSocketMethod "stealData" o = GObject.Object.ObjectStealDataMethodInfo
        ResolveSocketMethod "stealQdata" o = GObject.Object.ObjectStealQdataMethodInfo
        ResolveSocketMethod "thawNotify" o = GObject.Object.ObjectThawNotifyMethodInfo
        ResolveSocketMethod "unref" o = GObject.Object.ObjectUnrefMethodInfo
        ResolveSocketMethod "watchClosure" o = GObject.Object.ObjectWatchClosureMethodInfo
        ResolveSocketMethod "getAccessibleId" o = Atk.Object.ObjectGetAccessibleIdMethodInfo
        ResolveSocketMethod "getAlpha" o = Atk.Component.ComponentGetAlphaMethodInfo
        ResolveSocketMethod "getAttributes" o = Atk.Object.ObjectGetAttributesMethodInfo
        ResolveSocketMethod "getData" o = GObject.Object.ObjectGetDataMethodInfo
        ResolveSocketMethod "getDescription" o = Atk.Object.ObjectGetDescriptionMethodInfo
        ResolveSocketMethod "getExtents" o = Atk.Component.ComponentGetExtentsMethodInfo
        ResolveSocketMethod "getIndexInParent" o = Atk.Object.ObjectGetIndexInParentMethodInfo
        ResolveSocketMethod "getLayer" o = Atk.Object.ObjectGetLayerMethodInfo
        ResolveSocketMethod "getMdiZorder" o = Atk.Object.ObjectGetMdiZorderMethodInfo
        ResolveSocketMethod "getNAccessibleChildren" o = Atk.Object.ObjectGetNAccessibleChildrenMethodInfo
        ResolveSocketMethod "getName" o = Atk.Object.ObjectGetNameMethodInfo
        ResolveSocketMethod "getObjectLocale" o = Atk.Object.ObjectGetObjectLocaleMethodInfo
        ResolveSocketMethod "getParent" o = Atk.Object.ObjectGetParentMethodInfo
        ResolveSocketMethod "getPosition" o = Atk.Component.ComponentGetPositionMethodInfo
        ResolveSocketMethod "getProperty" o = GObject.Object.ObjectGetPropertyMethodInfo
        ResolveSocketMethod "getQdata" o = GObject.Object.ObjectGetQdataMethodInfo
        ResolveSocketMethod "getRole" o = Atk.Object.ObjectGetRoleMethodInfo
        ResolveSocketMethod "getSize" o = Atk.Component.ComponentGetSizeMethodInfo
        ResolveSocketMethod "setAccessibleId" o = Atk.Object.ObjectSetAccessibleIdMethodInfo
        ResolveSocketMethod "setData" o = GObject.Object.ObjectSetDataMethodInfo
        ResolveSocketMethod "setDescription" o = Atk.Object.ObjectSetDescriptionMethodInfo
        ResolveSocketMethod "setExtents" o = Atk.Component.ComponentSetExtentsMethodInfo
        ResolveSocketMethod "setName" o = Atk.Object.ObjectSetNameMethodInfo
        ResolveSocketMethod "setParent" o = Atk.Object.ObjectSetParentMethodInfo
        ResolveSocketMethod "setPosition" o = Atk.Component.ComponentSetPositionMethodInfo
        ResolveSocketMethod "setProperty" o = GObject.Object.ObjectSetPropertyMethodInfo
        ResolveSocketMethod "setRole" o = Atk.Object.ObjectSetRoleMethodInfo
        ResolveSocketMethod "setSize" o = Atk.Component.ComponentSetSizeMethodInfo
        ResolveSocketMethod l o = O.MethodResolutionFailed l o

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

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

    #if ENABLE_OVERLOADING
    instance O.HasAttributeList Socket
    type instance O.AttributeList Socket = SocketAttributeList
    type SocketAttributeList = ('[ '("accessibleComponentLayer", Atk.Object.ObjectAccessibleComponentLayerPropertyInfo), '("accessibleComponentMdiZorder", Atk.Object.ObjectAccessibleComponentMdiZorderPropertyInfo), '("accessibleDescription", Atk.Object.ObjectAccessibleDescriptionPropertyInfo), '("accessibleHypertextNlinks", Atk.Object.ObjectAccessibleHypertextNlinksPropertyInfo), '("accessibleName", Atk.Object.ObjectAccessibleNamePropertyInfo), '("accessibleParent", Atk.Object.ObjectAccessibleParentPropertyInfo), '("accessibleRole", Atk.Object.ObjectAccessibleRolePropertyInfo), '("accessibleTableCaption", Atk.Object.ObjectAccessibleTableCaptionPropertyInfo), '("accessibleTableCaptionObject", Atk.Object.ObjectAccessibleTableCaptionObjectPropertyInfo), '("accessibleTableColumnDescription", Atk.Object.ObjectAccessibleTableColumnDescriptionPropertyInfo), '("accessibleTableColumnHeader", Atk.Object.ObjectAccessibleTableColumnHeaderPropertyInfo), '("accessibleTableRowDescription", Atk.Object.ObjectAccessibleTableRowDescriptionPropertyInfo), '("accessibleTableRowHeader", Atk.Object.ObjectAccessibleTableRowHeaderPropertyInfo), '("accessibleTableSummary", Atk.Object.ObjectAccessibleTableSummaryPropertyInfo), '("accessibleValue", Atk.Object.ObjectAccessibleValuePropertyInfo)] :: [(Symbol, *)])
    #endif

    #if ENABLE_OVERLOADING
    #endif

    #if ENABLE_OVERLOADING
    type instance O.SignalList Socket = SocketSignalList
    type SocketSignalList = ('[ '("activeDescendantChanged", Atk.Object.ObjectActiveDescendantChangedSignalInfo), '("boundsChanged", Atk.Component.ComponentBoundsChangedSignalInfo), '("childrenChanged", Atk.Object.ObjectChildrenChangedSignalInfo), '("focusEvent", Atk.Object.ObjectFocusEventSignalInfo), '("notify", GObject.Object.ObjectNotifySignalInfo), '("propertyChange", Atk.Object.ObjectPropertyChangeSignalInfo), '("stateChange", Atk.Object.ObjectStateChangeSignalInfo), '("visibleDataChanged", Atk.Object.ObjectVisibleDataChangedSignalInfo)] :: [(Symbol, *)])

    #endif

    -- method Socket::new
    -- method type : Constructor
    -- Args : []
    -- Lengths : []
    -- returnType : Just (TInterface (Name {namespace = "Atk", name = "Socket"}))
    -- throws : False
    -- Skip return : False

    foreign import ccall "atk_socket_new" atk_socket_new ::
        IO (Ptr Socket)

    {- |
    Creates a new 'GI.Atk.Objects.Socket.Socket'.
    -}
    socketNew ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        m Socket
        {- ^ __Returns:__ the newly created 'GI.Atk.Objects.Socket.Socket' instance -}
    socketNew  = liftIO $ do
        result <- atk_socket_new
        checkUnexpectedReturnNULL "socketNew" result
        result' <- (wrapObject Socket) result
        return result'

    #if ENABLE_OVERLOADING
    #endif

    -- method Socket::embed
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "obj", argType = TInterface (Name {namespace = "Atk", name = "Socket"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "an #AtkSocket", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "plug_id", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the ID of an #AtkPlug", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "atk_socket_embed" atk_socket_embed ::
        Ptr Socket ->                           -- obj : TInterface (Name {namespace = "Atk", name = "Socket"})
        CString ->                              -- plug_id : TBasicType TUTF8
        IO ()

    {- |
    Embeds the children of an 'GI.Atk.Objects.Plug.Plug' as the children of the
    'GI.Atk.Objects.Socket.Socket'. The plug may be in the same process or in a different
    process.

    The class item used by this function should be filled in by the IPC
    layer (usually at-spi2-atk). The implementor of the AtkSocket
    should call this function and pass the id for the plug as returned
    by 'GI.Atk.Objects.Plug.plugGetId'.  It is the responsibility of the application
    to pass the plug id on to the process implementing the 'GI.Atk.Objects.Socket.Socket'
    as needed.

    /Since: 1.30/
    -}
    socketEmbed ::
        (B.CallStack.HasCallStack, MonadIO m, IsSocket a) =>
        a
        {- ^ /@obj@/: an 'GI.Atk.Objects.Socket.Socket' -}
        -> T.Text
        {- ^ /@plugId@/: the ID of an 'GI.Atk.Objects.Plug.Plug' -}
        -> m ()
    socketEmbed obj plugId = liftIO $ do
        obj' <- unsafeManagedPtrCastPtr obj
        plugId' <- textToCString plugId
        atk_socket_embed obj' plugId'
        touchManagedPtr obj
        freeMem plugId'
        return ()

    #if ENABLE_OVERLOADING
    data SocketEmbedMethodInfo
    instance (signature ~ (T.Text -> m ()), MonadIO m, IsSocket a) => O.MethodInfo SocketEmbedMethodInfo a signature where
        overloadedMethod _ = socketEmbed

    #endif

    -- method Socket::is_occupied
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "obj", argType = TInterface (Name {namespace = "Atk", name = "Socket"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "an #AtkSocket", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TBasicType TBoolean)
    -- throws : False
    -- Skip return : False

    foreign import ccall "atk_socket_is_occupied" atk_socket_is_occupied ::
        Ptr Socket ->                           -- obj : TInterface (Name {namespace = "Atk", name = "Socket"})
        IO CInt

    {- |
    Determines whether or not the socket has an embedded plug.

    /Since: 1.30/
    -}
    socketIsOccupied ::
        (B.CallStack.HasCallStack, MonadIO m, IsSocket a) =>
        a
        {- ^ /@obj@/: an 'GI.Atk.Objects.Socket.Socket' -}
        -> m Bool
        {- ^ __Returns:__ TRUE if a plug is embedded in the socket -}
    socketIsOccupied obj = liftIO $ do
        obj' <- unsafeManagedPtrCastPtr obj
        result <- atk_socket_is_occupied obj'
        let result' = (/= 0) result
        touchManagedPtr obj
        return result'

    #if ENABLE_OVERLOADING
    data SocketIsOccupiedMethodInfo
    instance (signature ~ (m Bool), MonadIO m, IsSocket a) => O.MethodInfo SocketIsOccupiedMethodInfo a signature where
        overloadedMethod _ = socketIsOccupied

    #endif