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

    A GPatternSpec struct is the \'compiled\' form of a pattern. This
    structure is opaque and its fields cannot be accessed directly.
    -}

    #define ENABLE_OVERLOADING \
           (!defined(__HADDOCK_VERSION__))

    module GI.GLib.Structs.PatternSpec
        (

    -- * Exported types
        PatternSpec(..)                         ,
        noPatternSpec                           ,

     -- * Methods
    -- ** equal #method:equal#

    #if ENABLE_OVERLOADING
        PatternSpecEqualMethodInfo              ,
    #endif
        patternSpecEqual                        ,

    -- ** free #method:free#

    #if ENABLE_OVERLOADING
        PatternSpecFreeMethodInfo               ,
    #endif
        patternSpecFree                         ,

        ) 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 PatternSpec = PatternSpec (ManagedPtr PatternSpec)
    -- XXX Wrapping a foreign struct/union with no known destructor or size, leak?
    instance WrappedPtr PatternSpec where
        wrappedPtrCalloc = return nullPtr
        wrappedPtrCopy = return
        wrappedPtrFree = Nothing

    -- | A convenience alias for `Nothing` :: `Maybe` `PatternSpec`.
    noPatternSpec :: Maybe PatternSpec
    noPatternSpec = Nothing

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

    -- method PatternSpec::equal
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "pspec1", argType = TInterface (Name {namespace = "GLib", name = "PatternSpec"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GPatternSpec", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "pspec2", argType = TInterface (Name {namespace = "GLib", name = "PatternSpec"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "another #GPatternSpec", 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_pattern_spec_equal" g_pattern_spec_equal ::
        Ptr PatternSpec ->                      -- pspec1 : TInterface (Name {namespace = "GLib", name = "PatternSpec"})
        Ptr PatternSpec ->                      -- pspec2 : TInterface (Name {namespace = "GLib", name = "PatternSpec"})
        IO CInt

    {- |
    Compares two compiled pattern specs and returns whether they will
    match the same set of strings.
    -}
    patternSpecEqual ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        PatternSpec
        {- ^ /@pspec1@/: a 'GI.GLib.Structs.PatternSpec.PatternSpec' -}
        -> PatternSpec
        {- ^ /@pspec2@/: another 'GI.GLib.Structs.PatternSpec.PatternSpec' -}
        -> m Bool
        {- ^ __Returns:__ Whether the compiled patterns are equal -}
    patternSpecEqual pspec1 pspec2 = liftIO $ do
        pspec1' <- unsafeManagedPtrGetPtr pspec1
        pspec2' <- unsafeManagedPtrGetPtr pspec2
        result <- g_pattern_spec_equal pspec1' pspec2'
        let result' = (/= 0) result
        touchManagedPtr pspec1
        touchManagedPtr pspec2
        return result'

    #if ENABLE_OVERLOADING
    data PatternSpecEqualMethodInfo
    instance (signature ~ (PatternSpec -> m Bool), MonadIO m) => O.MethodInfo PatternSpecEqualMethodInfo PatternSpec signature where
        overloadedMethod _ = patternSpecEqual

    #endif

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

    foreign import ccall "g_pattern_spec_free" g_pattern_spec_free ::
        Ptr PatternSpec ->                      -- pspec : TInterface (Name {namespace = "GLib", name = "PatternSpec"})
        IO ()

    {- |
    Frees the memory allocated for the 'GI.GLib.Structs.PatternSpec.PatternSpec'.
    -}
    patternSpecFree ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        PatternSpec
        {- ^ /@pspec@/: a 'GI.GLib.Structs.PatternSpec.PatternSpec' -}
        -> m ()
    patternSpecFree pspec = liftIO $ do
        pspec' <- unsafeManagedPtrGetPtr pspec
        g_pattern_spec_free pspec'
        touchManagedPtr pspec
        return ()

    #if ENABLE_OVERLOADING
    data PatternSpecFreeMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo PatternSpecFreeMethodInfo PatternSpec signature where
        overloadedMethod _ = patternSpecFree

    #endif

    #if ENABLE_OVERLOADING
    type family ResolvePatternSpecMethod (t :: Symbol) (o :: *) :: * where
        ResolvePatternSpecMethod "equal" o = PatternSpecEqualMethodInfo
        ResolvePatternSpecMethod "free" o = PatternSpecFreeMethodInfo
        ResolvePatternSpecMethod l o = O.MethodResolutionFailed l o

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

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