/*
 *  Copyright (C) 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 "contactpopupmenu.h"

// GTK+ related
#include <glib/gi18n.h>

// LRC
#include <contactmethod.h>
#include <person.h>
#include <numbercategory.h>
#include <call.h>

// Ring client
#include "utils/calling.h"
#include "models/gtkqtreemodel.h"
#include "utils/menus.h"

static constexpr const char* COPY_DATA_KEY = "copy_data";

struct _ContactPopupMenu
{
    GtkMenu parent;
};

struct _ContactPopupMenuClass
{
    GtkMenuClass parent_class;
};

typedef struct _ContactPopupMenuPrivate ContactPopupMenuPrivate;

struct _ContactPopupMenuPrivate
{
    GtkTreeView *treeview;
};

G_DEFINE_TYPE_WITH_PRIVATE(ContactPopupMenu, contact_popup_menu, GTK_TYPE_MENU);

#define CONTACT_POPUP_MENU_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CONTACT_POPUP_MENU_TYPE, ContactPopupMenuPrivate))

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 void
call_contactmethod(G_GNUC_UNUSED GtkWidget *item, ContactMethod *cm)
{
    g_return_if_fail(cm);
    place_new_call(cm);
}

static void
remove_contact(GtkWidget *item, Person *person)
{
    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());

    /* get parent window so we can center on it */
    GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(item));
    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);
    }

    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
        person->remove();
    }

    gtk_widget_destroy(dialog);
}

/**
 * Update the menu when the selected item in the treeview changes.
 */
static void
update(GtkTreeSelection *selection, ContactPopupMenu *self)
{
    ContactPopupMenuPrivate *priv = CONTACT_POPUP_MENU_GET_PRIVATE(self);

    /* clear the current menu */
    gtk_container_forall(GTK_CONTAINER(self), (GtkCallback)gtk_widget_destroy, nullptr);

    /* we always build a menu, however in some cases some or all of the items will be deactivated;
     * we prefer this to having an empty menu because GTK+ behaves weird in the empty menu case
     */
    auto call_item = gtk_menu_item_new_with_mnemonic(_("_Call"));
    gtk_widget_set_sensitive(GTK_WIDGET(call_item), FALSE);
    gtk_menu_shell_append(GTK_MENU_SHELL(self), call_item);
    auto copy_name_item = gtk_menu_item_new_with_mnemonic(_("_Copy name"));
    gtk_widget_set_sensitive(GTK_WIDGET(copy_name_item), FALSE);
    gtk_menu_shell_append(GTK_MENU_SHELL(self), copy_name_item);
    auto copy_number_item = gtk_menu_item_new_with_mnemonic(_("_Copy number"));
    gtk_widget_set_sensitive(GTK_WIDGET(copy_number_item), FALSE);
    gtk_menu_shell_append(GTK_MENU_SHELL(self), copy_number_item);
    auto add_to_contact_item = gtk_menu_item_new_with_mnemonic(_("_Add to contact"));
    gtk_widget_set_sensitive(GTK_WIDGET(add_to_contact_item), FALSE);
    gtk_menu_shell_append(GTK_MENU_SHELL(self), add_to_contact_item);
    auto remove_contact_item = gtk_menu_item_new_with_mnemonic(_("_Remove contact"));
    gtk_widget_set_sensitive(GTK_WIDGET(remove_contact_item), FALSE);
    gtk_menu_shell_append(GTK_MENU_SHELL(self), remove_contact_item);

    /* show all items */
    gtk_widget_show_all(GTK_WIDGET(self));

    GtkTreeIter iter;
    GtkTreeModel *model;
    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
        return;

    QModelIndex idx = gtk_q_tree_model_get_source_idx(GTK_Q_TREE_MODEL(model), &iter);

    auto type = idx.data(static_cast<int>(Ring::Role::ObjectType));
    auto object = idx.data(static_cast<int>(Ring::Role::Object));
    if (!type.isValid() || !object.isValid())
        return; // not a valid Ring::Role::Object, so nothing to do

    /* call */
    switch (type.value<Ring::ObjectType>()) {
        case Ring::ObjectType::Person:
        {
            /* possiblity for multiple numbers */
            auto cms = object.value<Person *>()->phoneNumbers();
            if (cms.size() == 1) {
                gtk_widget_set_sensitive(GTK_WIDGET(call_item), TRUE);
                g_signal_connect(call_item,
                                 "activate",
                                 G_CALLBACK(call_contactmethod),
                                 cms.at(0));
            } else if (cms.size() > 1) {
                gtk_widget_set_sensitive(GTK_WIDGET(call_item), TRUE);
                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));
                }
            }
        }
        break;
        case Ring::ObjectType::ContactMethod:
        {
            gtk_widget_set_sensitive(GTK_WIDGET(call_item), TRUE);
            auto cm = object.value<ContactMethod *>();
            g_signal_connect(call_item,
                             "activate",
                             G_CALLBACK(call_contactmethod),
                             cm);
        }
        break;
        case Ring::ObjectType::Call:
        {
            gtk_widget_set_sensitive(GTK_WIDGET(call_item), TRUE);
            auto call = object.value<Call *>();
            g_signal_connect(call_item,
                             "activate",
                             G_CALLBACK(call_contactmethod),
                             call->peerContactMethod());
        }
        break;
        case Ring::ObjectType::Media:
        case Ring::ObjectType::Certificate:
        // nothing to do for now
        case Ring::ObjectType::COUNT__:
        break;
    }

    /* copy name */
    QVariant name_var = idx.data(static_cast<int>(Ring::Role::Name));
    if (name_var.isValid()) {
        gtk_widget_set_sensitive(GTK_WIDGET(copy_name_item), TRUE);
        gchar *name = g_strdup_printf("%s", name_var.value<QString>().toUtf8().constData());
        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(s) */
    switch (type.value<Ring::ObjectType>()) {
        case Ring::ObjectType::Person:
        {
            /* possiblity for multiple numbers */
            auto cms = object.value<Person *>()->phoneNumbers();
            if (cms.size() == 1) {
                gtk_widget_set_sensitive(GTK_WIDGET(copy_number_item), TRUE);
                gchar *number = g_strdup_printf("%s",cms.at(0)->uri().toUtf8().constData());
                g_object_set_data_full(G_OBJECT(copy_number_item), COPY_DATA_KEY, number, (GDestroyNotify)g_free);
                g_signal_connect(copy_number_item,
                                 "activate",
                                 G_CALLBACK(copy_contact_info),
                                 NULL);
            } else if (cms.size() > 1) {
                gtk_widget_set_sensitive(GTK_WIDGET(copy_number_item), TRUE);
                auto copy_menu = gtk_menu_new();
                gtk_menu_item_set_submenu(GTK_MENU_ITEM(copy_number_item), copy_menu);
                for (int i = 0; i < cms.size(); ++i) {
                    auto number = g_strdup_printf("%s",cms.at(i)->uri().toUtf8().constData());
                    gchar *category_number = nullptr;
                    if (cms.at(i)->category()) {
                        // try to get the number category, eg: "home"
                        category_number = g_strdup_printf("(%s) %s",
                                                          cms.at(i)->category()->name().toUtf8().constData(),
                                                          number);
                    } else {
                        category_number = g_strdup_printf("%s", number);
                    }
                    auto item = gtk_menu_item_new_with_label(category_number);
                    g_free(category_number);
                    gtk_menu_shell_append(GTK_MENU_SHELL(copy_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);
                }
            }
        }
        break;
        case Ring::ObjectType::ContactMethod:
        case Ring::ObjectType::Call:
        {
            QVariant number_var = idx.data(static_cast<int>(Ring::Role::Number));
            if (number_var.isValid()) {
                gtk_widget_set_sensitive(GTK_WIDGET(copy_number_item), TRUE);
                gchar *number = g_strdup_printf("%s", number_var.value<QString>().toUtf8().constData());
                g_object_set_data_full(G_OBJECT(copy_number_item), COPY_DATA_KEY, number, (GDestroyNotify)g_free);
                g_signal_connect(copy_number_item,
                                 "activate",
                                 G_CALLBACK(copy_contact_info),
                                 NULL);
            }
        }
        break;
        case Ring::ObjectType::Media:
        case Ring::ObjectType::Certificate:
        // nothing to do
        case Ring::ObjectType::COUNT__:
        break;
    }

    /* get rectangle to know where to draw the add to contact popup */
    GdkRectangle rect;
    auto path = gtk_tree_model_get_path(model, &iter);
    auto column = gtk_tree_view_get_column(priv->treeview, 0);
    gtk_tree_view_get_cell_area(priv->treeview, path, column, &rect);
    gtk_tree_view_convert_bin_window_to_widget_coords(priv->treeview, rect.x, rect.y, &rect.x, &rect.y);
    gtk_tree_path_free(path);

    /* add to contact - only offer to add CMs which are not already associated with a Person */
    switch (type.value<Ring::ObjectType>()) {
        case Ring::ObjectType::Person:
        // already a contact
        break;
        case Ring::ObjectType::ContactMethod:
        {
            auto cm = object.value<ContactMethod *>();
            if (!cm->contact()) {
                gtk_widget_set_sensitive(GTK_WIDGET(add_to_contact_item), TRUE);
                menu_item_add_to_contact(GTK_MENU_ITEM(add_to_contact_item), cm, GTK_WIDGET(priv->treeview), &rect);
            }
        }
        break;
        case Ring::ObjectType::Call:
        {
            auto cm = object.value<Call *>()->peerContactMethod();
            if (!cm->contact()) {
                gtk_widget_set_sensitive(GTK_WIDGET(add_to_contact_item), TRUE);
                menu_item_add_to_contact(GTK_MENU_ITEM(add_to_contact_item), cm, GTK_WIDGET(priv->treeview), &rect);
            }
        }
        break;
        case Ring::ObjectType::Media:
        case Ring::ObjectType::Certificate:
        // nothing to do
        case Ring::ObjectType::COUNT__:
        break;
    }

     /* remove contact */
     if (type.value<Ring::ObjectType>() == Ring::ObjectType::Person) {
         gtk_widget_set_sensitive(GTK_WIDGET(remove_contact_item), TRUE);
         auto person = object.value<Person *>();
         g_signal_connect(remove_contact_item,
                          "activate",
                          G_CALLBACK(remove_contact),
                          person);
     }

     /* show all items */
     gtk_widget_show_all(GTK_WIDGET(self));
}

static void
contact_popup_menu_init(G_GNUC_UNUSED ContactPopupMenu *self)
{
    // nothing to do
}

static void
contact_popup_menu_dispose(GObject *object)
{
    G_OBJECT_CLASS(contact_popup_menu_parent_class)->dispose(object);
}

static void
contact_popup_menu_finalize(GObject *object)
{
    G_OBJECT_CLASS(contact_popup_menu_parent_class)->finalize(object);
}

static void
contact_popup_menu_class_init(ContactPopupMenuClass *klass)
{
    G_OBJECT_CLASS(klass)->finalize = contact_popup_menu_finalize;
    G_OBJECT_CLASS(klass)->dispose = contact_popup_menu_dispose;
}

GtkWidget *
contact_popup_menu_new(GtkTreeView *treeview)
{
    gpointer self = g_object_new(CONTACT_POPUP_MENU_TYPE, NULL);
    ContactPopupMenuPrivate *priv = CONTACT_POPUP_MENU_GET_PRIVATE(self);

    priv->treeview = treeview;
    GtkTreeSelection *selection = gtk_tree_view_get_selection(priv->treeview);
    g_signal_connect(selection, "changed", G_CALLBACK(update), self);

    // build the menu for the first time
    update(selection, CONTACT_POPUP_MENU(self));

    return (GtkWidget *)self;
}

gboolean
contact_popup_menu_show(ContactPopupMenu *self, GdkEventButton *event)
{
    /* check for right click */
    if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_SECONDARY ) {
        /* the menu will automatically get updated when the selection changes */
        gtk_menu_popup(GTK_MENU(self), NULL, NULL, NULL, NULL, event->button, event->time);
    }

    return GDK_EVENT_PROPAGATE; /* so that the item selection changes */
}
