/*
 * 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)
{
  gst_object_set_name (GST_OBJECT (self->sink), "sink");

  if (gst_bin_add (GST_BIN (self), self->sink) &&
      gst_element_link_pads (self->balance, "src", self->sink, "sink"))
    return TRUE;

  GST_ERROR_OBJECT (self, "Failed to link sink element into the pipeline");
  return FALSE;
}

static void
gst_gl_sink_bin_set_sink (GstGLSinkBin * self, GstElement * sink)
{
  g_return_if_fail (GST_IS_ELEMENT (sink));

  if (self->sink) {
    gst_bin_remove (GST_BIN (self), self->sink);
    self->sink = NULL;
  }

  /* We keep an indirect reference when the element is added */
  self->sink = sink;

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

void
gst_gl_sink_bin_finish_init_with_element (GstGLSinkBin * self,
    GstElement * element)
{
  gst_gl_sink_bin_set_sink (self, element);
}

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_set_sink (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:
      gst_gl_sink_bin_set_sink (self, g_value_get_object (value));
      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;
}
