/*
 *  Copyright (C) 2015-2017 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 <codecmodel.h>
#include "models/gtkqtreemodel.h"
#include <QtCore/QSortFilterProxyModel>
#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_tree_model_get_source_idx(GTK_Q_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_tree_model_source_index_to_iter(
            GTK_Q_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 */
    GtkQTreeModel *codec_model;
    GtkCellRenderer *renderer;
    GtkTreeViewColumn *column;

    codec_model = gtk_q_tree_model_new(
        priv->account->codecModel()->audioCodecs(),
        4,
        0, Qt::CheckStateRole, G_TYPE_BOOLEAN,
        0, CodecModel::Role::NAME, G_TYPE_STRING,
        0, CodecModel::Role::BITRATE, G_TYPE_STRING,
        0, 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;
}
