/* GStreamer
 * OSX video sink
 * Copyright (C) 2004-6 Zaheer Abbas Merali <zaheerabbas at merali dot org>
 * Copyright (C) 2007,2008,2009 Pioneers of the Inevitable <songbird@songbirdnest.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.
 *
 * The development of this code was made possible due to the involvement of
 * Pioneers of the Inevitable, the creators of the Songbird Music player.
 * 
 */

/**
 * SECTION:element-osxvideosink
 *
 * The OSXVideoSink renders video frames to a MacOSX window. The video output
 * must be directed to a window embedded in an existing NSApp.
 *
 * When the NSView to be embedded is created an element #GstMessage with a 
 * name of 'have-ns-view' will be created and posted on the bus. 
 * The pointer to the NSView to embed will be in the 'nsview' field of that 
 * message. The application MUST handle this message and embed the view
 * appropriately.
 */

#include "config.h"
#include <gst/video/videooverlay.h>
#include <gst/video/navigation.h>

#include "osxvideosink.h"
#include <unistd.h>
#import "cocoawindow.h"

GST_DEBUG_CATEGORY (gst_debug_osx_video_sink);
#define GST_CAT_DEFAULT gst_debug_osx_video_sink

#ifdef RUN_NS_APP_THREAD
#include <pthread.h>
extern  void _CFRunLoopSetCurrent(CFRunLoopRef rl);
extern pthread_t _CFMainPThread;
#endif



static GstStaticPadTemplate gst_osx_video_sink_sink_template_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-raw, "
        "framerate = (fraction) [ 0, MAX ], "
        "width = (int) [ 1, MAX ], "
        "height = (int) [ 1, MAX ], "
#if G_BYTE_ORDER == G_BIG_ENDIAN
       "format = (string) YUY2")
#else
        "format = (string) UYVY")
#endif
    );

enum
{
  ARG_0,
  ARG_EMBED,
  ARG_FORCE_PAR,
};

static void gst_osx_video_sink_osxwindow_destroy (GstOSXVideoSink * osxvideosink);
static GMutex _run_loop_check_mutex;
static GMutex _run_loop_mutex;
static GCond _run_loop_cond;
static GstOSXVideoSinkClass *sink_class = NULL;
static GstVideoSinkClass *parent_class = NULL;

/* Helper to trigger calls from the main thread */
static void
gst_osx_video_sink_call_from_main_thread(GstOSXVideoSink *osxvideosink,
    NSObject * object, SEL function, NSObject *data, BOOL waitUntilDone)
{

  NSThread *thread;
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  if (sink_class->ns_app_thread == NULL){
    thread = [NSThread mainThread];
  } else {
    thread = sink_class->ns_app_thread;
  }

  [object performSelector:function onThread:thread
          withObject:data waitUntilDone:waitUntilDone];
  [pool release];
}

/* Poll for cocoa events */
static void
run_ns_app_loop (void) {
  NSEvent *event;
  NSAutoreleasePool *pool =[[NSAutoreleasePool alloc] init];
  NSDate *pollTime = nil;

#ifdef RUN_NS_APP_THREAD
  /* when running the loop in a thread we want to sleep as long as possible */
  pollTime = [NSDate distantFuture];
#else
  pollTime = [NSDate distantPast];
#endif

  do {
      event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:pollTime
          inMode:NSDefaultRunLoopMode dequeue:YES];
      [NSApp sendEvent:event];
    }
  while (event != nil);
  [pool release];
}

static void
gst_osx_videosink_check_main_run_loop (GstOSXVideoSink *sink)
{
  /* check if the main run loop is running */
  gboolean is_running;

  /* the easy way */
  is_running = [[NSRunLoop mainRunLoop] currentMode] != nil;
  if (is_running) {
    goto exit;
  } else {
    /* the previous check doesn't always work with main loops that run
     * cocoa's main run loop manually, like the gdk one, giving false
     * negatives. This check defers a call to the main thread and waits to
     * be awaken by this function. */
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    GstOSXVideoSinkObject * object = (GstOSXVideoSinkObject *) sink->osxvideosinkobject;
    gint64 abstime;

    g_mutex_lock (&_run_loop_mutex);
    [object performSelectorOnMainThread:
          @selector(checkMainRunLoop)
          withObject:nil waitUntilDone:NO];
    /* Wait 100 ms */
    abstime = g_get_monotonic_time () + 100 * 1000;
    is_running = g_cond_wait_until (&_run_loop_cond,
        &_run_loop_mutex, abstime);
    g_mutex_unlock (&_run_loop_mutex);

    [pool release];
  }

exit:
  {
  GST_DEBUG_OBJECT(sink, "The main runloop %s is running",
      is_running ? "" : " not ");
  if (is_running) {
    sink_class->run_loop_state = GST_OSX_VIDEO_SINK_RUN_LOOP_STATE_RUNNING;
    sink_class->ns_app_thread = [NSThread mainThread];
  } else {
    sink_class->run_loop_state = GST_OSX_VIDEO_SINK_RUN_LOOP_STATE_NOT_RUNNING;
  }
  }
}

static void
gst_osx_video_sink_run_cocoa_loop (GstOSXVideoSink * sink )
{
  /* Cocoa applications require a main runloop running to dispatch UI
   * events and process deferred calls to the main thread through
   * perfermSelectorOnMainThread.
   * Since the sink needs to create it's own Cocoa window when no
   * external NSView is passed to the sink through the GstVideoOverlay API,
   * we need to run the cocoa mainloop somehow.
   * This run loop can only be started once, by the first sink needing it
   */

  g_mutex_lock (&_run_loop_check_mutex);

  if (sink_class->run_loop_state == GST_OSX_VIDEO_SINK_RUN_LOOP_STATE_UNKNOWN) {
    gst_osx_videosink_check_main_run_loop (sink);
  }

  if (sink_class->run_loop_state == GST_OSX_VIDEO_SINK_RUN_LOOP_STATE_RUNNING) {
    g_mutex_unlock (&_run_loop_check_mutex);
    return;
  }

  if (sink_class->ns_app_thread == NULL) {
#ifdef RUN_NS_APP_THREAD
    /* run the main runloop in a separate thread */

    /* override [NSThread isMainThread] with our own implementation so that we can
     * make it believe our dedicated thread is the main thread
     */
    Method origIsMainThread = class_getClassMethod([NSThread class],
        NSSelectorFromString(@"isMainThread"));
    Method ourIsMainThread = class_getClassMethod([GstOSXVideoSinkObject class],
        NSSelectorFromString(@"isMainThread"));

    method_exchangeImplementations(origIsMainThread, ourIsMainThread);

    sink_class->ns_app_thread = [[NSThread alloc]
        initWithTarget:sink->osxvideosinkobject
        selector:@selector(nsAppThread) object:nil];
    [sink_class->ns_app_thread start];

    g_mutex_lock (&_run_loop_mutex);
    g_cond_wait (&_run_loop_cond, &_run_loop_mutex);
    g_mutex_unlock (&_run_loop_mutex);
#else
  /* assume that there is a GMainLoop and iterate the main runloop from there
   */
    sink_class->cocoa_timeout = g_timeout_add (10,
        (GSourceFunc) run_ns_app_loop, NULL);
#endif
  }

  g_mutex_unlock (&_run_loop_check_mutex);
}

static void
gst_osx_video_sink_stop_cocoa_loop (GstOSXVideoSink * osxvideosink)
{
#ifndef RUN_NS_APP_THREAD
  if (sink_class->cocoa_timeout)
    g_source_remove(sink_klass->cocoa_timeout);
#endif
}

/* This function handles osx window creation */
static gboolean
gst_osx_video_sink_osxwindow_create (GstOSXVideoSink * osxvideosink, gint width,
    gint height)
{
  NSRect rect;
  GstOSXWindow *osxwindow = NULL;
  GstStructure *s;
  GstMessage *msg;
  gboolean res = TRUE;
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  g_return_val_if_fail (GST_IS_OSX_VIDEO_SINK (osxvideosink), FALSE);

  GST_DEBUG_OBJECT (osxvideosink, "Creating new OSX window");

  osxvideosink->osxwindow = osxwindow = g_new0 (GstOSXWindow, 1);

  osxwindow->width = width;
  osxwindow->height = height;
  osxwindow->closed = FALSE;
  osxwindow->internal = FALSE;

  /* Allocate our GstGLView for the window, and then tell the application
   * about it (hopefully it's listening...) */
  rect.origin.x = 0.0;
  rect.origin.y = 0.0;
  rect.size.width = (float) osxwindow->width;
  rect.size.height = (float) osxwindow->height;
  osxwindow->gstview =[[GstGLView alloc] initWithFrame:rect];

  s = gst_structure_new ("have-ns-view",
     "nsview", G_TYPE_POINTER, osxwindow->gstview,
     nil);

  msg = gst_message_new_element (GST_OBJECT (osxvideosink), s);
  gst_element_post_message (GST_ELEMENT (osxvideosink), msg);

  GST_INFO_OBJECT (osxvideosink, "'have-ns-view' message sent");

  gst_osx_video_sink_run_cocoa_loop (osxvideosink);
  [osxwindow->gstview setMainThread:sink_class->ns_app_thread];

  /* check if have-ns-view was handled and osxwindow->gstview was added to a
   * superview
   */
  if ([osxwindow->gstview haveSuperview] == NO) {
    /* have-ns-view wasn't handled, post prepare-xwindow-id */
    if (osxvideosink->superview == NULL) {
      GST_INFO_OBJECT (osxvideosink, "emitting prepare-xwindow-id");
      gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (osxvideosink));
    }

    if (osxvideosink->superview != NULL) {
      /* prepare-xwindow-id was handled, we have the superview in
       * osxvideosink->superview. We now add osxwindow->gstview to the superview
       * from the main thread
       */
      GST_INFO_OBJECT (osxvideosink, "we have a superview, adding our view to it");
      gst_osx_video_sink_call_from_main_thread(osxvideosink, osxwindow->gstview,
          @selector(addToSuperview:), osxvideosink->superview, NO);

    } else {
      if (osxvideosink->embed) {
        /* the view wasn't added to a superview. It's possible that the
         * application handled have-ns-view, stored our view internally and is
         * going to add it to a superview later (webkit does that now).
         */
        GST_INFO_OBJECT (osxvideosink, "no superview");
      } else {
        gst_osx_video_sink_call_from_main_thread(osxvideosink,
          osxvideosink->osxvideosinkobject,
          @selector(createInternalWindow), nil, YES);
        GST_INFO_OBJECT (osxvideosink, "No superview, creating an internal window.");
      }
    }
  }
  [osxwindow->gstview setNavigation: GST_NAVIGATION(osxvideosink)];
  [osxvideosink->osxwindow->gstview setKeepAspectRatio: osxvideosink->keep_par];

  [pool release];

  return res;
}

static void
gst_osx_video_sink_osxwindow_destroy (GstOSXVideoSink * osxvideosink)
{
  NSAutoreleasePool *pool;

  g_return_if_fail (GST_IS_OSX_VIDEO_SINK (osxvideosink));
  pool = [[NSAutoreleasePool alloc] init];

  gst_osx_video_sink_call_from_main_thread(osxvideosink,
      osxvideosink->osxvideosinkobject,
      @selector(destroy), (id) nil, YES);
  gst_osx_video_sink_stop_cocoa_loop (osxvideosink);
  [pool release];
}

/* This function resizes a GstXWindow */
static void
gst_osx_video_sink_osxwindow_resize (GstOSXVideoSink * osxvideosink,
    GstOSXWindow * osxwindow, guint width, guint height)
{
  GstOSXVideoSinkObject *object = osxvideosink->osxvideosinkobject;

  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  g_return_if_fail (osxwindow != NULL);
  g_return_if_fail (GST_IS_OSX_VIDEO_SINK (osxvideosink));

  osxwindow->width = width;
  osxwindow->height = height;

  GST_DEBUG_OBJECT (osxvideosink, "Resizing window to (%d,%d)", width, height);

  /* Directly resize the underlying view */
  GST_DEBUG_OBJECT (osxvideosink, "Calling setVideoSize on %p", osxwindow->gstview);
  gst_osx_video_sink_call_from_main_thread(osxvideosink, object,
      @selector(resize), (id)nil, YES);

  [pool release];
}

static gboolean
gst_osx_video_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
{
  GstOSXVideoSink *osxvideosink;
  GstStructure *structure;
  gboolean res, result = FALSE;
  gint video_width, video_height;

  osxvideosink = GST_OSX_VIDEO_SINK (bsink);

  GST_DEBUG_OBJECT (osxvideosink, "caps: %" GST_PTR_FORMAT, caps);

  structure = gst_caps_get_structure (caps, 0);
  res = gst_structure_get_int (structure, "width", &video_width);
  res &= gst_structure_get_int (structure, "height", &video_height);

  if (!res) {
    goto beach;
  }

  GST_DEBUG_OBJECT (osxvideosink, "our format is: %dx%d video",
      video_width, video_height);

  GST_VIDEO_SINK_WIDTH (osxvideosink) = video_width;
  GST_VIDEO_SINK_HEIGHT (osxvideosink) = video_height;

  gst_osx_video_sink_osxwindow_resize (osxvideosink, osxvideosink->osxwindow,
      video_width, video_height);
  result = TRUE;

beach:
  return result;

}

static GstStateChangeReturn
gst_osx_video_sink_change_state (GstElement * element,
    GstStateChange transition)
{
  GstOSXVideoSink *osxvideosink;
  GstStateChangeReturn ret;

  osxvideosink = GST_OSX_VIDEO_SINK (element);

  GST_DEBUG_OBJECT (osxvideosink, "%s => %s", 
        gst_element_state_get_name(GST_STATE_TRANSITION_CURRENT (transition)),
        gst_element_state_get_name(GST_STATE_TRANSITION_NEXT (transition)));

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      /* Creating our window and our image */
      GST_VIDEO_SINK_WIDTH (osxvideosink) = 320;
      GST_VIDEO_SINK_HEIGHT (osxvideosink) = 240;
      if (!gst_osx_video_sink_osxwindow_create (osxvideosink,
          GST_VIDEO_SINK_WIDTH (osxvideosink),
          GST_VIDEO_SINK_HEIGHT (osxvideosink))) {
        ret = GST_STATE_CHANGE_FAILURE;
        goto done;
      }
      break;
    default:
      break;
  }

  ret = (GST_ELEMENT_CLASS (parent_class))->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_VIDEO_SINK_WIDTH (osxvideosink) = 0;
      GST_VIDEO_SINK_HEIGHT (osxvideosink) = 0;
      gst_osx_video_sink_osxwindow_destroy (osxvideosink);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

done:
  return ret;
}

static GstFlowReturn
gst_osx_video_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
{
  GstOSXVideoSink *osxvideosink;
  GstBufferObject* bufferobject;
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  osxvideosink = GST_OSX_VIDEO_SINK (bsink);

  GST_DEBUG ("show_frame");
  bufferobject = [[GstBufferObject alloc] initWithBuffer:buf];
  gst_osx_video_sink_call_from_main_thread(osxvideosink,
      osxvideosink->osxvideosinkobject,
      @selector(showFrame:), bufferobject, NO);
  [pool release];
  return GST_FLOW_OK;
}

/* Buffer management */



/* =========================================== */
/*                                             */
/*              Init & Class init              */
/*                                             */
/* =========================================== */

static void
gst_osx_video_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstOSXVideoSink *osxvideosink;

  g_return_if_fail (GST_IS_OSX_VIDEO_SINK (object));

  osxvideosink = GST_OSX_VIDEO_SINK (object);

  switch (prop_id) {
    case ARG_EMBED:
      osxvideosink->embed = g_value_get_boolean(value);
      g_warning ("The \"embed\" property of osxvideosink is deprecated and "
          "will be removed in the near future. Use the GstVideoOverlay "
          "instead.");
      break;
    case ARG_FORCE_PAR:
      osxvideosink->keep_par = g_value_get_boolean(value);
      if (osxvideosink->osxwindow)
        [osxvideosink->osxwindow->gstview
            setKeepAspectRatio: osxvideosink->keep_par];
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_osx_video_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstOSXVideoSink *osxvideosink;

  g_return_if_fail (GST_IS_OSX_VIDEO_SINK (object));

  osxvideosink = GST_OSX_VIDEO_SINK (object);

  switch (prop_id) {
    case ARG_EMBED:
      g_value_set_boolean (value, osxvideosink->embed);
      break;
    case ARG_FORCE_PAR:
      g_value_set_boolean (value, osxvideosink->keep_par);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


static void
gst_osx_video_sink_init (GstOSXVideoSink * sink)
{
  sink->osxwindow = NULL;
  sink->superview = NULL;
  sink->osxvideosinkobject = [[GstOSXVideoSinkObject alloc] initWithSink:sink];
  sink->keep_par = FALSE;
}

static void
gst_osx_video_sink_base_init (gpointer g_class)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);

  gst_element_class_set_static_metadata (element_class, "OSX Video sink",
      "Sink/Video", "OSX native videosink",
      "Zaheer Abbas Merali <zaheerabbas at merali dot org>");

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_osx_video_sink_sink_template_factory));
}

static void
gst_osx_video_sink_finalize (GObject *object)
{
  GstOSXVideoSink *osxvideosink = GST_OSX_VIDEO_SINK (object);

  if (osxvideosink->superview)
    [osxvideosink->superview release];

  if (osxvideosink->osxvideosinkobject)
    [(GstOSXVideoSinkObject*)(osxvideosink->osxvideosinkobject) release];

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gst_osx_video_sink_class_init (GstOSXVideoSinkClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSinkClass *gstbasesink_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstbasesink_class = (GstBaseSinkClass *) klass;

  parent_class = g_type_class_ref (GST_TYPE_VIDEO_SINK);
  sink_class = klass;

  klass->run_loop_state = GST_OSX_VIDEO_SINK_RUN_LOOP_STATE_UNKNOWN;
  klass->ns_app_thread = NULL;

  gobject_class->set_property = gst_osx_video_sink_set_property;
  gobject_class->get_property = gst_osx_video_sink_get_property;
  gobject_class->finalize = gst_osx_video_sink_finalize;

  gstbasesink_class->set_caps = gst_osx_video_sink_setcaps;
  gstbasesink_class->preroll = gst_osx_video_sink_show_frame;
  gstbasesink_class->render = gst_osx_video_sink_show_frame;
  gstelement_class->change_state = gst_osx_video_sink_change_state;

  /**
   * GstOSXVideoSink:embed
   *
   * Set to #TRUE if you are embedding the video window in an application.
   *
   **/

  g_object_class_install_property (gobject_class, ARG_EMBED,
      g_param_spec_boolean ("embed", "embed", "For ABI compatiblity only, do not use",
          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstOSXVideoSink:force-aspect-ratio
   *
   * When enabled, scaling will respect original aspect ratio.
   *
   **/

  g_object_class_install_property (gobject_class, ARG_FORCE_PAR,
      g_param_spec_boolean ("force-aspect-ratio", "force aspect ration",
          "When enabled, scaling will respect original aspect ration",
          TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
gst_osx_video_sink_navigation_send_event (GstNavigation * navigation,
    GstStructure * structure)
{
  GstOSXVideoSink *osxvideosink = GST_OSX_VIDEO_SINK (navigation);
  GstPad *peer;
  GstEvent *event;
  GstVideoRectangle src, dst, result;
  NSRect bounds;
  gdouble x, y, xscale = 1.0, yscale = 1.0;

  peer = gst_pad_get_peer (GST_VIDEO_SINK_PAD (osxvideosink));

  if (!peer || !osxvideosink->osxwindow)
    return;

  event = gst_event_new_navigation (structure);

  bounds = [osxvideosink->osxwindow->gstview getDrawingBounds];

  if (osxvideosink->keep_par) {
    /* We get the frame position using the calculated geometry from _setcaps
       that respect pixel aspect ratios */
    src.w = GST_VIDEO_SINK_WIDTH (osxvideosink);
    src.h = GST_VIDEO_SINK_HEIGHT (osxvideosink);
    dst.w = bounds.size.width;
    dst.h = bounds.size.height;

    gst_video_sink_center_rect (src, dst, &result, TRUE);
    result.x += bounds.origin.x;
    result.y += bounds.origin.y;
  } else {
    result.x = bounds.origin.x;
    result.y = bounds.origin.y;
    result.w = bounds.size.width;
    result.h = bounds.size.height;
  }

  /* We calculate scaling using the original video frames geometry to include
     pixel aspect ratio scaling. */
  xscale = (gdouble) osxvideosink->osxwindow->width / result.w;
  yscale = (gdouble) osxvideosink->osxwindow->height / result.h;

  /* Converting pointer coordinates to the non scaled geometry */
  if (gst_structure_get_double (structure, "pointer_x", &x)) {
    x = MIN (x, result.x + result.w);
    x = MAX (x - result.x, 0);
    gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE,
        (gdouble) x * xscale, NULL);
  }
  if (gst_structure_get_double (structure, "pointer_y", &y)) {
    y = MIN (y, result.y + result.h);
    y = MAX (y - result.y, 0);
    gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE,
        (gdouble) y * yscale, NULL);
  }

  gst_pad_send_event (peer, event);
  gst_object_unref (peer);
}

static void
gst_osx_video_sink_navigation_init (GstNavigationInterface * iface)
{
  iface->send_event = gst_osx_video_sink_navigation_send_event;
}

static void
gst_osx_video_sink_set_window_handle (GstVideoOverlay * overlay, guintptr handle_id)
{
  GstOSXVideoSink *osxvideosink = GST_OSX_VIDEO_SINK (overlay);
  NSView *view = (NSView *) handle_id;

  gst_osx_video_sink_call_from_main_thread(osxvideosink,
      osxvideosink->osxvideosinkobject,
      @selector(setView:), view, YES);
}

static void
gst_osx_video_sink_xoverlay_init (GstVideoOverlayInterface * iface)
{
  iface->set_window_handle = gst_osx_video_sink_set_window_handle;
  iface->expose = NULL;
  iface->handle_events = NULL;
}

/* ============================================================= */
/*                                                               */
/*                       Public Methods                          */
/*                                                               */
/* ============================================================= */

/* =========================================== */
/*                                             */
/*          Object typing & Creation           */
/*                                             */
/* =========================================== */

GType
gst_osx_video_sink_get_type (void)
{
  static GType osxvideosink_type = 0;

  if (!osxvideosink_type) {
    static const GTypeInfo osxvideosink_info = {
      sizeof (GstOSXVideoSinkClass),
      gst_osx_video_sink_base_init,
      NULL,
      (GClassInitFunc) gst_osx_video_sink_class_init,
      NULL,
      NULL,
      sizeof (GstOSXVideoSink),
      0,
      (GInstanceInitFunc) gst_osx_video_sink_init,
    };

    static const GInterfaceInfo overlay_info = {
      (GInterfaceInitFunc) gst_osx_video_sink_xoverlay_init,
      NULL,
      NULL,
    };

    static const GInterfaceInfo navigation_info = {
      (GInterfaceInitFunc) gst_osx_video_sink_navigation_init,
      NULL,
      NULL,
    };
    osxvideosink_type = g_type_register_static (GST_TYPE_VIDEO_SINK,
        "GstOSXVideoSink", &osxvideosink_info, 0);

    g_type_add_interface_static (osxvideosink_type, GST_TYPE_VIDEO_OVERLAY,
        &overlay_info);
    g_type_add_interface_static (osxvideosink_type, GST_TYPE_NAVIGATION,
        &navigation_info);
  }

  return osxvideosink_type;
}

@implementation GstWindowDelegate
- (id) initWithSink: (GstOSXVideoSink *) sink
{
  self = [super init];
  self->osxvideosink = sink;
  return self;
}

- (void)windowWillClose:(NSNotification *)notification {
  /* Only handle close events if the window was closed manually by the user
   * and not becuase of a state change state to READY */
  if (osxvideosink->osxwindow == NULL) {
    return;
  }
  if (!osxvideosink->osxwindow->closed) {
    osxvideosink->osxwindow->closed = TRUE;
    GST_ELEMENT_ERROR (osxvideosink, RESOURCE, NOT_FOUND, ("Output window was closed"), (NULL));
    gst_osx_video_sink_osxwindow_destroy(osxvideosink);
  }
}

@end

@ implementation GstOSXVideoSinkObject

-(id) initWithSink: (GstOSXVideoSink*) sink
{
  self = [super init];
  self->osxvideosink = sink;
  return self;
}

-(void) createInternalWindow
{
  GstOSXWindow *osxwindow = osxvideosink->osxwindow;
  ProcessSerialNumber psn;
  NSRect rect;
  unsigned int mask;

  osxwindow->internal = TRUE;

  mask =  NSTitledWindowMask             |
          NSClosableWindowMask           |
          NSResizableWindowMask          |
          NSTexturedBackgroundWindowMask |
          NSMiniaturizableWindowMask;

  rect.origin.x = 100.0;
  rect.origin.y = 100.0;
  rect.size.width = (float) osxwindow->width;
  rect.size.height = (float) osxwindow->height;

#ifndef RUN_NS_APP_THREAD
  if (!osxvideosink->app_started) {
    [NSApplication sharedApplication];
    [NSApp finishLaunching];
    osxvideosink->app_started = TRUE;
  }
#endif

  if (!GetCurrentProcess(&psn)) {
      TransformProcessType(&psn, kProcessTransformToForegroundApplication);
      SetFrontProcess(&psn);
  }

  osxwindow->win =[[[GstOSXVideoSinkWindow alloc]
                       initWithContentNSRect: rect
                       styleMask: mask
                       backing: NSBackingStoreBuffered
                       defer: NO
                       screen: nil] retain];
  GST_DEBUG("VideoSinkWindow created, %p", osxwindow->win);
  [osxwindow->win makeKeyAndOrderFront:NSApp];
  osxwindow->gstview =[osxwindow->win gstView];
  [osxwindow->win setDelegate:[[GstWindowDelegate alloc]
      initWithSink:osxvideosink]];

}

#ifdef RUN_NS_APP_THREAD
+ (BOOL) isMainThread
{
  /* FIXME: ideally we should return YES only for ->ns_app_thread here */
  return YES;
}
#endif

- (void) setView: (NSView*)view
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  if (osxvideosink->superview) {
    GST_INFO_OBJECT (osxvideosink, "old xwindow id %p", osxvideosink->superview);
    if (osxvideosink->osxwindow) {
      [osxvideosink->osxwindow->gstview removeFromSuperview];
    }
    [osxvideosink->superview release];
  }
  if (osxvideosink->osxwindow != NULL && view != NULL) {
    if (osxvideosink->osxwindow->internal) {
      GST_INFO_OBJECT (osxvideosink, "closing internal window");
      osxvideosink->osxwindow->closed = TRUE;
      [osxvideosink->osxwindow->win close];
      [osxvideosink->osxwindow->win release];
    }
  }

  GST_INFO_OBJECT (osxvideosink, "set xwindow id %p", view);
  osxvideosink->superview = [view retain];
  if (osxvideosink->osxwindow) {
    [osxvideosink->osxwindow->gstview addToSuperview: osxvideosink->superview];
    if (view) {
      osxvideosink->osxwindow->internal = FALSE;
    }
  }

  [pool release];
}

- (void) resize
{
  GstOSXWindow *osxwindow = osxvideosink->osxwindow;

  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  GST_INFO_OBJECT (osxvideosink, "resizing");
  NSSize size = {osxwindow->width, osxwindow->height};
  if (osxwindow->internal) {
    [osxwindow->win setContentSize:size];
  }
  if (osxwindow->gstview) {
      [osxwindow->gstview setVideoSize :(int)osxwindow->width :(int)osxwindow->height];
  }
  GST_INFO_OBJECT (osxvideosink, "done");

  [pool release];
}

- (void) showFrame: (GstBufferObject *) object
{
  GstMapInfo info;
  guint8 *viewdata;
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  GstBuffer *buf = object->buf;

  if (osxvideosink->osxwindow != NULL)
  {
    gst_buffer_map (buf, &info, GST_MAP_READ);
    viewdata = (guint8 *) [osxvideosink->osxwindow->gstview getTextureBuffer];

    if (G_UNLIKELY (viewdata == NULL)) {
      GST_ELEMENT_ERROR (osxvideosink, RESOURCE, WRITE,
        ("Could not get a texture buffer"), (NULL));
    } else {
      memcpy (viewdata, info.data, info.size);
      [osxvideosink->osxwindow->gstview displayTexture];
      gst_buffer_unmap (buf, &info);
    }
  }

  [object release];

  [pool release];
}

-(void) destroy
{
  NSAutoreleasePool *pool;
  GstOSXWindow *osxwindow;

  pool = [[NSAutoreleasePool alloc] init];

  osxwindow = osxvideosink->osxwindow;
  osxvideosink->osxwindow = NULL;

  if (osxwindow) {
    if (osxvideosink->superview) {
      [osxwindow->gstview removeFromSuperview];
    }
    [osxwindow->gstview release];
    if (osxwindow->internal) {
      if (!osxwindow->closed) {
        osxwindow->closed = TRUE;
        [osxwindow->win close];
        [osxwindow->win release];
      }
    }
    g_free (osxwindow);
  }
  [pool release];
}

#ifdef RUN_NS_APP_THREAD
-(void) nsAppThread
{
  NSAutoreleasePool *pool;

  /* set the main runloop as the runloop for the current thread. This has the
   * effect that calling NSApp nextEventMatchingMask:untilDate:inMode:dequeue
   * runs the main runloop.
   */
  _CFRunLoopSetCurrent(CFRunLoopGetMain());

  /* this is needed to make IsMainThread checks in core foundation work from the
   * current thread
   */
  _CFMainPThread = pthread_self();

  pool = [[NSAutoreleasePool alloc] init];

  [NSApplication sharedApplication];
  [NSApp finishLaunching];

  g_mutex_lock (&_run_loop_mutex);
  g_cond_signal (&_run_loop_cond);
  g_mutex_unlock (&_run_loop_mutex);

  /* run the loop */
  run_ns_app_loop ();

  [pool release];
}
#endif

-(void) checkMainRunLoop
{
  g_mutex_lock (&_run_loop_mutex);
  g_cond_signal (&_run_loop_cond);
  g_mutex_unlock (&_run_loop_mutex);
}

@end

@ implementation GstBufferObject
-(id) initWithBuffer: (GstBuffer*) buffer
{
  self = [super init];
  gst_buffer_ref(buffer);
  self->buf = buffer;
  return self;
}

-(void) dealloc{
  gst_buffer_unref(buf);
  [super dealloc];
}
@end

static gboolean
plugin_init (GstPlugin * plugin)
{

  if (!gst_element_register (plugin, "osxvideosink",
          GST_RANK_PRIMARY, GST_TYPE_OSX_VIDEO_SINK))
    return FALSE;

  GST_DEBUG_CATEGORY_INIT (gst_debug_osx_video_sink, "osxvideosink", 0,
      "osxvideosink element");

  return TRUE;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    osxvideo,
    "OSX native video output plugin",
    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
