/*
 * GStreamer
 * Copyright (C) 2014 Sebastian Dröge <sebastian@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

#import <OpenGLES/EAGL.h>
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
#include <OpenGLES/ES2/gl.h>

#include "gstglcontext_eagl.h"

#define GST_CAT_DEFAULT gst_gl_context_debug

static gboolean gst_gl_context_eagl_create_context (GstGLContext * context,
    GstGLAPI gl_api, GstGLContext * other_context, GError ** error);
static void gst_gl_context_eagl_destroy_context (GstGLContext * context);
static gboolean gst_gl_context_eagl_choose_format (GstGLContext * context,
    GError ** error);
static guintptr gst_gl_context_eagl_get_gl_context (GstGLContext * window);
static gboolean gst_gl_context_eagl_activate (GstGLContext * context,
    gboolean activate);
static void gst_gl_context_eagl_swap_buffers (GstGLContext * context);
static GstGLAPI gst_gl_context_eagl_get_gl_api (GstGLContext * context);
static GstGLPlatform gst_gl_context_eagl_get_gl_platform (GstGLContext *
    context);

struct _GstGLContextEaglPrivate
{
  EAGLContext *eagl_context;

  /* Used if we render to a window */
  CAEAGLLayer *eagl_layer;
  GLuint framebuffer;
  GLuint color_renderbuffer;
  GLuint depth_renderbuffer;
};

#define GST_GL_CONTEXT_EAGL_GET_PRIVATE(o)  \
  (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_CONTEXT_EAGL, GstGLContextEaglPrivate))

G_DEFINE_TYPE (GstGLContextEagl, gst_gl_context_eagl, GST_GL_TYPE_CONTEXT);

static void
gst_gl_context_eagl_class_init (GstGLContextEaglClass * klass)
{
  GstGLContextClass *context_class;

  context_class = (GstGLContextClass *) klass;

  g_type_class_add_private (klass, sizeof (GstGLContextEaglPrivate));

  context_class->destroy_context =
      GST_DEBUG_FUNCPTR (gst_gl_context_eagl_destroy_context);
  context_class->create_context =
      GST_DEBUG_FUNCPTR (gst_gl_context_eagl_create_context);
  context_class->choose_format =
      GST_DEBUG_FUNCPTR (gst_gl_context_eagl_choose_format);
  context_class->get_gl_context =
      GST_DEBUG_FUNCPTR (gst_gl_context_eagl_get_gl_context);
  context_class->activate = GST_DEBUG_FUNCPTR (gst_gl_context_eagl_activate);
  context_class->swap_buffers =
      GST_DEBUG_FUNCPTR (gst_gl_context_eagl_swap_buffers);
  context_class->get_gl_api =
      GST_DEBUG_FUNCPTR (gst_gl_context_eagl_get_gl_api);
  context_class->get_gl_platform =
      GST_DEBUG_FUNCPTR (gst_gl_context_eagl_get_gl_platform);
}

static void
gst_gl_context_eagl_init (GstGLContextEagl * context)
{
  context->priv = GST_GL_CONTEXT_EAGL_GET_PRIVATE (context);
}

/* Must be called in the gl thread */
GstGLContextEagl *
gst_gl_context_eagl_new (GstGLDisplay * display)
{
  /* there isn't actually a display type for eagl yet? */
  return g_object_new (GST_GL_TYPE_CONTEXT_EAGL, NULL);
}

void
gst_gl_context_eagl_resize (GstGLContextEagl * eagl_context)
{
  int width, height;

  glBindRenderbuffer (GL_RENDERBUFFER, eagl_context->priv->color_renderbuffer);
  [eagl_context->priv->eagl_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:eagl_context->priv->eagl_layer];
  glGetRenderbufferParameteriv (GL_RENDERBUFFER,
      GL_RENDERBUFFER_WIDTH, &width);
  glGetRenderbufferParameteriv (GL_RENDERBUFFER,
      GL_RENDERBUFFER_HEIGHT, &height);
  glBindRenderbuffer (GL_RENDERBUFFER, eagl_context->priv->depth_renderbuffer);
  glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width,
      height);
}

static void
gst_gl_context_eagl_release_layer (GstGLContext * context)
{
  GstGLContextEagl *context_eagl;

  context_eagl = GST_GL_CONTEXT_EAGL (context);

  if (context_eagl->priv->eagl_layer) {
    gst_gl_context_eagl_activate (context, TRUE);

    [context_eagl->priv->eagl_context renderbufferStorage: GL_RENDERBUFFER fromDrawable:nil];

    glDeleteFramebuffers (1, &context_eagl->priv->framebuffer);
    context_eagl->priv->framebuffer = 0;

    glDeleteRenderbuffers (1, &context_eagl->priv->depth_renderbuffer);
    context_eagl->priv->depth_renderbuffer = 0;
    glDeleteRenderbuffers (1, &context_eagl->priv->color_renderbuffer);
    context_eagl->priv->color_renderbuffer = 0;

    context_eagl->priv->eagl_layer = nil;
    gst_gl_context_eagl_activate (context, FALSE);
  }
}

void
gst_gl_context_eagl_update_layer (GstGLContext * context)
{
  GLuint framebuffer;
  GLuint color_renderbuffer;
  GLuint depth_renderbuffer;
  GLint width;
  GLint height;
  CAEAGLLayer *eagl_layer;
  GLenum status;
  GstGLContextEagl *context_eagl = GST_GL_CONTEXT_EAGL (context);
  GstGLContextEaglPrivate *priv = context_eagl->priv;
  UIView *window_handle = nil;
  GstGLWindow *window = gst_gl_context_get_window (context);
  if (window)
    window_handle = (UIView *) gst_gl_window_get_window_handle (window);

  if (!window_handle) {
    GST_INFO_OBJECT (context, "window handle not set yet, not updating layer");
    goto out;
  }

  GST_INFO_OBJECT (context, "updating layer, frame %fx%f",
      window_handle.frame.size.width, window_handle.frame.size.height);

  if (priv->eagl_layer)
    gst_gl_context_eagl_release_layer (context);

  eagl_layer = (CAEAGLLayer *)[window_handle layer];
  [EAGLContext setCurrentContext:priv->eagl_context];

  /* Allocate framebuffer */
  glGenFramebuffers (1, &framebuffer);
  glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
  /* Allocate color render buffer */
  glGenRenderbuffers (1, &color_renderbuffer);
  glBindRenderbuffer (GL_RENDERBUFFER, color_renderbuffer);
  [priv->eagl_context renderbufferStorage: GL_RENDERBUFFER fromDrawable:eagl_layer];
  glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
      GL_RENDERBUFFER, color_renderbuffer);
  /* Get renderbuffer width/height */
  glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH,
      &width);
  glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT,
      &height);
  /* allocate depth render buffer */
  glGenRenderbuffers (1, &depth_renderbuffer);
  glBindRenderbuffer (GL_RENDERBUFFER, depth_renderbuffer);
  glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width,
      height);
  glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
      GL_RENDERBUFFER, depth_renderbuffer);

  /* check creation status */
  status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
  if (status != GL_FRAMEBUFFER_COMPLETE) {
    GST_ERROR ("Failed to make complete framebuffer object %x", status);
    goto out;
  }
  glBindRenderbuffer (GL_RENDERBUFFER, 0);
  glBindFramebuffer (GL_FRAMEBUFFER, 0);

  priv->eagl_layer = eagl_layer;
  priv->framebuffer = framebuffer;
  priv->color_renderbuffer = color_renderbuffer;
  priv->depth_renderbuffer = depth_renderbuffer;

out:
  if (window)
    gst_object_unref (window);
}

static gboolean
gst_gl_context_eagl_create_context (GstGLContext * context, GstGLAPI gl_api,
    GstGLContext * other_context, GError ** error)
{
  GstGLContextEagl *context_eagl = GST_GL_CONTEXT_EAGL (context);
  GstGLContextEaglPrivate *priv = context_eagl->priv;
  EAGLSharegroup *share_group;

  if (other_context) {
    EAGLContext *external_gl_context = (EAGLContext *)
        gst_gl_context_get_gl_context (other_context);
    share_group = [external_gl_context sharegroup];
  } else {
    share_group = nil;
  }

  priv->eagl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3 sharegroup:share_group];
  if (!priv->eagl_context) {
    priv->eagl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:share_group];
  }
  if (!priv->eagl_context) {
    g_set_error_literal (error, GST_GL_CONTEXT_ERROR,
        GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
        "Failed to create OpenGL ES context");
    return FALSE;
  }

  if (share_group)
    [share_group release];

  priv->eagl_layer = NULL;
  priv->framebuffer = 0;
  priv->color_renderbuffer = 0;
  priv->depth_renderbuffer = 0;

  GST_INFO_OBJECT (context, "context created, updating layer");
  gst_gl_context_eagl_update_layer (context);

  return TRUE;
}

static void
gst_gl_context_eagl_destroy_context (GstGLContext * context)
{
  GstGLContextEagl *context_eagl;

  context_eagl = GST_GL_CONTEXT_EAGL (context);

  if (!context_eagl->priv->eagl_context)
    return;

  gst_gl_context_eagl_release_layer (context);

  [context_eagl->priv->eagl_context release];
  context_eagl->priv->eagl_context = nil;
}

static gboolean
gst_gl_context_eagl_choose_format (GstGLContext * context, GError ** error)
{
  GstGLContextEagl *context_eagl;
  GstGLWindow *window;
  UIView *window_handle = nil;

  context_eagl = GST_GL_CONTEXT_EAGL (context);
  window = gst_gl_context_get_window (context);

  if (!window)
    return TRUE;

  if (window)
    window_handle = (UIView *) gst_gl_window_get_window_handle (window);

  if (!window_handle) {
    gst_object_unref (window);
    return TRUE;
  }
  
  CAEAGLLayer *eagl_layer;
  NSDictionary * dict =[NSDictionary dictionaryWithObjectsAndKeys:
      [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking,
      kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];

  eagl_layer = (CAEAGLLayer *)[window_handle layer];
  [eagl_layer setOpaque:YES];
  [eagl_layer setDrawableProperties:dict];

  gst_object_unref (window);

  return TRUE;
}

static guintptr
gst_gl_context_eagl_get_gl_context (GstGLContext * context)
{
  return (guintptr) GST_GL_CONTEXT_EAGL (context)->priv->eagl_context;
}

void
gst_gl_context_eagl_prepare_draw (GstGLContextEagl * context)
{
  if (!context->priv->eagl_layer)
    return;
  
  glBindFramebuffer (GL_FRAMEBUFFER, context->priv->framebuffer);
  glBindRenderbuffer (GL_RENDERBUFFER, context->priv->color_renderbuffer);
}

void
gst_gl_context_eagl_finish_draw (GstGLContextEagl * context)
{
  if (!context->priv->eagl_layer)
    return;

  glBindRenderbuffer (GL_RENDERBUFFER, 0);
  glBindFramebuffer (GL_FRAMEBUFFER, 0);
}

static void
gst_gl_context_eagl_swap_buffers (GstGLContext * context)
{
  GstGLContextEagl *context_eagl;

  context_eagl = GST_GL_CONTEXT_EAGL (context);

  if (!context_eagl->priv->eagl_layer)
    return;

  [context_eagl->priv->eagl_context presentRenderbuffer:GL_RENDERBUFFER];
}

static gboolean
gst_gl_context_eagl_activate (GstGLContext * context, gboolean activate)
{
  GstGLContextEagl *context_eagl;

  context_eagl = GST_GL_CONTEXT_EAGL (context);

  if (activate) {
    EAGLContext *cur_ctx =[EAGLContext currentContext];

    if (cur_ctx == context_eagl->priv->eagl_context) {
      GST_DEBUG ("Already attached the context to thread %p", g_thread_self ());
      return TRUE;
    }

    GST_DEBUG ("Attaching context to thread %p", g_thread_self ());
    if ([EAGLContext setCurrentContext:context_eagl->priv->eagl_context] == NO) {
      GST_ERROR ("Couldn't make context current");
      return FALSE;
    }
  } else {
    GST_DEBUG ("Detaching context from thread %p", g_thread_self ());
    if ([EAGLContext setCurrentContext:nil] == NO) {
      GST_ERROR ("Couldn't unbind context");
      return FALSE;
    }
  }

  return TRUE;
}

static GstGLAPI
gst_gl_context_eagl_get_gl_api (GstGLContext * context)
{
  return GST_GL_API_GLES2;
}

static GstGLPlatform
gst_gl_context_eagl_get_gl_platform (GstGLContext * context)
{
  return GST_GL_PLATFORM_EAGL;
}

guintptr
gst_gl_context_eagl_get_current_context (void)
{
  return (guintptr) [EAGLContext currentContext];
}
