/* GStreamer
 *
 * Copyright (C) 2011 Stefan Sauer <ensonic@users.sf.net>
 *
 * gstargbcontrolbinding.c: Attachment for multiple control sources to gargb
 *                            properties
 *
 * 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:gstargbcontrolbinding
 * @short_description: attachment for control sources to argb properties
 *
 * A value mapping object that attaches multiple control sources to a guint
 * gobject properties representing a color. A control value of 0.0 will turn the
 * color component off and a value of 1.0 will be the color level.
 */

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

#include "gstargbcontrolbinding.h"

#include <gst/math-compat.h>

#define GST_CAT_DEFAULT control_binding_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

static GObject *gst_argb_control_binding_constructor (GType type,
    guint n_construct_params, GObjectConstructParam * construct_params);
static void gst_argb_control_binding_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_argb_control_binding_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);
static void gst_argb_control_binding_dispose (GObject * object);
static void gst_argb_control_binding_finalize (GObject * object);

static gboolean gst_argb_control_binding_sync_values (GstControlBinding * _self,
    GstObject * object, GstClockTime timestamp, GstClockTime last_sync);
static GValue *gst_argb_control_binding_get_value (GstControlBinding * _self,
    GstClockTime timestamp);
static gboolean gst_argb_control_binding_get_value_array (GstControlBinding *
    _self, GstClockTime timestamp, GstClockTime interval, guint n_values,
    gpointer values);
static gboolean gst_argb_control_binding_get_g_value_array (GstControlBinding *
    _self, GstClockTime timestamp, GstClockTime interval, guint n_values,
    GValue * values);

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

#define gst_argb_control_binding_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstARGBControlBinding, gst_argb_control_binding,
    GST_TYPE_CONTROL_BINDING, _do_init);

enum
{
  PROP_0,
  PROP_CS_A,
  PROP_CS_R,
  PROP_CS_G,
  PROP_CS_B,
  PROP_LAST
};

static GParamSpec *properties[PROP_LAST];

/* vmethods */

static void
gst_argb_control_binding_class_init (GstARGBControlBindingClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstControlBindingClass *control_binding_class =
      GST_CONTROL_BINDING_CLASS (klass);

  gobject_class->constructor = gst_argb_control_binding_constructor;
  gobject_class->set_property = gst_argb_control_binding_set_property;
  gobject_class->get_property = gst_argb_control_binding_get_property;
  gobject_class->dispose = gst_argb_control_binding_dispose;
  gobject_class->finalize = gst_argb_control_binding_finalize;

  control_binding_class->sync_values = gst_argb_control_binding_sync_values;
  control_binding_class->get_value = gst_argb_control_binding_get_value;
  control_binding_class->get_value_array =
      gst_argb_control_binding_get_value_array;
  control_binding_class->get_g_value_array =
      gst_argb_control_binding_get_g_value_array;

  properties[PROP_CS_A] =
      g_param_spec_object ("control-source-a", "ControlSource A",
      "The control source for the alpha color component",
      GST_TYPE_CONTROL_SOURCE,
      G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);

  properties[PROP_CS_R] =
      g_param_spec_object ("control-source-r", "ControlSource R",
      "The control source for the red color component",
      GST_TYPE_CONTROL_SOURCE,
      G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);

  properties[PROP_CS_G] =
      g_param_spec_object ("control-source-g", "ControlSource G",
      "The control source for the green color component",
      GST_TYPE_CONTROL_SOURCE,
      G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);

  properties[PROP_CS_B] =
      g_param_spec_object ("control-source-b", "ControlSource B",
      "The control source for the blue color component",
      GST_TYPE_CONTROL_SOURCE,
      G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);

  g_object_class_install_properties (gobject_class, PROP_LAST, properties);
}

static void
gst_argb_control_binding_init (GstARGBControlBinding * self)
{
}

static GObject *
gst_argb_control_binding_constructor (GType type, guint n_construct_params,
    GObjectConstructParam * construct_params)
{
  GstARGBControlBinding *self;

  self =
      GST_ARGB_CONTROL_BINDING (G_OBJECT_CLASS (parent_class)->constructor
      (type, n_construct_params, construct_params));

  if (GST_CONTROL_BINDING_PSPEC (self)) {
    if (!(G_PARAM_SPEC_VALUE_TYPE (GST_CONTROL_BINDING_PSPEC (self)) ==
            G_TYPE_UINT)) {
      GST_WARNING ("can't bind to paramspec type '%s'",
          G_PARAM_SPEC_TYPE_NAME (GST_CONTROL_BINDING_PSPEC (self)));
      GST_CONTROL_BINDING_PSPEC (self) = NULL;
    } else {
      g_value_init (&self->cur_value, G_TYPE_UINT);
    }
  }
  return (GObject *) self;
}

static void
gst_argb_control_binding_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstARGBControlBinding *self = GST_ARGB_CONTROL_BINDING (object);

  switch (prop_id) {
    case PROP_CS_A:
      gst_object_replace ((GstObject **) & self->cs_a,
          g_value_get_object (value));
      break;
    case PROP_CS_R:
      gst_object_replace ((GstObject **) & self->cs_r,
          g_value_get_object (value));
      break;
    case PROP_CS_G:
      gst_object_replace ((GstObject **) & self->cs_g,
          g_value_get_object (value));
      break;
    case PROP_CS_B:
      gst_object_replace ((GstObject **) & self->cs_b,
          g_value_get_object (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_argb_control_binding_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstARGBControlBinding *self = GST_ARGB_CONTROL_BINDING (object);

  switch (prop_id) {
    case PROP_CS_A:
      g_value_set_object (value, self->cs_a);
      break;
    case PROP_CS_R:
      g_value_set_object (value, self->cs_r);
      break;
    case PROP_CS_G:
      g_value_set_object (value, self->cs_g);
      break;
    case PROP_CS_B:
      g_value_set_object (value, self->cs_b);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_argb_control_binding_dispose (GObject * object)
{
  GstARGBControlBinding *self = GST_ARGB_CONTROL_BINDING (object);

  gst_object_replace ((GstObject **) & self->cs_a, NULL);
  gst_object_replace ((GstObject **) & self->cs_r, NULL);
  gst_object_replace ((GstObject **) & self->cs_g, NULL);
  gst_object_replace ((GstObject **) & self->cs_b, NULL);

  G_OBJECT_CLASS (parent_class)->dispose (object);
}

static void
gst_argb_control_binding_finalize (GObject * object)
{
  GstARGBControlBinding *self = GST_ARGB_CONTROL_BINDING (object);

  g_value_unset (&self->cur_value);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static gboolean
gst_argb_control_binding_sync_values (GstControlBinding * _self,
    GstObject * object, GstClockTime timestamp, GstClockTime last_sync)
{
  GstARGBControlBinding *self = GST_ARGB_CONTROL_BINDING (_self);
  gdouble src_val_a = 1.0, src_val_r = 0.0, src_val_g = 0.0, src_val_b = 0.0;
  gboolean ret = TRUE;

  g_return_val_if_fail (GST_IS_ARGB_CONTROL_BINDING (self), FALSE);
  g_return_val_if_fail (GST_CONTROL_BINDING_PSPEC (self), FALSE);

  GST_LOG_OBJECT (object, "property '%s' at ts=%" GST_TIME_FORMAT,
      _self->name, GST_TIME_ARGS (timestamp));

  if (self->cs_a)
    ret &= gst_control_source_get_value (self->cs_a, timestamp, &src_val_a);
  if (self->cs_r)
    ret &= gst_control_source_get_value (self->cs_r, timestamp, &src_val_r);
  if (self->cs_g)
    ret &= gst_control_source_get_value (self->cs_g, timestamp, &src_val_g);
  if (self->cs_b)
    ret &= gst_control_source_get_value (self->cs_b, timestamp, &src_val_b);
  if (G_LIKELY (ret)) {
    guint src_val = (((guint) (CLAMP (src_val_a, 0.0, 1.0) * 255)) << 24) |
        (((guint) (CLAMP (src_val_r, 0.0, 1.0) * 255)) << 16) |
        (((guint) (CLAMP (src_val_g, 0.0, 1.0) * 255)) << 8) |
        ((guint) (CLAMP (src_val_b, 0.0, 1.0) * 255));
    GST_LOG_OBJECT (object, "  new value 0x%08x", src_val);
    /* always set the value for first time, but then only if it changed
     * this should limit g_object_notify invocations.
     * FIXME: can we detect negative playback rates?
     */
    if ((timestamp < last_sync) || (src_val != self->last_value)) {
      GValue *dst_val = &self->cur_value;

      g_value_set_uint (dst_val, src_val);
      /* we can make this faster
       * http://bugzilla.gnome.org/show_bug.cgi?id=536939
       */
      g_object_set_property ((GObject *) object, _self->name, dst_val);
      self->last_value = src_val;
    }
  } else {
    GST_DEBUG_OBJECT (object, "no control value for param %s", _self->name);
  }
  return (ret);
}

static GValue *
gst_argb_control_binding_get_value (GstControlBinding * _self,
    GstClockTime timestamp)
{
  GstARGBControlBinding *self = GST_ARGB_CONTROL_BINDING (_self);
  GValue *dst_val = NULL;
  gdouble src_val_a = 1.0, src_val_r = 0.0, src_val_g = 0.0, src_val_b = 0.0;
  gboolean ret = TRUE;

  g_return_val_if_fail (GST_IS_ARGB_CONTROL_BINDING (self), NULL);
  g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), NULL);
  g_return_val_if_fail (GST_CONTROL_BINDING_PSPEC (self), FALSE);

  /* get current value via control source */
  if (self->cs_a)
    ret &= gst_control_source_get_value (self->cs_a, timestamp, &src_val_a);
  if (self->cs_r)
    ret &= gst_control_source_get_value (self->cs_r, timestamp, &src_val_r);
  if (self->cs_g)
    ret &= gst_control_source_get_value (self->cs_g, timestamp, &src_val_g);
  if (self->cs_b)
    ret &= gst_control_source_get_value (self->cs_b, timestamp, &src_val_b);
  if (G_LIKELY (ret)) {
    guint src_val = (((guint) (CLAMP (src_val_a, 0.0, 1.0) * 255)) << 24) |
        (((guint) (CLAMP (src_val_r, 0.0, 1.0) * 255)) << 16) |
        (((guint) (CLAMP (src_val_g, 0.0, 1.0) * 255)) << 8) |
        ((guint) (CLAMP (src_val_b, 0.0, 1.0) * 255));
    dst_val = g_new0 (GValue, 1);
    g_value_init (dst_val, G_TYPE_UINT);
    g_value_set_uint (dst_val, src_val);
  } else {
    GST_LOG ("no control value for property %s at ts %" GST_TIME_FORMAT,
        _self->name, GST_TIME_ARGS (timestamp));
  }

  return dst_val;
}

static gboolean
gst_argb_control_binding_get_value_array (GstControlBinding * _self,
    GstClockTime timestamp, GstClockTime interval, guint n_values,
    gpointer values_)
{
  GstARGBControlBinding *self = GST_ARGB_CONTROL_BINDING (_self);
  gint i;
  gdouble *src_val_a = NULL, *src_val_r = NULL, *src_val_g = NULL, *src_val_b =
      NULL;
  guint *values = (guint *) values_;
  gboolean ret = TRUE;

  g_return_val_if_fail (GST_IS_ARGB_CONTROL_BINDING (self), 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);
  g_return_val_if_fail (GST_CONTROL_BINDING_PSPEC (self), FALSE);

  if (self->cs_a) {
    src_val_a = g_new0 (gdouble, n_values);
    ret &= gst_control_source_get_value_array (self->cs_a, timestamp,
        interval, n_values, src_val_a);
  }
  if (self->cs_r) {
    src_val_r = g_new0 (gdouble, n_values);
    ret &= gst_control_source_get_value_array (self->cs_r, timestamp,
        interval, n_values, src_val_r);
  }
  if (self->cs_g) {
    src_val_g = g_new0 (gdouble, n_values);
    ret &= gst_control_source_get_value_array (self->cs_g, timestamp,
        interval, n_values, src_val_g);
  }
  if (self->cs_b) {
    src_val_b = g_new0 (gdouble, n_values);
    ret &= gst_control_source_get_value_array (self->cs_b, timestamp,
        interval, n_values, src_val_b);
  }
  if (G_LIKELY (ret)) {
    for (i = 0; i < n_values; i++) {
      gdouble a = 1.0, r = 0.0, g = 0.0, b = 0.0;
      if (src_val_a && !isnan (src_val_a[i]))
        a = src_val_a[i];
      if (src_val_r && !isnan (src_val_r[i]))
        r = src_val_r[i];
      if (src_val_g && !isnan (src_val_g[i]))
        g = src_val_g[i];
      if (src_val_b && !isnan (src_val_b[i]))
        b = src_val_b[i];
      values[i] = (((guint) (CLAMP (a, 0.0, 1.0) * 255)) << 24) |
          (((guint) (CLAMP (r, 0.0, 1.0) * 255)) << 16) |
          (((guint) (CLAMP (g, 0.0, 1.0) * 255)) << 8) |
          ((guint) (CLAMP (b, 0.0, 1.0) * 255));
    }
  } else {
    GST_LOG ("failed to get control value for property %s at ts %"
        GST_TIME_FORMAT, _self->name, GST_TIME_ARGS (timestamp));
  }
  g_free (src_val_a);
  g_free (src_val_r);
  g_free (src_val_g);
  g_free (src_val_b);
  return ret;
}

static gboolean
gst_argb_control_binding_get_g_value_array (GstControlBinding * _self,
    GstClockTime timestamp, GstClockTime interval, guint n_values,
    GValue * values)
{
  GstARGBControlBinding *self = GST_ARGB_CONTROL_BINDING (_self);
  gint i;
  gdouble *src_val_a = NULL, *src_val_r = NULL, *src_val_g = NULL, *src_val_b =
      NULL;
  guint src_val;
  gboolean ret = TRUE;

  g_return_val_if_fail (GST_IS_ARGB_CONTROL_BINDING (self), 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);
  g_return_val_if_fail (GST_CONTROL_BINDING_PSPEC (self), FALSE);

  if (self->cs_a) {
    src_val_a = g_new0 (gdouble, n_values);
    ret &= gst_control_source_get_value_array (self->cs_a, timestamp,
        interval, n_values, src_val_a);
  }
  if (self->cs_r) {
    src_val_r = g_new0 (gdouble, n_values);
    ret &= gst_control_source_get_value_array (self->cs_r, timestamp,
        interval, n_values, src_val_r);
  }
  if (self->cs_g) {
    src_val_g = g_new0 (gdouble, n_values);
    ret &= gst_control_source_get_value_array (self->cs_g, timestamp,
        interval, n_values, src_val_g);
  }
  if (self->cs_b) {
    src_val_b = g_new0 (gdouble, n_values);
    ret &= gst_control_source_get_value_array (self->cs_b, timestamp,
        interval, n_values, src_val_b);
  }
  if (G_LIKELY (ret)) {
    for (i = 0; i < n_values; i++) {
      gdouble a = 1.0, r = 0.0, g = 0.0, b = 0.0;
      if (src_val_a && !isnan (src_val_a[i]))
        a = src_val_a[i];
      if (src_val_r && !isnan (src_val_r[i]))
        r = src_val_r[i];
      if (src_val_g && !isnan (src_val_g[i]))
        g = src_val_g[i];
      if (src_val_b && !isnan (src_val_b[i]))
        b = src_val_b[i];
      src_val = (((guint) (CLAMP (a, 0.0, 1.0) * 255)) << 24) |
          (((guint) (CLAMP (r, 0.0, 1.0) * 255)) << 16) |
          (((guint) (CLAMP (g, 0.0, 1.0) * 255)) << 8) |
          ((guint) (CLAMP (b, 0.0, 1.0) * 255));
      g_value_init (&values[i], G_TYPE_UINT);
      g_value_set_uint (&values[i], src_val);
    }
  } else {
    GST_LOG ("failed to get control value for property %s at ts %"
        GST_TIME_FORMAT, _self->name, GST_TIME_ARGS (timestamp));
  }
  g_free (src_val_a);
  g_free (src_val_r);
  g_free (src_val_g);
  g_free (src_val_b);
  return ret;
}

/* functions */

/**
 * gst_argb_control_binding_new:
 * @object: the object of the property
 * @property_name: the property-name to attach the control source
 * @cs_a: the control source for the alpha channel
 * @cs_r: the control source for the red channel
 * @cs_g: the control source for the green channel
 * @cs_b: the control source for the blue channel
 *
 * Create a new control-binding that attaches the given #GstControlSource to the
 * #GObject property.
 *
 * Returns: (transfer floating): the new #GstARGBControlBinding
 */
GstControlBinding *
gst_argb_control_binding_new (GstObject * object, const gchar * property_name,
    GstControlSource * cs_a, GstControlSource * cs_r, GstControlSource * cs_g,
    GstControlSource * cs_b)
{
  return (GstControlBinding *) g_object_new (GST_TYPE_ARGB_CONTROL_BINDING,
      "object", object, "name", property_name,
      "control-source-a", cs_a,
      "control-source-r", cs_r,
      "control-source-g", cs_g, "control-source-b", cs_b, NULL);
}

/* functions */
