#pragma once
#include "Deer/Components.h"

#include "DeerRender/Mesh.h"
#include "DeerRender/Shader.h"

#define GLM_ENABLE_EXPERIMENTAL
#include "glm/gtc/quaternion.hpp"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"

#define MAX_TEXTURE_BINDINGS 4

namespace Deer {
	struct MeshComponent {
		MeshComponent() { clear(); }
		MeshComponent(uint16_t _meshId) : meshId(_meshId), active(true) { } 
		MeshComponent(const MeshComponent&) = default;

		inline void setMesh(uint16_t _meshId) {
			meshId = _meshId;
		}

		inline void clear() {
			meshId = 0;
		}

		inline VertexArray& getMesh() {
			return MeshManager::getModel(meshId);
		}

		inline const Path& getMeshName() {
			return MeshManager::getModelName(meshId);
		}

		inline bool hasMesh() {
			return meshId != 0;
		}

		inline bool isActive() {
			return active;
		}

		inline bool setActive(bool value) {
			return active = value;
		}
	private:
		uint16_t meshId;
		bool active = true;
	};

	struct ShaderComponent {
		ShaderComponent() { clear(); }
		ShaderComponent(uint16_t _shaderId) : shaderId(_shaderId) { } 
		ShaderComponent(const ShaderComponent&) = default;

		inline void setShader(uint16_t _shaderId) {
			shaderId = _shaderId;
		}

		inline Shader& getShader() {
			return ShaderManager::getShader(shaderId);
		}

		inline const Path& getName() {
			return ShaderManager::getShaderName(shaderId);
		}

		inline bool hasShader() {
			return shaderId != 0;
		}

		inline void clear() {
			shaderId = 0;
		}

	private:
		uint16_t shaderId;
	};

	struct CameraComponent {
		CameraComponent() = default;
		CameraComponent(const CameraComponent&) = default;

		float fov = glm::radians(50.0f);
		float aspect = 16 / 9;
		float nearZ = 0.1f;
		float farZ = 1000;

		inline glm::mat4 getMatrix() const { return glm::perspective(fov, aspect, nearZ, farZ); }
	};

}