/*
 * GStreamer
 * Copyright (C) 2015 Matthew Waters <matthew@centricular.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

#include <Cocoa/Cocoa.h>

#include "gstglcaopengllayer.h"
#include "gstgl_cocoa_private.h"

@implementation GstGLCAOpenGLLayer
- (void)dealloc {
  if (self->draw_notify)
    self->draw_notify (self->draw_data);

  if (self->draw_context)
    gst_object_unref (self->draw_context);

  GST_TRACE ("dealloc GstGLCAOpenGLLayer %p context %p", self, self->gst_gl_context);

  [super dealloc];
}

static void
_context_ready (gpointer data)
{
  GstGLCAOpenGLLayer *ca_layer = data;

  g_atomic_int_set (&ca_layer->can_draw, 1);
}

- (id)initWithGstGLContext:(GstGLContextCocoa *)parent_gl_context {
  [super init];

  GST_LOG ("init CAOpenGLLayer");

  self->gst_gl_context = parent_gl_context;
  self.needsDisplayOnBoundsChange = YES;

  gst_gl_window_send_message_async (GST_GL_CONTEXT (parent_gl_context)->window,
      (GstGLWindowCB) _context_ready, self, NULL);

  return self;
}

- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask {
  CGLPixelFormatObj fmt = NULL;

  if (self->gst_gl_context)
    fmt = gst_gl_context_cocoa_get_pixel_format (self->gst_gl_context);

  if (!fmt) {
    CGLPixelFormatAttribute attribs[] = {
      kCGLPFADoubleBuffer,
      kCGLPFAAccumSize, 32,
      0
    };
    CGLError ret;
    gint npix = 0;

    GST_DEBUG ("creating new pixel format for CAOpenGLLayer %p", self);

    ret = CGLChoosePixelFormat (attribs, &fmt, &npix);
    if (ret != kCGLNoError) {
      GST_ERROR ("CAOpenGLLayer cannot choose a pixel format: %s", CGLErrorString (ret));
    }
  }

  return fmt;
}

- (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat {
  GstGLDisplay *display;
  CGLContextObj external_context = NULL;
  CGLError ret;
  GError *error = NULL;

  if (self->gst_gl_context)
    external_context = (CGLContextObj) gst_gl_context_get_gl_context (GST_GL_CONTEXT (self->gst_gl_context));

  GST_INFO ("attempting to create CGLContext for CAOpenGLLayer with "
      "share context %p", external_context);

  ret = CGLCreateContext (pixelFormat, external_context, &self->gl_context);
  if (ret != kCGLNoError) {
    GST_ERROR ("failed to create CGL context in CAOpenGLLayer with share context %p: %s", external_context, CGLErrorString(ret));
    return NULL;
  }

  if (self->draw_context)
    gst_object_unref (self->draw_context);

  if (kCGLNoError != CGLSetCurrentContext (self->gl_context)) {
    GST_ERROR ("failed set cgl context %p current", self->gl_context);
    return NULL;
  }

  display = gst_gl_context_get_display (GST_GL_CONTEXT (self->gst_gl_context));
  self->draw_context = gst_gl_context_new_wrapped (display,
      (guintptr) self->gl_context, GST_GL_PLATFORM_CGL,
      gst_gl_context_get_current_gl_api (GST_GL_PLATFORM_CGL, NULL, NULL));
  gst_object_unref (display);

  if (!self->draw_context) {
    GST_ERROR ("failed to create wrapped context");
    return NULL;
  }

  gst_gl_context_activate (self->draw_context, TRUE);
  gst_gl_context_set_shared_with (self->draw_context, GST_GL_CONTEXT (self->gst_gl_context));
  if (!gst_gl_context_fill_info (self->draw_context, &error)) {
    GST_ERROR ("failed to fill wrapped context information: %s", error->message);
    return NULL;
  }
  gst_gl_context_activate (self->draw_context, FALSE);

  return self->gl_context;
}

- (void)queueResize {
  self->queue_resize = TRUE;
}

- (void)releaseCGLContext:(CGLContextObj)glContext {
  CGLReleaseContext (glContext);
}

- (void)setDrawCallback:(GstGLWindowCB)cb data:(gpointer)data
      notify:(GDestroyNotify)notify {
  g_return_if_fail (cb);

  if (self->draw_notify)
    self->draw_notify (self->draw_data);

  self->draw_cb = cb;
  self->draw_data = data;
  self->draw_notify = notify;
}

- (void)setResizeCallback:(GstGLWindowResizeCB)cb data:(gpointer)data
      notify:(GDestroyNotify)notify {
  if (self->resize_notify)
    self->resize_notify (self->resize_notify);

  self->resize_cb = cb;
  self->resize_data = data;
  self->resize_notify = notify;
}

- (BOOL)canDrawInCGLContext:(CGLContextObj)glContext
               pixelFormat:(CGLPixelFormatObj)pixelFormat
            forLayerTime:(CFTimeInterval)interval
             displayTime:(const CVTimeStamp *)timeStamp {
  return g_atomic_int_get (&self->can_draw);
}

- (void)drawInCGLContext:(CGLContextObj)glContext
               pixelFormat:(CGLPixelFormatObj)pixelFormat
            forLayerTime:(CFTimeInterval)interval
             displayTime:(const CVTimeStamp *)timeStamp {
  const GstGLFuncs *gl = ((GstGLContext *)self->gst_gl_context)->gl_vtable;
  GstVideoRectangle src, dst, result;
  gint ca_viewport[4];

  GST_LOG ("CAOpenGLLayer drawing with cgl context %p", glContext);

  /* attempt to get the correct viewport back due to CA being too smart
   * and messing around with it so center the expected viewport into
   * the CA viewport set up on entry to this function */
  gl->GetIntegerv (GL_VIEWPORT, ca_viewport);

  gst_gl_context_activate (self->draw_context, TRUE);
  if (self->queue_resize || self->last_bounds.size.width != self.bounds.size.width
      || self->last_bounds.size.height != self.bounds.size.height) {
    if (self->resize_cb) {
      self->resize_cb (self->resize_data, 
          self.bounds.size.width*self.contentsScale,
          self.bounds.size.height*self.contentsScale);

      gl->GetIntegerv (GL_VIEWPORT, self->expected_dims);
    } else {
      /* default to whatever ca gives us */
      self->expected_dims[0] = ca_viewport[0];
      self->expected_dims[1] = ca_viewport[1];
      self->expected_dims[2] = ca_viewport[2];
      self->expected_dims[3] = ca_viewport[3];
    }

    self->last_bounds = self.bounds;
    self->queue_resize = FALSE;
  }

  src.x = self->expected_dims[0];
  src.y = self->expected_dims[1];
  src.w = self->expected_dims[2];
  src.h = self->expected_dims[3];

  dst.x = ca_viewport[0];
  dst.y = ca_viewport[1];
  dst.w = ca_viewport[2];
  dst.h = ca_viewport[3];

  gst_video_sink_center_rect (src, dst, &result, TRUE);

  gl->Viewport (result.x, result.y, result.w, result.h);

  if (self->draw_cb)
    self->draw_cb (self->draw_data);
  gst_gl_context_activate (self->draw_context, FALSE);

  /* flushes the buffer */
  [super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:interval displayTime:timeStamp];
}

@end
