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

    Opaque datatype that records a start time.
    -}

    #define ENABLE_OVERLOADING \
           (!defined(__HADDOCK_VERSION__))

    module GI.GLib.Structs.Timer
        (

    -- * Exported types
        Timer(..)                               ,
        noTimer                                 ,

     -- * Methods
    -- ** continue #method:continue#

    #if ENABLE_OVERLOADING
        TimerContinueMethodInfo                 ,
    #endif
        timerContinue                           ,

    -- ** destroy #method:destroy#

    #if ENABLE_OVERLOADING
        TimerDestroyMethodInfo                  ,
    #endif
        timerDestroy                            ,

    -- ** elapsed #method:elapsed#

    #if ENABLE_OVERLOADING
        TimerElapsedMethodInfo                  ,
    #endif
        timerElapsed                            ,

    -- ** reset #method:reset#

    #if ENABLE_OVERLOADING
        TimerResetMethodInfo                    ,
    #endif
        timerReset                              ,

    -- ** start #method:start#

    #if ENABLE_OVERLOADING
        TimerStartMethodInfo                    ,
    #endif
        timerStart                              ,

    -- ** stop #method:stop#

    #if ENABLE_OVERLOADING
        TimerStopMethodInfo                     ,
    #endif
        timerStop                               ,

        ) 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

    -- | Memory-managed wrapper type.
    newtype Timer = Timer (ManagedPtr Timer)
    -- XXX Wrapping a foreign struct/union with no known destructor or size, leak?
    instance WrappedPtr Timer where
        wrappedPtrCalloc = return nullPtr
        wrappedPtrCopy = return
        wrappedPtrFree = Nothing

    -- | A convenience alias for `Nothing` :: `Maybe` `Timer`.
    noTimer :: Maybe Timer
    noTimer = Nothing

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

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

    foreign import ccall "g_timer_continue" g_timer_continue ::
        Ptr Timer ->                            -- timer : TInterface (Name {namespace = "GLib", name = "Timer"})
        IO ()

    {- |
    Resumes a timer that has previously been stopped with
    'GI.GLib.Structs.Timer.timerStop'. 'GI.GLib.Structs.Timer.timerStop' must be called before using this
    function.

    /Since: 2.4/
    -}
    timerContinue ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        Timer
        {- ^ /@timer@/: a 'GI.GLib.Structs.Timer.Timer'. -}
        -> m ()
    timerContinue timer = liftIO $ do
        timer' <- unsafeManagedPtrGetPtr timer
        g_timer_continue timer'
        touchManagedPtr timer
        return ()

    #if ENABLE_OVERLOADING
    data TimerContinueMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo TimerContinueMethodInfo Timer signature where
        overloadedMethod _ = timerContinue

    #endif

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

    foreign import ccall "g_timer_destroy" g_timer_destroy ::
        Ptr Timer ->                            -- timer : TInterface (Name {namespace = "GLib", name = "Timer"})
        IO ()

    {- |
    Destroys a timer, freeing associated resources.
    -}
    timerDestroy ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        Timer
        {- ^ /@timer@/: a 'GI.GLib.Structs.Timer.Timer' to destroy. -}
        -> m ()
    timerDestroy timer = liftIO $ do
        timer' <- unsafeManagedPtrGetPtr timer
        g_timer_destroy timer'
        touchManagedPtr timer
        return ()

    #if ENABLE_OVERLOADING
    data TimerDestroyMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo TimerDestroyMethodInfo Timer signature where
        overloadedMethod _ = timerDestroy

    #endif

    -- method Timer::elapsed
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "timer", argType = TInterface (Name {namespace = "GLib", name = "Timer"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GTimer.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "microseconds", argType = TBasicType TULong, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "return location for the fractional part of seconds\n               elapsed, in microseconds (that is, the total number\n               of microseconds elapsed, modulo 1000000), or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TBasicType TDouble)
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_timer_elapsed" g_timer_elapsed ::
        Ptr Timer ->                            -- timer : TInterface (Name {namespace = "GLib", name = "Timer"})
        CULong ->                               -- microseconds : TBasicType TULong
        IO CDouble

    {- |
    If /@timer@/ has been started but not stopped, obtains the time since
    the timer was started. If /@timer@/ has been stopped, obtains the
    elapsed time between the time it was started and the time it was
    stopped. The return value is the number of seconds elapsed,
    including any fractional part. The /@microseconds@/ out parameter is
    essentially useless.
    -}
    timerElapsed ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        Timer
        {- ^ /@timer@/: a 'GI.GLib.Structs.Timer.Timer'. -}
        -> CULong
        {- ^ /@microseconds@/: return location for the fractional part of seconds
                   elapsed, in microseconds (that is, the total number
                   of microseconds elapsed, modulo 1000000), or 'Nothing' -}
        -> m Double
        {- ^ __Returns:__ seconds elapsed as a floating point value, including any
             fractional part. -}
    timerElapsed timer microseconds = liftIO $ do
        timer' <- unsafeManagedPtrGetPtr timer
        result <- g_timer_elapsed timer' microseconds
        let result' = realToFrac result
        touchManagedPtr timer
        return result'

    #if ENABLE_OVERLOADING
    data TimerElapsedMethodInfo
    instance (signature ~ (CULong -> m Double), MonadIO m) => O.MethodInfo TimerElapsedMethodInfo Timer signature where
        overloadedMethod _ = timerElapsed

    #endif

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

    foreign import ccall "g_timer_reset" g_timer_reset ::
        Ptr Timer ->                            -- timer : TInterface (Name {namespace = "GLib", name = "Timer"})
        IO ()

    {- |
    This function is useless; it\'s fine to call 'GI.GLib.Structs.Timer.timerStart' on an
    already-started timer to reset the start time, so 'GI.GLib.Structs.Timer.timerReset'
    serves no purpose.
    -}
    timerReset ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        Timer
        {- ^ /@timer@/: a 'GI.GLib.Structs.Timer.Timer'. -}
        -> m ()
    timerReset timer = liftIO $ do
        timer' <- unsafeManagedPtrGetPtr timer
        g_timer_reset timer'
        touchManagedPtr timer
        return ()

    #if ENABLE_OVERLOADING
    data TimerResetMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo TimerResetMethodInfo Timer signature where
        overloadedMethod _ = timerReset

    #endif

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

    foreign import ccall "g_timer_start" g_timer_start ::
        Ptr Timer ->                            -- timer : TInterface (Name {namespace = "GLib", name = "Timer"})
        IO ()

    {- |
    Marks a start time, so that future calls to 'GI.GLib.Structs.Timer.timerElapsed' will
    report the time since 'GI.GLib.Structs.Timer.timerStart' was called. @/g_timer_new()/@
    automatically marks the start time, so no need to call
    'GI.GLib.Structs.Timer.timerStart' immediately after creating the timer.
    -}
    timerStart ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        Timer
        {- ^ /@timer@/: a 'GI.GLib.Structs.Timer.Timer'. -}
        -> m ()
    timerStart timer = liftIO $ do
        timer' <- unsafeManagedPtrGetPtr timer
        g_timer_start timer'
        touchManagedPtr timer
        return ()

    #if ENABLE_OVERLOADING
    data TimerStartMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo TimerStartMethodInfo Timer signature where
        overloadedMethod _ = timerStart

    #endif

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

    foreign import ccall "g_timer_stop" g_timer_stop ::
        Ptr Timer ->                            -- timer : TInterface (Name {namespace = "GLib", name = "Timer"})
        IO ()

    {- |
    Marks an end time, so calls to 'GI.GLib.Structs.Timer.timerElapsed' will return the
    difference between this end time and the start time.
    -}
    timerStop ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        Timer
        {- ^ /@timer@/: a 'GI.GLib.Structs.Timer.Timer'. -}
        -> m ()
    timerStop timer = liftIO $ do
        timer' <- unsafeManagedPtrGetPtr timer
        g_timer_stop timer'
        touchManagedPtr timer
        return ()

    #if ENABLE_OVERLOADING
    data TimerStopMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo TimerStopMethodInfo Timer signature where
        overloadedMethod _ = timerStop

    #endif

    #if ENABLE_OVERLOADING
    type family ResolveTimerMethod (t :: Symbol) (o :: *) :: * where
        ResolveTimerMethod "continue" o = TimerContinueMethodInfo
        ResolveTimerMethod "destroy" o = TimerDestroyMethodInfo
        ResolveTimerMethod "elapsed" o = TimerElapsedMethodInfo
        ResolveTimerMethod "reset" o = TimerResetMethodInfo
        ResolveTimerMethod "start" o = TimerStartMethodInfo
        ResolveTimerMethod "stop" o = TimerStopMethodInfo
        ResolveTimerMethod l o = O.MethodResolutionFailed l o

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

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