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

Utility struct to help handling 'GI.Gst.Enums.FlowReturn' combination. Useful for
'GI.Gst.Objects.Element.Element'\<!-- -->s that have multiple source pads and need to combine
the different 'GI.Gst.Enums.FlowReturn' for those pads.

'GI.GstBase.Structs.FlowCombiner.FlowCombiner' works by using the last 'GI.Gst.Enums.FlowReturn' for all 'GI.Gst.Objects.Pad.Pad'
it has in its list and computes the combined return value and provides
it to the caller.

To add a new pad to the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' use 'GI.GstBase.Structs.FlowCombiner.flowCombinerAddPad'.
The new 'GI.Gst.Objects.Pad.Pad' is stored with a default value of 'GI.Gst.Enums.FlowReturnOk'.

In case you want a 'GI.Gst.Objects.Pad.Pad' to be removed, use 'GI.GstBase.Structs.FlowCombiner.flowCombinerRemovePad'.

Please be aware that this struct isn\'t thread safe as its designed to be
 used by demuxers, those usually will have a single thread operating it.

These functions will take refs on the passed 'GI.Gst.Objects.Pad.Pad'\<!-- -->s.

Aside from reducing the user\'s code size, the main advantage of using this
helper struct is to follow the standard rules for 'GI.Gst.Enums.FlowReturn' combination.
These rules are:

* 'GI.Gst.Enums.FlowReturnEos': only if all returns are EOS too
* 'GI.Gst.Enums.FlowReturnNotLinked': only if all returns are NOT_LINKED too
* 'GI.Gst.Enums.FlowReturnError' or below: if at least one returns an error return
* 'GI.Gst.Enums.FlowReturnNotNegotiated': if at least one returns a not-negotiated return
* 'GI.Gst.Enums.FlowReturnFlushing': if at least one returns flushing
* 'GI.Gst.Enums.FlowReturnOk': otherwise

'GI.Gst.Enums.FlowReturnError' or below, GST_FLOW_NOT_NEGOTIATED and GST_FLOW_FLUSHING are
returned immediately from the 'GI.GstBase.Structs.FlowCombiner.flowCombinerUpdateFlow' function.

/Since: 1.4/
-}

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

module GI.GstBase.Structs.FlowCombiner
    (

-- * Exported types
    FlowCombiner(..)                        ,
    noFlowCombiner                          ,


 -- * Methods
-- ** addPad #method:addPad#

#if ENABLE_OVERLOADING
    FlowCombinerAddPadMethodInfo            ,
#endif
    flowCombinerAddPad                      ,


-- ** clear #method:clear#

#if ENABLE_OVERLOADING
    FlowCombinerClearMethodInfo             ,
#endif
    flowCombinerClear                       ,


-- ** free #method:free#

#if ENABLE_OVERLOADING
    FlowCombinerFreeMethodInfo              ,
#endif
    flowCombinerFree                        ,


-- ** new #method:new#

    flowCombinerNew                         ,


-- ** ref #method:ref#

#if ENABLE_OVERLOADING
    FlowCombinerRefMethodInfo               ,
#endif
    flowCombinerRef                         ,


-- ** removePad #method:removePad#

#if ENABLE_OVERLOADING
    FlowCombinerRemovePadMethodInfo         ,
#endif
    flowCombinerRemovePad                   ,


-- ** reset #method:reset#

#if ENABLE_OVERLOADING
    FlowCombinerResetMethodInfo             ,
#endif
    flowCombinerReset                       ,


-- ** unref #method:unref#

#if ENABLE_OVERLOADING
    FlowCombinerUnrefMethodInfo             ,
#endif
    flowCombinerUnref                       ,


-- ** updateFlow #method:updateFlow#

#if ENABLE_OVERLOADING
    FlowCombinerUpdateFlowMethodInfo        ,
#endif
    flowCombinerUpdateFlow                  ,


-- ** updatePadFlow #method:updatePadFlow#

#if ENABLE_OVERLOADING
    FlowCombinerUpdatePadFlowMethodInfo     ,
#endif
    flowCombinerUpdatePadFlow               ,




    ) 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

import qualified GI.Gst.Enums as Gst.Enums
import qualified GI.Gst.Objects.Pad as Gst.Pad

-- | Memory-managed wrapper type.
newtype FlowCombiner = FlowCombiner (ManagedPtr FlowCombiner)
foreign import ccall "gst_flow_combiner_get_type" c_gst_flow_combiner_get_type ::
    IO GType

instance BoxedObject FlowCombiner where
    boxedType _ = c_gst_flow_combiner_get_type

-- | A convenience alias for `Nothing` :: `Maybe` `FlowCombiner`.
noFlowCombiner :: Maybe FlowCombiner
noFlowCombiner = Nothing


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

-- method FlowCombiner::new
-- method type : Constructor
-- Args : []
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "GstBase", name = "FlowCombiner"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_flow_combiner_new" gst_flow_combiner_new ::
    IO (Ptr FlowCombiner)

{- |
Creates a new 'GI.GstBase.Structs.FlowCombiner.FlowCombiner', use 'GI.GstBase.Structs.FlowCombiner.flowCombinerFree' to free it.

/Since: 1.4/
-}
flowCombinerNew ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    m FlowCombiner
    {- ^ __Returns:__ A new 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' -}
flowCombinerNew  = liftIO $ do
    result <- gst_flow_combiner_new
    checkUnexpectedReturnNULL "flowCombinerNew" result
    result' <- (wrapBoxed FlowCombiner) result
    return result'

#if ENABLE_OVERLOADING
#endif

-- method FlowCombiner::add_pad
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "combiner", argType = TInterface (Name {namespace = "GstBase", name = "FlowCombiner"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstFlowCombiner", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "pad", argType = TInterface (Name {namespace = "Gst", name = "Pad"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstPad that is being added", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "gst_flow_combiner_add_pad" gst_flow_combiner_add_pad ::
    Ptr FlowCombiner ->                     -- combiner : TInterface (Name {namespace = "GstBase", name = "FlowCombiner"})
    Ptr Gst.Pad.Pad ->                      -- pad : TInterface (Name {namespace = "Gst", name = "Pad"})
    IO ()

{- |
Adds a new 'GI.Gst.Objects.Pad.Pad' to the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner'.

/Since: 1.4/
-}
flowCombinerAddPad ::
    (B.CallStack.HasCallStack, MonadIO m, Gst.Pad.IsPad a) =>
    FlowCombiner
    {- ^ /@combiner@/: the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' -}
    -> a
    {- ^ /@pad@/: the 'GI.Gst.Objects.Pad.Pad' that is being added -}
    -> m ()
flowCombinerAddPad combiner pad = liftIO $ do
    combiner' <- unsafeManagedPtrGetPtr combiner
    pad' <- unsafeManagedPtrCastPtr pad
    gst_flow_combiner_add_pad combiner' pad'
    touchManagedPtr combiner
    touchManagedPtr pad
    return ()

#if ENABLE_OVERLOADING
data FlowCombinerAddPadMethodInfo
instance (signature ~ (a -> m ()), MonadIO m, Gst.Pad.IsPad a) => O.MethodInfo FlowCombinerAddPadMethodInfo FlowCombiner signature where
    overloadedMethod _ = flowCombinerAddPad

#endif

-- method FlowCombiner::clear
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "combiner", argType = TInterface (Name {namespace = "GstBase", name = "FlowCombiner"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstFlowCombiner to clear", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "gst_flow_combiner_clear" gst_flow_combiner_clear ::
    Ptr FlowCombiner ->                     -- combiner : TInterface (Name {namespace = "GstBase", name = "FlowCombiner"})
    IO ()

{- |
Removes all pads from a 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' and resets it to its initial state.

/Since: 1.6/
-}
flowCombinerClear ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    FlowCombiner
    {- ^ /@combiner@/: the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' to clear -}
    -> m ()
flowCombinerClear combiner = liftIO $ do
    combiner' <- unsafeManagedPtrGetPtr combiner
    gst_flow_combiner_clear combiner'
    touchManagedPtr combiner
    return ()

#if ENABLE_OVERLOADING
data FlowCombinerClearMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo FlowCombinerClearMethodInfo FlowCombiner signature where
    overloadedMethod _ = flowCombinerClear

#endif

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

foreign import ccall "gst_flow_combiner_free" gst_flow_combiner_free ::
    Ptr FlowCombiner ->                     -- combiner : TInterface (Name {namespace = "GstBase", name = "FlowCombiner"})
    IO ()

{- |
Frees a 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' struct and all its internal data.

/Since: 1.4/
-}
flowCombinerFree ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    FlowCombiner
    {- ^ /@combiner@/: the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' to free -}
    -> m ()
flowCombinerFree combiner = liftIO $ do
    combiner' <- unsafeManagedPtrGetPtr combiner
    gst_flow_combiner_free combiner'
    touchManagedPtr combiner
    return ()

#if ENABLE_OVERLOADING
data FlowCombinerFreeMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo FlowCombinerFreeMethodInfo FlowCombiner signature where
    overloadedMethod _ = flowCombinerFree

#endif

-- method FlowCombiner::ref
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "combiner", argType = TInterface (Name {namespace = "GstBase", name = "FlowCombiner"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstFlowCombiner to add a reference to.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "GstBase", name = "FlowCombiner"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_flow_combiner_ref" gst_flow_combiner_ref ::
    Ptr FlowCombiner ->                     -- combiner : TInterface (Name {namespace = "GstBase", name = "FlowCombiner"})
    IO (Ptr FlowCombiner)

{- |
Increments the reference count on the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner'.

/Since: 1.12.1/
-}
flowCombinerRef ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    FlowCombiner
    {- ^ /@combiner@/: the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' to add a reference to. -}
    -> m FlowCombiner
    {- ^ __Returns:__ the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner'. -}
flowCombinerRef combiner = liftIO $ do
    combiner' <- unsafeManagedPtrGetPtr combiner
    result <- gst_flow_combiner_ref combiner'
    checkUnexpectedReturnNULL "flowCombinerRef" result
    result' <- (wrapBoxed FlowCombiner) result
    touchManagedPtr combiner
    return result'

#if ENABLE_OVERLOADING
data FlowCombinerRefMethodInfo
instance (signature ~ (m FlowCombiner), MonadIO m) => O.MethodInfo FlowCombinerRefMethodInfo FlowCombiner signature where
    overloadedMethod _ = flowCombinerRef

#endif

-- method FlowCombiner::remove_pad
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "combiner", argType = TInterface (Name {namespace = "GstBase", name = "FlowCombiner"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstFlowCombiner", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "pad", argType = TInterface (Name {namespace = "Gst", name = "Pad"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstPad to remove", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "gst_flow_combiner_remove_pad" gst_flow_combiner_remove_pad ::
    Ptr FlowCombiner ->                     -- combiner : TInterface (Name {namespace = "GstBase", name = "FlowCombiner"})
    Ptr Gst.Pad.Pad ->                      -- pad : TInterface (Name {namespace = "Gst", name = "Pad"})
    IO ()

{- |
Removes a 'GI.Gst.Objects.Pad.Pad' from the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner'.

/Since: 1.4/
-}
flowCombinerRemovePad ::
    (B.CallStack.HasCallStack, MonadIO m, Gst.Pad.IsPad a) =>
    FlowCombiner
    {- ^ /@combiner@/: the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' -}
    -> a
    {- ^ /@pad@/: the 'GI.Gst.Objects.Pad.Pad' to remove -}
    -> m ()
flowCombinerRemovePad combiner pad = liftIO $ do
    combiner' <- unsafeManagedPtrGetPtr combiner
    pad' <- unsafeManagedPtrCastPtr pad
    gst_flow_combiner_remove_pad combiner' pad'
    touchManagedPtr combiner
    touchManagedPtr pad
    return ()

#if ENABLE_OVERLOADING
data FlowCombinerRemovePadMethodInfo
instance (signature ~ (a -> m ()), MonadIO m, Gst.Pad.IsPad a) => O.MethodInfo FlowCombinerRemovePadMethodInfo FlowCombiner signature where
    overloadedMethod _ = flowCombinerRemovePad

#endif

-- method FlowCombiner::reset
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "combiner", argType = TInterface (Name {namespace = "GstBase", name = "FlowCombiner"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstFlowCombiner to clear", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "gst_flow_combiner_reset" gst_flow_combiner_reset ::
    Ptr FlowCombiner ->                     -- combiner : TInterface (Name {namespace = "GstBase", name = "FlowCombiner"})
    IO ()

{- |
Reset flow combiner and all pads to their initial state without removing pads.

/Since: 1.6/
-}
flowCombinerReset ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    FlowCombiner
    {- ^ /@combiner@/: the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' to clear -}
    -> m ()
flowCombinerReset combiner = liftIO $ do
    combiner' <- unsafeManagedPtrGetPtr combiner
    gst_flow_combiner_reset combiner'
    touchManagedPtr combiner
    return ()

#if ENABLE_OVERLOADING
data FlowCombinerResetMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo FlowCombinerResetMethodInfo FlowCombiner signature where
    overloadedMethod _ = flowCombinerReset

#endif

-- method FlowCombiner::unref
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "combiner", argType = TInterface (Name {namespace = "GstBase", name = "FlowCombiner"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstFlowCombiner to unreference.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "gst_flow_combiner_unref" gst_flow_combiner_unref ::
    Ptr FlowCombiner ->                     -- combiner : TInterface (Name {namespace = "GstBase", name = "FlowCombiner"})
    IO ()

{- |
Decrements the reference count on the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner'.

/Since: 1.12.1/
-}
flowCombinerUnref ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    FlowCombiner
    {- ^ /@combiner@/: the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' to unreference. -}
    -> m ()
flowCombinerUnref combiner = liftIO $ do
    combiner' <- unsafeManagedPtrGetPtr combiner
    gst_flow_combiner_unref combiner'
    touchManagedPtr combiner
    return ()

#if ENABLE_OVERLOADING
data FlowCombinerUnrefMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo FlowCombinerUnrefMethodInfo FlowCombiner signature where
    overloadedMethod _ = flowCombinerUnref

#endif

-- method FlowCombiner::update_flow
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "combiner", argType = TInterface (Name {namespace = "GstBase", name = "FlowCombiner"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstFlowCombiner", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "fret", argType = TInterface (Name {namespace = "Gst", name = "FlowReturn"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the latest #GstFlowReturn received for a pad in this #GstFlowCombiner", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Gst", name = "FlowReturn"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_flow_combiner_update_flow" gst_flow_combiner_update_flow ::
    Ptr FlowCombiner ->                     -- combiner : TInterface (Name {namespace = "GstBase", name = "FlowCombiner"})
    CInt ->                                 -- fret : TInterface (Name {namespace = "Gst", name = "FlowReturn"})
    IO CInt

{- |
Computes the combined flow return for the pads in it.

The 'GI.Gst.Enums.FlowReturn' parameter should be the last flow return update for a pad
in this 'GI.GstBase.Structs.FlowCombiner.FlowCombiner'. It will use this value to be able to shortcut some
combinations and avoid looking over all pads again. e.g. The last combined
return is the same as the latest obtained 'GI.Gst.Enums.FlowReturn'.

/Since: 1.4/
-}
flowCombinerUpdateFlow ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    FlowCombiner
    {- ^ /@combiner@/: the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' -}
    -> Gst.Enums.FlowReturn
    {- ^ /@fret@/: the latest 'GI.Gst.Enums.FlowReturn' received for a pad in this 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' -}
    -> m Gst.Enums.FlowReturn
    {- ^ __Returns:__ The combined 'GI.Gst.Enums.FlowReturn' -}
flowCombinerUpdateFlow combiner fret = liftIO $ do
    combiner' <- unsafeManagedPtrGetPtr combiner
    let fret' = (fromIntegral . fromEnum) fret
    result <- gst_flow_combiner_update_flow combiner' fret'
    let result' = (toEnum . fromIntegral) result
    touchManagedPtr combiner
    return result'

#if ENABLE_OVERLOADING
data FlowCombinerUpdateFlowMethodInfo
instance (signature ~ (Gst.Enums.FlowReturn -> m Gst.Enums.FlowReturn), MonadIO m) => O.MethodInfo FlowCombinerUpdateFlowMethodInfo FlowCombiner signature where
    overloadedMethod _ = flowCombinerUpdateFlow

#endif

-- method FlowCombiner::update_pad_flow
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "combiner", argType = TInterface (Name {namespace = "GstBase", name = "FlowCombiner"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstFlowCombiner", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "pad", argType = TInterface (Name {namespace = "Gst", name = "Pad"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstPad whose #GstFlowReturn to update", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "fret", argType = TInterface (Name {namespace = "Gst", name = "FlowReturn"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the latest #GstFlowReturn received for a pad in this #GstFlowCombiner", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Gst", name = "FlowReturn"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_flow_combiner_update_pad_flow" gst_flow_combiner_update_pad_flow ::
    Ptr FlowCombiner ->                     -- combiner : TInterface (Name {namespace = "GstBase", name = "FlowCombiner"})
    Ptr Gst.Pad.Pad ->                      -- pad : TInterface (Name {namespace = "Gst", name = "Pad"})
    CInt ->                                 -- fret : TInterface (Name {namespace = "Gst", name = "FlowReturn"})
    IO CInt

{- |
Sets the provided pad\'s last flow return to provided value and computes
the combined flow return for the pads in it.

The 'GI.Gst.Enums.FlowReturn' parameter should be the last flow return update for a pad
in this 'GI.GstBase.Structs.FlowCombiner.FlowCombiner'. It will use this value to be able to shortcut some
combinations and avoid looking over all pads again. e.g. The last combined
return is the same as the latest obtained 'GI.Gst.Enums.FlowReturn'.

/Since: 1.6/
-}
flowCombinerUpdatePadFlow ::
    (B.CallStack.HasCallStack, MonadIO m, Gst.Pad.IsPad a) =>
    FlowCombiner
    {- ^ /@combiner@/: the 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' -}
    -> a
    {- ^ /@pad@/: the 'GI.Gst.Objects.Pad.Pad' whose 'GI.Gst.Enums.FlowReturn' to update -}
    -> Gst.Enums.FlowReturn
    {- ^ /@fret@/: the latest 'GI.Gst.Enums.FlowReturn' received for a pad in this 'GI.GstBase.Structs.FlowCombiner.FlowCombiner' -}
    -> m Gst.Enums.FlowReturn
    {- ^ __Returns:__ The combined 'GI.Gst.Enums.FlowReturn' -}
flowCombinerUpdatePadFlow combiner pad fret = liftIO $ do
    combiner' <- unsafeManagedPtrGetPtr combiner
    pad' <- unsafeManagedPtrCastPtr pad
    let fret' = (fromIntegral . fromEnum) fret
    result <- gst_flow_combiner_update_pad_flow combiner' pad' fret'
    let result' = (toEnum . fromIntegral) result
    touchManagedPtr combiner
    touchManagedPtr pad
    return result'

#if ENABLE_OVERLOADING
data FlowCombinerUpdatePadFlowMethodInfo
instance (signature ~ (a -> Gst.Enums.FlowReturn -> m Gst.Enums.FlowReturn), MonadIO m, Gst.Pad.IsPad a) => O.MethodInfo FlowCombinerUpdatePadFlowMethodInfo FlowCombiner signature where
    overloadedMethod _ = flowCombinerUpdatePadFlow

#endif

#if ENABLE_OVERLOADING
type family ResolveFlowCombinerMethod (t :: Symbol) (o :: *) :: * where
    ResolveFlowCombinerMethod "addPad" o = FlowCombinerAddPadMethodInfo
    ResolveFlowCombinerMethod "clear" o = FlowCombinerClearMethodInfo
    ResolveFlowCombinerMethod "free" o = FlowCombinerFreeMethodInfo
    ResolveFlowCombinerMethod "ref" o = FlowCombinerRefMethodInfo
    ResolveFlowCombinerMethod "removePad" o = FlowCombinerRemovePadMethodInfo
    ResolveFlowCombinerMethod "reset" o = FlowCombinerResetMethodInfo
    ResolveFlowCombinerMethod "unref" o = FlowCombinerUnrefMethodInfo
    ResolveFlowCombinerMethod "updateFlow" o = FlowCombinerUpdateFlowMethodInfo
    ResolveFlowCombinerMethod "updatePadFlow" o = FlowCombinerUpdatePadFlowMethodInfo
    ResolveFlowCombinerMethod l o = O.MethodResolutionFailed l o

instance (info ~ ResolveFlowCombinerMethod t FlowCombiner, O.MethodInfo info FlowCombiner p) => OL.IsLabel t (FlowCombiner -> 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