/*
 *  Copyright (C) 2016-2018 Savoir-faire Linux Inc.
 *  Author: Nicolas Jager <nicolas.jager@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.
 */

#include "avatarmanipulation.h"

/* LRC */
#include <api/newaccountmodel.h>
#include <globalinstances.h>
#include <person.h>
#include <profile.h>
#include <video/configurationproxy.h>
#include <video/previewmanager.h>
#include <video/devicemodel.h>

/* client */
#include "native/pixbufmanipulator.h"
#include "video/video_widget.h"
#include "cc-crop-area.h"

/* system */
#include <glib/gi18n.h>

/* size of avatar */
static constexpr int AVATAR_WIDTH  = 150; /* px */
static constexpr int AVATAR_HEIGHT = 150; /* px */

/* size of video widget */
static constexpr int VIDEO_WIDTH = 150; /* px */
static constexpr int VIDEO_HEIGHT = 150; /* px */

struct _AvatarManipulation
{
    GtkBox parent;
};

struct _AvatarManipulationClass
{
    GtkBoxClass parent_class;
};

typedef struct _AvatarManipulationPrivate AvatarManipulationPrivate;

struct _AvatarManipulationPrivate
{
    AccountInfoPointer const *accountInfo_ = nullptr;
    gchar* temporaryAvatar = nullptr;

    GtkWidget *stack_avatar_manipulation;
    GtkWidget *video_widget;
    GtkWidget *box_views_and_controls;
    GtkWidget *box_controls;

    GtkWidget *button_box_current;
    GtkWidget *button_box_photo;
    GtkWidget *button_box_edit;

    GtkWidget *button_start_camera;
    GtkWidget *button_choose_picture;
    GtkWidget *button_take_photo;
    GtkWidget *button_return_photo;
    GtkWidget *button_set_avatar;
    GtkWidget *button_return_edit;

    // GtkWidget *selector_widget;
    GtkWidget *stack_views;
    GtkWidget *image_avatar;
    GtkWidget *vbox_crop_area;
    GtkWidget *frame_video;

    AvatarManipulationState state;
    AvatarManipulationState last_state;

    /* this is used to keep track of the state of the preview when the camera is used to take a
     * photo; if a call is in progress, then the preview should already be started and we don't want
     * to stop it when the settings are closed, in this case
     */
    gboolean video_started_by_avatar_manipulation;

    GtkWidget *crop_area;
};

G_DEFINE_TYPE_WITH_PRIVATE(AvatarManipulation, avatar_manipulation, GTK_TYPE_BOX);

#define AVATAR_MANIPULATION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), AVATAR_MANIPULATION_TYPE, \
                                                                                             AvatarManipulationPrivate))

static void set_state(AvatarManipulation *self, AvatarManipulationState state);

static void start_camera(AvatarManipulation *self);
static void take_a_photo(AvatarManipulation *self);
static void choose_picture(AvatarManipulation *self);
static void return_to_previous(AvatarManipulation *self);
static void update_preview_cb(GtkFileChooser *file_chooser, GtkWidget *preview);
static void set_avatar(AvatarManipulation *self);
static void got_snapshot(AvatarManipulation *parent);

static void
avatar_manipulation_dispose(GObject *object)
{
    AvatarManipulationPrivate *priv = AVATAR_MANIPULATION_GET_PRIVATE(object);

    /* make sure we stop the preview and the video widget */
    if (priv->video_started_by_avatar_manipulation)
        Video::PreviewManager::instance().stopPreview();
    if (priv->video_widget) {
        gtk_container_remove(GTK_CONTAINER(priv->frame_video), priv->video_widget);
        priv->video_widget = NULL;
    }

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

static void
avatar_manipulation_finalize(GObject *object)
{
    G_OBJECT_CLASS(avatar_manipulation_parent_class)->finalize(object);
}

GtkWidget*
avatar_manipulation_new(AccountInfoPointer const & accountInfo)
{
    // a profile must exist
    gpointer view = g_object_new(AVATAR_MANIPULATION_TYPE, NULL);

    auto* priv = AVATAR_MANIPULATION_GET_PRIVATE(view);
    priv->accountInfo_ = &accountInfo;

    set_state(AVATAR_MANIPULATION(view), AVATAR_MANIPULATION_STATE_CURRENT);

    return reinterpret_cast<GtkWidget*>(view);
}

GtkWidget*
avatar_manipulation_new_from_wizard(void)
{
    // a profile must exist
    gpointer view = g_object_new(AVATAR_MANIPULATION_TYPE, NULL);

    auto* priv = AVATAR_MANIPULATION_GET_PRIVATE(view);
    priv->accountInfo_ = nullptr;

    set_state(AVATAR_MANIPULATION(view), AVATAR_MANIPULATION_STATE_CURRENT);

    return reinterpret_cast<GtkWidget*>(view);
}

gchar*
avatar_manipulation_get_temporary(AvatarManipulation *view)
{
    g_return_val_if_fail(IS_AVATAR_MANIPULATION(view), nullptr);
    AvatarManipulationPrivate *priv = AVATAR_MANIPULATION_GET_PRIVATE(view);
    return priv->temporaryAvatar;
}

static void
avatar_manipulation_class_init(AvatarManipulationClass *klass)
{
    G_OBJECT_CLASS(klass)->finalize = avatar_manipulation_finalize;
    G_OBJECT_CLASS(klass)->dispose = avatar_manipulation_dispose;

    gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS (klass), "/cx/ring/RingGnome/avatarmanipulation.ui");

    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, box_views_and_controls);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, box_controls);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, button_start_camera);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, button_choose_picture);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, button_take_photo);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, button_return_photo);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, button_set_avatar);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, button_return_edit);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, stack_views);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, image_avatar);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, frame_video);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, vbox_crop_area);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, button_box_current);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, button_box_photo);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AvatarManipulation, button_box_edit);
}

static void
avatar_manipulation_init(AvatarManipulation *self)
{
    AvatarManipulationPrivate *priv = AVATAR_MANIPULATION_GET_PRIVATE(self);
    gtk_widget_init_template(GTK_WIDGET(self));

    /* our desired size for the image area */
    gtk_widget_set_size_request(priv->stack_views, VIDEO_WIDTH, VIDEO_HEIGHT);

    /* signals */
    g_signal_connect_swapped(priv->button_start_camera, "clicked", G_CALLBACK(start_camera), self);
    g_signal_connect_swapped(priv->button_choose_picture, "clicked", G_CALLBACK(choose_picture), self);
    g_signal_connect_swapped(priv->button_take_photo, "clicked", G_CALLBACK(take_a_photo), self);
    g_signal_connect_swapped(priv->button_return_photo, "clicked", G_CALLBACK(return_to_previous), self);
    g_signal_connect_swapped(priv->button_set_avatar, "clicked", G_CALLBACK(set_avatar), self);
    g_signal_connect_swapped(priv->button_return_edit, "clicked", G_CALLBACK(return_to_previous), self);

    set_state(self, AVATAR_MANIPULATION_STATE_CURRENT);

    gtk_widget_show_all(priv->stack_views);
}

static void
set_state(AvatarManipulation *self, AvatarManipulationState state)
{
    // note: this function does not check if the state transition is valid, this is assumed to have
    // been done by the caller
    AvatarManipulationPrivate *priv = AVATAR_MANIPULATION_GET_PRIVATE(self);

    // save prev state
    priv->last_state = priv->state;

    switch (state) {
        case AVATAR_MANIPULATION_STATE_CURRENT:
        {
            /* get the current or default profile avatar */
            auto default_avatar = Interfaces::PixbufManipulator().generateAvatar("", "");
            auto default_scaled = Interfaces::PixbufManipulator().scaleAndFrame(default_avatar.get(), QSize(AVATAR_WIDTH, AVATAR_HEIGHT));
            auto photo = default_scaled;
            if ((priv->accountInfo_ && (*priv->accountInfo_)) || priv->temporaryAvatar) {
                auto photostr = priv->temporaryAvatar? priv->temporaryAvatar : (*priv->accountInfo_)->profileInfo.avatar;
                QByteArray byteArray(photostr.c_str(), photostr.length());
                QVariant avatar = Interfaces::PixbufManipulator().personPhoto(byteArray);
                auto pixbuf_photo = Interfaces::PixbufManipulator().scaleAndFrame(avatar.value<std::shared_ptr<GdkPixbuf>>().get(), QSize(AVATAR_WIDTH, AVATAR_HEIGHT));
                if (avatar.isValid()) {
                    photo = pixbuf_photo;
                }
            }
            gtk_image_set_from_pixbuf(GTK_IMAGE(priv->image_avatar), photo.get());

            gtk_stack_set_visible_child_name(GTK_STACK(priv->stack_views), "page_avatar");

            /* available actions: start camera (if available) or choose image */
            if (Video::DeviceModel::instance().rowCount() > 0) {
                // TODO: update if a video device gets inserted while in this state
                gtk_widget_set_visible(priv->button_start_camera, true);
            }
            gtk_widget_set_visible(priv->button_box_current, true);
            gtk_widget_set_visible(priv->button_box_photo,   false);
            gtk_widget_set_visible(priv->button_box_edit,    false);

            /* make sure video widget and camera is not running */
            if (priv->video_started_by_avatar_manipulation)
                Video::PreviewManager::instance().stopPreview();
            if (priv->video_widget) {
                gtk_container_remove(GTK_CONTAINER(priv->frame_video), priv->video_widget);
                priv->video_widget = NULL;
            }
        }
        break;
        case AVATAR_MANIPULATION_STATE_PHOTO:
        {
            // start the video; if its not available we should not be in this state
            priv->video_widget = video_widget_new();
            g_signal_connect_swapped(priv->video_widget, "snapshot-taken", G_CALLBACK (got_snapshot), self);
            gtk_widget_set_vexpand_set(priv->video_widget, FALSE);
            gtk_widget_set_hexpand_set(priv->video_widget, FALSE);
            gtk_container_add(GTK_CONTAINER(priv->frame_video), priv->video_widget);
            gtk_widget_set_visible(priv->video_widget, true);
            gtk_stack_set_visible_child_name(GTK_STACK(priv->stack_views), "page_photobooth");


            /* local renderer, but set as "remote" so that it takes up the whole screen */
            video_widget_push_new_renderer(VIDEO_WIDGET(priv->video_widget),
                                           Video::PreviewManager::instance().previewRenderer(),
                                           VIDEO_RENDERER_REMOTE);

            if (!Video::PreviewManager::instance().isPreviewing()) {
                priv->video_started_by_avatar_manipulation = TRUE;
                Video::PreviewManager::instance().startPreview();
            } else {
                priv->video_started_by_avatar_manipulation = FALSE;
            }

            /* available actions: take snapshot, return*/
            gtk_widget_set_visible(priv->button_box_current, false);
            gtk_widget_set_visible(priv->button_box_photo,   true);
            gtk_widget_set_visible(priv->button_box_edit,    false);
        }
        break;
        case AVATAR_MANIPULATION_STATE_EDIT:
        {
            /* make sure video widget and camera is not running */
            if (priv->video_started_by_avatar_manipulation)
                Video::PreviewManager::instance().stopPreview();
            if (priv->video_widget) {
                gtk_container_remove(GTK_CONTAINER(priv->frame_video), priv->video_widget);
                priv->video_widget = NULL;
            }

            /* available actions: set avatar, return */
            gtk_widget_set_visible(priv->button_box_current, false);
            gtk_widget_set_visible(priv->button_box_photo,   false);
            gtk_widget_set_visible(priv->button_box_edit,    true);

            gtk_stack_set_visible_child_name(GTK_STACK(priv->stack_views), "page_edit_view");
        }
        break;
    }

    priv->state = state;
}

static void
start_camera(AvatarManipulation *self)
{
    set_state(self, AVATAR_MANIPULATION_STATE_PHOTO);
}

static void
take_a_photo(AvatarManipulation *self)
{
    AvatarManipulationPrivate *priv = AVATAR_MANIPULATION_GET_PRIVATE(self);
    video_widget_take_snapshot(VIDEO_WIDGET(priv->video_widget));
}

static void
set_avatar(AvatarManipulation *self)
{
    AvatarManipulationPrivate *priv = AVATAR_MANIPULATION_GET_PRIVATE(self);

    gchar* png_buffer_signed = nullptr;
    gsize png_buffer_size;
    GError* error =  nullptr;

    /* get the cropped area */
    GdkPixbuf *selector_pixbuf = cc_crop_area_get_picture(CC_CROP_AREA(priv->crop_area));

    /* scale it */
    GdkPixbuf* pixbuf_frame_resized = gdk_pixbuf_scale_simple(selector_pixbuf, AVATAR_WIDTH, AVATAR_HEIGHT,
                                                              GDK_INTERP_HYPER);

    /* save the png in memory */
    gdk_pixbuf_save_to_buffer(pixbuf_frame_resized, &png_buffer_signed, &png_buffer_size, "png", &error, NULL);
    if (!png_buffer_signed) {
        g_warning("(set_avatar) failed to save pixbuffer to png: %s\n", error->message);
        g_error_free(error);
        return;
    }

    /* convert buffer to QByteArray in base 64*/
    QByteArray png_q_byte_array = QByteArray::fromRawData(png_buffer_signed, png_buffer_size).toBase64();

    /* save in profile */
    if (priv->accountInfo_ && (*priv->accountInfo_)) {
        try {
            (*priv->accountInfo_)->accountModel->setAvatar((*priv->accountInfo_)->id, png_q_byte_array.toStdString());
        } catch (std::out_of_range&) {
            g_warning("Can't set avatar for unknown account");
        }
    } else {
        priv->temporaryAvatar = g_strdup(png_q_byte_array.toStdString().c_str());
    }

    g_free(png_buffer_signed);
    g_object_unref(selector_pixbuf);
    g_object_unref(pixbuf_frame_resized);

    set_state(self, AVATAR_MANIPULATION_STATE_CURRENT);
}

static void
return_to_previous(AvatarManipulation *self)
{
    AvatarManipulationPrivate *priv = AVATAR_MANIPULATION_GET_PRIVATE(self);

    if (priv->state == AVATAR_MANIPULATION_STATE_PHOTO) {
        // from photo we alway go back to current
        set_state(self, AVATAR_MANIPULATION_STATE_CURRENT);
    } else {
        // otherwise, if we were in edit state, we may have come from photo or current state
        set_state(self, priv->last_state);
    }
}

static void
choose_picture(AvatarManipulation *self)
{
    AvatarManipulationPrivate *priv = AVATAR_MANIPULATION_GET_PRIVATE(self);
    GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
    gint res;

    auto preview = gtk_image_new();

    GtkWidget *ring_main_window = gtk_widget_get_toplevel(GTK_WIDGET(self));

    auto dialog = gtk_file_chooser_dialog_new (_("Open Avatar Image"),
                                          GTK_WINDOW(ring_main_window),
                                          action,
                                          _("_Cancel"),
                                          GTK_RESPONSE_CANCEL,
                                          _("_Open"),
                                          GTK_RESPONSE_ACCEPT,
                                          NULL);

    /* add an image preview inside the file choose */
    gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER(dialog), preview);
    g_signal_connect (GTK_FILE_CHOOSER(dialog), "update-preview", G_CALLBACK (update_preview_cb), preview);

    /* start the file chooser */
    res = gtk_dialog_run (GTK_DIALOG(dialog)); /* blocks until the dialog is closed */

    if (res == GTK_RESPONSE_ACCEPT) {
        if(auto filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (dialog))) {
            GError* error =  nullptr; /* initialising to null avoid trouble... */

            auto picture = gdk_pixbuf_new_from_file_at_size (filename, VIDEO_WIDTH, VIDEO_HEIGHT, &error);

            if (!error) {
                /* reset crop area */
                if (priv->crop_area)
                    gtk_container_remove(GTK_CONTAINER(priv->vbox_crop_area), priv->crop_area);
                priv->crop_area = cc_crop_area_new();
                gtk_widget_show(priv->crop_area);
                gtk_box_pack_start(GTK_BOX(priv->vbox_crop_area), priv->crop_area, TRUE, TRUE, 0);
                cc_crop_area_set_picture(CC_CROP_AREA(priv->crop_area), picture);
                g_object_unref(picture);

                set_state(self, AVATAR_MANIPULATION_STATE_EDIT);
            } else {
                g_warning("(choose_picture) failed to load pixbuf from file: %s", error->message);
                g_error_free(error);
            }

            g_free(filename);
        } else {
            g_warning("(choose_picture) filename empty");
        }
    }

    gtk_widget_destroy(dialog);
}

static void
update_preview_cb(GtkFileChooser *file_chooser, GtkWidget *preview)
{
    gboolean have_preview = FALSE;
    if (auto filename = gtk_file_chooser_get_preview_filename(file_chooser)) {
        GError* error =  nullptr;
        auto pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 128, 128, &error);
        if (!error) {
            gtk_image_set_from_pixbuf(GTK_IMAGE(preview), pixbuf);
            g_object_unref(pixbuf);
            have_preview = TRUE;
        } else {
            // nothing to do, the file is probably not a picture
        }
        g_free (filename);
    }
    gtk_file_chooser_set_preview_widget_active(file_chooser, have_preview);
}

static void
got_snapshot(AvatarManipulation *self)
{
    AvatarManipulationPrivate *priv = AVATAR_MANIPULATION_GET_PRIVATE(self);
    GdkPixbuf* pix = video_widget_get_snapshot(VIDEO_WIDGET(priv->video_widget));

    if (priv->crop_area)
        gtk_container_remove(GTK_CONTAINER(priv->vbox_crop_area), priv->crop_area);
    priv->crop_area = cc_crop_area_new();
    gtk_widget_show(priv->crop_area);
    gtk_box_pack_start(GTK_BOX(priv->vbox_crop_area), priv->crop_area, TRUE, TRUE, 0);
    cc_crop_area_set_picture(CC_CROP_AREA(priv->crop_area), pix);

    set_state(self, AVATAR_MANIPULATION_STATE_EDIT);
}

void
avatar_manipulation_wizard_completed(AvatarManipulation *self)
{
    auto priv = AVATAR_MANIPULATION_GET_PRIVATE(self);

    /* Tuleap: #1441
     * if the user did not validate the avatar area selection, we still take that as the image
     * for their avatar; otherwise many users end up with no avatar by default
     * TODO: improve avatar creation process to not need this fix
     */
    if (priv->state == AVATAR_MANIPULATION_STATE_EDIT)
        set_avatar(self);
}
