/* GStreamer - GParamSpecs for some of our types
 * Copyright (C) 2007 Tim-Philipp Müller  <tim centricular net>
 *
 * 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:gstparamspec
 * @title: GstParamSpec
 * @short_description: GParamSpec implementations specific
 * to GStreamer
 *
 * GParamSpec implementations specific to GStreamer.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gst_private.h"
#include "glib-compat-private.h"
#include "gstparamspecs.h"

/* --- GstParamSpecFraction --- */

static void
_gst_param_fraction_init (GParamSpec * pspec)
{
  GstParamSpecFraction *fspec = GST_PARAM_SPEC_FRACTION (pspec);

  fspec->min_num = 0;
  fspec->min_den = 1;
  fspec->max_num = G_MAXINT;
  fspec->max_den = 1;
  fspec->def_num = 1;
  fspec->def_den = 1;
}

static void
_gst_param_fraction_set_default (GParamSpec * pspec, GValue * value)
{
  value->data[0].v_int = GST_PARAM_SPEC_FRACTION (pspec)->def_num;
  value->data[1].v_int = GST_PARAM_SPEC_FRACTION (pspec)->def_den;
}

static gboolean
_gst_param_fraction_validate (GParamSpec * pspec, GValue * value)
{
  GstParamSpecFraction *fspec = GST_PARAM_SPEC_FRACTION (pspec);
  gboolean within_range = FALSE;
  GValue f_this = { 0, };
  GValue f_min = { 0, };
  GValue f_max = { 0, };
  gint res;

  g_value_init (&f_this, GST_TYPE_FRACTION);
  gst_value_set_fraction (&f_this, value->data[0].v_int, value->data[1].v_int);

  g_value_init (&f_min, GST_TYPE_FRACTION);
  gst_value_set_fraction (&f_min, fspec->min_num, fspec->min_den);

  g_value_init (&f_max, GST_TYPE_FRACTION);
  gst_value_set_fraction (&f_max, fspec->max_num, fspec->max_den);

  res = gst_value_compare (&f_min, &f_this);
#ifndef GST_DISABLE_GST_DEBUG
  GST_LOG ("comparing %d/%d to %d/%d, result = %d", fspec->min_num,
      fspec->min_den, value->data[0].v_int, value->data[1].v_int, res);
#endif
  if (res != GST_VALUE_LESS_THAN && res != GST_VALUE_EQUAL)
    goto out;

#ifndef GST_DISABLE_GST_DEBUG
  GST_LOG ("comparing %d/%d to %d/%d, result = %d", value->data[0].v_int,
      value->data[1].v_int, fspec->max_num, fspec->max_den, res);
#endif
  res = gst_value_compare (&f_this, &f_max);
  if (res != GST_VALUE_LESS_THAN && res != GST_VALUE_EQUAL)
    goto out;

  within_range = TRUE;

out:

  g_value_unset (&f_min);
  g_value_unset (&f_max);
  g_value_unset (&f_this);

#ifndef GST_DISABLE_GST_DEBUG
  GST_LOG ("%swithin range", (within_range) ? "" : "not ");
#endif

  /* return FALSE if everything ok, otherwise TRUE */
  return !within_range;
}

static gint
_gst_param_fraction_values_cmp (GParamSpec * pspec, const GValue * value1,
    const GValue * value2)
{
  gint res;

  res = gst_value_compare (value1, value2);

  g_assert (res != GST_VALUE_UNORDERED);

  /* GST_VALUE_LESS_THAN is -1, EQUAL is 0, and GREATER_THAN is 1 */
  return res;
}

GType
gst_param_spec_fraction_get_type (void)
{
  static volatile GType gst_faction_type = 0;

  /* register GST_TYPE_PARAM_FRACTION */
  if (g_once_init_enter (&gst_faction_type)) {
    GType type;
    static GParamSpecTypeInfo pspec_info = {
      sizeof (GstParamSpecFraction),    /* instance_size     */
      0,                        /* n_preallocs       */
      _gst_param_fraction_init, /* instance_init     */
      G_TYPE_INVALID,           /* value_type        */
      NULL,                     /* finalize          */
      _gst_param_fraction_set_default,  /* value_set_default */
      _gst_param_fraction_validate,     /* value_validate    */
      _gst_param_fraction_values_cmp,   /* values_cmp        */
    };
    pspec_info.value_type = gst_fraction_get_type ();
    type = g_param_type_register_static ("GstParamFraction", &pspec_info);
    g_once_init_leave (&gst_faction_type, type);
  }

  return gst_faction_type;
}

/**
 * gst_param_spec_fraction:
 * @name: canonical name of the property specified
 * @nick: nick name for the property specified
 * @blurb: description of the property specified
 * @min_num: minimum value (fraction numerator)
 * @min_denom: minimum value (fraction denominator)
 * @max_num: maximum value (fraction numerator)
 * @max_denom: maximum value (fraction denominator)
 * @default_num: default value (fraction numerator)
 * @default_denom: default value (fraction denominator)
 * @flags: flags for the property specified
 *
 * This function creates a fraction GParamSpec for use by objects/elements
 * that want to expose properties of fraction type. This function is typically
 * used in connection with g_object_class_install_property() in a GObjects's
 * instance_init function.
 *
 * Returns: (transfer full): a newly created parameter specification
 */
GParamSpec *
gst_param_spec_fraction (const gchar * name, const gchar * nick,
    const gchar * blurb, gint min_num, gint min_denom, gint max_num,
    gint max_denom, gint default_num, gint default_denom, GParamFlags flags)
{
  GstParamSpecFraction *fspec;
  GParamSpec *pspec;
  GValue default_val = { 0, };

  fspec =
      g_param_spec_internal (GST_TYPE_PARAM_FRACTION, name, nick, blurb, flags);

  fspec->min_num = min_num;
  fspec->min_den = min_denom;
  fspec->max_num = max_num;
  fspec->max_den = max_denom;
  fspec->def_num = default_num;
  fspec->def_den = default_denom;

  pspec = G_PARAM_SPEC (fspec);

  /* check that min <= default <= max */
  g_value_init (&default_val, GST_TYPE_FRACTION);
  gst_value_set_fraction (&default_val, default_num, default_denom);
  /* validate returns TRUE if the validation fails */
  if (_gst_param_fraction_validate (pspec, &default_val)) {
    g_critical ("GstParamSpec of type 'fraction' for property '%s' has a "
        "default value of %d/%d, which is not within the allowed range of "
        "%d/%d to %d/%d", name, default_num, default_denom, min_num,
        min_denom, max_num, max_denom);
    g_param_spec_ref (pspec);
    g_param_spec_sink (pspec);
    g_param_spec_unref (pspec);
    pspec = NULL;
  }
  g_value_unset (&default_val);

  return pspec;
}

static void
_gst_param_array_init (GParamSpec * pspec)
{
  GstParamSpecArray *aspec = GST_PARAM_SPEC_ARRAY_LIST (pspec);

  aspec->element_spec = NULL;
}

static void
_gst_param_array_finalize (GParamSpec * pspec)
{
  GstParamSpecArray *aspec = GST_PARAM_SPEC_ARRAY_LIST (pspec);
  GParamSpecClass *parent_class =
      g_type_class_peek (g_type_parent (GST_TYPE_PARAM_ARRAY_LIST));

  if (aspec->element_spec) {
    g_param_spec_unref (aspec->element_spec);
    aspec->element_spec = NULL;
  }

  parent_class->finalize (pspec);
}

static gboolean
_gst_param_array_validate (GParamSpec * pspec, GValue * value)
{
  GstParamSpecArray *aspec = GST_PARAM_SPEC_ARRAY_LIST (pspec);
  gboolean ret = FALSE;

  /* ensure array values validity against a present element spec */
  if (aspec->element_spec) {
    GParamSpec *element_spec = aspec->element_spec;
    guint i;

    for (i = 0; i < gst_value_array_get_size (value); i++) {
      GValue *element = (GValue *) gst_value_array_get_value (value, i);

      /* need to fixup value type, or ensure that the array value is initialized at all */
      if (!g_value_type_compatible (G_VALUE_TYPE (element),
              G_PARAM_SPEC_VALUE_TYPE (element_spec))) {
        if (G_VALUE_TYPE (element) != 0)
          g_value_unset (element);
        g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec));
        g_param_value_set_default (element_spec, element);
        ret = TRUE;
      }

      /* validate array value against element_spec */
      if (g_param_value_validate (element_spec, element))
        ret = TRUE;
    }
  }

  return ret;
}

static gint
_gst_param_array_values_cmp (GParamSpec * pspec, const GValue * value1,
    const GValue * value2)
{
  GstParamSpecArray *aspec = GST_PARAM_SPEC_ARRAY_LIST (pspec);
  guint size1, size2;

  if (!value1 || !value2)
    return value2 ? -1 : value1 != value2;

  size1 = gst_value_array_get_size (value1);
  size2 = gst_value_array_get_size (value2);

  if (size1 != size2)
    return size1 < size2 ? -1 : 1;
  else if (!aspec->element_spec) {
    /* we need an element specification for comparisons, so there's not much
     * to compare here, try to at least provide stable lesser/greater result
     */
    return size1 < size2 ? -1 : size1 > size2;
  } else {                      /* size1 == size2 */
    guint i;

    for (i = 0; i < size1; i++) {
      const GValue *element1 = gst_value_array_get_value (value1, i);
      const GValue *element2 = gst_value_array_get_value (value2, i);
      gint cmp;

      /* need corresponding element types, provide stable result otherwise */
      if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2))
        return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1;
      cmp = g_param_values_cmp (aspec->element_spec, element1, element2);
      if (cmp)
        return cmp;
    }
    return 0;
  }
}

GType
gst_param_spec_array_get_type (void)
{
  static volatile GType gst_array_type = 0;

  /* register GST_TYPE_PARAM_FRACTION */
  if (g_once_init_enter (&gst_array_type)) {
    GType type;
    static GParamSpecTypeInfo pspec_info = {
      sizeof (GstParamSpecArray),       /* instance_size     */
      0,                        /* n_preallocs       */
      _gst_param_array_init,    /* instance_init     */
      G_TYPE_INVALID,           /* value_type        */
      _gst_param_array_finalize,        /* finalize          */
      NULL,                     /* value_set_default */
      _gst_param_array_validate,        /* value_validate    */
      _gst_param_array_values_cmp,      /* values_cmp        */
    };
    pspec_info.value_type = gst_value_array_get_type ();
    type = g_param_type_register_static ("GstParamArray", &pspec_info);
    g_once_init_leave (&gst_array_type, type);
  }

  return gst_array_type;
}

/**
 * gst_param_spec_array:
 * @name: canonical name of the property specified
 * @nick: nick name for the property specified
 * @blurb: description of the property specified
 * @element_spec: GParamSpec of the array
 * @flags: flags for the property specified
 *
 * This function creates a GstArray GParamSpec for use by objects/elements
 * that want to expose properties of GstArray type. This function is
 * typically * used in connection with g_object_class_install_property() in a
 * GObjects's instance_init function.
 *
 * Returns: (transfer full): a newly created parameter specification
 */

GParamSpec *
gst_param_spec_array (const gchar * name,
    const gchar * nick,
    const gchar * blurb, GParamSpec * element_spec, GParamFlags flags)
{
  GstParamSpecArray *aspec;

  if (element_spec)
    g_return_val_if_fail (G_IS_PARAM_SPEC (element_spec), NULL);

  aspec = g_param_spec_internal (GST_TYPE_PARAM_ARRAY_LIST,
      name, nick, blurb, flags);
  if (aspec == NULL)
    return NULL;

  if (element_spec) {
    aspec->element_spec = g_param_spec_ref (element_spec);
    g_param_spec_sink (element_spec);
  }

  return G_PARAM_SPEC (aspec);
}
