    {- |
    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 @GOptionGroup@ struct defines the options in a single
    group. The struct has only private fields and should not be directly accessed.

    All options in a group share the same translation function. Libraries which
    need to parse commandline options are expected to provide a function for
    getting a @GOptionGroup@ holding their options, which
    the application can then add to its 'GI.GLib.Structs.OptionContext.OptionContext'.
    -}

    #define ENABLE_OVERLOADING \
           (!defined(__HADDOCK_VERSION__))

    module GI.GLib.Structs.OptionGroup
        (

    -- * Exported types
        OptionGroup(..)                         ,
        noOptionGroup                           ,

     -- * Methods
    -- ** addEntries #method:addEntries#

    #if ENABLE_OVERLOADING
        OptionGroupAddEntriesMethodInfo         ,
    #endif
        optionGroupAddEntries                   ,

    -- ** free #method:free#

    #if ENABLE_OVERLOADING
        OptionGroupFreeMethodInfo               ,
    #endif
        optionGroupFree                         ,

    -- ** new #method:new#

        optionGroupNew                          ,

    -- ** ref #method:ref#

    #if ENABLE_OVERLOADING
        OptionGroupRefMethodInfo                ,
    #endif
        optionGroupRef                          ,

    -- ** setTranslateFunc #method:setTranslateFunc#

    #if ENABLE_OVERLOADING
        OptionGroupSetTranslateFuncMethodInfo   ,
    #endif
        optionGroupSetTranslateFunc             ,

    -- ** setTranslationDomain #method:setTranslationDomain#

    #if ENABLE_OVERLOADING
        OptionGroupSetTranslationDomainMethodInfo,
    #endif
        optionGroupSetTranslationDomain         ,

    -- ** unref #method:unref#

    #if ENABLE_OVERLOADING
        OptionGroupUnrefMethodInfo              ,
    #endif
        optionGroupUnref                        ,

        ) 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 qualified GI.GLib.Callbacks as GLib.Callbacks
    import {-# SOURCE #-} qualified GI.GLib.Structs.OptionEntry as GLib.OptionEntry

    -- | Memory-managed wrapper type.
    newtype OptionGroup = OptionGroup (ManagedPtr OptionGroup)
    foreign import ccall "g_option_group_get_type" c_g_option_group_get_type ::
        IO GType

    instance BoxedObject OptionGroup where
        boxedType _ = c_g_option_group_get_type

    -- | A convenience alias for `Nothing` :: `Maybe` `OptionGroup`.
    noOptionGroup :: Maybe OptionGroup
    noOptionGroup = Nothing

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

    -- method OptionGroup::new
    -- method type : Constructor
    -- Args : [Arg {argCName = "name", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the name for the option group, this is used to provide\n  help for the options in this group with `--help-`@name", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "description", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a description for this group to be shown in\n  `--help`. This string is translated using the translation\n  domain or translation function of the group", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "help_description", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a description for the `--help-`@name option.\n  This string is translated using the translation domain or translation function\n  of the group", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "user_data", argType = TBasicType TPtr, direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "user data that will be passed to the pre- and post-parse hooks,\n  the error hook and to callbacks of %G_OPTION_ARG_CALLBACK options, or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "destroy", argType = TInterface (Name {namespace = "GLib", name = "DestroyNotify"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "a function that will be called to free @user_data, or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeAsync, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TInterface (Name {namespace = "GLib", name = "OptionGroup"}))
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_option_group_new" g_option_group_new ::
        CString ->                              -- name : TBasicType TUTF8
        CString ->                              -- description : TBasicType TUTF8
        CString ->                              -- help_description : TBasicType TUTF8
        Ptr () ->                               -- user_data : TBasicType TPtr
        FunPtr GLib.Callbacks.C_DestroyNotify -> -- destroy : TInterface (Name {namespace = "GLib", name = "DestroyNotify"})
        IO (Ptr OptionGroup)

    {- |
    Creates a new 'GI.GLib.Structs.OptionGroup.OptionGroup'.

    /Since: 2.6/
    -}
    optionGroupNew ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        T.Text
        {- ^ /@name@/: the name for the option group, this is used to provide
      help for the options in this group with @--help-@/@name@/ -}
        -> T.Text
        {- ^ /@description@/: a description for this group to be shown in
      @--help@. This string is translated using the translation
      domain or translation function of the group -}
        -> T.Text
        {- ^ /@helpDescription@/: a description for the @--help-@/@name@/ option.
      This string is translated using the translation domain or translation function
      of the group -}
        -> Ptr ()
        {- ^ /@userData@/: user data that will be passed to the pre- and post-parse hooks,
      the error hook and to callbacks of 'GI.GLib.Enums.OptionArgCallback' options, or 'Nothing' -}
        -> Maybe (GLib.Callbacks.DestroyNotify)
        {- ^ /@destroy@/: a function that will be called to free /@userData@/, or 'Nothing' -}
        -> m OptionGroup
        {- ^ __Returns:__ a newly created option group. It should be added
      to a 'GI.GLib.Structs.OptionContext.OptionContext' or freed with 'GI.GLib.Structs.OptionGroup.optionGroupUnref'. -}
    optionGroupNew name description helpDescription userData destroy = liftIO $ do
        name' <- textToCString name
        description' <- textToCString description
        helpDescription' <- textToCString helpDescription
        maybeDestroy <- case destroy of
            Nothing -> return (castPtrToFunPtr nullPtr)
            Just jDestroy -> do
                ptrdestroy <- callocMem :: IO (Ptr (FunPtr GLib.Callbacks.C_DestroyNotify))
                jDestroy' <- GLib.Callbacks.mk_DestroyNotify (GLib.Callbacks.wrap_DestroyNotify (Just ptrdestroy) jDestroy)
                poke ptrdestroy jDestroy'
                return jDestroy'
        result <- g_option_group_new name' description' helpDescription' userData maybeDestroy
        checkUnexpectedReturnNULL "optionGroupNew" result
        result' <- (wrapBoxed OptionGroup) result
        freeMem name'
        freeMem description'
        freeMem helpDescription'
        return result'

    #if ENABLE_OVERLOADING
    #endif

    -- method OptionGroup::add_entries
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "group", argType = TInterface (Name {namespace = "GLib", name = "OptionGroup"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GOptionGroup", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "entries", argType = TInterface (Name {namespace = "GLib", name = "OptionEntry"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a %NULL-terminated array of #GOptionEntrys", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_option_group_add_entries" g_option_group_add_entries ::
        Ptr OptionGroup ->                      -- group : TInterface (Name {namespace = "GLib", name = "OptionGroup"})
        Ptr GLib.OptionEntry.OptionEntry ->     -- entries : TInterface (Name {namespace = "GLib", name = "OptionEntry"})
        IO ()

    {- |
    Adds the options specified in /@entries@/ to /@group@/.

    /Since: 2.6/
    -}
    optionGroupAddEntries ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        OptionGroup
        {- ^ /@group@/: a 'GI.GLib.Structs.OptionGroup.OptionGroup' -}
        -> GLib.OptionEntry.OptionEntry
        {- ^ /@entries@/: a 'Nothing'-terminated array of @/GOptionEntrys/@ -}
        -> m ()
    optionGroupAddEntries group entries = liftIO $ do
        group' <- unsafeManagedPtrGetPtr group
        entries' <- unsafeManagedPtrGetPtr entries
        g_option_group_add_entries group' entries'
        touchManagedPtr group
        touchManagedPtr entries
        return ()

    #if ENABLE_OVERLOADING
    data OptionGroupAddEntriesMethodInfo
    instance (signature ~ (GLib.OptionEntry.OptionEntry -> m ()), MonadIO m) => O.MethodInfo OptionGroupAddEntriesMethodInfo OptionGroup signature where
        overloadedMethod _ = optionGroupAddEntries

    #endif

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

    foreign import ccall "g_option_group_free" g_option_group_free ::
        Ptr OptionGroup ->                      -- group : TInterface (Name {namespace = "GLib", name = "OptionGroup"})
        IO ()

    {-# DEPRECATED optionGroupFree ["(Since version 2.44)","Use 'GI.GLib.Structs.OptionGroup.optionGroupUnref' instead."] #-}
    {- |
    Frees a 'GI.GLib.Structs.OptionGroup.OptionGroup'. Note that you must not free groups
    which have been added to a 'GI.GLib.Structs.OptionContext.OptionContext'.

    /Since: 2.6/
    -}
    optionGroupFree ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        OptionGroup
        {- ^ /@group@/: a 'GI.GLib.Structs.OptionGroup.OptionGroup' -}
        -> m ()
    optionGroupFree group = liftIO $ do
        group' <- unsafeManagedPtrGetPtr group
        g_option_group_free group'
        touchManagedPtr group
        return ()

    #if ENABLE_OVERLOADING
    data OptionGroupFreeMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo OptionGroupFreeMethodInfo OptionGroup signature where
        overloadedMethod _ = optionGroupFree

    #endif

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

    foreign import ccall "g_option_group_ref" g_option_group_ref ::
        Ptr OptionGroup ->                      -- group : TInterface (Name {namespace = "GLib", name = "OptionGroup"})
        IO (Ptr OptionGroup)

    {- |
    Increments the reference count of /@group@/ by one.

    /Since: 2.44/
    -}
    optionGroupRef ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        OptionGroup
        {- ^ /@group@/: a 'GI.GLib.Structs.OptionGroup.OptionGroup' -}
        -> m OptionGroup
        {- ^ __Returns:__ a 'GI.GLib.Structs.OptionGroup.OptionGroup' -}
    optionGroupRef group = liftIO $ do
        group' <- unsafeManagedPtrGetPtr group
        result <- g_option_group_ref group'
        checkUnexpectedReturnNULL "optionGroupRef" result
        result' <- (wrapBoxed OptionGroup) result
        touchManagedPtr group
        return result'

    #if ENABLE_OVERLOADING
    data OptionGroupRefMethodInfo
    instance (signature ~ (m OptionGroup), MonadIO m) => O.MethodInfo OptionGroupRefMethodInfo OptionGroup signature where
        overloadedMethod _ = optionGroupRef

    #endif

    -- method OptionGroup::set_translate_func
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "group", argType = TInterface (Name {namespace = "GLib", name = "OptionGroup"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GOptionGroup", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "func", argType = TInterface (Name {namespace = "GLib", name = "TranslateFunc"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "the #GTranslateFunc, or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeNotified, argClosure = 2, argDestroy = 3, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "data", argType = TBasicType TPtr, direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "user data to pass to @func, or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "destroy_notify", argType = TInterface (Name {namespace = "GLib", name = "DestroyNotify"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "a function which gets called to free @data, or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeAsync, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_option_group_set_translate_func" g_option_group_set_translate_func ::
        Ptr OptionGroup ->                      -- group : TInterface (Name {namespace = "GLib", name = "OptionGroup"})
        FunPtr GLib.Callbacks.C_TranslateFunc -> -- func : TInterface (Name {namespace = "GLib", name = "TranslateFunc"})
        Ptr () ->                               -- data : TBasicType TPtr
        FunPtr GLib.Callbacks.C_DestroyNotify -> -- destroy_notify : TInterface (Name {namespace = "GLib", name = "DestroyNotify"})
        IO ()

    {- |
    Sets the function which is used to translate user-visible strings,
    for @--help@ output. Different groups can use different
    @/GTranslateFuncs/@. If /@func@/ is 'Nothing', strings are not translated.

    If you are using @/gettext()/@, you only need to set the translation
    domain, see 'GI.GLib.Structs.OptionGroup.optionGroupSetTranslationDomain'.

    /Since: 2.6/
    -}
    optionGroupSetTranslateFunc ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        OptionGroup
        {- ^ /@group@/: a 'GI.GLib.Structs.OptionGroup.OptionGroup' -}
        -> Maybe (GLib.Callbacks.TranslateFunc)
        {- ^ /@func@/: the 'GI.GLib.Callbacks.TranslateFunc', or 'Nothing' -}
        -> m ()
    optionGroupSetTranslateFunc group func = liftIO $ do
        group' <- unsafeManagedPtrGetPtr group
        maybeFunc <- case func of
            Nothing -> return (castPtrToFunPtr nullPtr)
            Just jFunc -> do
                jFunc' <- GLib.Callbacks.mk_TranslateFunc (GLib.Callbacks.wrap_TranslateFunc Nothing jFunc)
                return jFunc'
        let data_ = castFunPtrToPtr maybeFunc
        let destroyNotify = safeFreeFunPtrPtr
        g_option_group_set_translate_func group' maybeFunc data_ destroyNotify
        touchManagedPtr group
        return ()

    #if ENABLE_OVERLOADING
    data OptionGroupSetTranslateFuncMethodInfo
    instance (signature ~ (Maybe (GLib.Callbacks.TranslateFunc) -> m ()), MonadIO m) => O.MethodInfo OptionGroupSetTranslateFuncMethodInfo OptionGroup signature where
        overloadedMethod _ = optionGroupSetTranslateFunc

    #endif

    -- method OptionGroup::set_translation_domain
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "group", argType = TInterface (Name {namespace = "GLib", name = "OptionGroup"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GOptionGroup", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "domain", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the domain to use", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_option_group_set_translation_domain" g_option_group_set_translation_domain ::
        Ptr OptionGroup ->                      -- group : TInterface (Name {namespace = "GLib", name = "OptionGroup"})
        CString ->                              -- domain : TBasicType TUTF8
        IO ()

    {- |
    A convenience function to use @/gettext()/@ for translating
    user-visible strings.

    /Since: 2.6/
    -}
    optionGroupSetTranslationDomain ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        OptionGroup
        {- ^ /@group@/: a 'GI.GLib.Structs.OptionGroup.OptionGroup' -}
        -> T.Text
        {- ^ /@domain@/: the domain to use -}
        -> m ()
    optionGroupSetTranslationDomain group domain = liftIO $ do
        group' <- unsafeManagedPtrGetPtr group
        domain' <- textToCString domain
        g_option_group_set_translation_domain group' domain'
        touchManagedPtr group
        freeMem domain'
        return ()

    #if ENABLE_OVERLOADING
    data OptionGroupSetTranslationDomainMethodInfo
    instance (signature ~ (T.Text -> m ()), MonadIO m) => O.MethodInfo OptionGroupSetTranslationDomainMethodInfo OptionGroup signature where
        overloadedMethod _ = optionGroupSetTranslationDomain

    #endif

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

    foreign import ccall "g_option_group_unref" g_option_group_unref ::
        Ptr OptionGroup ->                      -- group : TInterface (Name {namespace = "GLib", name = "OptionGroup"})
        IO ()

    {- |
    Decrements the reference count of /@group@/ by one.
    If the reference count drops to 0, the /@group@/ will be freed.
    and all memory allocated by the /@group@/ is released.

    /Since: 2.44/
    -}
    optionGroupUnref ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        OptionGroup
        {- ^ /@group@/: a 'GI.GLib.Structs.OptionGroup.OptionGroup' -}
        -> m ()
    optionGroupUnref group = liftIO $ do
        group' <- unsafeManagedPtrGetPtr group
        g_option_group_unref group'
        touchManagedPtr group
        return ()

    #if ENABLE_OVERLOADING
    data OptionGroupUnrefMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo OptionGroupUnrefMethodInfo OptionGroup signature where
        overloadedMethod _ = optionGroupUnref

    #endif

    #if ENABLE_OVERLOADING
    type family ResolveOptionGroupMethod (t :: Symbol) (o :: *) :: * where
        ResolveOptionGroupMethod "addEntries" o = OptionGroupAddEntriesMethodInfo
        ResolveOptionGroupMethod "free" o = OptionGroupFreeMethodInfo
        ResolveOptionGroupMethod "ref" o = OptionGroupRefMethodInfo
        ResolveOptionGroupMethod "unref" o = OptionGroupUnrefMethodInfo
        ResolveOptionGroupMethod "setTranslateFunc" o = OptionGroupSetTranslateFuncMethodInfo
        ResolveOptionGroupMethod "setTranslationDomain" o = OptionGroupSetTranslationDomainMethodInfo
        ResolveOptionGroupMethod l o = O.MethodResolutionFailed l o

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

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