//
// Asura_Mesh_System.h
//
// Created by Kevin Lea - 12/06/2001 11:16:08
// 
// Copyright (C) 2001 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef __ASURA_MESH_SYSTEM_H__
#define __ASURA_MESH_SYSTEM_H__

class Asura_Matrix_3x3;
class Asura_Mesh;
class Asura_String;
class Asura_Vector_3;

#include "Core/Asura_NameTree.h"
#include "Network/Asura_Guid.h"

// RICHARDS	#define ASURA_MAX_NO_OF_MESHES 1000
#define ASURA_MAX_NO_OF_MESHES 8000

class Asura_Mesh_System
{
	public:
			static void Initialise(void);
			static void Shutdown(void);
			static void Reset(void);

            static Asura_Mesh* GetMesh( const Asura_Char* szName, bool bCreate = false );

			static inline Asura_Mesh* GetMesh( const Asura_String& xName, bool bCreate = false )
            {
                return GetMesh( xName.GetString(), bCreate );
            }

			static inline Asura_Mesh* GetMesh(int i)
			{
				return MeshStorage[i];
			}

			static inline int GetNumberOfMeshes(void)
			{
				return NumberOfMeshesStored;
			}

			//Delete a mesh , and remove it from the Asura_Mesh_System.
			//WARNING!!!
			//This won't currently delete project specific mesh data correctly. This is mainly intended
			//at the moment so that I can get rid of any unwanted LOD meshes.
			//RAR 05/09/02			
			// (RMS) 11 Sep 2002 - I am using this in the new shape table code to remove unwanted shapes
			static void DeleteMesh(Asura_Mesh* pxMesh);

			#ifdef ASURA_TOOLS
			static bool RenameMesh(Asura_Mesh* pxMesh,const char* pszName);
			#endif
			

			// KJL - 12-Apr-01 17:03:37 - platform specific functions; called by Asura_Render
			static void PlatformInitialiseRenderMeshes(void);
			static void PlatformShutdownRenderMeshes(void);
			static void PlatformResetRenderMeshes(void);
			static void PlatformRenderMesh( Asura_Mesh* pxMesh, const Asura_Vector_3* pxPos, const Asura_Matrix_3x3* pxOri );
            static void PlatformRenderMeshHighlight( Asura_Mesh* pxMesh,
                                                     const Asura_Vector_3* pxPos,
                                                     const Asura_Matrix_3x3* pxOri,
                                                     u_int uColour,
                                                     bool bWireframe,
                                                     bool bOffset );
			static void Asura_Mesh_System::PlatformResetRenderMesh(Asura_Mesh* mesh);

#if defined(ASURA_TOOLS) && defined(ASURA_MAIN)
			//So tools can force patch subdivision to be redone , without resetting prelighting etc.
			static void Asura_Mesh_System::PlatformResetRenderMeshesOnly();
			//Similarly for a single mesh.. RAR 17/03/03
			static void Asura_Mesh_System::PlatformResetRenderMeshOnly(const Asura_Mesh* pxMesh);
			//So tools can force recalulation of prelighting without re subdividing and rebuilding normals
			static void Asura_Mesh_System::PlatformResetMeshLightingOnly(Asura_Mesh* mesh);
            static u_int Platform_GetRenderMeshTriCount( int iIndex );

			static void Asura_Mesh_System::PlatformDeleteMesh( int iIndex );
#endif //defined(ASURA_TOOLS) && defined(ASURA_MAIN)
			
			/// Richard May - 30/07/2002 15:07:37 - special render function that includes the 'don't render for
			/// this camera' & 'render only for this camera' stuff as per usual. 
			static void RenderAsuraMesh(Asura_Mesh* mesh, Asura_Guid guid, const Asura_Vector_3* position, const Asura_Matrix_3x3* orientation, const unsigned uCamVisFlags );
			
		private:
			static Asura_Mesh* MeshStorage[ASURA_MAX_NO_OF_MESHES];
			static int NumberOfMeshesStored;
			static Asura_NameTree* NameTree;

			static Asura_Mesh* MeshExistsWithThisName( const Asura_String& name );

		

};

#endif//__ASURA_MESH_SYSTEM_H__
