//	Darkstar Engine  (c) UnderWorld Interactive Studio (all coding by Svarog    2007-2008)
//
//      Данный файл является частью Darkstar Engine. Любое использование кода файла
//      без согласия компании, является нарушением закона об авторском праве (в слу-
//      чае если не оговорено обратное).
//
//      Имя файла: vertex_buffer.hpp
//      Краткое описание: Вершинный буфер
//

#include <Darkstar/Resource System/Model/vertex_buffer.hpp>
#include <Darkstar/Kernel/logh.hpp>

using namespace rs;
using gs::GraphicDriver;
using ker::Log;

VertexBuffer::VertexBuffer(const shared_ptr<InputLayout>& il)
{
	input_layout = il;
	elems_count = 0;
};

VertexBuffer::~VertexBuffer()
{
	streams.clear();
};

int VertexBuffer::createNextStream(const unsigned int stream_elem_size, const unsigned int elems_count, 
								   const DEUSAGE& usage /* = DEU_DYNAMIC */)
{
	shared_ptr<VertexStream> new_stream(new VertexStream);
	if(this->elems_count != 0)
	{
		if(this->elems_count != elems_count)
		{
			lwar << "Number of elements in different vertex stream is not equal each other";
			return -1;
		};
	}
	else
		this->elems_count = elems_count;
		
	if(!new_stream->create(stream_elem_size, elems_count, usage))
	{
		lwar << "Cannot create new stream";
		return -1;
	}
	else
	{
		streams.push_back(new_stream);
		return (int)(streams.size()-1);
	};
};

int VertexBuffer::createNextStreamWithData(const unsigned int stream_elem_size, 
										   const unsigned int elems_count, void* data, 
										   const DEUSAGE& usage /* = DEU_DEFAULT */)
{
	shared_ptr<VertexStream> new_stream(new VertexStream);
	if(this->elems_count != 0)
	{
		if(this->elems_count != elems_count)
		{
			lwar << "Number of elements in different vertex stream is not equal each other";
			return -1;
		};
	}
	else
		this->elems_count = elems_count;
	if(!new_stream->createWithData(stream_elem_size, elems_count, data, usage))
	{
		lwar << "Cannot create new stream with data";
		return -1;
	}
	else
	{
		streams.push_back(new_stream);
		return (int)(streams.size()-1);
	};
};

bool VertexBuffer::uploadStream(const unsigned int stream_num, const unsigned int size, void* data, const unsigned int offset /* = 0 */)
{
	if(stream_num >= streams.size())
	{
		lwar << "In this vertex buffer cannot exist vertex stream with num: " << stream_num;
		return false;
	};
	streams[stream_num]->upload(size, data, offset);
	return true;
};

void* VertexBuffer::mapStream(const unsigned int stream_num, const DEMAPTYPE& map_type /* = DEMT_WRITE */)
{
	if(stream_num >= streams.size())
	{
		lwar << "In this vertex buffer cannot exists vertex stream with number of stream: " << stream_num;
		return NULL;
	};
	return streams[stream_num]->map(map_type);
};

void VertexBuffer::unmapStream(const unsigned int stream_num)
{
	if(stream_num >= streams.size())
	{
		lwar << "In this vertex buffer cannot exists vertex stream with number of stream: " << stream_num;
		return;
	};
	streams[stream_num]->unmap();
};

unsigned int VertexBuffer::getElementsCount() const
{
	return elems_count;
};