/*
 * GStreamer
 * Copyright (C) 2009 Julien Isorce <julien.isorce@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.
 */

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

/* ============================================================= */
/*                                                               */
/*                          MainWindow                           */
/*                                                               */
/* ============================================================= */

@interface MainWindow: NSWindow <NSApplicationDelegate> {
  GMainLoop *m_loop;
  GstElement *m_pipeline;
  gboolean m_isClosed;
}
- (id) initWithContentRect:(NSRect) contentRect Loop:(GMainLoop*)loop Pipeline:(GstElement*)pipeline;
- (GMainLoop*) loop;
- (GstElement*) pipeline;
- (gboolean) isClosed;
@end

@implementation MainWindow

- (id) initWithContentRect:(NSRect)contentRect Loop:(GMainLoop*)loop Pipeline:(GstElement*)pipeline
{
  m_loop = loop;
  m_pipeline = pipeline;
  m_isClosed = FALSE;

  self = [super initWithContentRect: contentRect
		styleMask: (NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask)
    backing: NSBackingStoreBuffered defer: NO screen: nil];

  [self setReleasedWhenClosed:NO];
  [[NSApplication sharedApplication] setDelegate:self];

  [self setTitle:@"gst-plugins-gl implements videooverlay interface"];

  return self;
}

- (GMainLoop*) loop {
  return m_loop;
}

- (GstElement*) pipeline {
  return m_pipeline;
}

- (gboolean) isClosed {
  return m_isClosed;
}

- (void) customClose {
  m_isClosed = TRUE;
}

- (BOOL) windowShouldClose:(id)sender {
  gst_element_send_event (m_pipeline, gst_event_new_eos ());
  return YES;
}

- (void) applicationDidFinishLaunching: (NSNotification *) not {
  [self makeMainWindow];
  [self center];
  [self orderFront:self];
}

- (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app {
  return NO;
}

@end


/* ============================================================= */
/*                                                               */
/*                   gstreamer callbacks                         */
/*                                                               */
/* ============================================================= */


static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, MainWindow* window)
{
  // 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_print ("setting window handle %lud\n", (gulong) window);

  gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), (guintptr) [window contentView]);

  gst_message_unref (message);

  return GST_BUS_DROP;
}


static void end_stream_cb(GstBus* bus, GstMessage* message, MainWindow* window)
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  g_print ("end of stream\n");

  gst_element_set_state ([window pipeline], GST_STATE_NULL);
  gst_object_unref ([window pipeline]);
  g_main_loop_quit ([window loop]);

  [window performSelectorOnMainThread:@selector(customClose) withObject:nil waitUntilDone:YES];

  [pool release];
}

static gpointer thread_func (MainWindow* window)
{
  g_main_loop_run ([window loop]);

  return NULL;
}


/* ============================================================= */
/*                                                               */
/*                         application                           */
/*                                                               */
/* ============================================================= */

int main(int argc, char **argv)
{
	int width = 640;
  int height = 480;

  GMainLoop *loop = NULL;
  GstElement *pipeline = NULL;

  GstElement *videosrc  = NULL;
  GstElement *videosink = NULL;
  GstCaps *caps=NULL;
  gboolean ok=FALSE;
  GstBus *bus=NULL;
  GThread *loop_thread=NULL;
  NSAutoreleasePool *pool=nil;
  NSRect rect;
  MainWindow *window=nil;

  pool = [[NSAutoreleasePool alloc] init];
  [NSApplication sharedApplication];

  g_print("app created\n");

  gst_init (&argc, &argv);

  loop = g_main_loop_new (NULL, FALSE);
  pipeline = gst_pipeline_new ("pipeline");

  videosrc  = gst_element_factory_make ("videotestsrc", "videotestsrc");
  videosink = gst_element_factory_make ("glimagesink", "glimagesink");

  g_object_set(G_OBJECT(videosrc), "num-buffers", 500, NULL);

  gst_bin_add_many (GST_BIN (pipeline), videosrc, videosink, NULL);

  caps = gst_caps_new_simple("video/x-raw",
    "width", G_TYPE_INT, width,
    "height", G_TYPE_INT, height,
    "framerate", GST_TYPE_FRACTION, 25, 1,
    "format", G_TYPE_STRING, "I420",
    NULL);

  ok = gst_element_link_filtered(videosrc, videosink, caps);
  gst_caps_unref(caps);
  if (!ok)
    g_warning("could not link videosrc to videosink\n");

  rect.origin.x = 0; rect.origin.y = 0;
  rect.size.width = width; rect.size.height = height;

  window = [[MainWindow alloc] initWithContentRect:rect Loop:loop Pipeline:pipeline];

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_signal_watch (bus);
  g_signal_connect(bus, "message::error", G_CALLBACK(end_stream_cb), window);
  g_signal_connect(bus, "message::warning", G_CALLBACK(end_stream_cb), window);
  g_signal_connect(bus, "message::eos", G_CALLBACK(end_stream_cb), window);
  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, window, NULL);
  gst_object_unref (bus);

  loop_thread = g_thread_new (NULL,
      (GThreadFunc) thread_func, window);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  [window orderFront:window];

  while (![window isClosed]) {
    NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask
      untilDate:[NSDate dateWithTimeIntervalSinceNow:1]
      inMode:NSDefaultRunLoopMode dequeue:YES];
    if (event)
      [NSApp sendEvent:event];
  }

  g_thread_join (loop_thread);

  [window release];

  [pool release];

  return 0;
}
