#include "yacreader_busy_widget.h"

#include <QDebug>
#include <QPainter>
#include <QPixmapCache>
#include <QGradient>

YACReaderBusyWidget::YACReaderBusyWidget(QWidget *parent)
	:QWidget(parent)
{
	setFixedSize(70,70);
	BusyIndicator * busy = new BusyIndicator(this);
	busy->setIndicatorStyle(BusyIndicator::StyleArc);
	busy->setColor(Qt::white);
	busy->move(20,20);
}

void YACReaderBusyWidget::paintEvent(QPaintEvent * event)
{
	Q_UNUSED(event);
	QPainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing);
	painter.drawPixmap(0,0,width(),height(),QPixmap(":/images/busy_background.png"));
}

BusyIndicator::BusyIndicator(QWidget *parent) :
	QWidget(parent),
	startAngle(0),
	m_style(StyleArc)
{
	QSizePolicy policy(QSizePolicy::Preferred, QSizePolicy::Fixed);
	policy.setHeightForWidth(true);
	setSizePolicy(policy);

	fillColor = palette().color(QPalette::WindowText);

	timer.setInterval(16);
	connect(&timer, SIGNAL(timeout()), this, SLOT(rotate()));
	timer.start();
}

void BusyIndicator::rotate()
{
	startAngle += 9;
	startAngle %= 360;
	update();
}

void BusyIndicator::setIndicatorStyle(IndicatorStyle style)
{
	m_style = style;
	update();
}

void BusyIndicator::setColor(QColor color)
{
	fillColor = color;
}

const BusyIndicator::IndicatorStyle BusyIndicator::indicatorStyle() const
{
	return m_style;
}


QPixmap BusyIndicator::generatePixmap(int side)
{
	QPixmap pixmap(QSize(side, side));
	pixmap.fill(QColor(255, 255, 255, 0));

	QPainter painter(&pixmap);
	painter.setRenderHint(QPainter::Antialiasing);

	painter.translate(side / 2, side / 2);
	painter.scale(side / 200.0, side / 200.0);

	switch (m_style) {
	case StyleRect:
		drawRectStyle(&painter);
		break;
	case StyleEllipse:
		drawEllipseStyle(&painter);
		break;
	case StyleArc:
		drawArcStyle(&painter);
		break;
	}
	return pixmap;
}

void BusyIndicator::drawRectStyle(QPainter *painter)
{
	//    QColor color = palette().color(QPalette::WindowText);
	QColor color = fillColor;
	QBrush brush(color);
	painter->setPen(Qt::NoPen);

	painter->rotate(startAngle);

	float angle = 0;
	while (angle < 360) {
		painter->setBrush(brush);
		painter->drawRect(-8, -100, 16, 35);

		painter->rotate(30);
		angle += 30;

		color.setAlphaF(angle / 360);
		brush.setColor(color);
	}
}

void BusyIndicator::drawEllipseStyle(QPainter *painter)
{
	//    QColor color = palette().color(QPalette::WindowText);
	QColor color = fillColor;
	QBrush brush(color);
	painter->setPen(Qt::NoPen);

	painter->rotate(startAngle);

	float angle = 0;
	while (angle < 360) {
		painter->setBrush(brush);
		painter->drawEllipse(-10, -100, 30, 30);

		painter->rotate(30);
		angle += 30;

		color.setAlphaF(angle / 360);
		brush.setColor(color);
	}
}

void BusyIndicator::drawArcStyle(QPainter *painter)
{
	//    QColor color = palette().color(QPalette::WindowText);
	QColor color = fillColor;
	QConicalGradient gradient(0, 0, -startAngle);
	gradient.setColorAt(0, color);
	color.setAlpha(0);
	gradient.setColorAt(0.8, color);
	color.setAlpha(255);
	gradient.setColorAt(1, color);

	QPen pen;
	pen.setWidth(30);
	pen.setBrush(QBrush(gradient));
	painter->setPen(pen);

	painter->drawArc(-85, -85, 170, 170, 0 * 16, 360 * 16);
}

void BusyIndicator::paintEvent(QPaintEvent *)
{
	QString key = QString("%1:%2:%3:%4:%5")
			.arg(metaObject()->className())
			.arg(width())
			.arg(height())
			.arg(startAngle)
			.arg(m_style);

	QPixmap pixmap;
	QPainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing);

	int side = qMin(width(), height());

	if(!QPixmapCache::find(key, &pixmap)) {
		pixmap = generatePixmap(side);
		QPixmapCache::insert(key, pixmap);
	}

	painter.translate(width() / 2 - side / 2, height() / 2 - side / 2);

	painter.drawPixmap(0, 0, side, side, pixmap);
}

QSize BusyIndicator::minimumSizeHint() const
{
	return QSize(30, 30);
}

QSize BusyIndicator::sizeHint() const
{
	return QSize(30, 30);
}