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

    'GI.Gio.Objects.AppInfoMonitor.AppInfoMonitor' is a very simple object used for monitoring the app
    info database for changes (ie: newly installed or removed
    applications).

    Call 'GI.Gio.Objects.AppInfoMonitor.appInfoMonitorGet' to get a 'GI.Gio.Objects.AppInfoMonitor.AppInfoMonitor' and connect
    to the \"changed\" signal.

    In the usual case, applications should try to make note of the change
    (doing things like invalidating caches) but not act on it.  In
    particular, applications should avoid making calls to 'GI.Gio.Interfaces.AppInfo.AppInfo' APIs
    in response to the change signal, deferring these until the time that
    the data is actually required.  The exception to this case is when
    application information is actually being displayed on the screen
    (eg: during a search or when the list of all applications is shown).
    The reason for this is that changes to the list of installed
    applications often come in groups (like during system updates) and
    rescanning the list on every change is pointless and expensive.

    /Since: 2.40/
    -}

    #define ENABLE_OVERLOADING \
           (!defined(__HADDOCK_VERSION__))

    module GI.Gio.Objects.AppInfoMonitor
        (

    -- * Exported types
        AppInfoMonitor(..)                      ,
        IsAppInfoMonitor                        ,
        toAppInfoMonitor                        ,
        noAppInfoMonitor                        ,

     -- * Methods
    -- ** get #method:get#

        appInfoMonitorGet                       ,

     -- * Signals
    -- ** changed #signal:changed#

        AppInfoMonitorChangedCallback           ,
    #if ENABLE_OVERLOADING
        AppInfoMonitorChangedSignalInfo         ,
    #endif
        C_AppInfoMonitorChangedCallback         ,
        afterAppInfoMonitorChanged              ,
        genClosure_AppInfoMonitorChanged        ,
        mk_AppInfoMonitorChangedCallback        ,
        noAppInfoMonitorChangedCallback         ,
        onAppInfoMonitorChanged                 ,
        wrap_AppInfoMonitorChangedCallback      ,

        ) 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

    -- | Memory-managed wrapper type.
    newtype AppInfoMonitor = AppInfoMonitor (ManagedPtr AppInfoMonitor)
    foreign import ccall "g_app_info_monitor_get_type"
        c_g_app_info_monitor_get_type :: IO GType

    instance GObject AppInfoMonitor where
        gobjectType _ = c_g_app_info_monitor_get_type

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

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

    -- | A convenience alias for `Nothing` :: `Maybe` `AppInfoMonitor`.
    noAppInfoMonitor :: Maybe AppInfoMonitor
    noAppInfoMonitor = Nothing

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

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

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

    -- signal AppInfoMonitor::changed
    {- |
    Signal emitted when the app info database for changes (ie: newly installed
    or removed applications).
    -}
    type AppInfoMonitorChangedCallback =
        IO ()

    -- | A convenience synonym for @`Nothing` :: `Maybe` `AppInfoMonitorChangedCallback`@.
    noAppInfoMonitorChangedCallback :: Maybe AppInfoMonitorChangedCallback
    noAppInfoMonitorChangedCallback = Nothing

    -- | Type for the callback on the (unwrapped) C side.
    type C_AppInfoMonitorChangedCallback =
        Ptr () ->                               -- object
        Ptr () ->                               -- user_data
        IO ()

    -- | Generate a function pointer callable from C code, from a `C_AppInfoMonitorChangedCallback`.
    foreign import ccall "wrapper"
        mk_AppInfoMonitorChangedCallback :: C_AppInfoMonitorChangedCallback -> IO (FunPtr C_AppInfoMonitorChangedCallback)

    -- | Wrap the callback into a `Closure`.
    genClosure_AppInfoMonitorChanged :: AppInfoMonitorChangedCallback -> IO Closure
    genClosure_AppInfoMonitorChanged cb = do
        let cb' = wrap_AppInfoMonitorChangedCallback cb
        mk_AppInfoMonitorChangedCallback cb' >>= newCClosure

    -- | Wrap a `AppInfoMonitorChangedCallback` into a `C_AppInfoMonitorChangedCallback`.
    wrap_AppInfoMonitorChangedCallback ::
        AppInfoMonitorChangedCallback ->
        C_AppInfoMonitorChangedCallback
    wrap_AppInfoMonitorChangedCallback _cb _ _ = do
        _cb

    {- |
    Connect a signal handler for the “@changed@” signal, to be run before the default handler.
    When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

    @
    'Data.GI.Base.Signals.on' appInfoMonitor #changed callback
    @
    -}
    onAppInfoMonitorChanged :: (IsAppInfoMonitor a, MonadIO m) => a -> AppInfoMonitorChangedCallback -> m SignalHandlerId
    onAppInfoMonitorChanged obj cb = liftIO $ do
        let cb' = wrap_AppInfoMonitorChangedCallback cb
        cb'' <- mk_AppInfoMonitorChangedCallback cb'
        connectSignalFunPtr obj "changed" cb'' SignalConnectBefore

    {- |
    Connect a signal handler for the “@changed@” signal, to be run after the default handler.
    When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

    @
    'Data.GI.Base.Signals.after' appInfoMonitor #changed callback
    @
    -}
    afterAppInfoMonitorChanged :: (IsAppInfoMonitor a, MonadIO m) => a -> AppInfoMonitorChangedCallback -> m SignalHandlerId
    afterAppInfoMonitorChanged obj cb = liftIO $ do
        let cb' = wrap_AppInfoMonitorChangedCallback cb
        cb'' <- mk_AppInfoMonitorChangedCallback cb'
        connectSignalFunPtr obj "changed" cb'' SignalConnectAfter

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

    #if ENABLE_OVERLOADING
    #endif

    #if ENABLE_OVERLOADING
    data AppInfoMonitorChangedSignalInfo
    instance SignalInfo AppInfoMonitorChangedSignalInfo where
        type HaskellCallbackType AppInfoMonitorChangedSignalInfo = AppInfoMonitorChangedCallback
        connectSignal _ obj cb connectMode = do
            let cb' = wrap_AppInfoMonitorChangedCallback cb
            cb'' <- mk_AppInfoMonitorChangedCallback cb'
            connectSignalFunPtr obj "changed" cb'' connectMode

    type instance O.SignalList AppInfoMonitor = AppInfoMonitorSignalList
    type AppInfoMonitorSignalList = ('[ '("changed", AppInfoMonitorChangedSignalInfo), '("notify", GObject.Object.ObjectNotifySignalInfo)] :: [(Symbol, *)])

    #endif

    -- method AppInfoMonitor::get
    -- method type : MemberFunction
    -- Args : []
    -- Lengths : []
    -- returnType : Just (TInterface (Name {namespace = "Gio", name = "AppInfoMonitor"}))
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_app_info_monitor_get" g_app_info_monitor_get ::
        IO (Ptr AppInfoMonitor)

    {- |
    Gets the 'GI.Gio.Objects.AppInfoMonitor.AppInfoMonitor' for the current thread-default main
    context.

    The 'GI.Gio.Objects.AppInfoMonitor.AppInfoMonitor' will emit a \"changed\" signal in the
    thread-default main context whenever the list of installed
    applications (as reported by 'GI.Gio.Functions.appInfoGetAll') may have changed.

    You must only call 'GI.GObject.Objects.Object.objectUnref' on the return value from under
    the same main context as you created it.

    /Since: 2.40/
    -}
    appInfoMonitorGet ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        m AppInfoMonitor
        {- ^ __Returns:__ a reference to a 'GI.Gio.Objects.AppInfoMonitor.AppInfoMonitor' -}
    appInfoMonitorGet  = liftIO $ do
        result <- g_app_info_monitor_get
        checkUnexpectedReturnNULL "appInfoMonitorGet" result
        result' <- (wrapObject AppInfoMonitor) result
        return result'

    #if ENABLE_OVERLOADING
    #endif