/*
 * GStreamer
 * Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
 * Inspired from http://www.mdk.org.pl/2007/11/17/gl-colorspace-conversions
 *
 * 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.
 */

/**
 * SECTION:element-glfilterglass
 * @title: glfilterglass
 *
 * Map textures on moving glass.
 *
 * ## Examples
 * |[
 * gst-launch-1.0 -v videotestsrc ! glfilterglass ! glimagesink
 * ]| A pipeline inspired from http://www.mdk.org.pl/2007/11/17/gl-colorspace-conversions
 * FBO is required.
 * |[
 * gst-launch-1.0 -v videotestsrc ! glfilterglass ! video/x-raw, width=640, height=480 ! glimagesink
 * ]| The scene is greater than the input size.
 *
 */

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

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

#include "gstglfilterglass.h"

#include "gstglutils.h"

#define GST_CAT_DEFAULT gst_gl_filter_glass_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

enum
{
  PROP_0
};

#define DEBUG_INIT \
  GST_DEBUG_CATEGORY_INIT (gst_gl_filter_glass_debug, "glfilterglass", 0, "glfilterglass element");
#define gst_gl_filter_glass_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLFilterGlass, gst_gl_filter_glass,
    GST_TYPE_GL_FILTER, DEBUG_INIT);

static void gst_gl_filter_glass_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_gl_filter_glass_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static gboolean gst_gl_filter_glass_reset (GstBaseTransform * trans);

static gboolean gst_gl_filter_glass_init_shader (GstGLFilter * filter);
static gboolean gst_gl_filter_glass_filter_texture (GstGLFilter * filter,
    GstGLMemory * in_tex, GstGLMemory * out_tex);

static void gst_gl_filter_glass_draw_background_gradient ();
static void gst_gl_filter_glass_draw_video_plane (GstGLFilter * filter,
    gint width, gint height, guint texture, gfloat center_x, gfloat center_y,
    gfloat start_alpha, gfloat stop_alpha, gboolean reversed, gfloat rotation);

static gboolean gst_gl_filter_glass_callback (gpointer stuff);

/* *INDENT-OFF* */
static const gchar *glass_fragment_source =
    "uniform sampler2D tex;\n"
    "varying float alpha;\n"
    "void main () {\n"
    "  float p = 0.0525;\n"
    "  float L1 = p*1.0;\n"
    "  float L2 = 1.0 - L1;\n"
    "  float L3 = 1.0 - L1;\n"
    "  float w = 1.0;\n"
    "  float r = L1;\n"
    "  if (gl_TexCoord[0].x < L1 && gl_TexCoord[0].y < L1)\n"
    "      r = sqrt( (gl_TexCoord[0].x - L1) * (gl_TexCoord[0].x - L1) + (gl_TexCoord[0].y - L1) * (gl_TexCoord[0].y - L1) );\n"
    "  else if (gl_TexCoord[0].x > L2 && gl_TexCoord[0].y < L1)\n"
    "      r = sqrt( (gl_TexCoord[0].x - L2) * (gl_TexCoord[0].x - L2) + (gl_TexCoord[0].y - L1) * (gl_TexCoord[0].y - L1) );\n"
    "  else if (gl_TexCoord[0].x > L2 && gl_TexCoord[0].y > L3)\n"
    "      r = sqrt( (gl_TexCoord[0].x - L2) * (gl_TexCoord[0].x - L2) + (gl_TexCoord[0].y - L3) * (gl_TexCoord[0].y - L3) );\n"
    "  else if (gl_TexCoord[0].x < L1 && gl_TexCoord[0].y > L3)\n"
    "      r = sqrt( (gl_TexCoord[0].x - L1) * (gl_TexCoord[0].x - L1) + (gl_TexCoord[0].y - L3) * (gl_TexCoord[0].y - L3) );\n"
    "  if (r > L1)\n"
    "      w = 0.0;\n"
    "  vec4 color = texture2D (tex, gl_TexCoord[0].st);\n"
    "  gl_FragColor = vec4(color.rgb, alpha * w);\n"
    "}\n";

static const gchar *glass_vertex_source =
    "uniform float yrot;\n"
    "uniform float aspect;\n"
    "const float fovy = 80.0;\n"
    "const float znear = 1.0;\n"
    "const float zfar = 5000.0;\n"
    "varying float alpha;\n"
    "void main () {\n"
    "   float f = 1.0/(tan(radians(fovy/2.0)));\n"
    "   float rot = radians (yrot);\n"
    "   // replacement for gluPerspective\n"
    "   mat4 perspective = mat4 (\n"
    "            f/aspect, 0.0,  0.0,                      0.0,\n"
    "            0.0,      f,    0.0,                      0.0,\n"
    "            0.0,      0.0, (znear+zfar)/(znear-zfar), 2.0*znear*zfar/(znear-zfar),\n"
    "            0.0,      0.0, -1.0,                      0.0 );\n"
    "   mat4 trans = mat4 (\n"
    "            1.0, 0.0, 0.0, 0.0,\n"
    "            0.0, 1.0, 0.0, 0.0,\n"
    "            0.0, 0.0, 1.0, -3.0,\n"
    "            0.0, 0.0, 0.0, 1.0 );\n"
    "   mat4 rotation = mat4 (\n"
    "            cos(rot),  0.0, sin(rot), 0.0,\n"
    "            0.0,       1.0, 0.0,      0.0,\n"
    "            -sin(rot), 0.0, cos(rot), 0.0,\n"
    "            0.0,       0.0, 0.0,      1.0 );\n"
    "  gl_Position = trans * perspective * rotation * gl_ModelViewProjectionMatrix * gl_Vertex;\n"
    "  gl_TexCoord[0] = gl_MultiTexCoord0;\n"
    "  alpha = gl_Color.a;\n"
    "}\n";

static const gchar * passthrough_vertex = 
    "void main () {\n"
    "  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
    "  gl_FrontColor = gl_Color;\n"
    "}\n";

static const gchar * passthrough_fragment = 
    "void main () {\n"
    "  gl_FragColor = gl_Color;\n"
    "}\n";
/* *INDENT-ON* */

static void
gst_gl_filter_glass_class_init (GstGLFilterGlassClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;

  gobject_class = (GObjectClass *) klass;
  element_class = GST_ELEMENT_CLASS (klass);

  gst_gl_filter_add_rgba_pad_templates (GST_GL_FILTER_CLASS (klass));

  gobject_class->set_property = gst_gl_filter_glass_set_property;
  gobject_class->get_property = gst_gl_filter_glass_get_property;

  gst_element_class_set_metadata (element_class, "OpenGL glass filter",
      "Filter/Effect/Video", "Glass Filter",
      "Julien Isorce <julien.isorce@gmail.com>");

  GST_GL_FILTER_CLASS (klass)->filter_texture =
      gst_gl_filter_glass_filter_texture;
  GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_filter_glass_init_shader;
  GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_filter_glass_reset;

  GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api = GST_GL_API_OPENGL;
}

static void
gst_gl_filter_glass_init (GstGLFilterGlass * filter)
{
  filter->shader = NULL;
  filter->timestamp = 0;
}

static gboolean
gst_gl_filter_glass_reset (GstBaseTransform * trans)
{
  GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (trans);

  //blocking call, wait the opengl thread has destroyed the shader
  if (glass_filter->shader)
    gst_object_unref (glass_filter->shader);
  glass_filter->shader = NULL;
  if (glass_filter->passthrough_shader)
    gst_object_unref (glass_filter->passthrough_shader);
  glass_filter->passthrough_shader = NULL;

  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
}

static void
gst_gl_filter_glass_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  //GstGLFilterGlass *filter = GST_GL_FILTER_GLASS (object);

  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_gl_filter_glass_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  //GstGLFilterGlass *filter = GST_GL_FILTER_GLASS (object);

  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_gl_filter_glass_init_shader (GstGLFilter * filter)
{
  gboolean ret;
  GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (filter);

  //blocking call, wait the opengl thread has compiled the shader
  ret =
      gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context,
      glass_vertex_source, glass_fragment_source, &glass_filter->shader);
  if (ret)
    ret =
        gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context,
        passthrough_vertex, passthrough_fragment,
        &glass_filter->passthrough_shader);

  return ret;
}

static gboolean
gst_gl_filter_glass_filter_texture (GstGLFilter * filter, GstGLMemory * in_tex,
    GstGLMemory * out_tex)
{
  GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (filter);

  glass_filter->in_tex = in_tex;

  gst_gl_framebuffer_draw_to_texture (filter->fbo, out_tex,
      gst_gl_filter_glass_callback, glass_filter);

  return TRUE;
}

static gint64
get_time (void)
{
  static GTimeVal val;
  g_get_current_time (&val);

  return (val.tv_sec * G_USEC_PER_SEC) + val.tv_usec;
}

static void
gst_gl_filter_glass_draw_background_gradient (GstGLFilterGlass * glass)
{
  GstGLFilter *filter = GST_GL_FILTER (glass);
  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;

/* *INDENT-OFF* */
  gfloat mesh[] = {
  /* |       Vertex       |        Color         | */
      -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
       1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
       1.0f,  0.8f, 0.0f, 0.0f, 0.0f, 0.2f, 1.0f,
      -1.0f,  0.8f, 0.0f, 0.0f, 0.0f, 0.2f, 1.0f,
      -1.0f,  1.0f, 0.0f, 0.0f, 0.0f, 0.2f, 1.0f,
       1.0f,  1.0f, 0.0f, 0.0f, 0.0f, 0.2f, 1.0f,
  };
/* *INDENT-ON* */

  GLushort indices[] = {
    0, 1, 2,
    0, 2, 3,
    2, 3, 4,
    2, 4, 5
  };

  gl->ClientActiveTexture (GL_TEXTURE0);
  gl->EnableClientState (GL_VERTEX_ARRAY);
  gl->EnableClientState (GL_COLOR_ARRAY);

  gl->VertexPointer (3, GL_FLOAT, 7 * sizeof (gfloat), mesh);
  gl->ColorPointer (4, GL_FLOAT, 7 * sizeof (gfloat), &mesh[3]);

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

  gl->DisableClientState (GL_VERTEX_ARRAY);
  gl->DisableClientState (GL_COLOR_ARRAY);
}

static void
gst_gl_filter_glass_draw_video_plane (GstGLFilter * filter,
    gint width, gint height, guint texture,
    gfloat center_x, gfloat center_y,
    gfloat start_alpha, gfloat stop_alpha, gboolean reversed, gfloat rotation)
{
  GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (filter);
  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;

  gfloat topy = reversed ? center_y - 1.0f : center_y + 1.0f;
  gfloat bottomy = reversed ? center_y + 1.0f : center_y - 1.0f;

/* *INDENT-OFF* */
  gfloat mesh[] = {
 /*|           Vertex          |TexCoord0|      Colour               |*/
    center_x-1.6, topy,    0.0, 0.0, 1.0, 1.0, 1.0, 1.0, start_alpha,
    center_x+1.6, topy,    0.0, 1.0, 1.0, 1.0, 1.0, 1.0, start_alpha,
    center_x+1.6, bottomy, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, stop_alpha,
    center_x-1.6, bottomy, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, stop_alpha,
  };
/* *INDENT-ON* */

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

  gl->ActiveTexture (GL_TEXTURE0);
  gl->BindTexture (GL_TEXTURE_2D, texture);

  gst_gl_shader_set_uniform_1i (glass_filter->shader, "tex", 0);
  gst_gl_shader_set_uniform_1f (glass_filter->shader, "yrot", rotation);
  gst_gl_shader_set_uniform_1f (glass_filter->shader, "aspect",
      (gfloat) width / (gfloat) height);

  gl->ClientActiveTexture (GL_TEXTURE0);
  gl->EnableClientState (GL_TEXTURE_COORD_ARRAY);
  gl->EnableClientState (GL_VERTEX_ARRAY);
  gl->EnableClientState (GL_COLOR_ARRAY);

  gl->VertexPointer (3, GL_FLOAT, 9 * sizeof (gfloat), mesh);
  gl->TexCoordPointer (2, GL_FLOAT, 9 * sizeof (gfloat), &mesh[3]);
  gl->ColorPointer (4, GL_FLOAT, 9 * sizeof (gfloat), &mesh[5]);

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

  gl->DisableClientState (GL_TEXTURE_COORD_ARRAY);
  gl->DisableClientState (GL_VERTEX_ARRAY);
  gl->DisableClientState (GL_COLOR_ARRAY);
}

static gboolean
gst_gl_filter_glass_callback (gpointer stuff)
{
  static gint64 start_time = 0;
  gfloat rotation;

  GstGLFilter *filter = GST_GL_FILTER (stuff);
  GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (stuff);
  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;

  gint width = GST_VIDEO_INFO_WIDTH (&filter->out_info);
  gint height = GST_VIDEO_INFO_HEIGHT (&filter->out_info);
  guint texture = glass_filter->in_tex->tex_id;

  if (start_time == 0)
    start_time = get_time ();
  else {
    gint64 time_left =
        (glass_filter->timestamp / 1000) - (get_time () - start_time);
    time_left -= 1000000 / 25;
    if (time_left > 2000) {
      GST_LOG ("escape");
      return FALSE;
    }
  }

  gst_gl_shader_use (glass_filter->passthrough_shader);

  gst_gl_filter_glass_draw_background_gradient (glass_filter);

  //Rotation
  if (start_time != 0) {
    gint64 time_passed = get_time () - start_time;
    rotation = sin (time_passed / 1200000.0) * 45.0f;
  } else {
    rotation = 0.0f;
  }

  gl->Enable (GL_BLEND);
  gl->BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  gst_gl_shader_use (glass_filter->shader);

  //Reflection
  gst_gl_filter_glass_draw_video_plane (filter, width, height, texture,
      0.0f, 2.0f, 0.3f, 0.0f, TRUE, rotation);

  //Main video
  gst_gl_filter_glass_draw_video_plane (filter, width, height, texture,
      0.0f, 0.0f, 1.0f, 1.0f, FALSE, rotation);

  gst_gl_context_clear_shader (GST_GL_BASE_FILTER (filter)->context);

  gl->Disable (GL_BLEND);

  return TRUE;
}
