/* -*- c++ -*-
 *
 * statspageclients.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 <qvgroupbox.h>
#include <qscrollview.h>
#include <qpainter.h>

#include <kdebug.h>
#include <kglobalsettings.h>
#include <ktextbrowser.h>

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

#include "statspageclients.h"
#include "statspageclients.moc"

ClientsPieWidget::ClientsPieWidget(QWidget *parent) : QFrame(parent)
{
    //setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    //setBackgroundColor(Qt::white /*parent->paletteBackgroundColor()*/);
}

void ClientsPieWidget::addValue(const QString& label, const double value, QColor color)
{
    ClientsPieWidgetObject* obj = new ClientsPieWidgetObject();
    obj->label = label;
    obj->value = value;
    obj->color = color;
    values.append(obj);
}

void ClientsPieWidget::paintEvent(QPaintEvent*)
{
    QPixmap pixmap(width(), height());
    QPainter painter;
    painter.begin(&pixmap, this);

    painter.setClipRect(2, 2, width() - 4, height() - 4);
    pixmap.fill(paletteBackgroundColor());

    if (values.count() > 1) { // at least 2 values should be there to display a pie
        QFontMetrics fontmet( KGlobalSettings::generalFont() );

        int startpos = -1440; //-90*16
        int alen;
        int labelpos = fontmet.height() + 2;

        QValueList<ClientsPieWidgetObject*>::iterator it;
        for (it = values.begin(); it != values.end(); ++it) {
            alen = (int)( (*it)->value * 57.6 );

            painter.setBrush( (*it)->color );
            painter.setPen( (*it)->color );

            painter.drawPie(2 + 130, 2, width() - 4 - 130, height() - 4, startpos, alen);
            startpos += alen;

            painter.drawText(2, labelpos, (*it)->label);
            labelpos += fontmet.height() + 2;
        }
    }

    painter.end();
    bitBlt(this, 0, 0, &pixmap);
}

StatsPageClientsCallback::StatsPageClientsCallback()
{
    colorsList.append( Qt::blue );
    colorsList.append( Qt::darkBlue );
    colorsList.append( Qt::darkMagenta );
    colorsList.append( Qt::darkGreen );
    colorsList.append( Qt::red );
    colorsList.append( Qt::darkCyan );
    colorsList.append( Qt::darkRed );
    colorsList.append( Qt::darkYellow );
    //colorsList.append( Qt::green );

    colorsListIterator = colorsList.begin();
}

StatsPageClientsCallback::~StatsPageClientsCallback()
{
}

void StatsPageClientsCallback::callback(const QString& /*cmd*/, const QString& res)
{
    if (! page) return;
    delete page->box;
    page->box = new QVBox();
    page->box->setSpacing(6);
    page->box->setMargin(11);
    page->addChild(page->box);
    page->box->show();

    QStringList groups = QStringList::split("\n\n", res);
    QStringList list;
    int pos, count;
    QString label, value;
    QVGroupBox *grpBox;
    QHBox *hbox;
    QVBox *vbox;
    ClientsPieWidget *pie = 0;

    for (QStringList::Iterator groupit = groups.begin(); groupit != groups.end(); ++groupit) {
        list = QStringList::split("\n", *groupit);
        grpBox = new QVGroupBox(page->box);
        hbox = new QHBox(grpBox);
        vbox = new QVBox(hbox);
        vbox->setSpacing(6);
        count = 0;

        for (QStringList::Iterator listit = list.begin(); listit != list.end(); ++listit) {
            pos = (*listit).find(":");
            if (pos > 0) {
                label = (*listit).left(pos + 1).stripWhiteSpace();
                value = (*listit).right((*listit).length() - pos - 1).stripWhiteSpace();
                if (label.isEmpty()) continue;

                if (count == 0) {
                    grpBox->setTitle( label.left(label.length() - 1).stripWhiteSpace() );
                }
                else {
                    int p1 = value.find("(");
                    int p2 = value.find("%", p1);
                    int p3 = value.find(")", p2);
                    if (p3 > p2 && p2 > p1 && p1 > 0) {
                        bool ok;
                        double pv = value.mid(p1 + 1, p2 - p1 -1).stripWhiteSpace().toDouble(&ok);
                        if (ok && pv >= 0.5) {
                            if (! pie)
                                pie = new ClientsPieWidget(hbox);
                            if (! colorsMap.contains(label)) {
                                if (colorsListIterator == colorsList.end())
                                    colorsListIterator = colorsList.begin();
                                colorsMap[label] = (*colorsListIterator);
                                colorsListIterator++;
                            }
                            pie->addValue(label.endsWith(":") ? label.left(label.length() - 1) : label, pv, colorsMap[label]);
                            value = value.left(p1+1) + "<b>" + value.mid(p1+1, p3-p1-1) + "</b>" + value.right(value.length()-p3);
                        }
                    }
                }

                QHBox *hb = new QHBox(vbox);
                new QLabel(label, hb);
                new QLabel("<nobr>" + value + "</nobr>", hb);
                count++;
            }
        }
        if (pie) {
            pie->show();
            pie = 0;
        }
        grpBox->show();
    }
}

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

void StatsPageClients::keyPressEvent(QKeyEvent *e)
{
    switch(e->key()) {
        case Qt::Key_Up:
            scrollBy(0, -10);
            break;
        case Qt::Key_Down:
            scrollBy(0, 10);
            break;
        case Qt::Key_Left:
            scrollBy(-10, 0);
            break;
        case Qt::Key_Right:
            scrollBy(10, 0);
            break;
        case Qt::Key_Home:
            setContentsPos(0, 0);
            break;
        case Qt::Key_End:
            setContentsPos(0, contentsHeight() - visibleHeight());
            break;
    }
}

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

    KMLDonkey::App->donkey->sendConsoleMessage("client_stats", callback);
}

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

void StatsPageClients::hideEvent(QHideEvent *)
{
    delete box;
    box = 0;
}

