#include "Mesh.h"

MeshManager *MM = NULL;

MeshManager::MeshManager() {
	MM = this;

	nmesh = 0;
	maxmesh = 64;
	MSH = new MESHTPL [maxmesh];
	memset( MSH, 0, sizeof(MESHTPL)*maxmesh );
}

MeshManager::~MeshManager() {
	for( UINT j = 0; j < nmesh; j++ )
		delete MSH[j].TMesh;
	delete [ ] MSH;
}

void MeshManager::Store( MESHHANDLE hMesh ) {
	if( nmesh == maxmesh ) {
		MESHTPL *tmp = new MESHTPL [maxmesh+32];
		memset( tmp, 0, sizeof(MESHTPL)*(maxmesh+32) );
		memcpy( tmp, MSH, sizeof(MESHTPL)*maxmesh );
		delete [ ] MSH;
		MSH = tmp;
		maxmesh += 32;
	}

	MSH[nmesh].mesh = hMesh;
	MSH[nmesh].TMesh = new D3D11TPLMesh( hMesh );
	nmesh++;
}

D3D11TPLMesh *MeshManager::Find( MESHHANDLE hMesh ) {
	for( UINT j = 0; j < nmesh; j++ )
		if( MSH[j].mesh == hMesh )
			return MSH[j].TMesh;
	return NULL;
}

void MeshManager::UpdateAMSOMesh( MESHHANDLE hMesh ) {
	UINT j, i, k;

	for( j = 0; j < nmesh; j++ )
		if( MSH[j].mesh == hMesh ) {
			if( MSH[j].TMesh ) {
				DWORD ngrp = MSH[j].TMesh->ngrp;
				for( i = 0; i < ngrp; i++ ) {
					MGROUP &G = MSH[j].TMesh->GR[i];
					MESHGROUPEX *mg = oapiMeshGroupEx( hMesh, i );
					if( mg ) {
						for( k = 0; k < mg->nVtx; k++ ) {
							MSH[j].TMesh->_VB[G.svtx + k].pos.x = mg->Vtx[k].x;
							MSH[j].TMesh->_VB[G.svtx + k].pos.y = mg->Vtx[k].y;
							MSH[j].TMesh->_VB[G.svtx + k].pos.z = mg->Vtx[k].z;

							MSH[j].TMesh->_shadow_VB[G.svtx + k].x = mg->Vtx[k].x;
							MSH[j].TMesh->_shadow_VB[G.svtx + k].y = mg->Vtx[k].y;
							MSH[j].TMesh->_shadow_VB[G.svtx + k].z = mg->Vtx[k].z;
						}
						MSH[j].TMesh->ComputeTangents( &G );
						MSH[j].TMesh->ComputeBoundingBox( G );
					}
				}
				DWORD nmat = oapiMeshMaterialCount( hMesh );
				for( k = 0; k < nmat; k++ )
					MSH[j].TMesh->LoadMaterial( MSH[j].TMesh->MAT[k], oapiMeshMaterial( hMesh, k ) );
			}
			break;
		}
}