
#include <Spectre/Graphics/Renderer2D.h>
#include <Spectre/Graphics/Texture.h>
#include <Spectre/Graphics/Sprite.h>

Sprite::Sprite() :
m_texture	(NULL)
{
	unsigned short indices[6] = {
		0, 1, 2, 2, 3, 0
	};

	m_indicies.assign(indices, indices + 6);
	m_vertices.resize(4);

	setSize(vec2f(1.0f, 1.0f));
	setColor(Color(255, 255, 255));

	// Texcords
	m_vertices[0].uv = Vector2f( 0.0f,  0.0f);
	m_vertices[1].uv = Vector2f( 0.0f,  1.0f);
	m_vertices[2].uv = Vector2f( 1.0f,  1.0f);
	m_vertices[3].uv = Vector2f( 1.0f,  0.0f);
}

Sprite::Sprite(const vec2f& pos, const vec2f& size) :
m_texture	(NULL)
{
	unsigned short indices[6] = {
		0, 1, 2, 2, 3, 0
	};

	m_indicies.assign(indices, indices + 6);
	m_vertices.resize(4);

	setPosition(pos);
	setSize(size);
	setColor(Color(255, 255, 255));

	m_vertices[0].uv = Vector2f( 0.0f,  1.0f);
	m_vertices[1].uv = Vector2f( 0.0f,  0.0f);
	m_vertices[2].uv = Vector2f( 1.0f,  0.0f);
	m_vertices[3].uv = Vector2f( 1.0f,  1.0f);
}

void Sprite::init()
{
}

void Sprite::setSize(vec2f size)
{
	if (size < vec2f(0.0, 0.0f)) {
		size = vec2f(0.0, 0.0f);
	}

	m_vertices[0].position = vec2f(0.0f,	0.0f);
	m_vertices[1].position = vec2f(0.0f,	size.y);
	m_vertices[2].position = vec2f(size.x,	size.y);
	m_vertices[3].position = vec2f(size.x,  0.0f);
}

void Sprite::setColor(const Color& color)
{
	m_vertices[0].color = color.toRGBAf();
	m_vertices[1].color = m_vertices[0].color;
	m_vertices[2].color = m_vertices[0].color;
	m_vertices[3].color = m_vertices[0].color;
}

void Sprite::setTexture(const Texture& texture)
{
	m_texture = &texture;
}

void Sprite::setTextureCoords(const vec2u& pos, const vec2u& size)
{
	// No texture, nothing to do.
	if (!m_texture) {
		return;
	}

	Vector2f tex_size = Vector2f(m_texture->getSize());

	float left	= pos.x / tex_size.x;
	float right	= left + (size.x / tex_size.x);
	float top	= pos.y / tex_size.y;
	float bottom	= top + (size.y / tex_size.y); 

	m_vertices[0].uv = Vector2f(left , top);
	m_vertices[1].uv = Vector2f(left , bottom);
	m_vertices[2].uv = Vector2f(right, bottom);
	m_vertices[3].uv = Vector2f(right, top);
}

const Texture* Sprite::getTexture() const
{
	return m_texture;
}

const std::vector<Vertex2D>& Sprite::getVertices() const
{
	return m_vertices;
}

const std::vector<unsigned short>& Sprite::getIndices() const
{
	return m_indicies;
}

void Sprite::updateGeometry()
{
}

void Sprite::render(Renderer2D& renderer) const
{
	renderer.draw(this);
}