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

#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <account.h>
#include <audio/codecmodel.h>
#include "models/gtkqsortfiltertreemodel.h"
#include "utils/models.h"

struct _AccountAudioTab
{
    GtkBox parent;
};

struct _AccountAudioTabClass
{
    GtkBoxClass parent_class;
};

typedef struct _AccountAudioTabPrivate AccountAudioTabPrivate;

struct _AccountAudioTabPrivate
{
    Account   *account;
    GtkWidget *treeview_codecs;
    GtkWidget *button_moveup;
    GtkWidget *button_movedown;
};

G_DEFINE_TYPE_WITH_PRIVATE(AccountAudioTab, account_audio_tab, GTK_TYPE_BOX);

#define ACCOUNT_AUDIO_TAB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ACCOUNT_AUDIO_TAB_TYPE, AccountAudioTabPrivate))

static void
account_audio_tab_dispose(GObject *object)
{
    G_OBJECT_CLASS(account_audio_tab_parent_class)->dispose(object);
}

static void
account_audio_tab_init(AccountAudioTab *view)
{
    gtk_widget_init_template(GTK_WIDGET(view));
}

static void
account_audio_tab_class_init(AccountAudioTabClass *klass)
{
    G_OBJECT_CLASS(klass)->dispose = account_audio_tab_dispose;

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

    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountAudioTab, treeview_codecs);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountAudioTab, button_moveup);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), AccountAudioTab, button_movedown);
}

static void
codec_active_toggled(GtkCellRendererToggle *renderer, gchar *path, AccountAudioTab *view)
{
    g_return_if_fail(IS_ACCOUNT_AUDIO_TAB(view));
    AccountAudioTabPrivate *priv = ACCOUNT_AUDIO_TAB_GET_PRIVATE(view);

    /* we want to set it to the opposite of the current value */
    gboolean toggle = !gtk_cell_renderer_toggle_get_active(renderer);

    /* get iter which was clicked */
    GtkTreePath *tree_path = gtk_tree_path_new_from_string(path);
    GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(priv->treeview_codecs));
    GtkTreeIter iter;
    gtk_tree_model_get_iter(model, &iter, tree_path);

    /* get qmodelindex from iter and set the model data */
    QModelIndex idx = gtk_q_sort_filter_tree_model_get_source_idx(GTK_Q_SORT_FILTER_TREE_MODEL(model), &iter);
    if (idx.isValid()) {
        priv->account->codecModel()->audioCodecs()->setData(idx, QVariant(toggle), Qt::CheckStateRole);
    }
}

static void
move_selected_codec(AccountAudioTab *view, int position_diff)
{
    g_return_if_fail(IS_ACCOUNT_AUDIO_TAB(view));
    AccountAudioTabPrivate *priv = ACCOUNT_AUDIO_TAB_GET_PRIVATE(view);

    GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview_codecs));
    QModelIndex idx = get_index_from_selection(selection);

    if(!idx.isValid())
        return;

    QMimeData* mime = priv->account->codecModel()->audioCodecs()->mimeData(QModelIndexList() << idx);
    priv->account->codecModel()->audioCodecs()->dropMimeData(
                                                    mime,
                                                    Qt::MoveAction,
                                                    idx.row() + position_diff,
                                                    0,
                                                    QModelIndex());

    /* now make sure to select the same codec which was moved
     * TODO: UGLY! this should be somehow done in the qt modle bindings,
     *       or via a selection model, not here
     */
    int new_row = idx.row() + position_diff;
    int row_count = priv->account->codecModel()->audioCodecs()->rowCount(idx.parent());
    if (new_row < 0)
        new_row = row_count - 1;
    else if (new_row >= row_count)
        new_row = 0;

    idx = idx.sibling(new_row, idx.column());
    GtkTreeIter iter;
    if (gtk_q_sort_filter_tree_model_source_index_to_iter(
            GTK_Q_SORT_FILTER_TREE_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(priv->treeview_codecs))),
            idx,
            &iter)) {
        gtk_tree_selection_select_iter(selection, &iter);
    }
}

static void
move_codec_up(G_GNUC_UNUSED GtkButton *button, AccountAudioTab *view)
{
    move_selected_codec(view, -1);
}

static void
move_codec_down(G_GNUC_UNUSED GtkButton *button, AccountAudioTab *view)
{
    move_selected_codec(view, +1);
}

static void
build_tab_view(AccountAudioTab *view)
{
    g_return_if_fail(IS_ACCOUNT_AUDIO_TAB(view));
    AccountAudioTabPrivate *priv = ACCOUNT_AUDIO_TAB_GET_PRIVATE(view);

    /* codec model */
    GtkQSortFilterTreeModel *codec_model;
    GtkCellRenderer *renderer;
    GtkTreeViewColumn *column;

    codec_model = gtk_q_sort_filter_tree_model_new(
        priv->account->codecModel()->audioCodecs(),
        4,
        Qt::CheckStateRole, G_TYPE_BOOLEAN,
        CodecModel::Role::NAME, G_TYPE_STRING,
        CodecModel::Role::BITRATE, G_TYPE_STRING,
        CodecModel::Role::SAMPLERATE, G_TYPE_STRING);
    gtk_tree_view_set_model(GTK_TREE_VIEW(priv->treeview_codecs), GTK_TREE_MODEL(codec_model));

    renderer = gtk_cell_renderer_toggle_new();
    column = gtk_tree_view_column_new_with_attributes(_("Enabled"), renderer, "active", 0, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview_codecs), column);

    g_signal_connect(renderer, "toggled", G_CALLBACK(codec_active_toggled), view);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(C_("Name of the codec", "Name"), renderer, "text", 1, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview_codecs), column);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(_("Bitrate"), renderer, "text", 2, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview_codecs), column);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(_("Samplerate"), renderer, "text", 3, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview_codecs), column);

    /* connect move codecs up/down signals */
    g_signal_connect(priv->button_moveup, "clicked", G_CALLBACK(move_codec_up), view);
    g_signal_connect(priv->button_movedown, "clicked", G_CALLBACK(move_codec_down), view);
}

GtkWidget *
account_audio_tab_new(Account *account)
{
    g_return_val_if_fail(account != NULL, NULL);

    gpointer view = g_object_new(ACCOUNT_AUDIO_TAB_TYPE, NULL);

    AccountAudioTabPrivate *priv = ACCOUNT_AUDIO_TAB_GET_PRIVATE(view);
    priv->account = account;

    build_tab_view(ACCOUNT_AUDIO_TAB(view));

    return (GtkWidget *)view;
}
