/* GStreamer
 *
 * Copyright (C) 2014 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 <gst/gl/gstglupload.h>

#include <stdio.h>

static GstGLDisplay *display;
static GstGLContext *context;
static GstGLWindow *window;
static GstGLUpload *upload;
static guint tex_id;
static GstGLShader *shader;
static GLint shader_attr_position_loc;
static GLint shader_attr_texture_loc;
static guint vbo, vbo_indices, vao;

static const GLfloat vertices[] = {
  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 GLushort indices[] = { 0, 1, 2, 0, 2, 3 };

#define FORMAT GST_VIDEO_GL_TEXTURE_TYPE_RGBA
#define WIDTH 10
#define HEIGHT 10
#define RED 0xff, 0x00, 0x00, 0xff
#define GREEN 0x00, 0xff, 0x00, 0xff
#define BLUE 0x00, 0x00, 0xff, 0xff

static gchar rgba_data[] =
    { RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED,
  GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN,
  BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE,
  RED, RED, RED, RED, RED, RED, RED, RED, RED, RED,
  GREEN, GREEN, GREEN, GREEN, GREEN, GREEN, GREEN, GREEN, GREEN, GREEN,
  BLUE, BLUE, BLUE, BLUE, BLUE, BLUE, BLUE, BLUE, BLUE, BLUE,
  RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED,
  RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED,
  RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED,
  RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED
};

static void
setup (void)
{
  GError *error = NULL;

  display = gst_gl_display_new ();
  context = gst_gl_context_new (display);

  gst_gl_context_create (context, 0, &error);
  window = gst_gl_context_get_window (context);

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

  upload = gst_gl_upload_new (context);
}

static void
_check_gl_error (GstGLContext * context, gpointer data)
{
  GLuint error = context->gl_vtable->GetError ();
  fail_if (error != GL_NONE, "GL error 0x%x encountered during processing\n",
      error);
}

static void
teardown (void)
{
  gst_object_unref (upload);
  gst_object_unref (window);

  gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _check_gl_error,
      NULL);
  gst_object_unref (context);
  gst_object_unref (display);
  if (shader)
    gst_object_unref (shader);
}

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 (gpointer data)
{
  const GstGLFuncs *gl = context->gl_vtable;
  GError *error = NULL;

  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");

  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);
  }
}

static void
deinit (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;
}

static void
draw_render (gpointer data)
{
  GstGLContext *context = data;
  GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);
  const GstGLFuncs *gl = context->gl_vtable;

  gl->Clear (GL_COLOR_BUFFER_BIT);

  gst_gl_shader_use (shader);

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

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

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

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

  context_class->swap_buffers (context);
}

GST_START_TEST (test_upload_data)
{
  GstCaps *in_caps, *out_caps;
  GstBuffer *inbuf, *outbuf;
  GstMapInfo map_info;
  gboolean res;
  gint i = 0;

  in_caps = gst_caps_from_string ("video/x-raw,format=RGBA,"
      "width=10,height=10");
  out_caps = gst_caps_from_string ("video/x-raw(memory:GLMemory),"
      "format=RGBA,width=10,height=10");

  gst_gl_upload_set_caps (upload, in_caps, out_caps);

  inbuf = gst_buffer_new_wrapped_full (0, rgba_data, WIDTH * HEIGHT * 4,
      0, WIDTH * HEIGHT * 4, NULL, NULL);

  res = gst_gl_upload_perform_with_buffer (upload, inbuf, &outbuf);
  fail_if (res == FALSE, "Failed to upload buffer");
  fail_unless (GST_IS_BUFFER (outbuf));

  res = gst_buffer_map (outbuf, &map_info, GST_MAP_READ | GST_MAP_GL);
  fail_if (res == FALSE, "Failed to map gl memory");

  tex_id = *(guint *) map_info.data;

  gst_buffer_unmap (outbuf, &map_info);

  gst_gl_window_set_preferred_size (window, WIDTH, HEIGHT);
  gst_gl_window_draw (window);

  gst_gl_window_send_message (window, GST_GL_WINDOW_CB (init), context);

  while (i < 2) {
    gst_gl_window_send_message (window, GST_GL_WINDOW_CB (draw_render),
        context);
    i++;
  }
  gst_gl_window_send_message (window, GST_GL_WINDOW_CB (deinit), context);

  gst_caps_unref (in_caps);
  gst_caps_unref (out_caps);
  gst_buffer_unref (inbuf);
  gst_buffer_unref (outbuf);
}

GST_END_TEST;

GST_START_TEST (test_upload_gl_memory)
{
  GstGLBaseMemoryAllocator *base_mem_alloc;
  GstGLVideoAllocationParams *params;
  GstBuffer *buffer, *outbuf;
  GstGLMemory *gl_mem;
  GstCaps *in_caps, *out_caps;
  GstStructure *out_s;
  GstVideoInfo in_info;
  GstMapInfo map_info;
  gint i = 0;
  gboolean res;

  base_mem_alloc =
      GST_GL_BASE_MEMORY_ALLOCATOR (gst_allocator_find
      (GST_GL_MEMORY_ALLOCATOR_NAME));

  in_caps = gst_caps_from_string ("video/x-raw,format=RGBA,width=10,height=10");
  gst_video_info_from_caps (&in_info, in_caps);

  /* create GL buffer */
  buffer = gst_buffer_new ();
  params = gst_gl_video_allocation_params_new_wrapped_data (context, NULL,
      &in_info, 0, NULL, GST_GL_TEXTURE_TARGET_2D,
      GST_VIDEO_GL_TEXTURE_TYPE_RGBA, rgba_data, NULL, NULL);
  gl_mem = (GstGLMemory *) gst_gl_base_memory_alloc (base_mem_alloc,
      (GstGLAllocationParams *) params);
  gst_gl_allocation_params_free ((GstGLAllocationParams *) params);

  res =
      gst_memory_map ((GstMemory *) gl_mem, &map_info,
      GST_MAP_READ | GST_MAP_GL);
  fail_if (res == FALSE, "Failed to map gl memory\n");
  tex_id = *(guint *) map_info.data;
  gst_memory_unmap ((GstMemory *) gl_mem, &map_info);

  gst_buffer_append_memory (buffer, (GstMemory *) gl_mem);

  /* at this point glupload hasn't received any buffers so can output anything */
  out_caps = gst_gl_upload_transform_caps (upload, context,
      GST_PAD_SINK, in_caps, NULL);
  out_s = gst_caps_get_structure (out_caps, 0);
  fail_unless (gst_structure_has_field_typed (out_s, "texture-target",
          GST_TYPE_LIST));
  gst_caps_unref (out_caps);

  /* set some output caps without setting texture-target: this should trigger RECONFIGURE */
  out_caps = gst_caps_from_string ("video/x-raw(memory:GLMemory),"
      "format=RGBA,width=10,height=10");

  /* set caps with texture-target not fixed. This should trigger RECONFIGURE. */
  gst_gl_upload_set_caps (upload, in_caps, out_caps);
  gst_caps_unref (out_caps);

  /* push a texture-target=2D buffer */
  res = gst_gl_upload_perform_with_buffer (upload, buffer, &outbuf);
  fail_unless (res == GST_GL_UPLOAD_RECONFIGURE);
  fail_if (outbuf);

  /* now glupload has seen a 2D buffer and so wants to transform to that */
  out_caps = gst_gl_upload_transform_caps (upload, context,
      GST_PAD_SINK, in_caps, NULL);
  out_s = gst_caps_get_structure (out_caps, 0);
  fail_unless_equals_string (gst_structure_get_string (out_s, "texture-target"),
      "2D");
  gst_caps_unref (out_caps);

  /* try setting the wrong type first tho */
  out_caps = gst_caps_from_string ("video/x-raw(memory:GLMemory),"
      "format=RGBA,width=10,height=10,texture-target=RECTANGLE");
  gst_gl_upload_set_caps (upload, in_caps, out_caps);
  gst_caps_unref (out_caps);

  res = gst_gl_upload_perform_with_buffer (upload, buffer, &outbuf);
  fail_unless (res == GST_GL_UPLOAD_RECONFIGURE);
  fail_if (outbuf);

  /* finally do set the correct texture-target */
  out_caps = gst_caps_from_string ("video/x-raw(memory:GLMemory),"
      "format=RGBA,width=10,height=10,texture-target=2D");
  gst_gl_upload_set_caps (upload, in_caps, out_caps);
  gst_caps_unref (out_caps);

  res = gst_gl_upload_perform_with_buffer (upload, buffer, &outbuf);
  fail_unless (res == GST_GL_UPLOAD_DONE, "Failed to upload buffer");
  fail_unless (GST_IS_BUFFER (outbuf));

  gst_gl_window_set_preferred_size (window, WIDTH, HEIGHT);
  gst_gl_window_draw (window);
  gst_gl_window_send_message (window, GST_GL_WINDOW_CB (init), context);

  while (i < 2) {
    gst_gl_window_send_message (window, GST_GL_WINDOW_CB (draw_render),
        context);
    i++;
  }
  gst_gl_window_send_message (window, GST_GL_WINDOW_CB (deinit), context);

  gst_caps_unref (in_caps);
  gst_buffer_unref (buffer);
  gst_buffer_unref (outbuf);
  gst_object_unref (base_mem_alloc);
}

GST_END_TEST;


static Suite *
gst_gl_upload_suite (void)
{
  Suite *s = suite_create ("GstGLUpload");
  TCase *tc_chain = tcase_create ("upload");

  suite_add_tcase (s, tc_chain);
  tcase_add_checked_fixture (tc_chain, setup, teardown);
  tcase_add_test (tc_chain, test_upload_data);
  tcase_add_test (tc_chain, test_upload_gl_memory);

  return s;
}

GST_CHECK_MAIN (gst_gl_upload);
