DWORD CGUIStaticText::OnUpdateLanguageEntryParams(DWORD size, void *param)
{
	VERIFY_MESSAGE_SIZE(size, sizeof(IArchive*));
	IArchive* ar = (IArchive*) param;

	if (ar)
	{
		if (m_LanguageTextParams != NULL)
		{
			delete [] m_LanguageTextParams;
			m_LanguageTextParams = NULL;
		}
		// do deep copy of archive params
		UINT archiveSize = ar->SeekTo(0, SEEK_END);

		if (archiveSize > 0)
		{		
			ar->SeekTo(0, SEEK_SET);
			ar->SetIsWriting(false);

			m_LanguageTextParams = new BYTE[archiveSize];
			ar->Read(m_LanguageTextParams, archiveSize);

			m_iLangTextParamSize = archiveSize;
		}
	}

	UpdateLanguageEntryText();

	return MSG_HANDLED_STOP;
}
void CWorldEventToolPal::UpdateWorldEventTrigger( void )
{
	static DWORD msgHash_FindObject = CHashString(_T("FindObject")).GetUniqueID();
	static DWORD msgHash_GetComponentType = CHashString(_T("GetComponentType")).GetUniqueID();
	static DWORD msgHash_CreateArchive = CHashString(_T("CreateArchive")).GetUniqueID();
	static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();

	static CHashString Hash_Type = CHashString(_T("CWorldEventTrigger"));

	CString buf;
	m_Name.GetLBText(m_Name.GetCurSel(), buf);
	CHashString hszName((TCHAR*)buf.GetBuffer());
	FINDOBJECTPARAMS param;
	param.hszName = &hszName;
	DWORD result = m_ToolBox->SendMessage(msgHash_FindObject, sizeof(FINDOBJECTPARAMS), &param);

	// object exists 
	if( param.bFound == true )
	{
		GETCOMPONENTTYPEPARAMS gctp;
		gctp.name = &hszName;
		m_ToolBox->SendMessage(msgHash_GetComponentType, sizeof(gctp), &gctp);

		// it is a world event, get values from it
		if ( (gctp.componenttype != NULL) && (gctp.componenttype->GetUniqueID() == Hash_Type.GetUniqueID()) )
		{
			CREATEARCHIVE ca;
			CHashString streamType(_T("Memory"));
			ca.streamData = NULL;
			ca.mode = STREAM_MODE_WRITE | STREAM_MODE_READ;
			ca.streamType = &streamType;
	 	
			m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &ca, NULL, NULL);
			IArchive *MemArchive = (ca.archive);

			MemArchive->SetIsWriting(true);
			MemArchive->SeekTo(0);

			SERIALIZEOBJECTPARAMS sop;
			sop.name = &hszName;
			sop.archive = MemArchive;
			m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sop, NULL, NULL);

			MemArchive->SetIsWriting(false);
			MemArchive->SeekTo(0);

			StdString tmp;
			MemArchive->Read( tmp );
			m_EntityName.SetWindowText( tmp.c_str() );
			MemArchive->Read( tmp );
			m_EntityType.SetWindowText( tmp.c_str() );
			MemArchive->Read( tmp );
			m_EventName.SetWindowText( tmp.c_str() );
			
			MemArchive->Close();
		}
	}
}
DWORD CSchemaItem::GetType( DATABASEATTRIBUTEPARAMS *databaseAttributeParams )
{
	DWORD retVal = MSG_NOT_HANDLED;
	if( databaseAttributeParams != NULL )
	{
		
		if( databaseAttributeParams->m_AttributeTypeArchive != NULL )
		{
			IArchive *ar = databaseAttributeParams->m_AttributeTypeArchive;
			ar->SetIsWriting( true );
			ar->SeekTo( 0 );
			ar->Write( m_hszType.GetString() );
		}
		else
		{
			m_ToolBox->Log( LOGWARNING, _T("No archive specified for GetAttributeType.\n") );
		}

		retVal = MSG_HANDLED_STOP;
	}
	else
	{
		m_ToolBox->Log( LOGWARNING, _T("Attribute parameters not defined.\n") );
	}

	return retVal;
}
IArchive* CGUIStaticText::CreateAndFillArchive()
{
	if (m_LanguageTextParams)
	{
		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 *ar = ca.archive;
		if (ar)
		{
			ar->SetIsWriting(true);
			ar->SeekTo(0);
			ar->Write(m_LanguageTextParams, m_iLangTextParamSize);
		}
		return ar;
	}
	else
	{
		return NULL;
	}
}
void CModelViewRender::InitRenderScene()
{
    // set active scene to model view scene so objects created here will be placed in the correct scene
    SetActiveScene();

    //Create Cal3DRenderObject from loaded file
    CreateScene();

    // create a new Memory Archive
    IArchive *pArchive = CreateMemoryArchive();
    if (pArchive == NULL)
    {
        return;
    }

    StdString szEntityType(_T("EditorObject"));
    //Vec3 v3Zero(0.0f, 0.0f, 0.0f);
    Vec3 v3EntityLightPosition(0.0f, 200.0f, 200.0f);
    EulerAngle eaZero;
    Vec3 v3Scale(1.0f, 1.0f, 1.0f);
    pArchive->Write(szEntityType, _T("EntityType"));
    pArchive->Write(v3EntityLightPosition, _T("Position"));
    pArchive->Write(eaZero, _T("Rotation"));
    pArchive->Write(v3Scale, _T("Scale"));
    pArchive->SetIsWriting(false);

    CFileVersionSetter setter;
    // Create the CEntity LightObject Parent /////////////////////////////////////////////////////////
    static CHashString hszCEntity(_T("CEntity"));
    if (CreateEEObject(&m_hszSceneName, &hszCEntity, m_hszLightEntityName, pArchive))
    {
        pArchive->SetIsWriting(true);
        pArchive->SeekTo(0);
        int iVersionNumber = 1000;
        Vec3 v3LightPosition( 0.0, 0.0f, 0.0f );
        Vec3 v3LightDirection( 0.0f, 0.0f, 0.0f );
        float fAttenuation = 99999.0f;
        float fColor[] = { 0.75f, 0.75f, 0.75f, 1.0f };
        StdString szLightType(_T("OMNI_POINT_LIGHT"));
        bool bCastShadows = false;
        UINT numKeys = 0;
        pArchive->Write(iVersionNumber, _T("Version"));
        pArchive->Write(v3LightPosition, _T("Position"));
        pArchive->Write(v3LightDirection, _T("Direction"));
        pArchive->Write(fAttenuation, _T("Attenuation"));
        pArchive->Write(fColor[0], _T("ColorRed") );
        pArchive->Write(fColor[1], _T("ColorGreen") );
        pArchive->Write(fColor[2], _T("ColorBlue") );
        pArchive->Write(fColor[3], _T("ColorAlpha") );
        pArchive->Write(szLightType, _T("LightType") );
        pArchive->Write(bCastShadows, _T("CastShadows") );
        pArchive->Write(numKeys, _T("NumKeyframes") );
        pArchive->SetIsWriting(false);

        // Create the Light Object ////////////////////////////////////////////////////////////////
        static CHashString hszCLightObject(_T("CLightObject"));
        CreateEEObject(&m_hszLightEntityName, &hszCLightObject, m_hszLightObjectName, pArchive);
    }

    pArchive->Close();
}
DWORD CDatabaseManager::OnGetTypedDatabase(DWORD size, void *params)
{
	TYPEDATABASEINFO *pDBTypeInfo = NULL;
	LOADFILEEXTPARAMS lfep;
	FILENAMETODATABASEMAP::iterator itrDBInfo;
	IDTOOBJECTMAP::iterator itrDBObject;
	DWORD result = 0;

	// Verify and Process incomming data.
	VERIFY_MESSAGE_SIZE(size, sizeof(TYPEDATABASEINFO));
	pDBTypeInfo = (TYPEDATABASEINFO *)params;

	IHashString *tempHash = pDBTypeInfo->phszFilepath;
	if (tempHash == NULL)
	{
		m_ToolBox->Log(LOGWARNING, _T("DB: Invalid database filename specifed, cannot be NULL\n"));
		return MSG_ERROR;
	}
	if (!pDBTypeInfo->pArchive)
	{
		m_ToolBox->Log(LOGWARNING, _T("DB: Invalid database archive specifed, cannot be NULL\n"));
		return MSG_ERROR;
	}
	// Check manager maps to see if database is already loaded.
	itrDBInfo = m_FilepathToDBInfo.find( tempHash->GetUniqueID() );
	itrDBObject = m_FilepathToObject.find( tempHash->GetUniqueID() );

	// Name is not found and database does not exist in manager map. Load DB.
	if( itrDBInfo == m_FilepathToDBInfo.end() && itrDBObject == m_FilepathToObject.end() )
	{
		lfep.fileName = (TCHAR *)tempHash->GetString();
		lfep.bInternalLoad = true;
		DWORD msgHash_LoadFileByExtension = CHashString(_T("LoadFileByExtension")).GetUniqueID();
		result = m_ToolBox->SendMessage(msgHash_LoadFileByExtension,
								   sizeof(LOADFILEEXTPARAMS), 
								   &lfep);
		if (result != MSG_HANDLED)
		{
			m_ToolBox->SetErrorValue(WARN_INVALID_FILE);
			m_ToolBox->Log(LOGWARNING, _T("Invalid database file %s\n"), lfep.fileName);
			return MSG_NOT_HANDLED;
		}

		// Because databases are added to the manager automatically and we cannot get
		// an iterator to the object just loaded by extension, we have to search for the
		// object again in manager map.
		itrDBInfo = m_FilepathToDBInfo.find( tempHash->GetUniqueID() );
		itrDBObject = m_FilepathToObject.find( tempHash->GetUniqueID() );
	}
	

	// There are two types of Databases, an old type that does not use schemas and a newer type that does.
	// New Type:
	CDefinedDatabase *pDefinedDB = NULL;
	CDatabaseSchema *pDBSchema = NULL;
	if ((itrDBInfo == m_FilepathToDBInfo.end()) &&  (itrDBObject != m_FilepathToObject.end()))
	{
		pDefinedDB = (CDefinedDatabase*)(itrDBObject->second);
		pDBSchema = (CDatabaseSchema*)(pDefinedDB->GetSchema());

		// Retrieve Schema Table.
		CREATEARCHIVE ca;
		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 * archive = ca.archive;
		pDBSchema->GetSchemaArchive( archive );
		
		IArchive * archiveOut = pDBTypeInfo->pArchive;

		StdString szTemp;
		bool bTemp;
		int nSchemaValues = 0;
		StdString szName;
		CHashString hszName;
		StdString szType;
		archive->Read(szTemp);
		archive->Read(nSchemaValues);
		int nDBItems = pDefinedDB->GetNumItems();

		// Write Total Number of Elements
		archiveOut->SetIsWriting(true);
		archiveOut->Write(nDBItems);
		archiveOut->Write(nSchemaValues);
		for (int i = 0; i < nDBItems; i++)
		{
			archive->SeekTo(0);	
			archive->Read(szTemp);
			archive->Read(nSchemaValues);
			for (int j = 0; j < nSchemaValues; j++)
			{
				archive->Read(szName);
				archive->Read(szType);
				archive->Read(bTemp);

				hszName.Init( szType.c_str() );
				archiveOut->Write(szName.c_str());
				archiveOut->Write(szType.c_str());
				DATABASEDATA * pValue = NULL;
				pValue = pDefinedDB->GetDatabaseItem(i)->GetDataByName( &hszName );
				pDBSchema->GetSchemaItem(&hszName)->DBWrite(pValue, archiveOut, _T(""));
			}
		}
		archiveOut->SetIsWriting(false);
		archive->Close();
		return MSG_HANDLED_STOP;
	}
	// Old Type DB or Missing DB:
	else
	{
		m_ToolBox->Log(LOGERROR, _T("DB: Attempt to call GetTypedDatabase on a non-existant DB or a CDatabase DB that does not support types.\n"));
		return MSG_ERROR;
	}
}
///	\brief	implementation for buffer data interaction of object undo/redo actions
///	\param	pCommand - pointer to command this action belongs to
///	\param	hashName - hash of object name to interact
///	\param	offset - delta data offset in command buffer
///	\param	size - delta data size in command buffer
///	\param	mode - command buffer interaction mode
DWORD UndoRedoObjectDataImpl(CUndoCommandData *pCommand, DWORD hashName, size_t offset, size_t size, DeltaMode mode)
{
	DWORD res = MSG_HANDLED;
	// get data offset
	LPBYTE pData = pCommand->GetDeltaData() + offset;

	IToolBox *pToolBox = EngineGetToolBox();
	CHashString hszName = pToolBox->GetHashString(hashName);
	// check if we need to apply data changes or may init object directly
	if (size > 0)
	{
		IArchive *pArchive;
		if (DeltaNone == mode)
		{
			// create archive for serialization and fill it with buffered data
			pArchive = CreateMemoryArchive(pData, (DWORD)size);
		}
		else
		{
			// get current object state for applying delta data
			pArchive = GetEEObjectProperties(&hszName);
			Buffer currentData;
			// extract serialized data to buffer
			GetArchiveStreamData(pArchive, currentData);

			// adjust serialized data length if this is needed
			if (currentData.size() < size)
			{
				currentData.resize(size, 0);
			}

			// restore correct data for the stream
			if (DeltaAdd == mode)
			{
				for (Buffer::iterator it = currentData.begin(); size > 0; --size, ++pData, ++it)
				{
					(*it) = (*it) + (*pData);
				}
			}
			else
			{
				for (Buffer::iterator it = currentData.begin(); size > 0; --size, ++pData, ++it)
				{
					(*it) = (*it) - (*pData);
				}
			}

			// then write it
			pArchive->SetIsWriting(true);
			pArchive->SeekTo(0);
			pArchive->Write(&currentData.front(), currentData.size());
		}

		CFileVersionSetter lastVersion;
		// setup up serialization parameters
		SERIALIZEOBJECTPARAMS sop;
		sop.name = &hszName;
		sop.archive = pArchive;
		pArchive->SetIsWriting(false);
		pArchive->SeekTo(0);
		// serialize object from archive
		static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();
		res = pToolBox->SendMessage(msgHash_SerializeObject, sizeof(sop), &sop);
		if (res != MSG_HANDLED)
		{
			// log this error?
			return res;
		}

		int count = 0;
		pArchive->Read(count, _T("count"));
		ASSERT(count >= 0 && count <= 8);
		if (count > 0)
		{
			EDITINGPROPERTIESPARAMS epp;
			epp.name = &hszName;
			while (count--)
			{
				StdString name;
				StdString value;
				pArchive->Read(name, _T("name"));
				pArchive->Read(value, _T("value"));
				epp.params.insert(make_pair(name, value));
			}
			static const DWORD hashMsg_SetEditingProperties = CHashString(_T("SetEditingProperties")).GetUniqueID();
			pToolBox->SendMessage(hashMsg_SetEditingProperties, sizeof(epp), &epp);
		}

		pArchive->Close();
	}

	INITOBJECTPARAMS iop;
	// send message to EE to initialize the object
	iop.name = &hszName;
	static DWORD msgHash_InitObject = CHashString(_T("InitObject")).GetUniqueID();
	res = pToolBox->SendMessage(msgHash_InitObject, sizeof(INITOBJECTPARAMS), &iop);

	return res;
}
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;
}