#include "µsprite.h"

CSprite::CSprite()
{
   //MAJ de variables
	px = 0;
	py = 0;
	alphaBlending = false;
	alpha = 31;
	height = 0;
	width = 0;
	frameCounter = currentFrame = 0;
	animNbr = 0;
	frameW = frameH = 0;
	currentAnim = defaultAnim = 0;
	image = NULL;
	isLoaded = isStarted = isPaused = isLoop = false;
	isGlow = false;
	glowPasses = 0;
	group = 0;
}
   
CSprite::CSprite(UL_IMAGE *img)
{
   //Creation du sprite
	image = img;
	animNbr = 0;
	frameCounter = 0;
	currentAnim = defaultAnim = currentFrame = 0;
	frameW = frameH = 0;
	isLoaded = true;
	isPaused = false;
	//MAJ de variables
	px = 0;
	py = 0;
	alphaBlending = false;
	alpha = 31;
	height = image->sizeY;
	width = image->sizeX;
	//Démarrage d'une animation par défaut
	isStarted = true;
	isLoop = true;
}

CSprite::~CSprite()
{
   //Liberation de la mémoire
   //ulDeleteImage(image);
}

void CSprite::assign(UL_IMAGE *img)
{
   //Creation du sprite
	image = img;
	animNbr = 0;
	frameW = frameH = 0;
	isLoaded = true;
	isStarted = isPaused = false;
	//MAJ de variables
	px = 0;
	py = 0;
	alphaBlending = false;
	alpha = 31;
	height = image->sizeY;
	width = image->sizeX;
	//Démarrage d'une animation par défaut
	isStarted = true;
	isLoop = true;
}

void CSprite::free()
{
   ulDeleteImage(image);
}

void CSprite::freeRessource(CRessourceManager* resMan)
{
   resMan->DeleteImage(image);
}	   

void CSprite::setXY(u16 x, u16 y)
{
   //Settings
	px = x;
   py = y;
}

void CSprite::draw()
{
   if(alphaBlending)
   {
	   ulSetAlpha(UL_FX_ALPHA, alpha, group);
	   ulDrawImageXY(image, px, py);
	   ulSetAlpha(UL_FX_DEFAULT, alpha, group);
	}
	else if(isGlow)
	{
	   int oldw = width;
	   int oldh = height;
	   //On affiche les parties Alpha
	   for(int k = 0; k < glowPasses; k++)
	   {
	      ulSetImageTint(image, RGB15(31,31,31));
			//On fait baisser l'alpha
			alpha = alpha - (31/glowPasses);
			//On augmente la taille
			scaleFactor = scaleFactor + 3;
			//On affiche
			ulSetAlpha(UL_FX_ALPHA, alpha, 0);
			scale(width+scaleFactor,height+scaleFactor);
	  	 	ulDrawImageXY(image, px-(3*k), py-(3*k));
	   	ulSetAlpha(UL_FX_DEFAULT, alpha, 0);
	   }
	   //On reset les valeurs
	   alpha = 31;
	   scaleFactor = 0;
	   width = oldw;
	   height = oldh;
	   //On affiche la premier sprite
	   scale(width, height);
	   ulDrawImageXY(image, px, py);
	}   
	else
	{
	   ulDrawImageXY(image, px, py);
	}   
}

void CSprite::play()
{
   if(!isPaused && isStarted)
   {
	   //On update le framecounter
	   frameCounter++;
	   //On vérifie l'état du framecounter
	   if(frameCounter > animations[currentAnim].fps)
	   {
	   	frameCounter = 0;
	   	currentFrame++;
		}
		//On vérifie l'état de la frame courante (cas loop)
		if(isLoop && currentFrame > animations[currentAnim].lengh)
			currentFrame = 0;
		//On vérifie si l'animation est finie
		if(!isLoop && currentFrame > animations[currentAnim].lengh)
			this->stop();
	   	
		//On clippe le sprite
		clip(animations[currentAnim].startx * frameW + currentFrame * frameW, 
			  animations[currentAnim].posy* frameH, frameW, frameH);
	}	
}   

void CSprite::rotate(u16 angle)
{
   image->angle = angle;
}   
		
void CSprite::setRotCenter(u16 x, u16 y)
{
	image->centerX = x;
	image->centerY = y;
}

void CSprite::mirror(bool h, bool v)
{
	ulMirrorImageH(image, h);			
	ulMirrorImageV(image, v);		  
}   

void CSprite::clip(u16 px, u16 py, u16 pw, u16 ph)
{
	ulSetImageTileSize(image, px, py, pw, ph);							
}

void CSprite::scale(u16 w, u16 h)
{
   image->stretchX = width = w;
   image->stretchY = height = h;
}

void CSprite::setColor(UL_COLOR color)
{
   ulSetImageTint(image, color);
}
   
void CSprite::setAlpha(bool blend, u8 a, int g)
{
	alphaBlending = blend;
	alpha = a;
	group = g;
}

void CSprite::setFrameWH(u16 w, u16 h)
{
	frameW = w;
	frameH = h;
	//On scale le sprite	  
	scale(frameW, frameH);
}

int CSprite::addAnim(u8 py, u8 stx, u8 len, u8 fps)
{
   //Déclaration d'une structure anim temporaire
   sSpriteAnim tmpAnim = {py, stx, len, fps};
   //Ajout au vector
   animations.push_back(tmpAnim);
   animNbr++;
   return animNbr;
}

void CSprite::setAnimSpeed(u8 anim, int speed)
{
   animations[anim].fps = speed;
}   

bool CSprite::anim(u8 anim)
{
   //Reset de l'ancienne animation
   if(currentAnim != anim)
   {
	   frameCounter = currentFrame = 0;
	   //Démarrage d'une animation
	   isStarted = true;
	   isLoop = false;
	   //Settings
	   currentAnim = anim;
	}
	return isStarted;
}

void CSprite::animLoop(u8 anim)
{
   //Reset de l'ancienne animation
   if(currentAnim != anim)
   {
	   frameCounter = currentFrame = 0;
	   //Démarrage d'une animation
	   isStarted = true;
	   isLoop = true;
	   //Settings
	   currentAnim = anim;
	}	
}

void CSprite::pause()
{
   isPaused = true;
}

void CSprite::restart()
{
	isPaused = false;
}

void CSprite::stop()
{
   frameCounter = 0;
   currentFrame--;
   isStarted = false;
}

void CSprite::glow(bool enable, int pass)
{
   isGlow = enable;
   glowPasses = pass;
}   
   
bool collision(CSprite * spr1, u16 x1, u16 y1, CSprite * spr2, u16 x2, u16 y2)
{
   if(x2 + spr2->width < x1)
        return false;
    if(x2 > x1 + spr1->width)
        return false;

    if(y2 + spr2->height < y1)
        return false;
    if(y2 > y1 + spr1->height)
        return false;

    return true;
}   
