#ifndef EDITOR_CAMERA_HPP
#define EDITOR_CAMERA_HPP

#include "camera.hpp"
#include "open_engine/events/event.hpp"
#include "open_engine/events/mouse_event.hpp"

#include <glm/glm.hpp>

namespace OpenEngine {

	class EditorCamera : public OpenEngine::Camera
	{
	public:
		EditorCamera() = default;
		EditorCamera(float fov, float aspect_ratio, float near_clip, float far_clip);

		void OnUpdate();
		void OnEvent(Event& e);

		inline float GetDistance() const { return distance; }
		inline void SetDistance(float _distance) { distance = _distance; }

		inline void SetViewportSize(float width, float height) { viewport_width = width; viewport_height = height; UpdateProjection(); }

		const glm::mat4& GetViewMatrix() const { return view_matrix; }
		glm::mat4 GetViewProjection() const { return projection * view_matrix; }

		glm::vec3 GetUpDirection() const;
		glm::vec3 GetRightDirection() const;
		glm::vec3 GetForwardDirection() const;
		const glm::vec3& GetPosition() const { return position; }
		glm::quat GetOrientation() const;

		float GetPitch() const { return pitch; }
		float GetYaw() const { return yaw; }

        bool GetMoving() { return moving; };

	private:
		void UpdateProjection();
		void UpdateView();

		bool OnMouseScroll(MouseScrolledEvent& e);

		void MousePan(const glm::vec2& delta);
		void MouseRotate(const glm::vec2& delta);
		void MouseZoom(float delta);

		glm::vec3 CalculatePosition() const;

		std::pair<float, float> PanSpeed() const;
		float RotationSpeed() const;
		float ZoomSpeed() const;

	private:
		float fov = 45.0f, aspect_ratio = 1.778f, near_clip = 0.1f, far_clip = 1000.0f;

		glm::mat4 view_matrix;
		glm::vec3 position = { 0.0f, 0.0f, 0.0f };
		glm::vec3 focal_point = { 0.0f, 0.0f, 0.0f };

		glm::vec2 initial_mouse_position = { 0.0f, 0.0f };

		float distance = 10.0f;
		float pitch = 0.0f, yaw = 0.0f;

        bool moving = false;

		float viewport_width = 1280, viewport_height = 720;
	};

}

#endif // EDITOR_CAMERA_HPP
