/*
 * GStreamer
 * Copyright (C) 2012 Matthew Waters <ystreet00@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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <Cocoa/Cocoa.h>

#include "gstglcontext_cocoa.h"
#include "gstgl_cocoa_private.h"

static gboolean gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
    GstGLContext * other_context, GError **error);
static void gst_gl_context_cocoa_destroy_context (GstGLContext *context);
static guintptr gst_gl_context_cocoa_get_gl_context (GstGLContext * window);
static gboolean gst_gl_context_cocoa_activate (GstGLContext * context, gboolean activate);
static GstGLAPI gst_gl_context_cocoa_get_gl_api (GstGLContext * context);
static GstGLPlatform gst_gl_context_cocoa_get_gl_platform (GstGLContext * context);

#define GST_GL_CONTEXT_COCOA_GET_PRIVATE(o)  \
  (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_CONTEXT_COCOA, GstGLContextCocoaPrivate))

GST_DEBUG_CATEGORY_STATIC (gst_gl_context_cocoa_debug);
#define GST_CAT_DEFAULT gst_gl_context_cocoa_debug

G_DEFINE_TYPE_WITH_CODE (GstGLContextCocoa, gst_gl_context_cocoa,
    GST_GL_TYPE_CONTEXT, GST_DEBUG_CATEGORY_INIT (gst_gl_context_cocoa_debug, "glcontext_cocoa", 0, "Cocoa GL Context"); );

static void
gst_gl_context_cocoa_class_init (GstGLContextCocoaClass * klass)
{
  GstGLContextClass *context_class = (GstGLContextClass *) klass;

  g_type_class_add_private (klass, sizeof (GstGLContextCocoaPrivate));

  context_class->destroy_context =
      GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_destroy_context);
  context_class->create_context =
      GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_create_context);
  context_class->get_gl_context =
      GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_get_gl_context);
  context_class->activate = GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_activate);
  context_class->get_gl_api =
      GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_get_gl_api);
  context_class->get_gl_platform =
      GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_get_gl_platform);
}

static void
gst_gl_context_cocoa_init (GstGLContextCocoa * context)
{
  context->priv = GST_GL_CONTEXT_COCOA_GET_PRIVATE (context);
}

/* Must be called in the gl thread */
GstGLContextCocoa *
gst_gl_context_cocoa_new (GstGLDisplay * display)
{
  if ((gst_gl_display_get_handle_type (display) & GST_GL_DISPLAY_TYPE_COCOA) == 0)
    /* we require an cocoa display to create CGL contexts */
    return NULL;

  return g_object_new (GST_GL_TYPE_CONTEXT_COCOA, NULL);
}

struct pixel_attr
{
  CGLPixelFormatAttribute attr;
  const gchar *attr_name;
};

static struct pixel_attr pixel_attrs[] = {
  {kCGLPFAAllRenderers, "All Renderers"},
  {kCGLPFADoubleBuffer, "Double Buffered"},
  {kCGLPFAAuxBuffers, "Aux Buffers"},
  {kCGLPFAColorSize, "Color Size"},
  {kCGLPFAAlphaSize, "Alpha Size"},
  {kCGLPFADepthSize, "Depth Size"},
  {kCGLPFAStencilSize, "Stencil Size"},
  {kCGLPFAAccumSize, "Accum Size"},
  {kCGLPFAMinimumPolicy, "Minimum Policy"},
  {kCGLPFAMaximumPolicy, "Maximum Policy"},
  {kCGLPFASampleBuffers, "Sample Buffers"},
  {kCGLPFASamples, "Samples"},
  {kCGLPFAAuxDepthStencil, "Aux Depth Stencil"},
  {kCGLPFAColorFloat, "Color Float"},
  {kCGLPFAMultisample, "Multisample"},
  {kCGLPFASupersample, "Supersample"},
  {kCGLPFARendererID, "Renderer ID"},
  {kCGLPFANoRecovery, "No Recovery"},
  {kCGLPFAAccelerated, "Accelerated"},
  {kCGLPFAClosestPolicy, "Closest Policy"},
  {kCGLPFABackingStore, "Backing Store"},
  {kCGLPFADisplayMask, "Display Mask"},
  {kCGLPFAAllowOfflineRenderers, "Allow Offline Renderers"},
  {kCGLPFAAcceleratedCompute, "Accelerated Compute"},
  {kCGLPFAOpenGLProfile, "OpenGL Profile"},
  {kCGLPFAVirtualScreenCount, "Virtual Screen Count"},
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_11
  {kCGLPFAStereo, "Stereo"},
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_9
  {kCGLPFACompliant, "Compliant"},
  {kCGLPFARemotePBuffer, "Remote PBuffer"},
  {kCGLPFASingleRenderer, "Single Renderer"},
  {kCGLPFAWindow, "Window"},
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
//  {kCGLPFAOffScreen, "Off Screen"},
//  {kCGLPFAPBuffer, "PBuffer"},
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
//  {kCGLPFAFullScreen, "Full Screen"},
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
//  {kCGLPFAMPSafe, "MP Safe"},
//  {kCGLPFAMultiScreen, "Multi Screen"},
//  {kCGLPFARobust, "Robust"},
#endif
};

void
gst_gl_context_cocoa_dump_pixel_format (CGLPixelFormatObj fmt)
{
  int i;

  for (i = 0; i < G_N_ELEMENTS (pixel_attrs); i++) {
    gint val;
    CGLError ret = CGLDescribePixelFormat (fmt, 0, pixel_attrs[i].attr, &val);

    if (ret != kCGLNoError) {
      GST_WARNING ("failed to get pixel format %p attribute %s", fmt, pixel_attrs[i].attr_name);
    } else {
      GST_DEBUG ("Pixel format %p attr %s = %i", fmt, pixel_attrs[i].attr_name,
          val);
    }
  }
}

CGLPixelFormatObj
gst_gl_context_cocoa_get_pixel_format (GstGLContextCocoa *context)
{
  return context->priv->pixel_format;
}

static gboolean
gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
    GstGLContext *other_context, GError **error)
{
  GstGLContextCocoa *context_cocoa = GST_GL_CONTEXT_COCOA (context);
  GstGLContextCocoaPrivate *priv = context_cocoa->priv;
  GstGLWindow *window = gst_gl_context_get_window (context);
  GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
  GstGLAPI context_api = GST_GL_API_NONE;
  const GLint swapInterval = 1;
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  CGLPixelFormatObj fmt = NULL;
  CGLContextObj glContext;
  CGLPixelFormatAttribute attribs[] = {
    kCGLPFADoubleBuffer,
    kCGLPFAAccumSize, 32,
    0
  };
  CGLError ret;
  gint pix_fmt_i = 0;
  gint npix;

  if ((gl_api & (GST_GL_API_OPENGL | GST_GL_API_OPENGL3)) == GST_GL_API_NONE) {
    g_set_error (error, GST_GL_CONTEXT_ERROR,
        GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
        "The CGL backend only supports GL and GL3");
    goto error;
  }

  priv->gl_context = nil;
  if (other_context)
    priv->external_gl_context = (CGLContextObj) gst_gl_context_get_gl_context (other_context);
  else
    priv->external_gl_context = NULL;

  if (priv->external_gl_context) {
    gint profile;

    fmt = CGLGetPixelFormat (priv->external_gl_context);

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
    /* core profile is only available in >= 10.7 */
    if (kCGLNoError == CGLDescribePixelFormat (fmt, 0, kCGLPFAOpenGLProfile,
          &profile)) {
      if (profile == kCGLOGLPVersion_3_2_Core) {
        context_api = GST_GL_API_OPENGL3;
      } else {
        context_api =GST_GL_API_OPENGL;
      }
    }
#else
    context_api = GST_GL_API_OPENGL;
#endif
  }

  if (!fmt) {
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
    if (gl_api & GST_GL_API_OPENGL3) {
      attribs[pix_fmt_i++] = kCGLPFAOpenGLProfile;
      attribs[pix_fmt_i++] = (int) kCGLOGLPVersion_3_2_Core;
      context_api = GST_GL_API_OPENGL3;
    } else {
      context_api = GST_GL_API_OPENGL;
    }
#else
    context_api = GST_GL_API_OPENGL;
#endif

    attribs[pix_fmt_i++] = 0;

    ret = CGLChoosePixelFormat (attribs, &fmt, &npix);
    if (ret != kCGLNoError) {
      g_set_error (error, GST_GL_CONTEXT_ERROR,
          GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "cannot choose a pixel format: %s", CGLErrorString (ret));
      goto error;
    }
  }

  gst_gl_context_cocoa_dump_pixel_format (fmt);

  ret = CGLCreateContext (fmt, priv->external_gl_context, &glContext);
  if (ret != kCGLNoError) {
    g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
        "failed to create context: %s", CGLErrorString (ret));
    goto error;
  }

  context_cocoa->priv->pixel_format = fmt;
  context_cocoa->priv->gl_context = glContext;

  _invoke_on_main ((GstGLWindowCB) gst_gl_window_cocoa_create_window,
      window_cocoa);

  if (!context_cocoa->priv->gl_context) {
    goto error;
  }

  GST_INFO_OBJECT (context, "GL context created: %p", context_cocoa->priv->gl_context);

  CGLSetCurrentContext (context_cocoa->priv->gl_context);

  /* Back and front buffers are swapped only during the vertical retrace of the monitor.
   * Discarded if you configured your driver to Never-use-V-Sync.
   */
  CGLSetParameter (context_cocoa->priv->gl_context, kCGLCPSwapInterval, &swapInterval);

  context_cocoa->priv->context_api = context_api;

  if (window)
    gst_object_unref (window);
  [pool release];

  return TRUE;

error:
  {
    if (window)
      gst_object_unref (window);
    [pool release];
    return FALSE;
  }
}

static void
gst_gl_context_cocoa_destroy_context (GstGLContext *context)
{
  /* FIXME: Need to release context and other things? */
}

static guintptr
gst_gl_context_cocoa_get_gl_context (GstGLContext * context)
{
  return (guintptr) GST_GL_CONTEXT_COCOA (context)->priv->gl_context;
}

static gboolean
gst_gl_context_cocoa_activate (GstGLContext * context, gboolean activate)
{
  GstGLContextCocoa *context_cocoa = GST_GL_CONTEXT_COCOA (context);
  gpointer context_handle = activate ? context_cocoa->priv->gl_context : NULL;

  return kCGLNoError == CGLSetCurrentContext (context_handle);
}

static GstGLAPI
gst_gl_context_cocoa_get_gl_api (GstGLContext * context)
{
  GstGLContextCocoa *context_cocoa = GST_GL_CONTEXT_COCOA (context);

  if (context_cocoa->priv->gl_context)
    return context_cocoa->priv->context_api;

  return GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
}

static GstGLPlatform
gst_gl_context_cocoa_get_gl_platform (GstGLContext * context)
{
  return GST_GL_PLATFORM_CGL;
}

guintptr
gst_gl_context_cocoa_get_current_context (void)
{
  return (guintptr) CGLGetCurrentContext ();
}
