/*
 * GStreamer
 * Copyright (C) 2016 Freescale Semiconductor, Inc. All rights reserved.
 *
 * 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 <stdio.h>

#include <gst/video/video.h>
#include "qtwindow.h"
#include "gstqsgtexture.h"
#include "gstqtglutility.h"

#include <QtCore/QDateTime>
#include <QtCore/QRunnable>
#include <QtGui/QGuiApplication>
#include <QtQuick/QQuickWindow>
#include <QOpenGLFramebufferObject>

/* compatability definitions... */
#ifndef GL_READ_FRAMEBUFFER
#define GL_READ_FRAMEBUFFER 0x8CA8
#endif

/**
 * SECTION:
 *
 * #QtGLWindow is an #QQuickWindow that grab QtQuick view to GStreamer OpenGL video buffers.
 */

GST_DEBUG_CATEGORY_STATIC (qt_window_debug);
#define GST_CAT_DEFAULT qt_window_debug

struct _QtGLWindowPrivate
{
  GMutex lock;
  GCond update_cond;

  GstBuffer *buffer;
  GstCaps *caps;
  GstVideoInfo v_info;

  gboolean initted;
  gboolean updated;
  gboolean quit;
  gboolean result;
  gboolean useDefaultFbo;

  GstGLDisplay *display;
  GstGLContext *other_context;

  GLuint fbo;

  /* frames that qmlview rendered in its gl thread */
  quint64 frames_rendered;
  quint64 start;
  quint64 stop;
};

class InitQtGLContext : public QRunnable
{
public:
  InitQtGLContext(QtGLWindow *window);
  void run();

private:
  QtGLWindow *window_;
};

InitQtGLContext::InitQtGLContext(QtGLWindow *window) :
  window_(window)
{
}

void InitQtGLContext::run()
{
  window_->onSceneGraphInitialized();
}

QtGLWindow::QtGLWindow ( QWindow * parent, QQuickWindow *src ) :
  QQuickWindow( parent ), source (src)
{
  QGuiApplication *app = static_cast<QGuiApplication *> (QCoreApplication::instance ());
  static volatile gsize _debug;

  g_assert (app != NULL);

  if (g_once_init_enter (&_debug)) {
    GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "qtglwindow", 0, "Qt GL QuickWindow");
    g_once_init_leave (&_debug, 1);
  }

  this->priv = g_new0 (QtGLWindowPrivate, 1);

  g_mutex_init (&this->priv->lock);
  g_cond_init (&this->priv->update_cond);

  this->priv->display = gst_qt_get_gl_display();

  connect (source, SIGNAL(beforeRendering()), this, SLOT(beforeRendering()), Qt::DirectConnection);
  connect (source, SIGNAL(afterRendering()), this, SLOT(afterRendering()), Qt::DirectConnection);
  connect (app, SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit()), Qt::DirectConnection);
  if (source->isSceneGraphInitialized())
    source->scheduleRenderJob(new InitQtGLContext(this), QQuickWindow::BeforeSynchronizingStage);
  else
    connect (source, SIGNAL(sceneGraphInitialized()), this, SLOT(onSceneGraphInitialized()), Qt::DirectConnection);

  connect (source, SIGNAL(sceneGraphInvalidated()), this, SLOT(onSceneGraphInvalidated()), Qt::DirectConnection);

  GST_DEBUG ("%p init Qt Window", this->priv->display);
}

QtGLWindow::~QtGLWindow()
{
  GST_DEBUG ("deinit Qt Window");
  g_mutex_clear (&this->priv->lock);
  g_cond_clear (&this->priv->update_cond);
  if (this->priv->other_context)
    gst_object_unref(this->priv->other_context);
  if (this->priv->display)
    gst_object_unref(this->priv->display);
  g_free (this->priv);
  this->priv = NULL;
}

void
QtGLWindow::beforeRendering()
{
  unsigned int width, height;

  g_mutex_lock (&this->priv->lock);

  static volatile gsize once = 0;
  if (g_once_init_enter(&once)) {
    this->priv->start = QDateTime::currentDateTime().toMSecsSinceEpoch();
    g_once_init_leave(&once,1);
  }

  if (!fbo && !this->priv->useDefaultFbo) {

    width = source->width();
    height = source->height();

    GST_DEBUG ("create new framebuffer object %dX%d", width, height);

    fbo.reset(new QOpenGLFramebufferObject (width, height,
          QOpenGLFramebufferObject::NoAttachment, GL_TEXTURE_2D, GL_RGBA));

    source->setRenderTarget(fbo.data());
  } else if (this->priv->useDefaultFbo) {
    GST_DEBUG ("use default fbo for render target");
    fbo.reset(NULL);
    source->setRenderTarget(NULL);
  }

  g_mutex_unlock (&this->priv->lock);
}


void
QtGLWindow::afterRendering()
{
  GstVideoFrame gl_frame;
  GstVideoInfo *info;
  GstGLContext *context;
  gboolean ret;
  guint width, height;
  const GstGLFuncs *gl;
  GLuint dst_tex;

  g_mutex_lock (&this->priv->lock);

  this->priv->frames_rendered++;

  if(!this->priv->buffer || this->priv->updated == TRUE) {
    GST_DEBUG ("skip this frame");
    g_mutex_unlock (&this->priv->lock);
    return;
  }

  GST_DEBUG ("copy buffer %p",this->priv->buffer);

  width = GST_VIDEO_INFO_WIDTH (&this->priv->v_info);
  height = GST_VIDEO_INFO_HEIGHT (&this->priv->v_info);
  info = &this->priv->v_info;
  context = this->priv->other_context;

  gst_gl_context_activate (context, TRUE);
  gl = context->gl_vtable;

  ret = gst_video_frame_map (&gl_frame, info, this->priv->buffer,
      (GstMapFlags) (GST_MAP_WRITE | GST_MAP_GL));

  if (!ret) {
    this->priv->buffer = NULL;
    GST_ERROR ("Failed to map video frame");
    goto errors;
  }

  gl->BindFramebuffer (GL_READ_FRAMEBUFFER, this->source->renderTargetId());

  ret = gst_gl_context_check_framebuffer_status (context, GL_READ_FRAMEBUFFER);
  if (!ret) {
    GST_ERROR ("FBO errors");
    goto errors;
  }

  dst_tex = *(guint *) gl_frame.data[0];
  GST_DEBUG ("qml render target id %d, render to tex %d %dX%d", 
      this->source->renderTargetId(), dst_tex, width,height);

  gl->BindTexture (GL_TEXTURE_2D, dst_tex);
  if (gl->BlitFramebuffer) {
    gl->BindFramebuffer (GL_DRAW_FRAMEBUFFER, this->priv->fbo);
    gl->FramebufferTexture2D (GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
              GL_TEXTURE_2D, dst_tex, 0);

    ret = gst_gl_context_check_framebuffer_status (context, GL_DRAW_FRAMEBUFFER);
    if (!ret) {
      GST_ERROR ("FBO errors");
      goto errors;
    }
    gl->ReadBuffer (GL_COLOR_ATTACHMENT0);
    gl->BlitFramebuffer (0, 0, width, height,
        0, 0, width, height,
        GL_COLOR_BUFFER_BIT, GL_LINEAR);
  } else {
    gl->CopyTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, width, height, 0);
  }
  
  GST_DEBUG ("rendering finished");

errors:
  gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
  gst_video_frame_unmap (&gl_frame);

  gst_gl_context_activate (context, FALSE);

  this->priv->result = ret;
  this->priv->updated = TRUE;
  g_cond_signal (&this->priv->update_cond);
  g_mutex_unlock (&this->priv->lock);
}

void
QtGLWindow::aboutToQuit()
{
  g_mutex_lock (&this->priv->lock);

  this->priv->updated = TRUE;
  this->priv->quit = TRUE;
  g_cond_signal (&this->priv->update_cond);

  this->priv->stop = QDateTime::currentDateTime().toMSecsSinceEpoch();
  qint64 duration = this->priv->stop - this->priv->start;
  float fps = ((float)this->priv->frames_rendered / duration * 1000);

  GST_DEBUG("about to quit, total refresh frames (%lld) in (%0.3f) seconds, fps: %0.3f",
      this->priv->frames_rendered, (float)duration / 1000, fps);

  g_mutex_unlock (&this->priv->lock);
}

void
QtGLWindow::onSceneGraphInitialized()
{
  GST_DEBUG ("scene graph initialization with Qt GL context %p",
      this->source->openglContext ());

  this->priv->initted = gst_qt_get_gl_wrapcontext (this->priv->display,
      &this->priv->other_context, NULL);

  if (this->priv->initted && this->priv->other_context) {
    const GstGLFuncs *gl;

    gst_gl_context_activate (this->priv->other_context, TRUE);
    gl = this->priv->other_context->gl_vtable;

    gl->GenFramebuffers (1, &this->priv->fbo);

    gst_gl_context_activate (this->priv->other_context, FALSE);
  }

  GST_DEBUG ("%p created wrapped GL context %" GST_PTR_FORMAT, this,
      this->priv->other_context);
}

void
QtGLWindow::onSceneGraphInvalidated()
{
  GST_DEBUG ("scene graph invalidated");

  if (this->priv->fbo && this->priv->other_context) {
    const GstGLFuncs *gl;

    gst_gl_context_activate (this->priv->other_context, TRUE);
    gl = this->priv->other_context->gl_vtable;

    gl->DeleteFramebuffers (1, &this->priv->fbo);

    gst_gl_context_activate (this->priv->other_context, FALSE);
  }
}

bool
QtGLWindow::getGeometry(int * width, int * height)
{
  if (width == NULL || height == NULL)
    return FALSE;

  *width = this->source->width();
  *height = this->source->height();

  return TRUE;
}

GstGLContext *
qt_window_get_qt_context (QtGLWindow * qt_window)
{
  g_return_val_if_fail (qt_window != NULL, NULL);

  if (!qt_window->priv->other_context)
    return NULL;

  return (GstGLContext *) gst_object_ref (qt_window->priv->other_context);
}

GstGLDisplay *
qt_window_get_display (QtGLWindow * qt_window)
{
  g_return_val_if_fail (qt_window != NULL, NULL);

  if (!qt_window->priv->display)
    return NULL;

  return (GstGLDisplay *) gst_object_ref (qt_window->priv->display);
}

gboolean
qt_window_is_scenegraph_initialized (QtGLWindow * qt_window)
{
  g_return_val_if_fail (qt_window != NULL, FALSE);

  return qt_window->priv->initted;
}

gboolean
qt_window_set_caps (QtGLWindow * qt_window, GstCaps * caps)
{
  GstVideoInfo v_info;

  g_return_val_if_fail (qt_window != NULL, FALSE);
  g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
  g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);

  if (qt_window->priv->caps && gst_caps_is_equal_fixed (qt_window->priv->caps, caps))
    return TRUE;

  if (!gst_video_info_from_caps (&v_info, caps))
    return FALSE;

  g_mutex_lock (&qt_window->priv->lock);

  gst_caps_replace (&qt_window->priv->caps, caps);

  qt_window->priv->v_info = v_info;

  g_mutex_unlock (&qt_window->priv->lock);

  return TRUE;
}

gboolean
qt_window_set_buffer (QtGLWindow * qt_window, GstBuffer * buffer)
{
  g_return_val_if_fail (qt_window != NULL, FALSE);
  g_return_val_if_fail (qt_window->priv->initted, FALSE);
  gboolean ret;

  g_mutex_lock (&qt_window->priv->lock);

  if (qt_window->priv->quit){
    GST_DEBUG("about to quit, drop this buffer");
    g_mutex_unlock (&qt_window->priv->lock);
    return TRUE;
  }

  qt_window->priv->updated = FALSE;
  qt_window->priv->buffer = buffer;

  while (!qt_window->priv->updated) 
    g_cond_wait (&qt_window->priv->update_cond, &qt_window->priv->lock);
  
  ret = qt_window->priv->result;

  g_mutex_unlock (&qt_window->priv->lock);

  return ret;
}

void
qt_window_use_default_fbo (QtGLWindow * qt_window, gboolean useDefaultFbo)
{
  g_return_if_fail (qt_window != NULL);

  g_mutex_lock (&qt_window->priv->lock);

  GST_DEBUG ("set to use default fbo %d", useDefaultFbo);
  qt_window->priv->useDefaultFbo = useDefaultFbo;

  g_mutex_unlock (&qt_window->priv->lock);
}
