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

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

#define ENABLE_OVERLOADING (MIN_VERSION_haskell_gi_overloading(1,0,0) \
       && !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.GClosure as B.GClosure
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.GI.Base.Properties as B.Properties
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 GHC.OverloadedLabels as OL


-- | 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) => OL.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