/*
 * GStreamer
 * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.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

#define GLIB_DISABLE_DEPRECATION_WARNINGS
#define CLUTTER_VERSION_MIN_REQUIRED CLUTTER_VERSION_1_8

#include <X11/Xlib.h>
#include <X11/extensions/Xcomposite.h>
#include <clutter/clutter.h>
#include <clutter/x11/clutter-x11.h>
#include <clutter/glx/clutter-glx.h>
#include <gst/gst.h>
#include <gst/video/videooverlay.h>

#define ROWS 3
#define COLS 3
#define N_ACTORS ROWS*COLS
#define W 160
#define H 120

struct GstGLClutterActor_
{
  Window win;
  Window root;
  ClutterActor *texture;
  ClutterActor *stage;
};

typedef struct GstGLClutterActor_ GstGLClutterActor;

static gboolean
create_actor (GstGLClutterActor * actor)
{
  static gint xpos = 0;
  static gint ypos = 0;
  actor->texture = g_object_new (CLUTTER_X11_TYPE_TEXTURE_PIXMAP,
      "window", actor->win, "automatic-updates", TRUE, NULL);
  clutter_container_add_actor (CLUTTER_CONTAINER (actor->stage),
      actor->texture);
  clutter_actor_set_position (actor->texture, xpos, ypos);

  if (xpos > (COLS - 1) * W) {
    xpos = 0;
    ypos += H + 1;
  } else
    xpos += W + 1;
  clutter_actor_show (actor->texture);

  return FALSE;
}

static GstBusSyncReply
create_window (GstBus * bus, GstMessage * message, gpointer data)
{
  GstGLClutterActor **actor = (GstGLClutterActor **) data;
  static gint count = 0;
  static GMutex mutex;
  // ignore anything but 'prepare-window-handle' element messages
  if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
    return GST_BUS_PASS;

  if (!gst_is_video_overlay_prepare_window_handle_message (message))
    return GST_BUS_PASS;

  g_mutex_lock (&mutex);

  if (count < N_ACTORS) {
    g_message ("adding actor %d", count);
    gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC
            (message)), actor[count]->win);
    clutter_threads_add_idle ((GSourceFunc) create_actor, actor[count]);
    count++;
  }

  g_mutex_unlock (&mutex);

  gst_message_unref (message);
  return GST_BUS_DROP;
}

#if 0
void
apply_fx (GstElement * element, const gchar * fx)
{
  GEnumClass *p_class;

  /* from fxtest ;) */
  /* heeeellppppp!! */
  p_class =
      G_PARAM_SPEC_ENUM (g_object_class_find_property (G_OBJECT_GET_CLASS
          (G_OBJECT (data)), "effect")
      )->enum_class;

  g_print ("setting: %s - %s\n", fx, g_enum_get_value_by_nick (p_class,
          fx)->value_name);
  g_object_set (G_OBJECT (element), "effect", g_enum_get_value_by_nick (p_class,
          fx)->value, NULL);
}
#endif

int
main (int argc, char *argv[])
{
  GstPipeline *pipeline;
  GstBus *bus;

  GstElement *srcbin;
  GstElement *tee;
  GstElement *queue[N_ACTORS], *sink[N_ACTORS];
  GstElement *upload[N_ACTORS];
/*
  GstElement *effect[N_ACTORS];
*/
  ClutterActor *stage;
  GstGLClutterActor *actor[N_ACTORS];
  Display *disp;
  Window stage_win;
  const gchar *desc;
  gint i;
  gint ok = FALSE;
  ClutterInitError clutter_err = CLUTTER_INIT_ERROR_UNKNOWN;

  clutter_err = clutter_init (&argc, &argv);
  if (clutter_err != CLUTTER_INIT_SUCCESS)
    g_warning ("Failed to initalize clutter: %d\n", clutter_err);

  gst_init (&argc, &argv);

  disp = clutter_x11_get_default_display ();
  if (!clutter_x11_has_composite_extension ()) {
    g_error ("XComposite extension missing");
  }

  stage = clutter_stage_get_default ();
  clutter_actor_set_size (CLUTTER_ACTOR (stage),
      W * COLS + (COLS - 1), H * ROWS + (ROWS - 1));

  stage_win = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
  XCompositeRedirectSubwindows (disp, stage_win, CompositeRedirectManual);

  for (i = 0; i < N_ACTORS; i++) {
    actor[i] = g_new0 (GstGLClutterActor, 1);
    actor[i]->stage = stage;
    actor[i]->win = XCreateSimpleWindow (disp, stage_win, 0, 0, W, H, 0, 0, 0);
    XMapRaised (disp, actor[i]->win);
    XSync (disp, FALSE);
  }
/*
  desc = g_strdup_printf ("v4l2src ! "
                          "video/x-raw, width=640, height=480, framerate=30/1 ! "
                          "videoscale !"
                          "video/x-raw, width=%d, height=%d ! "
                          "identity", W, H);
*/
  desc = g_strdup_printf ("videotestsrc ! "
      "video/x-raw, format=RGB, width=%d, height=%d !" "identity", W, H);
  pipeline = GST_PIPELINE (gst_pipeline_new (NULL));

  srcbin = gst_parse_bin_from_description (desc, TRUE, NULL);
  if (!srcbin)
    g_error ("Source bin creation failed");

  tee = gst_element_factory_make ("tee", NULL);

  gst_bin_add_many (GST_BIN (pipeline), srcbin, tee, NULL);

  for (i = 0; i < N_ACTORS; i++) {
    queue[i] = gst_element_factory_make ("queue", NULL);
    upload[i] = gst_element_factory_make ("glupload", NULL);
/*      effect[i] = gst_element_factory_make ("gleffects", NULL); */
    sink[i] = gst_element_factory_make ("glimagesink", NULL);
/*    gst_bin_add_many (GST_BIN (pipeline),
        queue[i], upload[i], effect[i], sink[i], NULL); */
    gst_bin_add_many (GST_BIN (pipeline), queue[i], upload[i], sink[i], NULL);
  }

  gst_element_link_many (srcbin, tee, NULL);

  for (i = 0; i < N_ACTORS; i++) {
    ok |=
//        gst_element_link_many (tee, queue[i], upload[i], effect[i], sink[i],
        gst_element_link_many (tee, queue[i], upload[i], sink[i], NULL);
  }

  if (!ok)
    g_error ("Failed to link one or more elements");

/*
  for (i = 0; i < N_ACTORS; i++) {
    g_message ("setting effect %d on %s", i + 1,
        gst_element_get_name (effect[i]));
    g_object_set (G_OBJECT (effect[i]), "effect", i + 1, NULL);
  }
*/

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));

  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, actor,
      NULL);
  gst_object_unref (bus);

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);

  clutter_actor_show_all (stage);

  clutter_main ();

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
  gst_object_unref (pipeline);

  return 0;
}
