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

#include <glib/gi18n.h>
#include <contactmethod.h>
#include <personmodel.h>
#include <numbercategorymodel.h>
#include "utils/models.h"

enum
{
    PERSON_SAVED,

    LAST_SIGNAL
};

struct _EditContactView
{
    GtkGrid parent;
};

struct _EditContactViewClass
{
    GtkGridClass parent_class;
};

typedef struct _EditContactViewPrivate EditContactViewPrivate;

struct _EditContactViewPrivate
{
    GtkWidget *button_save;
    GtkWidget *combobox_addressbook;
    GtkWidget *entry_name;
    GtkWidget *combobox_detail;
    GtkWidget *label_uri;

    ContactMethod *cm;
    Person        *person;
};

static guint edit_contact_signals[LAST_SIGNAL] = { 0 };

G_DEFINE_TYPE_WITH_PRIVATE(EditContactView, edit_contact_view, GTK_TYPE_GRID);

#define EDIT_CONTACT_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EDIT_CONTACT_VIEW_TYPE, EditContactViewPrivate))

static void
save_cb(EditContactView *self)
{
    g_return_if_fail(IS_EDIT_CONTACT_VIEW(self));
    EditContactViewPrivate *priv = EDIT_CONTACT_VIEW_GET_PRIVATE(self);

    auto name = gtk_entry_get_text(GTK_ENTRY(priv->entry_name));
    if (!priv->person) {
        /* make sure that the entry is not empty */
        if (!name or strlen(name) == 0) {
            g_warning("new contact must have a name");
            gtk_widget_grab_focus(priv->entry_name);
            return;
        }
    }

    /* get the selected number category */
    const auto& idx = gtk_combo_box_get_index(GTK_COMBO_BOX(priv->combobox_detail));
    if (idx.isValid()) {
        auto category = NumberCategoryModel::instance().getCategory(idx.data().toString());
        priv->cm->setCategory(category);
    }

    if (!priv->person) {
        /* get the selected collection */
        GtkTreeIter iter;
        gtk_combo_box_get_active_iter(GTK_COMBO_BOX(priv->combobox_addressbook), &iter);
        auto addressbook_model = gtk_combo_box_get_model(GTK_COMBO_BOX(priv->combobox_addressbook));
        GValue value = G_VALUE_INIT;
        gtk_tree_model_get_value(addressbook_model, &iter, 1, &value);
        auto collection = (CollectionInterface *)g_value_get_pointer(&value);

        /* create a new person */
        priv->person = new Person(collection);
        priv->person->setFormattedName(name);

        /* associate the new person with the contact method */
        Person::ContactMethods numbers;
        numbers << priv->cm;
        priv->person->setContactMethods(numbers);

        PersonModel::instance().addNewPerson(priv->person, collection);
    } else {
        auto numbers = priv->person->phoneNumbers();
        numbers << priv->cm;
        priv->person->setContactMethods(numbers);
        priv->person->save();
    }

    g_signal_emit(self, edit_contact_signals[PERSON_SAVED], 0);
}

static void
name_changed(GtkEntry *entry_name, EditContactView *self)
{
    g_return_if_fail(IS_EDIT_CONTACT_VIEW(self));
    EditContactViewPrivate *priv = EDIT_CONTACT_VIEW_GET_PRIVATE(self);

    auto name = gtk_entry_get_text(entry_name);
    /* make sure that the entry is not empty */
    if (!name or strlen(name) == 0) {
        gtk_widget_set_sensitive(priv->button_save, FALSE);
    } else {
        gtk_widget_set_sensitive(priv->button_save, TRUE);
    }
}

static void
edit_contact_view_init(EditContactView *self)
{
    gtk_widget_init_template(GTK_WIDGET(self));

    EditContactViewPrivate *priv = EDIT_CONTACT_VIEW_GET_PRIVATE(self);

    /* model for the combobox for the choice of addressbooks */
    auto addressbook_model = gtk_list_store_new(
        2, G_TYPE_STRING, G_TYPE_POINTER
    );

    gtk_combo_box_set_model(GTK_COMBO_BOX(priv->combobox_addressbook),
                            GTK_TREE_MODEL(addressbook_model));
    GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(priv->combobox_addressbook),
                               renderer, FALSE);
    gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(priv->combobox_addressbook),
                                   renderer, "text", 0, NULL);

    /* get all the available contact backends (addressbooks) */
    const auto& collections = PersonModel::instance().enabledCollections();
    for (int i = 0; i < collections.size(); ++i) {
        GtkTreeIter iter;
        gtk_list_store_append(addressbook_model, &iter);
        gtk_list_store_set(addressbook_model, &iter,
                           0, collections.at(i)->name().toUtf8().constData(),
                           1, collections.at(i),
                           -1);
    }

    /* set the first addressbook which is not the "vCard" to be used, unless its
     * the only one */
    GtkTreeIter iter_to_select;
    if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(addressbook_model), &iter_to_select)) {
        GValue value = G_VALUE_INIT;
        gtk_tree_model_get_value(GTK_TREE_MODEL(addressbook_model), &iter_to_select, 1, &value);
        auto collection = (CollectionInterface *)g_value_get_pointer(&value);
        GtkTreeIter iter = iter_to_select;
        while ( (collection->name() == "vCard") && gtk_tree_model_iter_next(GTK_TREE_MODEL(addressbook_model), &iter)) {
            iter_to_select = iter;
            value = G_VALUE_INIT;
            gtk_tree_model_get_value(GTK_TREE_MODEL(addressbook_model), &iter, 1, &value);
            collection = (CollectionInterface *)g_value_get_pointer(&value);
        }
    }
    gtk_combo_box_set_active_iter(GTK_COMBO_BOX(priv->combobox_addressbook), &iter_to_select);

    /* model for the available details to choose from */
    gtk_combo_box_set_qmodel_text(GTK_COMBO_BOX(priv->combobox_detail),
                             (QAbstractItemModel *)&NumberCategoryModel::instance(), NULL);

    /* set "home" as the default number category */
    const auto& idx = NumberCategoryModel::instance().nameToIndex(C_("Phone number category", "home"));
    if (idx.isValid())
        gtk_combo_box_set_active_index(GTK_COMBO_BOX(priv->combobox_detail), idx);

    /* disable save button until name is entered */
    gtk_widget_set_sensitive(priv->button_save, FALSE);

    /* connect to the button signals */
    g_signal_connect_swapped(priv->button_save, "clicked", G_CALLBACK(save_cb), self);
    g_signal_connect(priv->entry_name, "changed", G_CALLBACK(name_changed), self);
}

static void
edit_contact_view_dispose(GObject *object)
{
    G_OBJECT_CLASS(edit_contact_view_parent_class)->dispose(object);
}

static void
edit_contact_view_finalize(GObject *object)
{
    G_OBJECT_CLASS(edit_contact_view_parent_class)->finalize(object);
}

static void
edit_contact_view_class_init(EditContactViewClass *klass)
{
    G_OBJECT_CLASS(klass)->finalize = edit_contact_view_finalize;
    G_OBJECT_CLASS(klass)->dispose = edit_contact_view_dispose;

    edit_contact_signals[PERSON_SAVED] =
        g_signal_new("person-saved",
            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);

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

    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), EditContactView, button_save);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), EditContactView, combobox_addressbook);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), EditContactView, entry_name);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), EditContactView, combobox_detail);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS(klass), EditContactView, label_uri);
}

/**
 * If a Person is specified, a view to edit the given Person will be created;
 * if no Person is given (NULL), then a new Person object will be created when
 * 'save' is clicked
 */
GtkWidget *
edit_contact_view_new(ContactMethod *cm, Person *p)
{
    g_return_val_if_fail(cm, NULL);

    gpointer self = g_object_new(EDIT_CONTACT_VIEW_TYPE, NULL);

    EditContactViewPrivate *priv = EDIT_CONTACT_VIEW_GET_PRIVATE(self);

    priv->cm = cm;
    auto uri_escaped = g_markup_printf_escaped("<b>%s</b>", cm->uri().toUtf8().constData());
    gtk_label_set_markup(GTK_LABEL(priv->label_uri), uri_escaped);
    g_free(uri_escaped);

    /* use the primaryName as the suggested name (usually the display name), unless it is the same
     * as the uri */
    if (cm->primaryName() != cm->uri())
        gtk_entry_set_text(GTK_ENTRY(priv->entry_name), cm->primaryName().toUtf8().constData());

    if (p) {
        priv->person = p;

        /* select the proper addressbook and prevent it from being modified */
        if (p->collection() != NULL) {
            auto model = gtk_combo_box_get_model(GTK_COMBO_BOX(priv->combobox_addressbook));
            GtkTreeIter iter;
            if (gtk_tree_model_get_iter_first(model, &iter)) {
                GValue value = G_VALUE_INIT;
                gtk_tree_model_get_value(model, &iter, 1, &value);
                auto collection = (CollectionInterface *)g_value_get_pointer(&value);
                while (collection != p->collection() && gtk_tree_model_iter_next(model, &iter)) {
                    value = G_VALUE_INIT;
                    gtk_tree_model_get_value(model, &iter, 1, &value);
                    collection = (CollectionInterface *)g_value_get_pointer(&value);
                }
            }

            gtk_combo_box_set_active_iter(GTK_COMBO_BOX(priv->combobox_addressbook), &iter);
        }
        gtk_widget_set_sensitive(priv->combobox_addressbook, FALSE);

        /* set the name of the person, and prevent it from being edited */
        gtk_entry_set_text(GTK_ENTRY(priv->entry_name), p->formattedName().toUtf8().constData());
        g_object_set(G_OBJECT(priv->entry_name), "editable", FALSE, NULL);
    }

    return (GtkWidget *)self;
}
