BOOL CRichDocument::LoadXML(CXMLElement* pBase, CMapStringToPtr* pMap, int nGroup)
{
	CSingleLock pLock( &m_pSection, TRUE );
	
	if ( pBase == NULL ) return FALSE;
	
	CString strTemp;
	
	if ( pBase->IsNamed( _T("document") ) )
	{
		strTemp = pBase->GetAttributeValue( _T("fontFace") );
		if ( strTemp.GetLength() ) CreateFonts( strTemp );
		
		LoadXMLColour( pBase, _T("crBackground"), &m_crBackground );
		LoadXMLColour( pBase, _T("crText"), &m_crText );
		LoadXMLColour( pBase, _T("crLink"), &m_crLink );
		LoadXMLColour( pBase, _T("crHover"), &m_crHover );
		LoadXMLColour( pBase, _T("crHeading"), &m_crHeading );
		
		strTemp = pBase->GetAttributeValue( _T("leftMargin") );
		if ( strTemp.GetLength() ) _stscanf( strTemp, _T("%i"), &m_szMargin.cx );
		strTemp = pBase->GetAttributeValue( _T("topMargin") );
		if ( strTemp.GetLength() ) _stscanf( strTemp, _T("%i"), &m_szMargin.cy );
	}
	
	for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
	{
		CXMLElement* pXML		= pBase->GetNextElement( pos );
		CRichElement* pElement	= NULL;
		
		if ( pXML->IsNamed( _T("text") ) )
		{
			pElement = new CRichElement( retText );
		}
		else if ( pXML->IsNamed( _T("link") ) )
		{
			pElement = new CRichElement( retLink );
		}
		else if ( pXML->IsNamed( _T("heading") ) )
		{
			pElement = new CRichElement( retHeading );
		}
		else if ( pXML->IsNamed( _T("newline") ) )
		{
			pElement = new CRichElement( retNewline );
			
			strTemp = pXML->GetAttributeValue( _T("gap") );
			
			if ( strTemp.GetLength() )
			{
				pElement->m_sText = strTemp;
				strTemp = pXML->GetAttributeValue( _T("indent") );
				if ( strTemp.GetLength() ) pElement->m_sText += '.' + strTemp;
			}
			else
			{
				strTemp = pXML->GetAttributeValue( _T("indent") );
				if ( strTemp.GetLength() ) pElement->m_sText = _T("0.") + strTemp;
			}
		}
		else if ( pXML->IsNamed( _T("gap") ) )
		{
			pElement = new CRichElement( retGap );
			
			strTemp = pXML->GetAttributeValue( _T("size") );
			if ( strTemp ) pElement->m_sText = strTemp;
		}
		else if ( pXML->IsNamed( _T("bitmap") ) )
		{
			pElement = new CRichElement( retBitmap );
		}
		else if ( pXML->IsNamed( _T("icon") ) )
		{
			pElement = new CRichElement( retIcon );
		}
		else if ( pXML->IsNamed( _T("anchor") ) )
		{
			pElement = new CRichElement( retAnchor );
		}
		else if ( pXML->IsNamed( _T("para") ) )
		{
			Add( pElement = new CRichElement( retAlign,
				pXML->GetAttributeValue( _T("align") ) ) );
			
			if ( pXML->GetElementCount() )
			{
				if ( ! LoadXML( pXML, pMap, nGroup ) ) return FALSE;
				if ( pElement->m_sText.CompareNoCase( _T("left") ) )
				{
					Add( new CRichElement( retAlign, _T("left") ) );
				}
			}
			
			continue;
		}
		else if ( pXML->IsNamed( _T("group") ) )
		{
			int nSubGroup = 0;
			if ( _stscanf( pXML->GetAttributeValue( _T("id") ), _T("%i"), &nSubGroup ) != 1 )
				return FALSE;
			if ( ! LoadXML( pXML, pMap, nSubGroup ) ) return FALSE;
			continue;
		}
		else if ( pXML->IsNamed( _T("styles") ) )
		{
			if ( ! LoadXMLStyles( pXML ) ) return FALSE;
		}
		else
		{
			return FALSE;
		}
		
		if ( pElement == NULL ) continue;
		
		strTemp = pXML->GetValue();
		if ( strTemp.GetLength() ) pElement->m_sText = strTemp;
		
		pElement->m_nGroup = nGroup;
		strTemp = pXML->GetAttributeValue( _T("group") );
		if ( strTemp.GetLength() ) _stscanf( strTemp, _T("%i"), &pElement->m_nGroup );
		
		strTemp = pXML->GetAttributeValue( _T("format") );
		CharLower( strTemp.GetBuffer() );
		strTemp.ReleaseBuffer();
		if ( strTemp.Find( 'b' ) >= 0 )	pElement->m_nFlags |= retfBold;
		if ( strTemp.Find( 'i' ) >= 0 )	pElement->m_nFlags |= retfItalic;
		if ( strTemp.Find( 'u' ) >= 0 )	pElement->m_nFlags |= retfUnderline;
		
		strTemp = pXML->GetAttributeValue( _T("align") );
		CharLower( strTemp.GetBuffer() );
		strTemp.ReleaseBuffer(); 
		if ( strTemp == _T("middle") ) pElement->m_nFlags |= retfMiddle;
		
		strTemp = pXML->GetAttributeValue( _T("colour") );
		if ( strTemp.GetLength() == 6 )
		{
			pElement->m_nFlags |= retfColour;
			LoadXMLColour( pXML, _T("colour"), &pElement->m_cColour );
		}
		
		if ( pElement->m_nType == retIcon )
		{
			strTemp = pXML->GetAttributeValue( _T("command") );
			if ( strTemp.GetLength() )
			{
				pElement->m_nType = retCmdIcon;
				pElement->m_sText = strTemp;
			}
		}
		
		if ( pElement->m_nType == retIcon || pElement->m_nType == retBitmap || pElement->m_nType == retAnchor )
		{
			strTemp = pXML->GetAttributeValue( _T("res") );
			if ( strTemp.GetLength() ) pElement->m_sText = strTemp;
			strTemp = pXML->GetAttributeValue( _T("path") );
			if ( strTemp.GetLength() ) pElement->m_sText = strTemp;
			
			strTemp = pXML->GetAttributeValue( _T("width") );
			if ( strTemp.GetLength() )
			{
				if ( pElement->m_sText.GetLength() ) pElement->m_sText += '.';
				pElement->m_sText += strTemp;
				strTemp = pXML->GetAttributeValue( _T("height") );
				if ( strTemp.GetLength() ) pElement->m_sText += '.' + strTemp;
			}
		}
		
		pElement->m_sLink = pXML->GetAttributeValue( _T("target") );
		
		if ( pMap )
		{
			strTemp = pXML->GetAttributeValue( _T("id") );
			if ( strTemp.GetLength() ) pMap->SetAt( strTemp, pElement );
		}
		
		Add( pElement );
	}
	
	return TRUE;
}