#pragma once
#include "Collision.h"
#include "SoundEffect.h"
#include "TextureManager.h"
#include "Animations/Animation.h"
#include "GridSystem/WorldTile.h"
#include "Particle/Particle.h"

class WorldLevel;

enum class PlayerState
{
	Idle,
	Walking,
	Digging,
	Turning,
	Flying
};

enum class PlayerDirection
{
	Left,
	Right,
	Up,
	Down,
};

enum class DigDirection
{
	Left,
	Right,
	Down
};

class Player
{
public:
	explicit Player(const Vector2f& Position, TextureManager* pTextureManager);
	Player( const Player& other ) = default;
	Player(Player&& other) = delete;
	Player& operator=(const Player& other) = delete;
	Player& operator=(Player&& other) = delete;
	
	~Player();
	
	Collision::CollisionRect GetCollisionRect() const;
	void Update(float elapsedTime, WorldLevel& level);
	void Draw() const;

	void SetPosition(Vector2f pos) {
		m_Position = pos;
	}
	Vector2f GetPosition() const {
		return m_Position;
	}

	void SetVelocity(Vector2f vel) {
		m_Vel = vel;
	}
	Vector2f GetVelocity() const {
		return m_Vel;
	}

	auto GetContactMap() {
		return m_ContactMap;
	}
	void SetContactMap(Collision::CollisionDirection dir, WorldTile* tile) {
		m_ContactMap[dir] = tile;
	}

	void Die();


private:
	void Dig(Collision::CollisionDirection dir, WorldLevel& level);
	bool CanDig(Collision::CollisionDirection dir, WorldLevel& level);

	void ChangeSound(SoundEffect* sound);
	
	Vector2f m_Position;
	Vector2f m_Size;

	Vector2f m_OutletPos;
	Vector2f m_OutLeftPos{ 55, 45};
	Vector2f m_OutRightPos{ -40, 45 };

	Vector2f m_Vel;

	const float m_Speed{ 400.0f };

	std::map<Collision::CollisionDirection, WorldTile *> m_ContactMap;

	Vector2f m_Acc;
	Vector2f m_Gravity { 0, -1000.0f };
	float m_BobTimer{ 0.0f };
	const float m_BobTime{ 0.1f };
	bool m_BobUp{ true };

	Vector2f m_DigDestination{};
	bool m_Digging{ false };
	Vector2f m_DigStart{};
	float m_DigProgress{};
	bool m_HasDeletedTile{ false };
	WorldTile* m_DigTile{ nullptr };

	int m_ToAddPoints{ 0 };
	GroundTileType* m_ToAddTile{ nullptr };
	
	bool m_IsDiggingPrimed{ false };

	std::vector<Particle*> m_DigParticles{}; 
	std::vector<Particle*> m_SmokeParticles{};
	float m_SmokeTimer{ 0.0f };
	const float m_SmokeTime{ 0.25f };

	const float m_DigTime{ 0.5f };

	bool m_IsDead{ false };
	bool m_HasPlayedDeathAnimation{ false };

	bool m_Grounded { false };
	bool m_IsTurning{ false };

	bool m_DidJustDigRight { false };
	bool m_DidJustDigLeft { false };
	Animation* m_CurrentAnimation{ nullptr };
	Animation* m_WalkAnimation;
	Animation* m_TurnAnimation{ nullptr };
	Animation* m_DigStartAnimation{ nullptr };
	Animation* m_DigAnimation{ nullptr };

	Animation* m_FlyStartAnimation{ nullptr };
	Animation* m_FlyAnimation{ nullptr };
	Animation* m_FlyTurnAnimation{ nullptr };

	Animation* m_DieStartAnimation{ nullptr };
	Animation* m_DieLoopAnimation{ nullptr };
	
	bool m_IsPropellorDeployed{ false };

	PlayerState m_State { PlayerState::Idle };
	PlayerDirection m_Direction { PlayerDirection::Left };
	DigDirection m_DigDirection { DigDirection::Right };

	SoundEffect* m_IdleSound{ nullptr };
	SoundEffect* m_WalkSound{ nullptr };
	SoundEffect* m_DigSound{ nullptr };
	SoundEffect* m_FlySound{ nullptr };

	SoundEffect* m_CurrentSound{ nullptr };
	SoundEffect* m_PrevSound{ nullptr };

	bool m_DidSoundChange{ false };

	//Testing
	bool m_DrawCollisionRect { false };
};
