#pragma once

#include <vector>

#include "GlInclude.h"


namespace lib_gl
{


//! OpenGL VertexArray用データ管理, 描画呼び出しクラス.
class GlVertexArray
{
public:
	GlVertexArray(void)
	{
		m_VertElemSize  = 3;
		m_UVElemSize    = 2;
		m_PrimitiveType = GL_TRIANGLES;
	}

	void ClearBuffer(void);
	bool GLDraw(void) const;


public:
	GLint                   m_VertElemSize; //!< 頂点バッファの次元 ( 2 , 3 or 4 )
	GLint                   m_UVElemSize;   //!< UVバッファの次元   ( 1 , 2 , 3 or 4 )

	std::vector< GLfloat >  m_Verts;        //!< 頂点バッファ ( size == NumVertex * 3 )
	std::vector< GLfloat >  m_Normals;      //!< 法線バッファ ( size == NumVertex * 3 )
	std::vector< GLfloat >  m_UVs;          //!< UVバッファ   ( size == NumVertex * 2 )

	GLenum                m_PrimitiveType;  //!< 描画オブジェクトの形式.
	std::vector< GLuint > m_IndexBuffer;    //!< インデックスバッファ
};




inline
void GlVertexArray::ClearBuffer(void)
{
	m_Verts.clear();
	m_Normals.clear();
	m_UVs.clear();
	m_IndexBuffer.clear();
}


inline
bool GlVertexArray::GLDraw(void) const
{
	if( m_Verts.empty() ) return false;

	_ASSERTE( m_Verts.size()   % m_VertElemSize == 0 );
	_ASSERTE( m_Normals.size() % 3              == 0 );
	_ASSERTE( m_UVs.size()     % m_UVElemSize   == 0 );
	if( m_Verts.size()   % m_VertElemSize != 0 ) return false;
	if( m_Normals.size() % 3              != 0 ) return false;
	if( m_UVs.size()     % m_UVElemSize   != 0 ) return false;

	GLint num_verts = (GLint)m_Verts.size() / m_VertElemSize;

	// set vertex
	glEnableClientState( GL_VERTEX_ARRAY );
	glVertexPointer( m_VertElemSize , GL_FLOAT , 0 , &m_Verts.front() );

	// set normal
	if( !m_Normals.empty() )
	{
		_ASSERTE( m_Normals.size() / 3 == num_verts );
		if( m_Normals.size() / 3 == num_verts )
		{
			glEnableClientState( GL_NORMAL_ARRAY );
			glNormalPointer  ( GL_FLOAT , 0 , &m_Normals.front() );
		}
	}

	// set uv
	if( !m_UVs.empty() )
	{
		_ASSERTE( m_UVs.size() / m_UVElemSize == num_verts );
		if( m_UVs.size() / m_UVElemSize == num_verts )
		{
			glEnableClientState( GL_TEXTURE_COORD_ARRAY );
			glTexCoordPointer( m_UVElemSize , GL_FLOAT , 0 , &m_UVs.front() );
		}
	}

	glDrawElements( m_PrimitiveType , (GLsizei)m_IndexBuffer.size() , GL_UNSIGNED_INT , &m_IndexBuffer.front() );

	glDisableClientState( GL_VERTEX_ARRAY );
	glDisableClientState( GL_NORMAL_ARRAY );
	glDisableClientState( GL_TEXTURE_COORD_ARRAY );

	return true;
}


}
