/*
 *  Copyright (C) 2015-2016 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.
 */

#include "ringwelcomeview.h"

#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include "utils/accounts.h"
#include <account.h>
#include <accountmodel.h>
#include <qrencode.h>

// Qt
#include <QObject>
#include <QItemSelectionModel>

// LRC
#include <availableaccountmodel.h>

struct _RingWelcomeView
{
    GtkScrolledWindow parent;
};

struct _RingWelcomeViewClass
{
    GtkScrolledWindowClass parent_class;
};

typedef struct _RingWelcomeViewPrivate RingWelcomeViewPrivate;

struct _RingWelcomeViewPrivate
{
    GtkWidget *box_overlay;
    GtkWidget *label_ringid;
    GtkWidget *label_explanation;
    GtkWidget *button_qrcode;
    GtkWidget *revealer_qrcode;

    QMetaObject::Connection account_model_data_changed;
};

G_DEFINE_TYPE_WITH_PRIVATE(RingWelcomeView, ring_welcome_view, GTK_TYPE_SCROLLED_WINDOW);

#define RING_WELCOME_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), RING_WELCOME_VIEW_TYPE, RingWelcomeViewPrivate))

static gboolean   draw_qrcode(GtkWidget*,cairo_t*,gpointer);
static void       switch_qrcode(RingWelcomeView* self);

static void
update_view(RingWelcomeView *self) {
    auto priv = RING_WELCOME_VIEW_GET_PRIVATE(self);

    if (auto account = get_active_ring_account()) {
        gchar *ring_id = nullptr;
        if(!account->registeredName().isEmpty()){
            gtk_label_set_text(
                GTK_LABEL(priv->label_explanation),
                _("This is your Ring username.\nCopy and share it with your friends!")
            );
            ring_id = g_markup_printf_escaped("<span fgcolor=\"black\">ring:%s</span>",
                                              account->registeredName().toUtf8().constData());
        }
        else if (!account->username().isEmpty()) {
            gtk_label_set_text(
                GTK_LABEL(priv->label_explanation),
                C_("Do not translate \"RingID\"", "This is your RingID.\nCopy and share it with your friends!")
            );
            ring_id = g_markup_printf_escaped("<span fgcolor=\"black\">%s</span>",
                                              account->username().toUtf8().constData());
        } else {
            gtk_label_set_text(GTK_LABEL(priv->label_explanation), NULL);
            ring_id = g_markup_printf_escaped("<span fgcolor=\"gray\">%s</span>",
                                              _("fetching RingID..."));
        }
        gtk_label_set_markup(GTK_LABEL(priv->label_ringid), ring_id);
        gtk_widget_show(priv->label_explanation);
        gtk_widget_show(priv->label_ringid);
        gtk_widget_show(priv->button_qrcode);
        gtk_widget_show(priv->revealer_qrcode);

        g_free(ring_id);

    } else { // any other protocols
        gtk_widget_hide(priv->label_explanation);
        gtk_widget_hide(priv->label_ringid);
        gtk_widget_hide(priv->button_qrcode);
        gtk_widget_hide(priv->revealer_qrcode);
        gtk_revealer_set_reveal_child(GTK_REVEALER(priv->revealer_qrcode), FALSE);
        gtk_widget_set_opacity(priv->box_overlay, 1.0);
    }
}

static void
ring_welcome_view_init(RingWelcomeView *self)
{
    RingWelcomeViewPrivate *priv = RING_WELCOME_VIEW_GET_PRIVATE(self);

    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(self), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);

    auto box_main = gtk_box_new(GTK_ORIENTATION_VERTICAL, 15);
    gtk_container_add(GTK_CONTAINER(self), box_main);
    gtk_box_set_baseline_position(GTK_BOX(box_main), GTK_BASELINE_POSITION_CENTER);
    gtk_widget_set_vexpand(GTK_WIDGET(box_main), TRUE);
    gtk_widget_set_hexpand(GTK_WIDGET(box_main), FALSE);
    gtk_widget_set_valign(GTK_WIDGET(box_main), GTK_ALIGN_CENTER);
    gtk_widget_set_halign(GTK_WIDGET(box_main), GTK_ALIGN_CENTER);
    gtk_widget_set_visible(GTK_WIDGET(box_main), TRUE);

    /* overlay to show hide the qr code over the stuff in it */
    auto overlay_qrcode = gtk_overlay_new();
    gtk_box_pack_start(GTK_BOX(box_main), overlay_qrcode, FALSE, TRUE, 0);

    /* box which will be in the overaly so that we can display the QR code over the stuff in this box */
    priv->box_overlay = gtk_box_new(GTK_ORIENTATION_VERTICAL, 15);
    gtk_container_add(GTK_CONTAINER(overlay_qrcode), priv->box_overlay);

    /* get logo */
    GError *error = NULL;
    GdkPixbuf* logo = gdk_pixbuf_new_from_resource_at_scale("/cx/ring/RingGnome/ring-logo-blue",
                                                            350, -1, TRUE, &error);
    if (logo == NULL) {
        g_debug("Could not load logo: %s", error->message);
        g_clear_error(&error);
    } else {
        auto image_ring_logo = gtk_image_new_from_pixbuf(logo);
        gtk_box_pack_start(GTK_BOX(priv->box_overlay), image_ring_logo, FALSE, TRUE, 0);
        gtk_widget_set_visible(GTK_WIDGET(image_ring_logo), TRUE);
    }

    /* welcome text */
    auto label_welcome_text = gtk_label_new(_("Ring is free software for universal communication which respects the freedoms and privacy of its users."));
    gtk_label_set_justify(GTK_LABEL(label_welcome_text), GTK_JUSTIFY_CENTER);
    PangoAttrList *attrs_welcome_text = pango_attr_list_new();
    PangoAttribute *font_desc_welcome_text = pango_attr_font_desc_new(pango_font_description_from_string("12"));
    pango_attr_list_insert(attrs_welcome_text, font_desc_welcome_text);
    gtk_label_set_attributes(GTK_LABEL(label_welcome_text), attrs_welcome_text);
    pango_attr_list_unref(attrs_welcome_text);
    gtk_label_set_line_wrap(GTK_LABEL(label_welcome_text), TRUE);
    /* the max width chars is to limit how much the text expands */
    gtk_label_set_max_width_chars(GTK_LABEL(label_welcome_text), 50);
    gtk_label_set_selectable(GTK_LABEL(label_welcome_text), TRUE);
    gtk_box_pack_start(GTK_BOX(priv->box_overlay), label_welcome_text, FALSE, TRUE, 0);
    gtk_widget_set_visible(GTK_WIDGET(label_welcome_text), TRUE);

    /* RingID explanation */
    priv->label_explanation = gtk_label_new(NULL);
    auto context = gtk_widget_get_style_context(priv->label_explanation);
    gtk_style_context_add_class(context, GTK_STYLE_CLASS_DIM_LABEL);
    gtk_label_set_justify(GTK_LABEL(priv->label_explanation), GTK_JUSTIFY_CENTER);
    gtk_label_set_selectable(GTK_LABEL(priv->label_explanation), TRUE);
    gtk_widget_set_margin_top(priv->label_explanation, 20);
    gtk_widget_set_no_show_all(priv->label_explanation, TRUE);
    gtk_box_pack_start(GTK_BOX(priv->box_overlay), priv->label_explanation, FALSE, TRUE, 0);

    /* RingID label */
    priv->label_ringid = gtk_label_new(NULL);
    gtk_label_set_selectable(GTK_LABEL(priv->label_ringid), TRUE);
    PangoAttrList *attrs_ringid = pango_attr_list_new();
    PangoAttribute *font_desc_ringid = pango_attr_font_desc_new(pango_font_description_from_string("monospace 12"));
    pango_attr_list_insert(attrs_ringid, font_desc_ringid);
    gtk_label_set_attributes(GTK_LABEL(priv->label_ringid), attrs_ringid);
    pango_attr_list_unref(attrs_ringid);
    gtk_widget_set_no_show_all(priv->label_ringid, TRUE);
    gtk_box_pack_start(GTK_BOX(box_main), priv->label_ringid, FALSE, TRUE, 0);
    gtk_label_set_ellipsize(GTK_LABEL(priv->label_ringid), PANGO_ELLIPSIZE_END);

    /* QR drawing area */
    auto drawingarea_qrcode = gtk_drawing_area_new();
    auto qrsize = 200;
    gtk_widget_set_size_request(drawingarea_qrcode, qrsize, qrsize);
    g_signal_connect(drawingarea_qrcode, "draw", G_CALLBACK(draw_qrcode), NULL);
    gtk_widget_set_visible(drawingarea_qrcode, TRUE);

    /* revealer which will show the qr code */
    priv->revealer_qrcode = gtk_revealer_new();
    gtk_container_add(GTK_CONTAINER(priv->revealer_qrcode), drawingarea_qrcode);
    gtk_revealer_set_transition_type(GTK_REVEALER(priv->revealer_qrcode), GTK_REVEALER_TRANSITION_TYPE_CROSSFADE); //GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP);
    gtk_widget_set_halign(priv->revealer_qrcode, GTK_ALIGN_CENTER);
    gtk_widget_set_valign(priv->revealer_qrcode, GTK_ALIGN_CENTER);
    gtk_overlay_add_overlay(GTK_OVERLAY(overlay_qrcode), priv->revealer_qrcode);
    gtk_widget_set_no_show_all(priv->revealer_qrcode, TRUE);
    gtk_widget_set_visible(priv->revealer_qrcode, FALSE);

    /* QR code button */
    priv->button_qrcode = gtk_button_new_with_label(C_("Do not translate \"Ring ID\"", "Ring ID QR code"));
    gtk_widget_set_hexpand(priv->button_qrcode, FALSE);
    gtk_widget_set_size_request(priv->button_qrcode,10,10);
    g_signal_connect_swapped(priv->button_qrcode, "clicked", G_CALLBACK(switch_qrcode), self);
    gtk_widget_set_no_show_all(priv->button_qrcode, TRUE);
    gtk_box_pack_start(GTK_BOX(box_main), priv->button_qrcode, TRUE, TRUE, 0);

    update_view(self);
    priv->account_model_data_changed = QObject::connect(
        AvailableAccountModel::instance().selectionModel(),
        &QItemSelectionModel::currentChanged,
        [self] ()
        {
            update_view(self);
        });

    gtk_widget_show_all(GTK_WIDGET(self));
}

static void
ring_welcome_view_dispose(GObject *object)
{
    RingWelcomeView *self = RING_WELCOME_VIEW(object);
    RingWelcomeViewPrivate *priv = RING_WELCOME_VIEW_GET_PRIVATE(self);

    QObject::disconnect(priv->account_model_data_changed);

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

static void
ring_welcome_view_finalize(GObject *object)
{
    G_OBJECT_CLASS(ring_welcome_view_parent_class)->finalize(object);
}

static void
ring_welcome_view_class_init(RingWelcomeViewClass *klass)
{
    G_OBJECT_CLASS(klass)->finalize = ring_welcome_view_finalize;
    G_OBJECT_CLASS(klass)->dispose = ring_welcome_view_dispose;
}

GtkWidget *
ring_welcome_view_new()
{
    gpointer self = g_object_new(RING_WELCOME_VIEW_TYPE, NULL);

    return (GtkWidget *)self;
}

static gboolean
draw_qrcode(G_GNUC_UNUSED GtkWidget* diese,
            cairo_t*   cr,
            G_GNUC_UNUSED gpointer   data)
{
    auto account = get_active_ring_account();
    if (!account)
        return TRUE;

    auto rcode = QRcode_encodeString(account->username().toStdString().c_str(),
                                      0, //Let the version be decided by libqrencode
                                      QR_ECLEVEL_L, // Lowest level of error correction
                                      QR_MODE_8, // 8-bit data mode
                                      1);

    if (!rcode) { // no rcode, no draw
        g_warning("Failed to generate QR code");
        return TRUE;
    }

    auto margin = 5;
    auto qrsize = 200;
    int qrwidth = rcode->width + margin * 2;

    /* scaling */
    auto scale = qrsize/qrwidth;
    cairo_scale(cr, scale, scale);

    /* fill the background in white */
    cairo_set_source_rgb(cr, 1, 1, 1);
    cairo_rectangle(cr, 0, 0, qrwidth, qrwidth);
    cairo_fill (cr);

    unsigned char *row, *p;
    p = rcode->data;
    cairo_set_source_rgb(cr, 0, 0, 0); // back in black
    for(int y = 0; y < rcode->width; y++) {
        row = (p + (y * rcode->width));
        for(int x = 0; x < rcode->width; x++) {
            if(*(row + x) & 0x1) {
                cairo_rectangle(cr, margin + x, margin + y, 1, 1);
                cairo_fill(cr);
            }
        }

    }

    QRcode_free(rcode);
    return TRUE;

}

static void
switch_qrcode(RingWelcomeView* self)
{
    auto priv = RING_WELCOME_VIEW_GET_PRIVATE(self);

    auto to_reveal = !gtk_revealer_get_reveal_child(GTK_REVEALER(priv->revealer_qrcode));
    gtk_revealer_set_reveal_child(GTK_REVEALER(priv->revealer_qrcode), to_reveal);
    gtk_widget_set_opacity(priv->box_overlay, to_reveal ? 0.25 : 1.0);
}
