/*
 * GStreamer
 * Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
 *
 * 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 <gst/video/videooverlay.h>
#include <gst/video/navigation.h>

#include "gstglsinkbin.h"

GST_DEBUG_CATEGORY (gst_debug_gl_sink_bin);
#define GST_CAT_DEFAULT gst_debug_gl_sink_bin

static void gst_gl_sink_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * param_spec);
static void gst_gl_sink_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * param_spec);

static GstStateChangeReturn gst_gl_sink_bin_change_state (GstElement * element,
    GstStateChange transition);

static void gst_gl_sink_bin_video_overlay_init (gpointer g_iface,
    gpointer g_iface_data);
static void gst_gl_sink_bin_navigation_interface_init (gpointer g_iface,
    gpointer g_iface_data);
static void gst_gl_sink_bin_color_balance_init (gpointer g_iface,
    gpointer g_iface_data);

#define DEFAULT_SYNC                TRUE
#define DEFAULT_MAX_LATENESS        -1
#define DEFAULT_QOS                 FALSE
#define DEFAULT_ASYNC               TRUE
#define DEFAULT_TS_OFFSET           0
#define DEFAULT_BLOCKSIZE           4096
#define DEFAULT_RENDER_DELAY        0
#define DEFAULT_ENABLE_LAST_SAMPLE  TRUE
#define DEFAULT_THROTTLE_TIME       0
#define DEFAULT_MAX_BITRATE         0

/* GstGLColorBalance properties */
#define DEFAULT_PROP_CONTRAST       1.0
#define DEFAULT_PROP_BRIGHTNESS	    0.0
#define DEFAULT_PROP_HUE            0.0
#define DEFAULT_PROP_SATURATION	    1.0

enum
{
  PROP_0,
  PROP_FORCE_ASPECT_RATIO,
  PROP_SINK,
  PROP_SYNC,
  PROP_MAX_LATENESS,
  PROP_QOS,
  PROP_ASYNC,
  PROP_TS_OFFSET,
  PROP_ENABLE_LAST_SAMPLE,
  PROP_LAST_SAMPLE,
  PROP_BLOCKSIZE,
  PROP_RENDER_DELAY,
  PROP_THROTTLE_TIME,
  PROP_MAX_BITRATE,
  PROP_CONTRAST,
  PROP_BRIGHTNESS,
  PROP_HUE,
  PROP_SATURATION,
};

enum
{
  SIGNAL_0,
  SIGNAL_CREATE_ELEMENT,
  SIGNAL_LAST,
};

static guint gst_gl_sink_bin_signals[SIGNAL_LAST] = { 0, };

#define gst_gl_sink_bin_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLSinkBin, gst_gl_sink_bin,
    GST_TYPE_BIN, G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY,
        gst_gl_sink_bin_video_overlay_init);
    G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION,
        gst_gl_sink_bin_navigation_interface_init);
    G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE,
        gst_gl_sink_bin_color_balance_init)
    GST_DEBUG_CATEGORY_INIT (gst_debug_gl_sink_bin, "glimagesink", 0,
        "OpenGL Video Sink Bin"));

static void
gst_gl_sink_bin_class_init (GstGLSinkBinClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;
  GstCaps *upload_caps;

  gobject_class = (GObjectClass *) klass;
  element_class = GST_ELEMENT_CLASS (klass);

  element_class->change_state = gst_gl_sink_bin_change_state;

  gobject_class->set_property = gst_gl_sink_bin_set_property;
  gobject_class->get_property = gst_gl_sink_bin_get_property;

  g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO,
      g_param_spec_boolean ("force-aspect-ratio",
          "Force aspect ratio",
          "When enabled, scaling will respect original aspect ratio", TRUE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_SINK,
      g_param_spec_object ("sink",
          "GL sink element",
          "The GL sink chain to use",
          GST_TYPE_ELEMENT,
          GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE |
          G_PARAM_STATIC_STRINGS));

  /* base sink */
  g_object_class_install_property (gobject_class, PROP_SYNC,
      g_param_spec_boolean ("sync", "Sync", "Sync on the clock", DEFAULT_SYNC,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_MAX_LATENESS,
      g_param_spec_int64 ("max-lateness", "Max Lateness",
          "Maximum number of nanoseconds that a buffer can be late before it "
          "is dropped (-1 unlimited)", -1, G_MAXINT64, DEFAULT_MAX_LATENESS,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_QOS,
      g_param_spec_boolean ("qos", "Qos",
          "Generate Quality-of-Service events upstream", DEFAULT_QOS,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_ASYNC,
      g_param_spec_boolean ("async", "Async",
          "Go asynchronously to PAUSED", DEFAULT_ASYNC,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_TS_OFFSET,
      g_param_spec_int64 ("ts-offset", "TS Offset",
          "Timestamp offset in nanoseconds", G_MININT64, G_MAXINT64,
          DEFAULT_TS_OFFSET, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_ENABLE_LAST_SAMPLE,
      g_param_spec_boolean ("enable-last-sample", "Enable Last Buffer",
          "Enable the last-sample property", DEFAULT_ENABLE_LAST_SAMPLE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_LAST_SAMPLE,
      g_param_spec_boxed ("last-sample", "Last Sample",
          "The last sample received in the sink", GST_TYPE_SAMPLE,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_BLOCKSIZE,
      g_param_spec_uint ("blocksize", "Block size",
          "Size in bytes to pull per buffer (0 = default)", 0, G_MAXUINT,
          DEFAULT_BLOCKSIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_RENDER_DELAY,
      g_param_spec_uint64 ("render-delay", "Render Delay",
          "Additional render delay of the sink in nanoseconds", 0, G_MAXUINT64,
          DEFAULT_RENDER_DELAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_THROTTLE_TIME,
      g_param_spec_uint64 ("throttle-time", "Throttle time",
          "The time to keep between rendered buffers (0 = disabled)", 0,
          G_MAXUINT64, DEFAULT_THROTTLE_TIME,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_MAX_BITRATE,
      g_param_spec_uint64 ("max-bitrate", "Max Bitrate",
          "The maximum bits per second to render (0 = disabled)", 0,
          G_MAXUINT64, DEFAULT_MAX_BITRATE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /* colorbalance */
  g_object_class_install_property (gobject_class, PROP_CONTRAST,
      g_param_spec_double ("contrast", "Contrast", "contrast",
          0.0, 2.0, DEFAULT_PROP_CONTRAST,
          GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_BRIGHTNESS,
      g_param_spec_double ("brightness", "Brightness", "brightness", -1.0, 1.0,
          DEFAULT_PROP_BRIGHTNESS,
          GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_HUE,
      g_param_spec_double ("hue", "Hue", "hue", -1.0, 1.0, DEFAULT_PROP_HUE,
          GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_SATURATION,
      g_param_spec_double ("saturation", "Saturation", "saturation", 0.0, 2.0,
          DEFAULT_PROP_SATURATION,
          GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstGLSinkBin::create-element:
   * @object: the #GstGLSinkBin
   *
   * Will be emitted when we need the processing element/s that this bin will use
   *
   * Returns: a new #GstElement
   */
  gst_gl_sink_bin_signals[SIGNAL_CREATE_ELEMENT] =
      g_signal_new ("create-element", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
      GST_TYPE_ELEMENT, 0);

  gst_element_class_set_metadata (element_class,
      "GL Sink Bin", "Sink/Video",
      "Infrastructure to process GL textures",
      "Matthew Waters <matthew@centricular.com>");

  upload_caps = gst_gl_upload_get_input_template_caps ();
  gst_element_class_add_pad_template (element_class,
      gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, upload_caps));
  gst_caps_unref (upload_caps);
}

static void
gst_gl_sink_bin_init (GstGLSinkBin * self)
{
  gboolean res = TRUE;
  GstPad *pad;

  self->upload = gst_element_factory_make ("glupload", NULL);
  self->convert = gst_element_factory_make ("glcolorconvert", NULL);
  self->balance = gst_element_factory_make ("glcolorbalance", NULL);

  res &= gst_bin_add (GST_BIN (self), self->upload);
  res &= gst_bin_add (GST_BIN (self), self->convert);
  res &= gst_bin_add (GST_BIN (self), self->balance);

  res &= gst_element_link_pads (self->upload, "src", self->convert, "sink");
  res &= gst_element_link_pads (self->convert, "src", self->balance, "sink");

  pad = gst_element_get_static_pad (self->upload, "sink");
  if (!pad) {
    res = FALSE;
  } else {
    GST_DEBUG_OBJECT (self, "setting target sink pad %" GST_PTR_FORMAT, pad);
    self->sinkpad = gst_ghost_pad_new ("sink", pad);
    gst_element_add_pad (GST_ELEMENT_CAST (self), self->sinkpad);
    gst_object_unref (pad);
  }

  gst_gl_object_add_control_binding_proxy (GST_OBJECT (self->balance),
      GST_OBJECT (self), "contrast");
  gst_gl_object_add_control_binding_proxy (GST_OBJECT (self->balance),
      GST_OBJECT (self), "brightness");
  gst_gl_object_add_control_binding_proxy (GST_OBJECT (self->balance),
      GST_OBJECT (self), "hue");
  gst_gl_object_add_control_binding_proxy (GST_OBJECT (self->balance),
      GST_OBJECT (self), "saturation");

  if (!res) {
    GST_WARNING_OBJECT (self, "Failed to add/connect the necessary machinery");
  }
}

static gboolean
_connect_sink_element (GstGLSinkBin * self)
{
  gboolean res = TRUE;

  gst_object_set_name (GST_OBJECT (self->sink), "sink");
  res &= gst_bin_add (GST_BIN (self), self->sink);

  res &= gst_element_link_pads (self->balance, "src", self->sink, "sink");

  if (!res)
    GST_ERROR_OBJECT (self, "Failed to link sink element into the pipeline");

  return res;
}

void
gst_gl_sink_bin_finish_init_with_element (GstGLSinkBin * self,
    GstElement * element)
{
  g_return_if_fail (GST_IS_ELEMENT (element));

  self->sink = element;

  if (!_connect_sink_element (self)) {
    gst_object_unref (self->sink);
    self->sink = NULL;
  }
}

void
gst_gl_sink_bin_finish_init (GstGLSinkBin * self)
{
  GstGLSinkBinClass *klass = GST_GL_SINK_BIN_GET_CLASS (self);
  GstElement *element = NULL;

  if (klass->create_element)
    element = klass->create_element ();

  if (element)
    gst_gl_sink_bin_finish_init_with_element (self, element);
}

static void
gst_gl_sink_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstGLSinkBin *self = GST_GL_SINK_BIN (object);

  switch (prop_id) {
    case PROP_SINK:
    {
      GstElement *sink = g_value_get_object (value);
      if (self->sink)
        gst_bin_remove (GST_BIN (self), self->sink);
      self->sink = sink;
      if (sink) {
        gst_object_ref_sink (sink);
        _connect_sink_element (self);
      }
      break;
    }
    case PROP_CONTRAST:
    case PROP_BRIGHTNESS:
    case PROP_HUE:
    case PROP_SATURATION:
      if (self->balance)
        g_object_set_property (G_OBJECT (self->balance), pspec->name, value);
      break;
    default:
      if (self->sink)
        g_object_set_property (G_OBJECT (self->sink), pspec->name, value);
      break;
  }
}

static void
gst_gl_sink_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstGLSinkBin *self = GST_GL_SINK_BIN (object);

  switch (prop_id) {
    case PROP_SINK:
      g_value_set_object (value, self->sink);
      break;
    case PROP_CONTRAST:
    case PROP_BRIGHTNESS:
    case PROP_HUE:
    case PROP_SATURATION:
      if (self->balance)
        g_object_get_property (G_OBJECT (self->balance), pspec->name, value);
      break;
    default:
      if (self->sink)
        g_object_get_property (G_OBJECT (self->sink), pspec->name, value);
      break;
  }
}

static GstStateChangeReturn
gst_gl_sink_bin_change_state (GstElement * element, GstStateChange transition)
{
  GstGLSinkBin *self = GST_GL_SINK_BIN (element);
  GstGLSinkBinClass *klass = GST_GL_SINK_BIN_GET_CLASS (self);
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;

  GST_DEBUG ("changing state: %s => %s",
      gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
      gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (!self->sink) {
        if (klass->create_element)
          self->sink = klass->create_element ();

        if (!self->sink)
          g_signal_emit (element,
              gst_gl_sink_bin_signals[SIGNAL_CREATE_ELEMENT], 0, &self->sink);

        if (!self->sink) {
          GST_ERROR_OBJECT (element, "Failed to retrieve element");
          return GST_STATE_CHANGE_FAILURE;
        }
        if (!_connect_sink_element (self))
          return GST_STATE_CHANGE_FAILURE;
      }
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    default:
      break;
  }

  return ret;
}

static void
gst_gl_sink_bin_navigation_send_event (GstNavigation * navigation, GstStructure
    * structure)
{
  GstGLSinkBin *self = GST_GL_SINK_BIN (navigation);
  GstElement *nav =
      gst_bin_get_by_interface (GST_BIN (self), GST_TYPE_NAVIGATION);

  if (nav) {
    gst_navigation_send_event (GST_NAVIGATION (nav), structure);
    structure = NULL;
    gst_object_unref (nav);
  } else {
    GstEvent *event = gst_event_new_navigation (structure);
    structure = NULL;
    gst_element_send_event (GST_ELEMENT (self), event);
  }
}

static void
gst_gl_sink_bin_navigation_interface_init (gpointer g_iface,
    gpointer g_iface_data)
{
  GstNavigationInterface *iface = (GstNavigationInterface *) g_iface;
  iface->send_event = gst_gl_sink_bin_navigation_send_event;
}

static void
gst_gl_sink_bin_overlay_expose (GstVideoOverlay * overlay)
{
  GstGLSinkBin *self = GST_GL_SINK_BIN (overlay);
  GstVideoOverlay *overlay_element = NULL;

  overlay_element =
      GST_VIDEO_OVERLAY (gst_bin_get_by_interface (GST_BIN (self),
          GST_TYPE_VIDEO_OVERLAY));

  if (overlay_element) {
    gst_video_overlay_expose (overlay_element);
    gst_object_unref (overlay_element);
  }
}

static void
gst_gl_sink_bin_overlay_handle_events (GstVideoOverlay * overlay,
    gboolean handle_events)
{
  GstGLSinkBin *self = GST_GL_SINK_BIN (overlay);
  GstVideoOverlay *overlay_element = NULL;

  overlay_element =
      GST_VIDEO_OVERLAY (gst_bin_get_by_interface (GST_BIN (self),
          GST_TYPE_VIDEO_OVERLAY));

  if (overlay_element) {
    gst_video_overlay_handle_events (overlay_element, handle_events);
    gst_object_unref (overlay_element);
  }
}

static void
gst_gl_sink_bin_overlay_set_render_rectangle (GstVideoOverlay * overlay, gint x,
    gint y, gint width, gint height)
{
  GstGLSinkBin *self = GST_GL_SINK_BIN (overlay);
  GstVideoOverlay *overlay_element = NULL;

  overlay_element =
      GST_VIDEO_OVERLAY (gst_bin_get_by_interface (GST_BIN (self),
          GST_TYPE_VIDEO_OVERLAY));

  if (overlay_element) {
    gst_video_overlay_set_render_rectangle (overlay_element, x, y, width,
        height);
    gst_object_unref (overlay_element);
  }
}

static void
gst_gl_sink_bin_overlay_set_window_handle (GstVideoOverlay * overlay,
    guintptr handle)
{
  GstGLSinkBin *self = GST_GL_SINK_BIN (overlay);
  GstVideoOverlay *overlay_element = NULL;

  overlay_element =
      GST_VIDEO_OVERLAY (gst_bin_get_by_interface (GST_BIN (self),
          GST_TYPE_VIDEO_OVERLAY));

  if (overlay_element) {
    gst_video_overlay_set_window_handle (overlay_element, handle);
    gst_object_unref (overlay_element);
  }
}

static void
gst_gl_sink_bin_video_overlay_init (gpointer g_iface, gpointer g_iface_data)
{
  GstVideoOverlayInterface *iface = (GstVideoOverlayInterface *) g_iface;
  iface->expose = gst_gl_sink_bin_overlay_expose;
  iface->handle_events = gst_gl_sink_bin_overlay_handle_events;
  iface->set_render_rectangle = gst_gl_sink_bin_overlay_set_render_rectangle;
  iface->set_window_handle = gst_gl_sink_bin_overlay_set_window_handle;
}

static const GList *
gst_gl_sink_bin_color_balance_list_channels (GstColorBalance * balance)
{
  GstGLSinkBin *self = GST_GL_SINK_BIN (balance);
  GstColorBalance *balance_element = NULL;
  const GList *list = NULL;

  balance_element =
      GST_COLOR_BALANCE (gst_bin_get_by_interface (GST_BIN (self),
          GST_TYPE_COLOR_BALANCE));

  if (balance_element) {
    list = gst_color_balance_list_channels (balance_element);
    gst_object_unref (balance_element);
  }

  return list;
}

static void
gst_gl_sink_bin_color_balance_set_value (GstColorBalance * balance,
    GstColorBalanceChannel * channel, gint value)
{
  GstGLSinkBin *self = GST_GL_SINK_BIN (balance);
  GstColorBalance *balance_element = NULL;

  balance_element =
      GST_COLOR_BALANCE (gst_bin_get_by_interface (GST_BIN (self),
          GST_TYPE_COLOR_BALANCE));

  if (balance_element) {
    gst_color_balance_set_value (balance_element, channel, value);
    gst_object_unref (balance_element);
  }
}

static gint
gst_gl_sink_bin_color_balance_get_value (GstColorBalance * balance,
    GstColorBalanceChannel * channel)
{
  GstGLSinkBin *self = GST_GL_SINK_BIN (balance);
  GstColorBalance *balance_element = NULL;
  gint val = 0;

  balance_element =
      GST_COLOR_BALANCE (gst_bin_get_by_interface (GST_BIN (self),
          GST_TYPE_COLOR_BALANCE));

  if (balance_element) {
    val = gst_color_balance_get_value (balance_element, channel);
    gst_object_unref (balance_element);
  }

  return val;
}

static GstColorBalanceType
gst_gl_sink_bin_color_balance_get_balance_type (GstColorBalance * balance)
{
  GstGLSinkBin *self = GST_GL_SINK_BIN (balance);
  GstColorBalance *balance_element = NULL;
  GstColorBalanceType type = 0;

  balance_element =
      GST_COLOR_BALANCE (gst_bin_get_by_interface (GST_BIN (self),
          GST_TYPE_COLOR_BALANCE));

  if (balance_element) {
    type = gst_color_balance_get_balance_type (balance_element);
    gst_object_unref (balance_element);
  }

  return type;
}

static void
gst_gl_sink_bin_color_balance_init (gpointer g_iface, gpointer g_iface_data)
{
  GstColorBalanceInterface *iface = (GstColorBalanceInterface *) g_iface;

  iface->list_channels = gst_gl_sink_bin_color_balance_list_channels;
  iface->set_value = gst_gl_sink_bin_color_balance_set_value;
  iface->get_value = gst_gl_sink_bin_color_balance_get_value;
  iface->get_balance_type = gst_gl_sink_bin_color_balance_get_balance_type;
}
