/*
 *   This file is part of Dianara
 *   Copyright 2012-2016  JanKusanagi JRR <jancoding@gmx.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 2 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 "filtereditor.h"

FilterEditor::FilterEditor(FilterChecker *filterChecker,
                           QWidget *parent) : QWidget(parent)
{
    this->fChecker = filterChecker;

    this->setWindowTitle(tr("Filter Editor") + " - Dianara");
    this->setWindowIcon(QIcon::fromTheme("view-filter",
                                         QIcon(":/images/button-filter.png")));
    this->setWindowFlags(Qt::Dialog);
    this->setWindowModality(Qt::ApplicationModal);
    this->setMinimumSize(520, 400);


    ruleString = tr("%1 if %2 contains: %3",
                    "This explains a filter rule, like: "
                    "Hide if Author ID contains JohnDoe");

    QFont explanationFont;
    explanationFont.setPointSize(explanationFont.pointSize() - 1);

    explanationLabel = new QLabel(tr("Here you can set some rules for hiding or "
                                     "highlighting stuff. "
                                     "You can filter by content, author "
                                     "or application.\n\n"
                                     "For instance, you can filter out messages posted by "
                                     "the application Open Farm Game, or which contain the "
                                     "word NSFW in the message. You could also highlight "
                                     "messages that contain your name.")
                                  + "\n",
                                  this);
    explanationLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);
    explanationLabel->setWordWrap(true);
    explanationLabel->setFont(explanationFont);


    actionTypeComboBox = new QComboBox(this);
    actionTypeComboBox->addItem(QIcon::fromTheme("edit-delete",
                                                 QIcon(":/images/button-delete.png")),
                                tr("Hide"));
    actionTypeComboBox->addItem(QIcon::fromTheme("format-fill-color",
                                                 QIcon(":/images/button-online.png")),
                                tr("Highlight"));
    actionTypeComboBox->setCurrentIndex(1); // #2 option (highlight) as default

    filterTypeComboBox = new QComboBox(this);
    filterTypeComboBox->addItem(QIcon::fromTheme("accessories-text-editor",
                                                 QIcon(":/images/button-edit.png")),
                                tr("Post Contents"));
    filterTypeComboBox->addItem(QIcon::fromTheme("user-identity",
                                                 QIcon(":/images/no-avatar.png")),
                                tr("Author ID"));
    filterTypeComboBox->addItem(QIcon::fromTheme("applications-other",
                                                 QIcon(":/images/button-configure.png")),
                                tr("Application"));
    filterTypeComboBox->addItem(QIcon::fromTheme("accessories-text-editor",
                                                 QIcon(":/images/button-edit.png")),
                                tr("Activity Description"));

    filterWordsLineEdit = new QLineEdit(this);
    filterWordsLineEdit->setPlaceholderText(tr("Keywords..."));

    addFilterButton = new QPushButton(QIcon::fromTheme("list-add",
                                                       QIcon(":/images/list-add.png")),
                                      tr("&Add Filter"),
                                      this);
    addFilterButton->setDisabled(true);
    connect(addFilterButton, SIGNAL(clicked()),
            this, SLOT(addFilter()));
    connect(filterWordsLineEdit, SIGNAL(returnPressed()),
            this, SLOT(addFilter()));
    connect(filterWordsLineEdit, SIGNAL(textChanged(QString)),
            this, SLOT(onFilterTextChanged(QString)));



    currentFiltersListWidget = new QListWidget(this);
    currentFiltersListWidget->setToolTip(tr("Filters in use"));
    currentFiltersListWidget->setDragDropMode(QAbstractItemView::InternalMove);


    removeFilterButton = new QPushButton(QIcon::fromTheme("list-remove",
                                                          QIcon(":/images/list-remove.png")),
                                         tr("&Remove Selected Filter"),
                                         this);
    removeFilterButton->setDisabled(true);
    connect(removeFilterButton, SIGNAL(clicked()),
            this, SLOT(removeFilter()));
    connect(currentFiltersListWidget, SIGNAL(currentRowChanged(int)),
            this, SLOT(onFilterRowChanged(int)));


    saveButton = new QPushButton(QIcon::fromTheme("document-save",
                                                  QIcon(":/images/button-save.png")),
                                 tr("&Save Filters"),
                                 this);
    connect(saveButton, SIGNAL(clicked()),
            this, SLOT(saveFilters()));

    cancelButton = new QPushButton(QIcon::fromTheme("dialog-cancel",
                                                    QIcon(":/images/button-cancel.png")),
                                   tr("&Cancel"),
                                   this);
    connect(cancelButton, SIGNAL(clicked()),
            this, SLOT(hide()));

    closeAction = new QAction(this);
    closeAction->setShortcut(QKeySequence(Qt::Key_Escape));
    connect(closeAction, SIGNAL(triggered()),
            this, SLOT(hide()));
    this->addAction(closeAction);

    // Layout
    topLayout = new QHBoxLayout();
    topLayout->addWidget(actionTypeComboBox);
    topLayout->addSpacing(2);
    topLayout->addWidget(new QLabel(tr("if"), this));
    topLayout->addSpacing(2);
    topLayout->addWidget(filterTypeComboBox);
    topLayout->addSpacing(2);
    topLayout->addWidget(new QLabel(tr("contains"), this));
    topLayout->addSpacing(2);
    topLayout->addWidget(filterWordsLineEdit, 1);
    topLayout->addSpacing(8);
    topLayout->addWidget(addFilterButton);

    newFilterGroupBox = new QGroupBox(tr("&New Filter"), this);
    newFilterGroupBox->setLayout(topLayout);

    middleLayout = new QVBoxLayout();
    middleLayout->addWidget(currentFiltersListWidget);
    middleLayout->addWidget(removeFilterButton, 0, Qt::AlignRight);

    currentFiltersGroupBox = new QGroupBox(tr("C&urrent Filters"), this);
    currentFiltersGroupBox->setLayout(middleLayout);


    bottomLayout = new QHBoxLayout();
    bottomLayout->setAlignment(Qt::AlignRight);
    bottomLayout->addWidget(saveButton);
    bottomLayout->addWidget(cancelButton);

    mainLayout = new QVBoxLayout();
    mainLayout->addWidget(explanationLabel);
    mainLayout->addSpacing(8);
    mainLayout->addWidget(newFilterGroupBox);
    mainLayout->addSpacing(8);
    mainLayout->addWidget(currentFiltersGroupBox);
    mainLayout->addSpacing(16);
    mainLayout->addLayout(bottomLayout);
    this->setLayout(mainLayout);


    loadFilters();

    qDebug() << "FilterEditor created";
}


FilterEditor::~FilterEditor()
{
    qDebug() << "FilterEditor destroyed";
}


void FilterEditor::loadFilters()
{
    QSettings settings;
    this->filtersList = settings.value("Filters/currentFilters").toList();

    foreach (QVariant filterItem, filtersList)
    {
        int actionType = filterItem.toMap().value("action").toInt();
        int filterType = filterItem.toMap().value("type").toInt();
        QString filterWords = filterItem.toMap().value("text").toString();

        QVariantMap itemMap;
        itemMap.insert("action", actionType);
        itemMap.insert("type",   filterType);
        itemMap.insert("text",   filterWords);

        QListWidgetItem *item = new QListWidgetItem(ruleString
                                                    .arg(actionTypeComboBox->itemText(actionType))
                                                    .arg("'" + filterTypeComboBox->itemText(filterType) + "'")
                                                    .arg("  " + filterWords));
        item->setData(Qt::UserRole, itemMap);

        this->currentFiltersListWidget->addItem(item);
    }

    // Let the FilterChecker know
    this->fChecker->setFilters(filtersList);
}



/****************************************************************************/
/********************************* SLOTS ************************************/
/****************************************************************************/



void FilterEditor::onFilterTextChanged(QString text)
{
    this->addFilterButton->setDisabled(text.isEmpty());
}


void FilterEditor::onFilterRowChanged(int row)
{
    this->removeFilterButton->setEnabled(row != -1);
}



void FilterEditor::addFilter()
{
    QString words = this->filterWordsLineEdit->text().trimmed();
    if (words.isEmpty())
    {
        return;
    }

    QVariantMap itemMap;
    itemMap.insert("action", actionTypeComboBox->currentIndex());
    itemMap.insert("type",   filterTypeComboBox->currentIndex());
    itemMap.insert("text",   words);

    QListWidgetItem *item = new QListWidgetItem(ruleString
                                                .arg(actionTypeComboBox->currentText())
                                                .arg("'" + filterTypeComboBox->currentText() + "'")
                                                .arg("  " + words));
    item->setData(Qt::UserRole, itemMap);

    currentFiltersListWidget->addItem(item);
    currentFiltersListWidget->setCurrentRow(currentFiltersListWidget->count() - 1);


    filterWordsLineEdit->clear();
}


void FilterEditor::removeFilter()
{
    int selectedFilter = currentFiltersListWidget->currentRow();
    qDebug() << "FilterEditor::removeFilter()" << selectedFilter;

    if (selectedFilter != -1)
    {
        QListWidgetItem *removedItem = currentFiltersListWidget->takeItem(selectedFilter);
        delete removedItem;
    }
}


void FilterEditor::saveFilters()
{
    qDebug() << "FilterEditor::saveFilters()";

    filtersList.clear();

    for (int counter = 0; counter != currentFiltersListWidget->count(); ++counter)
    {
        QListWidgetItem *item = currentFiltersListWidget->item(counter);
        filtersList.append(item->data(Qt::UserRole)); // item->data() holds a QVariantMap with the filter
    }

    qDebug() << "filtersList: " << this->filtersList;

    QSettings settings;
    settings.setValue("Filters/currentFilters", filtersList);

    // Send to the FilterChecker too
    this->fChecker->setFilters(filtersList);

    this->hide();
}

