#include "q2048tile.h"
#include "q2048view.h"

#include <QBrush>
#include <QGraphicsRectItem>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>
#include <QDebug>

Q2048Tile::TilesListT Q2048Tile::Tiles;
Q2048Tile::ColorMapT Q2048Tile::ColorMap = initColorMap();
QParallelAnimationGroup* Q2048Tile::Animation = 0;

Q2048Tile::Q2048Tile(int x, int y, Q2048View* v) : X(x), Y(y), View(v)
{
	QRectF bounds = View->tileRect(X,Y);
	setPos(bounds.center());

	RectItem = new QGraphicsRectItem(bounds);
	RectItem->setBrush(QBrush(Qt::white));
	RectItem->setPen(Qt::NoPen);
	addToGroup(RectItem);

	TextItem = new QGraphicsSimpleTextItem(this);

	addToGroup(TextItem);



	Tiles.append(this);
	View->scene()->addItem(this);

	grow(2*(qrand()/(float)RAND_MAX)+1);
	animate();
}

void Q2048Tile::setZValue(qreal z)
{
	removeTile();
	QGraphicsItemGroup::setZValue(z);
}

Q2048Tile::~Q2048Tile()
{
	//qDebug() << "destructor" << (QGraphicsItem*) this << " count:" << Tiles.count();

	removeTile();
}

void Q2048Tile::shift(int dx, int dy)
{
	X+=dx;
	Y+=dy;
	//Index = Y*View->Size+X;
	QRectF bounds = View->tileRect(X,Y);
	//setPos(bounds.center());

	QPropertyAnimation* ani = new QPropertyAnimation(this, "pos");
	ani->setDuration(AnimationDuration);
	ani->setStartValue(pos());
	ani->setEndValue(bounds.center());

	addAnimation(ani);
}

Q2048Tile* Q2048Tile::getTile(int x, int y)
{
	foreach (Q2048Tile* t, Tiles)
	{
		if ( (t->X==x) && (t->Y==y) )
			return t;
	}

	return 0;
}

int Q2048Tile::count()
{
	return Tiles.count();
}

void Q2048Tile::grow (int v)
{
	if (v!=-1) //init
		Value = v*2;
	else
		Value*=2;

	QColor tc = (Value>4) ? QColor("#F9F6F2") : QColor("#776E65");

	TextItem->setFont(QFont("Liberation sans", -1, QFont::Bold));
	TextItem->setBrush(QBrush(tc));
	TextItem->setText(QString::number(Value));
	TextItem->setPos(/*bounds.center()*/ - TextItem->boundingRect().center());

	//color-animation
	QPropertyAnimation* anicolor = new QPropertyAnimation(this, "brush");
	anicolor->setDuration(AnimationDuration);

	QColor startcolor = (v==-1) ? ColorMap[Value/2] : ColorMap[Value];
	if (v!=-1)
		startcolor.setAlpha(0);

	anicolor->setStartValue(startcolor);
	anicolor->setEndValue(ColorMap[Value]);

	addAnimation(anicolor);

	//pulse/create animation
	QPropertyAnimation* anipulse = new QPropertyAnimation(this, "scale");
	anipulse->setDuration(AnimationDuration);

	qreal start = (v == -1) ? 1 : 0;
	anipulse->setStartValue(start);

	anipulse->setKeyValueAt(0.5, 1.15);
	anipulse->setEndValue(1);

	addAnimation(anipulse);


}

QColor Q2048Tile::brush(void) const
{
	return RectItem->brush().color();
}

void Q2048Tile::setBrush(QColor c)
{
	RectItem->setBrush(QBrush(c));
}

Q2048Tile::ColorMapT Q2048Tile::initColorMap()
{
	ColorMapT cm;

	cm[2]=QColor("#EEE4DA");
	cm[4]=QColor("#EDE0C8");
	cm[8]=QColor("#F2B179");
	cm[16]=QColor("#F49663");
	cm[32]=QColor("#F67C5F");
	cm[64]=QColor("#F65E3B");
	cm[128]=QColor("#EDCF72");
	cm[256]=QColor("#EDCC61");
	cm[512]=QColor("#EDC850");
	cm[1024]=QColor("#EDC53F");
	cm[2048]=QColor("#FFFFFF");

	return cm;

}

void Q2048Tile::addAnimation(QAbstractAnimation* a)
{

	if (Animation == 0)
	{
		Animation = new QParallelAnimationGroup(View);
		connect(Animation, SIGNAL(finished()), View, SLOT(deleteMerged()));
	}

	Animation->addAnimation(a);

}

void Q2048Tile::animate()
{
	if (Animation)
		Animation->start(QAbstractAnimation::DeleteWhenStopped);

	Animation = 0;
}

void Q2048Tile::removeTile(void)
{
	int i = Tiles.indexOf(this);
	if (i >= 0)
		Tiles.removeAt(i);
}
