DWORD CSoundManager::OnRunPlaylist(DWORD size, void *param)
{
	VERIFY_MESSAGE_SIZE(size, sizeof(IHashString*));

	IHashString *fileName = (IHashString*)param;
	IDTOOBJECTMAP::iterator plIter;	

	if (fileName)
	{
		// convert to lowercase hashstring
		StdString szFileName = fileName->GetString();
		szFileName.tolower();
		CHashString tempFileName(szFileName);

		if (m_pCurrentPlaylist)
		{
			m_pCurrentPlaylist->Stop();
		}

		IDTOOBJECTMAP *objMap = GetObjectMap(&m_hsPlaylistTypeName);
		bool found = false;
		if (objMap != NULL)
		{
			plIter = objMap->find(tempFileName.GetUniqueID());

			if (plIter != objMap->end())
			{
				found = true;
			}
		}

		if (!found)
		{

			// not in map... try to load and check again
			LOADFILEEXTPARAMS lfep;
			lfep.fileName = (TCHAR*) tempFileName.GetString();
			lfep.bInternalLoad = true;
			static DWORD msgHash_LoadFileByExtension = CHashString(_T("LoadFileByExtension")).GetUniqueID();
			m_ToolBox->SendMessage(msgHash_LoadFileByExtension, sizeof(LOADFILEEXTPARAMS), &lfep);
			
			objMap = GetObjectMap(&m_hsPlaylistTypeName);
			if (objMap != NULL)
			{
				plIter = objMap->find(tempFileName.GetUniqueID());
				if (plIter != objMap->end())
				{
					found = true;
				}
			}

			if (!found)
			{
				m_ToolBox->Log(LOGWARNING, _T("Sound manager: could not open playlist file %s\n"), tempFileName.GetString());
				return MSG_NOT_HANDLED;
			}
		}
		
		m_pCurrentPlaylist = dynamic_cast<ISoundObject *>(plIter->second);
		if (m_pCurrentPlaylist != NULL)
		{
			m_pCurrentPlaylist->Play();
		}
		else
		{
			m_ToolBox->Log(LOGWARNING, _T("Dynamic cast failed for CMusicPlayList in %s at line %d\n"),
				__FILE__, __LINE__);
			return MSG_NOT_HANDLED;
		}		
	}

	return MSG_HANDLED_STOP;
}
DWORD CSoundLoader::OnLoadFile(DWORD size, void *params)
{
	VERIFY_MESSAGE_SIZE(size, sizeof(TCHAR *));
	TCHAR *pFileName = (TCHAR *)params;
	
	StdString fileName = pFileName;

	fileName.tolower();

	DWORD retval = MSG_HANDLED_STOP;
	CHashString hszFileName(fileName);

	set<DWORD>::iterator fileIter = m_FilesLoaded.find(hszFileName.GetUniqueID());
	if (fileIter != m_FilesLoaded.end())
	{
		// this file has already been loaded (hopefully correctly)
		return retval;
	}

	StdString extension, currentToken;
	fileName.GetToken(_T("."), currentToken);

	while (_tcscmp(currentToken, _T("")) != 0)
	{
		extension = currentToken;
		fileName.GetToken(_T("."), currentToken);
	}
	
	static CHashString hszWav(_T("wav"));
	static CHashString hszOgg(_T("ogg"));
	static CHashString hszMP3(_T("mp3"));
	static CHashString hszXmp(_T("xmp"));

	CHashString hszExt(extension);
	DWORD extID = hszExt.GetUniqueID();

	if ((extID == hszWav.GetUniqueID()) ||
		(extID == hszOgg.GetUniqueID()) ||
		(extID == hszMP3.GetUniqueID()))
	{
		bool success = LoadSoundFile(fileName, &hszExt);
		if (!success)
		{
			m_ToolBox->Log(LOGWARNING, _T("Failed to load sound %s\n"), (const TCHAR*)fileName);
			retval = MSG_WARNING;
		}
		else
		{
			m_FilesLoaded.insert(hszFileName.GetUniqueID());
		}
	}

	else if (extID == hszXmp.GetUniqueID())
	{
		bool success = LoadPlaylistFile(fileName);
		if (!success)
		{
			m_ToolBox->Log(LOGWARNING, _T("Failed to load playlist %s\n"), (const TCHAR*)fileName);
			retval = MSG_WARNING;
		}
		else
		{
			m_FilesLoaded.insert(hszFileName.GetUniqueID());
		}
	}

	return retval;
}
DWORD COpenALSoundUtility::OnLoadSoundDatabase(DWORD size, void* param)
{
	VERIFY_MESSAGE_SIZE(size, sizeof(IHashString));
	IHashString *dbFileName = (IHashString*) param;

	if ((dbFileName != NULL) && (_tcscmp(dbFileName->GetString(), _T("")) != 0))
	{
		TCHAR *fileName = _tcsdup(dbFileName->GetString());
		LOADFILEEXTPARAMS lfep;
		lfep.fileName = fileName;
		lfep.bInternalLoad = true;

		static DWORD msgLoadFileByExtension = CHashString(_T("LoadFileByExtension")).GetUniqueID();
		DWORD retval = m_ToolBox->SendMessage(msgLoadFileByExtension, sizeof(LOADFILEEXTPARAMS), &lfep);
		free( fileName );
		if (retval == MSG_HANDLED)
		{
			// clear prior sound list - not additive, exclusive!
			m_SoundMap.clear();
			
			CHashString hsSoundDBObject;
			DATABASEINFO dbi;
			dbi.m_FileName = dbFileName;
			static DWORD msgGetDatabase = CHashString(_T("GetDatabase")).GetUniqueID();
			retval = m_ToolBox->SendMessage(msgGetDatabase, sizeof(DATABASEINFO), &dbi);
			if (retval == MSG_HANDLED)
			{
				hsSoundDBObject.Init(dbi.m_DatabaseName->GetString());
				DATABASEATTRIBUTEPARAMS dap;
				CREATEARCHIVE ca;
				static CHashString memType(_T("Memory"));

				ca.mode = STREAM_MODE_WRITE | STREAM_MODE_READ;
				ca.streamData = NULL;
				ca.streamSize = 0;
				ca.streamType = &memType;
				static DWORD msgHash_CreateArchive = CHashString(_T("CreateArchive")).GetUniqueID();
				m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &ca);

				IArchive *attribArchive = ca.archive;
				if (attribArchive == NULL)
				{
					m_ToolBox->Log(LOGERROR, _T("Sound manager: archive is null; could not get sound attributes!\n\tNo sounds loaded!\n"));
					return MSG_ERROR;
				}

				dap.m_AttributeArchive = attribArchive;

				static DWORD msgGetAttribute = CHashString(_T("GetAttribute")).GetUniqueID();
				static CHashString hsKeyString(_T("KeyString"));
				static CHashString hsFileName(_T("FileName"));
				static CHashString hsGlobalVolume(_T("GlobalVolume"));
				static CHashString hsCachedUncompressed(_T("CacheUncompressed"));

				static CHashString hsDBType(_T("CDefinedDatabase"));
				for (UINT i=0; i<(UINT)dbi.m_nItems; i++)
				{
					// get key string
					attribArchive->SeekTo(0, SEEK_SET);
					dap.m_Index = i;
					dap.m_AttributeName = &hsKeyString;
					retval = m_ToolBox->SendMessage(msgGetAttribute, sizeof(DATABASEATTRIBUTEPARAMS), &dap, &hsSoundDBObject, &hsDBType);
					if (retval != MSG_HANDLED)
					{
						m_ToolBox->Log(LOGERROR, _T("Sound manager: could not get key attribute for row %d; sounds not fully loaded!\n"), i);
						attribArchive->Close();
						return MSG_ERROR;
					}

					CHashString hsKey;
					StdString szKey;
					attribArchive->SetIsWriting(false);
					attribArchive->Read(szKey);
					hsKey = szKey;

					// get filename
					attribArchive->SeekTo(0, SEEK_SET);
					dap.m_AttributeName = &hsFileName;
					retval = m_ToolBox->SendMessage(msgGetAttribute, sizeof(DATABASEATTRIBUTEPARAMS), &dap, &hsSoundDBObject, &hsDBType);
					if (retval != MSG_HANDLED)
					{
						m_ToolBox->Log(LOGERROR, _T("Sound manager: could not get file attribute for row %d; sounds not fully loaded!\n"), i);
						attribArchive->Close();
						return MSG_ERROR;
					}

					CHashString hsFile;
					StdString szFile;
					attribArchive->SetIsWriting(false);
					attribArchive->Read(szFile);
					szFile.tolower();
					hsFile = szFile;

					// get volume
					attribArchive->SeekTo(0, SEEK_SET);
					dap.m_AttributeName = &hsGlobalVolume;
					retval = m_ToolBox->SendMessage(msgGetAttribute, sizeof(DATABASEATTRIBUTEPARAMS), &dap, &hsSoundDBObject, &hsDBType);
					if (retval != MSG_HANDLED)
					{
						m_ToolBox->Log(LOGERROR, _T("Sound manager: could not get volume attribute for row %d; sounds not fully loaded!\n"), i);
						attribArchive->Close();
						return MSG_ERROR;
					}

					float fVolume;
					attribArchive->SetIsWriting(false);
					attribArchive->Read(fVolume);

					// get cached attribute
					attribArchive->SeekTo(0, SEEK_SET);
					dap.m_AttributeName = &hsCachedUncompressed;
					retval = m_ToolBox->SendMessage(msgGetAttribute, sizeof(DATABASEATTRIBUTEPARAMS), &dap, &hsSoundDBObject, &hsDBType);
					if (retval != MSG_HANDLED)
					{
						m_ToolBox->Log(LOGERROR, _T("Sound manager: could not get volume attribute for row %d; sounds not fully loaded!\n"), i);
						attribArchive->Close();
						return MSG_ERROR;
					}

					bool bCachedUncompressed;
					attribArchive->SetIsWriting(false);
					attribArchive->Read(bCachedUncompressed);

					if (_tcscmp(szKey, _T("GlobalSoundVolume")) == 0)
					{
						static DWORD msgSetGlobalSoundVolume = CHashString(_T("SetGlobalSoundVolume")).GetUniqueID();
						m_ToolBox->SendMessage(msgSetGlobalSoundVolume, sizeof(float), &fVolume);						
					}
					else if(_tcscmp(szKey, _T("GlobalMusicVolume")) == 0)
					{
						static DWORD msgSetGlobalMusicVolume = CHashString(_T("SetGlobalMusicVolume")).GetUniqueID();
						m_ToolBox->SendMessage(msgSetGlobalMusicVolume, sizeof(float), &fVolume);
					}
					else
					{					
						// insert into map
						GLOBALSOUNDDATA gsd;
						gsd.dwFileName = hsFile.GetUniqueID();
						gsd.fVolume = fVolume;
						gsd.bCachedUncompressed = bCachedUncompressed;

						m_SoundMap[hsKey.GetUniqueID()] = gsd;
						m_FileToKeyMap[hsFile.GetUniqueID()] = hsKey.GetUniqueID();
					}
				}

				attribArchive->Close();
			}
			else
			{
				m_ToolBox->Log(LOGERROR, _T("Sound manager: could not get database info!\n\tNo sounds loaded!\n"));
				return MSG_ERROR;
			}
		}
		else
		{
			m_ToolBox->Log(LOGERROR, _T("Sound manager: sound database failed to load!\n\tNo sounds loaded!\n"));
			return MSG_ERROR;
		}
	}
	return MSG_HANDLED_STOP;
}