/* 
 * 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 "gl.h"
#include "gstglframebuffer.h"

GST_DEBUG_CATEGORY_STATIC (gst_gl_framebuffer_debug);
#define GST_CAT_DEFAULT gst_gl_framebuffer_debug

#define DEBUG_INIT \
  GST_DEBUG_CATEGORY_INIT (gst_gl_framebuffer_debug, "glframebuffer", 0, "GL Framebuffer");

G_DEFINE_TYPE_WITH_CODE (GstGLFramebuffer, gst_gl_framebuffer, G_TYPE_OBJECT,
    DEBUG_INIT);

#define GST_GL_FRAMEBUFFER_GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GL_FRAMEBUFFER, GstGLFramebufferPrivate))

static void gst_gl_framebuffer_finalize (GObject * object);

struct _GstGLFramebufferPrivate
{
  gint width;
  gint height;

  guint fbo;
  guint depth;
};

static void
gst_gl_framebuffer_class_init (GstGLFramebufferClass * klass)
{
  g_type_class_add_private (klass, sizeof (GstGLFramebufferPrivate));

  G_OBJECT_CLASS (klass)->finalize = gst_gl_framebuffer_finalize;
}

static void
gst_gl_framebuffer_init (GstGLFramebuffer * fbo)
{
  fbo->priv = GST_GL_FRAMEBUFFER_GET_PRIVATE (fbo);
}

static void
gst_gl_framebuffer_finalize (GObject * object)
{
  GstGLFramebuffer *fbo = GST_GL_FRAMEBUFFER (object);

  if (fbo->context) {
    gst_object_unref (fbo->context);
    fbo->context = NULL;
  }

  G_OBJECT_CLASS (gst_gl_framebuffer_parent_class)->finalize (object);
}

GstGLFramebuffer *
gst_gl_framebuffer_new (GstGLContext * context)
{
  GstGLFramebuffer *fbo = g_object_new (GST_TYPE_GL_FRAMEBUFFER, NULL);

  fbo->context = gst_object_ref (context);

  return fbo;
}

gboolean
gst_gl_framebuffer_generate (GstGLFramebuffer * frame, gint width, gint height,
    guint * fbo, guint * depth)
{
  GLuint fake_texture = 0;
  const GstGLFuncs *gl;
  GLenum internal_format;

  g_return_val_if_fail (GST_IS_GL_FRAMEBUFFER (frame), FALSE);
  g_return_val_if_fail (fbo != NULL && depth != NULL, FALSE);
  g_return_val_if_fail (width > 0 && height > 0, FALSE);

  gl = frame->context->gl_vtable;

  GST_TRACE ("creating FBO dimensions:%ux%u", width, height);

  if (!gl->GenFramebuffers) {
    gst_gl_context_set_error (frame->context,
        "Context, EXT_framebuffer_object not supported");
    return FALSE;
  }
  /* setup FBO */
  gl->GenFramebuffers (1, fbo);
  gl->BindFramebuffer (GL_FRAMEBUFFER, *fbo);

  /* setup the render buffer for depth */
  gl->GenRenderbuffers (1, depth);
  gl->BindRenderbuffer (GL_RENDERBUFFER, *depth);

  if (gst_gl_context_get_gl_api (frame->context) & (GST_GL_API_OPENGL |
          GST_GL_API_OPENGL3)) {
    gl->RenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width,
        height);
  }
  if (gst_gl_context_get_gl_api (frame->context) & GST_GL_API_GLES2) {
    gl->RenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
        width, height);
  }

  /* setup a texture to render to */
  gl->GenTextures (1, &fake_texture);
  gl->BindTexture (GL_TEXTURE_2D, fake_texture);
  internal_format =
      gst_gl_sized_gl_format_from_gl_format_type (frame->context, GL_RGBA,
      GL_UNSIGNED_BYTE);
  gl->TexImage2D (GL_TEXTURE_2D, 0, internal_format, width, height, 0, GL_RGBA,
      GL_UNSIGNED_BYTE, NULL);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

  /* attach the texture to the FBO to renderer to */
  gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
      GL_TEXTURE_2D, fake_texture, 0);

  /* attach the depth render buffer to the FBO */
  gl->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
      GL_RENDERBUFFER, *depth);

  if (gst_gl_context_get_gl_api (frame->context) & (GST_GL_API_OPENGL |
          GST_GL_API_OPENGL3)) {
    gl->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
        GL_RENDERBUFFER, *depth);
  }

  if (gl->CheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    gst_gl_context_set_error (frame->context,
        "GL framebuffer status incomplete");

    gl->DeleteTextures (1, &fake_texture);

    return FALSE;
  }

  /* unbind the FBO */
  gl->BindFramebuffer (GL_FRAMEBUFFER, 0);

  gl->DeleteTextures (1, &fake_texture);

  return TRUE;
}

gboolean
gst_gl_framebuffer_use_v2 (GstGLFramebuffer * frame, gint texture_fbo_width,
    gint texture_fbo_height, GLuint fbo, GLuint depth_buffer,
    GLuint texture_fbo, GLCB_V2 cb, gpointer stuff)
{
  const GstGLFuncs *gl;
  GLint viewport_dim[4];

  g_return_val_if_fail (GST_IS_GL_FRAMEBUFFER (frame), FALSE);
  g_return_val_if_fail (texture_fbo_width > 0 && texture_fbo_height > 0, FALSE);
  g_return_val_if_fail (fbo != 0, FALSE);
  g_return_val_if_fail (texture_fbo != 0, FALSE);
  g_return_val_if_fail (cb != NULL, FALSE);

  gl = frame->context->gl_vtable;

  GST_TRACE ("Binding v2 FBO %u dimensions:%ux%u with texture:%u ",
      fbo, texture_fbo_width, texture_fbo_height, texture_fbo);

  gl->BindFramebuffer (GL_FRAMEBUFFER, fbo);

  /* setup a texture to render to */
  gl->BindTexture (GL_TEXTURE_2D, texture_fbo);

  /* attach the texture to the FBO to renderer to */
  gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
      GL_TEXTURE_2D, texture_fbo, 0);

  gl->GetIntegerv (GL_VIEWPORT, viewport_dim);

  gl->Viewport (0, 0, texture_fbo_width, texture_fbo_height);

  if (gst_gl_context_get_gl_api (frame->context) & (GST_GL_API_OPENGL |
          GST_GL_API_OPENGL3))
    gl->DrawBuffer (GL_COLOR_ATTACHMENT0);

  /* the opengl scene */
  cb (stuff);

  if (gst_gl_context_get_gl_api (frame->context) & (GST_GL_API_OPENGL |
          GST_GL_API_OPENGL3))
    gl->DrawBuffer (GL_NONE);

  gl->Viewport (viewport_dim[0], viewport_dim[1],
      viewport_dim[2], viewport_dim[3]);

  gl->BindFramebuffer (GL_FRAMEBUFFER, 0);

  return TRUE;
}

void
gst_gl_framebuffer_delete (GstGLFramebuffer * frame, guint fbo, guint depth)
{
  const GstGLFuncs *gl;

  g_return_if_fail (GST_IS_GL_FRAMEBUFFER (frame));

  gl = frame->context->gl_vtable;

  GST_TRACE ("Deleting FBO %u", fbo);

  if (fbo) {
    gl->DeleteFramebuffers (1, &fbo);
  }
  if (depth) {
    gl->DeleteRenderbuffers (1, &depth);
  }
}
