/***************************************************************************
                          dcspy.cpp  -  description
                             -------------------
    begin                : Fre Nov 8 2002
    copyright            : (C) 2002 by Mathias Küster
    email                : mathen@users.berlios.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "dcspy.h"

#include <QCheckBox>
#include <QPushButton>
#include <QLabel>
#include <QDateTime>
#include <QApplication>
#include <QCursor>
#include <QClipboard>

#include <QMdiArea>
#include <QMdiSubWindow>

#include "dcconfig.h"
#include "dciconloader.h"
#include "dcmenuhandler.h"

#include "searchspymodel.h"

#include <dclib/dcobject.h>
#include <dclib/cquerymanager.h>

#include "dcguiutils.h"

/** */
DCSpy *DCSpy::pSpy = NULL;

/** */
DCSpy::DCSpy(QWidget * parent) : QWidget(parent) {
    setupUi(this);

    // set default icon
    setWindowIcon(DCIconLoader::Instance()->GetPixmap(eiSPY));

    /* Sort A-Z by default not Z-A, no idea why QT default seems strange */
    TreeView_SPY->sortByColumn(0, Qt::AscendingOrder);

    model = new SearchSpyModel(this);
    TreeView_SPY->setModel(model);

    if (parent && qobject_cast<QMdiArea*>(parent)) {
        m_pContainerWindow = new QMdiSubWindow();
        m_pContainerWindow->setWidget(this);
    } else {
        m_pContainerWindow = 0;
    }

    InitDocument();
}

/** */
DCSpy::~DCSpy() {
    /* model(s) are deleted automatically */

    m_Timer.stop();

    if (m_pContainerWindow) {
        m_pContainerWindow->setWidget(0); // otherwise the QMdiSubWindow will delete this again
        delete m_pContainerWindow;
        m_pContainerWindow = 0;
    }
}

/** */
void DCSpy::InitDocument() {
    StringMap * map;

    // restore settings
    if (DCConfig::Instance()->GetMap("SPYVIEW", map)) {
        if (((*map)["WIDTH"].toInt() > 0) && ((*map)["HEIGHT"].toInt() > 0)) {
            if (m_pContainerWindow != 0) {
                m_pContainerWindow->setGeometry((*map)["X"].toInt(), (*map)["Y"].toInt(), (*map)["WIDTH"].toInt(), (*map)["HEIGHT"].toInt());
            }
        }

        if ((*map)["CHECKED"] == "1") {
            CheckBox_ENABLESPY->setChecked(true);
        }

        if ((*map)["HIDETTH"] == "1") {
            CheckBox_HIDETTH->setChecked(true);
        }

        if (map->contains("SORTCOLUMN") && map->contains("SORTORDER")) {
            TreeView_SPY->sortByColumn(map->value("SORTCOLUMN").toInt(), DCGuiUtils::SortOrderFromName(map->value("SORTORDER")));
        }
    }

    connect(PushButton_CLEAR, SIGNAL(clicked()), model, SLOT(clear()));

    connect(&m_Timer, SIGNAL(timeout()), this, SLOT(timerDone()));

    connect(TreeView_SPY, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(slotContextMenuSpy(const QPoint &)));

    TreeView_SPY->setAlternatingRowColors(DCConfig::Instance()->GetAlternatingRowColors());
    connect(DCConfig::Instance(), SIGNAL(alternatingRowColorsChanged(bool)), this, SLOT(slotAltRowColors(bool)));

    m_Timer.setSingleShot(true);
    m_Timer.start(1000);
}

/** */
void DCSpy::DeInitDocument() {
    StringMap * map;

    // save search view settings
    DCConfig::Instance()->GetMap("SPYVIEW", map);

    if (m_pContainerWindow) {
        (*map)["X"] = QString().setNum(m_pContainerWindow->x());
        (*map)["Y"] = QString().setNum(m_pContainerWindow->y());
        (*map)["WIDTH"] = QString().setNum(m_pContainerWindow->width());
        (*map)["HEIGHT"] = QString().setNum(m_pContainerWindow->height());
        (*map)["VISIBLE"] = QString().setNum(m_pContainerWindow->isVisible());
        (*map)["MAXIMIZED"] = QString().setNum(m_pContainerWindow->isMaximized());
        (*map)["MINIMIZED"] = QString().setNum(m_pContainerWindow->isMinimized());
    }
    (*map)["CHECKED"] = QString().setNum(CheckBox_ENABLESPY->isChecked());
    (*map)["HIDETTH"] = QString().setNum(CheckBox_HIDETTH->isChecked());

    (*map)["SORTCOLUMN"] = QString::number(model->getSortColumn());
    (*map)["SORTORDER"] = DCGuiUtils::SortOrderName(model->getSortOrder());
}

/** */
void DCSpy::timerDone() {
    if (CQueryManager::Instance()) {
        // update search stat
        TextLabel_SEARCHCOUNTACTIVE->setText(QString().setNum(CQueryManager::Instance()->GetStat(essCOUNTACTIVE)));
        TextLabel_SEARCHCOUNTPASSIVE->setText(QString().setNum(CQueryManager::Instance()->GetStat(essCOUNTPASSIVE)));
        TextLabel_SEARCHCOUNTREJECT->setText(QString().setNum(CQueryManager::Instance()->GetStat(essCOUNTREJECT)));
        TextLabel_SEARCHCOUNTERROR->setText(QString().setNum(CQueryManager::Instance()->GetStat(essCOUNTERROR)));
        TextLabel_RESULTCOUNT->setText(QString().setNum(CQueryManager::Instance()->GetStat(essRESULTCOUNT)));
        TextLabel_RESULTCOUNTERROR->setText(QString().setNum(CQueryManager::Instance()->GetStat(essRESULTCOUNTERROR)));
    }

    m_Timer.setSingleShot(true);
    m_Timer.start(1000);
}

/** search */
void DCSpy::DC_Search(CMessageSearchFile * MessageSearch) {
    if (CheckBox_ENABLESPY->isChecked()) {
        QString s = QString::fromAscii(MessageSearch->m_sString.Data());

        if (MessageSearch->m_eFileType == eftHASH) {
            if (CheckBox_HIDETTH->isChecked()) {
                return;
            }
            s.prepend("TTH:");
        } else {
            s = s.toLower();
        }

        model->search(s);
    }
}

/** */
void DCSpy::slotContextMenuSpy(const QPoint & /* point */) {
    QModelIndexList list = TreeView_SPY->selectionModel()->selectedIndexes();
    if (list.isEmpty()) {
        return;
    }

    QVariant data = TreeView_SPY->model()->data(list.first());

    QMenu * m = new QMenu(this);
    QAction * copy = DCMenuHandler::addAction(m, emiCOPY);

    QAction * chosen = m->exec(QCursor::pos());

    delete m;

    if (chosen == copy) {
        QApplication::clipboard()->setText(data.toString());
    }
}

/** */
void DCSpy::closeEvent(QCloseEvent * e) {
    emit onDie(this);

    QWidget::closeEvent(e);

    if (m_pContainerWindow && m_pContainerWindow->parent()) {
        /* Using QMdiArea::removeSubWindow() breaks tabs mode but this works */
        m_pContainerWindow->setParent(0);
    }
}

/** */
void DCSpy::slotAltRowColors(bool enable) {
    TreeView_SPY->setAlternatingRowColors(enable);
}
