/*
 * GStreamer
 * Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
 * 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 <gst/gst.h>

#include <gst/gl/gl.h>
#include <gst/gl/gstglfuncs.h>

#include "gstglcontext_wgl.h"
#include <GL/wglext.h>

#include "../utils/opengl_versions.h"
#include "../gstglcontext_private.h"

struct _GstGLContextWGLPrivate
{
  PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;

  GstGLAPI context_api;
};

#define GST_CAT_DEFAULT gst_gl_context_debug

#define gst_gl_context_wgl_parent_class parent_class
G_DEFINE_TYPE (GstGLContextWGL, gst_gl_context_wgl, GST_TYPE_GL_CONTEXT);
#define GST_GL_CONTEXT_WGL_GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GL_CONTEXT_WGL, GstGLContextWGLPrivate))

static guintptr gst_gl_context_wgl_get_gl_context (GstGLContext * context);
static void gst_gl_context_wgl_swap_buffers (GstGLContext * context);
static gboolean gst_gl_context_wgl_choose_format (GstGLContext * context,
    GError ** error);
static gboolean gst_gl_context_wgl_activate (GstGLContext * context,
    gboolean activate);
static gboolean gst_gl_context_wgl_create_context (GstGLContext * context,
    GstGLAPI gl_api, GstGLContext * other_context, GError ** error);
static void gst_gl_context_wgl_destroy_context (GstGLContext * context);
GstGLAPI gst_gl_context_wgl_get_gl_api (GstGLContext * context);
static GstGLPlatform gst_gl_context_wgl_get_gl_platform (GstGLContext *
    context);

static void
gst_gl_context_wgl_class_init (GstGLContextWGLClass * klass)
{
  GstGLContextClass *context_class = (GstGLContextClass *) klass;

  g_type_class_add_private (klass, sizeof (GstGLContextWGLPrivate));

  context_class->get_gl_context =
      GST_DEBUG_FUNCPTR (gst_gl_context_wgl_get_gl_context);
  context_class->choose_format =
      GST_DEBUG_FUNCPTR (gst_gl_context_wgl_choose_format);
  context_class->activate = GST_DEBUG_FUNCPTR (gst_gl_context_wgl_activate);
  context_class->create_context =
      GST_DEBUG_FUNCPTR (gst_gl_context_wgl_create_context);
  context_class->destroy_context =
      GST_DEBUG_FUNCPTR (gst_gl_context_wgl_destroy_context);
  context_class->swap_buffers =
      GST_DEBUG_FUNCPTR (gst_gl_context_wgl_swap_buffers);

  context_class->get_proc_address =
      GST_DEBUG_FUNCPTR (gst_gl_context_wgl_get_proc_address);
  context_class->get_gl_api = GST_DEBUG_FUNCPTR (gst_gl_context_wgl_get_gl_api);
  context_class->get_gl_platform =
      GST_DEBUG_FUNCPTR (gst_gl_context_wgl_get_gl_platform);
}

static void
gst_gl_context_wgl_init (GstGLContextWGL * context_wgl)
{
  context_wgl->priv = GST_GL_CONTEXT_WGL_GET_PRIVATE (context_wgl);

  context_wgl->priv->context_api = GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
}

/* Must be called in the gl thread */
GstGLContextWGL *
gst_gl_context_wgl_new (GstGLDisplay * display)
{
  GstGLContextWGL *context;

  if ((gst_gl_display_get_handle_type (display) & GST_GL_DISPLAY_TYPE_WIN32) ==
      0)
    /* we require an win32 display handle to create WGL contexts */
    return NULL;

  context = g_object_new (GST_TYPE_GL_CONTEXT_WGL, NULL);
  gst_object_ref_sink (context);

  return context;
}

static HGLRC
_create_context_with_flags (GstGLContextWGL * context_wgl, HDC dpy,
    HGLRC share_context, gint major, gint minor, gint contextFlags,
    gint profileMask)
{
  HGLRC ret;
#define N_ATTRIBS 20
  gint attribs[N_ATTRIBS];
  gint n = 0;

  if (major) {
    attribs[n++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
    attribs[n++] = major;
  }
  if (minor) {
    attribs[n++] = WGL_CONTEXT_MINOR_VERSION_ARB;
    attribs[n++] = minor;
  }
  if (contextFlags) {
    attribs[n++] = WGL_CONTEXT_FLAGS_ARB;
    attribs[n++] = contextFlags;
  }
  if (profileMask) {
    attribs[n++] = WGL_CONTEXT_PROFILE_MASK_ARB;
    attribs[n++] = profileMask;
  }
  attribs[n++] = 0;

  g_assert (n < N_ATTRIBS);
#undef N_ATTRIBS

  ret =
      context_wgl->priv->wglCreateContextAttribsARB (dpy, share_context,
      attribs);

  return ret;
}

static gboolean
gst_gl_context_wgl_create_context (GstGLContext * context,
    GstGLAPI gl_api, GstGLContext * other_context, GError ** error)
{
  GstGLWindow *window;
  GstGLContextWGL *context_wgl;
  HGLRC external_gl_context = NULL;
  HGLRC trampoline;
  HDC device;

  context_wgl = GST_GL_CONTEXT_WGL (context);
  window = gst_gl_context_get_window (context);
  device = (HDC) gst_gl_window_get_display (window);

  if (other_context) {
    if (gst_gl_context_get_gl_platform (other_context) != GST_GL_PLATFORM_WGL) {
      g_set_error (error, GST_GL_CONTEXT_ERROR,
          GST_GL_CONTEXT_ERROR_WRONG_CONFIG,
          "Cannot share context with a non-WGL context");
      goto failure;
    }
    external_gl_context = (HGLRC) gst_gl_context_get_gl_context (other_context);
  }

  trampoline = wglCreateContext (device);
  if (trampoline)
    GST_DEBUG ("gl context created: %" G_GUINTPTR_FORMAT,
        (guintptr) trampoline);
  else {
    g_set_error (error, GST_GL_CONTEXT_ERROR,
        GST_GL_CONTEXT_ERROR_CREATE_CONTEXT, "failed to create glcontext:0x%x",
        (unsigned int) GetLastError ());
    goto failure;
  }
  g_assert (trampoline);

  /* get extension functions */
  wglMakeCurrent (device, trampoline);

  context_wgl->priv->wglCreateContextAttribsARB =
      (PFNWGLCREATECONTEXTATTRIBSARBPROC)
      wglGetProcAddress ("wglCreateContextAttribsARB");

  wglMakeCurrent (device, 0);
  wglDeleteContext (trampoline);
  trampoline = NULL;

  if (context_wgl->priv->wglCreateContextAttribsARB != NULL
      && gl_api & GST_GL_API_OPENGL3) {
    gint i;

    for (i = 0; i < G_N_ELEMENTS (opengl_versions); i++) {
      gint profileMask = 0;
      gint contextFlags = 0;

      if ((opengl_versions[i].major > 3
              || (opengl_versions[i].major == 3
                  && opengl_versions[i].minor >= 2))) {
        profileMask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
        contextFlags |= WGL_CONTEXT_DEBUG_BIT_ARB;
      } else {
        break;
      }

      GST_DEBUG_OBJECT (context, "trying to create a GL %d.%d context",
          opengl_versions[i].major, opengl_versions[i].minor);

      context_wgl->wgl_context = _create_context_with_flags (context_wgl,
          device, external_gl_context, opengl_versions[i].major,
          opengl_versions[i].minor, contextFlags, profileMask);

      if (context_wgl->wgl_context) {
        context_wgl->priv->context_api = GST_GL_API_OPENGL3;
        break;
      }
    }
  }

  if (!context_wgl->wgl_context) {

    if (context_wgl->priv->wglCreateContextAttribsARB && external_gl_context) {
      context_wgl->wgl_context =
          context_wgl->priv->wglCreateContextAttribsARB (device,
          external_gl_context, 0);
    }


    if (!context_wgl->wgl_context) {

      context_wgl->wgl_context = wglCreateContext (device);

      if (!context_wgl->wgl_context) {
        g_set_error (error, GST_GL_CONTEXT_ERROR,
            GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
            "Failed to create WGL context 0x%x",
            (unsigned int) GetLastError ());
        goto failure;
      }

      if (external_gl_context) {
        if (!wglShareLists (external_gl_context, context_wgl->wgl_context)) {
          g_set_error (error, GST_GL_CONTEXT_ERROR,
              GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
              "failed to share contexts through wglShareLists 0x%x",
              (unsigned int) GetLastError ());
          goto failure;
        }
      }
    }

    context_wgl->priv->context_api = GST_GL_API_OPENGL;
  }

  GST_LOG ("gl context id: %" G_GUINTPTR_FORMAT,
      (guintptr) context_wgl->wgl_context);

  gst_object_unref (window);

  return TRUE;

failure:
  gst_object_unref (window);

  return FALSE;
}

static void
gst_gl_context_wgl_destroy_context (GstGLContext * context)
{
  GstGLContextWGL *context_wgl;

  context_wgl = GST_GL_CONTEXT_WGL (context);

  if (context_wgl->wgl_context)
    wglDeleteContext (context_wgl->wgl_context);
  context_wgl->wgl_context = NULL;
}

static gboolean
gst_gl_context_wgl_choose_format (GstGLContext * context, GError ** error)
{
  GstGLWindow *window;
  PIXELFORMATDESCRIPTOR pfd;
  gint pixelformat = 0;
  gboolean res = FALSE;
  HDC device;

  window = gst_gl_context_get_window (context);
  gst_gl_window_win32_create_window (GST_GL_WINDOW_WIN32 (window), error);
  device = (HDC) gst_gl_window_get_display (window);
  gst_object_unref (window);

  pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
  pfd.nVersion = 1;
  pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
  pfd.iPixelType = PFD_TYPE_RGBA;
  pfd.cColorBits = 24;
  pfd.cRedBits = 8;
  pfd.cRedShift = 0;
  pfd.cGreenBits = 8;
  pfd.cGreenShift = 0;
  pfd.cBlueBits = 8;
  pfd.cBlueShift = 0;
  pfd.cAlphaBits = 0;
  pfd.cAlphaShift = 0;
  pfd.cAccumBits = 0;
  pfd.cAccumRedBits = 0;
  pfd.cAccumGreenBits = 0;
  pfd.cAccumBlueBits = 0;
  pfd.cAccumAlphaBits = 0;
  pfd.cDepthBits = 24;
  pfd.cStencilBits = 8;
  pfd.cAuxBuffers = 0;
  pfd.iLayerType = PFD_MAIN_PLANE;
  pfd.bReserved = 0;
  pfd.dwLayerMask = 0;
  pfd.dwVisibleMask = 0;
  pfd.dwDamageMask = 0;

  pfd.cColorBits = (BYTE) GetDeviceCaps (device, BITSPIXEL);

  pixelformat = ChoosePixelFormat (device, &pfd);

  if (!pixelformat) {
    g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
        "Failed to choose a pixel format");
    return FALSE;
  }

  res = SetPixelFormat (device, pixelformat, &pfd);

  return res;
}

static void
gst_gl_context_wgl_swap_buffers (GstGLContext * context)
{
  GstGLWindow *window = gst_gl_context_get_window (context);
  HDC device = (HDC) gst_gl_window_get_display (window);

  SwapBuffers (device);

  gst_object_unref (window);
}

static guintptr
gst_gl_context_wgl_get_gl_context (GstGLContext * context)
{
  return (guintptr) GST_GL_CONTEXT_WGL (context)->wgl_context;
}

static gboolean
gst_gl_context_wgl_activate (GstGLContext * context, gboolean activate)
{
  GstGLWindow *window;
  GstGLContextWGL *context_wgl;
  HDC device;
  gboolean result;

  window = gst_gl_context_get_window (context);
  context_wgl = GST_GL_CONTEXT_WGL (context);
  device = (HDC) gst_gl_window_get_display (window);

  if (activate) {
    result = wglMakeCurrent (device, context_wgl->wgl_context);
  } else {
    result = wglMakeCurrent (NULL, NULL);
  }

  gst_object_unref (window);

  return result;
}

GstGLAPI
gst_gl_context_wgl_get_gl_api (GstGLContext * context)
{
  GstGLContextWGL *context_wgl = GST_GL_CONTEXT_WGL (context);

  return context_wgl->priv->context_api;
}

static GstGLPlatform
gst_gl_context_wgl_get_gl_platform (GstGLContext * context)
{
  return GST_GL_PLATFORM_WGL;
}

gpointer
gst_gl_context_wgl_get_proc_address (GstGLAPI gl_api, const gchar * name)
{
  gpointer result;

  if (!(result = gst_gl_context_default_get_proc_address (gl_api, name))) {
    result = wglGetProcAddress ((LPCSTR) name);
  }

  return result;
}

guintptr
gst_gl_context_wgl_get_current_context (void)
{
  return (guintptr) wglGetCurrentContext ();
}
