/*
Gwenview: an image viewer
Copyright 2007 Aurélien Gâteau <aurelien.gateau@free.fr>

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 Street, Fifth Floor, Boston, MA  02110-1301, USA.

*/
#include "paintutils.h"

#include <math.h>

// Qt
#include <QPainter>
#include <QPainterPath>
#include <QPixmap>
#include <QRectF>

namespace Gwenview {

namespace PaintUtils {


// Copied from KFileItemDelegate
QPainterPath roundedRectangle(const QRectF &rect, qreal radius) {
	QPainterPath path(QPointF(rect.left(), rect.top() + radius));
	path.quadTo(rect.left(), rect.top(), rect.left() + radius, rect.top());         // Top left corner
	path.lineTo(rect.right() - radius, rect.top());                                 // Top side
	path.quadTo(rect.right(), rect.top(), rect.right(), rect.top() + radius);       // Top right corner
	path.lineTo(rect.right(), rect.bottom() - radius);                              // Right side
	path.quadTo(rect.right(), rect.bottom(), rect.right() - radius, rect.bottom()); // Bottom right corner
	path.lineTo(rect.left() + radius, rect.bottom());                               // Bottom side
	path.quadTo(rect.left(), rect.bottom(), rect.left(), rect.bottom() - radius);   // Bottom left corner
	path.closeSubpath();

	return path;
}


QPixmap generateFuzzyRect(const QSize& size, const QColor& color, int radius) {
	QPixmap pix(size);
	const QColor transparent(0, 0, 0, 0);
	pix.fill(transparent);

	QPainter painter(&pix);
	painter.setRenderHint(QPainter::Antialiasing, true);

	// Fill middle
	painter.fillRect(pix.rect().adjusted(radius, radius, -radius, -radius), color);

	// Corners
	QRadialGradient gradient;
	gradient.setColorAt(0, color);
	gradient.setColorAt(1, transparent);
	gradient.setRadius(radius);
	QPoint center;

	// Top Left
	center = QPoint(radius, radius);
	gradient.setCenter(center);
	gradient.setFocalPoint(center);
	painter.fillRect(0, 0, radius, radius, gradient);

	// Top right
	center = QPoint(size.width() - radius, radius);
	gradient.setCenter(center);
	gradient.setFocalPoint(center);
	painter.fillRect(center.x(), 0, radius, radius, gradient);

	// Bottom left
	center = QPoint(radius, size.height() - radius);
	gradient.setCenter(center);
	gradient.setFocalPoint(center);
	painter.fillRect(0, center.y(), radius, radius, gradient);

	// Bottom right
	center = QPoint(size.width() - radius, size.height() - radius);
	gradient.setCenter(center);
	gradient.setFocalPoint(center);
	painter.fillRect(center.x(), center.y(), radius, radius, gradient);

	// Borders
	QLinearGradient linearGradient;
	linearGradient.setColorAt(0, color);
	linearGradient.setColorAt(1, transparent);

	// Top
	linearGradient.setStart(0, radius);
	linearGradient.setFinalStop(0, 0);
	painter.fillRect(radius, 0, size.width() - 2*radius, radius, linearGradient);

	// Bottom
	linearGradient.setStart(0, size.height() - radius);
	linearGradient.setFinalStop(0, size.height());
	painter.fillRect(radius, int(linearGradient.start().y()), size.width() - 2*radius, radius, linearGradient);

	// Left
	linearGradient.setStart(radius, 0);
	linearGradient.setFinalStop(0, 0);
	painter.fillRect(0, radius, radius, size.height() - 2*radius, linearGradient);

	// Right
	linearGradient.setStart(size.width() - radius, 0);
	linearGradient.setFinalStop(size.width(), 0);
	painter.fillRect(int(linearGradient.start().x()), radius, radius, size.height() - 2*radius, linearGradient);
	return pix;
}


QColor adjustedHsv(const QColor& color, int deltaH, int deltaS, int deltaV) {
	int hue, saturation, value;
	color.getHsv(&hue, &saturation, &value);
	return QColor::fromHsv(
		qBound(0, hue + deltaH, 359),
		qBound(0, saturation + deltaS, 255),
		qBound(0, value + deltaV, 255)
		);
}


QColor alphaAdjustedF(const QColor& color, qreal alphaF) {
	QColor tmp = color;
	tmp.setAlphaF(alphaF);
	return tmp;
}

QRect containingRect(const QRectF& rectF) {
	return QRect(
		QPoint(
			qRound(floor(rectF.left())),
			qRound(floor(rectF.top()))
			),
		QPoint(
			qRound(ceil(rectF.right() - 1.)),
			qRound(ceil(rectF.bottom() - 1.))
			)
		);
	// Note: QRect::right = left + width - 1, while QRectF::right = left + width
}

} // namespace
} // namespace
