#include "Extensions.h"
#include "Renderer.h"
#include "Mesh.h"
#include "3dsftk.h"

void	CMesh::Free(){
	if ( Vertices ) delete[] Vertices; Vertices = NULL;
	if ( Indices ) delete[] Indices; Indices = NULL;
}

void	CMesh::Alloc(){
	Free();
	Vertices = new Vertex[ VerticesCount ];
	Indices = new uint[ IndicesCount ];
}

bool	CMesh::Load3ds( const char* Name ){
	file3ds* file_3ds		= OpenFile3ds( Name, "rw" );
	database3ds* db			= NULL;
	mesh3ds* mesh_3ds		= NULL;
	material3ds* mat3ds		= NULL;
	InitDatabase3ds( &db );
	CreateDatabase3ds( file_3ds, db );
	if ( GetMeshCount3ds( db ) == 0 ) return false;
	GetMeshByIndex3ds( db, 0, &mesh_3ds );
	point3ds* v3ds		= mesh_3ds->vertexarray;
	face3ds* f3ds		= mesh_3ds->facearray;
	textvert3ds* uv3ds	= mesh_3ds->textarray;

	VerticesCount = mesh_3ds->nvertices;
	IndicesCount = mesh_3ds->nfaces * 3;
	Alloc();

	for ( int v=0; v<VerticesCount; v++ ){
		Vertices[v].Coord.x = v3ds[v].x * 0.02f;
		Vertices[v].Coord.y = v3ds[v].z * 0.02f;
		Vertices[v].Coord.z = v3ds[v].y * 0.02f;

		Vertices[v].UV.x	= uv3ds[v].u;
		Vertices[v].UV.y	= -uv3ds[v].v;
	}

	for ( int f=0; f<mesh_3ds->nfaces; f++ ){
		Indices[ f*3 + 0 ] = f3ds[f].v1;
		Indices[ f*3 + 1 ] = f3ds[f].v2;
		Indices[ f*3 + 2 ] = f3ds[f].v3;
	}
	Upload();
	return true;
}

void	CMesh::Upload(){
	Unload();
	glGenBuffersARB( 2, ID );
	if ( ID[0] == 0 || ID[1] == 0 ) return;
    glBindBufferARB( GL_ARRAY_BUFFER_ARB, ID[0] );
    glBufferDataARB( GL_ARRAY_BUFFER_ARB, VerticesCount * sizeof( Vertex ), Vertices, GL_STATIC_DRAW_ARB );
	glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, ID[1] );
	glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, IndicesCount * sizeof( uint ), Indices, GL_STATIC_DRAW_ARB );
	glEnableClientState( GL_VERTEX_ARRAY );
	glEnableClientState( GL_NORMAL_ARRAY );
	glEnableClientState( GL_TEXTURE_COORD_ARRAY );
}

void	CMesh::Unload(){
	if ( ID[0] != 0 )	glDeleteBuffersARB( 1, &ID[0] );	ID[0] = 0;
	if ( ID[1] != 0 )	glDeleteBuffersARB( 1, &ID[1] );	ID[1] = 0;
}

void	CMesh::Render(){
	glColor3f( 1,1,1 );
	glBindBufferARB( GL_ARRAY_BUFFER_ARB,			ID[0] );
    glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB,	ID[1] );

    glVertexPointer( 3, GL_FLOAT, sizeof( Vertex ), (byte*)NULL );
	glNormalPointer( GL_FLOAT, sizeof( Vertex ), (byte*)NULL + sizeof( float3 ) );
	glTexCoordPointer( 2, GL_FLOAT, sizeof( Vertex ), (byte*)NULL + sizeof(float3)*2 );
	glDrawElements( GL_TRIANGLES, IndicesCount, GL_UNSIGNED_INT, (UINT*)NULL + 0 );
}
