#pragma once
#include "olcUTIL_Animate2D.h"
#include "Animation.h"
#include "Monster.h"
#include "State.h"
#include "Ability.h"
#include "Class.h"
#include "Buff.h"
#include "Pathfinding.h"

struct Player{
	friend class Crawler;
	friend class Warrior;
	friend class Thief;
	friend class Ranger;
	friend class Bard;
	friend class Wizard;
	friend class Witch;
	private:
	Class cl=WARRIOR;
	int hp=100,maxhp=hp;
	int mana=100,maxmana=mana;
	int atk=10;
	vf2d pos;
	vf2d vel={0,0};
	float friction=400;
	float z=0;
	float moveSpd=1.0f;
	float size=1.0f;
	float attack_range=1.5f;
	Ability rightClickAbility,ability1,ability2,ability3;
	const float ATTACK_COOLDOWN=0.35f;
	const float MAGIC_ATTACK_COOLDOWN=0.85f;
	float attack_cooldown_timer=0;
	float spin_attack_timer=0;
	float spin_spd=0;
	float spin_angle=0;
	float lastAnimationFlip=0;
	float swordSwingTimer=0;
	float iframe_time=0;
	float manaTickTimer=0;
	float teleportAnimationTimer=0;
	vf2d teleportTarget={};
	vf2d teleportStartPosition={};
	std::pair<std::string,float> notEnoughManaDisplay={"",0};
	std::pair<std::string,float> notificationDisplay={"",0};
	float teleportAttemptWaitTime=0; //If a teleport fails, we wait awhile before trying again, it's expensive.
	State state=State::NORMAL;
	Animate2D::Animation<AnimationState>animation;
	Animate2D::AnimationState internal_animState;
	Key lastReleasedMovementKey;
	Key facingDirection;
	bool upperLevel=false;
	void AddAnimation(AnimationState state);
	void Update(float fElapsedTime);
	void SetSwordSwingTimer(float val);
	void SetState(State newState);
	void SetFacingDirection(Key direction);
	void SetLastReleasedMovementKey(Key k);
	void Spin(float duration,float spinSpd);
	//Returns true if the move was valid and successful.
	bool SetX(float x);
	//Returns true if the move was valid and successful.
	bool SetY(float y);
	void SetZ(float z);
	//Returns true if the move was valid and successful.
	bool SetPos(vf2d pos);
	void SetClass(Class cl);
	std::vector<Buff>buffList;
	Pathfinding path;
	protected:
	public:
	Player();
	const static float GROUND_SLAM_SPIN_TIME;
	vf2d&GetPos();
	float GetX();
	float GetY();
	float GetZ();
	int GetHealth();
	int GetMaxHealth();
	int GetMana();
	int GetMaxMana();
	int GetAttack();
	float GetMoveSpdMult();
	float GetSizeMult();
	float GetAttackRangeMult();
	float GetSpinAngle();
	State GetState();
	Key GetFacingDirection();
	vf2d GetVelocity();
	bool HasIframes();
	void UpdateWalkingAnimation(Key direction);
	void UpdateIdleAnimation(Key direction);
	//The range is the search range in tiles.
	bool CanPathfindTo(vf2d pos,vf2d targetPos,float range=8);

	void AddBuff(BuffType type,float duration,float intensity);
	std::vector<Buff>GetBuffs(BuffType buff);

	bool Hurt(int damage);
	void UpdateAnimation(AnimationState animState);
	Animate2D::Frame GetFrame();
	Key GetLastReleasedMovementKey();
	float GetSwordSwingTimer();
	bool OnUpperLevel();

	float GetAbility2Cooldown();
	float GetRightClickCooldown();

	//Triggers when the player has moved.
	void Moved();
};