/* -*- c++ -*-
 *
 * statspageovernet.cpp
 *
 * Copyright (C) 2003 Sebastian Sauer <mail@dipe.org>
 *
 * 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 Steet, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#include <qlabel.h>
#include <qvbox.h>
#include <qsplitter.h>
#include <qscrollview.h>
#include <qregexp.h>

#include <kdebug.h>
#include <klocale.h>
#include <klistview.h>
#include <ktextbrowser.h>

#include "kmldonkey.h"
#include "donkeyprotocol.h"
#include "prefs.h"

#include "statspageovernet.h"
#include "statspageovernet.moc"

void StatsPageOvernetCallback::callback(const QString& cmd, const QString& res)
{
    if (! page) return;
    if (! page->box) {
        page->box = new QVBox();
        page->addChild(page->box);
        page->box->show();
    }

    if (cmd.endsWith("md4"))
        page->parseOvmd4(res);
    if (cmd.endsWith("stats"))
        page->parseOvstat(res);
    else if (cmd.endsWith("store"))
        page->parseOvstore(res);
}

StatsPageOvernet::StatsPageOvernet(QWidget *parent) : QScrollView(parent)
{
    setResizePolicy(QScrollView::AutoOneFit);
    viewport()->setBackgroundMode(PaletteBackground);
    box = 0;
    callback = 0;
}

void StatsPageOvernet::parseOvmd4(const QString &res)
{
    addItem(res);
}

void StatsPageOvernet::parseOvstat(const QString &res)
{
    KListView *view;
    KListView *viewFile = 0;
    KListView *viewKeyword = 0;
    KTextBrowser *browser = 0;

    int count, pos;
    QString s, t;
    QStringList values;
    QStringList list = QStringList::split("\n", res);
    for (QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
        s = *it;

        QRegExp rx("^Search (file|keyword) for[\\s]*([a-zA-Z0-9]+)[\\s]*\\((.*)\\).*");
        if (rx.search(s) >= 0) {
            if(rx.cap(1) == "file") {
                if (! viewFile) {
                    viewFile = new KListView(box);
                    viewFile->addColumn(i18n("Search filehash"));
                    viewFile->show();
                }
                view = viewFile;
            }
            else {
                if (! viewKeyword) {
                    viewKeyword = new KListView(box);
                    viewKeyword->addColumn(i18n("Search keyword"));
                    viewKeyword->show();
                }
                view = viewKeyword;
            }
            KListViewItem *item = new KListViewItem(view);
            item->setText(0, rx.cap(2));
            values = QStringList::split(",", rx.cap(3));
            count = 1;
            for (QStringList::Iterator it = values.begin(); it != values.end(); ++it) {
                s = (*it).stripWhiteSpace();
                t = QString("");
                pos = s.find(" ");
                if (pos > 0) {
                    t = s.mid(pos + 1, s.length() - pos - 1).replace("_", " ").stripWhiteSpace();
                    s = s.remove(pos, s.length() - pos).stripWhiteSpace();
                }
                if (view->columns() <= count)
                    view->addColumn(t);
                item->setText(count, s);
                count++;
            }
            continue;
        }

        if (s.isEmpty() || s.startsWith("Overnet statistics")) continue;

        QRegExp rxHits("(Search|Source)[\\s]+hits[\\s]*:(.*)");
        if (rxHits.search(s) >= 0) {
            if (rxHits.cap(1).startsWith("Se"))
                addItem( i18n("Search hits: %1").arg(rxHits.cap(2).stripWhiteSpace()) );
            else
                addItem( i18n("Source hits: %1").arg(rxHits.cap(2).stripWhiteSpace()) );
            continue;
        }

        if (! browser) {
            browser = new KTextBrowser(box);
            //browser->setMinimumHeight(60);
            browser->setTextFormat(QTextBrowser::RichText);
            browser->show();
        }
        browser->append( s );
    }
}

void StatsPageOvernet::parseOvstore(const QString &res)
{
    QString s;
    QStringList list = QStringList::split("\n", res);
    for (QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
        s = (*it).stripWhiteSpace();
        if (s.isEmpty() || s.startsWith("Overnet store")) continue;

        QRegExp rx("^size[\\s]*\\=[\\s]*([0-9]+)[\\s]*\\,[\\s]*max_size[\\s]*\\=[\\s]*([0-9]+).*");
        if(rx.search(s) >= 0) {
            addItem(i18n("Size: %1").arg(rx.cap(1)));
            addItem(i18n("Max size: %1").arg(rx.cap(2)));
        }
        else {
            /*TODO
            md4=F665E93FA8785A7A698EC5E56C0164EF, files =
            r_md4=815DD38583ADE072D70C32A21DF96D32
            tags=loc = "bcp://813dd385a85df092d70c32ea25df86832:212.212.22.2:8080"
            */
        }
    }
}

void StatsPageOvernet::addItem(QString text)
{
    if (! box) return;
    QHBox *hbox = new QHBox(box);
    hbox->setMargin(3);
    new QLabel(text.stripWhiteSpace(), hbox);
    hbox->show();
}

void StatsPageOvernet::slotUpdate()
{
    if (! KMLDonkey::App->donkey->isConnected()) return;
    if (! callback) {
        callback = new StatsPageOvernetCallback;
        callback->page = this;
    }

    //FIXME cause of bug http://bugs.kde.org/show_bug.cgi?id=87123
    //      we just send both kind of messages. That's not nice and
    //      3 of them will fail, but it's so far the easiest way
    //      to get right of those (let us name it stupid) change
    //      of the commandnames.
    //      We may like to remove the first 3 ones if older
    //      cores (< 2.5.23/2.6pre5, tag release-2-5-23) arn't
    //      supported any longer.
    KMLDonkey::App->donkey->sendConsoleMessage("ovmd4", callback);
    KMLDonkey::App->donkey->sendConsoleMessage("ovstats", callback);
    KMLDonkey::App->donkey->sendConsoleMessage("ovstore", callback);

    KMLDonkey::App->donkey->sendConsoleMessage("ov_md4", callback);
    KMLDonkey::App->donkey->sendConsoleMessage("ov_stats", callback);
    KMLDonkey::App->donkey->sendConsoleMessage("ov_store", callback);
}

void StatsPageOvernet::showEvent(QShowEvent* /*event*/)
{
    slotUpdate();
}

void StatsPageOvernet::hideEvent(QHideEvent* /*event*/)
{
    delete box;
    box = 0;
}
