#pragma once

#ifndef __gx_indexbuffer_h__
	#define __gx_indexbuffer_h__

#include "buffer.h"

namespace Gx
{
	struct IndexElementType
	{
		enum Enum
		{
			UnsignedShort,
			UnsignedInteger
		};
	};

	class GX_API  IndexBuffer : public Buffer
	{
		friend class GraphicsDevice;

	public:
		template<typename T>
		void setData(const T* data) {
			GX_ASSERT(sizeof(T) == m_indexSize, "Mismatch index type size.");
			this->copyData(m_indexCount * m_indexSize, reinterpret_cast<const GLvoid*>(data));
		}

		GLuint getIndexCount() const {
			return m_indexCount;
		}

		GLuint getIndexSize() const {
			return m_indexSize;
		}

		void bind() {
			glBindBuffer(m_target, m_id);
		}

		void unbind() {
			glBindBuffer(m_target, 0);
		}

	protected:
		IndexBuffer(IndexElementType::Enum indexElementType, GLuint indexCount, GLenum usage)
			: Buffer(GL_ELEMENT_ARRAY_BUFFER, usage), m_indexCount(indexCount)
		{
			m_indexSize = this->getTypeSize(indexElementType);
			this->reserve(indexCount * m_indexSize);
		}

		GLuint getTypeSize(IndexElementType::Enum type)
		{
			GLuint size = 0;

			switch(type)
			{
			case IndexElementType::UnsignedShort:		size = 2; break;
			case IndexElementType::UnsignedInteger:		size = 4; break;
			}

			GX_ASSERT(size != 0, "Cannot compute index type size.");

			return size;
		}
		

	private:
		GLuint m_indexCount;
		GLuint m_indexSize; // in bytes
	};
}

#endif /* __gx_indexbuffer_h__ */