#include "utility/debugdraw.h"

Circle::Circle(const glm::vec3& position, float radius)
{
	this->radius = radius;
	float vertex[4] = {
		position.x, position.y, position.z, radius
	};

	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);

	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);

	glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), &vertex, GL_DYNAMIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
	glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);
	setMVP(glm::mat4(1.f));
	setColor(glm::vec4(1.f, 0.0f, 0.0f, 1.0f));
}

void Circle::updatePosition(const glm::vec3& position)
{
	float vertex[4] = {
		position.x, position.y, position.z, radius
	};
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	float* ptr = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
	if (ptr)
	{
		for (int i = 0; i < sizeof(vertex) / sizeof(float); i++)
		{
			ptr[i] = vertex[i];
		}
		glUnmapBuffer(GL_ARRAY_BUFFER);
	}
	glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void Circle::draw()
{
	glBindVertexArray(VAO);
	glPointSize(2.0f);
	glDrawArraysInstanced(GL_POINTS, 0, 1, 360);
	glBindVertexArray(0);
}

Circle::~Circle()
{
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);
}

Line::Line(glm::vec3 start, glm::vec3 end)
{
	float vertices[] = {
		start.x, start.y, start.z,
		end.x,   end.y,   end.z
	};

	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);

	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);

	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_DYNAMIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);
	color = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
}

void Line::updateVertices(const glm::vec3& origin, const glm::vec3& target)
{
	float vertices[] = {
		origin.x, origin.y, origin.z,
		target.x, target.y, target.z
	};
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	float* ptr = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
	if (ptr)
	{
		for (int i = 0; i < sizeof(vertices) / sizeof(vertices[0]); i++)
		{
			ptr[i] = vertices[i];
		}
		glUnmapBuffer(GL_ARRAY_BUFFER);
	}
	glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void Line::draw()
{
	glBindVertexArray(VAO);
	glLineWidth(2.0f);
	glDrawArrays(GL_LINES, 0, 2);
	glBindVertexArray(0);
}

Line::~Line()
{
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);
}
