#include "dcantispamcontrol.h"
#include "dcconfig.h"
#include "dcantispam.h"

#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QLineEdit>
#include <QPushButton>

DCAntiSpamControl::DCAntiSpamControl(QWidget *parent) : QDialog(parent) {
    setupUi(this);

    InitDocument();
}

DCAntiSpamControl::~DCAntiSpamControl() {
    clearTreeWidget(treeWidget_WHITE);
    clearTreeWidget(treeWidget_BLACK);
    clearTreeWidget(treeWidget_BLACK);

    if (DCAntiSpam::Instance()) {
        DCAntiSpam::Instance()->saveLists();
        DCAntiSpam::Instance()->saveSettings();
    }
}

void DCAntiSpamControl::InitDocument() {
    if (DCConfig::Instance()->GetAntiSpamEnabled()) {
        if (!DCAntiSpam::Instance())
            DCAntiSpam::SetInstance(new DCAntiSpam());

        DCAntiSpam::Instance()->loadSettings();
        DCAntiSpam::Instance()->loadLists();

        checkBox_ASENABLE->setChecked(true);
    } else
        checkBox_ASENABLE->setChecked(false);

    loadGUIData();

    connect(checkBox_ASENABLE, SIGNAL(clicked()), this, SLOT(slotAntiSpamSwitch()));

    connect(pushButton_ADDWHITE, SIGNAL(clicked()), this, SLOT(slotAddToWhite()));
    connect(pushButton_ADDBLACK, SIGNAL(clicked()), this, SLOT(slotAddToBlack()));
    connect(pushButton_ADDGRAY, SIGNAL(clicked()), this, SLOT(slotAddToGray()));
    connect(pushButton_REMWHITE, SIGNAL(clicked()), this, SLOT(slotRemFromWhite()));
    connect(pushButton_REMBLACK, SIGNAL(clicked()), this, SLOT(slotRemFromBlack()));
    connect(pushButton_REMGRAY, SIGNAL(clicked()), this, SLOT(slotRemFromGray()));
    connect(pushButton_CLRWHITE, SIGNAL(clicked()), this, SLOT(slotClearWhite()));
    connect(pushButton_CLRBLACK, SIGNAL(clicked()), this, SLOT(slotClearBlack()));
    connect(pushButton_CLRGRAY, SIGNAL(clicked()), this, SLOT(slotClearGray()));

    connect(pushButton_OK, SIGNAL(clicked()), this, SLOT(slotAccept()));

    connect(pushButton_WTOG, SIGNAL(clicked()), this, SLOT(slotWToG()));
    connect(pushButton_WTOB, SIGNAL(clicked()), this, SLOT(slotWToB()));
    connect(pushButton_BTOW, SIGNAL(clicked()), this, SLOT(slotBToW()));
    connect(pushButton_BTOG, SIGNAL(clicked()), this, SLOT(slotBToG()));
    connect(pushButton_GTOB, SIGNAL(clicked()), this, SLOT(slotGToB()));
    connect(pushButton_GTOW, SIGNAL(clicked()), this, SLOT(slotGToW()));

    slotAntiSpamSwitch();
}

void DCAntiSpamControl::slotAntiSpamSwitch() {
    bool b = checkBox_ASENABLE->isChecked();

    DCConfig::Instance()->SetAntiSpamEnabled(b);

    groupBox_WHITE->setEnabled(b);
    groupBox_BLACK->setEnabled(b);
    groupBox_GRAY->setEnabled(b);

    groupBox_PHRASE->setEnabled(b);

    pushButton_WTOG->setEnabled(b);
    pushButton_WTOB->setEnabled(b);
    pushButton_BTOW->setEnabled(b);
    pushButton_BTOG->setEnabled(b);
    pushButton_GTOB->setEnabled(b);
    pushButton_GTOW->setEnabled(b);

    if (!b && DCAntiSpam::Instance()) {
        DCAntiSpam::Instance()->setAttempts(spinBox_TRYCOUNT->value());
        DCAntiSpam::Instance()->saveSettings();
        DCAntiSpam::Instance()->saveLists();

        delete DCAntiSpam::Instance();

        DCAntiSpam::SetInstance(NULL);
    } else if (b && (DCAntiSpam::Instance() == NULL)) {
        DCAntiSpam::SetInstance(new DCAntiSpam());

        DCAntiSpam::Instance()->loadSettings();
        DCAntiSpam::Instance()->loadLists();

        loadGUIData();
    }
}

void DCAntiSpamControl::loadGUIData() {
    if (DCAntiSpam::Instance()) {
        lineEdit_PHRASE->setText(DCAntiSpam::Instance()->getPhrase());

        spinBox_TRYCOUNT->setValue(DCAntiSpam::Instance()->getAttempts());

	QList<QString> keys = DCAntiSpam::Instance()->getKeys();
	QString words = "";

	for (int i = 0; i < keys.size(); i++)
	    words += keys.at(i) + "|";

        if (words.right(1) == "|")
            words = words.left(words.length()-1);

	lineEdit_KEY->setText(words);

        loadBlackList();
        loadGrayList();
        loadWhiteList();

    }
}

void DCAntiSpamControl::loadBlackList() {
    QList<QString> list = DCAntiSpam::Instance()->getBlack();
    loadList(treeWidget_BLACK, list);
}

void DCAntiSpamControl::loadGrayList() {
    QList<QString> list = DCAntiSpam::Instance()->getGray();
    loadList(treeWidget_GRAY, list);
}

void DCAntiSpamControl::loadWhiteList() {
    QList<QString> list = DCAntiSpam::Instance()->getWhite();
    loadList(treeWidget_WHITE, list);
}

void DCAntiSpamControl::loadList(QTreeWidget *tree, QList<QString> &list) {
    if (!tree)
        return;

    clearTreeWidget(tree);

    for (int i = 0; i < list.size(); i++) {
        QTreeWidgetItem *it = new QTreeWidgetItem(tree);

        it->setText(0, list.at(i));
    }
}

void DCAntiSpamControl::clearTreeWidget(QTreeWidget *tree) {
    QTreeWidgetItemIterator it(tree, QTreeWidgetItemIterator::NotHidden);

    while (*it) {
        if (*it)
            delete *it;
        ++it;
    }

    tree->clear();
}

bool DCAntiSpamControl::addToList(AntiSpamObjectState state, QString nick) {
    if (nick == "")
        return false;

    if (!DCAntiSpam::Instance())
        return false;

    if (DCAntiSpam::Instance()->isInAny(nick)) {//nick already in lists
        AntiSpamObjectState e;

        if (DCAntiSpam::Instance()->isInBlack(nick))
            e = eIN_BLACK;
        else if (DCAntiSpam::Instance()->isInGray(nick))
            e = eIN_GRAY;
        else
            e = eIN_WHITE;

        if (e == state)//in some list
            return false;

        DCAntiSpam::Instance()->move(nick, state);

        QTreeWidget *tree = NULL;

        switch (e) {
            case eIN_BLACK:
                tree = treeWidget_BLACK;
                break;
            case eIN_GRAY:
                tree = treeWidget_GRAY;
                break;
            case eIN_WHITE:
                tree = treeWidget_WHITE;
                break;
        }
        remItemFromTree(tree, nick);

        tree = NULL;
        switch (state) {
            case eIN_BLACK:
                tree = treeWidget_BLACK;
                break;
            case eIN_GRAY:
                tree = treeWidget_GRAY;
                break;
            case eIN_WHITE:
                tree = treeWidget_WHITE;
                break;
        }
        addItemToTree(tree, nick);

        return true;
    }

    QTreeWidget *tree = NULL;

    switch (state) {
        case eIN_BLACK:
            DCAntiSpam::Instance()->addToBlack(QList<QString > () << nick);
            tree = treeWidget_BLACK;
            break;
        case eIN_GRAY:
            DCAntiSpam::Instance()->addToGray(QList<QString > () << nick);
            tree = treeWidget_GRAY;
            break;
        case eIN_WHITE:
            DCAntiSpam::Instance()->addToWhite(QList<QString > () << nick);
            tree = treeWidget_WHITE;
    }

    addItemToTree(tree, nick);

    return true;
}

void DCAntiSpamControl::addItemToTree(QTreeWidget *tree, QString text) {
    if (tree == NULL || text == "")
        return;

    QTreeWidgetItem *it = new QTreeWidgetItem(tree);

    it->setText(0, text);
}

void DCAntiSpamControl::remItemFromTree(QTreeWidget *tree, QString text) {
    if (tree == NULL || text == "")
        return;

    QTreeWidgetItemIterator it(tree, QTreeWidgetItemIterator::NotHidden);

    while (*it) {
        if ((*it)->text(0) == text) {
            tree->removeItemWidget(*it, 0);

            delete (*it);

            tree->repaint();

            break;
        }
        ++it;
    }
}

void DCAntiSpamControl::slotAddToBlack() {
    addToList(eIN_BLACK, lineEdit_BLACK->text());
    lineEdit_BLACK->setText("");
    lineEdit_BLACK->setFocus();
}

void DCAntiSpamControl::slotAddToGray() {
    addToList(eIN_GRAY, lineEdit_GRAY->text());
    lineEdit_GRAY->setText("");
    lineEdit_GRAY->setFocus();
}

void DCAntiSpamControl::slotAddToWhite() {
    addToList(eIN_WHITE, lineEdit_WHITE->text());
    lineEdit_WHITE->setText("");
    lineEdit_WHITE->setFocus();
}

void DCAntiSpamControl::slotClearBlack() {
    clearTreeWidget(treeWidget_BLACK);

    if (DCAntiSpam::Instance())
        DCAntiSpam::Instance()->clearBlack();
}

void DCAntiSpamControl::slotClearGray() {
    clearTreeWidget(treeWidget_GRAY);

    if (DCAntiSpam::Instance())
        DCAntiSpam::Instance()->clearGray();
}

void DCAntiSpamControl::slotClearWhite() {
    clearTreeWidget(treeWidget_WHITE);

    if (DCAntiSpam::Instance())
        DCAntiSpam::Instance()->clearWhite();
}

void DCAntiSpamControl::slotRemFromBlack() {
    QTreeWidgetItem *it = treeWidget_BLACK->currentItem();

    if (it) {
        QString nick = it->text(0);

        remItemFromTree(treeWidget_BLACK, nick);

        if (DCAntiSpam::Instance())
            DCAntiSpam::Instance()->remFromBlack(QList<QString > () << nick);
    }
}

void DCAntiSpamControl::slotRemFromGray() {
    QTreeWidgetItem *it = treeWidget_GRAY->currentItem();

    if (it) {
        QString nick = it->text(0);

        remItemFromTree(treeWidget_GRAY, nick);

        if (DCAntiSpam::Instance())
            DCAntiSpam::Instance()->remFromGray(QList<QString > () << nick);
    }
}

void DCAntiSpamControl::slotRemFromWhite() {
    QTreeWidgetItem *it = treeWidget_WHITE->currentItem();

    if (it) {
        QString nick = it->text(0);

        remItemFromTree(treeWidget_WHITE, nick);

        if (DCAntiSpam::Instance())
            DCAntiSpam::Instance()->remFromWhite(QList<QString > () << nick);
    }
}

void DCAntiSpamControl::slotAccept() {
    if (!DCAntiSpam::Instance()) {
        accept();
        return;
    }

    QString phrase = lineEdit_PHRASE->text();
    QList<QString> keys = lineEdit_KEY->text().split("|");

    for (int i = 0; i < keys.size(); i++){
	if (keys.at(i) == ""){
	    keys.removeAt(i);
	    i = 0;
	}
    }

    DCAntiSpam::Instance()->setPhrase(phrase);
    DCAntiSpam::Instance()->setKeys(keys);
    DCAntiSpam::Instance()->setAttempts(spinBox_TRYCOUNT->value());

    accept();
}

void DCAntiSpamControl::slotWToG() {
    QTreeWidgetItem *it = treeWidget_WHITE->currentItem();

    if (it) {
        QString nick = it->text(0);

        addToList(eIN_GRAY, nick);
    }
}

void DCAntiSpamControl::slotWToB() {
    QTreeWidgetItem *it = treeWidget_WHITE->currentItem();

    if (it) {
        QString nick = it->text(0);

        addToList(eIN_BLACK, nick);
    }
}

void DCAntiSpamControl::slotBToW() {
    QTreeWidgetItem *it = treeWidget_BLACK->currentItem();

    if (it) {
        QString nick = it->text(0);

        addToList(eIN_WHITE, nick);
    }
}

void DCAntiSpamControl::slotBToG() {
    QTreeWidgetItem *it = treeWidget_BLACK->currentItem();

    if (it) {
        QString nick = it->text(0);

        addToList(eIN_GRAY, nick);
    }
}

void DCAntiSpamControl::slotGToB() {
    QTreeWidgetItem *it = treeWidget_GRAY->currentItem();

    if (it) {
        QString nick = it->text(0);

        addToList(eIN_BLACK, nick);
    }
}

void DCAntiSpamControl::slotGToW() {
    QTreeWidgetItem *it = treeWidget_GRAY->currentItem();

    if (it) {
        QString nick = it->text(0);

        addToList(eIN_WHITE, nick);
    }
}
