/* GStreamer
 *
 * Copyright (C) 2013 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/check/gstcheck.h>

#include <gst/gl/gstglcontext.h>

#include <stdio.h>

static GstGLDisplay *display;

static void
setup (void)
{
  display = gst_gl_display_new ();
}

static void
teardown (void)
{
  gst_object_unref (display);
}

static GstGLMemory *gl_tex, *gl_tex2;
static GLuint vbo, vbo_indices, vao;
static GstGLFramebuffer *fbo, *fbo2;
static GstGLShader *shader;
static GLint shader_attr_position_loc;
static GLint shader_attr_texture_loc;

static const GLfloat vertices[] = {
  /* x, y, z, s, t */
  1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
  -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
  -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
  1.0f, -1.0f, 0.0f, 1.0f, 1.0f
};

static const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };

static void
init (gpointer data)
{
  GstGLContext *context = data;
  GError *error = NULL;
  GstVideoInfo v_info;
  GstGLMemoryAllocator *allocator;
  GstGLVideoAllocationParams *params;

  gst_video_info_set_format (&v_info, GST_VIDEO_FORMAT_RGBA, 320, 240);
  allocator = gst_gl_memory_allocator_get_default (context);
  params =
      gst_gl_video_allocation_params_new (context, NULL, &v_info, 0, NULL,
      GST_GL_TEXTURE_TARGET_2D, GST_GL_RGBA);

  /* has to be called in the thread that is going to use the framebuffer */
  fbo = gst_gl_framebuffer_new_with_default_depth (context, 320, 240);

  fail_if (fbo == NULL, "failed to create framebuffer object");

  gl_tex =
      (GstGLMemory *) gst_gl_base_memory_alloc ((GstGLBaseMemoryAllocator *)
      allocator, (GstGLAllocationParams *) params);
  gl_tex2 =
      (GstGLMemory *) gst_gl_base_memory_alloc ((GstGLBaseMemoryAllocator *)
      allocator, (GstGLAllocationParams *) params);
  gst_object_unref (allocator);
  gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
  fail_if (gl_tex == NULL, "failed to create texture");

  shader = gst_gl_shader_new_default (context, &error);
  fail_if (shader == NULL, "failed to create shader object: %s",
      error->message);

  shader_attr_position_loc =
      gst_gl_shader_get_attribute_location (shader, "a_position");
  shader_attr_texture_loc =
      gst_gl_shader_get_attribute_location (shader, "a_texcoord");
}

static void
deinit (gpointer data)
{
  GstGLContext *context = data;
  GstGLFuncs *gl = context->gl_vtable;
  if (vao)
    gl->DeleteVertexArrays (1, &vao);
  gst_object_unref (fbo);
  gst_object_unref (shader);
  gst_memory_unref (GST_MEMORY_CAST (gl_tex));
  gst_memory_unref (GST_MEMORY_CAST (gl_tex2));
}

static gboolean
clear_tex (gpointer data)
{
  GstGLContext *context = data;
  GstGLFuncs *gl = context->gl_vtable;
  static gfloat r = 0.0, g = 0.0, b = 0.0;

  gl->ClearColor (r, g, b, 1.0);
  gl->Clear (GL_COLOR_BUFFER_BIT);

  r = r > 1.0 ? 0.0 : r + 0.03;
  g = g > 1.0 ? 0.0 : g + 0.01;
  b = b > 1.0 ? 0.0 : b + 0.015;

  return TRUE;
}

static void
draw_tex (gpointer data)
{
  gst_gl_framebuffer_draw_to_texture (fbo, gl_tex,
      (GstGLFramebufferFunc) clear_tex, data);
}

static void
_bind_buffer (GstGLContext * context)
{
  const GstGLFuncs *gl = context->gl_vtable;

  gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, vbo_indices);
  gl->BindBuffer (GL_ARRAY_BUFFER, vbo);

  /* Load the vertex position */
  gl->VertexAttribPointer (shader_attr_position_loc, 3, GL_FLOAT, GL_FALSE,
      5 * sizeof (GLfloat), (void *) 0);

  /* Load the texture coordinate */
  gl->VertexAttribPointer (shader_attr_texture_loc, 2, GL_FLOAT, GL_FALSE,
      5 * sizeof (GLfloat), (void *) (3 * sizeof (GLfloat)));

  gl->EnableVertexAttribArray (shader_attr_position_loc);
  gl->EnableVertexAttribArray (shader_attr_texture_loc);
}

static void
_unbind_buffer (GstGLContext * context)
{
  const GstGLFuncs *gl = context->gl_vtable;

  gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
  gl->BindBuffer (GL_ARRAY_BUFFER, 0);

  gl->DisableVertexAttribArray (shader_attr_position_loc);
  gl->DisableVertexAttribArray (shader_attr_texture_loc);
}

static void
init_blit (gpointer data)
{
  GstGLContext *context = data;
  const GstGLFuncs *gl = context->gl_vtable;

  if (!vbo) {
    if (gl->GenVertexArrays) {
      gl->GenVertexArrays (1, &vao);
      gl->BindVertexArray (vao);
    }

    gl->GenBuffers (1, &vbo);
    gl->BindBuffer (GL_ARRAY_BUFFER, vbo);
    gl->BufferData (GL_ARRAY_BUFFER, 4 * 5 * sizeof (GLfloat), vertices,
        GL_STATIC_DRAW);

    gl->GenBuffers (1, &vbo_indices);
    gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, vbo_indices);
    gl->BufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices,
        GL_STATIC_DRAW);

    if (gl->GenVertexArrays) {
      _bind_buffer (context);
      gl->BindVertexArray (0);
    }

    gl->BindBuffer (GL_ARRAY_BUFFER, 0);
    gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
  }
  /* has to be called in the thread that is going to use the framebuffer */
  fbo2 = gst_gl_framebuffer_new_with_default_depth (context, 320, 240);

  fail_if (fbo2 == NULL, "failed to create framebuffer object");
}

static void
deinit_blit (gpointer data)
{
  GstGLContext *context = data;
  const GstGLFuncs *gl = context->gl_vtable;

  if (vbo)
    gl->DeleteBuffers (1, &vbo);
  vbo = 0;
  if (vbo_indices)
    gl->DeleteBuffers (1, &vbo_indices);
  vbo_indices = 0;
  if (vao)
    gl->DeleteVertexArrays (1, &vao);
  vao = 0;
  gst_object_unref (fbo2);
  fbo2 = NULL;
}

static gboolean
blit_tex (gpointer data)
{
  GstGLContext *context = data;
  const GstGLFuncs *gl = context->gl_vtable;

  gl->Clear (GL_COLOR_BUFFER_BIT);

  gst_gl_shader_use (shader);

  gl->ActiveTexture (GL_TEXTURE0);
  gl->BindTexture (GL_TEXTURE_2D, gst_gl_memory_get_texture_id (gl_tex));
  gst_gl_shader_set_uniform_1i (shader, "s_texture", 0);

  if (gl->GenVertexArrays)
    gl->BindVertexArray (vao);
  _bind_buffer (context);

  gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);

  if (gl->GenVertexArrays)
    gl->BindVertexArray (0);
  _unbind_buffer (context);

  return TRUE;
}

static void
draw_render (gpointer data)
{
  gst_gl_framebuffer_draw_to_texture (fbo2, gl_tex2,
      (GstGLFramebufferFunc) blit_tex, data);
}

GST_START_TEST (test_share)
{
  GstGLContext *context;
  GstGLWindow *window;
  GstGLContext *other_context;
  GstGLWindow *other_window;
  GError *error = NULL;
  gint i = 0;

  context = gst_gl_context_new (display);

  window = gst_gl_window_new (display);
  gst_gl_context_set_window (context, window);

  gst_gl_context_create (context, 0, &error);

  fail_if (error != NULL, "Error creating master context %s\n",
      error ? error->message : "Unknown Error");

  other_window = gst_gl_window_new (display);

  other_context = gst_gl_context_new (display);
  gst_gl_context_set_window (other_context, other_window);

  gst_gl_context_create (other_context, context, &error);

  fail_if (error != NULL, "Error creating secondary context %s\n",
      error ? error->message : "Unknown Error");

  /* make the window visible */
  gst_gl_window_set_preferred_size (window, 320, 240);
  gst_gl_window_draw (window);

  gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (init),
      other_context);
  gst_gl_window_send_message (window, GST_GL_WINDOW_CB (init_blit), context);

  while (i < 10) {
    gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (draw_tex),
        context);
    gst_gl_window_send_message (window, GST_GL_WINDOW_CB (draw_render),
        context);
    i++;
  }

  gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (deinit),
      other_context);
  gst_gl_window_send_message (window, GST_GL_WINDOW_CB (deinit_blit), context);

  gst_object_unref (window);
  gst_object_unref (other_window);
  gst_object_unref (other_context);
  gst_object_unref (context);
}

GST_END_TEST;

static void
accum_true (GstGLContext * context, gpointer data)
{
  gint *i = data;
  *i = 1;
}

static void
check_wrapped (gpointer data)
{
  GstGLContext *wrapped_context = data;
  GError *error = NULL;
  gint i = 0;
  gboolean ret;

  /* check that scheduling on an unactivated wrapped context asserts */
  ASSERT_CRITICAL (gst_gl_context_thread_add (wrapped_context,
          (GstGLContextThreadFunc) accum_true, &i));
  fail_if (i != 0);

  /* check that scheduling on an activated context succeeds */
  gst_gl_context_activate (wrapped_context, TRUE);
  gst_gl_context_thread_add (wrapped_context,
      (GstGLContextThreadFunc) accum_true, &i);
  fail_if (i != 1);

  /* check filling out the wrapped context's info */
  fail_if (wrapped_context->gl_vtable->TexImage2D != NULL);
  ret = gst_gl_context_fill_info (wrapped_context, &error);
  fail_if (!ret, "error received %s\n",
      error ? error->message : "Unknown error");
  fail_if (wrapped_context->gl_vtable->TexImage2D == NULL);
  gst_gl_context_activate (wrapped_context, FALSE);
}

GST_START_TEST (test_wrapped_context)
{
  GstGLContext *context, *other_context, *wrapped_context;
  GstGLWindow *window, *other_window;
  GError *error = NULL;
  gint i = 0;
  guintptr handle, handle2;
  GstGLPlatform platform, platform2;
  GstGLAPI apis, apis2;

  context = gst_gl_context_new (display);

  window = gst_gl_window_new (display);
  gst_gl_context_set_window (context, window);

  gst_gl_context_create (context, 0, &error);

  fail_if (error != NULL, "Error creating master context %s\n",
      error ? error->message : "Unknown Error");

  handle = gst_gl_context_get_gl_context (context);
  platform = gst_gl_context_get_gl_platform (context);
  apis = gst_gl_context_get_gl_api (context);

  wrapped_context =
      gst_gl_context_new_wrapped (display, handle, platform, apis);

  handle2 = gst_gl_context_get_gl_context (wrapped_context);
  platform2 = gst_gl_context_get_gl_platform (wrapped_context);
  apis2 = gst_gl_context_get_gl_api (wrapped_context);

  fail_if (handle != handle2);
  fail_if (platform != platform2);
  fail_if (apis != apis2);

  other_context = gst_gl_context_new (display);
  other_window = gst_gl_window_new (display);
  gst_gl_context_set_window (other_context, other_window);

  gst_gl_context_create (other_context, wrapped_context, &error);

  fail_if (error != NULL, "Error creating secondary context %s\n",
      error ? error->message : "Unknown Error");

  gst_gl_window_set_preferred_size (window, 320, 240);
  gst_gl_window_draw (window);

  gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (init),
      other_context);
  gst_gl_window_send_message (window, GST_GL_WINDOW_CB (init_blit), context);

  while (i < 10) {
    gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (draw_tex),
        context);
    gst_gl_window_send_message (window, GST_GL_WINDOW_CB (draw_render),
        context);
    i++;
  }

  gst_gl_window_send_message (window, GST_GL_WINDOW_CB (check_wrapped),
      wrapped_context);

  gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (deinit),
      other_context);
  gst_gl_window_send_message (window, GST_GL_WINDOW_CB (deinit_blit), context);

  gst_object_unref (other_context);
  gst_object_unref (other_window);
  gst_object_unref (window);
  gst_object_unref (context);
  gst_object_unref (wrapped_context);
}

GST_END_TEST;

struct context_info
{
  GstGLAPI api;
  guint major;
  guint minor;
  GstGLPlatform platform;
  guintptr handle;
};

static void
_fill_context_info (GstGLContext * context, struct context_info *info)
{
  info->handle = gst_gl_context_get_current_gl_context (info->platform);
  info->api =
      gst_gl_context_get_current_gl_api (info->platform, &info->major,
      &info->minor);
}

GST_START_TEST (test_current_context)
{
  GstGLContext *context;
  GError *error = NULL;
  guintptr handle;
  GstGLPlatform platform;
  GstGLAPI api;
  gint major, minor;
  struct context_info info;

  context = gst_gl_context_new (display);

  gst_gl_context_create (context, 0, &error);

  fail_if (error != NULL, "Error creating master context %s\n",
      error ? error->message : "Unknown Error");

  handle = gst_gl_context_get_gl_context (context);
  platform = gst_gl_context_get_gl_platform (context);
  api = gst_gl_context_get_gl_api (context);
  gst_gl_context_get_gl_version (context, &major, &minor);

  info.platform = platform;

  gst_gl_context_thread_add (context,
      (GstGLContextThreadFunc) _fill_context_info, &info);

  fail_if (info.platform != platform);
  fail_if (info.api != api);
  fail_if (info.major != major);
  fail_if (info.minor != minor);
  fail_if (info.handle != handle);

  gst_object_unref (context);
}

GST_END_TEST;

GST_START_TEST (test_context_can_share)
{
  GstGLContext *c1, *c2, *c3;
  GError *error = NULL;

  c1 = gst_gl_context_new (display);
  gst_gl_context_create (c1, NULL, &error);
  fail_if (error != NULL, "Error creating context %s\n",
      error ? error->message : "Unknown Error");

  c2 = gst_gl_context_new (display);
  gst_gl_context_create (c2, c1, &error);
  fail_if (error != NULL, "Error creating context %s\n",
      error ? error->message : "Unknown Error");

  fail_unless (gst_gl_context_can_share (c1, c2));
  fail_unless (gst_gl_context_can_share (c2, c1));

  c3 = gst_gl_context_new (display);
  gst_gl_context_create (c3, c2, &error);
  fail_if (error != NULL, "Error creating context %s\n",
      error ? error->message : "Unknown Error");

  fail_unless (gst_gl_context_can_share (c1, c3));
  fail_unless (gst_gl_context_can_share (c3, c1));
  fail_unless (gst_gl_context_can_share (c2, c3));
  fail_unless (gst_gl_context_can_share (c3, c2));

  /* destroy the middle context */
  gst_object_unref (c2);
  c2 = NULL;

  fail_unless (gst_gl_context_can_share (c1, c3));
  fail_unless (gst_gl_context_can_share (c3, c1));

  gst_object_unref (c1);
  gst_object_unref (c3);
}

GST_END_TEST;

GST_START_TEST (test_is_shared)
{
  GstGLContext *c1, *c2;
  GError *error = NULL;

  c1 = gst_gl_context_new (display);
  gst_gl_context_create (c1, NULL, &error);
  fail_if (error != NULL, "Error creating context %s\n",
      error ? error->message : "Unknown Error");

  c2 = gst_gl_context_new (display);
  gst_gl_context_create (c2, c1, &error);
  fail_if (error != NULL, "Error creating context %s\n",
      error ? error->message : "Unknown Error");

  fail_unless (gst_gl_context_is_shared (c1));
  fail_unless (gst_gl_context_is_shared (c2));

  gst_object_unref (c2);
  c2 = NULL;

  fail_unless (!gst_gl_context_is_shared (c1));

  gst_object_unref (c1);
}

GST_END_TEST;

GST_START_TEST (test_display_list)
{
  GstGLContext *c1, *c2;
  GError *error = NULL;

  c1 = gst_gl_context_new (display);
  gst_gl_context_create (c1, NULL, &error);
  fail_if (error != NULL, "Error creating context %s\n",
      error ? error->message : "Unknown Error");

  GST_OBJECT_LOCK (display);
  {
    /* no context added so get should return NULL */
    GstGLContext *tmp =
        gst_gl_display_get_gl_context_for_thread (display, NULL);
    fail_unless (tmp == NULL);
  }

  fail_unless (gst_gl_display_add_context (display, c1));
  /* re-adding the same context is a no-op */
  fail_unless (gst_gl_display_add_context (display, c1));

  {
    GThread *thread;
    GstGLContext *tmp;

    thread = gst_gl_context_get_thread (c1);
    fail_unless (thread != NULL);

    tmp = gst_gl_display_get_gl_context_for_thread (display, thread);
    fail_unless (tmp == c1);
    g_thread_unref (thread);
    gst_object_unref (tmp);

    tmp = gst_gl_display_get_gl_context_for_thread (display, NULL);
    fail_unless (tmp == c1);
    gst_object_unref (tmp);
  }

  c2 = gst_gl_context_new (display);
  gst_gl_context_create (c2, c1, &error);
  fail_if (error != NULL, "Error creating context %s\n",
      error ? error->message : "Unknown Error");

  fail_unless (gst_gl_display_add_context (display, c2));
  /* re-adding the same context is a no-op */
  fail_unless (gst_gl_display_add_context (display, c2));

  {
    GThread *thread;
    GstGLContext *tmp;

    thread = gst_gl_context_get_thread (c2);
    fail_unless (thread != NULL);

    tmp = gst_gl_display_get_gl_context_for_thread (display, thread);
    fail_unless (tmp == c2);
    g_thread_unref (thread);
    gst_object_unref (tmp);

    /* undefined which context will be returned for the NULL thread */
    tmp = gst_gl_display_get_gl_context_for_thread (display, NULL);
    fail_unless (tmp != NULL);
    gst_object_unref (tmp);
  }

  gst_object_unref (c1);
  /* c1 is now dead */

  {
    GstGLContext *tmp;

    tmp = gst_gl_display_get_gl_context_for_thread (display, NULL);
    fail_unless (tmp == c2);
    gst_object_unref (tmp);
  }
  GST_OBJECT_UNLOCK (display);

  gst_object_unref (c2);
  /* c2 is now dead */

  {
    /* no more contexts alive */
    GstGLContext *tmp =
        gst_gl_display_get_gl_context_for_thread (display, NULL);
    fail_unless (tmp == NULL);
  }
}

GST_END_TEST;

static Suite *
gst_gl_context_suite (void)
{
  Suite *s = suite_create ("GstGLContext");
  TCase *tc_chain = tcase_create ("general");

  suite_add_tcase (s, tc_chain);
  tcase_add_checked_fixture (tc_chain, setup, teardown);
  tcase_add_test (tc_chain, test_share);
  tcase_add_test (tc_chain, test_wrapped_context);
  tcase_add_test (tc_chain, test_current_context);
  tcase_add_test (tc_chain, test_context_can_share);
  tcase_add_test (tc_chain, test_is_shared);
  tcase_add_test (tc_chain, test_display_list);

  return s;
}

GST_CHECK_MAIN (gst_gl_context);
