/*
 *  Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
 *  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>
#include <video/sourcemodel.h>
#include <video/devicemodel.h>
#include <QtCore/QUrl>
#include "../defines.h"
#include <stdlib.h>
#include "xrectsel.h"

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

/* check video frame queues at this rate;
 * use 30 ms (about 30 fps) since we don't expect to
 * receive video frames faster than that */
#define FRAME_RATE_PERIOD           30

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;

    guint                    frame_timeout_source;
};

struct _VideoWidgetRenderer {
    GAsyncQueue             *frame_queue;
    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;

/* static prototypes */
static FrameInfo *prepare_framedata(Video::Renderer *renderer, ClutterActor* image_actor);
static void free_framedata(gpointer data);
static void clutter_render_image(FrameInfo *frame);
static gboolean check_frame_queue(VideoWidget *self);
static void renderer_stop(VideoWidgetRenderer *renderer);
static void renderer_start(VideoWidgetRenderer *renderer);
static void video_widget_set_renderer(VideoWidgetRenderer *renderer);
static void on_drag_data_received(GtkWidget *, GdkDragContext *, gint, gint, GtkSelectionData *, guint, guint32, gpointer);
static gboolean on_button_press_in_screen_event(GtkWidget *, GdkEventButton *, gpointer);

/*
 * 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);

    /* dispose may be called multiple times, make sure
     * not to call g_source_remove more than once */
    if (priv->frame_timeout_source) {
        g_source_remove(priv->frame_timeout_source);
        priv->frame_timeout_source = 0;
    }

    if (priv->remote->frame_queue) {
        g_async_queue_unref(priv->remote->frame_queue);
        priv->remote->frame_queue = NULL;
    }

    if (priv->local->frame_queue) {
        g_async_queue_unref(priv->local->frame_queue);
        priv->local->frame_queue = NULL;
    }

    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);

    /* init frame queues and the timeout sources to check them */
    priv->remote->frame_queue = g_async_queue_new_full((GDestroyNotify)free_framedata);
    priv->local->frame_queue = g_async_queue_new_full((GDestroyNotify)free_framedata);
    priv->frame_timeout_source = g_timeout_add(FRAME_RATE_PERIOD, (GSourceFunc)check_frame_queue, self);

    /* handle button event */
    g_signal_connect(GTK_WIDGET(self), "button-press-event", G_CALLBACK(on_button_press_in_screen_event), NULL);

    /* drag & drop files as video sources */
    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), NULL);
}

/*
 * on_drag_data_received()
 *
 * Handle dragged data in the video widget window.
 * Dropping an image causes the client to switch the video input to that image.
 */
static void
on_drag_data_received(G_GNUC_UNUSED GtkWidget *self,
                      G_GNUC_UNUSED GdkDragContext *context,
                      G_GNUC_UNUSED gint x,
                      G_GNUC_UNUSED gint y,
                      GtkSelectionData *selection_data,
                      G_GNUC_UNUSED guint info,
                      G_GNUC_UNUSED guint32 time,
                      G_GNUC_UNUSED gpointer data)
{
    gchar **uris = gtk_selection_data_get_uris(selection_data);

    /* only play the first selection */
    if (uris && *uris)
        Video::SourceModel::instance()->setFile(QUrl(*uris));

    g_strfreev(uris);
}

static void
switch_video_input(G_GNUC_UNUSED GtkWidget *widget, Video::Device *device)
{
    Video::DeviceModel::instance()->setActive(device);
    Video::SourceModel::instance()->switchTo(device);
}

static void
switch_video_input_screen(G_GNUC_UNUSED GtkWidget *widget, G_GNUC_UNUSED gpointer user_data)
{
    unsigned x, y;
    unsigned width, height;

    /* try to get the dispaly or default to 0 */
    QString display_env{getenv("DISPLAY")};
    int display = 0;

    if (!display_env.isEmpty()) {
        auto list = display_env.split(":", QString::SkipEmptyParts);
        /* should only be one display, so get the first one */
        if (list.size() > 0) {
            display = list.at(0).toInt();
            g_debug("sharing screen from DISPLAY %d", display);
        }
    }

    x = y = width = height = 0;

    xrectsel(&x, &y, &width, &height);

    if (!width || !height) {
        x = y = 0;
        width = gdk_screen_width();
        height = gdk_screen_height();
    }

    Video::SourceModel::instance()->setDisplay(display, QRect(x,y,width,height));
}

static void
switch_video_input_file(GtkWidget *parent)
{
    if (parent && GTK_IS_WIDGET(parent)) {
        /* get parent window */
        parent = gtk_widget_get_toplevel(GTK_WIDGET(parent));
    }

    gchar *uri = NULL;
    GtkWidget *dialog = gtk_file_chooser_dialog_new(
            "Choose File",
            GTK_WINDOW(parent),
            GTK_FILE_CHOOSER_ACTION_OPEN,
            "_Cancel", GTK_RESPONSE_CANCEL,
            "_Open", GTK_RESPONSE_ACCEPT,
            NULL);

    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
    }

    gtk_widget_destroy(dialog);

    Video::SourceModel::instance()->setFile(QUrl(uri));

    g_free(uri);
}

/*
 * on_button_press_in_screen_event()
 *
 * Handle button event in the video screen.
 */
static gboolean
on_button_press_in_screen_event(GtkWidget *parent,
                                GdkEventButton *event,
                                G_GNUC_UNUSED gpointer data)
{
    /* check for right click */
    if (event->button != BUTTON_RIGHT_CLICK || event->type != GDK_BUTTON_PRESS)
        return FALSE;

    /* create menu with available video sources */
    GtkWidget *menu = gtk_menu_new();

    /* list available devices and check off the active device */
    auto device_list = Video::DeviceModel::instance()->devices();

    for( auto device: device_list) {
        GtkWidget *item = gtk_check_menu_item_new_with_mnemonic(device->name().toLocal8Bit().constData());
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), device->isActive());
        g_signal_connect(item, "activate", G_CALLBACK(switch_video_input), device);
    }

    /* add separator */
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());

    /* add screen area as an input */
    GtkWidget *item = gtk_check_menu_item_new_with_mnemonic("Share screen area");
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
    g_signal_connect(item, "activate", G_CALLBACK(switch_video_input_screen), NULL);

    /* add file as an input */
    item = gtk_check_menu_item_new_with_mnemonic("Share file");
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
    g_signal_connect(item, "activate", G_CALLBACK(switch_video_input_file), parent);

    /* show menu */
    gtk_widget_show_all(menu);
    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button, event->time);

    return TRUE; /* event has been fully handled */
}

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)
{
    if (data == NULL) return;
    FrameInfo *frame = (FrameInfo *)data;
    g_free(frame->data);
    g_free(frame);
}

static void
clutter_render_image(FrameInfo *frame)
{
    if (frame == NULL) return;
    g_return_if_fail(CLUTTER_IS_ACTOR(frame->image_actor));

    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);
}

static gboolean
check_frame_queue(VideoWidget *self)
{
    g_return_val_if_fail(IS_VIDEO_WIDGET(self), FALSE);
    VideoWidgetPrivate *priv = VIDEO_WIDGET_GET_PRIVATE(self);

    /* get the latest frame in the queue */
    gpointer local_data_last = NULL;
    gpointer local_data_next = g_async_queue_try_pop(priv->local->frame_queue);
    while(local_data_next != NULL) {
        // if (local_data_last != NULL) g_debug("skipping local frame");
        /* make sure to free the frame we're skipping */
        free_framedata(local_data_last);
        local_data_last = local_data_next;
        local_data_next = g_async_queue_try_pop(priv->local->frame_queue);
    }

    /* display the frame */
    clutter_render_image((FrameInfo *)local_data_last);
    free_framedata(local_data_last);

    /* get the latest frame in the queue */
    gpointer remote_data_last = NULL;
    gpointer remote_data_next = g_async_queue_try_pop(priv->remote->frame_queue);
    while(remote_data_next != NULL) {
        // if (remote_data_last != NULL) g_debug("skipping remote frame");
        /* make sure to free the frame we're skipping */
        free_framedata(remote_data_last);
        remote_data_last = remote_data_next;
        remote_data_next = g_async_queue_try_pop(priv->remote->frame_queue);
    }

    /* display the frame */
    clutter_render_image((FrameInfo *)remote_data_last);
    free_framedata(remote_data_last);

    return TRUE; /* keep going */
}

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));
    QObject::disconnect(renderer->frame_update);
    renderer->frame_update = QObject::connect(
        renderer->renderer,
        &Video::Renderer::frameUpdated,
        [=]() {
            if (!renderer->renderer->isRendering()) {
                g_debug("got frame but not rendering");
                return;
            }

            /* this callback comes from another thread;
             * rendering must be done in the main loop;
             * copy the frame and add it to the frame queue
             */
            FrameInfo *frame = prepare_framedata(renderer->renderer,
                                                 renderer->actor);
            g_async_queue_push(renderer->frame_queue, frame);
        }
    );
}

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

    /* reset the content gravity so that the aspect ratio gets properly set if it chagnes */
    clutter_actor_set_content_gravity(renderer->actor, CLUTTER_CONTENT_GRAVITY_RESIZE_FILL);

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

    if (renderer->renderer->isRendering())
        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_add_renderer(VideoWidget *self, const VideoRenderer *new_renderer)
{
    g_return_if_fail(IS_VIDEO_WIDGET(self));
    if (new_renderer == NULL || new_renderer->renderer == NULL)
        return;

    VideoWidgetPrivate *priv = VIDEO_WIDGET_GET_PRIVATE(self);

    /* update the renderer */
    switch(new_renderer->type) {
        case VIDEO_RENDERER_REMOTE:
            priv->remote->renderer = new_renderer->renderer;
            video_widget_set_renderer(priv->remote);
            break;
        case VIDEO_RENDERER_LOCAL:
            priv->local->renderer = new_renderer->renderer;
            video_widget_set_renderer(priv->local);
            break;
        case VIDEO_RENDERER_COUNT:
            break;
    }
}
