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

Monitors a file or directory for changes.

To obtain a 'GI.Gio.Objects.FileMonitor.FileMonitor' for a file or directory, use
'GI.Gio.Interfaces.File.fileMonitor', 'GI.Gio.Interfaces.File.fileMonitorFile', or
'GI.Gio.Interfaces.File.fileMonitorDirectory'.

To get informed about changes to the file or directory you are
monitoring, connect to the 'GI.Gio.Objects.FileMonitor.FileMonitor'::@/changed/@ signal. The
signal will be emitted in the
[thread-default main context][g-main-context-push-thread-default]
of the thread that the monitor was created in
(though if the global default main context is blocked, this may
cause notifications to be blocked even if the thread-default
context is still running).
-}

module GI.Gio.Objects.FileMonitor
    ( 

-- * Exported types
    FileMonitor(..)                         ,
    IsFileMonitor                           ,
    toFileMonitor                           ,
    noFileMonitor                           ,


 -- * Methods
-- ** cancel #method:cancel#
    FileMonitorCancelMethodInfo             ,
    fileMonitorCancel                       ,


-- ** emitEvent #method:emitEvent#
    FileMonitorEmitEventMethodInfo          ,
    fileMonitorEmitEvent                    ,


-- ** isCancelled #method:isCancelled#
    FileMonitorIsCancelledMethodInfo        ,
    fileMonitorIsCancelled                  ,


-- ** setRateLimit #method:setRateLimit#
    FileMonitorSetRateLimitMethodInfo       ,
    fileMonitorSetRateLimit                 ,




 -- * Properties
-- ** cancelled #attr:cancelled#
    FileMonitorCancelledPropertyInfo        ,
    fileMonitorCancelled                    ,
    getFileMonitorCancelled                 ,


-- ** rateLimit #attr:rateLimit#
    FileMonitorRateLimitPropertyInfo        ,
    constructFileMonitorRateLimit           ,
    fileMonitorRateLimit                    ,
    getFileMonitorRateLimit                 ,
    setFileMonitorRateLimit                 ,




 -- * Signals
-- ** changed #signal:changed#
    C_FileMonitorChangedCallback            ,
    FileMonitorChangedCallback              ,
    FileMonitorChangedSignalInfo            ,
    afterFileMonitorChanged                 ,
    genClosure_FileMonitorChanged           ,
    mk_FileMonitorChangedCallback           ,
    noFileMonitorChangedCallback            ,
    onFileMonitorChanged                    ,
    wrap_FileMonitorChangedCallback         ,




    ) 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.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 {-# SOURCE #-} qualified GI.Gio.Enums as Gio.Enums
import {-# SOURCE #-} qualified GI.Gio.Interfaces.File as Gio.File

newtype FileMonitor = FileMonitor (ManagedPtr FileMonitor)
foreign import ccall "g_file_monitor_get_type"
    c_g_file_monitor_get_type :: IO GType

instance GObject FileMonitor where
    gobjectType _ = c_g_file_monitor_get_type
    

class GObject o => IsFileMonitor o
#if MIN_VERSION_base(4,9,0)
instance {-# OVERLAPPABLE #-} (GObject a, O.UnknownAncestorError FileMonitor a) =>
    IsFileMonitor a
#endif
instance IsFileMonitor FileMonitor
instance GObject.Object.IsObject FileMonitor

toFileMonitor :: IsFileMonitor o => o -> IO FileMonitor
toFileMonitor = unsafeCastTo FileMonitor

noFileMonitor :: Maybe FileMonitor
noFileMonitor = Nothing

type family ResolveFileMonitorMethod (t :: Symbol) (o :: *) :: * where
    ResolveFileMonitorMethod "bindProperty" o = GObject.Object.ObjectBindPropertyMethodInfo
    ResolveFileMonitorMethod "bindPropertyFull" o = GObject.Object.ObjectBindPropertyFullMethodInfo
    ResolveFileMonitorMethod "cancel" o = FileMonitorCancelMethodInfo
    ResolveFileMonitorMethod "emitEvent" o = FileMonitorEmitEventMethodInfo
    ResolveFileMonitorMethod "forceFloating" o = GObject.Object.ObjectForceFloatingMethodInfo
    ResolveFileMonitorMethod "freezeNotify" o = GObject.Object.ObjectFreezeNotifyMethodInfo
    ResolveFileMonitorMethod "isCancelled" o = FileMonitorIsCancelledMethodInfo
    ResolveFileMonitorMethod "isFloating" o = GObject.Object.ObjectIsFloatingMethodInfo
    ResolveFileMonitorMethod "notify" o = GObject.Object.ObjectNotifyMethodInfo
    ResolveFileMonitorMethod "notifyByPspec" o = GObject.Object.ObjectNotifyByPspecMethodInfo
    ResolveFileMonitorMethod "ref" o = GObject.Object.ObjectRefMethodInfo
    ResolveFileMonitorMethod "refSink" o = GObject.Object.ObjectRefSinkMethodInfo
    ResolveFileMonitorMethod "replaceData" o = GObject.Object.ObjectReplaceDataMethodInfo
    ResolveFileMonitorMethod "replaceQdata" o = GObject.Object.ObjectReplaceQdataMethodInfo
    ResolveFileMonitorMethod "runDispose" o = GObject.Object.ObjectRunDisposeMethodInfo
    ResolveFileMonitorMethod "stealData" o = GObject.Object.ObjectStealDataMethodInfo
    ResolveFileMonitorMethod "stealQdata" o = GObject.Object.ObjectStealQdataMethodInfo
    ResolveFileMonitorMethod "thawNotify" o = GObject.Object.ObjectThawNotifyMethodInfo
    ResolveFileMonitorMethod "unref" o = GObject.Object.ObjectUnrefMethodInfo
    ResolveFileMonitorMethod "watchClosure" o = GObject.Object.ObjectWatchClosureMethodInfo
    ResolveFileMonitorMethod "getData" o = GObject.Object.ObjectGetDataMethodInfo
    ResolveFileMonitorMethod "getProperty" o = GObject.Object.ObjectGetPropertyMethodInfo
    ResolveFileMonitorMethod "getQdata" o = GObject.Object.ObjectGetQdataMethodInfo
    ResolveFileMonitorMethod "setData" o = GObject.Object.ObjectSetDataMethodInfo
    ResolveFileMonitorMethod "setProperty" o = GObject.Object.ObjectSetPropertyMethodInfo
    ResolveFileMonitorMethod "setRateLimit" o = FileMonitorSetRateLimitMethodInfo
    ResolveFileMonitorMethod l o = O.MethodResolutionFailed l o

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

#if MIN_VERSION_base(4,9,0)
instance (info ~ ResolveFileMonitorMethod t FileMonitor, O.MethodInfo info FileMonitor p) => O.IsLabel t (FileMonitor -> p) where
    fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#endif

-- signal FileMonitor::changed
type FileMonitorChangedCallback =
    Gio.File.File ->
    Maybe Gio.File.File ->
    Gio.Enums.FileMonitorEvent ->
    IO ()

noFileMonitorChangedCallback :: Maybe FileMonitorChangedCallback
noFileMonitorChangedCallback = Nothing

type C_FileMonitorChangedCallback =
    Ptr () ->                               -- object
    Ptr Gio.File.File ->
    Ptr Gio.File.File ->
    CUInt ->
    Ptr () ->                               -- user_data
    IO ()

foreign import ccall "wrapper"
    mk_FileMonitorChangedCallback :: C_FileMonitorChangedCallback -> IO (FunPtr C_FileMonitorChangedCallback)

genClosure_FileMonitorChanged :: FileMonitorChangedCallback -> IO Closure
genClosure_FileMonitorChanged cb = do
    let cb' = wrap_FileMonitorChangedCallback cb
    mk_FileMonitorChangedCallback cb' >>= newCClosure


wrap_FileMonitorChangedCallback ::
    FileMonitorChangedCallback ->
    Ptr () ->
    Ptr Gio.File.File ->
    Ptr Gio.File.File ->
    CUInt ->
    Ptr () ->
    IO ()
wrap_FileMonitorChangedCallback _cb _ file otherFile eventType _ = do
    file' <- (newObject Gio.File.File) file
    maybeOtherFile <-
        if otherFile == nullPtr
        then return Nothing
        else do
            otherFile' <- (newObject Gio.File.File) otherFile
            return $ Just otherFile'
    let eventType' = (toEnum . fromIntegral) eventType
    _cb  file' maybeOtherFile eventType'


onFileMonitorChanged :: (GObject a, MonadIO m) => a -> FileMonitorChangedCallback -> m SignalHandlerId
onFileMonitorChanged obj cb = liftIO $ connectFileMonitorChanged obj cb SignalConnectBefore
afterFileMonitorChanged :: (GObject a, MonadIO m) => a -> FileMonitorChangedCallback -> m SignalHandlerId
afterFileMonitorChanged obj cb = connectFileMonitorChanged obj cb SignalConnectAfter

connectFileMonitorChanged :: (GObject a, MonadIO m) =>
                             a -> FileMonitorChangedCallback -> SignalConnectMode -> m SignalHandlerId
connectFileMonitorChanged obj cb after = liftIO $ do
    let cb' = wrap_FileMonitorChangedCallback cb
    cb'' <- mk_FileMonitorChangedCallback cb'
    connectSignalFunPtr obj "changed" cb'' after

-- VVV Prop "cancelled"
   -- Type: TBasicType TBoolean
   -- Flags: [PropertyReadable]
   -- Nullable: (Nothing,Nothing)

getFileMonitorCancelled :: (MonadIO m, IsFileMonitor o) => o -> m Bool
getFileMonitorCancelled obj = liftIO $ getObjectPropertyBool obj "cancelled"

data FileMonitorCancelledPropertyInfo
instance AttrInfo FileMonitorCancelledPropertyInfo where
    type AttrAllowedOps FileMonitorCancelledPropertyInfo = '[ 'AttrGet]
    type AttrSetTypeConstraint FileMonitorCancelledPropertyInfo = (~) ()
    type AttrBaseTypeConstraint FileMonitorCancelledPropertyInfo = IsFileMonitor
    type AttrGetType FileMonitorCancelledPropertyInfo = Bool
    type AttrLabel FileMonitorCancelledPropertyInfo = "cancelled"
    type AttrOrigin FileMonitorCancelledPropertyInfo = FileMonitor
    attrGet _ = getFileMonitorCancelled
    attrSet _ = undefined
    attrConstruct _ = undefined
    attrClear _ = undefined

-- VVV Prop "rate-limit"
   -- Type: TBasicType TInt
   -- Flags: [PropertyReadable,PropertyWritable]
   -- Nullable: (Nothing,Just False)

getFileMonitorRateLimit :: (MonadIO m, IsFileMonitor o) => o -> m Int32
getFileMonitorRateLimit obj = liftIO $ getObjectPropertyInt32 obj "rate-limit"

setFileMonitorRateLimit :: (MonadIO m, IsFileMonitor o) => o -> Int32 -> m ()
setFileMonitorRateLimit obj val = liftIO $ setObjectPropertyInt32 obj "rate-limit" val

constructFileMonitorRateLimit :: (IsFileMonitor o) => Int32 -> IO (GValueConstruct o)
constructFileMonitorRateLimit val = constructObjectPropertyInt32 "rate-limit" val

data FileMonitorRateLimitPropertyInfo
instance AttrInfo FileMonitorRateLimitPropertyInfo where
    type AttrAllowedOps FileMonitorRateLimitPropertyInfo = '[ 'AttrSet, 'AttrConstruct, 'AttrGet]
    type AttrSetTypeConstraint FileMonitorRateLimitPropertyInfo = (~) Int32
    type AttrBaseTypeConstraint FileMonitorRateLimitPropertyInfo = IsFileMonitor
    type AttrGetType FileMonitorRateLimitPropertyInfo = Int32
    type AttrLabel FileMonitorRateLimitPropertyInfo = "rate-limit"
    type AttrOrigin FileMonitorRateLimitPropertyInfo = FileMonitor
    attrGet _ = getFileMonitorRateLimit
    attrSet _ = setFileMonitorRateLimit
    attrConstruct _ = constructFileMonitorRateLimit
    attrClear _ = undefined

instance O.HasAttributeList FileMonitor
type instance O.AttributeList FileMonitor = FileMonitorAttributeList
type FileMonitorAttributeList = ('[ '("cancelled", FileMonitorCancelledPropertyInfo), '("rateLimit", FileMonitorRateLimitPropertyInfo)] :: [(Symbol, *)])

fileMonitorCancelled :: AttrLabelProxy "cancelled"
fileMonitorCancelled = AttrLabelProxy

fileMonitorRateLimit :: AttrLabelProxy "rateLimit"
fileMonitorRateLimit = AttrLabelProxy

data FileMonitorChangedSignalInfo
instance SignalInfo FileMonitorChangedSignalInfo where
    type HaskellCallbackType FileMonitorChangedSignalInfo = FileMonitorChangedCallback
    connectSignal _ = connectFileMonitorChanged

type instance O.SignalList FileMonitor = FileMonitorSignalList
type FileMonitorSignalList = ('[ '("changed", FileMonitorChangedSignalInfo), '("notify", GObject.Object.ObjectNotifySignalInfo)] :: [(Symbol, *)])

-- method FileMonitor::cancel
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "monitor", argType = TInterface (Name {namespace = "Gio", name = "FileMonitor"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GFileMonitor.", 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_file_monitor_cancel" g_file_monitor_cancel :: 
    Ptr FileMonitor ->                      -- monitor : TInterface (Name {namespace = "Gio", name = "FileMonitor"})
    IO CInt

{- |
Cancels a file monitor.
-}
fileMonitorCancel ::
    (B.CallStack.HasCallStack, MonadIO m, IsFileMonitor a) =>
    a
    {- ^ /@monitor@/: a 'GI.Gio.Objects.FileMonitor.FileMonitor'. -}
    -> m Bool
    {- ^ __Returns:__ always 'True' -}
fileMonitorCancel monitor = liftIO $ do
    monitor' <- unsafeManagedPtrCastPtr monitor
    result <- g_file_monitor_cancel monitor'
    let result' = (/= 0) result
    touchManagedPtr monitor
    return result'

data FileMonitorCancelMethodInfo
instance (signature ~ (m Bool), MonadIO m, IsFileMonitor a) => O.MethodInfo FileMonitorCancelMethodInfo a signature where
    overloadedMethod _ = fileMonitorCancel

-- method FileMonitor::emit_event
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "monitor", argType = TInterface (Name {namespace = "Gio", name = "FileMonitor"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GFileMonitor.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "child", argType = TInterface (Name {namespace = "Gio", name = "File"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GFile.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "other_file", argType = TInterface (Name {namespace = "Gio", name = "File"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GFile.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "event_type", argType = TInterface (Name {namespace = "Gio", name = "FileMonitorEvent"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a set of #GFileMonitorEvent flags.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "g_file_monitor_emit_event" g_file_monitor_emit_event :: 
    Ptr FileMonitor ->                      -- monitor : TInterface (Name {namespace = "Gio", name = "FileMonitor"})
    Ptr Gio.File.File ->                    -- child : TInterface (Name {namespace = "Gio", name = "File"})
    Ptr Gio.File.File ->                    -- other_file : TInterface (Name {namespace = "Gio", name = "File"})
    CUInt ->                                -- event_type : TInterface (Name {namespace = "Gio", name = "FileMonitorEvent"})
    IO ()

{- |
Emits the 'GI.Gio.Objects.FileMonitor.FileMonitor'::@/changed/@ signal if a change
has taken place. Should be called from file monitor
implementations only.

Implementations are responsible to call this method from the
[thread-default main context][g-main-context-push-thread-default] of the
thread that the monitor was created in.
-}
fileMonitorEmitEvent ::
    (B.CallStack.HasCallStack, MonadIO m, IsFileMonitor a, Gio.File.IsFile b, Gio.File.IsFile c) =>
    a
    {- ^ /@monitor@/: a 'GI.Gio.Objects.FileMonitor.FileMonitor'. -}
    -> b
    {- ^ /@child@/: a 'GI.Gio.Interfaces.File.File'. -}
    -> c
    {- ^ /@otherFile@/: a 'GI.Gio.Interfaces.File.File'. -}
    -> Gio.Enums.FileMonitorEvent
    {- ^ /@eventType@/: a set of 'GI.Gio.Enums.FileMonitorEvent' flags. -}
    -> m ()
fileMonitorEmitEvent monitor child otherFile eventType = liftIO $ do
    monitor' <- unsafeManagedPtrCastPtr monitor
    child' <- unsafeManagedPtrCastPtr child
    otherFile' <- unsafeManagedPtrCastPtr otherFile
    let eventType' = (fromIntegral . fromEnum) eventType
    g_file_monitor_emit_event monitor' child' otherFile' eventType'
    touchManagedPtr monitor
    touchManagedPtr child
    touchManagedPtr otherFile
    return ()

data FileMonitorEmitEventMethodInfo
instance (signature ~ (b -> c -> Gio.Enums.FileMonitorEvent -> m ()), MonadIO m, IsFileMonitor a, Gio.File.IsFile b, Gio.File.IsFile c) => O.MethodInfo FileMonitorEmitEventMethodInfo a signature where
    overloadedMethod _ = fileMonitorEmitEvent

-- method FileMonitor::is_cancelled
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "monitor", argType = TInterface (Name {namespace = "Gio", name = "FileMonitor"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GFileMonitor", 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_file_monitor_is_cancelled" g_file_monitor_is_cancelled :: 
    Ptr FileMonitor ->                      -- monitor : TInterface (Name {namespace = "Gio", name = "FileMonitor"})
    IO CInt

{- |
Returns whether the monitor is canceled.
-}
fileMonitorIsCancelled ::
    (B.CallStack.HasCallStack, MonadIO m, IsFileMonitor a) =>
    a
    {- ^ /@monitor@/: a 'GI.Gio.Objects.FileMonitor.FileMonitor' -}
    -> m Bool
    {- ^ __Returns:__ 'True' if monitor is canceled. 'False' otherwise. -}
fileMonitorIsCancelled monitor = liftIO $ do
    monitor' <- unsafeManagedPtrCastPtr monitor
    result <- g_file_monitor_is_cancelled monitor'
    let result' = (/= 0) result
    touchManagedPtr monitor
    return result'

data FileMonitorIsCancelledMethodInfo
instance (signature ~ (m Bool), MonadIO m, IsFileMonitor a) => O.MethodInfo FileMonitorIsCancelledMethodInfo a signature where
    overloadedMethod _ = fileMonitorIsCancelled

-- method FileMonitor::set_rate_limit
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "monitor", argType = TInterface (Name {namespace = "Gio", name = "FileMonitor"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GFileMonitor.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "limit_msecs", argType = TBasicType TInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a non-negative integer with the limit in milliseconds\n    to poll for changes", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "g_file_monitor_set_rate_limit" g_file_monitor_set_rate_limit :: 
    Ptr FileMonitor ->                      -- monitor : TInterface (Name {namespace = "Gio", name = "FileMonitor"})
    Int32 ->                                -- limit_msecs : TBasicType TInt
    IO ()

{- |
Sets the rate limit to which the /@monitor@/ will report
consecutive change events to the same file.
-}
fileMonitorSetRateLimit ::
    (B.CallStack.HasCallStack, MonadIO m, IsFileMonitor a) =>
    a
    {- ^ /@monitor@/: a 'GI.Gio.Objects.FileMonitor.FileMonitor'. -}
    -> Int32
    {- ^ /@limitMsecs@/: a non-negative integer with the limit in milliseconds
    to poll for changes -}
    -> m ()
fileMonitorSetRateLimit monitor limitMsecs = liftIO $ do
    monitor' <- unsafeManagedPtrCastPtr monitor
    g_file_monitor_set_rate_limit monitor' limitMsecs
    touchManagedPtr monitor
    return ()

data FileMonitorSetRateLimitMethodInfo
instance (signature ~ (Int32 -> m ()), MonadIO m, IsFileMonitor a) => O.MethodInfo FileMonitorSetRateLimitMethodInfo a signature where
    overloadedMethod _ = fileMonitorSetRateLimit