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

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.
-}

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

module GI.Gst.Objects.ControlSource
    (

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


 -- * Methods
-- ** controlSourceGetValue #method:controlSourceGetValue#

#if ENABLE_OVERLOADING
    ControlSourceControlSourceGetValueMethodInfo,
#endif
    controlSourceControlSourceGetValue      ,


-- ** controlSourceGetValueArray #method:controlSourceGetValueArray#

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

-- | Memory-managed wrapper type.
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


-- | Type class for types which can be safely cast to `ControlSource`, for instance with `toControlSource`.
class (GObject o, O.IsDescendantOf ControlSource o) => IsControlSource o
instance (GObject o, O.IsDescendantOf ControlSource o) => IsControlSource o

instance O.HasParentTypes ControlSource
type instance O.ParentTypes ControlSource = '[Gst.Object.Object, GObject.Object.Object]

-- | Cast to `ControlSource`, for types for which this is known to be safe. For general casts, use `Data.GI.Base.ManagedPtr.castTo`.
toControlSource :: (MonadIO m, IsControlSource o) => o -> m ControlSource
toControlSource = liftIO . unsafeCastTo ControlSource

-- | A convenience alias for `Nothing` :: `Maybe` `ControlSource`.
noControlSource :: Maybe ControlSource
noControlSource = Nothing

#if ENABLE_OVERLOADING
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 "getv" o = GObject.Object.ObjectGetvMethodInfo
    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 "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) => OL.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

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

#if ENABLE_OVERLOADING
#endif

#if ENABLE_OVERLOADING
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 ENABLE_OVERLOADING
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 ENABLE_OVERLOADING
data ControlSourceControlSourceGetValueArrayMethodInfo
instance (signature ~ (Word64 -> Word64 -> [Double] -> m Bool), MonadIO m, IsControlSource a) => O.MethodInfo ControlSourceControlSourceGetValueArrayMethodInfo a signature where
    overloadedMethod _ = controlSourceControlSourceGetValueArray

#endif