#ifndef _H_ANIMATION_H
#define _H_ANIMATION_H

#include <memory>
#include <SDL_timer.h>
#include <string>
#include <unordered_map>

#include "utility/direction.h"

class SpriteAtlas;
class ResourceManager;
class EventManager;

// Each entity will contain animation data,
// this data will hold:
// name of the animation,
// type of animation ie. idle animation, directional, etc.
// directory of the animation atlas containing the frames
struct AnimationData;

class Animation
{
public:
	Animation(const std::shared_ptr<AnimationData>& animData, ResourceManager* resourceManager);

	std::string getName() const { return animName; }
	std::string getType() const { return animType; }

	void bind();
	void draw();
	void draw(Direction dir);

	void play() { isPlaying = true; }
	void stop() { isPlaying = false; }

	const bool getPlaying() const		{ return isPlaying; }
	const bool getDirectional() const	{ return isDirectional; }
	const int  getCycles()	const		{ return cycles; }

private:
	std::string animName;
	std::string animType;

	std::shared_ptr<SpriteAtlas> spriteAtlas;

	Uint32 elapsedTime = 0;
	Uint32 lastFrameTick = 0;
	float FPS;
	int currentFrame;
	int cycles;

	bool isDirectional;
	bool isPlaying;

	// this ticks our frame forward according to ticks passed
	void frameTick();

	void singleDraw();
	void directionalDraw(Direction dir);
};

// We will load our animation component with every loaded animation, 
// this will be the handler for every animation an entity uses
class AnimationSet
{
public:
	AnimationSet(const int& entityid);
	AnimationSet(const int& entityid, ResourceManager* resourceManager, std::vector<std::shared_ptr<AnimationData>> animSet);
	AnimationSet(const int& entityid, const std::unordered_map<std::string, std::shared_ptr<Animation>>& animations);

	std::shared_ptr<Animation>& operator [](std::string animType) { return anims[animType]; }

	void addAnimation(const std::shared_ptr<Animation> anim) { anims.try_emplace(anim->getType(), anim); }
	void setAnimation(const std::string& animType) { curAnim = anims[animType]; }

	const int getEntityID() const { return entityid; }
	const bool getDirectional() const { return isDirectional; }

	void bind();
	void draw();

	void play() { curAnim->play(); }
	void stop() { curAnim->stop(); }

	void setFacingDir(Direction& dir) { facing = dir; }

	void attachEventManager(const std::shared_ptr<EventManager>& e);

private:
	int entityid;
	bool isDirectional;

	Direction facing = Direction::Down;

	std::unordered_map<std::string, std::shared_ptr<Animation>> anims;
	std::shared_ptr<Animation> curAnim;

	std::shared_ptr<EventManager> eventManager;
};

#endif // _H_ANIMATION_H