// libjingle
// Copyright 2004 Google Inc.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//  1. Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//  2. Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//  3. The name of the author may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Implementation of GtkVideoRenderer

#include "talk/session/phone/gtkvideorenderer.h"

#include <gtk/gtk.h>

#include "talk/session/phone/videocommon.h"
#include "talk/session/phone/videoframe.h"

namespace cricket {

class ScopedGdkLock {
 public:
  ScopedGdkLock() {
    gdk_threads_enter();
  }

  ~ScopedGdkLock() {
    gdk_threads_leave();
  }
};

GtkVideoRenderer::GtkVideoRenderer(int x, int y)
    : window_(NULL),
      draw_area_(NULL),
      initial_x_(x),
      initial_y_(y) {
  g_thread_init(NULL);
  gdk_threads_init();
}

GtkVideoRenderer::~GtkVideoRenderer() {
  if (window_) {
    ScopedGdkLock lock;
    gtk_widget_destroy(window_);
    // Run the Gtk main loop to tear down the window.
    Pump();
  }
  // Don't need to destroy draw_area_ because it is not top-level, so it is
  // implicitly destroyed by the above.
}

bool GtkVideoRenderer::SetSize(int width, int height, int reserved) {
  ScopedGdkLock lock;

  // For the first frame, initialize the GTK window
  if ((!window_ && !Initialize(width, height)) || IsClosed()) {
    return false;
  }

  image_.reset(new uint8[width * height * 4]);
  gtk_widget_set_size_request(draw_area_, width, height);
  return true;
}

bool GtkVideoRenderer::RenderFrame(const VideoFrame* frame) {
  if (!frame) {
    return false;
  }

  // convert I420 frame to ABGR format, which is accepted by GTK
  frame->ConvertToRgbBuffer(cricket::FOURCC_ABGR,
                            image_.get(),
                            frame->GetWidth() * frame->GetHeight() * 4,
                            frame->GetWidth() * 4);

  ScopedGdkLock lock;

  if (IsClosed()) {
    return false;
  }

  // draw the ABGR image
  gdk_draw_rgb_32_image(draw_area_->window,
                        draw_area_->style->fg_gc[GTK_STATE_NORMAL],
                        0,
                        0,
                        frame->GetWidth(),
                        frame->GetHeight(),
                        GDK_RGB_DITHER_MAX,
                        image_.get(),
                        frame->GetWidth() * 4);

  // Run the Gtk main loop to refresh the window.
  Pump();
  return true;
}

bool GtkVideoRenderer::Initialize(int width, int height) {
  gtk_init(NULL, NULL);
  window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  draw_area_ = gtk_drawing_area_new();
  if (!window_ || !draw_area_) {
    return false;
  }

  gtk_window_set_position(GTK_WINDOW(window_), GTK_WIN_POS_CENTER);
  gtk_window_set_title(GTK_WINDOW(window_), "Video Renderer");
  gtk_window_set_resizable(GTK_WINDOW(window_), FALSE);
  gtk_widget_set_size_request(draw_area_, width, height);
  gtk_container_add(GTK_CONTAINER(window_), draw_area_);
  gtk_widget_show_all(window_);
  gtk_window_move(GTK_WINDOW(window_), initial_x_, initial_y_);

  image_.reset(new uint8[width * height * 4]);
  return true;
}

void GtkVideoRenderer::Pump() {
  while (gtk_events_pending()) {
    gtk_main_iteration();
  }
}

bool GtkVideoRenderer::IsClosed() const {
  if (!window_) {
    // Not initialized yet, so hasn't been closed.
    return false;
  }

  if (!GTK_IS_WINDOW(window_) || !GTK_IS_DRAWING_AREA(draw_area_)) {
    return true;
  }

  return false;
}

}  // namespace cricket
