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

typedef struct
{
  GtkWidget *window;
  GtkWidget *fullscreen_window;
  GtkWidget *video_widget;

  GstElement *playbin;
} Player;

static void
toggle_fullscreen (Player *p)
{
  g_object_ref (p->video_widget);

  if (p->fullscreen_window)
    {
      gtk_container_remove (GTK_CONTAINER (p->fullscreen_window), p->video_widget);
      gtk_container_add (GTK_CONTAINER (p->window), p->video_widget);
      
      gtk_widget_destroy (p->fullscreen_window);
      p->fullscreen_window = NULL;
    }
  else
    {
      p->fullscreen_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

      gtk_container_remove (GTK_CONTAINER (p->window), p->video_widget);
      gtk_container_add (GTK_CONTAINER (p->fullscreen_window), p->video_widget);

      gtk_window_fullscreen (GTK_WINDOW (p->fullscreen_window));
      gtk_window_present (GTK_WINDOW (p->fullscreen_window));

    }

  g_message ("%s mode: GdkGLContext %p",
             (p->fullscreen_window) ? "Windowed" : "FullScreen", 
             gtk_gl_area_get_context (GTK_GL_AREA (p->video_widget)));

  g_object_unref (p->video_widget);

  gtk_widget_grab_focus (p->video_widget);
}

static Player *
player_new ()
{
  Player *p = g_new0 (Player, 1);
  GstElement *videosink;

  /* Create main window */
  p->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  /* Set some sane defaults */
  gtk_window_set_default_size (GTK_WINDOW (p->window), 800, 450);
  gtk_window_set_title (GTK_WINDOW (p->window), "Test Player");
  gtk_window_set_position (GTK_WINDOW (p->window), GTK_WIN_POS_CENTER);

  /* Quit app on delete-event */
  g_signal_connect (p->window, "delete-event", G_CALLBACK (gtk_main_quit), NULL);

  p->playbin = gst_element_factory_make ("playbin", NULL);

#ifdef USE_GTKSINK
  videosink = gst_element_factory_make ("gtksink", NULL);
  g_object_get (videosink, "widget", &p->video_widget, NULL);
#else
  {
    GstElement *gtkglsink = gst_element_factory_make ("gtkglsink", NULL);
    videosink = gst_element_factory_make ("glsinkbin", NULL);
    g_object_set (videosink, "sink", gtkglsink, NULL);
    g_object_get (gtkglsink, "widget", &p->video_widget, NULL);
  }
#endif

  g_object_set (p->playbin, "video-sink", videosink, NULL);

  gtk_container_add (GTK_CONTAINER (p->window), p->video_widget);
  g_signal_connect_swapped (p->video_widget, "key-release-event", G_CALLBACK (toggle_fullscreen), p);

  return p;
}

/* gcc test-player.c `pkg-config --libs --cflags gtk+-3.0 gstreamer-1.0 x11-xcb` */

int
main (int argc, char **argv)
{
  Player *player;

  /* Without this, the test case crashes on an Atom N450 (the only non nvidia GPU I have) */
  XInitThreads();

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

  if (argc < 2)
    {
      g_print ("Usage: %s file:///full/path/to/media/file\n", argv[0]);
      return 0;
    }

  player = player_new (NULL);

  gtk_widget_show_all (player->window);

  g_object_set (player->playbin, "uri", argv[1], NULL);
  gst_element_set_state (player->playbin, GST_STATE_PLAYING);

  gtk_main ();

  return 0;
}
