///////////////////////////////////////////////////////////////////////////////
//
// Name:		VertexBufferManager.cpp
// Author:		Rich Cross
// Contact:		rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#include "precompiled.h"

#include "lib/ogl.h"
#include "VertexBufferManager.h"
#include "ps/CLogger.h"

#define LOG_CATEGORY "graphics"

// janwas 2004-06-14: added dtor

CVertexBufferManager::~CVertexBufferManager()
{
}

///////////////////////////////////////////////////////////////////////////////
// Explicit shutdown of the vertex buffer subsystem.
// This avoids the ordering issues that arise when using destructors of
// global instances.
void CVertexBufferManager::Shutdown()
{
	typedef std::list<CVertexBuffer*>::iterator Iter;
	for (Iter iter=m_Buffers.begin();iter!=m_Buffers.end();++iter)
		delete *iter;
	
	CVertexBuffer::Shutdown();
}


///////////////////////////////////////////////////////////////////////////////
// Allocate: try to allocate a buffer of given number of vertices (each of 
// given size), with the given type, and using the given texture - return null 
// if no free chunks available
CVertexBuffer::VBChunk* CVertexBufferManager::Allocate(size_t vertexSize,size_t numVertices,bool dynamic)
{
	CVertexBuffer::VBChunk* result=0;

	// TODO, RC - run some sanity checks on allocation request

	// iterate through all existing buffers testing for one that'll 
	// satisfy the allocation
	typedef std::list<CVertexBuffer*>::iterator Iter;
	for (Iter iter=m_Buffers.begin();iter!=m_Buffers.end();++iter) {
		CVertexBuffer* buffer=*iter;
		result=buffer->Allocate(vertexSize,numVertices,dynamic);
		if (result) return result;
	}

	// got this far; need to allocate a new buffer
	CVertexBuffer* buffer=new CVertexBuffer(vertexSize,dynamic);
	m_Buffers.push_front(buffer);
	result=buffer->Allocate(vertexSize,numVertices,dynamic);
	
	// TODO, RC - debug_assert not really suitable?  probably need to handle "failed to create 
	// VBO case" better
	if (!result)
	{
		LOG(ERROR, LOG_CATEGORY, "Failed to create VBOs");
		debug_warn("Failed to create VBOs");
	}

	return result;
}

///////////////////////////////////////////////////////////////////////////////
// Release: return given chunk to its owner
void CVertexBufferManager::Release(CVertexBuffer::VBChunk* chunk)
{
	debug_assert(chunk);
	chunk->m_Owner->Release(chunk);
}

///////////////////////////////////////////////////////////////////////////////
// ClearBatchIndices: empty out the batch lists of all vertex buffers
void CVertexBufferManager::ClearBatchIndices()
{
	typedef std::list<CVertexBuffer*>::iterator Iter;
	for (Iter iter=m_Buffers.begin();iter!=m_Buffers.end();++iter) {
		CVertexBuffer* buffer=*iter;
		buffer->ClearBatchIndices();
	}
}
