
/////////////////////////////////////////////////////////////
// ToolsAVP_SurfaceOverlay.cpp
// Created by Chris Wallace - 31/07/2007
// Copyright (C) 2007 Rebellion, All Rights Reserved.
/////////////////////////////////////////////////////////////

#include "Core/Asura.h"
#include "Material/ToolsAVP_SurfaceOverlay.h"

#include "Blueprint/Asura_Blueprint_System.h"

#include "Interface/Asura_Overlay_System.h"
#include "Interface/Asura_Overlay.h"
#include "Interface/Asura_Dialog.h"
#include "Interface/Asura_Table_Dialog.h"

#include "ToolsAVP_Overlays.h"
#include "Tools_System.h"
#include "Load&Save/Tools_ModeDataFile.h"
#include "Load&Save/Tools_SaveAsura.h"
#include "Sound/Tools_Sound_System.h"

#include "Core/AVP_SurfaceEffects.h"
#include "Entity/Damage/AVP_EntityDamage.h"

#include "ChunkSystem/AVP_Chunk_SurfaceOverlay.h"
#include "Particles/Tools_PFX_Dialog.h"
#include "Misc/Tools_Timed_Messages.h"

/////////////////////////////////////////////
// Gloabal variable declaration
/////////////////////////////////////////////

static const Asura_Vector_2	g_xTestMinimumCellSize(4.0f, Asura_Dialog::DefaultSpacing());
static const Asura_Vector_2	g_xTableSize(60.0f, 20.0f);

static const char*	g_szSurfaceOverlayFilename	= "Misc\\SurfaceEffects.asr";

static const Asura_Hash_ID g_auSurfaceOverlaySelectable_DamageTypeBlueprintTypes[] =
{
	uAVP_BLUEPRINT_TYPE_DAMAGE
};

static const Asura_Hash_ID g_auSurfaceOverlaySelectable_DamageTypeBlueprintParents[] =
{
	uAVP_BLUEPRINT_NAME_DAMAGETYPE
};

static const Asura_Hash_ID g_auSurfaceOverlaySelectable_SurfaceEffectBlueprintTypes[] =
{
	uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS
};

static const Asura_Hash_ID g_auSurfaceOverlaySelectable_SurfaceEffectBlueprintParents[] =
{
	uAVP_BLUEPRINT_NAME_SURFACEEFFECT
};

static const Asura_Hash_ID g_auSurfaceOverlaySelectable_SurfaceTypeBlueprintTypes[] =
{
	uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS
};

static const Asura_Hash_ID g_auSurfaceOverlaySelectable_SurfaceTypeBlueprintParents[] =
{
	uAVP_BLUEPRINT_NAME_SURFACETYPE
};

static const u_int	g_uSurfaceOverlayNumSelectable_DamageTypeBlueprintTypes		= sizeof(g_auSurfaceOverlaySelectable_DamageTypeBlueprintTypes) / sizeof(g_auSurfaceOverlaySelectable_DamageTypeBlueprintTypes[0]);
static const u_int	g_uSurfaceOverlayNumSelectable_DamageTypeBlueprintParents	= sizeof(g_auSurfaceOverlaySelectable_DamageTypeBlueprintParents) / sizeof(g_auSurfaceOverlaySelectable_DamageTypeBlueprintParents[0]);
static const u_int	g_uSurfaceOverlayNumSelectable_SurfaceEffectBlueprintTypes	= sizeof(g_auSurfaceOverlaySelectable_SurfaceEffectBlueprintTypes) / sizeof(g_auSurfaceOverlaySelectable_SurfaceEffectBlueprintTypes[0]);
static const u_int	g_uSurfaceOverlayNumSelectable_SurfaceEffectBlueprintParents= sizeof(g_auSurfaceOverlaySelectable_SurfaceEffectBlueprintParents) / sizeof(g_auSurfaceOverlaySelectable_SurfaceEffectBlueprintParents[0]);
static const u_int	g_uSurfaceOverlayNumSelectable_SurfaceTypeBlueprintTypes	= sizeof(g_auSurfaceOverlaySelectable_SurfaceTypeBlueprintTypes) / sizeof(g_auSurfaceOverlaySelectable_SurfaceTypeBlueprintTypes[0]);
static const u_int	g_uSurfaceOverlayNumSelectable_SurfaceTypeBlueprintParents	= sizeof(g_auSurfaceOverlaySelectable_SurfaceTypeBlueprintParents) / sizeof(g_auSurfaceOverlaySelectable_SurfaceTypeBlueprintParents[0]);


static const Asura_Hash_ID g_auSurfaceOverlaySelectable_EffectTypeBlueprintTypes[] =
{
	uAVP_BLUEPRINT_TYPE_EFFECTTYPES
};

static const Asura_Hash_ID g_auSurfaceOverlaySelectable_EffectTypeBlueprintParents[] =
{
	uAVP_BLUEPRINT_NAME_ACTOR_SURFACE_TYPES		// Actor Surface Types	//	uAVP_BLUEPRINT_NAME_DAMAGETYPE
};

static const u_int	g_uSurfaceOverlayNumSelectable_EffectTypeBlueprintTypes		= sizeof(g_auSurfaceOverlaySelectable_EffectTypeBlueprintTypes  ) / sizeof(g_auSurfaceOverlaySelectable_EffectTypeBlueprintTypes[0]  );
static const u_int	g_uSurfaceOverlayNumSelectable_EffectTypeBlueprintParents	= sizeof(g_auSurfaceOverlaySelectable_EffectTypeBlueprintParents) / sizeof(g_auSurfaceOverlaySelectable_EffectTypeBlueprintParents[0]);





/////////////////////////////////////////////
// Static variable declaration
/////////////////////////////////////////////

Asura_Table_Dialog*	ToolsAVP_SurfaceOverlay::s_pxCollisionTableDialogue	= NULL;
Asura_Table_Dialog*	ToolsAVP_SurfaceOverlay::s_pxEffectTypeTableDialogue= NULL;
Asura_Table_Dialog*	ToolsAVP_SurfaceOverlay::s_pxDamageTableDialogue	= NULL;

Asura_Vector_2	ToolsAVP_SurfaceOverlay::s_xSurfaceOverlayPosition(20.0f,3.0f);
Asura_Vector_2	ToolsAVP_SurfaceOverlay::s_xSurfaceOverlaySize(g_xTableSize);

bool	ToolsAVP_SurfaceOverlay::s_bModified = false;


ToolsAVP_SurfaceOverlay::TypeNameArray	ToolsAVP_SurfaceOverlay::s_xEffectTypes;
ToolsAVP_SurfaceOverlay::TypeNameArray	ToolsAVP_SurfaceOverlay::s_xDamageTypes;
ToolsAVP_SurfaceOverlay::TypeNameArray	ToolsAVP_SurfaceOverlay::s_xSurfaceTypes;
ToolsAVP_SurfaceOverlay::TypeNameArray	ToolsAVP_SurfaceOverlay::s_xMaterialSurfaceTypes;


ToolsAVP_SurfaceOverlay_FilterData ToolsAVP_SurfaceOverlay::s_xCollisionTableColumnFilterData
(
 uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS,
 uAVP_BLUEPRINT_NAME_SURFACETYPE,
 g_uSurfaceOverlayNumSelectable_SurfaceTypeBlueprintTypes,
 g_auSurfaceOverlaySelectable_SurfaceTypeBlueprintTypes,
 g_uSurfaceOverlayNumSelectable_SurfaceTypeBlueprintParents,
 g_auSurfaceOverlaySelectable_SurfaceTypeBlueprintParents
 );

ToolsAVP_SurfaceOverlay_FilterData ToolsAVP_SurfaceOverlay::s_xCollisionTableRowFilterData
(
 uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS,
 uAVP_BLUEPRINT_NAME_SURFACETYPE,
 g_uSurfaceOverlayNumSelectable_SurfaceTypeBlueprintTypes,
 g_auSurfaceOverlaySelectable_SurfaceTypeBlueprintTypes,
 g_uSurfaceOverlayNumSelectable_SurfaceTypeBlueprintParents,
 g_auSurfaceOverlaySelectable_SurfaceTypeBlueprintParents
 );

// I need to fill these data correctly
ToolsAVP_SurfaceOverlay_FilterData ToolsAVP_SurfaceOverlay::s_xEffectTypeTableColumnFilterData
(
 uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS,
 uAVP_BLUEPRINT_NAME_SURFACETYPE,
 g_uSurfaceOverlayNumSelectable_SurfaceTypeBlueprintTypes,
 g_auSurfaceOverlaySelectable_SurfaceTypeBlueprintTypes,
 g_uSurfaceOverlayNumSelectable_SurfaceTypeBlueprintParents,
 g_auSurfaceOverlaySelectable_SurfaceTypeBlueprintParents
 );

// I need to fill these data correctly
ToolsAVP_SurfaceOverlay_FilterData ToolsAVP_SurfaceOverlay::s_xEffectTypeTableRowFilterData
(
 uAVP_BLUEPRINT_TYPE_EFFECTTYPES,
 uAVP_BLUEPRINT_NAME_ACTOR_SURFACE_TYPES,					// Actor Surface Types	//	uAVP_BLUEPRINT_NAME_DAMAGETYPE
 g_uSurfaceOverlayNumSelectable_EffectTypeBlueprintTypes,
 g_auSurfaceOverlaySelectable_EffectTypeBlueprintTypes,
 g_uSurfaceOverlayNumSelectable_EffectTypeBlueprintParents,
 g_auSurfaceOverlaySelectable_EffectTypeBlueprintParents
 );


ToolsAVP_SurfaceOverlay_FilterData ToolsAVP_SurfaceOverlay::s_xDamageTableColumnFilterData
(
	uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS,
	uAVP_BLUEPRINT_NAME_SURFACETYPE,
	g_uSurfaceOverlayNumSelectable_SurfaceTypeBlueprintTypes,
	g_auSurfaceOverlaySelectable_SurfaceTypeBlueprintTypes,
	g_uSurfaceOverlayNumSelectable_SurfaceTypeBlueprintParents,
	g_auSurfaceOverlaySelectable_SurfaceTypeBlueprintParents
);

ToolsAVP_SurfaceOverlay_FilterData ToolsAVP_SurfaceOverlay::s_xDamageTableRowFilterData
(
	uAVP_BLUEPRINT_TYPE_DAMAGE,
	uAVP_BLUEPRINT_NAME_DAMAGETYPE,
	g_uSurfaceOverlayNumSelectable_DamageTypeBlueprintTypes,
	g_auSurfaceOverlaySelectable_DamageTypeBlueprintTypes,
	g_uSurfaceOverlayNumSelectable_DamageTypeBlueprintParents,
	g_auSurfaceOverlaySelectable_DamageTypeBlueprintParents
);


const Asura_Blueprint* ToolsAVP_SurfaceOverlay_FilterData::RequestBlueprint(const char* szRequest)
{
	BlueprintSelect_Overlay xSelectDialog(szRequest,
										  &m_uFilterHash,
										  &m_uTypeHash,
										  m_uNumSelectableBlueprintTypes,
										  m_puSelectableBlueprintTypes,
										  m_uNumSelectableBlueprintParents,
										  m_puSelectableBlueprintParents);

	if(xSelectDialog.DoModal())
	{
		if(m_uFilterHash == uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS)
		{
			m_uFilterHash	= uAVP_BLUEPRINT_NAME_SURFACETYPE;
		}

		return(Asura_Blueprint_System::GetBlueprintByHashID(m_uTypeHash, m_uFilterHash));
	}
	else
	{
		return(NULL);
	}
}


/////////////////////////////////////////////
// ToolsAVP_SurfaceOverlay class]
/////////////////////////////////////////////

void ToolsAVP_SurfaceOverlay::Initialise()
{
	InitialiseArrays();
	LoadAsuraFile( g_szSurfaceOverlayFilename );
}

void ToolsAVP_SurfaceOverlay::Shutdown()
{
	Asura_Overlay_System::CloseOverlays(TOOLSAVP_OVERLAY_SURFACE);
	//TODO - This will never get called, still need to find a place to have this done

	s_xEffectTypes.Deallocate();
	s_xDamageTypes.Deallocate();
	s_xSurfaceTypes.Deallocate();
	s_xMaterialSurfaceTypes.Deallocate();

	s_xDamageTableRowFilterData.Deallocate();
	s_xDamageTableColumnFilterData.Deallocate();
	s_xCollisionTableRowFilterData.Deallocate();
	s_xCollisionTableColumnFilterData.Deallocate();
	s_xEffectTypeTableRowFilterData.Deallocate();
	s_xEffectTypeTableColumnFilterData.Deallocate();

}

void ToolsAVP_SurfaceOverlay::ToggleSurfaceOverlay()
{
	if(SurfaceOverlayIsOn())
	{
		Asura_Overlay_System::CloseOverlays(TOOLSAVP_OVERLAY_SURFACE);
	}
	else
	{
		CreateSurfaceOverlay();		
	}
}

bool ToolsAVP_SurfaceOverlay::SurfaceOverlayIsOn()
{
	return Asura_Overlay_System::DoesOverlayExist(TOOLSAVP_OVERLAY_SURFACE);
}

void ToolsAVP_SurfaceOverlay::SetAsChanged(void)
{
	s_bModified	= true;

	if(s_pxDamageTableDialogue != NULL)
	{
		s_pxDamageTableDialogue->UpdateAll();
	}

	if(s_pxCollisionTableDialogue != NULL)
	{
		s_pxCollisionTableDialogue->UpdateAll();
	}

	if( s_pxEffectTypeTableDialogue != NULL )
	{
		s_pxEffectTypeTableDialogue->UpdateAll();
	}
}

void ToolsAVP_SurfaceOverlay::LoadSettingsFromIniFile()
{
	TransferModeData(TOOLSMODEDATAFILE_LOAD);
}

void ToolsAVP_SurfaceOverlay::SaveSettingsToIniFile()
{
	TransferModeData(TOOLSMODEDATAFILE_SAVE);
}

bool ToolsAVP_SurfaceOverlay::Save( void )
{
	// Save the file to disc...
	const bool bOK = AVP_Chunk_SurfaceOverlay::Save( g_szSurfaceOverlayFilename );
	if( bOK )
	{
		Asura_String	xMessage("Saved \"");

		xMessage	+= g_szSurfaceOverlayFilename;
		xMessage	+= "\" successfully.";

		Tools_Timed_Message_System::AddMessage( 0x00FF00, xMessage.GetString() );
		s_bModified = false;
	}
	else
	{
		Asura_String	xMessage( "Failed to save \"");

		xMessage	+= g_szSurfaceOverlayFilename;
		xMessage	+= "\" - write-protected?";

		Tools_Timed_Message_System::AddMessage( 0xFF0000, xMessage.GetString() );
	}
	return bOK;
}

void ToolsAVP_SurfaceOverlay::TransferModeData(int iLoadOrSave)
{
	//(Most of the movement options are saved to a text ini file instead... just keeping the overlay
	//position here for now , since it isn't intended to be edited by hand).
	
	//open the file
	Tools_ModeDataFile xFile("SurfaceTypes.dat",iLoadOrSave);

	//transfer the data
	//(none of these should be removed , and new data should go on the end, otherwise
	//the files will get screwed up)
	xFile.Transfer(s_xSurfaceOverlayPosition);
}

void ToolsAVP_SurfaceOverlay::CreateSurfaceOverlay()
{
	const Asura_Blueprint*	pxBP;
	Asura_Dialog*			pxDialogue;
	Asura_Function_Dialog*	pxFuncDialog;

	if ( SurfaceOverlayIsOn() )
	{
		Asura_Overlay_System::CloseOverlays( TOOLSAVP_OVERLAY_SURFACE );
	}

	InitialiseArrays();

	Asura_Overlay* pxOverlay = new ToolsAVP_SurfaceOverlay("Surface Types",false,&s_xSurfaceOverlayPosition);	

	//Asura_Dialog* pxDialog;
	Asura_Vector_2 xOffset = Asura_Vector_2(1.0f,3.0f);

	//start of tabs
	Asura_Tabs_Dialog* pxTabsDialog = new Asura_Tabs_Dialog(xOffset,0,0);
	pxOverlay->AddDialog(pxTabsDialog);
	xOffset.y += Asura_Dialog::LargeSpacing();
	pxOverlay->SetCurrentParentDialog(pxTabsDialog);

	float fTabsStartY = xOffset.y;
	float fTabsEndY = xOffset.y;

	////////////////////////////////////////
	// Damage Table Tab
	////////////////////////////////////////

	pxTabsDialog->AddTab("Damage Table");
	xOffset.y = fTabsStartY;

	pxDialogue	= new Asura_Dialog("Row Filter:", xOffset);
	pxOverlay->AddDialog(pxDialogue);
	xOffset.x	+= 20.0f;

	pxDialogue	= new Asura_Dialog("Column Filter:", xOffset);
	pxOverlay->AddDialog(pxDialogue);
	xOffset.x	-= 20.0f;
	xOffset.y	+= Asura_Dialog::DefaultSpacing();

	pxBP			= s_xDamageTableRowFilterData.GetFilterBlueprint();
	pxFuncDialog	= new Asura_Function_Dialog((pxBP == NULL) ? "*None*" : pxBP->GetName().GetString(), xOffset, NULL);
	pxFuncDialog ->SetCallback(OnSetDamageTableRowFilter, reinterpret_cast<int>(pxFuncDialog));
	pxOverlay->AddDialog(pxFuncDialog);
	xOffset.x	+= 20.0f;

	pxBP			= s_xDamageTableColumnFilterData.GetFilterBlueprint();
	pxFuncDialog	= new Asura_Function_Dialog((pxBP == NULL) ? "*None*" : pxBP->GetName().GetString(), xOffset, NULL);
	pxFuncDialog ->SetCallback(OnSetDamageTableColumnFilter, reinterpret_cast<int>(pxFuncDialog));
	pxOverlay->AddDialog(pxFuncDialog);
	xOffset.x	-= 20.0f;
	xOffset.y	+= Asura_Dialog::LargeSpacing();

	s_pxDamageTableDialogue = new Asura_Table_Dialog( xOffset, g_xTableSize.x, g_xTableSize.y, false );
	pxOverlay->AddDialog( s_pxDamageTableDialogue );
	CreateDamageTable( s_pxDamageTableDialogue );
	xOffset.y = s_pxDamageTableDialogue->m_xMaxCoord.y + Asura_Dialog::DefaultSpacing();

	
	//End of table tab
	if(xOffset.y > fTabsEndY) fTabsEndY = xOffset.y;

	////////////////////////////////////////
	// Collision Table Tab
	////////////////////////////////////////

	pxTabsDialog->AddTab("Collision Table");
	xOffset.y = fTabsStartY;

	pxDialogue	= new Asura_Dialog("Row Filter:", xOffset);
	pxOverlay->AddDialog(pxDialogue);
	xOffset.x	+= 20.0f;

	pxDialogue	= new Asura_Dialog("Column Filter:", xOffset);
	pxOverlay->AddDialog(pxDialogue);
	xOffset.x	-= 20.0f;
	xOffset.y	+= Asura_Dialog::DefaultSpacing();

	pxBP			= s_xCollisionTableRowFilterData.GetFilterBlueprint();
	pxFuncDialog	= new Asura_Function_Dialog((pxBP == NULL) ? "*None*" : pxBP->GetName().GetString(), xOffset, NULL);
	pxFuncDialog ->SetCallback(OnSetCollisionTableRowFilter, reinterpret_cast<int>(pxFuncDialog));
	pxOverlay->AddDialog(pxFuncDialog);
	xOffset.x += 20.0f;

	pxBP			= s_xCollisionTableColumnFilterData.GetFilterBlueprint();
	pxFuncDialog	= new Asura_Function_Dialog((pxBP == NULL) ? "*None*" : pxBP->GetName().GetString(), xOffset, NULL);
	pxFuncDialog ->SetCallback(OnSetCollisionTableColumnFilter, reinterpret_cast<int>(pxFuncDialog));
	pxOverlay->AddDialog(pxFuncDialog);
	xOffset.x	-= 20.0f;
	xOffset.y	+= Asura_Dialog::LargeSpacing();

	s_pxCollisionTableDialogue = new Asura_Table_Dialog( xOffset, g_xTableSize.x, g_xTableSize.y, false );
	pxOverlay->AddDialog( s_pxCollisionTableDialogue );
	CreateCollisionTable( s_pxCollisionTableDialogue );
	xOffset.y = s_pxCollisionTableDialogue->m_xMaxCoord.y + Asura_Dialog::DefaultSpacing();

	//End of table tab
	if(xOffset.y > fTabsEndY) fTabsEndY = xOffset.y;

	////////////////////////////////////////
	// EffectType Table Tab
	////////////////////////////////////////

	pxTabsDialog->AddTab("Effect Type Table");
	xOffset.y = fTabsStartY;

	pxDialogue	= new Asura_Dialog("Row Filter:", xOffset);
	pxOverlay->AddDialog(pxDialogue);
	xOffset.x	+= 20.0f;

	pxDialogue	= new Asura_Dialog("Column Filter:", xOffset);
	pxOverlay->AddDialog(pxDialogue);
	xOffset.x	-= 20.0f;
	xOffset.y	+= Asura_Dialog::DefaultSpacing();

	pxBP			= s_xEffectTypeTableRowFilterData.GetFilterBlueprint();
	pxFuncDialog	= new Asura_Function_Dialog((pxBP == NULL) ? "*None*" : pxBP->GetName().GetString(), xOffset, NULL);
	pxFuncDialog ->SetCallback(OnSetEffectTypeTableRowFilter, reinterpret_cast<int>(pxFuncDialog));
	pxOverlay->AddDialog(pxFuncDialog);
	xOffset.x += 20.0f;

	pxBP			= s_xEffectTypeTableColumnFilterData.GetFilterBlueprint();
	pxFuncDialog	= new Asura_Function_Dialog((pxBP == NULL) ? "*None*" : pxBP->GetName().GetString(), xOffset, NULL);
	pxFuncDialog ->SetCallback(OnSetEffectTypeTableColumnFilter, reinterpret_cast<int>(pxFuncDialog));
	pxOverlay->AddDialog(pxFuncDialog);
	xOffset.x	-= 20.0f;
	xOffset.y	+= Asura_Dialog::LargeSpacing();

	s_pxEffectTypeTableDialogue = new Asura_Table_Dialog( xOffset, g_xTableSize.x, g_xTableSize.y, false );
	pxOverlay->AddDialog( s_pxEffectTypeTableDialogue );
	CreateEffectTypeTable( s_pxEffectTypeTableDialogue );
	xOffset.y = s_pxEffectTypeTableDialogue->m_xMaxCoord.y + Asura_Dialog::DefaultSpacing();

	//End of table tab
	if(xOffset.y > fTabsEndY) fTabsEndY = xOffset.y;




	
	////////////////////////////////////////
	//End of tabs
	xOffset.y = fTabsEndY + 1.0f;
	////////////////////////////////////////
	
	pxOverlay->SetCurrentParentDialog(0);

	pxFuncDialog = new Asura_Function_Dialog( "Refresh From Blueprints", xOffset, CreateSurfaceOverlay );
	pxFuncDialog->SetRelativePosition(pxTabsDialog, true, false);
	pxOverlay->AddDialog( pxFuncDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();
	pxFuncDialog = new Asura_Function_Dialog( "Save", xOffset, SaveNoReturn );
	pxFuncDialog->SetRelativePosition(pxTabsDialog, true, false);
	pxOverlay->AddDialog( pxFuncDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();

	static u_int s_uSelectedTab = 0;
	pxTabsDialog->SetSelectedTabPointer(&s_uSelectedTab);
	
	pxDialogue	= new Asura_Resize_Dialog (s_pxDamageTableDialogue, &s_xSurfaceOverlaySize);
	((Asura_Resize_Dialog*)pxDialogue)->AddResizableDialog(s_pxCollisionTableDialogue, &s_xSurfaceOverlaySize);
	((Asura_Resize_Dialog*)pxDialogue)->AddResizableDialog(s_pxEffectTypeTableDialogue, &s_xSurfaceOverlaySize);
	pxOverlay->AddDialog(pxDialogue);

	pxOverlay->m_uID = TOOLSAVP_OVERLAY_SURFACE;
	Asura_Overlay_System::SubmitNewOverlay(pxOverlay);
}

void ToolsAVP_SurfaceOverlay::PerFrameUpdate()
{
	Asura_Overlay::PerFrameUpdate();
	// TODO - this crashes because domodal closes our overlay before it's time
// 	if ( IsClosing() && s_bModified )
// 	{
// 		YesNo_Overlay xYesNoOverlay( "Surface effects have changed. Would you like to save your changes?" );
// 		if ( xYesNoOverlay.DoModal() )
// 		{
// 			Save();
// 		}
// 	}
}

void ToolsAVP_SurfaceOverlay::InitialiseArrays()
{
	// Create the custom headings...
	s_xEffectTypes.Initialise( uAVP_BLUEPRINT_TYPE_EFFECTTYPES, uAVP_BLUEPRINT_NAME_ACTOR_SURFACE_TYPES );
	s_xDamageTypes.Initialise( uAVP_BLUEPRINT_TYPE_DAMAGE, uAVP_BLUEPRINT_NAME_DAMAGETYPE );
	s_xSurfaceTypes.Initialise( uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS, uAVP_BLUEPRINT_NAME_SURFACETYPE );
	s_xMaterialSurfaceTypes.Initialise( uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS, uAVP_BLUEPRINT_NAME_SURFACETYPE_MATERIAL );

	ApplyFilterBlueprint(false, s_xDamageTableRowFilterData);
	ApplyFilterBlueprint(false, s_xDamageTableColumnFilterData);
	ApplyFilterBlueprint(false, s_xCollisionTableRowFilterData);
	ApplyFilterBlueprint(false, s_xCollisionTableColumnFilterData);
	ApplyFilterBlueprint(false, s_xEffectTypeTableRowFilterData);
	ApplyFilterBlueprint(false, s_xEffectTypeTableColumnFilterData);
}

void ToolsAVP_SurfaceOverlay::CreateDamageTable( Asura_Table_Dialog* pxTableDialog )
{
	const u_int	uNumRows	= s_xDamageTableRowFilterData.GetNumNamesAdded();
	const u_int	uNumColumns	= s_xDamageTableColumnFilterData.GetNumNamesAdded();

	pxTableDialog->DestroyTable();
	
	if( (uNumRows > 0) && (uNumColumns > 0) && (pxTableDialog != NULL) )
	{
		const char**	pszRowNames		= s_xDamageTableRowFilterData.GetNamesArray();
		const char**	pszColumnNames	= s_xDamageTableColumnFilterData.GetNamesArray();

		pxTableDialog->CreateTable(g_xTestMinimumCellSize, uNumRows, uNumColumns, CreateDamageCellDialog, pxTableDialog, pszRowNames, pszColumnNames);
	
		pxTableDialog->SortRowsUsingHeadings( false );
		pxTableDialog->SortColumnsUsingHeadings( false );
	}
}

void ToolsAVP_SurfaceOverlay::CreateCollisionTable(Asura_Table_Dialog* pxTableDialog)
{
	const u_int	uNumRows	= s_xCollisionTableRowFilterData.GetNumNamesAdded();
	const u_int	uNumColumns	= s_xCollisionTableColumnFilterData.GetNumNamesAdded();

	pxTableDialog->DestroyTable();

	if( (uNumRows > 0) && (uNumColumns > 0) && (pxTableDialog != NULL) )
	{
		const char**	pszRowNames		= s_xCollisionTableRowFilterData.GetNamesArray();
		const char**	pszColumnNames	= s_xCollisionTableColumnFilterData.GetNamesArray();

		pxTableDialog->CreateTable(g_xTestMinimumCellSize, uNumRows, uNumColumns, CreateCollisionCellDialog, pxTableDialog, pszRowNames, pszColumnNames);

		pxTableDialog->SortRowsUsingHeadings( false );
		pxTableDialog->SortColumnsUsingHeadings( false );
	}
}

void ToolsAVP_SurfaceOverlay::CreateEffectTypeTable(Asura_Table_Dialog* pxTableDialog)
{
	const u_int	uNumRows	= s_xEffectTypeTableRowFilterData.GetNumNamesAdded();
	const u_int	uNumColumns	= s_xEffectTypeTableColumnFilterData.GetNumNamesAdded();

	pxTableDialog->DestroyTable();

	if( (uNumRows > 0) && (uNumColumns > 0) && (pxTableDialog != NULL) )
	{
		const char**	pszRowNames		= s_xEffectTypeTableRowFilterData.GetNamesArray();
		const char**	pszColumnNames	= s_xEffectTypeTableColumnFilterData.GetNamesArray();

		pxTableDialog->CreateTable(g_xTestMinimumCellSize, uNumRows, uNumColumns, CreateEffectTypeCellDialog, pxTableDialog, pszRowNames, pszColumnNames);

		pxTableDialog->SortRowsUsingHeadings( false );
		pxTableDialog->SortColumnsUsingHeadings( false );
	}
}

Asura_TableCell_Dialog* ToolsAVP_SurfaceOverlay::CreateDamageCellDialog(
	Asura_Table_Dialog& xTableDialog,
	const Asura_Vector_2& xOffset,
	const Asura_Vector_2& xMinCellSize,
	const u_int uRow,
	const u_int uColumn,
	void* const pxUserData )
{
	return new ToolsAVP_DamageCell_Dialog( xTableDialog, xOffset, xMinCellSize, uRow, uColumn );
}

Asura_TableCell_Dialog* ToolsAVP_SurfaceOverlay::CreateCollisionCellDialog(
	Asura_Table_Dialog& xTableDialog,
	const Asura_Vector_2& xOffset,
	const Asura_Vector_2& xMinCellSize,
	const u_int uRow,
	const u_int uColumn,
	void* const pxUserData )
{
	return new ToolsAVP_CollisionCell_Dialog( xTableDialog, xOffset, xMinCellSize, uRow, uColumn );
}

Asura_TableCell_Dialog* ToolsAVP_SurfaceOverlay::CreateEffectTypeCellDialog(
	Asura_Table_Dialog& xTableDialog,
	const Asura_Vector_2& xOffset,
	const Asura_Vector_2& xMinCellSize,
	const u_int uRow,
	const u_int uColumn,
	void* const pxUserData )
{
	return new ToolsAVP_EffectTypeCell_Dialog( xTableDialog, xOffset, xMinCellSize, uRow, uColumn );
}

void ToolsAVP_SurfaceOverlay::ApplyFilterBlueprint(const bool bRefreshOverlay,
												   ToolsAVP_SurfaceOverlay_FilterData& xFilterData)
{
	const Asura_Hash_ID	uBlueprintType		= xFilterData.GetTypeHash();
	const Asura_Hash_ID	uFilterHash			= xFilterData.GetFilterHash();
	const u_int			uNumChildBlueprints	= Asura_Blueprint_System::GetNumChildBlueprints(uBlueprintType, uFilterHash, false);

	if(uNumChildBlueprints == 0)
	{
		Asura_Blueprint* pxBlueprint = Asura_Blueprint_System::GetBlueprintByHashID(uBlueprintType, uFilterHash);

		if(pxBlueprint != NULL)
		{
			xFilterData.Allocate(1);
			xFilterData.AddName(pxBlueprint->GetName());
		}
	}
	else
	{
		xFilterData.Allocate(uNumChildBlueprints);

		for(u_int u = 0; u < uNumChildBlueprints; u++)
		{
			Asura_Blueprint*	pxBlueprint	= Asura_Blueprint_System::GetChildBlueprint(uBlueprintType, uFilterHash, false, u);

			if(pxBlueprint == NULL)
			{
				Asura_Assert(false, "Blueprint not found");
			}
			else
			{
				if(Asura_Blueprint_System::GetNumChildBlueprints(uBlueprintType, pxBlueprint->GetHashID(), true) == 0)
				{
					xFilterData.AddName(pxBlueprint->GetName());
				}
			}
		}
	}

	if(bRefreshOverlay)
	{
		CreateSurfaceOverlay();
	}
}

void ToolsAVP_SurfaceOverlay::RequestFilter(const char* szRequest,
											Asura_Function_Dialog* pxFunctionDialogue,
											ToolsAVP_SurfaceOverlay_FilterData& xFilterData)
{
	const Asura_Blueprint*	pxBlueprint	= xFilterData.RequestBlueprint(szRequest);

	if(pxBlueprint != NULL)
	{
		const Asura_String&	xName	= pxBlueprint->GetName();
		const char*			szName	= xName.GetString();

		pxFunctionDialogue->UpdateLabel(szName);
		ApplyFilterBlueprint(true, xFilterData);
	}
}

void ToolsAVP_SurfaceOverlay::OnSetDamageTableRowFilter( int iFunctionDialog )
{
	Asura_Function_Dialog*	pxFunctionDialogue	= reinterpret_cast<Asura_Function_Dialog*>(iFunctionDialog);

	if(pxFunctionDialogue != NULL)
	{
		RequestFilter("Select blueprint for damage-type filtering...", pxFunctionDialogue, s_xDamageTableRowFilterData);
	}
}

void ToolsAVP_SurfaceOverlay::OnSetDamageTableColumnFilter( int iFunctionDialog )
{
	Asura_Function_Dialog*	pxFunctionDialogue	= reinterpret_cast<Asura_Function_Dialog*>(iFunctionDialog);

	if(pxFunctionDialogue != NULL)
	{
		RequestFilter("Select blueprint for surface-type filtering...", pxFunctionDialogue, s_xDamageTableColumnFilterData);
	}
}

void ToolsAVP_SurfaceOverlay::OnSetCollisionTableRowFilter( int iFunctionDialog )
{
	Asura_Function_Dialog*	pxFunctionDialogue	= reinterpret_cast<Asura_Function_Dialog*>(iFunctionDialog);

	if(pxFunctionDialogue != NULL)
	{
		RequestFilter("Select blueprint for row surface-type filtering...", pxFunctionDialogue, s_xCollisionTableRowFilterData);
	}
}

void ToolsAVP_SurfaceOverlay::OnSetCollisionTableColumnFilter( int iFunctionDialog )
{
	Asura_Function_Dialog*	pxFunctionDialogue	= reinterpret_cast<Asura_Function_Dialog*>(iFunctionDialog);

	if(pxFunctionDialogue != NULL)
	{
		RequestFilter("Select blueprint for column surface-type filtering...", pxFunctionDialogue, s_xCollisionTableColumnFilterData);
	}
}

void ToolsAVP_SurfaceOverlay::OnSetEffectTypeTableRowFilter( int iFunctionDialog )
{
	Asura_Function_Dialog*	pxFunctionDialogue	= reinterpret_cast<Asura_Function_Dialog*>(iFunctionDialog);

	if(pxFunctionDialogue != NULL)
	{
		RequestFilter("Select blueprint for effect type-type filtering...", pxFunctionDialogue, s_xEffectTypeTableRowFilterData);
	}
}

void ToolsAVP_SurfaceOverlay::OnSetEffectTypeTableColumnFilter( int iFunctionDialog )
{
	Asura_Function_Dialog*	pxFunctionDialogue	= reinterpret_cast<Asura_Function_Dialog*>(iFunctionDialog);

	if(pxFunctionDialogue != NULL)
	{
		RequestFilter("Select blueprint for surface-type filtering...", pxFunctionDialogue, s_xEffectTypeTableColumnFilterData);
	}
}
//////////////////////////////////////////////////////////////////////////
// ToolsAVP_DamageCell_Dialog
//////////////////////////////////////////////////////////////////////////

ToolsAVP_DamageCell_Dialog::ToolsAVP_DamageCell_Dialog( Asura_Table_Dialog& xTableDialogue, const Asura_Vector_2& xOffset,
													    const Asura_Vector_2& xMinCellSize, const u_int uRow, const u_int uColumn )
: PARENT( xTableDialogue, xOffset, xMinCellSize, uRow, uColumn )
{
	Asura_Vector_2			xLocalOffset(0.0f, 0.0f);

	const Asura_Hash_ID		uSurfaceHash	= ToolsAVP_SurfaceOverlay::s_xDamageTableColumnFilterData.GetNameHash(uColumn);
	const Asura_Hash_ID		uDamageHash		= ToolsAVP_SurfaceOverlay::s_xDamageTableRowFilterData.GetNameHash(uRow);
	AVP_SurfaceEffect_Map*	pxEffectMap		= AVP_SurfaceEffect_System::GetDamageMap(uSurfaceHash, uDamageHash, false);
	const Asura_Hash_ID		uEffectHash		= (pxEffectMap == NULL) ? ASURA_HASH_ID_UNSET : pxEffectMap->GetHash();
	const Asura_Blueprint*	pxBlueprint		= Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS, uEffectHash);
	const char*				szEffectName	= (pxBlueprint == NULL) ? "*None*" : pxBlueprint->GetName().GetString();

	m_pxSelectEffectDialogue	= new Asura_Function_Dialog (szEffectName, xLocalOffset, OnSelect, reinterpret_cast<int>(this));
	m_uEffectHash				= uEffectHash;

	AddDialogToPanel(m_pxSelectEffectDialogue);
}

void ToolsAVP_DamageCell_Dialog::OnSelect(void)
{
	Asura_Hash_ID			uBlueprintType	= uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS;
	BlueprintSelect_Overlay	xModalOverlay("Select surface-effect for damage...",
										  &m_uEffectHash,
										  &uBlueprintType,
										  g_uSurfaceOverlayNumSelectable_SurfaceEffectBlueprintTypes,
										  g_auSurfaceOverlaySelectable_SurfaceEffectBlueprintTypes,
										  g_uSurfaceOverlayNumSelectable_SurfaceEffectBlueprintParents,
										  g_auSurfaceOverlaySelectable_SurfaceEffectBlueprintParents);

	if(xModalOverlay.DoModal())
	{
		const Asura_Hash_ID			uSurfaceHash	= ToolsAVP_SurfaceOverlay::s_xDamageTableColumnFilterData.GetNameHash(m_iColumn);
		const Asura_Hash_ID			uDamageHash		= ToolsAVP_SurfaceOverlay::s_xDamageTableRowFilterData.GetNameHash(m_iRow);
		AVP_SurfaceEffect_Map*		pxEffectMap		= AVP_SurfaceEffect_System::GetDamageMap(uSurfaceHash, uDamageHash, true);

		if(pxEffectMap == NULL)
		{
			Asura_Assert(false, "Failed to add damage-map for surface.");
		}
		else
		{
			const Asura_Blueprint*	pxBlueprint		= Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS, m_uEffectHash);
			const char*				szEffectName	= (pxBlueprint == NULL) ? "*None*" : pxBlueprint->GetName().GetString();

			pxEffectMap->SetHash(m_uEffectHash);

			m_pxSelectEffectDialogue->UpdateLabel(szEffectName);
			UpdateSize();
			ToolsAVP_SurfaceOverlay::SetAsChanged();
		}
	}
}

void ToolsAVP_DamageCell_Dialog::OnSelect( int iCellDialog )
{
	ToolsAVP_DamageCell_Dialog*	pxCellDialog	= reinterpret_cast<ToolsAVP_DamageCell_Dialog*>(iCellDialog);

	if(pxCellDialog != NULL)
	{
		pxCellDialog->OnSelect();
	}
}

//////////////////////////////////////////////////////////////////////////
// ToolsAVP_CollisionCell_Dialog
//////////////////////////////////////////////////////////////////////////

ToolsAVP_CollisionCell_Dialog::ToolsAVP_CollisionCell_Dialog( Asura_Table_Dialog& xTableDialogue, const Asura_Vector_2& xOffset,
															  const Asura_Vector_2& xMinCellSize, const u_int uRow, const u_int uColumn )
: PARENT( xTableDialogue, xOffset, xMinCellSize, uRow, uColumn )
, m_uEffectHash( ASURA_HASH_ID_UNSET )
{
	Asura_Vector_2			xLocalOffset(0.0f, 0.0f);

	const Asura_Hash_ID		uCollidee		= ToolsAVP_SurfaceOverlay::s_xCollisionTableRowFilterData.GetNameHash(uRow);
	const Asura_Hash_ID		uCollider		= ToolsAVP_SurfaceOverlay::s_xCollisionTableColumnFilterData.GetNameHash(uColumn);
	AVP_SurfaceEffect_Map*	pxEffectMap		= AVP_SurfaceEffect_System::GetCollisionMap(uCollider, uCollidee, false);
	const Asura_Hash_ID		uEffectHash		= (pxEffectMap == NULL) ? ASURA_HASH_ID_UNSET : pxEffectMap->GetHash();
	const Asura_Blueprint*	pxBlueprint		= Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS, uEffectHash);
	const char*				szEffectName	= (pxBlueprint == NULL) ? "*None*" : pxBlueprint->GetName().GetString();


	m_pxSelectEffectDialogue	= new Asura_Function_Dialog (szEffectName, xLocalOffset, OnSelect, reinterpret_cast<int>(this));
	m_uEffectHash				= uEffectHash;

	AddDialogToPanel(m_pxSelectEffectDialogue);
}

void ToolsAVP_CollisionCell_Dialog::OnSelect(void)
{
	Asura_Hash_ID			uBlueprintType	= uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS;
	BlueprintSelect_Overlay	xModalOverlay("Select surface-effect for collisions...",
										  &m_uEffectHash,
										  &uBlueprintType,
										  g_uSurfaceOverlayNumSelectable_SurfaceEffectBlueprintTypes,
										  g_auSurfaceOverlaySelectable_SurfaceEffectBlueprintTypes,
										  g_uSurfaceOverlayNumSelectable_SurfaceEffectBlueprintParents,
										  g_auSurfaceOverlaySelectable_SurfaceEffectBlueprintParents);

	if(xModalOverlay.DoModal())
	{
		const Asura_Hash_ID		uCollider	= ToolsAVP_SurfaceOverlay::s_xCollisionTableColumnFilterData.GetNameHash(m_iColumn);
		const Asura_Hash_ID		uCollidee	= ToolsAVP_SurfaceOverlay::s_xCollisionTableRowFilterData.GetNameHash(m_iRow);
		AVP_SurfaceEffect_Map*	pxEffectMap	= AVP_SurfaceEffect_System::GetCollisionMap(uCollider, uCollidee, true);

		if(pxEffectMap == NULL)
		{
			Asura_Assert(false, "Failed to add collision-map for surface.");
		}
		else
		{
			const Asura_Blueprint*	pxBlueprint		= Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS, m_uEffectHash);
			const char*				szEffectName	= (pxBlueprint == NULL) ? "*None*" : pxBlueprint->GetName().GetString();

			pxEffectMap->SetHash(m_uEffectHash);

			m_pxSelectEffectDialogue->UpdateLabel(szEffectName);
			UpdateSize();
			ToolsAVP_SurfaceOverlay::SetAsChanged();
		}
	}
}

void ToolsAVP_CollisionCell_Dialog::OnSelect( int iCellDialog )
{
	ToolsAVP_CollisionCell_Dialog*	pxCellDialog	= reinterpret_cast<ToolsAVP_CollisionCell_Dialog*>(iCellDialog);

	if(pxCellDialog != NULL)
	{
		pxCellDialog->OnSelect();
	}
}

//------------------------------------------------------------------------


//////////////////////////////////////////////////////////////////////////
// ToolsAVP_EffectTypeCell_Dialog
//////////////////////////////////////////////////////////////////////////

ToolsAVP_EffectTypeCell_Dialog::ToolsAVP_EffectTypeCell_Dialog( Asura_Table_Dialog& xTableDialogue, const Asura_Vector_2& xOffset,
															 const Asura_Vector_2& xMinCellSize, const u_int uRow, const u_int uColumn )
															 : PARENT( xTableDialogue, xOffset, xMinCellSize, uRow, uColumn )
															 , m_uEffectHash( ASURA_HASH_ID_UNSET )
{
	Asura_Vector_2			xLocalOffset(0.0f, 0.0f);

	const Asura_Hash_ID		uSurfaceHash	= ToolsAVP_SurfaceOverlay::s_xEffectTypeTableColumnFilterData.GetNameHash(uColumn);
	const Asura_Hash_ID		uEffectTypeHash	= ToolsAVP_SurfaceOverlay::s_xEffectTypeTableRowFilterData.GetNameHash(uRow);
	AVP_SurfaceEffect_Map*	pxEffectMap		= AVP_SurfaceEffect_System::GetEffectTypeMap(uSurfaceHash, uEffectTypeHash, false);
	const Asura_Hash_ID		uEffectHash		= (pxEffectMap == NULL) ? ASURA_HASH_ID_UNSET : pxEffectMap->GetHash();
	const Asura_Blueprint*	pxBlueprint		= Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS, uEffectHash);
	const char*				szEffectName	= (pxBlueprint == NULL) ? "*None*" : pxBlueprint->GetName().GetString();


	m_pxSelectEffectDialogue	= new Asura_Function_Dialog (szEffectName, xLocalOffset, OnSelect, reinterpret_cast<int>(this));
	m_uEffectHash				= uEffectHash;

	AddDialogToPanel(m_pxSelectEffectDialogue);
}

void ToolsAVP_EffectTypeCell_Dialog::OnSelect(void)
{
	Asura_Hash_ID			uBlueprintType	= uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS;
	BlueprintSelect_Overlay	xModalOverlay("Select surface-effect for EffectTypes...",
		&m_uEffectHash,
		&uBlueprintType,
		g_uSurfaceOverlayNumSelectable_SurfaceEffectBlueprintTypes,
		g_auSurfaceOverlaySelectable_SurfaceEffectBlueprintTypes,
		g_uSurfaceOverlayNumSelectable_SurfaceEffectBlueprintParents,
		g_auSurfaceOverlaySelectable_SurfaceEffectBlueprintParents);

	if(xModalOverlay.DoModal())
	{
		const Asura_Hash_ID		uSurfaceHash	= ToolsAVP_SurfaceOverlay::s_xEffectTypeTableColumnFilterData.GetNameHash(m_iColumn);
		const Asura_Hash_ID		uEffectTypeHash	= ToolsAVP_SurfaceOverlay::s_xEffectTypeTableRowFilterData.GetNameHash(m_iRow);
		AVP_SurfaceEffect_Map*	pxEffectMap		= AVP_SurfaceEffect_System::GetEffectTypeMap(uSurfaceHash, uEffectTypeHash, true);

		if(pxEffectMap == NULL)
		{
			Asura_Assert(false, "Failed to add effect type-map for surface.");
		}
		else
		{
			const Asura_Blueprint*	pxBlueprint		= Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_SURFACEEFFECTS, m_uEffectHash);
			const char*				szEffectName	= (pxBlueprint == NULL) ? "*None*" : pxBlueprint->GetName().GetString();

			pxEffectMap->SetHash(m_uEffectHash);

			m_pxSelectEffectDialogue->UpdateLabel(szEffectName);
			UpdateSize();
			ToolsAVP_SurfaceOverlay::SetAsChanged();
		}
	}
}

void ToolsAVP_EffectTypeCell_Dialog::OnSelect( int iCellDialog )
{
	ToolsAVP_EffectTypeCell_Dialog*	pxCellDialog	= reinterpret_cast<ToolsAVP_EffectTypeCell_Dialog*>(iCellDialog);

	if(pxCellDialog != NULL)
	{
		pxCellDialog->OnSelect();
	}
}




// ------------- ToolsAVP_SurfaceOverlay::TypeNameArray --------------------

Asura_Hash_ID ToolsAVP_SurfaceOverlay::TypeNameArray::GetTypeHashFromIndex( u_int uIndex )
{
	if(uIndex < s_uNumTypesAdded)
	{
		return ( Asura_GetHashID( s_pszTypeNameArray[ uIndex ] ) );
	}
	else
	{
		Asura_Assertf(false, ( "Failed to get type for index %d", uIndex ) );
		return(ASURA_HASH_ID_UNSET);
	}
}

void ToolsAVP_SurfaceOverlay::TypeNameArray::Initialise( const Asura_Hash_ID uTypeHashID, const Asura_Hash_ID uParentBlueprintHashID )
{
	Deallocate();

	s_uMaxTypes			= Asura_Blueprint_System::GetNumChildBlueprints( uTypeHashID, uParentBlueprintHashID, false );
	s_uNumTypesAdded	= 0;
	s_pszTypeNameArray	= new const char*[ s_uMaxTypes ];


	for( u_int uItr = 0 ; uItr < s_uMaxTypes; ++uItr )
	{
		Asura_Blueprint* pxBlueprint = Asura_Blueprint_System::GetChildBlueprint( uTypeHashID, uParentBlueprintHashID, false, uItr );
		if ( pxBlueprint )
		{
			s_pszTypeNameArray[ s_uNumTypesAdded++ ] = pxBlueprint->GetName().GetString();
		}
		else
		{
			Asura_Assert( false, "Blueprint not found" );
		}
	}
}

void ToolsAVP_SurfaceOverlay::TypeNameArray::Deallocate()
{
	if( s_pszTypeNameArray )
	{
		delete [] s_pszTypeNameArray;
		s_pszTypeNameArray = NULL;
	}
}


/// End of File ///
