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

#include <contactmethod.h>
#include <personmodel.h>
#include <QtCore/QSortFilterProxyModel>
#include <memory>
#include "models/gtkqsortfiltertreemodel.h"
#include <globalinstances.h>
#include "native/pixbufmanipulator.h"
#include "utils/models.h"

enum
{
    PERSON_SELECTED,
    NEW_PERSON_CLICKED,

    LAST_SIGNAL
};

struct _ChooseContactView
{
    GtkBox parent;
};

struct _ChooseContactViewClass
{
    GtkBoxClass parent_class;
};

typedef struct _ChooseContactViewPrivate ChooseContactViewPrivate;

struct _ChooseContactViewPrivate
{
    GtkWidget *treeview_choose_contact;
    GtkWidget *button_create_contact;

    ContactMethod *cm;

    QSortFilterProxyModel *sorted_contacts;
};

static guint choose_contact_signals[LAST_SIGNAL] = { 0 };

G_DEFINE_TYPE_WITH_PRIVATE(ChooseContactView, choose_contact_view, GTK_TYPE_BOX);

#define CHOOSE_CONTACT_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CHOOSE_CONTACT_VIEW_TYPE, ChooseContactViewPrivate))

static void
render_contact_photo(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
                     GtkCellRenderer *cell,
                     GtkTreeModel *tree_model,
                     GtkTreeIter *iter,
                     G_GNUC_UNUSED gpointer data)
{
    /* show a photo for the top level (Person) */
    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 == 1) {
        /* 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
select_cb(ChooseContactView *self)
{
    g_return_if_fail(IS_CHOOSE_CONTACT_VIEW(self));
    ChooseContactViewPrivate *priv = CHOOSE_CONTACT_VIEW_GET_PRIVATE(self);

    /* get the selected collection */
    auto selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview_choose_contact));
    auto idx = get_index_from_selection(selection);
    if (idx.isValid()) {
        auto p = idx.data(static_cast<int>(Person::Role::Object)).value<Person *>();

        g_signal_emit(self, choose_contact_signals[PERSON_SELECTED], 0, p);
    } else {
        g_warning("invalid Person selected");
    }
}

static void
create_contact_cb(G_GNUC_UNUSED GtkButton *button, ChooseContactView *self)
{
    g_return_if_fail(IS_CHOOSE_CONTACT_VIEW(self));

    g_signal_emit(self, choose_contact_signals[NEW_PERSON_CLICKED], 0);
}

static void
choose_contact_view_init(ChooseContactView *self)
{
    gtk_widget_init_template(GTK_WIDGET(self));

    ChooseContactViewPrivate *priv = CHOOSE_CONTACT_VIEW_GET_PRIVATE(self);

    priv->sorted_contacts = new QSortFilterProxyModel(&PersonModel::instance());
    priv->sorted_contacts->setSourceModel(&PersonModel::instance());
    priv->sorted_contacts->setSortCaseSensitivity(Qt::CaseInsensitive);
    priv->sorted_contacts->sort(0);

    auto contacts_model = gtk_q_sort_filter_tree_model_new(
        priv->sorted_contacts,
        1,
        0, Qt::DisplayRole, G_TYPE_STRING);
    gtk_tree_view_set_model(GTK_TREE_VIEW(priv->treeview_choose_contact), GTK_TREE_MODEL(contacts_model));
    g_object_unref(contacts_model); /* the model should be freed when the view is destroyed */

    /* photo and name/contact method colparentumn */
    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_add_attribute(column, renderer, "text", 0);

    gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview_choose_contact), column);
    gtk_tree_view_column_set_resizable(column, TRUE);

    /* connect to the button signals */
    g_signal_connect_swapped(priv->treeview_choose_contact, "row-activated", G_CALLBACK(select_cb), self);
    g_signal_connect(priv->button_create_contact, "clicked", G_CALLBACK(create_contact_cb), self);
}

static void
choose_contact_view_dispose(GObject *object)
{
    G_OBJECT_CLASS(choose_contact_view_parent_class)->dispose(object);
}

static void
choose_contact_view_finalize(GObject *object)
{
    ChooseContactView *self = CHOOSE_CONTACT_VIEW(object);
    ChooseContactViewPrivate *priv = CHOOSE_CONTACT_VIEW_GET_PRIVATE(self);

    delete priv->sorted_contacts;

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

static void
choose_contact_view_class_init(ChooseContactViewClass *klass)
{
    G_OBJECT_CLASS(klass)->finalize = choose_contact_view_finalize;
    G_OBJECT_CLASS(klass)->dispose = choose_contact_view_dispose;

    choose_contact_signals[NEW_PERSON_CLICKED] =
        g_signal_new("new-person-clicked",
            G_OBJECT_CLASS_TYPE(G_OBJECT_CLASS(klass)),
            (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
            0, /* class offset */
            NULL, /* accumulater */
            NULL, /* accu data */
            g_cclosure_marshal_VOID__VOID,
            G_TYPE_NONE, 0);

    choose_contact_signals[PERSON_SELECTED] =
        g_signal_new ("person-selected",
            G_OBJECT_CLASS_TYPE(G_OBJECT_CLASS(klass)),
            (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
            0, /* class offset */
            NULL, /* accumulater */
            NULL, /* accu data */
            g_cclosure_marshal_VOID__POINTER,
            G_TYPE_NONE,
            1, G_TYPE_POINTER);

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

    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), ChooseContactView, treeview_choose_contact);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), ChooseContactView, button_create_contact);
}

GtkWidget *
choose_contact_view_new(ContactMethod *cm)
{
    g_return_val_if_fail(cm, NULL);

    gpointer self = g_object_new(CHOOSE_CONTACT_VIEW_TYPE, NULL);

    ChooseContactViewPrivate *priv = CHOOSE_CONTACT_VIEW_GET_PRIVATE(self);
    priv->cm = cm;

    return (GtkWidget *)self;
}
