#include "AnimationState.h"

void AnimationState::updateReverse()
{
	activeFrameNo -= 1;
	if (activeFrameNo < 0)
	{
		if (doLoop == true)
			activeFrameNo = ptrToAnimation->maxFrameCount - 1;
		else
			isActive = false;
	}
}

void AnimationState::updateNormal()
{
	activeFrameNo += 1;
	if (activeFrameNo == ptrToAnimation->maxFrameCount)
	{
		if (doLoop == true)
			activeFrameNo = 0;
		else
			isActive = false;
	}
}

bool AnimationState::needUpdate()
{
	auto timeNow = std::chrono::system_clock::now();
	if ((timeNow - lastUpdate) > ptrToAnimation->frameInterval)
		return true;
	else
		return false;
}

void AnimationState::updateState()
{
	lastUpdate = std::chrono::system_clock::now();
	if (doReverse)
		updateReverse();
	else
		updateNormal();
}


void AnimationState::setActiveNormal(Animation* animPtr)
{
	ptrToAnimation = animPtr;
	isActive = true;
	lastUpdate = std::chrono::system_clock::now() - animPtr->frameInterval;

	doLoop = false;
	doReverse = false;
	activeFrameNo = 0;
}

void AnimationState::setActiveReverse(Animation* animPtr)
{
	ptrToAnimation = animPtr;
	isActive = true;
	lastUpdate = std::chrono::system_clock::now() - animPtr->frameInterval;

	doLoop = false;
	doReverse = true;
	activeFrameNo = animPtr->maxFrameCount - 1;
}

void AnimationState::setDefaultNormal(Animation* animPtr)
{
	ptrToAnimation = animPtr;
	isActive = true;
	lastUpdate = std::chrono::system_clock::now() - animPtr->frameInterval;

	doLoop = true;
	doReverse = false;
	activeFrameNo = 0;
}

void AnimationState::setDefaultReverse(Animation* animPtr)
{
	ptrToAnimation = animPtr;
	isActive = true;
	lastUpdate = std::chrono::system_clock::now() - animPtr->frameInterval;

	doLoop = true;
	doReverse = true;
	activeFrameNo = animPtr->maxFrameCount - 1;
}


void AnimationState::clearState()
{
	isActive = false;
}

const bool& AnimationState::active()
{
	return isActive;
}


void AnimationState::drawFrame(Position& objPos, Position& camPos, float& xScale, float& yScale, ALLEGRO_COLOR& tint)
{
	if (isActive) 
	{
		if (needUpdate())
		{
			float virtualY = camPos.posY + (camPos.posY - objPos.posY);
			al_draw_tinted_scaled_rotated_bitmap(ptrToAnimation->animationFrames[activeFrameNo],
				tint, ptrToAnimation->centerX, ptrToAnimation->centerY,
				objPos.posX, virtualY, xScale, yScale, objPos.getRadRotX(), NULL);
			updateState();
		}
		else
		{
			float virtualY = camPos.posY + (camPos.posY - objPos.posY);
			al_draw_tinted_scaled_rotated_bitmap(ptrToAnimation->animationFrames[activeFrameNo],
				tint, ptrToAnimation->centerX, ptrToAnimation->centerY,
				objPos.posX, virtualY, xScale, yScale, objPos.getRadRotX(), NULL);
		}
	}
}

void AnimationState::drawFrame(Position& objPos, Position& camPos, float& xScale, float& yScale)
{
	if (isActive)
	{
		if (needUpdate())
		{
			float virtualY = camPos.posY + (camPos.posY - objPos.posY);
			al_draw_scaled_rotated_bitmap(ptrToAnimation->animationFrames[activeFrameNo],
				ptrToAnimation->centerX, ptrToAnimation->centerY,
				objPos.posX, virtualY, xScale, yScale, objPos.getRadRotX(), NULL);
			updateState();
		}
		else 
		{
			float virtualY = camPos.posY + (camPos.posY - objPos.posY);
			al_draw_scaled_rotated_bitmap(ptrToAnimation->animationFrames[activeFrameNo],
				ptrToAnimation->centerX, ptrToAnimation->centerY,
				objPos.posX, virtualY, xScale, yScale, objPos.getRadRotX(), NULL);
		}
	}
}

void AnimationState::drawFrame(Position& objPos, Position& camPos)
{
	if (isActive)
	{
		if (needUpdate())
		{
			float virtualY = camPos.posY + (camPos.posY - objPos.posY);
			al_draw_rotated_bitmap(ptrToAnimation->animationFrames[activeFrameNo],
				ptrToAnimation->centerX, ptrToAnimation->centerY,
				objPos.posX, virtualY, objPos.getRadRotX(), NULL);
			updateState();
		}
		else
		{
			float virtualY = camPos.posY + (camPos.posY - objPos.posY);
			al_draw_rotated_bitmap(ptrToAnimation->animationFrames[activeFrameNo],
				ptrToAnimation->centerX, ptrToAnimation->centerY,
				objPos.posX, virtualY, objPos.getRadRotX(), NULL);
		}
	}
}

void AnimationState::drawFrame(Position& objPos, float& xScale, float& yScale, ALLEGRO_COLOR& tint)
{
	if (isActive)
	{
		if (needUpdate())
		{
			al_draw_tinted_scaled_rotated_bitmap(ptrToAnimation->animationFrames[activeFrameNo],
				tint, ptrToAnimation->centerX, ptrToAnimation->centerY,
				objPos.posX, objPos.posY, xScale, yScale, objPos.getCounterRadRotX(), NULL);
			updateState();
		}
		else
		{
			al_draw_tinted_scaled_rotated_bitmap(ptrToAnimation->animationFrames[activeFrameNo],
				tint, ptrToAnimation->centerX, ptrToAnimation->centerY,
				objPos.posX, objPos.posY, xScale, yScale, objPos.getCounterRadRotX(), NULL);
		}
	}
}

void AnimationState::drawFrame(Position& objPos, float& xScale, float& yScale)
{
	if (isActive)
	{
		if (needUpdate())
		{
			al_draw_scaled_rotated_bitmap(ptrToAnimation->animationFrames[activeFrameNo],
				ptrToAnimation->centerX, ptrToAnimation->centerY,
				objPos.posX, objPos.posY, xScale, yScale, objPos.getCounterRadRotX(), NULL);
			updateState();
		}
		else
		{
			al_draw_scaled_rotated_bitmap(ptrToAnimation->animationFrames[activeFrameNo],
				ptrToAnimation->centerX, ptrToAnimation->centerY,
				objPos.posX, objPos.posY, xScale, yScale, objPos.getCounterRadRotX(), NULL);
		}
	}
}

void AnimationState::drawFrame(Position& objPos)
{
	if (isActive)
	{
		if (needUpdate())
		{
			al_draw_rotated_bitmap(ptrToAnimation->animationFrames[activeFrameNo],
				ptrToAnimation->centerX, ptrToAnimation->centerY,
				objPos.posX, objPos.posY, objPos.getCounterRadRotX(), NULL);
				updateState();
		}
		else
		{
			al_draw_rotated_bitmap(ptrToAnimation->animationFrames[activeFrameNo],
				ptrToAnimation->centerX, ptrToAnimation->centerY,
				objPos.posX, objPos.posY, objPos.getCounterRadRotX(), NULL);
		}
	}
}


AnimationState::AnimationState()
{
}

AnimationState::~AnimationState()
{
}
