/*
 * GStreamer
 * Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
 * Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it un der 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 <Cocoa/Cocoa.h>
#include <QuartzCore/QuartzCore.h>

#include "gstgl_cocoa_private.h"

#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
#define NSWindowStyleMaskTitled              NSTitledWindowMask
#define NSWindowStyleMaskClosable            NSClosableWindowMask
#define NSWindowStyleMaskResizable           NSResizableWindowMask
#define NSWindowStyleMaskMiniaturizable      NSMiniaturizableWindowMask
#endif

/* =============================================================*/
/*                                                              */
/*               GstGLNSWindow declaration                      */
/*                                                              */
/* =============================================================*/

@interface GstGLNSWindow: NSWindow {
  BOOL m_isClosed;
  GstGLWindowCocoa *window_cocoa;
}
- (id)initWithContentRect:(NSRect)contentRect
    styleMask: (unsigned int) styleMask
    backing: (NSBackingStoreType) bufferingType
    defer: (BOOL) flag screen: (NSScreen *) aScreen
    gstWin: (GstGLWindowCocoa *) window;
- (void) setClosed;
- (BOOL) isClosed;
- (BOOL) canBecomeMainWindow;
- (BOOL) canBecomeKeyWindow;
@end

/* =============================================================*/
/*                                                              */
/*                      GstGLWindow                             */
/*                                                              */
/* =============================================================*/

#define GST_GL_WINDOW_COCOA_GET_PRIVATE(o)  \
  (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GL_WINDOW_COCOA, GstGLWindowCocoaPrivate))

#define GST_CAT_DEFAULT gst_gl_window_cocoa_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

#define DEBUG_INIT \
  GST_DEBUG_CATEGORY_GET (GST_CAT_DEFAULT, "glwindow");
#define gst_gl_window_cocoa_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLWindowCocoa, gst_gl_window_cocoa, GST_TYPE_GL_WINDOW, DEBUG_INIT);
static void gst_gl_window_cocoa_finalize (GObject * object);

static gboolean gst_gl_window_cocoa_open (GstGLWindow *window, GError **err);
static void gst_gl_window_cocoa_close (GstGLWindow *window);
static guintptr gst_gl_window_cocoa_get_window_handle (GstGLWindow * window);
static void gst_gl_window_cocoa_set_window_handle (GstGLWindow * window,
    guintptr handle);
static void gst_gl_window_cocoa_draw (GstGLWindow * window);
static void gst_gl_window_cocoa_set_preferred_size (GstGLWindow * window,
    gint width, gint height);
static void gst_gl_window_cocoa_show (GstGLWindow * window);
static void gst_gl_window_cocoa_queue_resize (GstGLWindow * window);
static void gst_gl_window_cocoa_send_message_async (GstGLWindow * window,
    GstGLWindowCB callback, gpointer data, GDestroyNotify destroy);

struct _GstGLWindowCocoaPrivate
{
  gpointer internal_win_id;
  gpointer external_view;
  gboolean visible;
  gint preferred_width;
  gint preferred_height;

  GLint viewport_dim[4];

  /* atomic set when the internal NSView has been created */
  int view_ready;

  gpointer gl_queue;
};

static void
gst_gl_window_cocoa_class_init (GstGLWindowCocoaClass * klass)
{
  GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
  GObjectClass *gobject_class = (GObjectClass *) klass;

  g_type_class_add_private (klass, sizeof (GstGLWindowCocoaPrivate));

  window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_open);
  window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_close);
  window_class->get_window_handle =
      GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_get_window_handle);
  window_class->set_window_handle =
      GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_set_window_handle);
  window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_draw);
  window_class->set_preferred_size =
      GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_set_preferred_size);
  window_class->show = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_show);
  window_class->queue_resize = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_queue_resize);
  window_class->send_message_async =
      GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_send_message_async);

  gobject_class->finalize = gst_gl_window_cocoa_finalize;
}

static void
gst_gl_window_cocoa_init (GstGLWindowCocoa * window)
{
  window->priv = GST_GL_WINDOW_COCOA_GET_PRIVATE (window);

  window->priv->preferred_width = 320;
  window->priv->preferred_height = 240;
  window->priv->gl_queue = (__bridge_retained gpointer)
      (dispatch_queue_create ("org.freedesktop.gstreamer.glwindow", NULL));
}

static void
gst_gl_window_cocoa_finalize (GObject * object)
{
  GstGLWindowCocoa *window = GST_GL_WINDOW_COCOA (object);
  window->priv->gl_queue = NULL;
  G_OBJECT_CLASS (parent_class)->finalize (object);
}

GstGLWindowCocoa *
gst_gl_window_cocoa_new (GstGLDisplay * display)
{
  GstGLWindowCocoa *window;

  if ((gst_gl_display_get_handle_type (display) & GST_GL_DISPLAY_TYPE_COCOA) == 0)
    /* we require an cocoa display to create CGL windows */
    return NULL;

  window = g_object_new (GST_TYPE_GL_WINDOW_COCOA, NULL);
  gst_object_ref_sink (window);

  return window;
}

/* Must be called from the main thread */
gboolean
gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa)
{
  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
  GstGLWindow *window = GST_GL_WINDOW (window_cocoa);
  GstGLNSWindow *internal_win_id;
  NSRect mainRect = [[NSScreen mainScreen] visibleFrame];
  gint h = priv->preferred_height;
  gint y = mainRect.size.height > h ? (mainRect.size.height - h) * 0.5 : 0;
  NSRect rect = NSMakeRect (0, y, priv->preferred_width, priv->preferred_height);
  NSRect windowRect = NSMakeRect (0, y, priv->preferred_width, priv->preferred_height);
  GstGLContext *context = gst_gl_window_get_context (window);
  GstGLContextCocoa *context_cocoa;
  GstGLCAOpenGLLayer *layer;
  GstGLNSView *glView;

  if (!context)
    return FALSE;

  context_cocoa = GST_GL_CONTEXT_COCOA (context);
  layer = [[GstGLCAOpenGLLayer alloc] initWithGstGLContext:context];
  glView = [[GstGLNSView alloc] initWithFrameLayer:window_cocoa rect:windowRect layer:layer];

  gst_object_unref (context);

  internal_win_id = [[GstGLNSWindow alloc] initWithContentRect:rect styleMask:
      (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
      NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable)
      backing: NSBackingStoreBuffered defer: NO screen: nil gstWin: window_cocoa];

  priv->internal_win_id = (__bridge_retained gpointer)internal_win_id;

  GST_DEBUG ("NSWindow id: %"G_GUINTPTR_FORMAT, (guintptr) priv->internal_win_id);

  [internal_win_id setContentView:glView];

  g_atomic_int_set (&window_cocoa->priv->view_ready, 1);

  /* Set the window handle for real now that the NSWindow has been created. */
  if (priv->external_view)
    gst_gl_window_cocoa_set_window_handle (window,
        (guintptr) priv->external_view);

  return TRUE;
}

static gboolean
gst_gl_window_cocoa_open (GstGLWindow *window, GError **err)
{
  GstGLWindowCocoa *window_cocoa;

  window_cocoa = GST_GL_WINDOW_COCOA (window);

  return TRUE;
}

static void
gst_gl_window_cocoa_close (GstGLWindow *window)
{
  GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)window_cocoa->priv->internal_win_id;

  [[internal_win_id contentView] removeFromSuperview];
  CFBridgingRelease(window_cocoa->priv->internal_win_id);
  window_cocoa->priv->internal_win_id = NULL;
}

static guintptr
gst_gl_window_cocoa_get_window_handle (GstGLWindow *window)
{
  return (guintptr) GST_GL_WINDOW_COCOA (window)->priv->internal_win_id;
}

static void
gst_gl_window_cocoa_set_window_handle (GstGLWindow * window, guintptr handle)
{
  GstGLWindowCocoa *window_cocoa;
  GstGLWindowCocoaPrivate *priv;

  window_cocoa = GST_GL_WINDOW_COCOA (window);
  priv = window_cocoa->priv;

  if (priv->internal_win_id) {
    if (handle) {
      priv->external_view = (gpointer)handle;
      priv->visible = TRUE;
    } else {
      /* bring back our internal window */
      priv->external_view = 0;
      priv->visible = FALSE;
    }


    dispatch_async (dispatch_get_main_queue (), ^{
      GstGLNSWindow *internal_win_id =
          (__bridge GstGLNSWindow *)window_cocoa->priv->internal_win_id;
      NSView *external_view =
          (__bridge NSView *)window_cocoa->priv->external_view;

      NSView *view = [internal_win_id contentView];
      [internal_win_id orderOut:internal_win_id];

      [external_view addSubview: view];

      [view setFrame: [external_view bounds]];
      [view setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
    });
  } else {
    /* no internal window yet so delay it to the next drawing */
    priv->external_view = (gpointer)handle;
    priv->visible = FALSE;
  }
}

static void
_show_window (gpointer data)
{
  GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (data);
  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;

  GST_DEBUG_OBJECT (window_cocoa, "make the window available\n");
  [internal_win_id makeMainWindow];
  [internal_win_id orderFrontRegardless];
  [internal_win_id setViewsNeedDisplay:YES];

  priv->visible = TRUE;
}

static void
gst_gl_window_cocoa_show (GstGLWindow * window)
{
  GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;

  if (!priv->visible) {
    /* useful when set_window_handle is called before
     * the internal NSWindow */
    if (priv->external_view) {
      gst_gl_window_cocoa_set_window_handle (window, (guintptr) priv->external_view);
      priv->visible = TRUE;
      return;
    }

    if (!priv->external_view && !priv->visible)
      _invoke_on_main ((GstGLWindowCB) _show_window, gst_object_ref (window),
          (GDestroyNotify) gst_object_unref);
  }
}

static void
gst_gl_window_cocoa_queue_resize (GstGLWindow * window)
{
  GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
  GstGLNSView *view;
  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;

  if (!g_atomic_int_get (&window_cocoa->priv->view_ready))
    return;

  view = (GstGLNSView *)[internal_win_id contentView];

  [view->layer queueResize];
}

static void
gst_gl_window_cocoa_draw (GstGLWindow * window)
{
  GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
  GstGLNSView *view;
  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;

  /* As the view is created asynchronously in the main thread we cannot know
   * exactly when it will be ready to draw to */
  if (!g_atomic_int_get (&window_cocoa->priv->view_ready))
    return;

  view = (GstGLNSView *)[internal_win_id contentView];

  /* this redraws the GstGLCAOpenGLLayer which calls
   * gst_gl_window_cocoa_draw_thread(). Use an explicit CATransaction since we
   * don't know how often the main runloop is running.
   */
  [CATransaction begin];
  [view setNeedsDisplay:YES];
  [CATransaction commit];
}

static void
gst_gl_window_cocoa_set_preferred_size (GstGLWindow * window, gint width,
    gint height)
{
  GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);

  window_cocoa->priv->preferred_width = width;
  window_cocoa->priv->preferred_height = height;
}

static void
gst_gl_cocoa_draw_cb (GstGLWindowCocoa *window_cocoa)
{
  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;

  if (internal_win_id && ![internal_win_id isClosed]) {
   GstGLWindow *window = GST_GL_WINDOW (window_cocoa);

    /* draw opengl scene in the back buffer */
    if (window->draw)
      window->draw (window->draw_data);
  }
}

static void
gst_gl_cocoa_resize_cb (GstGLNSView * view, guint width, guint height)
{
  GstGLWindowCocoa *window_cocoa = view->window_cocoa;
  GstGLWindow *window = GST_GL_WINDOW (window_cocoa);
  GstGLContext *context = gst_gl_window_get_context (window);
  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;

  if (internal_win_id && ![internal_win_id isClosed]) {
    const GstGLFuncs *gl;
    NSRect bounds = [view bounds];
    NSRect visibleRect = [view visibleRect];
    gint viewport_dim[4];

    gl = context->gl_vtable;

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
    bounds = [view convertRectToBacking:bounds];
    visibleRect = [view convertRectToBacking:visibleRect];
#endif

    GST_DEBUG_OBJECT (window, "Window resized: bounds %lf %lf %lf %lf "
                      "visibleRect %lf %lf %lf %lf",
                      bounds.origin.x, bounds.origin.y,
                      bounds.size.width, bounds.size.height,
                      visibleRect.origin.x, visibleRect.origin.y,
                      visibleRect.size.width, visibleRect.size.height);

    gst_gl_window_resize (window, width, height);
    gl->GetIntegerv (GL_VIEWPORT, viewport_dim);

    gl->Viewport (viewport_dim[0] - visibleRect.origin.x,
                  viewport_dim[1] - visibleRect.origin.y,
                  viewport_dim[2], viewport_dim[3]);
  }

  gst_object_unref (context);
}

static void
gst_gl_window_cocoa_send_message_async (GstGLWindow * window,
    GstGLWindowCB callback, gpointer data, GDestroyNotify destroy)
{
  GstGLWindowCocoa *window_cocoa = (GstGLWindowCocoa *) window;
  GstGLContext *context = gst_gl_window_get_context (window);
  GThread *thread = gst_gl_context_get_thread (context);
  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
  dispatch_queue_t gl_queue = (__bridge dispatch_queue_t)priv->gl_queue;

  if (thread == g_thread_self()) {
    /* this case happens for nested calls happening from inside the GCD queue */
    callback (data);
    if (destroy)
      destroy (data);
    gst_object_unref (context);
  } else {
    dispatch_async (gl_queue, ^{
      gst_gl_context_activate (context, TRUE);
      gst_object_unref (context);
      callback (data);
      if (destroy)
        destroy (data);
    });
  }
  if (thread)
    g_thread_unref (thread);
}

/* =============================================================*/
/*                                                              */
/*                    GstGLNSWindow implementation              */
/*                                                              */
/* =============================================================*/

/* Must be called from the main thread */
@implementation GstGLNSWindow

- (id) initWithContentRect: (NSRect) contentRect
        styleMask: (unsigned int) styleMask
    backing: (NSBackingStoreType) bufferingType
    defer: (BOOL) flag screen: (NSScreen *) aScreen
    gstWin: (GstGLWindowCocoa *) cocoa {

  m_isClosed = NO;
  window_cocoa = cocoa;
  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;

  self = [super initWithContentRect: contentRect
        styleMask: styleMask backing: bufferingType
        defer: flag screen:aScreen];

  [self setReleasedWhenClosed:NO];

  GST_DEBUG ("initializing GstGLNSWindow\n");

  [self setTitle:@"OpenGL renderer"];

  [self setBackgroundColor:[NSColor blackColor]];

  [self orderOut:internal_win_id];

  return self;
}

- (void) setClosed {
  m_isClosed = YES;
}

- (BOOL) isClosed {
  return m_isClosed;
}

- (BOOL) canBecomeMainWindow {
  return YES;
}

- (BOOL) canBecomeKeyWindow {
  return YES;
}

static void
close_window_cb (gpointer data)
{
  GstGLWindowCocoa *window_cocoa = data;
  GstGLWindow *window;

  window = GST_GL_WINDOW (window_cocoa);

  if (window->close) {
    window->close (window->close_data);
  }
}

/* Called in the main thread which is never the gl thread */
- (BOOL) windowShouldClose:(id)sender {

  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;
  GST_DEBUG ("user clicked the close button\n");
  [internal_win_id setClosed];
  gst_gl_window_send_message_async (GST_GL_WINDOW (window_cocoa),
      (GstGLWindowCB) close_window_cb, gst_object_ref (window_cocoa),
      (GDestroyNotify) gst_object_unref);
  return YES;
}

@end

/* =============================================================*/
/*                                                              */
/*                GstGLNSView implementation              */
/*                                                              */
/* =============================================================*/

@implementation GstGLNSView

/* Must be called from the application main thread */
- (id)initWithFrameLayer:(GstGLWindowCocoa *)window rect:(NSRect)contentRect layer:(CALayer *)layerContent {

  self = [super initWithFrame: contentRect];

  window_cocoa = window;

  /* The order of the next two calls matters.  This creates a layer-hosted
   * NSView.  Calling setWantsLayer before setLayer will create a
   * layer-backed NSView.  See the apple developer documentation on the
   * difference.
   */
  [self setLayer:layerContent];
  [self setWantsLayer:YES];
  self->layer = (GstGLCAOpenGLLayer *)layerContent;
  [self->layer setDrawCallback:(GstGLWindowCB)gst_gl_cocoa_draw_cb
      data:window notify:NULL];
  [self->layer setResizeCallback:(GstGLWindowResizeCB)gst_gl_cocoa_resize_cb
      data:(__bridge_retained gpointer)self notify:(GDestroyNotify)CFRelease];

  [self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawOnSetNeedsDisplay];

  [self setWantsBestResolutionOpenGLSurface:YES];

  return self;
}

- (void) dealloc {
  self->layer = nil;
}

- (void)renewGState {
  /* Don't update the screen until we redraw, this
   * prevents flickering during scrolling, clipping,
   * resizing, etc
   */
  [[self window] disableScreenUpdatesUntilFlush];

  [super renewGState];
}

- (BOOL) isOpaque {
    return YES;
}

- (BOOL) isFlipped {
    return NO;
}

@end

void
_invoke_on_main (GstGLWindowCB func, gpointer data, GDestroyNotify notify)
{
  if ([NSThread isMainThread]) {
    func (data);
    if (notify)
      notify (data);
  } else {
    dispatch_async (dispatch_get_main_queue (), ^{
      func (data);
      if (notify)
        notify (data);
    });
  }
}
