/* GStreamer
 *
 * Copyright (C) 2011 Stefan Sauer <ensonic@users.sf.net>
 *
 * gstcontrolbinding.c: Attachment for control sources
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
/**
 * SECTION:gstcontrolbinding
 * @short_description: attachment for control source sources
 *
 * A base class for value mapping objects that attaches control sources to gobject
 * properties. Such an object is taking one or more #GstControlSource instances,
 * combines them and maps the resulting value to the type and value range of the
 * bound property.
 */
/* FIXME(ensonic): should we make gst_object_add_control_binding() internal
 * - we create the control_binding for a certain object anyway
 * - we could call gst_object_add_control_binding() at the end of
 *   gst_control_binding_constructor()
 * - the weak-ref on object is not nice, as is the same as gst_object_parent()
 *   once the object is added to the parent
 *
 * - another option would be to defer what is done in _constructor to when
 *   the parent is set (need to listen to the signal then)
 *   then basically I could
 *   a) remove the obj arg and wait the binding to be added or
 *   b) add the binding from constructor, unref object there and make obj
 *      writeonly
 */

#include "gst_private.h"

#include <glib-object.h>
#include <gst/gst.h>

#include "gstcontrolbinding.h"

#include <math.h>

#define GST_CAT_DEFAULT control_binding_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

#define _do_init \
  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "gstcontrolbinding", 0, \
      "dynamic parameter control source attachment");

static GObject *gst_control_binding_constructor (GType type,
    guint n_construct_params, GObjectConstructParam * construct_params);
static void gst_control_binding_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_control_binding_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_control_binding_dispose (GObject * object);
static void gst_control_binding_finalize (GObject * object);

G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstControlBinding, gst_control_binding,
    GST_TYPE_OBJECT, _do_init);

struct _GstControlBindingPrivate
{
  GWeakRef object;
};

enum
{
  PROP_0,
  PROP_OBJECT,
  PROP_NAME,
  PROP_LAST
};

static GParamSpec *properties[PROP_LAST];

static void
gst_control_binding_class_init (GstControlBindingClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  g_type_class_add_private (klass, sizeof (GstControlBindingPrivate));

  gobject_class->constructor = gst_control_binding_constructor;
  gobject_class->set_property = gst_control_binding_set_property;
  gobject_class->get_property = gst_control_binding_get_property;
  gobject_class->dispose = gst_control_binding_dispose;
  gobject_class->finalize = gst_control_binding_finalize;

  properties[PROP_OBJECT] =
      g_param_spec_object ("object", "Object",
      "The object of the property", GST_TYPE_OBJECT,
      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);

  properties[PROP_NAME] =
      g_param_spec_string ("name", "Name", "The name of the property", NULL,
      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);


  g_object_class_install_properties (gobject_class, PROP_LAST, properties);
}

static void
gst_control_binding_init (GstControlBinding * binding)
{
  binding->ABI.abi.priv =
      G_TYPE_INSTANCE_GET_PRIVATE (binding, GST_TYPE_CONTROL_BINDING,
      GstControlBindingPrivate);
  g_weak_ref_init (&binding->ABI.abi.priv->object, NULL);
}

static GObject *
gst_control_binding_constructor (GType type, guint n_construct_params,
    GObjectConstructParam * construct_params)
{
  GstControlBinding *binding;
  GParamSpec *pspec;
  GstObject *object;

  binding =
      GST_CONTROL_BINDING (G_OBJECT_CLASS (gst_control_binding_parent_class)
      ->constructor (type, n_construct_params, construct_params));

  object = g_weak_ref_get (&binding->ABI.abi.priv->object);
  if (!object) {
    GST_WARNING_OBJECT (object, "no object set");
    return (GObject *) binding;
  }

  GST_INFO_OBJECT (object, "trying to put property '%s' under control",
      binding->name);

  /* check if the object has a property of that name */
  if ((pspec =
          g_object_class_find_property (G_OBJECT_GET_CLASS (object),
              binding->name))) {
    GST_DEBUG_OBJECT (object, "  psec->flags : 0x%08x", pspec->flags);

    /* check if this param is witable && controlable && !construct-only */
    if ((pspec->flags & (G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE |
                G_PARAM_CONSTRUCT_ONLY)) ==
        (G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE)) {
      binding->pspec = pspec;
    } else {
      GST_WARNING_OBJECT (object,
          "property '%s' on class '%s' needs to "
          "be writeable, controlable and not construct_only", binding->name,
          G_OBJECT_TYPE_NAME (object));
    }
  } else {
    GST_WARNING_OBJECT (object, "class '%s' has no property '%s'",
        G_OBJECT_TYPE_NAME (object), binding->name);
  }

  gst_object_unref (object);

  return (GObject *) binding;
}

static void
gst_control_binding_dispose (GObject * object)
{
  GstControlBinding *self = GST_CONTROL_BINDING (object);

  /* we did not took a reference */
  g_object_remove_weak_pointer ((GObject *) self->__object,
      (gpointer *) & self->__object);
  self->__object = NULL;
  g_weak_ref_clear (&self->ABI.abi.priv->object);

  ((GObjectClass *) gst_control_binding_parent_class)->dispose (object);
}

static void
gst_control_binding_finalize (GObject * object)
{
  GstControlBinding *self = GST_CONTROL_BINDING (object);

  g_free (self->name);

  ((GObjectClass *) gst_control_binding_parent_class)->finalize (object);
}

static void
gst_control_binding_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstControlBinding *self = GST_CONTROL_BINDING (object);

  switch (prop_id) {
    case PROP_OBJECT:
      /* do not ref to avoid a ref cycle */
      self->__object = g_value_get_object (value);
      g_object_add_weak_pointer ((GObject *) self->__object,
          (gpointer *) & self->__object);

      g_weak_ref_set (&self->ABI.abi.priv->object, self->__object);
      break;
    case PROP_NAME:
      self->name = g_value_dup_string (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_control_binding_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstControlBinding *self = GST_CONTROL_BINDING (object);

  switch (prop_id) {
    case PROP_OBJECT:
      g_value_take_object (value, g_weak_ref_get (&self->ABI.abi.priv->object));
      break;
    case PROP_NAME:
      g_value_set_string (value, self->name);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/* functions */

/**
 * gst_control_binding_sync_values:
 * @binding: the control binding
 * @object: the object that has controlled properties
 * @timestamp: the time that should be processed
 * @last_sync: the last time this was called
 *
 * Sets the property of the @object, according to the #GstControlSources that
 * handle them and for the given timestamp.
 *
 * If this function fails, it is most likely the application developers fault.
 * Most probably the control sources are not setup correctly.
 *
 * Returns: %TRUE if the controller value could be applied to the object
 * property, %FALSE otherwise
 */
gboolean
gst_control_binding_sync_values (GstControlBinding * binding,
    GstObject * object, GstClockTime timestamp, GstClockTime last_sync)
{
  GstControlBindingClass *klass;
  gboolean ret = FALSE;

  g_return_val_if_fail (GST_IS_CONTROL_BINDING (binding), FALSE);

  if (binding->disabled)
    return TRUE;

  klass = GST_CONTROL_BINDING_GET_CLASS (binding);

  if (G_LIKELY (klass->sync_values != NULL)) {
    ret = klass->sync_values (binding, object, timestamp, last_sync);
  } else {
    GST_WARNING_OBJECT (binding, "missing sync_values implementation");
  }
  return ret;
}

/**
 * gst_control_binding_get_value:
 * @binding: the control binding
 * @timestamp: the time the control-change should be read from
 *
 * Gets the value for the given controlled property at the requested time.
 *
 * Returns: (nullable): the GValue of the property at the given time,
 * or %NULL if the property isn't controlled.
 */
GValue *
gst_control_binding_get_value (GstControlBinding * binding,
    GstClockTime timestamp)
{
  GstControlBindingClass *klass;
  GValue *ret = NULL;

  g_return_val_if_fail (GST_IS_CONTROL_BINDING (binding), NULL);
  g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), NULL);

  klass = GST_CONTROL_BINDING_GET_CLASS (binding);

  if (G_LIKELY (klass->get_value != NULL)) {
    ret = klass->get_value (binding, timestamp);
  } else {
    GST_WARNING_OBJECT (binding, "missing get_value implementation");
  }
  return ret;
}

/**
 * gst_control_binding_get_value_array: (skip)
 * @binding: the control binding
 * @timestamp: the time that should be processed
 * @interval: the time spacing between subsequent values
 * @n_values: the number of values
 * @values: (array length=n_values): array to put control-values in
 *
 * Gets a number of values for the given controlled property starting at the
 * requested time. The array @values need to hold enough space for @n_values of
 * the same type as the objects property's type.
 *
 * This function is useful if one wants to e.g. draw a graph of the control
 * curve or apply a control curve sample by sample.
 *
 * The values are unboxed and ready to be used. The similar function 
 * gst_control_binding_get_g_value_array() returns the array as #GValues and is
 * more suitable for bindings.
 *
 * Returns: %TRUE if the given array could be filled, %FALSE otherwise
 */
gboolean
gst_control_binding_get_value_array (GstControlBinding * binding,
    GstClockTime timestamp, GstClockTime interval, guint n_values,
    gpointer values)
{
  GstControlBindingClass *klass;
  gboolean ret = FALSE;

  g_return_val_if_fail (GST_IS_CONTROL_BINDING (binding), FALSE);
  g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
  g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), FALSE);
  g_return_val_if_fail (values, FALSE);

  klass = GST_CONTROL_BINDING_GET_CLASS (binding);

  if (G_LIKELY (klass->get_value_array != NULL)) {
    ret =
        klass->get_value_array (binding, timestamp, interval, n_values, values);
  } else {
    GST_WARNING_OBJECT (binding, "missing get_value_array implementation");
  }
  return ret;
}

#define CONVERT_ARRAY(type,TYPE) \
{ \
  g##type *v = g_new (g##type,n_values); \
  ret = gst_control_binding_get_value_array (binding, timestamp, interval, \
      n_values, v); \
  if (ret) { \
    for (i = 0; i < n_values; i++) { \
      g_value_init (&values[i], G_TYPE_##TYPE); \
      g_value_set_##type (&values[i], v[i]); \
    } \
  } \
  g_free (v); \
}

/**
 * gst_control_binding_get_g_value_array:
 * @binding: the control binding
 * @timestamp: the time that should be processed
 * @interval: the time spacing between subsequent values
 * @n_values: the number of values
 * @values: (array length=n_values): array to put control-values in
 *
 * Gets a number of #GValues for the given controlled property starting at the
 * requested time. The array @values need to hold enough space for @n_values of
 * #GValue.
 *
 * This function is useful if one wants to e.g. draw a graph of the control
 * curve or apply a control curve sample by sample.
 *
 * Returns: %TRUE if the given array could be filled, %FALSE otherwise
 */
gboolean
gst_control_binding_get_g_value_array (GstControlBinding * binding,
    GstClockTime timestamp, GstClockTime interval, guint n_values,
    GValue * values)
{
  GstControlBindingClass *klass;
  gboolean ret = FALSE;

  g_return_val_if_fail (GST_IS_CONTROL_BINDING (binding), FALSE);
  g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
  g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), FALSE);
  g_return_val_if_fail (values, FALSE);

  klass = GST_CONTROL_BINDING_GET_CLASS (binding);

  if (G_LIKELY (klass->get_g_value_array != NULL)) {
    ret =
        klass->get_g_value_array (binding, timestamp, interval, n_values,
        values);
  } else {
    guint i;
    GType type, base;

    base = type = G_PARAM_SPEC_VALUE_TYPE (GST_CONTROL_BINDING_PSPEC (binding));
    while ((type = g_type_parent (type)))
      base = type;

    GST_INFO_OBJECT (binding, "missing get_g_value_array implementation, we're "
        "emulating it");
    switch (base) {
      case G_TYPE_INT:
        CONVERT_ARRAY (int, INT);
        break;
      case G_TYPE_UINT:
        CONVERT_ARRAY (uint, UINT);
        break;
      case G_TYPE_LONG:
        CONVERT_ARRAY (long, LONG);
        break;
      case G_TYPE_ULONG:
        CONVERT_ARRAY (ulong, ULONG);
        break;
      case G_TYPE_INT64:
        CONVERT_ARRAY (int64, INT64);
        break;
      case G_TYPE_UINT64:
        CONVERT_ARRAY (uint64, UINT64);
        break;
      case G_TYPE_FLOAT:
        CONVERT_ARRAY (float, FLOAT);
        break;
      case G_TYPE_DOUBLE:
        CONVERT_ARRAY (double, DOUBLE);
        break;
      case G_TYPE_BOOLEAN:
        CONVERT_ARRAY (boolean, BOOLEAN);
        break;
      case G_TYPE_ENUM:
      {
        gint *v = g_new (gint, n_values);
        ret = gst_control_binding_get_value_array (binding, timestamp, interval,
            n_values, v);
        if (ret) {
          for (i = 0; i < n_values; i++) {
            g_value_init (&values[i], type);
            g_value_set_enum (&values[i], v[i]);
          }
        }
        g_free (v);
      }
        break;
      default:
        GST_WARNING ("incomplete implementation for paramspec type '%s'",
            G_PARAM_SPEC_TYPE_NAME (GST_CONTROL_BINDING_PSPEC (binding)));
        GST_CONTROL_BINDING_PSPEC (binding) = NULL;
        break;
    }
  }
  return ret;
}

/**
 * gst_control_binding_set_disabled:
 * @binding: the control binding
 * @disabled: boolean that specifies whether to disable the controller
 * or not.
 *
 * This function is used to disable a control binding for some time, i.e.
 * gst_object_sync_values() will do nothing.
 */
void
gst_control_binding_set_disabled (GstControlBinding * binding,
    gboolean disabled)
{
  g_return_if_fail (GST_IS_CONTROL_BINDING (binding));
  binding->disabled = disabled;
}

/**
 * gst_control_binding_is_disabled:
 * @binding: the control binding
 *
 * Check if the control binding is disabled.
 *
 * Returns: %TRUE if the binding is inactive
 */
gboolean
gst_control_binding_is_disabled (GstControlBinding * binding)
{
  g_return_val_if_fail (GST_IS_CONTROL_BINDING (binding), TRUE);
  return ! !binding->disabled;
}
