{- |
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.AttrIterator.AttrIterator' structure is used to represent an
iterator through a 'GI.Pango.Structs.AttrList.AttrList'. A new iterator is created
with @/pango_attr_list_get_iterator()/@. Once the iterator
is created, it can be advanced through the style changes
in the text using 'GI.Pango.Structs.AttrIterator.attrIteratorNext'. At each
style change, the range of the current style segment and the
attributes currently in effect can be queried.
-}

#define ENABLE_OVERLOADING (MIN_VERSION_haskell_gi_overloading(1,0,0) \
       && !defined(__HADDOCK_VERSION__))

module GI.Pango.Structs.AttrIterator
    (

-- * Exported types
    AttrIterator(..)                        ,
    noAttrIterator                          ,


 -- * Methods
-- ** destroy #method:destroy#

#if ENABLE_OVERLOADING
    AttrIteratorDestroyMethodInfo           ,
#endif
    attrIteratorDestroy                     ,


-- ** getAttrs #method:getAttrs#

#if ENABLE_OVERLOADING
    AttrIteratorGetAttrsMethodInfo          ,
#endif
    attrIteratorGetAttrs                    ,


-- ** getFont #method:getFont#

#if ENABLE_OVERLOADING
    AttrIteratorGetFontMethodInfo           ,
#endif
    attrIteratorGetFont                     ,


-- ** next #method:next#

#if ENABLE_OVERLOADING
    AttrIteratorNextMethodInfo              ,
#endif
    attrIteratorNext                        ,


-- ** range #method:range#

#if ENABLE_OVERLOADING
    AttrIteratorRangeMethodInfo             ,
#endif
    attrIteratorRange                       ,




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

-- | Memory-managed wrapper type.
newtype AttrIterator = AttrIterator (ManagedPtr AttrIterator)
-- XXX Wrapping a foreign struct/union with no known destructor or size, leak?
instance WrappedPtr AttrIterator where
    wrappedPtrCalloc = return nullPtr
    wrappedPtrCopy = return
    wrappedPtrFree = Nothing

-- | A convenience alias for `Nothing` :: `Maybe` `AttrIterator`.
noAttrIterator :: Maybe AttrIterator
noAttrIterator = Nothing


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

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

foreign import ccall "pango_attr_iterator_destroy" pango_attr_iterator_destroy ::
    Ptr AttrIterator ->                     -- iterator : TInterface (Name {namespace = "Pango", name = "AttrIterator"})
    IO ()

{- |
Destroy a 'GI.Pango.Structs.AttrIterator.AttrIterator' and free all associated memory.
-}
attrIteratorDestroy ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    AttrIterator
    {- ^ /@iterator@/: a 'GI.Pango.Structs.AttrIterator.AttrIterator'. -}
    -> m ()
attrIteratorDestroy iterator = liftIO $ do
    iterator' <- unsafeManagedPtrGetPtr iterator
    pango_attr_iterator_destroy iterator'
    touchManagedPtr iterator
    return ()

#if ENABLE_OVERLOADING
data AttrIteratorDestroyMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo AttrIteratorDestroyMethodInfo AttrIterator signature where
    overloadedMethod _ = attrIteratorDestroy

#endif

-- method AttrIterator::get_attrs
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "iterator", argType = TInterface (Name {namespace = "Pango", name = "AttrIterator"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoAttrIterator", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TGSList (TInterface (Name {namespace = "Pango", name = "Attribute"})))
-- throws : False
-- Skip return : False

foreign import ccall "pango_attr_iterator_get_attrs" pango_attr_iterator_get_attrs ::
    Ptr AttrIterator ->                     -- iterator : TInterface (Name {namespace = "Pango", name = "AttrIterator"})
    IO (Ptr (GSList (Ptr Pango.Attribute.Attribute)))

{- |
Gets a list of all attributes at the current position of the
iterator.

/Since: 1.2/
-}
attrIteratorGetAttrs ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    AttrIterator
    {- ^ /@iterator@/: a 'GI.Pango.Structs.AttrIterator.AttrIterator' -}
    -> m [Pango.Attribute.Attribute]
    {- ^ __Returns:__ a list of
  all attributes for the current range.
  To free this value, call 'GI.Pango.Structs.Attribute.attributeDestroy' on
  each value and @/g_slist_free()/@ on the list. -}
attrIteratorGetAttrs iterator = liftIO $ do
    iterator' <- unsafeManagedPtrGetPtr iterator
    result <- pango_attr_iterator_get_attrs iterator'
    result' <- unpackGSList result
    result'' <- mapM (wrapPtr Pango.Attribute.Attribute) result'
    g_slist_free result
    touchManagedPtr iterator
    return result''

#if ENABLE_OVERLOADING
data AttrIteratorGetAttrsMethodInfo
instance (signature ~ (m [Pango.Attribute.Attribute]), MonadIO m) => O.MethodInfo AttrIteratorGetAttrsMethodInfo AttrIterator signature where
    overloadedMethod _ = attrIteratorGetAttrs

#endif

-- method AttrIterator::get_font
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "iterator", argType = TInterface (Name {namespace = "Pango", name = "AttrIterator"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoAttrIterator", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "desc", argType = TInterface (Name {namespace = "Pango", name = "FontDescription"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoFontDescription to fill in with the current values.\n       The family name in this structure will be set using\n       pango_font_description_set_family_static() using values from\n       an attribute in the #PangoAttrList associated with the iterator,\n       so if you plan to keep it around, you must call:\n       <literal>pango_font_description_set_family (desc, pango_font_description_get_family (desc))</literal>.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "language", argType = TInterface (Name {namespace = "Pango", name = "Language"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "if non-%NULL, location to store language tag for item, or %NULL\n           if none is found.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "extra_attrs", argType = TGSList (TInterface (Name {namespace = "Pango", name = "Attribute"})), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "if non-%NULL,\n          location in which to store a list of non-font\n          attributes at the the current position; only the highest priority\n          value of each attribute will be added to this list. In order\n          to free this value, you must call pango_attribute_destroy() on\n          each member.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "pango_attr_iterator_get_font" pango_attr_iterator_get_font ::
    Ptr AttrIterator ->                     -- iterator : TInterface (Name {namespace = "Pango", name = "AttrIterator"})
    Ptr Pango.FontDescription.FontDescription -> -- desc : TInterface (Name {namespace = "Pango", name = "FontDescription"})
    Ptr Pango.Language.Language ->          -- language : TInterface (Name {namespace = "Pango", name = "Language"})
    Ptr (GSList (Ptr Pango.Attribute.Attribute)) -> -- extra_attrs : TGSList (TInterface (Name {namespace = "Pango", name = "Attribute"}))
    IO ()

{- |
Get the font and other attributes at the current iterator position.
-}
attrIteratorGetFont ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    AttrIterator
    {- ^ /@iterator@/: a 'GI.Pango.Structs.AttrIterator.AttrIterator' -}
    -> Pango.FontDescription.FontDescription
    {- ^ /@desc@/: a 'GI.Pango.Structs.FontDescription.FontDescription' to fill in with the current values.
       The family name in this structure will be set using
       'GI.Pango.Structs.FontDescription.fontDescriptionSetFamilyStatic' using values from
       an attribute in the 'GI.Pango.Structs.AttrList.AttrList' associated with the iterator,
       so if you plan to keep it around, you must call:
       \<literal>pango_font_description_set_family (desc, pango_font_description_get_family (desc))\<\/literal>. -}
    -> Maybe (Pango.Language.Language)
    {- ^ /@language@/: if non-'Nothing', location to store language tag for item, or 'Nothing'
           if none is found. -}
    -> [Pango.Attribute.Attribute]
    {- ^ /@extraAttrs@/: if non-'Nothing',
          location in which to store a list of non-font
          attributes at the the current position; only the highest priority
          value of each attribute will be added to this list. In order
          to free this value, you must call 'GI.Pango.Structs.Attribute.attributeDestroy' on
          each member. -}
    -> m ()
attrIteratorGetFont iterator desc language extraAttrs = liftIO $ do
    iterator' <- unsafeManagedPtrGetPtr iterator
    desc' <- unsafeManagedPtrGetPtr desc
    maybeLanguage <- case language of
        Nothing -> return nullPtr
        Just jLanguage -> do
            jLanguage' <- unsafeManagedPtrGetPtr jLanguage
            return jLanguage'
    extraAttrs' <- mapM unsafeManagedPtrGetPtr extraAttrs
    extraAttrs'' <- packGSList extraAttrs'
    pango_attr_iterator_get_font iterator' desc' maybeLanguage extraAttrs''
    touchManagedPtr iterator
    touchManagedPtr desc
    whenJust language touchManagedPtr
    mapM_ touchManagedPtr extraAttrs
    return ()

#if ENABLE_OVERLOADING
data AttrIteratorGetFontMethodInfo
instance (signature ~ (Pango.FontDescription.FontDescription -> Maybe (Pango.Language.Language) -> [Pango.Attribute.Attribute] -> m ()), MonadIO m) => O.MethodInfo AttrIteratorGetFontMethodInfo AttrIterator signature where
    overloadedMethod _ = attrIteratorGetFont

#endif

-- method AttrIterator::next
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "iterator", argType = TInterface (Name {namespace = "Pango", name = "AttrIterator"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoAttrIterator", 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 "pango_attr_iterator_next" pango_attr_iterator_next ::
    Ptr AttrIterator ->                     -- iterator : TInterface (Name {namespace = "Pango", name = "AttrIterator"})
    IO CInt

{- |
Advance the iterator until the next change of style.
-}
attrIteratorNext ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    AttrIterator
    {- ^ /@iterator@/: a 'GI.Pango.Structs.AttrIterator.AttrIterator' -}
    -> m Bool
    {- ^ __Returns:__ 'False' if the iterator is at the end of the list, otherwise 'True' -}
attrIteratorNext iterator = liftIO $ do
    iterator' <- unsafeManagedPtrGetPtr iterator
    result <- pango_attr_iterator_next iterator'
    let result' = (/= 0) result
    touchManagedPtr iterator
    return result'

#if ENABLE_OVERLOADING
data AttrIteratorNextMethodInfo
instance (signature ~ (m Bool), MonadIO m) => O.MethodInfo AttrIteratorNextMethodInfo AttrIterator signature where
    overloadedMethod _ = attrIteratorNext

#endif

-- method AttrIterator::range
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "iterator", argType = TInterface (Name {namespace = "Pango", name = "AttrIterator"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoAttrIterator", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "start", argType = TBasicType TInt, direction = DirectionOut, mayBeNull = False, argDoc = Documentation {rawDocText = Just "location to store the start of the range", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything},Arg {argCName = "end", argType = TBasicType TInt, direction = DirectionOut, mayBeNull = False, argDoc = Documentation {rawDocText = Just "location to store the end of the range", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "pango_attr_iterator_range" pango_attr_iterator_range ::
    Ptr AttrIterator ->                     -- iterator : TInterface (Name {namespace = "Pango", name = "AttrIterator"})
    Ptr Int32 ->                            -- start : TBasicType TInt
    Ptr Int32 ->                            -- end : TBasicType TInt
    IO ()

{- |
Get the range of the current segment. Note that the
stored return values are signed, not unsigned like
the values in 'GI.Pango.Structs.Attribute.Attribute'. To deal with this API
oversight, stored return values that wouldn\'t fit into
a signed integer are clamped to @/G_MAXINT/@.
-}
attrIteratorRange ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    AttrIterator
    {- ^ /@iterator@/: a 'GI.Pango.Structs.AttrIterator.AttrIterator' -}
    -> m ((Int32, Int32))
attrIteratorRange iterator = liftIO $ do
    iterator' <- unsafeManagedPtrGetPtr iterator
    start <- allocMem :: IO (Ptr Int32)
    end <- allocMem :: IO (Ptr Int32)
    pango_attr_iterator_range iterator' start end
    start' <- peek start
    end' <- peek end
    touchManagedPtr iterator
    freeMem start
    freeMem end
    return (start', end')

#if ENABLE_OVERLOADING
data AttrIteratorRangeMethodInfo
instance (signature ~ (m ((Int32, Int32))), MonadIO m) => O.MethodInfo AttrIteratorRangeMethodInfo AttrIterator signature where
    overloadedMethod _ = attrIteratorRange

#endif

#if ENABLE_OVERLOADING
type family ResolveAttrIteratorMethod (t :: Symbol) (o :: *) :: * where
    ResolveAttrIteratorMethod "destroy" o = AttrIteratorDestroyMethodInfo
    ResolveAttrIteratorMethod "next" o = AttrIteratorNextMethodInfo
    ResolveAttrIteratorMethod "range" o = AttrIteratorRangeMethodInfo
    ResolveAttrIteratorMethod "getAttrs" o = AttrIteratorGetAttrsMethodInfo
    ResolveAttrIteratorMethod "getFont" o = AttrIteratorGetFontMethodInfo
    ResolveAttrIteratorMethod l o = O.MethodResolutionFailed l o

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

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