/* GStreamer
 * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
 *
 * 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.
 */

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

#include "gstfrei0r.h"
#include "gstfrei0rfilter.h"
#include "gstfrei0rsrc.h"
#include "gstfrei0rmixer.h"

#include <string.h>
#include <gmodule.h>

GST_DEBUG_CATEGORY (frei0r_debug);
#define GST_CAT_DEFAULT frei0r_debug

static GstStaticCaps bgra8888_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
    ("BGRA"));
static GstStaticCaps rgba8888_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
    ("RGBA"));
static GstStaticCaps packed32_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
    ("{ BGRA, RGBA, ABGR, ARGB, BGRx, RGBx, xBGR, xRGB, AYUV }"));

GstCaps *
gst_frei0r_caps_from_color_model (gint color_model)
{
  switch (color_model) {
    case F0R_COLOR_MODEL_BGRA8888:
      return gst_static_caps_get (&bgra8888_caps);
    case F0R_COLOR_MODEL_RGBA8888:
      return gst_static_caps_get (&rgba8888_caps);
    case F0R_COLOR_MODEL_PACKED32:
      return gst_static_caps_get (&packed32_caps);
    default:
      break;
  }

  return NULL;
}

void
gst_frei0r_klass_install_properties (GObjectClass * gobject_class,
    GstFrei0rFuncTable * ftable, GstFrei0rProperty * properties,
    gint n_properties)
{
  gint i, count = 1;
  f0r_instance_t *instance = ftable->construct (640, 480);

  g_assert (instance);

  for (i = 0; i < n_properties; i++) {
    f0r_param_info_t *param_info = &properties[i].info;
    gchar *prop_name;

    ftable->get_param_info (param_info, i);

    if (!param_info->name) {
      GST_ERROR ("Property %d of %s without a valid name", i,
          g_type_name (G_TYPE_FROM_CLASS (gobject_class)));
      continue;
    }

    prop_name = g_ascii_strdown (param_info->name, -1);
    g_strcanon (prop_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-+", '-');
    /* satisfy glib2 (argname[0] must be [A-Za-z]) */
    if (!((prop_name[0] >= 'a' && prop_name[0] <= 'z') ||
            (prop_name[0] >= 'A' && prop_name[0] <= 'Z'))) {
      gchar *tempstr = prop_name;

      prop_name = g_strconcat ("param-", prop_name, NULL);
      g_free (tempstr);
    }

    properties[i].prop_id = count;
    properties[i].prop_idx = i;

    ftable->get_param_value (instance, &properties[i].default_value, i);
    if (param_info->type == F0R_PARAM_STRING)
      properties[i].default_value.data.s =
          g_strdup (properties[i].default_value.data.s);

    switch (param_info->type) {
      case F0R_PARAM_BOOL:
        g_object_class_install_property (gobject_class, count++,
            g_param_spec_boolean (prop_name, param_info->name,
                param_info->explanation,
                properties[i].default_value.data.b ? TRUE : FALSE,
                G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
        properties[i].n_prop_ids = 1;
        break;
      case F0R_PARAM_DOUBLE:{
        gdouble def = properties[i].default_value.data.d;

        /* If the default is NAN, +-INF we use 0.0 */
        if (!(def >= 0.0 && def <= 1.0))
          def = 0.0;

        g_object_class_install_property (gobject_class, count++,
            g_param_spec_double (prop_name, param_info->name,
                param_info->explanation, 0.0, 1.0, def,
                G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
        properties[i].n_prop_ids = 1;
        break;
      }
      case F0R_PARAM_STRING:
        g_object_class_install_property (gobject_class, count++,
            g_param_spec_string (prop_name, param_info->name,
                param_info->explanation, properties[i].default_value.data.s,
                G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
        properties[i].n_prop_ids = 1;
        break;
      case F0R_PARAM_COLOR:{
        gchar *prop_name_full;
        gchar *prop_nick_full;
        gdouble def;

        def = properties[i].default_value.data.color.r;
        /* If the default is out of range we use 0.0 */
        if (!(def <= 1.0 && def >= 0.0))
          def = 0.0;
        prop_name_full = g_strconcat (prop_name, "-r", NULL);
        prop_nick_full = g_strconcat (param_info->name, " (R)", NULL);
        g_object_class_install_property (gobject_class, count++,
            g_param_spec_float (prop_name_full, prop_nick_full,
                param_info->explanation, 0.0, 1.0, def,
                G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
        g_free (prop_name_full);
        g_free (prop_nick_full);

        def = properties[i].default_value.data.color.g;
        /* If the default is out of range we use 0.0 */
        if (!(def <= 1.0 && def >= 0.0))
          def = 0.0;
        prop_name_full = g_strconcat (prop_name, "-g", NULL);
        prop_nick_full = g_strconcat (param_info->name, " (G)", NULL);
        g_object_class_install_property (gobject_class, count++,
            g_param_spec_float (prop_name_full, prop_nick_full,
                param_info->explanation, 0.0, 1.0, def,
                G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
        g_free (prop_name_full);
        g_free (prop_nick_full);

        def = properties[i].default_value.data.color.b;
        /* If the default is out of range we use 0.0 */
        if (!(def <= 1.0 && def >= 0.0))
          def = 0.0;
        prop_name_full = g_strconcat (prop_name, "-b", NULL);
        prop_nick_full = g_strconcat (param_info->name, " (B)", NULL);
        g_object_class_install_property (gobject_class, count++,
            g_param_spec_float (prop_name_full, prop_nick_full,
                param_info->explanation, 0.0, 1.0, def,
                G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
        g_free (prop_name_full);
        g_free (prop_nick_full);

        properties[i].n_prop_ids = 3;
        break;
      }
      case F0R_PARAM_POSITION:{
        gchar *prop_name_full;
        gchar *prop_nick_full;
        gdouble def;

        def = properties[i].default_value.data.position.x;
        /* If the default is out of range we use 0.0 */
        if (!(def <= 1.0 && def >= 0.0))
          def = 0.0;
        prop_name_full = g_strconcat (prop_name, "-x", NULL);
        prop_nick_full = g_strconcat (param_info->name, " (X)", NULL);
        g_object_class_install_property (gobject_class, count++,
            g_param_spec_double (prop_name_full, prop_nick_full,
                param_info->explanation, 0.0, 1.0, def,
                G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
        g_free (prop_name_full);
        g_free (prop_nick_full);

        def = properties[i].default_value.data.position.y;
        /* If the default is out of range we use 0.0 */
        if (!(def <= 1.0 && def >= 0.0))
          def = 0.0;
        prop_name_full = g_strconcat (prop_name, "-Y", NULL);
        prop_nick_full = g_strconcat (param_info->name, " (Y)", NULL);
        g_object_class_install_property (gobject_class, count++,
            g_param_spec_double (prop_name_full, prop_nick_full,
                param_info->explanation, 0.0, 1.0, def,
                G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
        g_free (prop_name_full);
        g_free (prop_nick_full);

        properties[i].n_prop_ids = 2;
        break;
      }
      default:
        g_assert_not_reached ();
        break;
    }

    g_free (prop_name);
  }

  ftable->destruct (instance);
}

GstFrei0rPropertyValue *
gst_frei0r_property_cache_init (GstFrei0rProperty * properties,
    gint n_properties)
{
  gint i;
  GstFrei0rPropertyValue *ret = g_new0 (GstFrei0rPropertyValue, n_properties);

  for (i = 0; i < n_properties; i++) {
    memcpy (&ret[i].data, &properties[i].default_value,
        sizeof (GstFrei0rPropertyValue));

    if (properties[i].info.type == F0R_PARAM_STRING)
      ret[i].data.s = g_strdup (ret[i].data.s);
  }

  return ret;
}

void
gst_frei0r_property_cache_free (GstFrei0rProperty * properties,
    GstFrei0rPropertyValue * property_cache, gint n_properties)
{
  gint i;

  for (i = 0; i < n_properties; i++) {
    if (properties[i].info.type == F0R_PARAM_STRING)
      g_free (property_cache[i].data.s);
  }
  g_free (property_cache);
}

f0r_instance_t *
gst_frei0r_instance_construct (GstFrei0rFuncTable * ftable,
    GstFrei0rProperty * properties, gint n_properties,
    GstFrei0rPropertyValue * property_cache, gint width, gint height)
{
  f0r_instance_t *instance = ftable->construct (width, height);
  gint i;

  for (i = 0; i < n_properties; i++)
    ftable->set_param_value (instance, &property_cache[i].data, i);

  return instance;
}

gboolean
gst_frei0r_get_property (f0r_instance_t * instance, GstFrei0rFuncTable * ftable,
    GstFrei0rProperty * properties, gint n_properties,
    GstFrei0rPropertyValue * property_cache, guint prop_id, GValue * value)
{
  gint i;
  GstFrei0rProperty *prop = NULL;

  for (i = 0; i < n_properties; i++) {
    if (properties[i].prop_id <= prop_id &&
        properties[i].prop_id + properties[i].n_prop_ids > prop_id) {
      prop = &properties[i];
      break;
    }
  }

  if (!prop)
    return FALSE;

  switch (prop->info.type) {
    case F0R_PARAM_BOOL:{
      gdouble d;

      if (instance)
        ftable->get_param_value (instance, &d, prop->prop_idx);
      else
        d = property_cache[prop->prop_idx].data.b;

      g_value_set_boolean (value, (d < 0.5) ? FALSE : TRUE);
      break;
    }
    case F0R_PARAM_DOUBLE:{
      gdouble d;

      if (instance)
        ftable->get_param_value (instance, &d, prop->prop_idx);
      else
        d = property_cache[prop->prop_idx].data.d;

      g_value_set_double (value, d);
      break;
    }
    case F0R_PARAM_STRING:{
      gchar *s;

      if (instance)
        ftable->get_param_value (instance, &s, prop->prop_idx);
      else
        s = property_cache[prop->prop_idx].data.s;
      g_value_set_string (value, s);
      break;
    }
    case F0R_PARAM_COLOR:{
      f0r_param_color_t color;

      if (instance)
        ftable->get_param_value (instance, &color, prop->prop_idx);
      else
        color = property_cache[prop->prop_idx].data.color;

      switch (prop_id - prop->prop_id) {
        case 0:
          g_value_set_float (value, color.r);
          break;
        case 1:
          g_value_set_float (value, color.g);
          break;
        case 2:
          g_value_set_float (value, color.b);
          break;
      }
      break;
    }
    case F0R_PARAM_POSITION:{
      f0r_param_position_t position;

      if (instance)
        ftable->get_param_value (instance, &position, prop->prop_idx);
      else
        position = property_cache[prop->prop_idx].data.position;

      switch (prop_id - prop->prop_id) {
        case 0:
          g_value_set_double (value, position.x);
          break;
        case 1:
          g_value_set_double (value, position.y);
          break;
      }
      break;
    }
    default:
      g_assert_not_reached ();
      break;
  }

  return TRUE;
}

gboolean
gst_frei0r_set_property (f0r_instance_t * instance, GstFrei0rFuncTable * ftable,
    GstFrei0rProperty * properties, gint n_properties,
    GstFrei0rPropertyValue * property_cache, guint prop_id,
    const GValue * value)
{
  GstFrei0rProperty *prop = NULL;
  gint i;

  for (i = 0; i < n_properties; i++) {
    if (properties[i].prop_id <= prop_id &&
        properties[i].prop_id + properties[i].n_prop_ids > prop_id) {
      prop = &properties[i];
      break;
    }
  }

  if (!prop)
    return FALSE;

  switch (prop->info.type) {
    case F0R_PARAM_BOOL:{
      gboolean b = g_value_get_boolean (value);
      gdouble d = b ? 1.0 : 0.0;

      if (instance)
        ftable->set_param_value (instance, &d, prop->prop_idx);
      property_cache[prop->prop_idx].data.b = d;
      break;
    }
    case F0R_PARAM_DOUBLE:{
      gdouble d = g_value_get_double (value);

      if (instance)
        ftable->set_param_value (instance, &d, prop->prop_idx);
      property_cache[prop->prop_idx].data.d = d;
      break;
    }
    case F0R_PARAM_STRING:{
      gchar *s = g_value_dup_string (value);

      /* Copies the string */
      if (instance)
        ftable->set_param_value (instance, s, prop->prop_idx);
      property_cache[prop->prop_idx].data.s = s;
      break;
    }
    case F0R_PARAM_COLOR:{
      gfloat f = g_value_get_float (value);
      f0r_param_color_t *color = &property_cache[prop->prop_idx].data.color;

      switch (prop_id - prop->prop_id) {
        case 0:
          color->r = f;
          break;
        case 1:
          color->g = f;
          break;
        case 2:
          color->b = f;
          break;
        default:
          g_assert_not_reached ();
      }

      if (instance)
        ftable->set_param_value (instance, color, prop->prop_idx);
      break;
    }
    case F0R_PARAM_POSITION:{
      gdouble d = g_value_get_double (value);
      f0r_param_position_t *position =
          &property_cache[prop->prop_idx].data.position;

      switch (prop_id - prop->prop_id) {
        case 0:
          position->x = d;
          break;
        case 1:
          position->y = d;
          break;
        default:
          g_assert_not_reached ();
      }
      if (instance)
        ftable->set_param_value (instance, position, prop->prop_idx);
      break;
    }
    default:
      g_assert_not_reached ();
      break;
  }

  return TRUE;
}

static gboolean
register_plugin (GstPlugin * plugin, const gchar * vendor,
    const gchar * filename)
{
  GModule *module;
  GstFrei0rPluginRegisterReturn ret = GST_FREI0R_PLUGIN_REGISTER_RETURN_FAILED;
  GstFrei0rFuncTable ftable = { NULL, };
  gint i;
  f0r_plugin_info_t info = { NULL, };
  f0r_instance_t *instance = NULL;

  GST_DEBUG ("Registering plugin '%s'", filename);

  module = g_module_open (filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
  if (!module) {
    GST_WARNING ("Failed to load plugin");
    return FALSE;
  }

  if (!g_module_symbol (module, "f0r_init", (gpointer *) & ftable.init)) {
    GST_INFO ("No frei0r plugin");
    g_module_close (module);
    return FALSE;
  }

  if (!g_module_symbol (module, "f0r_deinit", (gpointer *) & ftable.deinit) ||
      !g_module_symbol (module, "f0r_construct",
          (gpointer *) & ftable.construct)
      || !g_module_symbol (module, "f0r_destruct",
          (gpointer *) & ftable.destruct)
      || !g_module_symbol (module, "f0r_get_plugin_info",
          (gpointer *) & ftable.get_plugin_info)
      || !g_module_symbol (module, "f0r_get_param_info",
          (gpointer *) & ftable.get_param_info)
      || !g_module_symbol (module, "f0r_set_param_value",
          (gpointer *) & ftable.set_param_value)
      || !g_module_symbol (module, "f0r_get_param_value",
          (gpointer *) & ftable.get_param_value))
    goto invalid_frei0r_plugin;

  /* One of these must exist */
  g_module_symbol (module, "f0r_update", (gpointer *) & ftable.update);
  g_module_symbol (module, "f0r_update2", (gpointer *) & ftable.update2);

  if (!ftable.init ()) {
    GST_WARNING ("Failed to initialize plugin");
    g_module_close (module);
    return FALSE;
  }

  if (!ftable.update && !ftable.update2)
    goto invalid_frei0r_plugin;

  ftable.get_plugin_info (&info);

  if (info.frei0r_version > 1) {
    GST_WARNING ("Unsupported frei0r version %d", info.frei0r_version);
    ftable.deinit ();
    g_module_close (module);
    return FALSE;
  }

  if (info.color_model > F0R_COLOR_MODEL_PACKED32) {
    GST_WARNING ("Unsupported color model %d", info.color_model);
    ftable.deinit ();
    g_module_close (module);
    return FALSE;
  }

  for (i = 0; i < info.num_params; i++) {
    f0r_param_info_t pinfo = { NULL, };

    ftable.get_param_info (&pinfo, i);
    if (pinfo.type > F0R_PARAM_STRING) {
      GST_WARNING ("Unsupported parameter type %d", pinfo.type);
      ftable.deinit ();
      g_module_close (module);
      return FALSE;
    }
  }

  instance = ftable.construct (640, 480);
  if (!instance) {
    GST_WARNING ("Failed to instanciate plugin '%s'", info.name);
    ftable.deinit ();
    g_module_close (module);
    return FALSE;
  }
  ftable.destruct (instance);

  switch (info.plugin_type) {
    case F0R_PLUGIN_TYPE_FILTER:
      ret = gst_frei0r_filter_register (plugin, vendor, &info, &ftable);
      break;
    case F0R_PLUGIN_TYPE_SOURCE:
      ret = gst_frei0r_src_register (plugin, vendor, &info, &ftable);
      break;
    case F0R_PLUGIN_TYPE_MIXER2:
    case F0R_PLUGIN_TYPE_MIXER3:
      ret = gst_frei0r_mixer_register (plugin, vendor, &info, &ftable);
      break;
    default:
      break;
  }

  switch (ret) {
    case GST_FREI0R_PLUGIN_REGISTER_RETURN_OK:
      return TRUE;
    case GST_FREI0R_PLUGIN_REGISTER_RETURN_FAILED:
      GST_ERROR ("Failed to register frei0r plugin");
      ftable.deinit ();
      g_module_close (module);
      return FALSE;
    case GST_FREI0R_PLUGIN_REGISTER_RETURN_ALREADY_REGISTERED:
      GST_DEBUG ("frei0r plugin already registered");
      ftable.deinit ();
      g_module_close (module);
      return TRUE;
    default:
      g_return_val_if_reached (FALSE);
  }

  g_return_val_if_reached (FALSE);

invalid_frei0r_plugin:
  GST_ERROR ("Invalid frei0r plugin");
  ftable.deinit ();
  g_module_close (module);

  return FALSE;
}

static gboolean
register_plugins (GstPlugin * plugin, GHashTable * plugin_names,
    const gchar * path, const gchar * base_path)
{
  GDir *dir;
  gchar *filename;
  const gchar *entry_name;
  gboolean ret = TRUE;

  GST_DEBUG ("Scanning directory '%s' for frei0r plugins", path);

  dir = g_dir_open (path, 0, NULL);
  if (!dir)
    return FALSE;

  while ((entry_name = g_dir_read_name (dir))) {
    gchar *tmp, *vendor = NULL;
    gchar *hashtable_name;

    tmp = g_strdup (path + strlen (base_path));
    if (*tmp == G_DIR_SEPARATOR && *(tmp + 1))
      vendor = tmp + 1;
    else if (*tmp)
      vendor = tmp;

    if (vendor)
      hashtable_name = g_strconcat (vendor, "-", entry_name, NULL);
    else
      hashtable_name = g_strdup (entry_name);

    if (g_hash_table_lookup_extended (plugin_names, hashtable_name, NULL, NULL)) {
      g_free (hashtable_name);
      continue;
    }

    filename = g_build_filename (path, entry_name, NULL);
    if ((g_str_has_suffix (filename, G_MODULE_SUFFIX)
#ifdef GST_EXTRA_MODULE_SUFFIX
            || g_str_has_suffix (filename, GST_EXTRA_MODULE_SUFFIX)
#endif
        ) && g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
      gboolean this_ret;

      this_ret = register_plugin (plugin, vendor, filename);
      if (this_ret)
        g_hash_table_insert (plugin_names, g_strdup (hashtable_name), NULL);

      ret = ret && this_ret;
    } else if (g_file_test (filename, G_FILE_TEST_IS_DIR)) {
      ret = ret && register_plugins (plugin, plugin_names, filename, base_path);
    }
    g_free (filename);
    g_free (hashtable_name);
    g_free (tmp);
  }
  g_dir_close (dir);

  return ret;
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  const gchar *homedir;
  gchar *path, *libdir_path;
  GHashTable *plugin_names;
  const gchar *frei0r_path;

  GST_DEBUG_CATEGORY_INIT (frei0r_debug, "frei0r", 0, "frei0r");

  gst_plugin_add_dependency_simple (plugin,
      "FREI0R_PATH:HOME/.frei0r-1/lib",
      LIBDIR "/frei0r-1:"
      "/usr/lib/frei0r-1:/usr/local/lib/frei0r-1:"
      "/usr/lib32/frei0r-1:/usr/local/lib32/frei0r-1:"
      "/usr/lib64/frei0r-1:/usr/local/lib64/frei0r-1",
      NULL, GST_PLUGIN_DEPENDENCY_FLAG_RECURSE);

  plugin_names =
      g_hash_table_new_full ((GHashFunc) g_str_hash, (GEqualFunc) g_str_equal,
      (GDestroyNotify) g_free, NULL);

  frei0r_path = g_getenv ("FREI0R_PATH");
  if (frei0r_path && *frei0r_path) {
    gchar **p, **paths = g_strsplit (frei0r_path, ":", -1);

    for (p = paths; *p; p++) {
      register_plugins (plugin, plugin_names, *p, *p);
    }

    g_strfreev (paths);
  } else {
#define register_plugins2(plugin, pn, p) register_plugins(plugin, pn, p, p)
    homedir = g_get_home_dir ();
    path = g_build_filename (homedir, ".frei0r-1", "lib", NULL);
    libdir_path = g_build_filename (LIBDIR, "frei0r-1", NULL);
    register_plugins2 (plugin, plugin_names, path);
    g_free (path);
    register_plugins2 (plugin, plugin_names, libdir_path);
    g_free (libdir_path);
    register_plugins2 (plugin, plugin_names, "/usr/local/lib/frei0r-1");
    register_plugins2 (plugin, plugin_names, "/usr/lib/frei0r-1");
    register_plugins2 (plugin, plugin_names, "/usr/local/lib32/frei0r-1");
    register_plugins2 (plugin, plugin_names, "/usr/lib32/frei0r-1");
    register_plugins2 (plugin, plugin_names, "/usr/local/lib64/frei0r-1");
    register_plugins2 (plugin, plugin_names, "/usr/lib64/frei0r-1");
#undef register_plugins2
  }

  g_hash_table_unref (plugin_names);

  return TRUE;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    frei0r,
    "frei0r plugin library",
    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
