/* 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
 * @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;
};

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_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;
    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;
    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);

  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);

  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;
}

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 NULL;
}

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_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;
}
