#pragma once

#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/geometric.hpp>
#include <GameObject.h>
#include <Camera.h>
#include <LevelMap.h>
#include <InputEnums.h>
#include <memory>

class PlayerInputComponent;

class Player : public GameObject
{
	std::vector<Sector>& LevelSectors;
	Sector* CurrentSector;
	float Yaw = -90.0f;
	float MouseSensitivity = 0.1f;
	
	// movement variables
	float WalkSpeed = 5.0f;
	float RunSpeed = 15.0f;
	bool bIsRunning = false;

	float JumpForce = 5.0f;
	float JumpVelocity = 0.0f;
	bool bJumping = false;
	const float GRAVITY = 9.8f;

	// collision constants
	const float STEP_HEIGHT = 0.25f;
	const float PLAYER_HEIGHT = 2.0f;
	const float PLAYER_RADIUS = 1.0f;

	bool CrossingWall(glm::vec3 NewPosition);
	bool LineSegmentsIntersect(const glm::vec2& p1, const glm::vec2& p2, const glm::vec2& q1, const glm::vec2& q2);
	float PointToLineSegmentDistance(const glm::vec2& point, const glm::vec2& segA, const glm::vec2& segB);
	bool PointInPolygon(glm::vec2 point, std::vector<Wall> polygon);
	bool CanFitInNextSector(Sector Sector);

	std::unique_ptr<PlayerInputComponent> cPlayerInput;

public:
	std::unique_ptr<Camera> PlayerCamera;

	Player(glm::vec3 Position, glm::vec3 Rotation, std::vector<Sector>& LevelSectors, GLFWwindow* Window);
	~Player() = default;

	void Update(float DeltaTime);
	void Move(EInputDirection Direction, float Delta);
	void Jump();
	void Sprint();
	void StopSprint();
	void Look(float XOffset, float YOffset, GLboolean bConstrainPitch = true);

	glm::mat4 GetViewMatrix() const;

};

