#include <QPainter>
#include <QApplication>
#include <qmath.h>
#include "busy_icon.h"
#include "qad_types.h"


BusyIcon::BusyIcon(QWidget * parent): QWidget(parent) {
	timer = ang = 0;
	icon_size = 5.f;
}


BusyIcon::~BusyIcon() {
}


void BusyIcon::start() {
	stop();
	ang = 0;
	timer = startTimer(25);
}


void BusyIcon::stop() {
	if (timer == 0) return;
	killTimer(timer);
	timer = 0;
}


QIcon BusyIcon::icon() {
	return icon_;
}


void BusyIcon::setIcon(QIcon i) {
	icon_ = i;
	image = i.pixmap(512, 512).toImage();
}


void BusyIcon::setIconSize(qreal s) {
	icon_size = s;
	updateGeometry();
}


QSize BusyIcon::sizeHint() const {
	return preferredIconSize(icon_size, this);
}


void BusyIcon::timerEvent(QTimerEvent *) {
	ang += 1;
	update();
}


QPointF point(qreal r, qreal a) {return QPointF(-r * sin(a), -r * cos(a));}
qreal frag(qreal a, qreal f) {int i = (int)(a / f); return a - (i * f);}
qreal angle(int a) {return (cos(frag(a / 15., M_PI)) - 1) * M_PI;}

void BusyIcon::paintEvent(QPaintEvent *) {
	QPainter p(this);
	if (rect().isEmpty()) return;
	qreal w = width(), h = height();
	p.translate(w / 2., h / 2.);
	p.scale(qMin(w, h), qMin(w, h));

	float imgsz = 0.75f, ioff = (1.f - imgsz) / 2.f;
	p.setRenderHint(QPainter::SmoothPixmapTransform);
	p.setRenderHint(QPainter::Antialiasing);
	p.drawImage(QRectF(-imgsz/2., -imgsz/2., imgsz, imgsz), image);
	p.setPen(Qt::NoPen);
	p.setBrush(palette().brush(QPalette::Active, QPalette::Highlight));
	p.setRenderHint(QPainter::Antialiasing);

	qreal sa = angle(ang), ea = angle(ang + 10);
	if (ea > sa) ea -= M_PI * 2.;
	qreal rs = 0.5 - ioff, rb = 0.5;
	int steps = qMin(128, qRound(qAbs(ea - sa) / 0.025));
	QPolygonF pol;
	for (int i = 0; i <= steps; ++i) {
		qreal c = i / (qreal)steps;
		pol << point(rs, sa * c  +  ea * (1. - c));
	}
	for (int i = 0; i <= steps; ++i) {
		qreal c = i / (qreal)steps;
		pol << point(rb, ea * c  +  sa * (1. - c));
	}
	p.drawPolygon(pol);
}
