/*
 * GStreamer
 * Copyright (C) 2015 Thiago Santos <thiagoss@osg.samsung.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.
 */


/**
 * SECTION:element-digitalzoom
 * @title: digitalzoom
 *
 * Does digital zooming by cropping and scaling an image.
 *
 * It is a bin that contains the internal pipeline:
 * videocrop ! videoscale ! capsfilter
 *
 * It keeps monitoring the input caps and when it is set/updated
 * the capsfilter gets set the same caps to guarantee that the same
 * input resolution is provided as output.
 *
 * Exposes the 'zoom' property as a float to allow setting the amount
 * of zoom desired. Zooming is done in the center.
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gst/gst-i18n-plugin.h>
#include "gstdigitalzoom.h"

enum
{
  PROP_0,
  PROP_ZOOM
};

GST_DEBUG_CATEGORY (digital_zoom_debug);
#define GST_CAT_DEFAULT digital_zoom_debug

#define gst_digital_zoom_parent_class parent_class
G_DEFINE_TYPE (GstDigitalZoom, gst_digital_zoom, GST_TYPE_BIN);

static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static void
gst_digital_zoom_update_crop (GstDigitalZoom * self, GstCaps * caps)
{
  gint w2_crop = 0, h2_crop = 0;
  gint left = 0;
  gint right = 0;
  gint top = 0;
  gint bottom = 0;
  gint width, height;
  gfloat zoom;
  GstStructure *structure;

  if (caps == NULL || gst_caps_is_any (caps)) {
    g_object_set (self->capsfilter, "caps", NULL, NULL);
    return;
  }

  structure = gst_caps_get_structure (caps, 0);
  gst_structure_get (structure, "width", G_TYPE_INT, &width, "height",
      G_TYPE_INT, &height, NULL);

  zoom = self->zoom;

  if (self->videocrop) {
    /* Update capsfilters to apply the zoom */
    GST_INFO_OBJECT (self, "zoom: %f, orig size: %dx%d", zoom, width, height);

    if (zoom != 1.0) {
      w2_crop = (width - (gint) (width * 1.0 / zoom)) / 2;
      h2_crop = (height - (gint) (height * 1.0 / zoom)) / 2;

      left += w2_crop;
      right += w2_crop;
      top += h2_crop;
      bottom += h2_crop;

      /* force number of pixels cropped from left to be even, to avoid slow code
       * path on videoscale */
      left &= 0xFFFE;
    }

    GST_INFO_OBJECT (self,
        "sw cropping: left:%d, right:%d, top:%d, bottom:%d", left, right, top,
        bottom);

    g_object_set (self->videocrop, "left", left, "right", right, "top",
        top, "bottom", bottom, NULL);
  }
}

static void
gst_digital_zoom_update_zoom (GstDigitalZoom * self)
{
  GstCaps *caps = NULL;

  if (!self->elements_created)
    return;

  g_object_get (self->capsfilter, "caps", &caps, NULL);
  if (caps) {
    gst_digital_zoom_update_crop (self, caps);
    gst_caps_unref (caps);
  }
}

static void
gst_digital_zoom_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstDigitalZoom *self = GST_DIGITAL_ZOOM_CAST (object);

  switch (prop_id) {
    case PROP_ZOOM:
      self->zoom = g_value_get_float (value);
      GST_DEBUG_OBJECT (self, "Setting zoom: %f", self->zoom);
      gst_digital_zoom_update_zoom (self);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
      break;
  }
}

static void
gst_digital_zoom_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstDigitalZoom *self = GST_DIGITAL_ZOOM_CAST (object);

  switch (prop_id) {
    case PROP_ZOOM:
      g_value_set_float (value, self->zoom);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
      break;
  }
}

static gboolean
gst_digital_zoom_sink_query (GstPad * sink, GstObject * parent,
    GstQuery * query)
{
  GstDigitalZoom *self = GST_DIGITAL_ZOOM_CAST (parent);
  switch (GST_QUERY_TYPE (query)) {
      /* for caps related queries we want to skip videocrop ! videoscale
       * as the digital zoom preserves input dimensions */
    case GST_QUERY_CAPS:
    case GST_QUERY_ACCEPT_CAPS:
      if (self->elements_created)
        return gst_pad_peer_query (self->srcpad, query);
      /* fall through */
    default:
      return gst_pad_query_default (sink, parent, query);
  }
}

static gboolean
gst_digital_zoom_src_query (GstPad * sink, GstObject * parent, GstQuery * query)
{
  GstDigitalZoom *self = GST_DIGITAL_ZOOM_CAST (parent);
  switch (GST_QUERY_TYPE (query)) {
      /* for caps related queries we want to skip videocrop ! videoscale
       * as the digital zoom preserves input dimensions */
    case GST_QUERY_CAPS:
    case GST_QUERY_ACCEPT_CAPS:
      if (self->elements_created)
        return gst_pad_peer_query (self->sinkpad, query);
      /* fall through */
    default:
      return gst_pad_query_default (sink, parent, query);
  }
}

static gboolean
gst_digital_zoom_sink_event (GstPad * sink, GstObject * parent,
    GstEvent * event)
{
  gboolean ret;
  gboolean is_caps;
  GstDigitalZoom *self = GST_DIGITAL_ZOOM_CAST (parent);
  GstCaps *old_caps = NULL;
  GstCaps *caps = NULL;

  is_caps = GST_EVENT_TYPE (event) == GST_EVENT_CAPS;

  if (is_caps) {
    gst_event_parse_caps (event, &caps);
    g_object_get (self->capsfilter, "caps", &old_caps, NULL);
    g_object_set (self->capsfilter, "caps", caps, NULL);
    gst_digital_zoom_update_crop (self, caps);
  }

  ret = gst_pad_event_default (sink, parent, event);

  if (is_caps) {
    if (!ret) {
      gst_digital_zoom_update_crop (self, old_caps);
      g_object_set (self->capsfilter, "caps", old_caps, NULL);
    }

    if (old_caps)
      gst_caps_unref (old_caps);
  }

  return ret;
}

static void
gst_digital_zoom_dispose (GObject * object)
{
  GstDigitalZoom *self = GST_DIGITAL_ZOOM_CAST (object);

  if (self->capsfilter_sinkpad) {
    gst_object_unref (self->capsfilter_sinkpad);
    self->capsfilter_sinkpad = NULL;
  }

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

static void
gst_digital_zoom_init (GstDigitalZoom * self)
{
  GstPadTemplate *tmpl;

  tmpl = gst_static_pad_template_get (&src_template);
  self->srcpad = gst_ghost_pad_new_no_target_from_template ("src", tmpl);
  gst_element_add_pad (GST_ELEMENT (self), self->srcpad);
  gst_object_unref (tmpl);

  tmpl = gst_static_pad_template_get (&sink_template);
  self->sinkpad = gst_ghost_pad_new_no_target_from_template ("sink", tmpl);
  gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);
  gst_object_unref (tmpl);

  gst_pad_set_event_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_digital_zoom_sink_event));
  gst_pad_set_query_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_digital_zoom_sink_query));

  gst_pad_set_query_function (self->srcpad,
      GST_DEBUG_FUNCPTR (gst_digital_zoom_src_query));

  self->zoom = 1;
}

static GstElement *
zoom_create_element (GstDigitalZoom * self, const gchar * element_name,
    const gchar * name)
{
  GstElement *element;
  element = gst_element_factory_make (element_name, name);
  if (element == NULL) {
    GST_ELEMENT_ERROR (self, CORE, MISSING_PLUGIN,
        (_("Missing element '%s' - check your GStreamer installation."),
            element_name), (NULL));
  }
  return element;
}

static gboolean
gst_digital_zoom_create_elements (GstDigitalZoom * self)
{
  GstPad *pad;

  if (self->elements_created)
    return TRUE;

  self->videocrop = zoom_create_element (self, "videocrop", "zoom-videocrop");
  if (self->videocrop == NULL)
    return FALSE;
  if (!gst_bin_add (GST_BIN_CAST (self), self->videocrop))
    return FALSE;

  self->videoscale =
      zoom_create_element (self, "videoscale", "zoom-videoscale");
  if (self->videoscale == NULL)
    return FALSE;
  if (!gst_bin_add (GST_BIN_CAST (self), self->videoscale))
    return FALSE;

  self->capsfilter =
      zoom_create_element (self, "capsfilter", "zoom-capsfilter");
  if (self->capsfilter == NULL)
    return FALSE;
  if (!gst_bin_add (GST_BIN_CAST (self), self->capsfilter))
    return FALSE;

  if (!gst_element_link_pads_full (self->videocrop, "src", self->videoscale,
          "sink", GST_PAD_LINK_CHECK_CAPS))
    return FALSE;
  if (!gst_element_link_pads_full (self->videoscale, "src", self->capsfilter,
          "sink", GST_PAD_LINK_CHECK_CAPS))
    return FALSE;

  pad = gst_element_get_static_pad (self->videocrop, "sink");
  gst_ghost_pad_set_target (GST_GHOST_PAD (self->sinkpad), pad);
  gst_object_unref (pad);

  pad = gst_element_get_static_pad (self->capsfilter, "src");
  gst_ghost_pad_set_target (GST_GHOST_PAD (self->srcpad), pad);
  gst_object_unref (pad);

  self->capsfilter_sinkpad =
      gst_element_get_static_pad (self->capsfilter, "sink");

  self->elements_created = TRUE;
  return TRUE;
}

static GstStateChangeReturn
gst_digital_zoom_change_state (GstElement * element, GstStateChange trans)
{
  GstDigitalZoom *self = GST_DIGITAL_ZOOM_CAST (element);

  switch (trans) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (!gst_digital_zoom_create_elements (self)) {
        return GST_STATE_CHANGE_FAILURE;
      }
      break;
    default:
      break;
  }

  return GST_ELEMENT_CLASS (parent_class)->change_state (element, trans);
}

static void
gst_digital_zoom_class_init (GstDigitalZoomClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);

  gobject_class->dispose = gst_digital_zoom_dispose;
  gobject_class->set_property = gst_digital_zoom_set_property;
  gobject_class->get_property = gst_digital_zoom_get_property;

  /* g_object_class_install_property .... */
  g_object_class_install_property (gobject_class, PROP_ZOOM,
      g_param_spec_float ("zoom", "Zoom",
          "Digital zoom level to be used", 1.0, G_MAXFLOAT, 1.0,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  gstelement_class->change_state = gst_digital_zoom_change_state;

  GST_DEBUG_CATEGORY_INIT (digital_zoom_debug, "digitalzoom",
      0, "digital zoom");

  gst_element_class_add_static_pad_template (gstelement_class, &sink_template);
  gst_element_class_add_static_pad_template (gstelement_class, &src_template);

  gst_element_class_set_static_metadata (gstelement_class,
      "Digital zoom bin", "Generic/Video",
      "Digital zoom bin", "Thiago Santos <thiagoss@osg.samsung.com>");
}
