//************************************************************************************
void CBCGPOutlineParser::Init ()
{
	RemoveAllBlockTypes ();

	// Default init for C++ outline blocks:
	AddEscapeSequence (_T("\\\""));
	AddEscapeSequence (_T("\\\\"));
	AddBlockType (_T("\""),	_T("\""),	_T("\"\""),	FALSE,	TRUE);
	AddBlockType (_T("//"),	_T("\n"),	_T("/**/"),	FALSE,	TRUE);
	AddBlockType (_T("/*"),	_T("*/"),	_T("/**/"),	FALSE,	FALSE);

	CStringList lstKeywords; 
	lstKeywords.AddTail (_T("if"));
	lstKeywords.AddTail (_T("else"));
	lstKeywords.AddTail (_T("while"));
	lstKeywords.AddTail (_T("for"));
	lstKeywords.AddTail (_T("do"));
	lstKeywords.AddTail (_T("switch"));
	lstKeywords.AddTail (_T("class"));
	lstKeywords.AddTail (_T("union"));
	lstKeywords.AddTail (_T("struct"));
	lstKeywords.AddTail (_T("namespace"));
	lstKeywords.AddTail (_T("catch"));
	lstKeywords.AddTail (_T("try"));
	lstKeywords.AddTail (_T("operator"));
	AddBlockType (_T("{"),	_T("}"),	_T("..."),	TRUE,	FALSE, &lstKeywords);
}
//************************************************************************************
void CBCGPOutlineParser::AddBlockType (LPCTSTR lpszOpen, LPCTSTR lpszClose, LPCTSTR lpszReplace, BOOL bNested, BOOL bIgnore, CStringList* pKeywordsList)
{
	ASSERT (lpszOpen != NULL);
	ASSERT (lpszClose != NULL);

	CString strClose = lpszClose;
	if (strClose.IsEmpty ())
	{
		AddEscapeSequence (lpszOpen);
		return;
	}

	BlockType* pNewBlockType = new BlockType (
		lpszOpen, lpszClose, (lpszReplace != NULL) ? lpszReplace : _T("..."), bNested, bIgnore, pKeywordsList);

	m_arrBlockTypes.Add (pNewBlockType);
}
void CSynBCGPEditCtrl::SelectLanguage( UINT nLanguage )
{
	RemoveXMLSettings();
	theApp.m_nSynLanguage = nLanguage;

	// 1)设置语言
	m_SynLanguage.SetCurLanguage(nLanguage);

	// 2)设置分隔符
	m_strWordDelimeters = m_SynLanguage.GetWordDelimeters();
	m_strSpecialDelimiters = m_SynLanguage.GetSpecialDelimiters();
	m_strIntelliSenseChars = m_SynLanguage.GetIntelliSenseChars();
	CString strEscapeSequence, strEscapeSequences;
	int nPos, nPosPrior = 0;

	strEscapeSequences = m_SynLanguage.GetEscapeSequences();
	nPos = strEscapeSequences.Find(_T(","), nPosPrior);
	while (nPos != -1)
	{
		strEscapeSequence = strEscapeSequences.Mid(nPosPrior, nPos - nPosPrior);
		AddEscapeSequence (strEscapeSequence);

		nPosPrior = nPos + 1;
		nPos = strEscapeSequences.Find(_T(","), nPosPrior);
	}
	
	// 3)设置关键字
	BOOL bCaseSensitive;
	CString strWords;
	CString strWord;
	nPosPrior = 0;

	m_SynLanguage.GetWords(strWords, bCaseSensitive);
	nPos = strWords.Find(_T(","), nPosPrior);
	while (nPos != -1)
	{
		strWord = strWords.Mid(nPosPrior, nPos - nPosPrior);
		SetWordColor(strWord, m_clrSyn, -1, bCaseSensitive);

		nPosPrior = nPos + 1;
		nPos = strWords.Find(_T(","), nPosPrior);
	}

	nPosPrior = 0;
	m_SynLanguage.GetTypeWords(strWords, bCaseSensitive);
	nPos = strWords.Find(_T(","), nPosPrior);
	while (nPos != -1)
	{
		strWord = strWords.Mid(nPosPrior, nPos - nPosPrior);
		SetWordColor(strWord, m_clrType, -1, bCaseSensitive);

		nPosPrior = nPos + 1;
		nPos = strWords.Find(_T(","), nPosPrior);
	}
	m_SynLanguage.GetIsNumberColor(m_bNumberColor);

	// 4)设置注释
	CString strBlockOpen, strBlockClose;

	m_SynLanguage.GetMultilineComment(strBlockOpen, strBlockClose, bCaseSensitive);
	if (_T("") != strBlockOpen.Trim())
	{
		SetBlockColor(strBlockOpen, strBlockClose, TRUE, m_clrComment, -1, bCaseSensitive);
	}

	CString strBlockOpens;
	m_SynLanguage.GetLineComment(strBlockOpens, bCaseSensitive);
	nPosPrior = 0;
	nPos = strBlockOpens.Find(_T(","), nPosPrior);
	while (nPos != -1)
	{
		strBlockOpen = strBlockOpens.Mid(nPosPrior, nPos - nPosPrior);
		SetBlockColor(strBlockOpen, _T(""), FALSE, m_clrComment, -1, bCaseSensitive);

		nPosPrior = nPos + 1;
		nPos = strBlockOpens.Find(_T(","), nPosPrior);
	}

	// 5)设置字符串
	m_SynLanguage.GetString(strBlockOpen, strBlockClose, bCaseSensitive);
	if (_T("") != strBlockOpen.Trim())
	{
		SetBlockColor(strBlockOpen, strBlockClose, FALSE, m_clrString, -1, bCaseSensitive);
	}
	m_SynLanguage.GetChar(strBlockOpen, strBlockClose, bCaseSensitive);
	if (_T("") != strBlockOpen.Trim())
	{
		SetBlockColor(strBlockOpen, strBlockClose, FALSE, m_clrChar, -1, bCaseSensitive);
	}

	// 6)设置折叠
	if (m_pOutlineParser != NULL)
	{
		m_OutlineNodes.DeleteAllBlocks ();
		m_pOutlineParser->RemoveAllBlockTypes ();		

		// 7)大纲设置
		m_pOutlineParser->m_strDelimiters = m_strWordDelimeters;
		m_pOutlineParser->m_bCaseSensitive = m_SynLanguage.GetOutlineCaseSensitive();
		m_pOutlineParser->m_bWholeWords = m_SynLanguage.GetOutlineWholeWords();

		// 8)转义字符
		m_SynLanguage.GetOutlineEscapeSequences(strEscapeSequences);
		nPosPrior = 0;
		nPos = strEscapeSequences.Find(_T(","), nPosPrior);
		while (nPos != -1)
		{
			strEscapeSequence = strEscapeSequences.Mid(nPosPrior, nPos - nPosPrior);
			m_pOutlineParser->AddEscapeSequence (strEscapeSequence);

			nPosPrior = nPos + 1;
			nPos = strEscapeSequences.Find(_T(","), nPosPrior);
		}

		// 9)折叠块
		CString strBlock, strBlocks;
		CString strReplace, strNested, strIgnore;
		CStringList lstKeywordsList;
		int nBlockPos, nBlockPosPrior = 0;
		m_SynLanguage.GetOutlineBlockType(strBlocks);
		nPosPrior = 0;
		nPos = strBlocks.Find(_T("|"), nPosPrior);
		while (nPos != -1)
		{
			strBlock = strBlocks.Mid(nPosPrior, nPos - nPosPrior);

			nBlockPosPrior = 0;
			nBlockPos = strBlock.Find(_T(","), nBlockPosPrior);
			if (nBlockPos != -1)
			{
				strBlockOpen = strBlock.Mid(nBlockPosPrior, nBlockPos - nBlockPosPrior);

				nBlockPosPrior = nBlockPos + 1;
				nBlockPos = strBlock.Find(_T(","), nBlockPosPrior);
				if (nBlockPos != -1)
				{
					strBlockClose = strBlock.Mid(nBlockPosPrior, nBlockPos - nBlockPosPrior);

					nBlockPosPrior = nBlockPos + 1;
					nBlockPos = strBlock.Find(_T(","), nBlockPosPrior);
					if (nBlockPos != -1)
					{
						strReplace =  strBlock.Mid(nBlockPosPrior, nBlockPos - nBlockPosPrior);

						nBlockPosPrior = nBlockPos + 1;
						nBlockPos = strBlock.Find(_T(","), nBlockPosPrior);
						if (nBlockPos != -1)
						{
							strNested =  strBlock.Mid(nBlockPosPrior, nBlockPos - nBlockPosPrior);

							nBlockPosPrior = nBlockPos + 1;
							nBlockPos = strBlock.Find(_T(","), nBlockPosPrior);
							if (nBlockPos != -1)
							{
								strIgnore =  strBlock.Mid(nBlockPosPrior, nBlockPos - nBlockPosPrior);

								nBlockPosPrior = nBlockPos + 1;
								nBlockPos = strBlock.Find(_T(","), nBlockPosPrior);
								lstKeywordsList.RemoveAll();
								while (nBlockPos != -1)
								{
									lstKeywordsList.AddTail(strBlock.Mid(nBlockPosPrior, nBlockPos - nBlockPosPrior));

									nBlockPosPrior = nBlockPos + 1;
									nBlockPos = strBlock.Find(_T(","), nBlockPosPrior);
								}
								m_pOutlineParser->AddBlockType(strBlockOpen, strBlockClose, strReplace, _ttoi(strNested), _ttoi(strIgnore), &lstKeywordsList);
							}
						}
					}
				}
			}

			nPosPrior = nPos + 1;
			nPos = strBlocks.Find(_T("|"), nPosPrior);
		}
		EnableAutoOutlining(!strBlocks.IsEmpty());  //禁止掉无大纲的语言,这样可以有“隐藏选定区域”功能
	}

	// 10)设置超链接
	m_lstURLPrefixes.RemoveAll ();
	m_arrHyperlinks.RemoveAll ();
	m_nCurrHyperlink = -1;
	m_nCurrHyperlinkHot = -1;	

	m_lstURLPrefixes.AddTail (_T("http://"));
	m_lstURLPrefixes.AddTail (_T("ftp://"));
	m_lstURLPrefixes.AddTail (_T("mailto:"));
	m_lstURLPrefixes.AddTail (_T("news://"));
	m_lstURLPrefixes.AddTail (_T("file://"));
	m_lstURLPrefixes.AddTail (_T("telnet://"));
	m_lstURLPrefixes.AddTail (_T("gopher://"));
	m_lstURLPrefixes.AddTail (_T("prospero://"));
	m_lstURLPrefixes.AddTail (_T("wais://"));
	m_lstURLPrefixes.AddTail (_T("nntp://"));

	m_bCheckColorTags = FALSE;
	UseXmlParser (FALSE);
	switch (nLanguage)
	{
	case SYN_ASP:
	case SYN_HTML:
	case SYN_XML:
		m_bCheckColorTags = TRUE;
		EnableAutoOutlining(TRUE);
		UseXmlParser(TRUE);
		break;
	case SYN_PASCAL:
		SetBlockColor(_T("(*"), _T("*)"), FALSE, m_clrComment, -1, FALSE);
		break;
	case SYN_AUTOIT:
		//SetBlockColor(_T("#comments-start"), _T("#comments-end"), FALSE, m_clrComment, -1, FALSE);
		break;
	case SYN_D:
		SetBlockColor(_T("/+"), _T("+/"), FALSE, m_clrComment, -1, FALSE);
		SetBlockColor(_T("`"), _T("`"), FALSE, m_clrChar, -1, FALSE);
		break;
	}
	RedrawWindow();
	UpdateAutoOutlining();
}