
#include <exception>
#include <vector>
#include <glad/glad.h>

struct Vertex {
	float x, y, z;          // position
	float nX, nY, zY;       // normal
	float u, v;             // texcoord
};

class Mesh
{
public:
	unsigned int VBO, VAO, EBO;
	std::size_t indexCount = 0;

	Mesh(const std::vector<Vertex>& vertices, const std::vector<unsigned int>& indices) : indexCount(indices.size())
	{
		if (vertices.empty() || indices.empty()) {
			throw std::runtime_error("Mesh created with empty vertices or indices");
		}
		
		try
		{
			glGenVertexArrays(1, &VAO);
			glGenBuffers(1, &VBO);
			glGenBuffers(1, &EBO);

			glBindVertexArray(VAO);

			glBindBuffer(GL_ARRAY_BUFFER, VBO);
			glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW);

			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
			glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);

			// Position
			glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, x));
			glEnableVertexAttribArray(0);

			// Normals
			glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, nX));
			glEnableVertexAttribArray(1);

			// Texcoords
			glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, u));
			glEnableVertexAttribArray(2);
		}
		catch (...)
		{
			std::cout << "Failed to load mesh" << std::endl;
		}
	}

	void Draw() const
	{
		//glDrawArrays(GL_TRIANGLES, 0, 36);
		glBindVertexArray(VAO);
		glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(indexCount),
					   GL_UNSIGNED_INT, 0);
	}
};
