#ifndef POLYGUN_ENGINE_CAMERA_H
#define POLYGUN_ENGINE_CAMERA_H

#include "game/core.hpp"

namespace polygun::engine {
	enum camera_movement {
		FORWARD,
		BACKWARD,
		LEFT,
		RIGHT,
		UP,
		DOWN
	};

	const float YAW         = 45.0f;
	const float PITCH       =  0.0f;
	const float SPEED       =  2.5f;
	const float SENSITIVITY =  0.1f;
	const float FOV        =  90.0f;

	class Camera {
	public:
		glm::vec3 m_position;
		glm::vec3 m_front;
		glm::vec2 m_movement_front;
		glm::vec3 m_up;
		glm::vec3 m_right;
		glm::vec3 m_worldup;
		float m_yaw;
		float m_pitch;
		float m_movement_speed;
		float m_mouse_sensitivity;
		float m_fov;

		Camera(glm::vec3 position = glm::vec3(-0.5f, 0.25f, -0.5f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH);
		Camera(float pos_x, float pos_y, float pos_z, float up_x, float up_y, float up_z, float yaw, float pitch);

		glm::mat4 get_view_matrix() const {
			return glm::lookAt(m_position, m_position + m_front, m_up);
		}

		void update(bool reset);
		void process_movement(camera_movement direction, float delta_time);
		void process_mouse_movement(float x_offset, float y_offset, GLboolean constrain_pitch = true);
		void process_mouse_scroll(float y_offset);

		static void mouse_callback(GLFWwindow* window, double x_pos_in, double y_pos_in);

	private:
		void update_camera_vectors();

		float m_last_x;
		float m_last_y;
		bool m_first_mouse;
	};
}

#endif // POLYGUN_ENGINE_CAMERA_H
