//
// Tools_SoundEvent_Export.cpp
//
// Created by Richard Rice - 14/07/2006
// 
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"

//asura
#include "ChunkSystem/Asura_SaveBlock.h"
#include "ChunkSystem/Asura_Chunk_SoundEvent.h"
#include "ChunkSystem/Asura_Chunk_DSP.h"
#include "Core/Asura_HashTree.h"
#include "Interface/Asura_Dialog.h"
#include "Interface/Asura_Overlay.h"
#include "Sound/Asura_Audio_System.h"
#include "Sound/Asura_Sound.h"
#include "Sound/Asura_Sound_Event.h"
#include "Sound/Asura_Sound_Event_Storage.h"

//tools
#include "Load&Save/LevelExport/Tools_Level_Export.h"
#include "Load&Save/Tools_ResourceExportLog.h"
#include "Misc/Tools_Modal_Overlay.h"
#include "PC/FileSystem/Tools_FileSystem.h"
#include "Sound/Tools_Sound_System.h"
#include "Sound/Tools_SoundEvent_System.h"

static const int g_iPLATFORM_TOOLS = TOOLS_PLATFORM_NUM_PLATFORMS;

static const char* g_szToolsGlobalSoundFile = "Sounds\\ToolsGmSnd.asr";

///////////////////////////////////////////////////////////////////////////////////////

class Tools_Overlay_SoundExportOptions : public Tools_Modal_Overlay
{
	public :
		Tools_Overlay_SoundExportOptions()
		:Tools_Modal_Overlay("Sound export :")
		,m_bLocalisedOnly(false)
		{
			EnableAllPlatformsForExport();
		}

		bool DoModal()
		{
			m_bReturnValue = false;
			ShowOverlay();
			return m_bReturnValue;
		}

		void InitialiseOverlay(Asura_Overlay* pxOverlay);

		#define OVERLAY_VOID_CALLBACK(__FnName)\
		static void __FnName(int iThis){((Tools_Overlay_SoundExportOptions*)iThis)->__FnName();}\
		void __FnName();

		OVERLAY_VOID_CALLBACK(EnableAllPlatformsForExport);
		OVERLAY_VOID_CALLBACK(DisableAllPlatformsForExport);

		OVERLAY_VOID_CALLBACK(Okay);
		OVERLAY_VOID_CALLBACK(Cancel);

		#undef OVERLAY_VOID_CALLBACK

		bool m_abExportPlatform[TOOLS_PLATFORM_NUM_PLATFORMS+1];
		bool m_bLocalisedOnly;
		bool m_bReturnValue;

};

void Tools_Overlay_SoundExportOptions::InitialiseOverlay(Asura_Overlay* pxOverlay)
{
	Asura_Vector_2 xOffset = Asura_Vector_2(1.0f,3.0f);
	Asura_Dialog* pxDialog = 0;

	//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;

	//start of platform tab
	pxTabsDialog->AddTab("Platform");
	xOffset.y = fTabsStartY;


	//add tickboxes for the allowed platforms
	for(int i=0; i<TOOLS_PLATFORM_NUM_PLATFORMS; i++)
	{

		if(Tools_Level_Export::IsPlatformSupported((Tools_Level_Export::EXPORT_TYPE)i))
		{
			const char* szName = Tools_Platform::GetPlatformName(i);

			pxDialog = new Asura_Tickbox_Dialog(szName, xOffset, &m_abExportPlatform[i]);
			pxDialog->SetHelpText("Should global sounds be exported for this platform?");
			pxOverlay->AddDialog(pxDialog);
			xOffset.y+=Asura_Dialog::DefaultSpacing();
			
		}
	}

	pxDialog = new Asura_Tickbox_Dialog("Tools", xOffset, &m_abExportPlatform[TOOLS_PLATFORM_NUM_PLATFORMS]);
	pxDialog->SetHelpText("Determines whether ToolsGmSnd.asr should be exported\nThis contains the wav files used by sound events , for speeding up quitting to game.");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::LargeSpacing();

	//and a couple of buttons for enabling/disabling all of them
	pxDialog = new Asura_Function_Dialog("All",xOffset,EnableAllPlatformsForExport,(int) this);
	pxDialog->SetHelpText("Ticks all platforms");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Function_Dialog("None",xOffset,DisableAllPlatformsForExport,(int) this);
	pxDialog->SetHelpText("Unticks all platforms");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();

	//end of platform tab
	if(xOffset.y > fTabsEndY) fTabsEndY = xOffset.y;

	//start of language tab
	pxTabsDialog->AddTab("Language");
	xOffset.y = fTabsStartY;

	pxDialog = new Asura_Tickbox_Dialog("Localised Only", xOffset, &m_bLocalisedOnly);
	pxDialog->SetHelpText("If tcked , then only the localised files will be written during the export");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::LargeSpacing();

	Tools_Level_Export::AddLanguageOverlayControls(pxOverlay,xOffset);

	//end of language tab
	if(xOffset.y > fTabsEndY) fTabsEndY = xOffset.y;

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

	static u_int s_uSelectedTab = 0;
	pxTabsDialog->SetSelectedTabPointer(&s_uSelectedTab);



	pxDialog = new Asura_Function_Dialog("Okay",xOffset,Okay,(int)this);
	pxOverlay->AddDialog(pxDialog);
	xOffset.x = pxDialog->m_xMaxCoord.x + 2.0f;

	pxDialog = new Asura_Function_Dialog("Cancel",xOffset,Cancel,(int)this);
	pxOverlay->AddDialog(pxDialog);

}

void Tools_Overlay_SoundExportOptions::EnableAllPlatformsForExport()
{
	for(int i=0; i<TOOLS_PLATFORM_NUM_PLATFORMS; i++)
	{
		m_abExportPlatform[i] = Tools_Level_Export::IsPlatformSupported((Tools_Level_Export::EXPORT_TYPE)i);
	}
	m_abExportPlatform[g_iPLATFORM_TOOLS] = true;
}

void Tools_Overlay_SoundExportOptions::DisableAllPlatformsForExport()
{
	for(int i=0; i<=TOOLS_PLATFORM_NUM_PLATFORMS; i++)
	{
		m_abExportPlatform[i] = false;
	}
}

void Tools_Overlay_SoundExportOptions::Okay()
{
	m_bReturnValue = true;
	CloseOverlay();
}

void Tools_Overlay_SoundExportOptions::Cancel()
{
	m_bReturnValue = false;
	CloseOverlay();
}

///////////////////////////////////////////////////////////////////////////////////////

void Tools_Level_Export::ExportGlobalSoundEvents()
{
	if(!This) return;

	//ask which platforms and languages to export for
	Tools_Overlay_SoundExportOptions xOverlay;
	if(!xOverlay.DoModal()) return;

	s_bOnlyExportLocalisedGlobalSounds = xOverlay.m_bLocalisedOnly;
	//export the selected platform(s)
	for(int iPlatform=0; iPlatform<=g_iPLATFORM_TOOLS; iPlatform++)
	{
		if(xOverlay.m_abExportPlatform[iPlatform])
		{
			EXPORT_TYPE ePlatform;
			if(iPlatform == g_iPLATFORM_TOOLS)
			{
				ePlatform = Export_PC;
			}
			else
			{
				ePlatform = (EXPORT_TYPE) iPlatform;
			}
			if(!This->IsPlatformAllowed(ePlatform)) continue;

			s_eExportType = ePlatform;
			This->ExportGlobalSoundEventsMain(iPlatform == g_iPLATFORM_TOOLS);
		}
	}
	s_bOnlyExportLocalisedGlobalSounds = false;
	s_eExportType = Export_PC;
}

void Tools_Level_Export::ExportGlobalSoundEvents(int iPlatform)
{
	Asura_Assert(This,"");

	s_eExportType = (EXPORT_TYPE) iPlatform;
	This->ExportGlobalSoundEventsMain(false);
	s_eExportType = Export_PC;
}

void Tools_Level_Export::ExportGlobalSoundEventsForTools()
{
	if(This != NULL)
	{
		s_eExportType = Export_PC;
		This->ExportGlobalSoundEventsMain( true );
	}
}

void Tools_Level_Export::ExportGlobalSoundEventsMain(bool bToolsExport)
{
	m_bIsToolsSoundExport = bToolsExport;
	if(bToolsExport)
	{
		Asura_Assert(s_eExportType == Export_PC,"Export platform should be PC for tools sound event export.");
	}

	//Early check to make sure destination files are writeable. RAR 17/01/2006
	if(!IsGlobalSoundEventFileWriteable())
	{
		return;
	}

	s_szMainHeading = "Sound Export";

	StartExport();
	OpenExportLog("GlobalSound");


	StartGlobalSoundEventExport();
	if(!IsAbortFlagSet())
	{
		StartFileExport();
	}

	if(!IsAbortFlagSet())
	{
		AddGlobalSoundEventsToExportList();
		
		if(!m_bIsToolsSoundExport)
		{
			#ifdef ASURA_USE_DIALOGUE_SYSTEM
			AddGlobalDialogueEventsToExportList();
			#endif

			#ifdef ASURA_USE_STREAMING
			AddGlobalMetaMusicToExportList();
			#endif
		}


		Asura_String xExportFilename;
		if(m_bIsToolsSoundExport)
		{
			xExportFilename = g_szToolsGlobalSoundFile;
		}
		else
		{
			GetGlobalSoundEventFilename(xExportFilename);
		}
		if(s_bOnlyExportLocalisedGlobalSounds)
		{
			//Process the sound and dialogue events with a blank file handle , so that the localised sounds
			//will be filled in
			AddSoundEvents(INVALID_HANDLE_VALUE);
			#ifdef ASURA_USE_DIALOGUE_SYSTEM
			AddDialogueEvents(INVALID_HANDLE_VALUE);
			#endif

			//export the localised files
			ExportLanguageFiles(xExportFilename.GetString());
			
		}
		else
		{
			ExportFilesInList( xExportFilename.GetString(),false);
		}
	}

	
	EndFileExport();
	EndGlobalSoundEventExport();
	CloseExportLog();

	EndExport(false);
}

void Tools_Level_Export::StartGlobalSoundEventExport()
{
    s_bIsGlobalSoundEventExport = true;
}

void Tools_Level_Export::EndGlobalSoundEventExport()
{
	DeleteTemporaryFiles();
    s_bIsGlobalSoundEventExport = false;
}

bool Tools_Level_Export::IsGlobalSoundEventFileWriteable(bool bShowMessage)
{
	Asura_String xFilename;
	if(m_bIsToolsSoundExport)
	{
		xFilename = g_szToolsGlobalSoundFile;
	}
	else
	{
		GetGlobalSoundEventFilename(xFilename);
	}

	return IsWriteableIncludingLanguageFiles(xFilename.GetString(),bShowMessage, s_bOnlyExportLocalisedGlobalSounds);

}

void Tools_Level_Export::GetGlobalSoundEventFilename(Asura_String& xOutputFilename)
{
	char acFilename[MAX_PATH];

	const char* szName = "GmSnd";

	const char* szPlatformName = GetPlatformName(s_eExportType);
	if (szPlatformName)
	{
		Asura_PrintfToBfr(acFilename, "..\\%s_Release\\sounds\\%s.asr%s", MAX_PATH, true, 
			szPlatformName, szName, ShouldExportBigEndian() ? ASURA_STANDARD_FILE_EXTENSION_BE_SUFFIX : "");
		xOutputFilename = acFilename;
	}
	else
	{
		xOutputFilename = szName;
		xOutputFilename += ".unknown_platform";
	}
}

void Tools_Level_Export::AddGlobalSoundEventsToExportList()
{
	if(Asura_Sound_Event_Storage::GetNumberOfEvents())
	{
		//Check the events in an order that should improve the chances of getting a balanced tree on reload. RAR 17/08/2006
		for(Asura_TemplateHashTree_SaveIterator xIt(Asura_Sound_Event_Storage::GetNumberOfEvents());!xIt.Done();xIt.Next())
		{
			const Asura_Sound_Event* pxEvent = Asura_Sound_Event_Storage::GetEventByIndex(xIt.GetCurrent());
			if(pxEvent->IsGlobalSound() || m_bIsToolsSoundExport)//(For the tools sound file we want to include all events) RAR 16/01/2007
			{
				AddSoundEventToExportList(pxEvent->GetHashID(), pxEvent->GetName());
			}
		}
	}
}


void Tools_Level_Export::ExcludeGlobalSoundEvents()
{

	//search for all sound events that have been flagged as global
	for(u_int i=0;i<Asura_Sound_Event_Storage::GetNumberOfEvents();i++)
	{
		const Asura_Sound_Event* pxEvent = Asura_Sound_Event_Storage::GetEventByIndex(i);
		if(pxEvent->IsGlobalSound())
		{
			AddSoundEventToIgnore(pxEvent);
		}	
	}

}

void Tools_Level_Export::AddSoundEventToIgnore(Asura_Hash_ID uEventHash)
{
	const Asura_Sound_Event* pxEvent = Asura_Sound_Event_Storage::GetEventByHash(uEventHash);
	if(pxEvent)
	{
		AddSoundEventToIgnore(pxEvent);
	}
}

void Tools_Level_Export::AddSoundEventToIgnore(const Asura_Sound_Event* pxEvent)
{
	Asura_Assert(pxEvent,"");

	bool bIgnoreChildrenAsWell = false;

	//remove from list of events to export
	if(m_xSoundEventList.contains(pxEvent))
	{
		m_xSoundEventList.delete_entry(pxEvent);
		//Event was in list to be exported , so will need to ignore child playables as well
		bIgnoreChildrenAsWell = true;
	}
		
	//mark as an event that has been dealt with to prevent subsequent inclusion
	int iJunkIndex;
	if(!m_pxSoundEventTree->FindNodeIndexByHash(pxEvent->GetHashID(),true,iJunkIndex))
	{
		//Event hasn't been seen before , so will need to ignore child playables as well.
		bIgnoreChildrenAsWell = true;
	}
	
	if(bIgnoreChildrenAsWell)
	{
		//exclude any events/samples that it uses
		for(u_int i=0;i<pxEvent->GetNumPlayables();i++)
		{
			const Asura_Sound_Playable* pxPlayable = pxEvent->GetPlayableSound(i);
			if(pxPlayable->IsSample())
			{
				const Asura_Sound_Sample* pxChildSample = (const Asura_Sound_Sample*) pxPlayable;
				AddSoundSampleToIgnore(pxChildSample);
			}
			else
			{
				const Asura_Sound_Event* pxChildEvent = (const Asura_Sound_Event*) pxPlayable;
				AddSoundEventToIgnore(pxChildEvent);
			}
		}
	}
}

void Tools_Level_Export::AddSoundSampleToIgnore(Asura_Hash_ID uSampleHash)
{
	const Asura_Sound_Sample* pxSample = Asura_Sound_Event_Storage::GetSampleByHash(uSampleHash);
	if(pxSample)
	{
		AddSoundSampleToIgnore(pxSample);
	}
}

void Tools_Level_Export::AddSoundSampleToIgnore(const Asura_Sound_Sample* pxSample)
{
	if(!pxSample) return;

	//remove from list of samples to export
	if(m_xSoundSampleList.contains(pxSample)) m_xSoundSampleList.delete_entry(pxSample);
	
	//mark as a sample that has been dealt with to prevent subsequent inclusion
	int iJunkIndex;
	m_pxSoundSampleTree->FindNodeIndexByHash(pxSample->GetHashID(),true,iJunkIndex);

	#if defined ASURA_USE_AUDIO_SYSTEM
		//get the filename used and exclude that as well
		Asura_Hash_ID uWave = pxSample->GetWaveHash();
		if(uWave == ASURA_HASH_ID_UNSET) return;

		const char* szFilename = Asura_Audio_System::GetWaveFilename(uWave);

		int iID = 0;
	#else
		//get the filename used and exclude that as well
		Asura_Sound_ID eSoundID = pxSample->GetSoundID();
		if(eSoundID == ASURA_SID_NO_SOUND) return;

		const char* szFilename = Asura_Sound_System::GetFileNameFromSoundID(eSoundID);

		int iID = ASURA_SID_DYNAMIC;
	#endif

	if(!szFilename) return;

	AddSoundToIgnore(iID, szFilename);
}


void Tools_Level_Export::AddSoundEventToExportList(Asura_Hash_ID uEventHash, const char* szDebugText)
{
	Asura_Assert(This,"");
	if(!uEventHash) return;

	Asura_Assert(This->m_pxSoundEventTree,"Not in the middle of a file export?");

	//event already dealt with?
	int iJunkIndex;
	if(This->m_pxSoundEventTree->FindNodeIndexByHash(uEventHash,true,iJunkIndex)) return;

	//does the event exist?
	const Asura_Sound_Event* pxEvent = Asura_Sound_Event_Storage::FindEvent(uEventHash);
	if(!pxEvent)
	{
		if(szDebugText)
		{
			Tools_Level_Export::AddMessage(Tools_Level_Export::MT_ERROR, "Failed to find sound event 0x%x - Info: %s",uEventHash, szDebugText);
		}
		else
		{
			Tools_Level_Export::AddMessage(Tools_Level_Export::MT_ERROR, "Failed to find sound event 0x%x",uEventHash);
		}
		return;
	}
	TOOLS_RESOURCEEXPORTLOG("Sound Event",pxEvent->GetName(),true);

	//add any events/samples this depends on first
	for(u_int i=0;i<pxEvent->GetNumPlayableID();i++)
	{
		const Asura_Sound_PlayableID& xID = pxEvent->GetPlayableID(i);
		if(xID.m_eType == ASURA_SOUND_PLAYABLE_SAMPLE)
		{
			AddSoundSampleToExportList(xID.m_uHashID);
		}
		else
		{
			Asura_Assert(xID.m_eType == ASURA_SOUND_PLAYABLE_EVENT,"");
			AddSoundEventToExportList(xID.m_uHashID);
		}
	}

	//and add this event to the list
	This->m_xSoundEventList.add_entry(pxEvent);

}

// SM - 21 August 2006 11:56:13 - Added "add by event pointer" as often sound events are only available by pointer at export time
void Tools_Level_Export::AddSoundEventToExportList(const Asura_Sound_Event* pxEvent)
{
	if(!pxEvent)
	{
		Tools_Level_Export::AddMessage(Tools_Level_Export::MT_ERROR, "Sound event is NULL on export");
		return;
	}

	AddSoundEventToExportList(pxEvent->GetHashID());

}

void Tools_Level_Export::AddSoundSampleToExportList(Asura_Hash_ID uSampleHash)
{
	Asura_Assert(This,"");
	if(!uSampleHash) return;

	Asura_Assert(This->m_pxSoundSampleTree,"Not in the middle of a file export?");

	//sample already dealt with?
	int iJunkIndex;
	if(This->m_pxSoundSampleTree->FindNodeIndexByHash(uSampleHash,true,iJunkIndex)) return;

	//does the sample exist?
	const Asura_Sound_Sample* pxSample = Asura_Sound_Event_Storage::FindSample(uSampleHash);
	if(!pxSample)
	{
		Tools_Level_Export::AddMessage(Tools_Level_Export::MT_ERROR, "Failed to find sound sample 0x%x",uSampleHash);
		return;
	}
	TOOLS_RESOURCEEXPORTLOG("Sound Sample",pxSample->GetName(),true);

	//add this sample to the list
	This->m_xSoundSampleList.add_entry(pxSample);
}

bool Tools_Level_Export::AddSoundEvents(HANDLE pSaveHandle)
{
	UpdateStatus(Tools_Level_Export::EXPORT_STAGE_SOUND_EVENT_SOUNDS, "Sound Event Sounds", 0);

	//Add all wav files used by the samples
	int iCount = 0;
	for(LIF<const Asura_Sound_Sample*> xSampleLIF(&m_xSoundSampleList);!xSampleLIF.done() && !IsAbortFlagSet() ;xSampleLIF.next(),iCount++)
	{
			
		s_iPercent = iCount*100/m_xSoundSampleList.size();
		UpdateProgress();

		#if defined ASURA_USE_AUDIO_SYSTEM
			Asura_Hash_ID uWave = xSampleLIF()->GetWaveHash();
			if(uWave == ASURA_HASH_ID_UNSET) continue;

			const char* szFilename = Asura_Audio_System::GetWaveFilename(uWave);
		#else
			Asura_Sound_ID eSoundID = xSampleLIF()->GetSoundID();
			if(eSoundID == ASURA_SID_NO_SOUND) continue;

			const char* szFilename = Asura_Sound_System::GetFileNameFromSoundID(eSoundID);
		#endif

		if(!szFilename)
		{
			Asura_Assert(0,"Failed to get sound filename");
			continue;
		}

		TOOLS_RESOURCEEXPORTLOG("Sound Sample",xSampleLIF()->GetName(),false);
	
		SoundExportData xSound;
		#ifndef ASURA_USE_AUDIO_SYSTEM
		xSound.m_iID = ASURA_SID_DYNAMIC;
		#else
		xSound.m_iID = 0;
		#endif
		xSound.m_xFilename = szFilename;
		xSound.m_bOnlyUsedByHash = true;
		xSound.m_bLooping = xSampleLIF()->GetLooping();
		if( Tools_SoundEvent_System::DoesPlatformUseCompressionQuality( s_eExportType ) )
		{
			xSound.m_iFrequency = xSampleLIF()->GetCompressionQuality( s_eExportType );
		}
		AddSound(pSaveHandle,&xSound);
	}

	UpdateStatus(Tools_Level_Export::EXPORT_STAGE_END, 0, -1);

	//For tools exports we are only interested in exporting the wav files , and not the events and sample chunks.
	if(m_bIsToolsSoundExport) return true;	

	if(IsAbortFlagSet()) return false;

	if(pSaveHandle != INVALID_HANDLE_VALUE)
	{
		//Fill in a save block containing the sample and event chunks
		//Also will need the mixers if this is the global sound events file.
		Asura_SaveBlock xSaveBlock;

		if(s_bIsGlobalSoundEventExport)
		{
			Asura_Chunk_SoundEvent_GlobalSettings::Create(&xSaveBlock);
			Asura_Chunk_SoundEvent_Mixer::Create(&xSaveBlock);
			#ifdef ASURA_USE_AUDIO_SYSTEM
			Asura_Chunk_DSP::Create( &xSaveBlock );
			#endif
		}
		for(LIF<const Asura_Sound_Sample*> xSampleLIF(&m_xSoundSampleList);!xSampleLIF.done();xSampleLIF.next())
		{
			Asura_Chunk_SoundEvent_Sample::Create(xSampleLIF(),&xSaveBlock);
		}

		for(LIF<const Asura_Sound_Event*> xEventLIF(&m_xSoundEventList);!xEventLIF.done();xEventLIF.next())
		{
			if(xEventLIF()->IsEventMapping())
			{
				Asura_Chunk_SoundEvent_Mapping::Create(xEventLIF(),&xSaveBlock);
			}
			else
			{
				Asura_Chunk_SoundEvent_Event::Create(xEventLIF(),&xSaveBlock);
			}
		}

		//write the chunks to the file
		u_int uDataSize = xSaveBlock.GetSize() - ASURA_FILE_ID_NUM_CHARS;

		DWORD uBytesWritten;
		WriteFile( pSaveHandle, xSaveBlock.GetStartPtr() + ASURA_FILE_ID_NUM_CHARS, uDataSize, &uBytesWritten, NULL );

		if(uBytesWritten != uDataSize)
		{
			AddMessage( MT_ERROR, "I/O error." );
			return false;
		}
	}
	return true;
}


void Tools_Level_Export::LoadSoundEventWavs()
{
	if(Tools_Sound_System::IsDontLoadWavs()) return;
	if(!Tools_Sound_System::ShouldLoadWavsOnQuitToGame()) return;
	
	static bool s_bFirstTime = true;
	if(!s_bFirstTime) return;
	s_bFirstTime = false;

	//Load the sound events
	UpdateStatus(Tools_Level_Export::EXPORT_STAGE_SOUND_EVENTS_TOOLSGMSND, "Sound Events (ToolsGmSnd.asr)", 0);

	//load most of the sounds from the tools sound file
	LoadAsuraFile(g_szToolsGlobalSoundFile);

	#if 1
	//load the remaining ones individually
	UpdateStatus(Tools_Level_Export::EXPORT_STAGE_SOUND_EVENTS_INDIVIDUAL, "Sound Events (Individual)", 0);

	for(u_int i=0;i<Asura_Sound_Event_Storage::GetNumberOfSamples();i++)
	{
		int iPercent = i*100/Asura_Sound_Event_Storage::GetNumberOfSamples();
		if(iPercent > s_iPercent)
		{
			s_iPercent = iPercent;
			UpdateProgress();
		}
		
		Asura_Sound_Sample* pxSample = Asura_Sound_Event_Storage::GetSampleByIndex(i);
		{
			#if defined ASURA_USE_AUDIO_SYSTEM

				const Asura_Hash_ID uWaveHash = pxSample->GetWaveHash();
				if(uWaveHash != ASURA_HASH_ID_UNSET)
				{
					Asura_Audio_System::ForceWaveToBeLoaded(uWaveHash);
				}

			#else

				Asura_Sound_ID eSoundID = pxSample->GetSoundID();
				if(eSoundID != ASURA_SID_NO_SOUND)
				{
					Asura_Sound_System::ForceSoundToBeLoaded(eSoundID);
				}

			#endif
		}
	}
	#endif
}

//eof
