/*
 *  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 "contactsview.h"

#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include "models/gtkqsortfiltertreemodel.h"
#include <categorizedcontactmodel.h>
#include <personmodel.h>
#include "utils/calling.h"
#include <memory>
#include <globalinstances.h>
#include "native/pixbufmanipulator.h"
#include <contactmethod.h>
#include "defines.h"
#include "utils/models.h"
#include <QtCore/QItemSelectionModel>
#include "numbercategory.h"

static constexpr const char* COPY_DATA_KEY = "copy_data";

struct _ContactsView
{
    GtkTreeView parent;
};

struct _ContactsViewClass
{
    GtkTreeViewClass parent_class;
};

typedef struct _ContactsViewPrivate ContactsViewPrivate;

struct _ContactsViewPrivate
{
    CategorizedContactModel::SortedProxy *q_sorted_proxy;
};

G_DEFINE_TYPE_WITH_PRIVATE(ContactsView, contacts_view, GTK_TYPE_TREE_VIEW);

#define CONTACTS_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CONTACTS_VIEW_TYPE, ContactsViewPrivate))

static void
render_contact_photo(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
                     GtkCellRenderer *cell,
                     GtkTreeModel *tree_model,
                     GtkTreeIter *iter,
                     G_GNUC_UNUSED gpointer data)
{
    /* check if this is a top level item (category),
     * or a bottom level item (contact method)
     * in this case we don't want to show a photo */
    GtkTreePath *path = gtk_tree_model_get_path(tree_model, iter);
    int depth = gtk_tree_path_get_depth(path);
    gtk_tree_path_free(path);
    if (depth == 2) {
        /* get person */
        QModelIndex idx = gtk_q_sort_filter_tree_model_get_source_idx(GTK_Q_SORT_FILTER_TREE_MODEL(tree_model), iter);
        if (idx.isValid()) {
            QVariant var_c = idx.data(static_cast<int>(Person::Role::Object));
            Person *c = var_c.value<Person *>();
            /* get photo */
            QVariant var_p = GlobalInstances::pixmapManipulator().contactPhoto(c, QSize(50, 50), false);
            std::shared_ptr<GdkPixbuf> photo = var_p.value<std::shared_ptr<GdkPixbuf>>();
            g_object_set(G_OBJECT(cell), "pixbuf", photo.get(), NULL);
            return;
        }
    }

    /* otherwise, make sure its an empty pixbuf */
    g_object_set(G_OBJECT(cell), "pixbuf", NULL, NULL);
}

static void
render_name_and_contact_method(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
                               GtkCellRenderer *cell,
                               GtkTreeModel *tree_model,
                               GtkTreeIter *iter,
                               GtkTreeView *treeview)
{
    // check if this iter is selected
    gboolean is_selected = FALSE;
    if (GTK_IS_TREE_VIEW(treeview)) {
        auto selection = gtk_tree_view_get_selection(treeview);
        is_selected = gtk_tree_selection_iter_is_selected(selection, iter);
    }

    /**
     * If contact (person), show the name and the contact method (number)
     * underneath; if multiple contact methods, then indicate as such
     *
     * Otherwise just display the category or contact method
     */
    GtkTreePath *path = gtk_tree_model_get_path(tree_model, iter);
    int depth = gtk_tree_path_get_depth(path);
    gtk_tree_path_free(path);

    gchar *text = NULL;

    QModelIndex idx = gtk_q_sort_filter_tree_model_get_source_idx(GTK_Q_SORT_FILTER_TREE_MODEL(tree_model), iter);
    if (idx.isValid()) {
        QVariant var = idx.data(Qt::DisplayRole);
        if (depth == 1) {
            /* category */
            text = g_markup_printf_escaped("<b>%s</b>", var.value<QString>().toUtf8().constData());
        } else if (depth == 2) {
            /* contact, check for contact methods */
            QVariant var_c = idx.data(static_cast<int>(Person::Role::Object));
            if (var_c.isValid()) {
                Person *c = var_c.value<Person *>();
                switch (c->phoneNumbers().size()) {
                    case 0:
                        text = g_strdup_printf("%s\n", c->formattedName().toUtf8().constData());
                        break;
                    case 1:
                    {
                        QString number;
                        QVariant var_n = c->phoneNumbers().first()->roleData(Qt::DisplayRole);
                        if (var_n.isValid())
                            number = var_n.value<QString>();

                        /* we want the color of the status text to be the default color if this iter is
                         * selected so that the treeview is able to invert it against the selection color */
                        if (is_selected) {
                            text = g_markup_printf_escaped("%s\n %s",
                                                           c->formattedName().toUtf8().constData(),
                                                           number.toUtf8().constData());
                        } else {
                            text = g_markup_printf_escaped("%s\n <span fgcolor=\"gray\">%s</span>",
                                                            c->formattedName().toUtf8().constData(),
                                                            number.toUtf8().constData());
                        }
                        break;
                    }
                    default:
                        /* more than one, for now don't show any of the contact methods */
                        text = g_markup_printf_escaped("%s\n", c->formattedName().toUtf8().constData());
                        break;
                }
            } else {
                /* should never happen since depth 2 should always be a contact (person) */
                text = g_markup_printf_escaped("%s", var.value<QString>().toUtf8().constData());
            }
        } else {
            auto var_object = idx.data(static_cast<int>(Ring::Role::Object));
            auto cm = var_object.value<ContactMethod *>();
            if (cm && cm->category()) {
                // try to get the number category, eg: "home"
                text = g_markup_printf_escaped("(%s) %s", cm->category()->name().toUtf8().constData(),
                                                          cm->uri().toUtf8().constData());
            } else if (cm) {
                text = g_markup_printf_escaped("%s", cm->uri().toUtf8().constData());
            } else {
                /* should only ever be a CM, so this should never execute */
                text = g_markup_printf_escaped("%s", var.value<QString>().toUtf8().constData());
            }
        }
    }

    g_object_set(G_OBJECT(cell), "markup", text, NULL);
    g_free(text);

    /* set the colour */
    if ( depth == 1) {
        /* nice blue taken from the ring logo */
        GdkRGBA rgba = {0.2, 0.75294117647, 0.82745098039, 0.1};
        g_object_set(G_OBJECT(cell), "cell-background-rgba", &rgba, NULL);
    } else {
        g_object_set(G_OBJECT(cell), "cell-background", NULL, NULL);
    }
}

static void
expand_if_child(G_GNUC_UNUSED GtkTreeModel *tree_model,
                GtkTreePath  *path,
                G_GNUC_UNUSED GtkTreeIter  *iter,
                GtkTreeView  *treeview)
{
    if (gtk_tree_path_get_depth(path) == 2)
        gtk_tree_view_expand_to_path(treeview, path);
}

static void
activate_contact_item(GtkTreeView *tree_view,
                      GtkTreePath *path,
                      G_GNUC_UNUSED GtkTreeViewColumn *column,
                      G_GNUC_UNUSED gpointer user_data)
{
    /* expand / contract row */
    if (gtk_tree_view_row_expanded(tree_view, path))
        gtk_tree_view_collapse_row(tree_view, path);
    else
        gtk_tree_view_expand_row(tree_view, path, FALSE);

    GtkTreeModel *model = gtk_tree_view_get_model(tree_view);

    /* get iter */
    GtkTreeIter iter;
    if (gtk_tree_model_get_iter(model, &iter, path)) {
        QModelIndex idx = gtk_q_sort_filter_tree_model_get_source_idx(GTK_Q_SORT_FILTER_TREE_MODEL(model), &iter);
        if (idx.isValid()) {
            int depth = gtk_tree_path_get_depth(path);
            switch (depth) {
                case 0:
                case 1:
                    /* category, nothing to do */
                    break;
                case 2:
                {
                    /* contact (person), use contact method if there is only one */
                    QVariant var_c = idx.data(static_cast<int>(Person::Role::Object));
                    if (var_c.isValid()) {
                        Person *c = var_c.value<Person *>();
                        if (c->phoneNumbers().size() == 1) {
                            /* call with contact method */
                            place_new_call(c->phoneNumbers().first());
                        }
                    }
                    break;
                }
                default:
                {
                    /* contact method (or deeper) */
                    QVariant var_n = idx.data(static_cast<int>(ContactMethod::Role::Object));
                    if (var_n.isValid()) {
                        /* call with contat method */
                        place_new_call(var_n.value<ContactMethod *>());
                    }
                    break;
                }
            }
        }
    }
}

static void
call_contactmethod(G_GNUC_UNUSED GtkWidget *item, ContactMethod *cm)
{
    g_return_if_fail(cm);
    place_new_call(cm);
}

static void
copy_contact_info(GtkWidget *item, G_GNUC_UNUSED gpointer user_data)
{
    gpointer data = g_object_get_data(G_OBJECT(item), COPY_DATA_KEY);
    g_return_if_fail(data);
    gchar* text = (gchar *)data;
    GtkClipboard* clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
    gtk_clipboard_set_text(clip, text, -1);
}


static gboolean
remove_contact_dialog(GtkWidget *widget, Person *person)
{
    gboolean response = FALSE;
    GtkWidget *dialog = gtk_message_dialog_new(NULL,
                            (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
                            GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL,
                            _("Are you sure you want to delete contact \"%s\"?"
                            " It will be removed from your system's addressbook."),
                            person->formattedName().toUtf8().constData());

    gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);

    /* get parent window so we can center on it */
    GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(widget));
    if (gtk_widget_is_toplevel(parent)) {
        gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(parent));
        gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT);
    }

    switch (gtk_dialog_run(GTK_DIALOG(dialog))) {
        case GTK_RESPONSE_OK:
            response = TRUE;
            break;
        default:
            response = FALSE;
            break;
    }

    gtk_widget_destroy(dialog);

    return response;
}

static void
remove_contact(GtkWidget *item, G_GNUC_UNUSED gpointer user_data)
{
    gpointer data = g_object_get_data(G_OBJECT(item), COPY_DATA_KEY);
    g_return_if_fail(data);
    Person* person = (Person *)data;
    if (remove_contact_dialog(item, person)) {
        person->remove();
    }
}

static gboolean
contacts_popup_menu(G_GNUC_UNUSED GtkWidget *widget, GdkEventButton *event, GtkTreeView *treeview)
{
    /* build popup menu when right clicking on contact item
     * user should be able to copy the contact's name or "number".
     * other functionality may be added later.
     */

    /* check for right click */
    if (event->button != BUTTON_RIGHT_CLICK || event->type != GDK_BUTTON_PRESS)
        return FALSE;

    /* we don't want a popup menu for categories for now, so everything deeper
     * than one */
    GtkTreeIter iter;
    GtkTreeModel *model;
    GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
        return FALSE;

    GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
    int depth = gtk_tree_path_get_depth(path);
    gtk_tree_path_free(path);

    if (depth < 2)
        return FALSE;

    /* deeper than a category, so create a menu */
    GtkWidget *menu = gtk_menu_new();
    QModelIndex idx = get_index_from_selection(selection);

    /* if depth == 2, it is a contact, offer to copy name, and if only one
     * contact method exists then also the "number",
     * if depth > 2, then its a contact method, so only offer to copy the number
     */
    if (depth == 2) {
        QVariant var_c = idx.data(static_cast<int>(Ring::Role::Object));
        if (var_c.isValid()) {
            Person *c = var_c.value<Person *>();

                /* call */
                /* possiblity for multiple numbers */
                auto cms = c->phoneNumbers();
                if (cms.size() == 1) {
                    auto item = gtk_menu_item_new_with_mnemonic(_("_Call"));
                    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
                    g_signal_connect(item,
                                     "activate",
                                     G_CALLBACK(call_contactmethod),
                                     cms.at(0));
                } else if (cms.size() > 1) {
                    // maybe this is not needed since there is the depth > 2 option
                    auto call_item = gtk_menu_item_new_with_mnemonic(_("_Call"));
                    gtk_menu_shell_append(GTK_MENU_SHELL(menu), call_item);
                    auto call_menu = gtk_menu_new();
                    gtk_menu_item_set_submenu(GTK_MENU_ITEM(call_item), call_menu);
                    for (int i = 0; i < cms.size(); ++i) {
                        gchar *number = nullptr;
                        if (cms.at(i)->category()) {
                            // try to get the number category, eg: "home"
                            number = g_strdup_printf("(%s) %s", cms.at(i)->category()->name().toUtf8().constData(),
                                                              cms.at(i)->uri().toUtf8().constData());
                        } else {
                            number = g_strdup_printf("%s", cms.at(i)->uri().toUtf8().constData());
                        }
                        auto item = gtk_menu_item_new_with_label(number);
                        g_free(number);
                        gtk_menu_shell_append(GTK_MENU_SHELL(call_menu), item);
                        g_signal_connect(item,
                                         "activate",
                                         G_CALLBACK(call_contactmethod),
                                         cms.at(i));
                    }
                }

            /* copy name */
            gchar *name = g_strdup_printf("%s", c->formattedName().toUtf8().constData());
            GtkWidget *copy_name_item = gtk_menu_item_new_with_mnemonic(_("_Copy name"));
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), copy_name_item);
            g_object_set_data_full(G_OBJECT(copy_name_item), COPY_DATA_KEY, name, (GDestroyNotify)g_free);
            g_signal_connect(copy_name_item,
                             "activate",
                             G_CALLBACK(copy_contact_info),
                             NULL);

            /* copy number if there is only one */
            if (c->phoneNumbers().size() == 1) {
                gchar *number = g_strdup_printf("%s",c->phoneNumbers().first()->uri().toUtf8().constData());
                GtkWidget *item = gtk_menu_item_new_with_mnemonic(_("_Copy number"));
                gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
                g_object_set_data_full(G_OBJECT(item), COPY_DATA_KEY, number, (GDestroyNotify)g_free);
                g_signal_connect(item,
                                "activate",
                                G_CALLBACK(copy_contact_info),
                                NULL);
            }

            /* delete contact */
            GtkWidget *remove_contact_item = gtk_menu_item_new_with_mnemonic(_("_Remove contact"));
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), remove_contact_item);
            g_object_set_data_full(G_OBJECT(remove_contact_item), COPY_DATA_KEY, c, (GDestroyNotify)g_free);
            g_signal_connect(remove_contact_item,
                             "activate",
                             G_CALLBACK(remove_contact),
                             NULL);

        }
    } else if (depth > 2) {
        QVariant var_n = idx.data(static_cast<int>(ContactMethod::Role::Object));
        if (var_n.isValid()) {
            /* copy number */
            ContactMethod *cm = var_n.value<ContactMethod *>();
            gchar *number = g_strdup_printf("%s",cm->uri().toUtf8().constData());
            GtkWidget *item = gtk_menu_item_new_with_mnemonic(_("_Copy number"));
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
            g_object_set_data_full(G_OBJECT(item), COPY_DATA_KEY, number, (GDestroyNotify)g_free);
            g_signal_connect(item,
                             "activate",
                             G_CALLBACK(copy_contact_info),
                             NULL);

            /* call */
            item = gtk_menu_item_new_with_mnemonic(_("_Call"));
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
            g_signal_connect(item,
                             "activate",
                             G_CALLBACK(call_contactmethod),
                             cm);
        }
    }

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

    return TRUE; /* we handled the event */
}

static void
contacts_view_init(ContactsView *self)
{
    ContactsViewPrivate *priv = CONTACTS_VIEW_GET_PRIVATE(self);

    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(self), FALSE);

    /* disable default search, we will handle it ourselves;
     * otherwise the search steals input focus on key presses */
    gtk_tree_view_set_enable_search(GTK_TREE_VIEW(self), FALSE);

    /* initial set up to be categorized by name and sorted alphabetically */
    priv->q_sorted_proxy = &CategorizedContactModel::SortedProxy::instance();
    CategorizedContactModel::instance().setUnreachableHidden(true);

    /* for now we always want to sort by ascending order */
    priv->q_sorted_proxy->model()->sort(0);

    /* select default category (the first one, which is by name) */
    priv->q_sorted_proxy->categorySelectionModel()->setCurrentIndex(
        priv->q_sorted_proxy->categoryModel()->index(0, 0),
        QItemSelectionModel::ClearAndSelect);

    GtkQSortFilterTreeModel *contact_model = gtk_q_sort_filter_tree_model_new(
        priv->q_sorted_proxy->model(),
        1,
        0, Qt::DisplayRole, G_TYPE_STRING);
    gtk_tree_view_set_model(GTK_TREE_VIEW(self), GTK_TREE_MODEL(contact_model));

    /* photo and name/contact method column */
    GtkCellArea *area = gtk_cell_area_box_new();
    GtkTreeViewColumn *column = gtk_tree_view_column_new_with_area(area);

    /* photo renderer */
    GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
    gtk_cell_area_box_pack_start(GTK_CELL_AREA_BOX(area), renderer, FALSE, FALSE, FALSE);

    /* get the photo */
    gtk_tree_view_column_set_cell_data_func(
        column,
        renderer,
        (GtkTreeCellDataFunc)render_contact_photo,
        NULL,
        NULL);

    /* name and contact method renderer */
    renderer = gtk_cell_renderer_text_new();
    g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
    gtk_cell_area_box_pack_start(GTK_CELL_AREA_BOX(area), renderer, FALSE, FALSE, FALSE);

    gtk_tree_view_column_set_cell_data_func(
        column,
        renderer,
        (GtkTreeCellDataFunc)render_name_and_contact_method,
        self,
        NULL);

    gtk_tree_view_append_column(GTK_TREE_VIEW(self), column);
    gtk_tree_view_column_set_resizable(column, TRUE);

    gtk_tree_view_expand_all(GTK_TREE_VIEW(self));
    g_signal_connect(contact_model, "row-inserted", G_CALLBACK(expand_if_child), self);
    g_signal_connect(self, "button-press-event", G_CALLBACK(contacts_popup_menu), self);
    g_signal_connect(self, "row-activated", G_CALLBACK(activate_contact_item), NULL);

    gtk_widget_show_all(GTK_WIDGET(self));
}

static void
contacts_view_dispose(GObject *object)
{
    G_OBJECT_CLASS(contacts_view_parent_class)->dispose(object);
}

static void
contacts_view_finalize(GObject *object)
{
    G_OBJECT_CLASS(contacts_view_parent_class)->finalize(object);
}

static void
contacts_view_class_init(ContactsViewClass *klass)
{
    G_OBJECT_CLASS(klass)->finalize = contacts_view_finalize;
    G_OBJECT_CLASS(klass)->dispose = contacts_view_dispose;
}

GtkWidget *
contacts_view_new()
{
    gpointer self = g_object_new(CONTACTS_VIEW_TYPE, NULL);

    return (GtkWidget *)self;
}
