/*
 *  Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
 *  Author: Sebastien Bourdelin <sebastien.bourdelin@savoirfairelinux.com>
 *  Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 *
 *  Additional permission under GNU GPL version 3 section 7:
 *
 *  If you modify this program, or any covered work, by linking or
 *  combining it with the OpenSSL project's OpenSSL library (or a
 *  modified version of that library), containing parts covered by the
 *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
 *  grants you additional permission to convey the resulting work.
 *  Corresponding Source for a non-source form of such a combination
 *  shall include the source code for the parts of OpenSSL used as well
 *  as that of the covered work.
 */

#include "video_widget.h"

#include <clutter/clutter.h>
#include <clutter-gtk/clutter-gtk.h>
#include <video/renderer.h>

#define VIDEO_LOCAL_SIZE            150
#define VIDEO_LOCAL_OPACITY_DEFAULT 150 /* out of 255 */

struct _VideoWidgetClass {
    GtkBinClass parent_class;
};

struct _VideoWidget {
    GtkBin parent;
};

typedef struct _VideoWidgetPrivate VideoWidgetPrivate;

typedef struct _VideoWidgetRenderer VideoWidgetRenderer;

struct _VideoWidgetPrivate {
    GtkWidget               *clutter_widget;
    ClutterActor            *stage;
    ClutterActor            *video_container;

    /* remote peer data */
    VideoWidgetRenderer     *remote;

    /* local peer data */
    VideoWidgetRenderer     *local;
};

struct _VideoWidgetRenderer {
    ClutterActor            *actor;
    Video::Renderer         *renderer;
    QMetaObject::Connection  frame_update;
    QMetaObject::Connection  render_stop;
    QMetaObject::Connection  render_start;
};

G_DEFINE_TYPE_WITH_PRIVATE(VideoWidget, video_widget, GTK_TYPE_BIN);

#define VIDEO_WIDGET_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), VIDEO_WIDGET_TYPE, VideoWidgetPrivate))

typedef struct _FrameInfo
{
    ClutterActor   *image_actor;
    ClutterContent *image;
    guchar         *data;
    gint            data_size;
    gint            width;
    gint            height;
} FrameInfo;

/*
 * video_widget_dispose()
 *
 * The dispose function for the video_widget class.
 */
static void
video_widget_dispose(GObject *object)
{
    VideoWidget *self = VIDEO_WIDGET(object);
    VideoWidgetPrivate *priv = VIDEO_WIDGET_GET_PRIVATE(self);

    QObject::disconnect(priv->remote->frame_update);
    QObject::disconnect(priv->remote->render_stop);
    QObject::disconnect(priv->remote->render_start);

    QObject::disconnect(priv->local->frame_update);
    QObject::disconnect(priv->local->render_stop);
    QObject::disconnect(priv->local->render_start);

    G_OBJECT_CLASS(video_widget_parent_class)->dispose(object);
}


/*
 * video_widget_finalize()
 *
 * The finalize function for the video_widget class.
 */
static void
video_widget_finalize(GObject *object)
{
    VideoWidget *self = VIDEO_WIDGET(object);
    VideoWidgetPrivate *priv = VIDEO_WIDGET_GET_PRIVATE(self);

    g_free(priv->remote);
    g_free(priv->local);

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


/*
 * video_widget_class_init()
 *
 * This function init the video_widget_class.
 */
static void
video_widget_class_init(VideoWidgetClass *klass)
{
    GObjectClass *object_class = G_OBJECT_CLASS(klass);

    /* override method */
    object_class->dispose = video_widget_dispose;
    object_class->finalize = video_widget_finalize;
}


/*
 * video_widget_init()
 *
 * This function init the video_widget.
 * - init clutter
 * - init all the widget members
 */
static void
video_widget_init(VideoWidget *self)
{
    VideoWidgetPrivate *priv = VIDEO_WIDGET_GET_PRIVATE(self);

    /* init clutter widget */
    priv->clutter_widget = gtk_clutter_embed_new();
    /* add it to the video_widget */
    gtk_container_add(GTK_CONTAINER(self), priv->clutter_widget);
    /* get the stage */
    priv->stage = gtk_clutter_embed_get_stage(GTK_CLUTTER_EMBED(priv->clutter_widget));

    /* layout manager is used to arrange children in space, here we ask clutter
     * to align children to fill the space when resizing the window */
    clutter_actor_set_layout_manager(priv->stage,
        clutter_bin_layout_new(CLUTTER_BIN_ALIGNMENT_FILL, CLUTTER_BIN_ALIGNMENT_FILL));

    /* add a scene container where we can add and remove our actors */
    priv->video_container = clutter_actor_new();
    clutter_actor_set_background_color(priv->video_container, CLUTTER_COLOR_Black);
    clutter_actor_add_child(priv->stage, priv->video_container);

    /* init the remote and local structs */
    priv->remote = g_new0(VideoWidgetRenderer, 1);
    priv->local = g_new0(VideoWidgetRenderer, 1);

    /* arrange remote actors */
    priv->remote->actor = clutter_actor_new();
    clutter_actor_insert_child_below(priv->video_container, priv->remote->actor, NULL);
    /* the remote camera must always fill the container size */
    ClutterConstraint *constraint = clutter_bind_constraint_new(priv->video_container,
                                                                CLUTTER_BIND_SIZE, 0);
    clutter_actor_add_constraint(priv->remote->actor, constraint);

    /* arrange local actor */
    priv->local->actor = clutter_actor_new();
    clutter_actor_insert_child_above(priv->video_container, priv->local->actor, NULL);
    /* set size to square, but it will stay the aspect ratio when the image is rendered */
    clutter_actor_set_size(priv->local->actor, VIDEO_LOCAL_SIZE, VIDEO_LOCAL_SIZE);
    /* set position constraint to right cornder */
    constraint = clutter_align_constraint_new(priv->video_container,
                                              CLUTTER_ALIGN_BOTH, 0.99);
    clutter_actor_add_constraint(priv->local->actor, constraint);
    clutter_actor_set_opacity(priv->local->actor,
                              VIDEO_LOCAL_OPACITY_DEFAULT);

    /* TODO: handle button event in screen */
    // g_signal_connect(screen, "button-press-event",
    //         G_CALLBACK(on_button_press_in_screen_event_cb),
    //         self);

    /* TODO: init drag & drop images */
    // gtk_drag_dest_set(GTK_WIDGET(self), GTK_DEST_DEFAULT_ALL, NULL, 0, (GdkDragAction)(GDK_ACTION_COPY | GDK_ACTION_PRIVATE));
    // gtk_drag_dest_add_uri_targets(GTK_WIDGET(self));
    // g_signal_connect(GTK_WIDGET(self), "drag-data-received",
    //                  G_CALLBACK(on_drag_data_received_cb), NULL);
}

static FrameInfo *
prepare_framedata(Video::Renderer *renderer, ClutterActor* image_actor)
{
    const QByteArray& data = renderer->currentFrame();
    QSize res = renderer->size();

    /* copy frame data */
    gpointer frame_data = g_memdup((gconstpointer)data.constData(), data.size());

    FrameInfo *frame = g_new0(FrameInfo, 1);

    frame->image_actor = image_actor;
    frame->data = (guchar *)frame_data;
    frame->data_size = data.size();
    frame->width = res.width();
    frame->height = res.height();

    return frame;
}

static void
free_framedata(gpointer data)
{
    FrameInfo *frame = (FrameInfo *)data;
    g_free(frame->data);
    g_free(frame);
}

static gboolean
clutter_render_image(FrameInfo *frame)
{
    g_return_val_if_fail(CLUTTER_IS_ACTOR(frame->image_actor), FALSE);

    ClutterContent * image_new = clutter_image_new();

    const gint BPP = 4;
    const gint ROW_STRIDE = BPP * frame->width;

    GError *error = NULL;
    clutter_image_set_data(
            CLUTTER_IMAGE(image_new),
            frame->data,
            COGL_PIXEL_FORMAT_BGRA_8888,
            frame->width,
            frame->height,
            ROW_STRIDE,
            &error);
    if (error) {
        g_warning("error rendering image to clutter: %s", error->message);
        g_error_free(error);
    }

    clutter_actor_set_content(frame->image_actor, image_new);
    g_object_unref (image_new);
    /* note: we must set the content gravity be "resize aspect" after setting the image data to make sure
     * that the aspect ratio is correct
     */
    clutter_actor_set_content_gravity(frame->image_actor, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT);

    return FALSE; /* we do not want this function to be called again */
}

static void
renderer_stop(VideoWidgetRenderer *renderer)
{
    g_return_if_fail(CLUTTER_IS_ACTOR(renderer->actor));
    QObject::disconnect(renderer->frame_update);
}

static void
renderer_start(VideoWidgetRenderer *renderer)
{
    g_return_if_fail(CLUTTER_IS_ACTOR(renderer->actor));
    renderer->frame_update = QObject::connect(
        renderer->renderer,
        &Video::Renderer::frameUpdated,
        [=]() {

            /* this callback comes from another thread;
             * rendering must be done in the main loop;
             * copy the frame and add it as a task on the main loop
             */

            /* for now use the video container for the remote image */
            FrameInfo *frame = prepare_framedata(renderer->renderer,
                                                 renderer->actor);

            g_idle_add_full(G_PRIORITY_HIGH_IDLE,
                            (GSourceFunc)clutter_render_image,
                            frame,
                            (GDestroyNotify)free_framedata);
        }
    );
}

static void
video_widget_set_renderer(VideoWidgetRenderer *renderer)
{
    if (renderer == NULL) return;

    /* update the renderer */
    QObject::disconnect(renderer->frame_update);
    QObject::disconnect(renderer->render_stop);
    QObject::disconnect(renderer->render_start);

    renderer_start(renderer);

    renderer->render_stop = QObject::connect(
        renderer->renderer,
        &Video::Renderer::stopped,
        [=]() {
            renderer_stop(renderer);
        }
    );

    renderer->render_start = QObject::connect(
        renderer->renderer,
        &Video::Renderer::started,
        [=]() {
            renderer_start(renderer);
        }
    );
}

/*
 * video_widget_new()
 *
 * The function use to create a new video_widget
 */
GtkWidget*
video_widget_new(void)
{
    GtkWidget *self = (GtkWidget *)g_object_new(VIDEO_WIDGET_TYPE, NULL);
    return self;
}

void
video_widget_set_remote_renderer(VideoWidget *self, Video::Renderer *renderer_remote_new)
{
    g_return_if_fail(IS_VIDEO_WIDGET(self));
    if (renderer_remote_new == NULL) return;

    VideoWidgetPrivate *priv = VIDEO_WIDGET_GET_PRIVATE(self);

    /* update the renderer */
    priv->remote->renderer = renderer_remote_new;
    video_widget_set_renderer(priv->remote);
}

void
video_widget_set_local_renderer(VideoWidget *self, Video::Renderer *renderer_local_new)
{
    g_return_if_fail(IS_VIDEO_WIDGET(self));
    if (renderer_local_new == NULL) return;

    VideoWidgetPrivate *priv = VIDEO_WIDGET_GET_PRIVATE(self);

    /* update the renderer */
    priv->local->renderer = renderer_local_new;
    video_widget_set_renderer(priv->local);
}
