/* GStreamer
 * Copyright (C) <2008> Stefan Kost <ensonic@users.sf.net>
 *
 * test-colorkey: test manual colorkey handling
 *
 * 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 <stdlib.h>
#include <string.h>

#include <glib.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>

#include <gst/gst.h>
#include <gst/video/videooverlay.h>

static GtkWidget *video_window = NULL;
static GstElement *sink = NULL;
static gulong embed_xid = 0;
static GdkRGBA trans_color;
static gboolean trans_color_set = FALSE;

static void
redraw_overlay (GtkWidget * widget)
{
  GtkAllocation allocation;
  GdkWindow *window = gtk_widget_get_window (widget);
  cairo_t *cr;

  cr = gdk_cairo_create (window);
  gtk_widget_get_allocation (widget, &allocation);

  cairo_set_source_rgb (cr, 1, 1, 1);
  cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
  cairo_fill (cr);

  if (trans_color_set) {
    guint x, y;
    guint h = allocation.height * 0.75;

    gdk_cairo_set_source_rgba (cr, &trans_color);
    cairo_rectangle (cr, 0, 0, allocation.width, h);
    cairo_fill (cr);

    for (y = h; y < allocation.height; y++) {
      for (x = 0; x < allocation.width; x++) {
        if (((x & 1) || (y & 1)) && (x & 1) != (y & 1)) {
          cairo_move_to (cr, x, y);
          cairo_paint (cr);
        }
      }
    }
  }
}

static gboolean
handle_resize_cb (GtkWidget * widget, GdkEventConfigure * event, gpointer data)
{
  redraw_overlay (widget);
  return FALSE;
}

static gboolean
draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data)
{
  redraw_overlay (widget);
  return FALSE;
}

static void
realize_cb (GtkWidget * widget, gpointer data)
{
  GdkWindow *window = gtk_widget_get_window (widget);

  /* This is here just for pedagogical purposes, GDK_WINDOW_XID will call it
   * as well */
  if (!gdk_window_ensure_native (window))
    g_error ("Couldn't create native window needed for GstVideoOverlay!");

  embed_xid = GDK_WINDOW_XID (window);
  g_print ("Window realize: video window XID = %lu\n", embed_xid);
}

static void
msg_state_changed (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
{
  const GstStructure *s;

  s = gst_message_get_structure (message);

  /* We only care about state changed on the pipeline */
  if (s && GST_MESSAGE_SRC (message) == GST_OBJECT_CAST (pipeline)) {
    GstState old, new, pending;
    gint color;

    gst_message_parse_state_changed (message, &old, &new, &pending);

    /* When state of the pipeline changes to paused or playing we start updating scale */
    switch (GST_STATE_TRANSITION (old, new)) {
      case GST_STATE_CHANGE_READY_TO_PAUSED:{
        g_object_get (G_OBJECT (sink), "colorkey", &color, NULL);
        if (color != -1) {
          trans_color.red = (color & 0xff0000) >> 8;
          trans_color.green = (color & 0xff00);
          trans_color.blue = (color & 0xff) << 8;
          trans_color_set = TRUE;
        } else {
          trans_color_set = FALSE;
        }
        handle_resize_cb (video_window, NULL, NULL);
        break;
      }
      default:
        break;
    }
  }
}

static void
window_closed (GtkWidget * widget, GdkEvent * event, gpointer user_data)
{
  GstElement *pipeline = user_data;

  g_print ("stopping\n");
  gtk_widget_hide (widget);
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gtk_main_quit ();
}

static gboolean
start_pipeline (gpointer user_data)
{
  GstElement *pipeline = GST_ELEMENT (user_data);
  GstStateChangeReturn sret;

  sret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
  if (sret == GST_STATE_CHANGE_FAILURE) {
    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (pipeline);
    gtk_main_quit ();
  }
  return FALSE;
}

int
main (int argc, char **argv)
{
  GtkWidget *window;
  GstElement *pipeline, *src;
  GstBus *bus;
  GstStateChangeReturn sret;
#if 0
  GstPropertyProbe *probe;
  GValueArray *arr;
#endif

  gst_init (&argc, &argv);
  gtk_init (&argc, &argv);

  /* prepare the pipeline */

  pipeline = gst_pipeline_new ("xvoverlay");
  src = gst_element_factory_make ("videotestsrc", NULL);
  sink = gst_element_factory_make ("xvimagesink", NULL);
  gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
  gst_element_link (src, sink);

#define COLOR_GRAY 0x7F7F7F

  g_object_set (G_OBJECT (sink), "autopaint-colorkey", FALSE,
      "force-aspect-ratio", TRUE, "draw-borders", FALSE,
      "colorkey", COLOR_GRAY, NULL);

  /* check xvimagesink capabilities */
  sret = gst_element_set_state (pipeline, GST_STATE_READY);
  if (sret == GST_STATE_CHANGE_FAILURE) {
    g_printerr ("Can't set pipeline to READY\n");
    gst_object_unref (pipeline);
    return -1;
  }
#if 0
  probe = GST_PROPERTY_PROBE (sink);
  if (!probe) {
    g_printerr ("Can't probe sink\n");
    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (pipeline);
    return -1;
  }
  arr =
      gst_property_probe_probe_and_get_values_name (probe,
      "autopaint-colorkey");
  if (!arr || !arr->n_values) {
    g_printerr ("Can't disable autopaint-colorkey property\n");
    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (pipeline);
    return -1;
  }
  if (arr)
    g_value_array_free (arr);
#endif

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
  g_signal_connect (bus, "message::state-changed",
      G_CALLBACK (msg_state_changed), pipeline);
  gst_object_unref (bus);

  /* prepare the ui */

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  g_signal_connect (G_OBJECT (window), "delete-event",
      G_CALLBACK (window_closed), (gpointer) pipeline);
  gtk_window_set_default_size (GTK_WINDOW (window), 320, 240);

  video_window = gtk_drawing_area_new ();
  g_signal_connect (G_OBJECT (video_window), "configure-event",
      G_CALLBACK (handle_resize_cb), NULL);
  g_signal_connect (G_OBJECT (video_window), "draw",
      G_CALLBACK (draw_cb), NULL);
  g_signal_connect (video_window, "realize", G_CALLBACK (realize_cb), NULL);
  gtk_container_add (GTK_CONTAINER (window), video_window);

  /* show the gui and play */

  gtk_widget_show_all (window);

  /* realize window now so that the video window gets created and we can
   * obtain its XID before the pipeline is started up and the videosink
   * asks for the XID of the window to render onto */
  gtk_widget_realize (window);

  /* we should have the XID now */
  g_assert (embed_xid != 0);

  /* we know what the video sink is in this case (xvimagesink), so we can
   * just set it directly here now (instead of waiting for a
   * prepare-window-handle element message in a sync bus handler and setting
   * it there) */
  g_print ("setting XID %lu\n", embed_xid);
  gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (sink), embed_xid);

  g_idle_add (start_pipeline, pipeline);
  gtk_main ();

  gst_object_unref (pipeline);

  return 0;
}
