{- |
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.Gst.Objects.ControlSource.ControlSource' is a base class for control value sources that could
be used to get timestamp-value pairs. A control source essentially is a
function over time.

A 'GI.Gst.Objects.ControlSource.ControlSource' is used by first getting an instance of a specific
control-source, creating a binding for the control-source to the target property
of the element and then adding the binding to the element. The binding will
convert the data types and value range to fit to the bound property.

For implementing a new 'GI.Gst.Objects.ControlSource.ControlSource' one has to implement
'GI.Gst.Callbacks.ControlSourceGetValue' and 'GI.Gst.Callbacks.ControlSourceGetValueArray' functions.
These are then used by 'GI.Gst.Objects.ControlSource.controlSourceControlSourceGetValue' and
'GI.Gst.Objects.ControlSource.controlSourceControlSourceGetValueArray' to get values for specific timestamps.
-}

module GI.Gst.Objects.ControlSource
    ( 

-- * Exported types
    ControlSource(..)                       ,
    IsControlSource                         ,
    toControlSource                         ,
    noControlSource                         ,


 -- * Methods
-- ** controlSourceGetValue #method:controlSourceGetValue#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    ControlSourceControlSourceGetValueMethodInfo,
#endif
    controlSourceControlSourceGetValue      ,


-- ** controlSourceGetValueArray #method:controlSourceGetValueArray#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    ControlSourceControlSourceGetValueArrayMethodInfo,
#endif
    controlSourceControlSourceGetValueArray ,




    ) 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.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.GObject.Objects.Object as GObject.Object
import {-# SOURCE #-} qualified GI.Gst.Objects.Object as Gst.Object

newtype ControlSource = ControlSource (ManagedPtr ControlSource)
foreign import ccall "gst_control_source_get_type"
    c_gst_control_source_get_type :: IO GType

instance GObject ControlSource where
    gobjectType _ = c_gst_control_source_get_type
    

class GObject o => IsControlSource o
#if MIN_VERSION_base(4,9,0)
instance {-# OVERLAPPABLE #-} (GObject a, O.UnknownAncestorError ControlSource a) =>
    IsControlSource a
#endif
instance IsControlSource ControlSource
instance Gst.Object.IsObject ControlSource
instance GObject.Object.IsObject ControlSource

toControlSource :: (MonadIO m, IsControlSource o) => o -> m ControlSource
toControlSource = liftIO . unsafeCastTo ControlSource

noControlSource :: Maybe ControlSource
noControlSource = Nothing

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
type family ResolveControlSourceMethod (t :: Symbol) (o :: *) :: * where
    ResolveControlSourceMethod "addControlBinding" o = Gst.Object.ObjectAddControlBindingMethodInfo
    ResolveControlSourceMethod "bindProperty" o = GObject.Object.ObjectBindPropertyMethodInfo
    ResolveControlSourceMethod "bindPropertyFull" o = GObject.Object.ObjectBindPropertyFullMethodInfo
    ResolveControlSourceMethod "controlSourceGetValue" o = ControlSourceControlSourceGetValueMethodInfo
    ResolveControlSourceMethod "controlSourceGetValueArray" o = ControlSourceControlSourceGetValueArrayMethodInfo
    ResolveControlSourceMethod "defaultError" o = Gst.Object.ObjectDefaultErrorMethodInfo
    ResolveControlSourceMethod "forceFloating" o = GObject.Object.ObjectForceFloatingMethodInfo
    ResolveControlSourceMethod "freezeNotify" o = GObject.Object.ObjectFreezeNotifyMethodInfo
    ResolveControlSourceMethod "hasActiveControlBindings" o = Gst.Object.ObjectHasActiveControlBindingsMethodInfo
    ResolveControlSourceMethod "hasAncestor" o = Gst.Object.ObjectHasAncestorMethodInfo
    ResolveControlSourceMethod "hasAsAncestor" o = Gst.Object.ObjectHasAsAncestorMethodInfo
    ResolveControlSourceMethod "hasAsParent" o = Gst.Object.ObjectHasAsParentMethodInfo
    ResolveControlSourceMethod "isFloating" o = GObject.Object.ObjectIsFloatingMethodInfo
    ResolveControlSourceMethod "notify" o = GObject.Object.ObjectNotifyMethodInfo
    ResolveControlSourceMethod "notifyByPspec" o = GObject.Object.ObjectNotifyByPspecMethodInfo
    ResolveControlSourceMethod "ref" o = Gst.Object.ObjectRefMethodInfo
    ResolveControlSourceMethod "refSink" o = GObject.Object.ObjectRefSinkMethodInfo
    ResolveControlSourceMethod "removeControlBinding" o = Gst.Object.ObjectRemoveControlBindingMethodInfo
    ResolveControlSourceMethod "replaceData" o = GObject.Object.ObjectReplaceDataMethodInfo
    ResolveControlSourceMethod "replaceQdata" o = GObject.Object.ObjectReplaceQdataMethodInfo
    ResolveControlSourceMethod "runDispose" o = GObject.Object.ObjectRunDisposeMethodInfo
    ResolveControlSourceMethod "stealData" o = GObject.Object.ObjectStealDataMethodInfo
    ResolveControlSourceMethod "stealQdata" o = GObject.Object.ObjectStealQdataMethodInfo
    ResolveControlSourceMethod "suggestNextSync" o = Gst.Object.ObjectSuggestNextSyncMethodInfo
    ResolveControlSourceMethod "syncValues" o = Gst.Object.ObjectSyncValuesMethodInfo
    ResolveControlSourceMethod "thawNotify" o = GObject.Object.ObjectThawNotifyMethodInfo
    ResolveControlSourceMethod "unparent" o = Gst.Object.ObjectUnparentMethodInfo
    ResolveControlSourceMethod "unref" o = Gst.Object.ObjectUnrefMethodInfo
    ResolveControlSourceMethod "watchClosure" o = GObject.Object.ObjectWatchClosureMethodInfo
    ResolveControlSourceMethod "getControlBinding" o = Gst.Object.ObjectGetControlBindingMethodInfo
    ResolveControlSourceMethod "getControlRate" o = Gst.Object.ObjectGetControlRateMethodInfo
    ResolveControlSourceMethod "getData" o = GObject.Object.ObjectGetDataMethodInfo
    ResolveControlSourceMethod "getGValueArray" o = Gst.Object.ObjectGetGValueArrayMethodInfo
    ResolveControlSourceMethod "getName" o = Gst.Object.ObjectGetNameMethodInfo
    ResolveControlSourceMethod "getParent" o = Gst.Object.ObjectGetParentMethodInfo
    ResolveControlSourceMethod "getPathString" o = Gst.Object.ObjectGetPathStringMethodInfo
    ResolveControlSourceMethod "getProperty" o = GObject.Object.ObjectGetPropertyMethodInfo
    ResolveControlSourceMethod "getQdata" o = GObject.Object.ObjectGetQdataMethodInfo
    ResolveControlSourceMethod "getValue" o = Gst.Object.ObjectGetValueMethodInfo
    ResolveControlSourceMethod "setControlBindingDisabled" o = Gst.Object.ObjectSetControlBindingDisabledMethodInfo
    ResolveControlSourceMethod "setControlBindingsDisabled" o = Gst.Object.ObjectSetControlBindingsDisabledMethodInfo
    ResolveControlSourceMethod "setControlRate" o = Gst.Object.ObjectSetControlRateMethodInfo
    ResolveControlSourceMethod "setData" o = GObject.Object.ObjectSetDataMethodInfo
    ResolveControlSourceMethod "setName" o = Gst.Object.ObjectSetNameMethodInfo
    ResolveControlSourceMethod "setParent" o = Gst.Object.ObjectSetParentMethodInfo
    ResolveControlSourceMethod "setProperty" o = GObject.Object.ObjectSetPropertyMethodInfo
    ResolveControlSourceMethod l o = O.MethodResolutionFailed l o

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

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

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
instance O.HasAttributeList ControlSource
type instance O.AttributeList ControlSource = ControlSourceAttributeList
type ControlSourceAttributeList = ('[ '("name", Gst.Object.ObjectNamePropertyInfo), '("parent", Gst.Object.ObjectParentPropertyInfo)] :: [(Symbol, *)])
#endif

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
#endif

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
type instance O.SignalList ControlSource = ControlSourceSignalList
type ControlSourceSignalList = ('[ '("deepNotify", Gst.Object.ObjectDeepNotifySignalInfo), '("notify", GObject.Object.ObjectNotifySignalInfo)] :: [(Symbol, *)])

#endif

-- method ControlSource::control_source_get_value
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "self", argType = TInterface (Name {namespace = "Gst", name = "ControlSource"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstControlSource object", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "timestamp", argType = TBasicType TUInt64, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the time for which the value should be returned", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "value", argType = TBasicType TDouble, direction = DirectionOut, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the value", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
-- Lengths : []
-- returnType : Just (TBasicType TBoolean)
-- throws : False
-- Skip return : False

foreign import ccall "gst_control_source_get_value" gst_control_source_get_value :: 
    Ptr ControlSource ->                    -- self : TInterface (Name {namespace = "Gst", name = "ControlSource"})
    Word64 ->                               -- timestamp : TBasicType TUInt64
    Ptr CDouble ->                          -- value : TBasicType TDouble
    IO CInt

{- |
Gets the value for this 'GI.Gst.Objects.ControlSource.ControlSource' at a given timestamp.
-}
controlSourceControlSourceGetValue ::
    (B.CallStack.HasCallStack, MonadIO m, IsControlSource a) =>
    a
    {- ^ /@self@/: the 'GI.Gst.Objects.ControlSource.ControlSource' object -}
    -> Word64
    {- ^ /@timestamp@/: the time for which the value should be returned -}
    -> m ((Bool, Double))
    {- ^ __Returns:__ 'False' if the value couldn\'t be returned, 'True' otherwise. -}
controlSourceControlSourceGetValue self timestamp = liftIO $ do
    self' <- unsafeManagedPtrCastPtr self
    value <- allocMem :: IO (Ptr CDouble)
    result <- gst_control_source_get_value self' timestamp value
    let result' = (/= 0) result
    value' <- peek value
    let value'' = realToFrac value'
    touchManagedPtr self
    freeMem value
    return (result', value'')

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data ControlSourceControlSourceGetValueMethodInfo
instance (signature ~ (Word64 -> m ((Bool, Double))), MonadIO m, IsControlSource a) => O.MethodInfo ControlSourceControlSourceGetValueMethodInfo a signature where
    overloadedMethod _ = controlSourceControlSourceGetValue

#endif

-- method ControlSource::control_source_get_value_array
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "self", argType = TInterface (Name {namespace = "Gst", name = "ControlSource"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstControlSource object", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "timestamp", argType = TBasicType TUInt64, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the first timestamp", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "interval", argType = TBasicType TUInt64, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the time steps", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "n_values", argType = TBasicType TUInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the number of values to fetch", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "values", argType = TCArray False (-1) 3 (TBasicType TDouble), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "array to put control-values in", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : [Arg {argCName = "n_values", argType = TBasicType TUInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the number of values to fetch", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- returnType : Just (TBasicType TBoolean)
-- throws : False
-- Skip return : False

foreign import ccall "gst_control_source_get_value_array" gst_control_source_get_value_array :: 
    Ptr ControlSource ->                    -- self : TInterface (Name {namespace = "Gst", name = "ControlSource"})
    Word64 ->                               -- timestamp : TBasicType TUInt64
    Word64 ->                               -- interval : TBasicType TUInt64
    Word32 ->                               -- n_values : TBasicType TUInt
    Ptr CDouble ->                          -- values : TCArray False (-1) 3 (TBasicType TDouble)
    IO CInt

{- |
Gets an array of values for for this 'GI.Gst.Objects.ControlSource.ControlSource'. Values that are
undefined contain NANs.
-}
controlSourceControlSourceGetValueArray ::
    (B.CallStack.HasCallStack, MonadIO m, IsControlSource a) =>
    a
    {- ^ /@self@/: the 'GI.Gst.Objects.ControlSource.ControlSource' object -}
    -> Word64
    {- ^ /@timestamp@/: the first timestamp -}
    -> Word64
    {- ^ /@interval@/: the time steps -}
    -> [Double]
    {- ^ /@values@/: array to put control-values in -}
    -> m Bool
    {- ^ __Returns:__ 'True' if the given array could be filled, 'False' otherwise -}
controlSourceControlSourceGetValueArray self timestamp interval values = liftIO $ do
    let nValues = fromIntegral $ length values
    self' <- unsafeManagedPtrCastPtr self
    values' <- (packMapStorableArray realToFrac) values
    result <- gst_control_source_get_value_array self' timestamp interval nValues values'
    let result' = (/= 0) result
    touchManagedPtr self
    freeMem values'
    return result'

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data ControlSourceControlSourceGetValueArrayMethodInfo
instance (signature ~ (Word64 -> Word64 -> [Double] -> m Bool), MonadIO m, IsControlSource a) => O.MethodInfo ControlSourceControlSourceGetValueArrayMethodInfo a signature where
    overloadedMethod _ = controlSourceControlSourceGetValueArray

#endif