// load a file if we recognize the type.
DWORD CXMLWorldLoader::OnLoadWorldFile(DWORD size, void *params)
{
	CHashString oldVersion = _T("");
	CREATEOBJECTPARAMS cop;
	INITOBJECTPARAMS iop;
	SERIALIZEOBJECTPARAMS sop;
	DWORD retVal;
	IXMLArchive *Archive = NULL;
	DWORD currNode = 0;
	LOADINGUPDATEPARAMS pbp;

	VERIFY_MESSAGE_SIZE(size, sizeof(TCHAR *));
	TCHAR *pFileName = (TCHAR *)params;

	// use both a hashstring and a pointer so that the first iteration of the loop
	// will pass SetParentName a NULL instead of an address of a hashstring
	// hashed to ""
	CHashString hszParentType(_T("CWorld"));
	CHashString hszParentName(_T("World"));
	CHashString hszName(_T(""));
	CHashString hszTypeName(_T(""));
	CHashString streamType(_T("File"));

	// delete previous world root
	DELETEOBJECTPARAMS dop;
	dop.name = &hszParentName;
	static DWORD msgHash_DeleteObject = CHashString(_T("DeleteObject")).GetUniqueID();
	EngineGetToolBox()->SendMessage(msgHash_DeleteObject, sizeof(dop), &dop );
	// delete is ok to fail if no world has been created yet

	// create new world root
	cop.name = &hszParentName;
	cop.parentName = NULL;
	cop.typeName = &hszParentType;
	static DWORD msgHash_CreateObject = CHashString(_T("CreateObject")).GetUniqueID();
	DWORD returnValue = EngineGetToolBox()->SendMessage(msgHash_CreateObject, sizeof(cop), &cop );
	if (returnValue != MSG_HANDLED)
	{
		EngineGetToolBox()->Log(LOGERROR, _T("Failed to create World Root Object\n"));
		return MSG_ERROR;
	}

	CREATEARCHIVE ca;
	ca.streamData = (void *)pFileName;
	ca.mode = STREAM_MODE_READ;
	ca.streamType = &streamType;
#ifdef USEXMLFILESTREAMS
	// call the Archive factory to create an XML archive
	static DWORD msgHash_CreateXMLArchiveStream = CHashString(_T("CreateXMLArchiveStream")).GetUniqueID();
	if (retVal = m_ToolBox->SendMessage(msgHash_CreateXMLArchiveStream, sizeof(CREATEARCHIVE), &ca) != MSG_HANDLED)
#else
	// call the Archive factory to create an XML archive
	static DWORD msgHash_CreateXMLArchive = CHashString(_T("CreateXMLArchive")).GetUniqueID();
	if (retVal = m_ToolBox->SendMessage(msgHash_CreateXMLArchive, sizeof(CREATEARCHIVE), &ca) != MSG_HANDLED)
#endif
	{
		return retVal;
	}

	Archive = dynamic_cast<IXMLArchive *>(ca.archive);
	DWORD numNodes = Archive->GetNumberOfNodes();

	// Deteriminte World Version
	int iWorldNumAttrib = Archive->GetNumAttributes();

	StdString szNodeName;
	Archive->GetNode(szNodeName);
	
	pbp.currentPosition = Archive->GetCurrentNodePosition();
	pbp.totalSize = numNodes;
	// update progress bar
	static DWORD msgHash_LoadingUpdate = CHashString(_T("LoadingUpdate")).GetUniqueID();
	m_ToolBox->SendMessage(msgHash_LoadingUpdate, sizeof(LOADINGUPDATEPARAMS), &pbp);


	// must start with <World>
	if (szNodeName != _T("CWorld"))
	{
		EngineGetToolBox()->SetErrorValue(WARN_INVALID_FILE);
		EngineGetToolBox()->Log(LOGWARNING, _T("Invalid world file %s\n"), pFileName);
		Archive->Close();
		return MSG_ERROR;
	}

	// Version 1.0
	if( iWorldNumAttrib == 1 )
	{
		// read the name of the world
		StdString szName;
		Archive->Read( szName, _T("Name") );
		m_WorldFileVersion = 1.0f;
		static DWORD msgHash_GetFileVersion = CHashString(_T("GetFileVersion")).GetUniqueID();
		DWORD retval = m_ToolBox->SendMessage(msgHash_GetFileVersion, sizeof(IHashString), &oldVersion);
		if (retval != MSG_HANDLED)
		{
			m_ToolBox->Log(LOGERROR, _T("Could not get world version!"));
			return MSG_ERROR;
		}
		CHashString hszNewVersion = _T("1.0");
		static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
		retval = m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &hszNewVersion);
		if (retval != MSG_HANDLED)
		{
			m_ToolBox->Log(LOGERROR, _T("Could not set world version!"));
			return MSG_ERROR;
		}
	}
	// Version 1.5
	else if( iWorldNumAttrib == 2 )
	{
		StdString szName;
		Archive->Read( szName, _T("Name") );
		float fileVersion = 0;
		Archive->Read( m_WorldFileVersion, _T("Version") );
		static DWORD msgHash_GetFileVersion = CHashString(_T("GetFileVersion")).GetUniqueID();
		DWORD retval = m_ToolBox->SendMessage(msgHash_GetFileVersion, sizeof(IHashString), &oldVersion);
		if (retval != MSG_HANDLED)
		{
			m_ToolBox->Log(LOGERROR, _T("Could not get world version!"));
			return MSG_ERROR;
		}
		TCHAR buf[50];
		_stprintf(buf, "%.1f", m_WorldFileVersion);
		CHashString hszNewVersion(buf);
		static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
		retval = m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &hszNewVersion);
		if (retval != MSG_HANDLED)
		{
			m_ToolBox->Log(LOGERROR, _T("Could not set world version!"));
			return MSG_ERROR;
		}
	}
	// Unknown Version
	else
	{
		EngineGetToolBox()->SetErrorValue(WARN_INVALID_FILE);
		EngineGetToolBox()->Log(LOGWARNING, _T("Invalid world file %s\n"), pFileName);
		Archive->Close();
		static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
		m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
		return MSG_ERROR;
	}

	// failure checks
	bool componentFailed = false;
	int failedDepth = 0;

	float secondsPerFrame = 1 / m_fLoadingUpdateFPS;
	ITimer *timer = EngineGetToolBox()->GetTimer();
	float lastLoadTime = timer->GetRealTime();
	float elapsedTime = 0.0f;

	while (Archive->GetNode(szNodeName))
	{
		int currDepth = Archive->GetDepth();
		if (componentFailed == true)
		{
			// current node is child of failed
			if (currDepth > failedDepth)
			{
				continue;
			}
			// if sibling or uncle, reset comp failed flag
			else
			{
				componentFailed = false;
			}
		}

		hszTypeName.Init( szNodeName.c_str() );

		StdString parentName;
		StdString parentType;
		StdString childType;
		Archive->GotoParentNode( parentType );
		Archive->Read( parentName, _T("Name") );
		if ( parentName != _T("") )
		{
			hszParentName = parentName;
		}
		Archive->ReturnToChildNode( childType );
		if( hszTypeName.GetString() != childType )
		{
			assert( hszTypeName.GetString() == childType );
			static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
			m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
			return MSG_ERROR;
		}
		//parentName = Archive->GetParentName();

		StdString szName;
		Archive->Read( szName, _T("Name") );
		hszName.Init( szName.c_str() );

		cop.parentName = &hszParentName;
		cop.typeName = &hszTypeName;
		cop.name = &hszName;
		static DWORD msgHash_CreateObject = CHashString(_T("CreateObject")).GetUniqueID();
		DWORD retval = m_ToolBox->SendMessage(msgHash_CreateObject, sizeof(CREATEOBJECTPARAMS), &cop, NULL, NULL);

		if (retval != MSG_HANDLED)
		{
			m_ToolBox->Log(LOGINFORMATION, _T("World loader: could not create component; skipping children!\n"));
			componentFailed = true;
			failedDepth = Archive->GetDepth();			
			continue;
		}

		// 1.0 -> 1.5 Readjusted scale and position on object by 1000/898
		if( m_WorldFileVersion == 1.0 )
		{
			float fConvert = 1000.0f/898.0f;
			if( hszTypeName.GetUniqueID() == CHashString(_T("CV3ORenderObject")).GetUniqueID() )
			{
				StdString szFileName;
				Vec3 vPosition(0,0,0);
				Vec3 vRotation(0,0,0);
				Vec3 vScaling(0,0,0);

				Archive->Read( szFileName, _T("FileName") );
				
				Archive->Read( vPosition, _T("Position") );
				vPosition.x = ( vPosition.x * fConvert );
				vPosition.y = ( vPosition.y * fConvert );
				vPosition.z = ( vPosition.z * fConvert );
				
				Archive->Read( vRotation, _T("Rotation") );

				Archive->Read( vScaling, _T("Scaling") );
				vScaling.x = ( vScaling.x * fConvert );
				vScaling.y = ( vScaling.y * fConvert );
				vScaling.z = ( vScaling.z * fConvert );

				IArchive *MemArchive;
				CHashString memType(_T("Memory"));

				CREATEARCHIVE caOut;
				caOut.mode = STREAM_MODE_WRITE;
				caOut.streamData = NULL;
				caOut.streamSize = 0;
				caOut.streamType = &memType;
				static DWORD msgHash_CreateArchive = CHashString(_T("CreateArchive")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &caOut) != MSG_HANDLED)
				{
					static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
					m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
					return true;
				}
				MemArchive = caOut.archive;

				MemArchive->Write( szFileName, _T("FileName") );
				MemArchive->Write( vPosition, _T("Position") );
				MemArchive->Write( vRotation, _T("Rotation") );
				MemArchive->Write( vScaling, _T("Scaling") );
		
				CREATESTREAM cs;
				cs.streamData = caOut.streamData;
				cs.streamSize = caOut.streamSize;
				cs.mode = STREAM_MODE_READ;
				static DWORD msgHash_CreateStream_Memory = CHashString(_T("CreateStream_Memory")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateStream_Memory, sizeof(CREATESTREAM), &cs) != MSG_HANDLED)
				{
					static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
					m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
					return true;
				}
				MemArchive->Init(cs.openStream);

				sop.name = &hszName;
				sop.archive = MemArchive;
				static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();
				m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sop, NULL, NULL);
				
				MemArchive->Close();
			}

			else if( hszTypeName.GetUniqueID() == CHashString(_T("CPhysicsObject")).GetUniqueID() )
			{
				//StdString szDynamics;
				StdString szType;
				StdString szShapeFileName;
				//float fMass;
				//Vec3 vPosition;
				//Vec3 vRotation;
				//Vec3 vScaling;

				//Archive->Read( vPosition, _T("pos") );
				//vPosition.SetX( vPosition.GetX() * fConvert );
				//vPosition.SetY( vPosition.GetY() * fConvert );
				//vPosition.SetZ( vPosition.GetZ() * fConvert );

				//Archive->Read( vRotation, _T("rot") );
				
				//Archive->Read( vScaling, _T("scale") );
				//vScaling.SetX( vScaling.GetX() * fConvert );
				//vScaling.SetY( vScaling.GetY() * fConvert );
				//vScaling.SetZ( vScaling.GetZ() * fConvert );

				//Archive->Read( fMass, _T("mass") );
				Archive->Read( szType, _T("Type") );
				Archive->Read( szShapeFileName, _T("filename") );

				IArchive *MemArchive;
				CHashString memType(_T("Memory"));
				//int size =	sizeof(char) * 256 * 2 + sizeof(float) + sizeof(Vec3) * 3 + 256;
				
				CREATEARCHIVE caOut;
				caOut.mode = STREAM_MODE_WRITE;
				caOut.streamData = NULL;
				caOut.streamSize = 0;
				caOut.streamType = &memType;
				static DWORD msgHash_CreateArchive = CHashString(_T("CreateArchive")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &caOut) != MSG_HANDLED)
				{
					static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
					m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
					return true;
				}
				MemArchive = caOut.archive;

				//MemArchive->Write( vPosition, _T("pos") );
				//MemArchive->Write( vRotation, _T("rot") );
				//MemArchive->Write( vScaling, _T("scale") );
				//MemArchive->Write( fMass, _T("mass") );
				//MemArchive->Write( szDynamics, _T("dynamics") );
				//MemArchive->Write( szShapeFileName, _T("shapeFile") );
				MemArchive->Write( szType, _T("Type") );
				MemArchive->Write( szShapeFileName, _T("filename") );

				CREATESTREAM cs;
				cs.streamData = caOut.streamData;
				cs.streamSize = caOut.streamSize;
				cs.mode = STREAM_MODE_READ;
				static DWORD msgHash_CreateStream_Memory = CHashString(_T("CreateStream_Memory")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateStream_Memory, sizeof(CREATESTREAM), &cs) != MSG_HANDLED)
				{
					static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
					m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
					return true;
				}
				MemArchive->Init(cs.openStream);

				sop.name = &hszName;
				sop.archive = MemArchive;
				static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();
				m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sop, NULL, NULL);

				MemArchive->Close();
			}
			else if( hszTypeName.GetUniqueID() == CHashString(_T("CTerrainConfig")).GetUniqueID() )
			{
				StdString szTerShaderLib;
				StdString szTerShaderEff;
				int iSectorRes;
				float fSectorSize;
				float fZScale;
				float fLODDistance;

				Archive->Read( szTerShaderLib, _T("TerrainShaderLibrary") );
				Archive->Read( szTerShaderEff, _T("TerrainShaderEffect") );
				Archive->Read( iSectorRes, _T("SectorResolution") );
				Archive->Read( fSectorSize, _T("SectorSize") );
				fSectorSize = fSectorSize * fConvert;
				Archive->Read( fZScale, _T("ZScale") );
				fZScale = fZScale * fConvert;
				Archive->Read( fLODDistance, _T("LODDistance") );
				
				IArchive *MemArchive;
				CHashString memType(_T("Memory"));
				
				CREATEARCHIVE caOut;
				caOut.mode = STREAM_MODE_WRITE;
				caOut.streamData = NULL;
				caOut.streamSize = 0;
				caOut.streamType = &memType;
				static DWORD msgHash_CreateArchive = CHashString(_T("CreateArchive")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &caOut) != MSG_HANDLED)
				{
					static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
					m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
					return true;
				}
				MemArchive = caOut.archive;

				MemArchive->Write( szTerShaderLib, _T("TerrainShaderLibrary") );
				MemArchive->Write( szTerShaderEff, _T("TerrainShaderEffect") );
				MemArchive->Write( iSectorRes, _T("SectorResolution") );
				MemArchive->Write( fSectorSize, _T("SectorSize") );
				MemArchive->Write( fZScale, _T("ZScale") );
				MemArchive->Write( fLODDistance, _T("LODDistance") );

				CREATESTREAM cs;
				cs.streamData = caOut.streamData;
				cs.streamSize = caOut.streamSize;
				cs.mode = STREAM_MODE_READ;
				static DWORD msgHash_CreateStream_Memory = CHashString(_T("CreateStream_Memory")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateStream_Memory, sizeof(CREATESTREAM), &cs) != MSG_HANDLED)
				{
					static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
					m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
					return true;
				}
				MemArchive->Init(cs.openStream);

				sop.name = &hszName;
				sop.archive = MemArchive;
				static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();
				m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sop, NULL, NULL);

				MemArchive->Close();
			}
			else
			{
				sop.name = &hszName;
				sop.archive = Archive;
				static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();
				m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sop, NULL, NULL);
			}
		}
		else
		{
			sop.name = &hszName;
			sop.archive = Archive;
			static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();
			m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sop, NULL, NULL);
		}

		iop.name = &hszName;
		static DWORD msgHash_InitObject = CHashString(_T("InitObject")).GetUniqueID();
		m_ToolBox->SendMessage(msgHash_InitObject, sizeof(INITOBJECTPARAMS), &iop, NULL, NULL);

		elapsedTime += timer->GetRealTime() - lastLoadTime;
		lastLoadTime = timer->GetRealTime();				
		if (elapsedTime > secondsPerFrame)
		{
			elapsedTime = 0.0f;
			pbp.currentPosition = Archive->GetCurrentNodePosition();
			pbp.totalSize = numNodes;
			m_ToolBox->SendMessage(msgHash_LoadingUpdate, sizeof(LOADINGUPDATEPARAMS), &pbp);
		}
	}

	pbp.currentPosition = 0;
	pbp.totalSize = 0;
	m_ToolBox->SendMessage(msgHash_LoadingUpdate, sizeof(LOADINGUPDATEPARAMS), &pbp);

	Archive->Close();

	static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
	m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);

	return MSG_HANDLED_STOP;
}
bool CWorldVisitor::Visit( IComponent * component, bool bVisitEnter )
{
	IObject *theObject;
	IHashString *name;
	IHashString *parentName;
	IHashString *type;

	StdString parentType;
	StdString childType;

	std::string str;

	theObject = dynamic_cast<IObject *>(component);
	// This shouldn't happen but it does for some odd reason....
	assert(theObject);
	if( theObject == NULL )
	{
		return false;
	}
	name = theObject->GetName();
	parentName = theObject->GetParentName();
	type = theObject->GetComponentType();

	//Check to see if it is a valid object (for object exclusion)
	if( !CheckObject( type->GetString() ) )
	{
		return true;
	}

	else
	{
		if ( name == NULL )
		{
			name = &CHashString(_T("NULL"));
		}	

		if( bVisitEnter == true )
		{
			//if( (m_pArchiver != NULL) && ( _tcscmp( type->GetString(), _T("CPhysicsObject") ) != 0 ) )
			if( (m_pArchiver != NULL) )
			{
				// Start the Node
				m_pArchiver->StartClass( type->GetString() );
				
				// Write out the Unique ID aka Name
				m_pArchiver->Write( name->GetString(), _T("Name") );
				theObject->Serialize( *m_pArchiver );
			}

			// Removal of CPhysShape and changes to CPhysicsObject
			if( _tcscmp( type->GetString(), _T("CPhysicsObject") ) == 0 )
			{
				
				CPhysObjectStruct tmpCPhysObject;
				StdString CPhyShapeFile;
				StdString CPhyShapeFileOld;
				// if it's parent is not a CTerrainSector Object
				if( _tcsstr( name->GetString(), _T("Terrain") ) == NULL )
				{
					static DWORD msgHash_GetModelFileName = CHashString(_T("GetModelFileName")).GetUniqueID();
					m_ToolBox->SendMessage(msgHash_GetModelFileName, sizeof(StdString*), &CPhyShapeFile, parentName, NULL );
					CPhyShapeFile += _T(".psl");
				}
				// CTerrainSector Object
				else
				{
					CPhyShapeFile = _T("maps\\terrain.psl");
				}

				IArchive *PhysObjectIn;
				IArchive *PhysObjectRead;
				CHashString memTypePhysObjectIn(_T("Memory"));
				
				int PhysObjectInMemSize = 1024 * 1024 * sizeof(char);
				char* PhysObjectInMemChunk = new char[PhysObjectInMemSize];
				memset( PhysObjectInMemChunk, 0, PhysObjectInMemSize );

				CREATEARCHIVE caPhysObjectIn;
				caPhysObjectIn.mode = STREAM_MODE_READ;
				caPhysObjectIn.streamData = PhysObjectInMemChunk;
				caPhysObjectIn.streamSize = PhysObjectInMemSize;
				caPhysObjectIn.streamType = &memTypePhysObjectIn;
				static DWORD msgHash_CreateArchive = CHashString(_T("CreateArchive")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &caPhysObjectIn) != MSG_HANDLED)
				{
					return true;
				}
				PhysObjectIn = caPhysObjectIn.archive;

				CREATESTREAM csPhysObjectIn;
				csPhysObjectIn.streamData = caPhysObjectIn.streamData;
				csPhysObjectIn.streamSize = caPhysObjectIn.streamSize;
				csPhysObjectIn.mode = STREAM_MODE_WRITE;
				static DWORD msgHash_CreateStream_Memory = CHashString(_T("CreateStream_Memory")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateStream_Memory, sizeof(CREATESTREAM), &csPhysObjectIn) != MSG_HANDLED)
				{
					return true;
				}
				PhysObjectIn->Init(csPhysObjectIn.openStream);		    

				SERIALIZEOBJECTPARAMS sop;
				sop.name = name;
				sop.archive = PhysObjectIn;
				static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();
				m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sop, NULL, NULL);
				PhysObjectIn->Close();
				
				CREATEARCHIVE caPhysObjectRead;
				caPhysObjectRead.mode = STREAM_MODE_WRITE;
				caPhysObjectRead.streamData = PhysObjectInMemChunk;
				caPhysObjectRead.streamSize = PhysObjectInMemSize;
				caPhysObjectRead.streamType = &memTypePhysObjectIn;
				if (m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &caPhysObjectRead) != MSG_HANDLED)
				{
					return true;
				}
				PhysObjectRead = caPhysObjectRead.archive;

				CREATESTREAM csPhysObjectRead;
				csPhysObjectRead.streamData = caPhysObjectRead.streamData;
				csPhysObjectRead.streamSize = caPhysObjectRead.streamSize;
				csPhysObjectRead.mode = STREAM_MODE_READ;
				if (m_ToolBox->SendMessage(msgHash_CreateStream_Memory, sizeof(CREATESTREAM), &csPhysObjectRead) != MSG_HANDLED)
				{
					return true;
				}
				PhysObjectRead->Init(csPhysObjectRead.openStream);
				PhysObjectRead->Read( tmpCPhysObject.vPosition, _T("pos") );
				PhysObjectRead->Read( tmpCPhysObject.vRotation, _T("rot") );
				PhysObjectRead->Read( tmpCPhysObject.vScale, _T("scale") );
				PhysObjectRead->Read( tmpCPhysObject.fMass, _T("mass") );
				PhysObjectRead->Read( tmpCPhysObject.szDynamic, _T("dynamics") );
				PhysObjectRead->Read( CPhyShapeFileOld, _T("shapeFile") );
				PhysObjectRead->Close();
                
				// Archive the Data Back In
				IArchive *MemArchivePhysObject;	
				CHashString memTypePhysObject(_T("Memory"));
				//int sizePhysObject = 1024 * 1024;
				//char* memchunkPhysObject = new char[sizePhysObject];

				CREATEARCHIVE caPhysObject;
				caPhysObject.mode = STREAM_MODE_WRITE;
				caPhysObject.streamData = PhysObjectInMemChunk;
				caPhysObject.streamSize = PhysObjectInMemSize;
				caPhysObject.streamType = &memTypePhysObject;
				if (m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &caPhysObject) != MSG_HANDLED)
				{
					return true;
				}
				MemArchivePhysObject = caPhysObject.archive;
				MemArchivePhysObject->Write( tmpCPhysObject.vPosition, _T("pos") );
				MemArchivePhysObject->Write( tmpCPhysObject.vRotation, _T("rot") );
				MemArchivePhysObject->Write( tmpCPhysObject.vScale, _T("scale") );
				MemArchivePhysObject->Write( tmpCPhysObject.fMass, _T("mass") );
				MemArchivePhysObject->Write( tmpCPhysObject.szDynamic, _T("dynamics") );
				MemArchivePhysObject->Write( CPhyShapeFile, _T("shapeFile") );
				
				CREATESTREAM csPhysObject;
				csPhysObject.streamData = caPhysObject.streamData;
				csPhysObject.streamSize = caPhysObject.streamSize;
				csPhysObject.mode = STREAM_MODE_READ;
				if (m_ToolBox->SendMessage(msgHash_CreateStream_Memory, sizeof(CREATESTREAM), &csPhysObject) != MSG_HANDLED)
				{
					return true;
				}
				MemArchivePhysObject->Init(csPhysObject.openStream);

				SERIALIZEOBJECTPARAMS sopPhysObject;
				sopPhysObject.name = name;
				sopPhysObject.archive = MemArchivePhysObject;
				m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sopPhysObject, NULL, NULL);

				MemArchivePhysObject->Close();
				//delete [] memchunkPhysObject;
				//memchunkPhysObject = NULL;
				delete [] PhysObjectInMemChunk;
				PhysObjectInMemChunk = NULL;
			}

			// Model Rename Changes
			if( (m_pReporter != NULL) && ( _tcscmp( type->GetString(), _T("CV3ORenderObject") ) == 0 ) )
			{
				IArchive *MemArchive;
				IArchive *MemArchive2;
				CHashString memType(_T("Memory"));
				memset( m_pMemChunk, '\0', m_iMemSize );

				CREATEARCHIVE ca;
				ca.mode = STREAM_MODE_READ;
				ca.streamData = m_pMemChunk;
				ca.streamSize = m_iMemSize;
				ca.streamType = &memType;
				static DWORD msgHash_CreateArchive = CHashString(_T("CreateArchive")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &ca) != MSG_HANDLED)
				{
					return true;
				}
				MemArchive = ca.archive;

				CREATESTREAM cs;
				cs.streamData = ca.streamData;
				cs.streamSize = ca.streamSize;
				cs.mode = STREAM_MODE_WRITE;
				static DWORD msgHash_CreateStream_Memory = CHashString(_T("CreateStream_Memory")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateStream_Memory, sizeof(CREATESTREAM), &cs) != MSG_HANDLED)
				{
					return true;
				}
				MemArchive->Init(cs.openStream);		    

				SERIALIZEOBJECTPARAMS sop;
				sop.name = name;
				sop.archive = MemArchive;
				static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();
				m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sop, NULL, NULL);
				MemArchive->Close();
				
				CREATEARCHIVE ca2;
				ca2.mode = STREAM_MODE_WRITE;
				ca2.streamData = m_pMemChunk;
				ca2.streamSize = m_iMemSize;
				ca2.streamType = &memType;
				if (m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &ca2) != MSG_HANDLED)
				{
					return true;
				}
				MemArchive2 = ca2.archive;

				CREATESTREAM cs2;
				cs2.streamData = ca2.streamData;
				cs2.streamSize = ca2.streamSize;
				cs2.mode = STREAM_MODE_READ;
				if (m_ToolBox->SendMessage(msgHash_CreateStream_Memory, sizeof(CREATESTREAM), &cs2) != MSG_HANDLED)
				{
					return true;
				}
				MemArchive2->Init(cs2.openStream);

				StdString wszModelFileName;
				Vec3 Position;
				Vec3 Rotation;
				Vec3 Scale;

				MemArchive2->Read( wszModelFileName );
				MemArchive2->Read( Position );
				MemArchive2->Read( Rotation );
				MemArchive2->Read( Scale );
				MemArchive2->Close();
				
				MODELMAP::iterator itr;
				bool bReArchive = false;
				while( 1 )
				{		
					itr = m_vModelReference.find( wszModelFileName );
					// If the Model Refernce already exists
					if( itr != m_vModelReference.end() )
					{
						// If its newfilename is different and it isn't an empty string
						// We Change the file name and set the archive flag
						if( (wszModelFileName != itr->second.m_wszNewFileName) &&
							(itr->second.m_wszNewFileName != StdString("")) )
						{
							wszModelFileName = itr->second.m_wszNewFileName;
							bReArchive = true;
						}
						
						// We've reached a file that has the same exact newfilename, no change neccisary
						else
						{
							break;
						}
					}
					
					
					// We change model name first (up above) and then make sure to add it as a reference and break out
					itr = m_vModelReference.find( wszModelFileName );
					if( itr == m_vModelReference.end() )
					{
						/*
						MODELINFO tmpModelInfo;
						tmpModelInfo.m_wszNewFileName = wszModelFileName;
						m_vModelReference[wszModelFileName] = tmpModelInfo;
						m_iNewEntries++;
						*/
						break;
					}
					
				}
				
				m_szLastV3OFileName = wszModelFileName;

				// Archive the object back out
				if( bReArchive == true )
				{
					IArchive *MemArchiveRE;	
					CHashString memTypeRE(_T("Memory"));
					int sizeRE = 1024 + sizeof(Vec3) * 3;
					char* memchunkRE = new char[sizeRE];

					CREATEARCHIVE caRE;
					caRE.mode = STREAM_MODE_WRITE;
					caRE.streamData = memchunkRE;
					caRE.streamSize = sizeRE;
					caRE.streamType = &memTypeRE;
					static DWORD msgHash_CreateArchive = CHashString(_T("CreateArchive")).GetUniqueID();
					if (m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &caRE) != MSG_HANDLED)
					{
						return true;
					}
					MemArchiveRE = caRE.archive;
					MemArchiveRE->Write( wszModelFileName );
					MemArchiveRE->Write( Position );
					MemArchiveRE->Write( Rotation );
					MemArchiveRE->Write( Scale );

					CREATESTREAM csRE;
					csRE.streamData = caRE.streamData;
					csRE.streamSize = caRE.streamSize;
					csRE.mode = STREAM_MODE_READ;
					static DWORD msgHash_CreateStream_Memory = CHashString(_T("CreateStream_Memory")).GetUniqueID();
					if (m_ToolBox->SendMessage(msgHash_CreateStream_Memory, sizeof(CREATESTREAM), &csRE) != MSG_HANDLED)
					{
						return true;
					}
					MemArchiveRE->Init(csRE.openStream);

					SERIALIZEOBJECTPARAMS sopRE;
					sopRE.name = name;
					sopRE.archive = MemArchiveRE;
					static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();
					m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sopRE, NULL, NULL);

					MemArchiveRE->Close();
					delete [] memchunkRE;
					memchunkRE = NULL;
					m_iV3ONameEdits++;
				}
			}
		}

		// bVisitEnter == false
		else
		{
			if( m_pArchiver != NULL )
			{
				m_pArchiver->EndClass();
			}
		}
	}
	
	return true;
}
void CParticleToolPal::CreateParticleSystem()
{
	CREATEOBJECTPARAMS cop;
	INITOBJECTPARAMS iop;
	SERIALIZEOBJECTPARAMS sop;
	
	CHashString hszParentName(_T("World"));
	CHashString hszTypeName(_T("CParticleRenderObject"));
	
	cop.parentName = &hszParentName;
	cop.typeName = &hszTypeName;
	cop.name = &m_ParticleName;
	DWORD retval = m_ToolBox->SendMessage(_T("CreateObject"), sizeof(CREATEOBJECTPARAMS), &cop, NULL, NULL);

	IArchive *MemArchive;
	CHashString memType(_T("Memory"));
	int size =	sizeof(char) * 256 + sizeof(Vec3) * 3 + 256;
	char* memchunk = new char[size];
	memset( memchunk, 0, size );
				
	CREATEARCHIVE caOut;
	caOut.mode = STREAM_MODE_WRITE;
	caOut.streamData = memchunk;
	caOut.streamSize = size;
	caOut.streamType = &memType;
	if (m_ToolBox->SendMessage(_T("CreateArchive"), sizeof(CREATEARCHIVE), &caOut) != MSG_HANDLED)
	{
		return;
	}
	MemArchive = caOut.archive;
	Vec3 vec(0,0,0);
	int clip = 30000;
	float life = 300000;
	bool enabled = true;
	bool screenaligned = true;
	MemArchive->Write( _T("Particles/Fire.xml"), _T("FileName") );
	MemArchive->Write( vec, _T("Position"));
	MemArchive->Write( vec, _T("Rotation") );
	MemArchive->Write( vec, _T("Scaling") );		
	MemArchive->Write( enabled , _T("Enabled"));
	MemArchive->Write( clip, _T("ClipDistance"));
	MemArchive->Write( life, _T("RemaingLife") );
	MemArchive->Write( screenaligned, _T("ScreenAligned") );

	CREATESTREAM cs;
	cs.streamData = caOut.streamData;
	cs.streamSize = caOut.streamSize;
	cs.mode = STREAM_MODE_READ;
	if (m_ToolBox->SendMessage(_T("CreateStream_Memory"), sizeof(CREATESTREAM), &cs) != MSG_HANDLED)
	{
		return;
	}
	MemArchive->Init(cs.openStream);

	sop.name = &m_ParticleName;
	sop.archive = MemArchive;
	m_ToolBox->SendMessage(_T("SerializeObject"), sizeof(SERIALIZEOBJECTPARAMS), &sop, NULL, NULL);
	

	iop.name = &m_ParticleName;
	if( retval == MSG_HANDLED )
	{
		retval = m_ToolBox->SendMessage(_T("InitObject"), sizeof(INITOBJECTPARAMS), &iop, NULL, NULL);
	}
	if( retval == MSG_HANDLED )
	{
		retval = m_ToolBox->SendMessage(_T("Enable"), 0, 0, &m_ParticleName, NULL);
	}

	if( retval == MSG_HANDLED )
	{
		m_ParticleVisible = true;
	}
	return;
}