/// Copyright (c) 2010 Ruben Penalva. All rights reserved.
/// Redistribution and use in source and binary forms, with or without modification, 
/// are permitted provided that the following conditions are met:
///    1. Redistributions of source code must retain the above copyright notice, this 
///    list of conditions and the following disclaimer.
///    2. Redistributions in binary form must reproduce the above copyright notice,
///    this list of conditions and the following disclaimer in the documentation and/or
///    other materials provided with the distribution.
///    3. The name of the author may not be used to endorse or promote products derived
///    from this software without specific prior written permission.
///
/// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
/// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 
/// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
/// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
/// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
/// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
/// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef _OPENGL_INDEX_BUFFER_H_
#define _OPENGL_INDEX_BUFFER_H_

#include <GL\glew.h>
#include <boost\shared_array.hpp>
#include "OpenglException.h"

namespace TestFrameWork
{

template<class T>
class OpenglIndexBuffer
{
public:
	OpenglIndexBuffer(boost::shared_array<T> indices, size_t indicesCount);

	~OpenglIndexBuffer(void);

	GLuint GetOpenglId(void) const;

	size_t GetIndicesCount(void) const;

private:
	GLuint m_id;

	size_t m_indicesCount;

	GLuint CreateBuffer(boost::shared_array<T> indices, size_t indicesCount);
};

typedef OpenglIndexBuffer<int> OpenglIndexBuffer32;
typedef boost::shared_ptr<OpenglIndexBuffer32> OpenglIndexBuffer32Ptr;
typedef boost::shared_array<int> Indices32;

template<class T>
OpenglIndexBuffer<T>::OpenglIndexBuffer(boost::shared_array<T> indices, size_t indicesCount)	:	m_id(CreateBuffer(indices, indicesCount)), 
																									m_indicesCount(indicesCount)
{

}

template<class T>
OpenglIndexBuffer<T>::~OpenglIndexBuffer(void)
{
	glDeleteBuffers(1, &m_id);
}

template<class T>
GLuint OpenglIndexBuffer<T>::GetOpenglId(void) const
{
	return m_id;
}

template<class T>
size_t OpenglIndexBuffer<T>::GetIndicesCount(void) const
{
	return m_indicesCount;
}

template<class T>
GLuint OpenglIndexBuffer<T>::CreateBuffer(boost::shared_array<T> indices, size_t indicesCount)
{
	GLuint id;
	glGenBuffers(1, &id);
	TestFrameWork::OnGLErrorThrowException();

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id);
	TestFrameWork::OnGLErrorThrowException();

	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(T) * indicesCount, indices.get(), GL_STATIC_DRAW);
	TestFrameWork::OnGLErrorThrowException();

	return id;
}

}

#endif