#include "CharacterAnimator.hpp"
#include "GameObject.hpp"
#include "SpriteRenderer.hpp"
#include "Logger.hpp"

#define Stand_Sprite sprites[0]
#define Walk_Frame_1 sprites[1]
#define Walk_Frame_2 sprites[2]
#define Jump_Sprite sprites[3]
#define Air_Sprite sprites[4]
#define Fall_Sprite sprites[5]

CharacterAnimator::CharacterAnimator(GameObject* gameObject) : Behaviour(gameObject){}

void CharacterAnimator::SetState(State newState){
	if (currentState != newState) {
		stateChanged = true;
		currentState = newState;
		clipTimer = 0;
		Logger::Debug("Animator State Changed");
	}
}

void CharacterAnimator::InitialiseSelf() {
	renderer = gameObject.GetComponents<SpriteRenderer>().front();
}

void CharacterAnimator::Update(float deltaTime) {
	clipTimer += deltaTime;
	switch (currentState) {
	case CharacterAnimator::State::Idle:
		if (!stateChanged)return;
		renderer->SetSprite(Stand_Sprite);
		break;
	case CharacterAnimator::State::WalkLeft:
		if (stateChanged) {
			if (Walk_Frame_1.getFlip() != glm::bvec2(true, false))Walk_Frame_1.setFlip(glm::bvec2(true, false));
			if (Walk_Frame_2.getFlip() != glm::bvec2(true, false))Walk_Frame_2.setFlip(glm::bvec2(true, false));
			clipTimer = clipTime + 1;
		}
		if (clipTimer > clipTime) {
			if (++currentWalkFrame % 2 == 0)renderer->SetSprite(Walk_Frame_1);
			else renderer->SetSprite(Walk_Frame_2);
			clipTimer = 0;
		}
		break;
	case CharacterAnimator::State::WalkRight:
		if (stateChanged) {
			if (Walk_Frame_1.getFlip() != glm::bvec2(false, false))Walk_Frame_1.setFlip(glm::bvec2(false, false));
			if (Walk_Frame_2.getFlip() != glm::bvec2(false, false))Walk_Frame_2.setFlip(glm::bvec2(false, false));
			clipTimer = clipTime + 1;
		}
		if (clipTimer > clipTime) {
			if (++currentWalkFrame % 2 == 0)renderer->SetSprite(Walk_Frame_1);
			else renderer->SetSprite(Walk_Frame_2);
			clipTimer = 0;
		}
		break;
	case CharacterAnimator::State::Jump:
		if (!stateChanged)return;
		renderer->SetSprite(Jump_Sprite);
		break;
	case CharacterAnimator::State::Air:
		if (!stateChanged)return;
		renderer->SetSprite(Air_Sprite);
		break;
	case CharacterAnimator::State::Fall:
		if (!stateChanged)return;
		renderer->SetSprite(Fall_Sprite);
		break;
	default:
		break;
	}
	stateChanged = false;
}

#undef Stand_Sprite
#undef Walk_Frame_1
#undef Walk_Frame_2
#undef Jump_Sprite
#undef Air_Sprite
#undef Fall_Sprite
