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

    The 'GI.Pango.Structs.AttrString.AttrString' structure is used to represent attributes with
    a string value.
    -}

    #define ENABLE_OVERLOADING \
           (!defined(__HADDOCK_VERSION__))

    module GI.Pango.Structs.AttrString
        (

    -- * Exported types
        AttrString(..)                          ,
        newZeroAttrString                       ,
        noAttrString                            ,

     -- * Properties
    -- ** attr #attr:attr#
    {- | the common portion of the attribute
    -}
    #if ENABLE_OVERLOADING
        attrString_attr                         ,
    #endif
        getAttrStringAttr                       ,

    -- ** value #attr:value#
    {- | the string which is the value of the attribute
    -}
    #if ENABLE_OVERLOADING
        attrString_value                        ,
    #endif
        clearAttrStringValue                    ,
        getAttrStringValue                      ,
        setAttrStringValue                      ,

        ) 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 {-# SOURCE #-} qualified GI.Pango.Structs.Attribute as Pango.Attribute

    -- | Memory-managed wrapper type.
    newtype AttrString = AttrString (ManagedPtr AttrString)
    instance WrappedPtr AttrString where
        wrappedPtrCalloc = callocBytes 24
        wrappedPtrCopy = \p -> withManagedPtr p (copyBytes 24 >=> wrapPtr AttrString)
        wrappedPtrFree = Just ptr_to_g_free

    -- | Construct a `AttrString` struct initialized to zero.
    newZeroAttrString :: MonadIO m => m AttrString
    newZeroAttrString = liftIO $ wrappedPtrCalloc >>= wrapPtr AttrString

    instance tag ~ 'AttrSet => Constructible AttrString tag where
        new _ attrs = do
            o <- newZeroAttrString
            GI.Attributes.set o attrs
            return o

    -- | A convenience alias for `Nothing` :: `Maybe` `AttrString`.
    noAttrString :: Maybe AttrString
    noAttrString = Nothing

    {- |
    Get the value of the “@attr@” field.
    When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

    @
    'Data.GI.Base.Attributes.get' attrString #attr
    @
    -}
    getAttrStringAttr :: MonadIO m => AttrString -> m Pango.Attribute.Attribute
    getAttrStringAttr s = liftIO $ withManagedPtr s $ \ptr -> do
        let val = ptr `plusPtr` 0 :: (Ptr Pango.Attribute.Attribute)
        val' <- (newPtr Pango.Attribute.Attribute) val
        return val'

    #if ENABLE_OVERLOADING
    data AttrStringAttrFieldInfo
    instance AttrInfo AttrStringAttrFieldInfo where
        type AttrAllowedOps AttrStringAttrFieldInfo = '[ 'AttrGet]
        type AttrSetTypeConstraint AttrStringAttrFieldInfo = (~) (Ptr Pango.Attribute.Attribute)
        type AttrBaseTypeConstraint AttrStringAttrFieldInfo = (~) AttrString
        type AttrGetType AttrStringAttrFieldInfo = Pango.Attribute.Attribute
        type AttrLabel AttrStringAttrFieldInfo = "attr"
        type AttrOrigin AttrStringAttrFieldInfo = AttrString
        attrGet _ = getAttrStringAttr
        attrSet _ = undefined
        attrConstruct = undefined
        attrClear _ = undefined

    attrString_attr :: AttrLabelProxy "attr"
    attrString_attr = AttrLabelProxy

    #endif

    {- |
    Get the value of the “@value@” field.
    When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

    @
    'Data.GI.Base.Attributes.get' attrString #value
    @
    -}
    getAttrStringValue :: MonadIO m => AttrString -> m (Maybe T.Text)
    getAttrStringValue s = liftIO $ withManagedPtr s $ \ptr -> do
        val <- peek (ptr `plusPtr` 16) :: IO CString
        result <- SP.convertIfNonNull val $ \val' -> do
            val'' <- cstringToText val'
            return val''
        return result

    {- |
    Set the value of the “@value@” field.
    When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

    @
    'Data.GI.Base.Attributes.set' attrString [ #value 'Data.GI.Base.Attributes.:=' value ]
    @
    -}
    setAttrStringValue :: MonadIO m => AttrString -> CString -> m ()
    setAttrStringValue s val = liftIO $ withManagedPtr s $ \ptr -> do
        poke (ptr `plusPtr` 16) (val :: CString)

    {- |
    Set the value of the “@value@” field to `Nothing`.
    When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

    @
    'Data.GI.Base.Attributes.clear' #value
    @
    -}
    clearAttrStringValue :: MonadIO m => AttrString -> m ()
    clearAttrStringValue s = liftIO $ withManagedPtr s $ \ptr -> do
        poke (ptr `plusPtr` 16) (FP.nullPtr :: CString)

    #if ENABLE_OVERLOADING
    data AttrStringValueFieldInfo
    instance AttrInfo AttrStringValueFieldInfo where
        type AttrAllowedOps AttrStringValueFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
        type AttrSetTypeConstraint AttrStringValueFieldInfo = (~) CString
        type AttrBaseTypeConstraint AttrStringValueFieldInfo = (~) AttrString
        type AttrGetType AttrStringValueFieldInfo = Maybe T.Text
        type AttrLabel AttrStringValueFieldInfo = "value"
        type AttrOrigin AttrStringValueFieldInfo = AttrString
        attrGet _ = getAttrStringValue
        attrSet _ = setAttrStringValue
        attrConstruct = undefined
        attrClear _ = clearAttrStringValue

    attrString_value :: AttrLabelProxy "value"
    attrString_value = AttrLabelProxy

    #endif

    #if ENABLE_OVERLOADING
    instance O.HasAttributeList AttrString
    type instance O.AttributeList AttrString = AttrStringAttributeList
    type AttrStringAttributeList = ('[ '("attr", AttrStringAttrFieldInfo), '("value", AttrStringValueFieldInfo)] :: [(Symbol, *)])
    #endif

    #if ENABLE_OVERLOADING
    type family ResolveAttrStringMethod (t :: Symbol) (o :: *) :: * where
        ResolveAttrStringMethod l o = O.MethodResolutionFailed l o

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

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