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

    Extends the 'GI.Gio.Interfaces.Icon.Icon' interface and adds the ability to
    load icons from streams.
    -}

    #define ENABLE_OVERLOADING \
           (!defined(__HADDOCK_VERSION__))

    module GI.Gio.Interfaces.LoadableIcon
        (

    -- * Exported types
        LoadableIcon(..)                        ,
        noLoadableIcon                          ,
        IsLoadableIcon                          ,
        toLoadableIcon                          ,

     -- * Methods
    -- ** load #method:load#

    #if ENABLE_OVERLOADING
        LoadableIconLoadMethodInfo              ,
    #endif
        loadableIconLoad                        ,

    -- ** loadAsync #method:loadAsync#

    #if ENABLE_OVERLOADING
        LoadableIconLoadAsyncMethodInfo         ,
    #endif
        loadableIconLoadAsync                   ,

    -- ** loadFinish #method:loadFinish#

    #if ENABLE_OVERLOADING
        LoadableIconLoadFinishMethodInfo        ,
    #endif
        loadableIconLoadFinish                  ,

        ) 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 qualified GI.GObject.Objects.Object as GObject.Object
    import qualified GI.Gio.Callbacks as Gio.Callbacks
    import {-# SOURCE #-} qualified GI.Gio.Interfaces.AsyncResult as Gio.AsyncResult
    import {-# SOURCE #-} qualified GI.Gio.Interfaces.Icon as Gio.Icon
    import {-# SOURCE #-} qualified GI.Gio.Objects.Cancellable as Gio.Cancellable
    import {-# SOURCE #-} qualified GI.Gio.Objects.InputStream as Gio.InputStream

    -- interface LoadableIcon
    -- | Memory-managed wrapper type.
    newtype LoadableIcon = LoadableIcon (ManagedPtr LoadableIcon)
    -- | A convenience alias for `Nothing` :: `Maybe` `LoadableIcon`.
    noLoadableIcon :: Maybe LoadableIcon
    noLoadableIcon = Nothing

    #if ENABLE_OVERLOADING
    type instance O.SignalList LoadableIcon = LoadableIconSignalList
    type LoadableIconSignalList = ('[ '("notify", GObject.Object.ObjectNotifySignalInfo)] :: [(Symbol, *)])

    #endif

    foreign import ccall "g_loadable_icon_get_type"
        c_g_loadable_icon_get_type :: IO GType

    instance GObject LoadableIcon where
        gobjectType _ = c_g_loadable_icon_get_type

    -- | Type class for types which can be safely cast to `LoadableIcon`, for instance with `toLoadableIcon`.
    class GObject o => IsLoadableIcon o
    #if MIN_VERSION_base(4,9,0)
    instance {-# OVERLAPPABLE #-} (GObject a, O.UnknownAncestorError LoadableIcon a) =>
        IsLoadableIcon a
    #endif
    instance IsLoadableIcon LoadableIcon
    instance Gio.Icon.IsIcon LoadableIcon
    instance GObject.Object.IsObject LoadableIcon

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

    #if ENABLE_OVERLOADING
    instance O.HasAttributeList LoadableIcon
    type instance O.AttributeList LoadableIcon = LoadableIconAttributeList
    type LoadableIconAttributeList = ('[ ] :: [(Symbol, *)])
    #endif

    #if ENABLE_OVERLOADING
    #endif

    #if ENABLE_OVERLOADING
    type family ResolveLoadableIconMethod (t :: Symbol) (o :: *) :: * where
        ResolveLoadableIconMethod "bindProperty" o = GObject.Object.ObjectBindPropertyMethodInfo
        ResolveLoadableIconMethod "bindPropertyFull" o = GObject.Object.ObjectBindPropertyFullMethodInfo
        ResolveLoadableIconMethod "equal" o = Gio.Icon.IconEqualMethodInfo
        ResolveLoadableIconMethod "forceFloating" o = GObject.Object.ObjectForceFloatingMethodInfo
        ResolveLoadableIconMethod "freezeNotify" o = GObject.Object.ObjectFreezeNotifyMethodInfo
        ResolveLoadableIconMethod "getv" o = GObject.Object.ObjectGetvMethodInfo
        ResolveLoadableIconMethod "isFloating" o = GObject.Object.ObjectIsFloatingMethodInfo
        ResolveLoadableIconMethod "load" o = LoadableIconLoadMethodInfo
        ResolveLoadableIconMethod "loadAsync" o = LoadableIconLoadAsyncMethodInfo
        ResolveLoadableIconMethod "loadFinish" o = LoadableIconLoadFinishMethodInfo
        ResolveLoadableIconMethod "notify" o = GObject.Object.ObjectNotifyMethodInfo
        ResolveLoadableIconMethod "notifyByPspec" o = GObject.Object.ObjectNotifyByPspecMethodInfo
        ResolveLoadableIconMethod "ref" o = GObject.Object.ObjectRefMethodInfo
        ResolveLoadableIconMethod "refSink" o = GObject.Object.ObjectRefSinkMethodInfo
        ResolveLoadableIconMethod "runDispose" o = GObject.Object.ObjectRunDisposeMethodInfo
        ResolveLoadableIconMethod "serialize" o = Gio.Icon.IconSerializeMethodInfo
        ResolveLoadableIconMethod "stealData" o = GObject.Object.ObjectStealDataMethodInfo
        ResolveLoadableIconMethod "stealQdata" o = GObject.Object.ObjectStealQdataMethodInfo
        ResolveLoadableIconMethod "thawNotify" o = GObject.Object.ObjectThawNotifyMethodInfo
        ResolveLoadableIconMethod "toString" o = Gio.Icon.IconToStringMethodInfo
        ResolveLoadableIconMethod "unref" o = GObject.Object.ObjectUnrefMethodInfo
        ResolveLoadableIconMethod "watchClosure" o = GObject.Object.ObjectWatchClosureMethodInfo
        ResolveLoadableIconMethod "getData" o = GObject.Object.ObjectGetDataMethodInfo
        ResolveLoadableIconMethod "getProperty" o = GObject.Object.ObjectGetPropertyMethodInfo
        ResolveLoadableIconMethod "getQdata" o = GObject.Object.ObjectGetQdataMethodInfo
        ResolveLoadableIconMethod "setData" o = GObject.Object.ObjectSetDataMethodInfo
        ResolveLoadableIconMethod "setProperty" o = GObject.Object.ObjectSetPropertyMethodInfo
        ResolveLoadableIconMethod l o = O.MethodResolutionFailed l o

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

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

    -- method LoadableIcon::load
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "icon", argType = TInterface (Name {namespace = "Gio", name = "LoadableIcon"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GLoadableIcon.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "size", argType = TBasicType TInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "an integer.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "type", argType = TBasicType TUTF8, direction = DirectionOut, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a location to store the type of the loaded\nicon, %NULL to ignore.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything},Arg {argCName = "cancellable", argType = TInterface (Name {namespace = "Gio", name = "Cancellable"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "optional #GCancellable object, %NULL to\nignore.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TInterface (Name {namespace = "Gio", name = "InputStream"}))
    -- throws : True
    -- Skip return : False

    foreign import ccall "g_loadable_icon_load" g_loadable_icon_load ::
        Ptr LoadableIcon ->                     -- icon : TInterface (Name {namespace = "Gio", name = "LoadableIcon"})
        Int32 ->                                -- size : TBasicType TInt
        Ptr CString ->                          -- type : TBasicType TUTF8
        Ptr Gio.Cancellable.Cancellable ->      -- cancellable : TInterface (Name {namespace = "Gio", name = "Cancellable"})
        Ptr (Ptr GError) ->                     -- error
        IO (Ptr Gio.InputStream.InputStream)

    {- |
    Loads a loadable icon. For the asynchronous version of this function,
    see 'GI.Gio.Interfaces.LoadableIcon.loadableIconLoadAsync'.
    -}
    loadableIconLoad ::
        (B.CallStack.HasCallStack, MonadIO m, IsLoadableIcon a, Gio.Cancellable.IsCancellable b) =>
        a
        {- ^ /@icon@/: a 'GI.Gio.Interfaces.LoadableIcon.LoadableIcon'. -}
        -> Int32
        {- ^ /@size@/: an integer. -}
        -> Maybe (b)
        {- ^ /@cancellable@/: optional 'GI.Gio.Objects.Cancellable.Cancellable' object, 'Nothing' to
    ignore. -}
        -> m ((Gio.InputStream.InputStream, T.Text))
        {- ^ __Returns:__ a 'GI.Gio.Objects.InputStream.InputStream' to read the icon from. /(Can throw 'Data.GI.Base.GError.GError')/ -}
    loadableIconLoad icon size cancellable = liftIO $ do
        icon' <- unsafeManagedPtrCastPtr icon
        type_ <- allocMem :: IO (Ptr CString)
        maybeCancellable <- case cancellable of
            Nothing -> return nullPtr
            Just jCancellable -> do
                jCancellable' <- unsafeManagedPtrCastPtr jCancellable
                return jCancellable'
        onException (do
            result <- propagateGError $ g_loadable_icon_load icon' size type_ maybeCancellable
            checkUnexpectedReturnNULL "loadableIconLoad" result
            result' <- (wrapObject Gio.InputStream.InputStream) result
            type_' <- peek type_
            type_'' <- cstringToText type_'
            freeMem type_'
            touchManagedPtr icon
            whenJust cancellable touchManagedPtr
            freeMem type_
            return (result', type_'')
         ) (do
            freeMem type_
         )

    #if ENABLE_OVERLOADING
    data LoadableIconLoadMethodInfo
    instance (signature ~ (Int32 -> Maybe (b) -> m ((Gio.InputStream.InputStream, T.Text))), MonadIO m, IsLoadableIcon a, Gio.Cancellable.IsCancellable b) => O.MethodInfo LoadableIconLoadMethodInfo a signature where
        overloadedMethod _ = loadableIconLoad

    #endif

    -- method LoadableIcon::load_async
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "icon", argType = TInterface (Name {namespace = "Gio", name = "LoadableIcon"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GLoadableIcon.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "size", argType = TBasicType TInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "an integer.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "cancellable", argType = TInterface (Name {namespace = "Gio", name = "Cancellable"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "optional #GCancellable object, %NULL to ignore.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "callback", argType = TInterface (Name {namespace = "Gio", name = "AsyncReadyCallback"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "a #GAsyncReadyCallback to call when the\n           request is satisfied", sinceVersion = Nothing}, argScope = ScopeTypeAsync, argClosure = 4, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "user_data", argType = TBasicType TPtr, direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "the data to pass to callback function", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_loadable_icon_load_async" g_loadable_icon_load_async ::
        Ptr LoadableIcon ->                     -- icon : TInterface (Name {namespace = "Gio", name = "LoadableIcon"})
        Int32 ->                                -- size : TBasicType TInt
        Ptr Gio.Cancellable.Cancellable ->      -- cancellable : TInterface (Name {namespace = "Gio", name = "Cancellable"})
        FunPtr Gio.Callbacks.C_AsyncReadyCallback -> -- callback : TInterface (Name {namespace = "Gio", name = "AsyncReadyCallback"})
        Ptr () ->                               -- user_data : TBasicType TPtr
        IO ()

    {- |
    Loads an icon asynchronously. To finish this function, see
    'GI.Gio.Interfaces.LoadableIcon.loadableIconLoadFinish'. For the synchronous, blocking
    version of this function, see 'GI.Gio.Interfaces.LoadableIcon.loadableIconLoad'.
    -}
    loadableIconLoadAsync ::
        (B.CallStack.HasCallStack, MonadIO m, IsLoadableIcon a, Gio.Cancellable.IsCancellable b) =>
        a
        {- ^ /@icon@/: a 'GI.Gio.Interfaces.LoadableIcon.LoadableIcon'. -}
        -> Int32
        {- ^ /@size@/: an integer. -}
        -> Maybe (b)
        {- ^ /@cancellable@/: optional 'GI.Gio.Objects.Cancellable.Cancellable' object, 'Nothing' to ignore. -}
        -> Maybe (Gio.Callbacks.AsyncReadyCallback)
        {- ^ /@callback@/: a 'GI.Gio.Callbacks.AsyncReadyCallback' to call when the
               request is satisfied -}
        -> m ()
    loadableIconLoadAsync icon size cancellable callback = liftIO $ do
        icon' <- unsafeManagedPtrCastPtr icon
        maybeCancellable <- case cancellable of
            Nothing -> return nullPtr
            Just jCancellable -> do
                jCancellable' <- unsafeManagedPtrCastPtr jCancellable
                return jCancellable'
        maybeCallback <- case callback of
            Nothing -> return (castPtrToFunPtr nullPtr)
            Just jCallback -> do
                ptrcallback <- callocMem :: IO (Ptr (FunPtr Gio.Callbacks.C_AsyncReadyCallback))
                jCallback' <- Gio.Callbacks.mk_AsyncReadyCallback (Gio.Callbacks.wrap_AsyncReadyCallback (Just ptrcallback) (Gio.Callbacks.drop_closures_AsyncReadyCallback jCallback))
                poke ptrcallback jCallback'
                return jCallback'
        let userData = nullPtr
        g_loadable_icon_load_async icon' size maybeCancellable maybeCallback userData
        touchManagedPtr icon
        whenJust cancellable touchManagedPtr
        return ()

    #if ENABLE_OVERLOADING
    data LoadableIconLoadAsyncMethodInfo
    instance (signature ~ (Int32 -> Maybe (b) -> Maybe (Gio.Callbacks.AsyncReadyCallback) -> m ()), MonadIO m, IsLoadableIcon a, Gio.Cancellable.IsCancellable b) => O.MethodInfo LoadableIconLoadAsyncMethodInfo a signature where
        overloadedMethod _ = loadableIconLoadAsync

    #endif

    -- method LoadableIcon::load_finish
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "icon", argType = TInterface (Name {namespace = "Gio", name = "LoadableIcon"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GLoadableIcon.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "res", argType = TInterface (Name {namespace = "Gio", name = "AsyncResult"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GAsyncResult.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "type", argType = TBasicType TUTF8, direction = DirectionOut, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a location to store the type of the loaded\n       icon, %NULL to ignore.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
    -- Lengths : []
    -- returnType : Just (TInterface (Name {namespace = "Gio", name = "InputStream"}))
    -- throws : True
    -- Skip return : False

    foreign import ccall "g_loadable_icon_load_finish" g_loadable_icon_load_finish ::
        Ptr LoadableIcon ->                     -- icon : TInterface (Name {namespace = "Gio", name = "LoadableIcon"})
        Ptr Gio.AsyncResult.AsyncResult ->      -- res : TInterface (Name {namespace = "Gio", name = "AsyncResult"})
        Ptr CString ->                          -- type : TBasicType TUTF8
        Ptr (Ptr GError) ->                     -- error
        IO (Ptr Gio.InputStream.InputStream)

    {- |
    Finishes an asynchronous icon load started in 'GI.Gio.Interfaces.LoadableIcon.loadableIconLoadAsync'.
    -}
    loadableIconLoadFinish ::
        (B.CallStack.HasCallStack, MonadIO m, IsLoadableIcon a, Gio.AsyncResult.IsAsyncResult b) =>
        a
        {- ^ /@icon@/: a 'GI.Gio.Interfaces.LoadableIcon.LoadableIcon'. -}
        -> b
        {- ^ /@res@/: a 'GI.Gio.Interfaces.AsyncResult.AsyncResult'. -}
        -> m ((Gio.InputStream.InputStream, T.Text))
        {- ^ __Returns:__ a 'GI.Gio.Objects.InputStream.InputStream' to read the icon from. /(Can throw 'Data.GI.Base.GError.GError')/ -}
    loadableIconLoadFinish icon res = liftIO $ do
        icon' <- unsafeManagedPtrCastPtr icon
        res' <- unsafeManagedPtrCastPtr res
        type_ <- allocMem :: IO (Ptr CString)
        onException (do
            result <- propagateGError $ g_loadable_icon_load_finish icon' res' type_
            checkUnexpectedReturnNULL "loadableIconLoadFinish" result
            result' <- (wrapObject Gio.InputStream.InputStream) result
            type_' <- peek type_
            type_'' <- cstringToText type_'
            freeMem type_'
            touchManagedPtr icon
            touchManagedPtr res
            freeMem type_
            return (result', type_'')
         ) (do
            freeMem type_
         )

    #if ENABLE_OVERLOADING
    data LoadableIconLoadFinishMethodInfo
    instance (signature ~ (b -> m ((Gio.InputStream.InputStream, T.Text))), MonadIO m, IsLoadableIcon a, Gio.AsyncResult.IsAsyncResult b) => O.MethodInfo LoadableIconLoadFinishMethodInfo a signature where
        overloadedMethod _ = loadableIconLoadFinish

    #endif