/// \brief	message handler to create zipped memory stream
/// \param	size - size of LPCTSTR
/// \param	param - pointer to string with path
/// \return	EE message return code
DWORD CZLibStreamFactory::OnAddZipFile(DWORD size, void *param)
{
	VERIFY_MESSAGE_SIZE(size, sizeof(LPCTSTR));
	StdString sPath = static_cast<LPCTSTR>(param);
	sPath.MakeSafeFileName();
	//sPath.ConformSlashesForward();
	if (!CZipFileStream::AddSearchPath(sPath.c_str()))
	{
		return MSG_ERROR;
	}
	return MSG_HANDLED_STOP;
}
///	removes previous state machine mapping to file and adds new one
///	\param	stateMachine - pointer to state machine to map
///	\param	fileName - current file name for state machine
///	\param	oldFileName - old mapping file name. This value may be NULL
void CQHStateMachineManager::MapStateMachineToFileName( IObject *stateMachine, 
														IHashString *fileName, 
														IHashString *oldFileName )
{
	if( oldFileName != NULL && !oldFileName->IsEmpty() && oldFileName->GetString() != NULL )
	{
		StdString oldFile = oldFileName->GetString();
		oldFile.MakeSafeFileName();
		CHashString safeOldFileName( oldFile );

		m_StateMachineToFileName.erase( stateMachine->GetName()->GetUniqueID() );
		m_FilenameToStateMachine.erase( safeOldFileName.GetUniqueID() );
	}

	StdString file = fileName->GetString();
	file.MakeSafeFileName();
	CHashString safeFileName( file );

	// Map file unique IDs to corresponding state machines and vice versa
	// TODO: There seems to be a problem calling GetUniqueID() from the hash string returned from CQHStateMachine::GetFileName
	m_StateMachineToFileName[stateMachine->GetName()->GetUniqueID()] = safeFileName.GetUniqueID();
	m_FilenameToStateMachine[safeFileName.GetUniqueID()] = stateMachine;
}
CQHStateMachine *CQHStateMachineManager::GetStateMachineByFile( IHashString *fileName )
{
	CQHStateMachine *areturn = NULL;

	StdString file = fileName->GetString();
	file.MakeSafeFileName();
	CHashString srcFileName(file);

	static CHashString cqhsmTypeName(_T("CQHStateMachine"));
	IDTOOBJECTMAP::iterator fnameToSM = m_FilenameToStateMachine.find(srcFileName.GetUniqueID());
	if (fnameToSM != m_FilenameToStateMachine.end())
	{
		areturn = (CQHStateMachine*)(fnameToSM->second);
	}
	return areturn;
}
IBaseTextureObject * CTextureManager::GetTexture(IHashString *name )
{
	if( name != NULL )
	{
		StdString szSafeName = name->GetString();
		szSafeName.MakeSafeFileName();
		CHashString hsSafeName(szSafeName);
		//do we have it in the mapping already?
		TEXTURENAMEMAP::iterator cur = m_TextureNameMap.find( hsSafeName.GetUniqueID() );
		if( cur != m_TextureNameMap.end() )
		{
			//found one already loaded
			return (cur->second);
		}
	}
	return NULL;
}
/// message handler to check if a file exists
/// \param size - size of a CHECKFILEEXISTS
/// \param param - pointer to a CHECKFILEEXISTS struct
/// \return MSG_XXX return value
DWORD CZLibStreamFactory::OnCheckFileExists(DWORD size, void *param)
{
	VERIFY_MESSAGE_SIZE(size, sizeof(CHECKFILEEXISTS));
	CHECKFILEEXISTS &cfe = *(CHECKFILEEXISTS*)param;

	StdString sPath = cfe.pFilePath;
	sPath.MakeSafeFileName();
	sPath.ConformSlashesForward();

	if( CZipFileStream::CheckFileExist( sPath.c_str() ) )
	{
		cfe.bExists = true;
		return MSG_HANDLED_STOP;
	}
	
	cfe.bExists = false;
	return MSG_HANDLED_PROCEED;
}
bool CQHStateMachineManager::AddStateMachine( IHashString *afileName )
{
	bool areturn = false;
	if( afileName != NULL && 
		afileName->GetString() != NULL &&
		!afileName->IsEmpty() )
	{
		StdString file = afileName->GetString();
		file.MakeSafeFileName();
		LOADFILEEXTPARAMS lfep;
		lfep.fileName = (TCHAR*)file.c_str();
		lfep.bInternalLoad = true;

		static DWORD msgHash_LoadFileByExtension = CHashString(_T("LoadFileByExtension")).GetUniqueID();
		DWORD retVal = m_ToolBox->SendMessage(msgHash_LoadFileByExtension, sizeof(LOADFILEEXTPARAMS), &lfep);
	}

	return areturn;
}
/// \brief Adds a texture to the manager and returns a pointer to the object. If object already
/// exists, increments its internal reference count and returns the object. Takes
/// a structure of type TEXTUREOBJECTPARAMS
DWORD CTextureManager::OnAddTexture(DWORD size, void *params)
{
	//maybe change this to a loader? But texture objects should not exist in the hierarchy.
	//get the param structure
	TEXTUREOBJECTPARAMS *texObjParams;
	IBaseTextureObject * currentTexture = NULL;
	TEXTURENAMEMAP::iterator cur;

	texObjParams = (TEXTUREOBJECTPARAMS *)params;
	VERIFY_MESSAGE_SIZE(sizeof(TEXTUREOBJECTPARAMS), size);
	//look for it
	if( texObjParams->Name != NULL )
	{
		// convert to safe file name
		StdString szFileName = texObjParams->Name->GetString();
		szFileName.MakeSafeFileName();
		CHashString hashFile(szFileName);
		//do we have it in the mapping already?
		TEXTURENAMEMAP::iterator itr = m_TextureNameMap.find( hashFile.GetUniqueID() );
		if (itr != m_TextureNameMap.end())
			currentTexture = itr->second;

		if( currentTexture != NULL )
		{
			currentTexture->IncrementRefCount();
		}
		else
		{
			if (texObjParams->bLoad)
			{
				if (m_currentTexMemArea == TEX_MEM_VIDEO)
				{
					//new texture
					//check extension
					if( _tcsstr( hashFile.GetString(), ".hdr" )!= NULL ) 
					{
						static CHashString texName(_T("CDX9TextureObject"));
						currentTexture = (ITextureObject*)CreateTextureObject( &hashFile,  &texName);
						assert( currentTexture );
						currentTexture->SetTextureName( &hashFile );
						currentTexture->LoadFromFile(hashFile.GetString() );
					}else if( _tcsstr( hashFile.GetString(), ".ant" )!= NULL ) 
					{
						static CHashString aniTexObj(_T("CAnimatedTextureObject") );
						currentTexture = CreateTextureObject( &hashFile, &aniTexObj);
						currentTexture->LoadFromFile(hashFile.GetString() );
					}else if( _tcsstr( hashFile.GetString(), _T(".dds") ) != NULL )
					{
						//we can automatically load cubemap textures if it is a cubemap texture
						currentTexture = LoadCubeDDSTexture( &hashFile );
					}
				}

				// use the internal loader as it deals with a lot of issues
				// (ie. linear vs. tiled texture alignments/restrictions) for us.
				// and gets around the bug in DevIL on small mip levels of textures
				if( !currentTexture )
				{
					static CHashString DX9TexObj(_T("CDX9TextureObject"));
					currentTexture = CreateTextureObject( &hashFile, &DX9TexObj);
					currentTexture->SetTextureName( &hashFile );
					if (!currentTexture->LoadFromFile( hashFile.GetString() ))
					{
						DeleteTextureObject( currentTexture );
						currentTexture = NULL;
					}
				}

				//try loading file by extension
				if( !currentTexture )
				{
					currentTexture = LoadTextureByExtension( &hashFile );
				}

				if( !currentTexture )
				{
					// log message about creating or allocating memory
					m_ToolBox->Log( LOGERROR, _T("Could not create texture %s\n"),
						hashFile.GetString() );
					return MSG_ERROR;
				}
			}
			else
			{
				currentTexture = texObjParams->TextureObjectInterface;
				currentTexture->IncrementRefCount();
			}
			//add to internal list
			m_TextureNameMap[hashFile.GetUniqueID()] = currentTexture;
		}		
		//set the return value
		texObjParams->TextureObjectInterface = currentTexture;
		
	}
	else //No name/filename specified, return nothing
	{
		texObjParams->TextureObjectInterface = NULL;
	}
	return MSG_HANDLED_PROCEED;
}