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

    The @GMainLoop@ struct is an opaque data type
    representing the main event loop of a GLib or GTK+ application.
    -}

    #define ENABLE_OVERLOADING \
           (!defined(__HADDOCK_VERSION__))

    module GI.GLib.Structs.MainLoop
        (

    -- * Exported types
        MainLoop(..)                            ,
        noMainLoop                              ,

     -- * Methods
    -- ** getContext #method:getContext#

    #if ENABLE_OVERLOADING
        MainLoopGetContextMethodInfo            ,
    #endif
        mainLoopGetContext                      ,

    -- ** isRunning #method:isRunning#

    #if ENABLE_OVERLOADING
        MainLoopIsRunningMethodInfo             ,
    #endif
        mainLoopIsRunning                       ,

    -- ** new #method:new#

        mainLoopNew                             ,

    -- ** quit #method:quit#

    #if ENABLE_OVERLOADING
        MainLoopQuitMethodInfo                  ,
    #endif
        mainLoopQuit                            ,

    -- ** ref #method:ref#

    #if ENABLE_OVERLOADING
        MainLoopRefMethodInfo                   ,
    #endif
        mainLoopRef                             ,

    -- ** run #method:run#

    #if ENABLE_OVERLOADING
        MainLoopRunMethodInfo                   ,
    #endif
        mainLoopRun                             ,

    -- ** unref #method:unref#

    #if ENABLE_OVERLOADING
        MainLoopUnrefMethodInfo                 ,
    #endif
        mainLoopUnref                           ,

        ) 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.GLib.Structs.MainContext as GLib.MainContext

    -- | Memory-managed wrapper type.
    newtype MainLoop = MainLoop (ManagedPtr MainLoop)
    foreign import ccall "g_main_loop_get_type" c_g_main_loop_get_type ::
        IO GType

    instance BoxedObject MainLoop where
        boxedType _ = c_g_main_loop_get_type

    -- | A convenience alias for `Nothing` :: `Maybe` `MainLoop`.
    noMainLoop :: Maybe MainLoop
    noMainLoop = Nothing

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

    -- method MainLoop::new
    -- method type : Constructor
    -- Args : [Arg {argCName = "context", argType = TInterface (Name {namespace = "GLib", name = "MainContext"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "a #GMainContext  (if %NULL, the default context will be used).", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "is_running", argType = TBasicType TBoolean, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "set to %TRUE to indicate that the loop is running. This\nis not very important since calling g_main_loop_run() will set this to\n%TRUE anyway.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TInterface (Name {namespace = "GLib", name = "MainLoop"}))
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_main_loop_new" g_main_loop_new ::
        Ptr GLib.MainContext.MainContext ->     -- context : TInterface (Name {namespace = "GLib", name = "MainContext"})
        CInt ->                                 -- is_running : TBasicType TBoolean
        IO (Ptr MainLoop)

    {- |
    Creates a new 'GI.GLib.Structs.MainLoop.MainLoop' structure.
    -}
    mainLoopNew ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        Maybe (GLib.MainContext.MainContext)
        {- ^ /@context@/: a 'GI.GLib.Structs.MainContext.MainContext'  (if 'Nothing', the default context will be used). -}
        -> Bool
        {- ^ /@isRunning@/: set to 'True' to indicate that the loop is running. This
    is not very important since calling 'GI.GLib.Structs.MainLoop.mainLoopRun' will set this to
    'True' anyway. -}
        -> m MainLoop
        {- ^ __Returns:__ a new 'GI.GLib.Structs.MainLoop.MainLoop'. -}
    mainLoopNew context isRunning = liftIO $ do
        maybeContext <- case context of
            Nothing -> return nullPtr
            Just jContext -> do
                jContext' <- unsafeManagedPtrGetPtr jContext
                return jContext'
        let isRunning' = (fromIntegral . fromEnum) isRunning
        result <- g_main_loop_new maybeContext isRunning'
        checkUnexpectedReturnNULL "mainLoopNew" result
        result' <- (wrapBoxed MainLoop) result
        whenJust context touchManagedPtr
        return result'

    #if ENABLE_OVERLOADING
    #endif

    -- method MainLoop::get_context
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "loop", argType = TInterface (Name {namespace = "GLib", name = "MainLoop"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GMainLoop.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TInterface (Name {namespace = "GLib", name = "MainContext"}))
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_main_loop_get_context" g_main_loop_get_context ::
        Ptr MainLoop ->                         -- loop : TInterface (Name {namespace = "GLib", name = "MainLoop"})
        IO (Ptr GLib.MainContext.MainContext)

    {- |
    Returns the 'GI.GLib.Structs.MainContext.MainContext' of /@loop@/.
    -}
    mainLoopGetContext ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        MainLoop
        {- ^ /@loop@/: a 'GI.GLib.Structs.MainLoop.MainLoop'. -}
        -> m GLib.MainContext.MainContext
        {- ^ __Returns:__ the 'GI.GLib.Structs.MainContext.MainContext' of /@loop@/ -}
    mainLoopGetContext loop = liftIO $ do
        loop' <- unsafeManagedPtrGetPtr loop
        result <- g_main_loop_get_context loop'
        checkUnexpectedReturnNULL "mainLoopGetContext" result
        result' <- (newBoxed GLib.MainContext.MainContext) result
        touchManagedPtr loop
        return result'

    #if ENABLE_OVERLOADING
    data MainLoopGetContextMethodInfo
    instance (signature ~ (m GLib.MainContext.MainContext), MonadIO m) => O.MethodInfo MainLoopGetContextMethodInfo MainLoop signature where
        overloadedMethod _ = mainLoopGetContext

    #endif

    -- method MainLoop::is_running
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "loop", argType = TInterface (Name {namespace = "GLib", name = "MainLoop"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GMainLoop.", 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 "g_main_loop_is_running" g_main_loop_is_running ::
        Ptr MainLoop ->                         -- loop : TInterface (Name {namespace = "GLib", name = "MainLoop"})
        IO CInt

    {- |
    Checks to see if the main loop is currently being run via 'GI.GLib.Structs.MainLoop.mainLoopRun'.
    -}
    mainLoopIsRunning ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        MainLoop
        {- ^ /@loop@/: a 'GI.GLib.Structs.MainLoop.MainLoop'. -}
        -> m Bool
        {- ^ __Returns:__ 'True' if the mainloop is currently being run. -}
    mainLoopIsRunning loop = liftIO $ do
        loop' <- unsafeManagedPtrGetPtr loop
        result <- g_main_loop_is_running loop'
        let result' = (/= 0) result
        touchManagedPtr loop
        return result'

    #if ENABLE_OVERLOADING
    data MainLoopIsRunningMethodInfo
    instance (signature ~ (m Bool), MonadIO m) => O.MethodInfo MainLoopIsRunningMethodInfo MainLoop signature where
        overloadedMethod _ = mainLoopIsRunning

    #endif

    -- method MainLoop::quit
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "loop", argType = TInterface (Name {namespace = "GLib", name = "MainLoop"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GMainLoop", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_main_loop_quit" g_main_loop_quit ::
        Ptr MainLoop ->                         -- loop : TInterface (Name {namespace = "GLib", name = "MainLoop"})
        IO ()

    {- |
    Stops a 'GI.GLib.Structs.MainLoop.MainLoop' from running. Any calls to 'GI.GLib.Structs.MainLoop.mainLoopRun'
    for the loop will return.

    Note that sources that have already been dispatched when
    'GI.GLib.Structs.MainLoop.mainLoopQuit' is called will still be executed.
    -}
    mainLoopQuit ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        MainLoop
        {- ^ /@loop@/: a 'GI.GLib.Structs.MainLoop.MainLoop' -}
        -> m ()
    mainLoopQuit loop = liftIO $ do
        loop' <- unsafeManagedPtrGetPtr loop
        g_main_loop_quit loop'
        touchManagedPtr loop
        return ()

    #if ENABLE_OVERLOADING
    data MainLoopQuitMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo MainLoopQuitMethodInfo MainLoop signature where
        overloadedMethod _ = mainLoopQuit

    #endif

    -- method MainLoop::ref
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "loop", argType = TInterface (Name {namespace = "GLib", name = "MainLoop"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GMainLoop", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TInterface (Name {namespace = "GLib", name = "MainLoop"}))
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_main_loop_ref" g_main_loop_ref ::
        Ptr MainLoop ->                         -- loop : TInterface (Name {namespace = "GLib", name = "MainLoop"})
        IO (Ptr MainLoop)

    {- |
    Increases the reference count on a 'GI.GLib.Structs.MainLoop.MainLoop' object by one.
    -}
    mainLoopRef ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        MainLoop
        {- ^ /@loop@/: a 'GI.GLib.Structs.MainLoop.MainLoop' -}
        -> m MainLoop
        {- ^ __Returns:__ /@loop@/ -}
    mainLoopRef loop = liftIO $ do
        loop' <- unsafeManagedPtrGetPtr loop
        result <- g_main_loop_ref loop'
        checkUnexpectedReturnNULL "mainLoopRef" result
        result' <- (wrapBoxed MainLoop) result
        touchManagedPtr loop
        return result'

    #if ENABLE_OVERLOADING
    data MainLoopRefMethodInfo
    instance (signature ~ (m MainLoop), MonadIO m) => O.MethodInfo MainLoopRefMethodInfo MainLoop signature where
        overloadedMethod _ = mainLoopRef

    #endif

    -- method MainLoop::run
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "loop", argType = TInterface (Name {namespace = "GLib", name = "MainLoop"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GMainLoop", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_main_loop_run" g_main_loop_run ::
        Ptr MainLoop ->                         -- loop : TInterface (Name {namespace = "GLib", name = "MainLoop"})
        IO ()

    {- |
    Runs a main loop until 'GI.GLib.Structs.MainLoop.mainLoopQuit' is called on the loop.
    If this is called for the thread of the loop\'s 'GI.GLib.Structs.MainContext.MainContext',
    it will process events from the loop, otherwise it will
    simply wait.
    -}
    mainLoopRun ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        MainLoop
        {- ^ /@loop@/: a 'GI.GLib.Structs.MainLoop.MainLoop' -}
        -> m ()
    mainLoopRun loop = liftIO $ do
        loop' <- unsafeManagedPtrGetPtr loop
        g_main_loop_run loop'
        touchManagedPtr loop
        return ()

    #if ENABLE_OVERLOADING
    data MainLoopRunMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo MainLoopRunMethodInfo MainLoop signature where
        overloadedMethod _ = mainLoopRun

    #endif

    -- method MainLoop::unref
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "loop", argType = TInterface (Name {namespace = "GLib", name = "MainLoop"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GMainLoop", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_main_loop_unref" g_main_loop_unref ::
        Ptr MainLoop ->                         -- loop : TInterface (Name {namespace = "GLib", name = "MainLoop"})
        IO ()

    {- |
    Decreases the reference count on a 'GI.GLib.Structs.MainLoop.MainLoop' object by one. If
    the result is zero, free the loop and free all associated memory.
    -}
    mainLoopUnref ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        MainLoop
        {- ^ /@loop@/: a 'GI.GLib.Structs.MainLoop.MainLoop' -}
        -> m ()
    mainLoopUnref loop = liftIO $ do
        loop' <- unsafeManagedPtrGetPtr loop
        g_main_loop_unref loop'
        touchManagedPtr loop
        return ()

    #if ENABLE_OVERLOADING
    data MainLoopUnrefMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo MainLoopUnrefMethodInfo MainLoop signature where
        overloadedMethod _ = mainLoopUnref

    #endif

    #if ENABLE_OVERLOADING
    type family ResolveMainLoopMethod (t :: Symbol) (o :: *) :: * where
        ResolveMainLoopMethod "isRunning" o = MainLoopIsRunningMethodInfo
        ResolveMainLoopMethod "quit" o = MainLoopQuitMethodInfo
        ResolveMainLoopMethod "ref" o = MainLoopRefMethodInfo
        ResolveMainLoopMethod "run" o = MainLoopRunMethodInfo
        ResolveMainLoopMethod "unref" o = MainLoopUnrefMethodInfo
        ResolveMainLoopMethod "getContext" o = MainLoopGetContextMethodInfo
        ResolveMainLoopMethod l o = O.MethodResolutionFailed l o

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

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