/* GStreamer
 *
 * Copyright (C) 2014-2015 Sebastian Dröge <sebastian@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.
 */

/**
 * SECTION:gstplayer-videooverlayvideorenderer
 * @title: GstPlayerVideoOverlayVideoRenderer
 * @short_description: Player Video Overlay Video Renderer
 *
 */

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

#include "gstplayer-video-overlay-video-renderer.h"
#include "gstplayer.h"

#include <gst/video/video.h>

struct _GstPlayerVideoOverlayVideoRenderer
{
  GObject parent;

  GstVideoOverlay *video_overlay;
  gpointer window_handle;
  gint x, y, width, height;

  GstElement *video_sink;       /* configured video sink, or NULL      */
};

struct _GstPlayerVideoOverlayVideoRendererClass
{
  GObjectClass parent_class;
};

static void
    gst_player_video_overlay_video_renderer_interface_init
    (GstPlayerVideoRendererInterface * iface);

enum
{
  VIDEO_OVERLAY_VIDEO_RENDERER_PROP_0,
  VIDEO_OVERLAY_VIDEO_RENDERER_PROP_WINDOW_HANDLE,
  VIDEO_OVERLAY_VIDEO_RENDERER_PROP_VIDEO_SINK,
  VIDEO_OVERLAY_VIDEO_RENDERER_PROP_LAST
};

G_DEFINE_TYPE_WITH_CODE (GstPlayerVideoOverlayVideoRenderer,
    gst_player_video_overlay_video_renderer, G_TYPE_OBJECT,
    G_IMPLEMENT_INTERFACE (GST_TYPE_PLAYER_VIDEO_RENDERER,
        gst_player_video_overlay_video_renderer_interface_init));

static GParamSpec
    * video_overlay_video_renderer_param_specs
    [VIDEO_OVERLAY_VIDEO_RENDERER_PROP_LAST] = { NULL, };

static void
gst_player_video_overlay_video_renderer_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstPlayerVideoOverlayVideoRenderer *self =
      GST_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER (object);

  switch (prop_id) {
    case VIDEO_OVERLAY_VIDEO_RENDERER_PROP_WINDOW_HANDLE:
      self->window_handle = g_value_get_pointer (value);
      if (self->video_overlay)
        gst_video_overlay_set_window_handle (self->video_overlay,
            (guintptr) self->window_handle);
      break;
    case VIDEO_OVERLAY_VIDEO_RENDERER_PROP_VIDEO_SINK:
      self->video_sink = gst_object_ref_sink (g_value_get_object (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_player_video_overlay_video_renderer_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstPlayerVideoOverlayVideoRenderer *self =
      GST_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER (object);

  switch (prop_id) {
    case VIDEO_OVERLAY_VIDEO_RENDERER_PROP_WINDOW_HANDLE:
      g_value_set_pointer (value, self->window_handle);
      break;
    case VIDEO_OVERLAY_VIDEO_RENDERER_PROP_VIDEO_SINK:
      g_value_set_object (value, self->video_sink);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_player_video_overlay_video_renderer_finalize (GObject * object)
{
  GstPlayerVideoOverlayVideoRenderer *self =
      GST_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER (object);

  if (self->video_overlay)
    gst_object_unref (self->video_overlay);

  if (self->video_sink)
    gst_object_unref (self->video_sink);

  G_OBJECT_CLASS
      (gst_player_video_overlay_video_renderer_parent_class)->finalize (object);
}

static void
    gst_player_video_overlay_video_renderer_class_init
    (GstPlayerVideoOverlayVideoRendererClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->set_property =
      gst_player_video_overlay_video_renderer_set_property;
  gobject_class->get_property =
      gst_player_video_overlay_video_renderer_get_property;
  gobject_class->finalize = gst_player_video_overlay_video_renderer_finalize;

  video_overlay_video_renderer_param_specs
      [VIDEO_OVERLAY_VIDEO_RENDERER_PROP_WINDOW_HANDLE] =
      g_param_spec_pointer ("window-handle", "Window Handle",
      "Window handle to embed the video into",
      G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);

  video_overlay_video_renderer_param_specs
      [VIDEO_OVERLAY_VIDEO_RENDERER_PROP_VIDEO_SINK] =
      g_param_spec_object ("video-sink", "Video Sink",
      "the video output element to use (NULL = default sink)",
      GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);

  g_object_class_install_properties (gobject_class,
      VIDEO_OVERLAY_VIDEO_RENDERER_PROP_LAST,
      video_overlay_video_renderer_param_specs);
}

static void
    gst_player_video_overlay_video_renderer_init
    (GstPlayerVideoOverlayVideoRenderer * self)
{
  self->x = self->y = self->width = self->height = -1;
  self->video_sink = NULL;
}

static GstElement *gst_player_video_overlay_video_renderer_create_video_sink
    (GstPlayerVideoRenderer * iface, GstPlayer * player)
{
  GstElement *video_overlay;
  GstPlayerVideoOverlayVideoRenderer *self =
      GST_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER (iface);

  if (self->video_overlay)
    gst_object_unref (self->video_overlay);

  video_overlay = gst_player_get_pipeline (player);
  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY (video_overlay), NULL);

  self->video_overlay = GST_VIDEO_OVERLAY (video_overlay);

  gst_video_overlay_set_window_handle (self->video_overlay,
      (guintptr) self->window_handle);
  if (self->width != -1 || self->height != -1)
    gst_video_overlay_set_render_rectangle (self->video_overlay, self->x,
        self->y, self->width, self->height);

  return self->video_sink;
}

static void
    gst_player_video_overlay_video_renderer_interface_init
    (GstPlayerVideoRendererInterface * iface)
{
  iface->create_video_sink =
      gst_player_video_overlay_video_renderer_create_video_sink;
}

/**
 * gst_player_video_overlay_video_renderer_new:
 * @window_handle: (allow-none): Window handle to use or %NULL
 *
 * Returns: (transfer full):
 */
GstPlayerVideoRenderer *
gst_player_video_overlay_video_renderer_new (gpointer window_handle)
{
  return g_object_new (GST_TYPE_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER,
      "window-handle", window_handle, NULL);
}

/**
 * gst_player_video_overlay_video_renderer_new_with_sink:
 * @window_handle: (allow-none): Window handle to use or %NULL
 * @video_sink: (transfer floating): the custom video_sink element to be set for the video renderer
 *
 * Returns: (transfer full):
 *
 * Since 1.12
 */
GstPlayerVideoRenderer *
gst_player_video_overlay_video_renderer_new_with_sink (gpointer window_handle,
    GstElement * video_sink)
{
  return g_object_new (GST_TYPE_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER,
      "window-handle", window_handle, "video-sink", video_sink, NULL);
}

/**
 * gst_player_video_overlay_video_renderer_set_window_handle:
 * @self: #GstPlayerVideoRenderer instance
 * @window_handle: handle referencing to the platform specific window
 *
 * Sets the platform specific window handle into which the video
 * should be rendered
 **/
void gst_player_video_overlay_video_renderer_set_window_handle
    (GstPlayerVideoOverlayVideoRenderer * self, gpointer window_handle)
{
  g_return_if_fail (GST_IS_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER (self));

  g_object_set (self, "window-handle", window_handle, NULL);
}

/**
 * gst_player_video_overlay_video_renderer_get_window_handle:
 * @self: #GstPlayerVideoRenderer instance
 *
 * Returns: (transfer none): The currently set, platform specific window
 * handle
 */
gpointer
    gst_player_video_overlay_video_renderer_get_window_handle
    (GstPlayerVideoOverlayVideoRenderer * self) {
  gpointer window_handle;

  g_return_val_if_fail (GST_IS_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER (self),
      NULL);

  g_object_get (self, "window-handle", &window_handle, NULL);

  return window_handle;
}

/**
 * gst_player_video_overlay_video_renderer_expose:
 * @self: a #GstPlayerVideoOverlayVideoRenderer instance.
 *
 * Tell an overlay that it has been exposed. This will redraw the current frame
 * in the drawable even if the pipeline is PAUSED.
 */
void gst_player_video_overlay_video_renderer_expose
    (GstPlayerVideoOverlayVideoRenderer * self)
{
  g_return_if_fail (GST_IS_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER (self));

  if (self->video_overlay)
    gst_video_overlay_expose (self->video_overlay);
}

/**
 * gst_player_video_overlay_video_renderer_set_render_rectangle:
 * @self: a #GstPlayerVideoOverlayVideoRenderer instance
 * @x: the horizontal offset of the render area inside the window
 * @y: the vertical offset of the render area inside the window
 * @width: the width of the render area inside the window
 * @height: the height of the render area inside the window
 *
 * Configure a subregion as a video target within the window set by
 * gst_player_video_overlay_video_renderer_set_window_handle(). If this is not
 * used or not supported the video will fill the area of the window set as the
 * overlay to 100%. By specifying the rectangle, the video can be overlaid to
 * a specific region of that window only. After setting the new rectangle one
 * should call gst_player_video_overlay_video_renderer_expose() to force a
 * redraw. To unset the region pass -1 for the @width and @height parameters.
 *
 * This method is needed for non fullscreen video overlay in UI toolkits that
 * do not support subwindows.
 *
 */
void gst_player_video_overlay_video_renderer_set_render_rectangle
    (GstPlayerVideoOverlayVideoRenderer * self, gint x, gint y, gint width,
    gint height)
{
  g_return_if_fail (GST_IS_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER (self));

  self->x = x;
  self->y = y;
  self->width = width;
  self->height = height;

  if (self->video_overlay)
    gst_video_overlay_set_render_rectangle (self->video_overlay,
        x, y, width, height);
}

/**
 * gst_player_video_overlay_video_renderer_get_render_rectangle:
 * @self: a #GstPlayerVideoOverlayVideoRenderer instance
 * @x: (out) (allow-none): the horizontal offset of the render area inside the window
 * @y: (out) (allow-none): the vertical offset of the render area inside the window
 * @width: (out) (allow-none): the width of the render area inside the window
 * @height: (out) (allow-none): the height of the render area inside the window
 *
 * Return the currently configured render rectangle. See gst_player_video_overlay_video_renderer_set_render_rectangle()
 * for details.
 *
 */
void gst_player_video_overlay_video_renderer_get_render_rectangle
    (GstPlayerVideoOverlayVideoRenderer * self, gint * x, gint * y,
    gint * width, gint * height)
{
  g_return_if_fail (GST_IS_PLAYER_VIDEO_OVERLAY_VIDEO_RENDERER (self));

  if (x)
    *x = self->x;
  if (y)
    *y = self->y;
  if (width)
    *width = self->width;
  if (height)
    *height = self->height;
}
