/***************************************************************************
                          dcwidget.cpp  -  description
                             -------------------
    begin                : Don Mai 30 2002
    copyright            : (C) 2002-2005 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 "dcwidget.h"

#include <QApplication>
#include <QStyle>
#include <QPainter>
#include <Q3Header>
#include <QPixmap>
#include <QStyleOption>
#include <QProgressBar>
#include <QBrush>

#include <Q3ListViewItemIterator>

#include "dctransferview.h"
#include "dcconfig.h"

#include <dclib/dcos.h>

#define DC_QProgressListItemRTTI 3000

#include "search-result-columns.h"

/** */
int DC_QListViewItem::compare(Q3ListViewItem * i, int col, bool ascending) const {
    if (col == DC_QNumericSortItem::mycol)
        return DC_QNumericSortItem::mycompare(((DC_QListViewItem*) i)->myvalue);
    else
        return Q3ListViewItem::compare(i, col, ascending);
}

/** */
int DC_QNumericSortItem::mycompare(ulonglong other) const {
    if (myvalue < other) return -1;
    else if (myvalue == other) return 0;
    else return 1;
}

/** */
QString DC_QListViewItem::key(int column, bool /*ascending*/) const {
    return text(column).toLower();
}

/** */
DC_QProgressListItem::DC_QProgressListItem(DC_QProgressListItem * parent, int co)
: Q3ListViewItem(parent) {
    m_nColumn = co;
    init();
}

/** */
DC_QProgressListItem::DC_QProgressListItem(Q3ListViewItem * parent, int co)
: Q3ListViewItem(parent) {
    m_nColumn = co;
    init();
}

/** */
DC_QProgressListItem::DC_QProgressListItem(Q3ListView * parent, int co)
: Q3ListViewItem(parent) {
    m_nColumn = co;
    init();
}

/** */
int DC_QProgressListItem::rtti() const {
    return DC_QProgressListItemRTTI;
}

/** */
void DC_QProgressListItem::init() {
    // init progress bar
    m_ProgressBar = new QProgressBar(0);
    m_ProgressBar->setTextVisible(true);
    m_bProgressEnable = true;
    //m_ProgressBar->setIndicatorFollowsStyle(false);
    resetProgress();
}

/** */
void DC_QProgressListItem::resetProgress() {
    m_ProgressBar->reset();
    m_ProgressBar->setRange(0, 100);
    //m_ProgressBar->setTotalSteps(100);
}

/** */
void DC_QProgressListItem::setProgress(int i) {
    m_ProgressBar->setValue(i);
}

/** */
DC_QProgressListItem::~DC_QProgressListItem() {
    delete m_ProgressBar;
}

/** */
void DC_QProgressListItem::setup() {
    Q3ListViewItem::setup();
    int h = Q3ListViewItem::height();
    //h = QMAX( listView()->style().pixelMetric(QStyle::PM_ProgressBarChunkWidth, listView()), h );
    //h = QMAX( h, QApplication::globalStrut().height() );
    setHeight(h);
    m_ProgressBar->setFixedHeight(h - listView()->itemMargin());
    m_ProgressBar->setFixedWidth(160);
}

/** */
int DC_QProgressListItem::width(const QFontMetrics& fm, const Q3ListView* lv, int column) const {
    int r = Q3ListViewItem::width(fm, lv, column);
    if ((column == m_nColumn) && m_bProgressEnable) {
        r += lv->itemMargin();

        QStyleOptionProgressBarV2 qso;
        qso.initFrom(m_ProgressBar);
        r += lv->style()->pixelMetric(QStyle::PM_ProgressBarChunkWidth, &qso, lv) + 4;
    }

    return QMAX(r, QApplication::globalStrut().width());
}

/*!
    Paints the item using the painter \a p and the color group \a cg.
    The item is in column \a column, has width \a width and has
    alignment \a align. (See Qt::AlignmentFlags for valid alignments.)
 */
void DC_QProgressListItem::paintCell(QPainter * p, const QColorGroup & cg,
        int column, int width, int align) {
    if (!p)
        return;

    Q3ListView *lv = listView();
    if (!lv)
        return;

    //const Qt::BackgroundMode bgmode = lv->viewport()->backgroundMode();
    const QColorGroup::ColorRole crole = lv->viewport()->backgroundRole(); //QPalette::backgroundRoleFromMode( bgmode );

    // we are not friends ...
    //	if ( cg.brush( crole ) != lv->colorGroup().brush( crole ) )
    p->fillRect(0, 0, width, Q3ListViewItem::height(), cg.brush(crole));
    //	else
    //		paintEmptyArea( p, QRect( 0, 0, width, QListViewItem::height() ) );

    if ((column != m_nColumn) || (m_bProgressEnable == false)) {
        // The rest is text, or for subclasses to change.
        Q3ListViewItem::paintCell(p, cg, column, width, align);
        return;
    }

    int r = lv->itemMargin();

    QStyleOptionProgressBarV2 styleoption;
    styleoption.initFrom(m_ProgressBar);
    styleoption.maximum = m_ProgressBar->maximum();
    styleoption.minimum = m_ProgressBar->minimum();
    styleoption.progress = m_ProgressBar->value();
    styleoption.text = m_ProgressBar->text();
    styleoption.textAlignment = m_ProgressBar->alignment();
    styleoption.textVisible = m_ProgressBar->isTextVisible();
    styleoption.rect = m_ProgressBar->contentsRect();

    if (isSelected()) {
        styleoption.state = styleoption.state | QStyle::State_Selected;
    }

    if (Q3ListViewItem::isEnabled() && lv->isEnabled()) {
        styleoption.state = styleoption.state | QStyle::State_Enabled;
    }

    p->save();

    m_ProgressBar->style()->drawControl(QStyle::CE_ProgressBar, &styleoption, p, m_ProgressBar);

    r += m_ProgressBar->width();

    p->restore();

    p->translate(r, 0);
    p->setBrush(((QPalette) cg).text());
    Q3ListViewItem::paintCell(p, cg, column, width - r, align);
}

/*!
    Draws the focus rectangle \a r using the color group \a cg on the
    painter \a p.
 */
void DC_QProgressListItem::paintFocus(QPainter *p, const QColorGroup & cg,
        const QRect & r) {
    bool intersect = true;
    Q3ListView *lv = listView();

    if (lv && lv->header()->mapToActual(0) != 0) {
        int xdepth = lv->treeStepSize() * (depth() + (lv->rootIsDecorated() ? 1 : 0)) + lv->itemMargin();
        int p = lv->header()->cellPos(lv->header()->mapToActual(0));
        xdepth += p;
        intersect = r.intersects(QRect(p, r.y(), xdepth - p + 1, r.height()));
    }

    if (intersect) {
        QRect rect;
        int boxsize = 0; //lv->style().pixelMetric(QStyle::PM_ProgressBarChunkWidth, lv);
        if (lv->columnAlignment(0) == Qt::AlignCenter) {
            QFontMetrics fm(lv->font());
            int bx = (lv->columnWidth(0) - (boxsize + fm.width(text(0)))) / 2 + boxsize;
            if (bx < 0) bx = 0;
            rect.setRect(r.x() + bx /*+ 5*/, r.y(), r.width() - bx /*- 5*/, r.height());
        } else
            rect.setRect(r.x() + boxsize /*+ 5*/, r.y(), r.width() - boxsize /*- 5*/, r.height());
        Q3ListViewItem::paintFocus(p, cg, rect);
    } else {
        Q3ListViewItem::paintFocus(p, cg, r);
    }
}

/** Returns the key used to sort the items.
 *  If the progress bar is enabled, we return a key like d069 or u071
 *  The initial letter stands for download or upload etc., the number is the percentage of the transfer.
 *  If the progress bar is not enabled or the column isn't the transfer column, returns QListViewItem::key() .
 *  QT Docs say ascending parameter can be ignored. 
 */
QString DC_QProgressListItem::key(int n, bool ascending) const {
    // printf("DC_QProgessListItem::key called for column: %d\n", n);

    // column 2 is Transfer column
    if ((n == 2) && (m_bProgressEnable)) {
        QString s;
        s.setNum(m_ProgressBar->value()).rightJustified(3, '0');
        s.prepend(sTransferState);
        //printf("Key for sorting transfer column is %s\n", s.toAscii().constData());
        return s;
    } else {
        return Q3ListViewItem::key(n, ascending);
    }
}

/** */
void DC_QProgressListItem::setTransferState(QString s) {
    sTransferState = s;
}
