#include "SimpleObjectRenderer.h"
#include "VisibleObject.h"
#include "Model.h"
#include "OpenGLMatrix.h"
#include "OpenGLUtils.h"

#include <Utility/Log.h>
#include <stdexcept>

//////////////////////////////////////////////////////////////
namespace Dubious
{
namespace Renderer
{

//////////////////////////////////////////////////////////////
SimpleObjectRenderer::SimpleObjectRenderer()
{
}

//////////////////////////////////////////////////////////////
SimpleObjectRenderer::~SimpleObjectRenderer()
{
	for (auto iter = m_ObjectDataMap.begin(), end = m_ObjectDataMap.end(); iter!=end; ++iter) {
		glDeleteBuffers(1, &iter->second.VertexID);
		glDeleteBuffers(1, &iter->second.IndexID);
	}
}

//////////////////////////////////////////////////////////////
void SimpleObjectRenderer::RenderObject( VisibleObjectPtr pObject )
{
	auto iter = m_ObjectDataMap.find( pObject );
	if( iter == m_ObjectDataMap.end() ){
		m_ObjectDataMap[pObject] = BindToVBO( pObject );
		iter = m_ObjectDataMap.find( pObject );
		if (iter == m_ObjectDataMap.end()) {
			throw std::runtime_error( "SimpleObjectRenderer couldn't find the object it just created" );
		}
	}
	OpenGLMatrix GLMatrix;
	float m[16];
	pObject->CoordinateSpace().GLMatrix( m );
	GLMatrix.MultMatrix( m );

	OpenGLUtils::Material( GL_AMBIENT, pObject->BaseColor() );
	OpenGLUtils::Material( GL_DIFFUSE, pObject->BaseColor() );

	glBindBuffer(GL_ARRAY_BUFFER, iter->second.VertexID);
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(3, GL_FLOAT, VBOData::SIZEOF_BUFFER_DATA, reinterpret_cast<void*>(0));

	glEnableClientState(GL_NORMAL_ARRAY);
	glNormalPointer(GL_FLOAT, VBOData::SIZEOF_BUFFER_DATA, reinterpret_cast<void*>(12));

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iter->second.IndexID);
	glDrawElements(GL_TRIANGLES, iter->second.IndexCount, GL_UNSIGNED_SHORT, reinterpret_cast<void*>(0));
}

//////////////////////////////////////////////////////////////
void SimpleObjectRenderer::ResetGL()
{
	m_ObjectDataMap.clear();
}

}
}
