/***************************************************************************
 *   Copyright (C) 2007 by Sébastien Laoût                                 *
 *   slaout@linux62.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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "progressbar.h"

#include <qpainter.h>
#include <qpixmap.h>
#include <kpixmap.h>
#include <kpixmapeffect.h>
#include <kglobalsettings.h>
#include <klocale.h>
#include <qtooltip.h>

ProgressBar::ProgressBar(QWidget *parent, const char *name)
 : QWidget(parent, name, Qt::WNoAutoErase),
   m_total(0), m_current(0), m_underMouse(false), m_mousePressed(false)
{
	setBackgroundMode(Qt::NoBackground);
}

ProgressBar::~ProgressBar()
{
}

bool ProgressBar::underMouse()
{
	return m_underMouse;
}

QString ProgressBar::leftText()
{
	return m_leftText;
}

QString ProgressBar::rightText()
{
	return m_rightText;
}

void ProgressBar::setTotal(int total)
{
	if (total != m_total) {
		m_total = total;
		if (m_current > m_total)
			m_current = m_total;
		update();
	}
}

void ProgressBar::setCurrent(int current)
{
	if (current != m_current) {
		m_current = current;
		if (m_current > m_total)
			m_current = m_total;
		update();
	}
}

void ProgressBar::setLeftText(const QString &leftText)
{
	if (m_leftText != leftText) {
		m_leftText = leftText;
		update();
	}
}

void ProgressBar::setRightText(const QString &rightText)
{
	if (m_rightText != rightText) {
		m_rightText = rightText;
		update();
	}
}

void ProgressBar::drawGlowingGradient(QPainter &painter, const QRect &rect, QColor color)
{
	if (m_underMouse)
		color = color.light(110);

	QColor top          = color;
	QColor middleTop    = color.dark(height() >= 20 ? 130 : 105);
	QColor middleBottom = color.dark(height() >= 20 ? 150 : 110);
	QColor bottom       = color.dark(height() >= 20 ? 190 : 115);

	KPixmap gradient;

	// Draw the top part:
	gradient.resize(rect.width(), rect.height() / 2);
	if (!gradient.isNull()) {
		KPixmapEffect::gradient(gradient, top, middleTop, KPixmapEffect::VerticalGradient);
		painter.drawPixmap(rect.x(), rect.y(), gradient);
	}

	// Draw the bottom part:
	gradient.resize(rect.width(), rect.height() - rect.height() / 2);
	if (!gradient.isNull()) {
		KPixmapEffect::gradient(gradient, middleBottom, bottom, KPixmapEffect::VerticalGradient);
		painter.drawPixmap(rect.x(), rect.y() + rect.height() / 2, gradient);
	}
}

QPixmap ProgressBar::progressPixmap(bool underMouse, int total, int current, const QString &leftText, const QString &rightText)
{
	const int BORDER_DARK = 140;

	// Begin drawing:
	QPixmap buffer(width(), height());
	QPainter painter(&buffer);

	// Draw the surrounding frame:
	QColor borderColor = (underMouse ? KGlobalSettings::highlightColor().light(120) : KGlobalSettings::highlightColor());
	int h, s, v;
	borderColor.getHsv(&h, &s, &v);
	borderColor = QColor(h, 255, v, QColor::Hsv).dark(BORDER_DARK);
	painter.setPen(borderColor);
	painter.drawRect(0, 0, width(), height());

	// Draw the white background:
	int padding = 1 + (height() >= 20 ? 2 : 1);
	drawGlowingGradient(painter, QRect(1, 1, width() - 2, height() - 2), KGlobalSettings::baseColor()); // Light padding
	drawGlowingGradient(painter, QRect(padding, padding, width() - 2 * padding, height() - 2 * padding), KGlobalSettings::baseColor().dark(110)); // Normal

	// Draw the bar:
	int barWidth = (total == 0 ? 0 : (width() - 2) * current / total);
	if (barWidth > 0) {
		drawGlowingGradient(painter, QRect(1, 1, barWidth, height() - 2), KGlobalSettings::highlightColor().light(120)); // Light padding
		drawGlowingGradient(painter, QRect(padding, padding, QMIN(barWidth - padding + 1, width() - 2 * padding), height() - 2 * padding), KGlobalSettings::highlightColor()); // Normal
	}

	// Draw the left & right texts if the size is sufficient:
	if (height() >= 10) {
		int margin = (height() < 20 ? 1 : 4);
		QFont font = painter.font();
		font.setPixelSize(height() - 2 * margin);
		if (height() >= 20)
			font.setBold(true);
		painter.setFont(font);

		painter.setClipRect(1 + barWidth, 0, width() - 1 - barWidth, height());
		painter.setPen(KGlobalSettings::textColor());
		painter.drawText(QRect(margin, margin, width() - 2 * margin, height() - 2 * margin), Qt::AlignLeft  | Qt::AlignVCenter, leftText);
		painter.drawText(QRect(margin, margin, width() - 2 * margin, height() - 2 * margin), Qt::AlignRight | Qt::AlignVCenter, rightText);

		painter.setClipRect(0, 0, 1 + barWidth, height());
		painter.setPen(KGlobalSettings::highlightedTextColor());
		painter.drawText(QRect(margin, margin, width() - 2 * margin, height() - 2 * margin), Qt::AlignLeft  | Qt::AlignVCenter, leftText);
		painter.drawText(QRect(margin, margin, width() - 2 * margin, height() - 2 * margin), Qt::AlignRight | Qt::AlignVCenter, rightText);
	}

	// End drawing:
	painter.end();

	return buffer;
}

void ProgressBar::paintEvent(QPaintEvent */*event*/)
{
	QPainter painter(this);
	painter.drawPixmap(0, 0, progressPixmap(m_underMouse, m_total, m_current, m_leftText, m_rightText));
	painter.end();
}

void ProgressBar::mousePressEvent(QMouseEvent *event)
{
	m_mousePressed = true;
	changePosition(event);

	QWidget::mousePressEvent(event);
}

void ProgressBar::mouseReleaseEvent(QMouseEvent *event)
{
	m_mousePressed = false;

	QWidget::mouseReleaseEvent(event);
}

void ProgressBar::removeHighlighting()
{
	if (m_underMouse) {
		m_underMouse = false;
		update();
	}
}

void ProgressBar::mouseMoveEvent(QMouseEvent *event)
{
	// If the progressbar highlighting was disabled (because cursor was hidden in full screen), re-highlight it again:
	if (m_underMouse == false) {
		m_underMouse = true;
		update();
	}

	if (m_mousePressed)
		changePosition(event);

	QWidget::mouseMoveEvent(event);
}

void ProgressBar::changePosition(QMouseEvent *event)
{
	int x = event->pos().x();
	if (x > 0 && x < width() - 1)
		emit changePosition((x - 1) * m_total / (width() - 2));
}

void ProgressBar::enterEvent(QEvent *event)
{
	// This is only to get MouseMoveEvent is FullScreen mode, to re-show mouse cursor (with an event filter in CoverDisplay)!
	setMouseTracking(true);

	// Highlight the progressbar on mouse hover:
	m_underMouse = true;
	update();

	QWidget::enterEvent(event);
}

void ProgressBar::leaveEvent(QEvent *event)
{
	setMouseTracking(false);

	// Disable the progressbar highlighting because mouse is now out:
	m_underMouse = false;
	update();

	QWidget::leaveEvent(event);
}

#include "progressbar.moc"
