/*------------------------------------------------------------------------------*
 * File Name:	FunctionBrwList.h												*
 * Creation: 	Frank 															*
 * Purpose: OriginC Source C file												*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 * Frank	3/1/05			CHANGED_BOXES_TO_SPLITTER_AND_ADD_FILTER			*
 * Frank	3/2/05			HANDLE_FILE_NOT_EXIST								*
 * Forest 03/08/05 QA70-7345 NEW_DESIGN_FOR_FILTER_GUI							*
 * Forest 03/10/05 QA70-7345 CACHE_FILTER_RESULT								*
 * DG 3/11/05 v8.0202 FB_STRUCTURE_REWRITE										*
 * DG 3/14/05 v8.0203 FB_SPEED_UP_LOADING_MECHANISM								*
 * AW 03/16/05 v8.0205 CENTERLIZE_CODES_IN_FB									*
 *------------------------------------------------------------------------------*/
#ifndef _FB_LIST_H
#define _FB_LIST_H
#include <GetNBox.h>
#include "FBFilter.h"///Forest 03/25/05
#include "FunctionBrowserCache.h"///Forest 03/25/05

#define STR_OCGF_PATH					okutil_get_origin_path(SYS_FOLDER) + "Help\\"
//#define	STR_OCGF_CURRENT				THEME_FILENAME_LAST_USED + ".xml"
//#define STR_OCGF_CATEGORY_FILENAME_PRE	".xml"
//#define STR_OC_WORK_AREA				"Work area"
//#define STR_GLOBAL_FUNCTION_TREE_PATH	STR_OCGF_PATH + STR_OCGF_FILENAME
//#define STR_READTREE_ATTRIB				"DetailInFo"
//#define STR_FUNCTION_FLAG_ATTRIB		"Function"
//#define STR_LASTUSE_REG_ITEM			"Last User"
#define CHAR_LAST_USE_SEPARATOR_CHAR	'|'
//#define STR_ARGUMENT_LIST_LABEL			"Argument"
//
//#define STR_INSERT_LABEL				"Insert"
//#define STR_FUNCTION_LABEL				"Function"
//#define STR_DESCRIPTION_LABEL			"Description"
////#define WM_USER_ON_FILTER_CHANGE		(WM_USER + 1020)
//#define STR_FILTER_INCLUDE_BASE_LABEL	"All listed below|Any listed below"
//#define STR_FILTER_INCLUDE_ADVANCE_LABEL	"Only the list below"
//#define STR_FILTER_EXCLUDE_ADVANCE_LABEL	"Exclude all not include"

//#define		IDST_FB_MUST_HAVE_VAR				0x00201940	
//#define		IDST_FB_MUST_NOT_HAVE_VAR			0x00201941	
//#define		IDST_FB_MUST_HAVE_ITEM_BEGIN		0x00201000	
//#define		IDST_FB_MUST_NOT_HAVE_ITEM_BEGIN	0x00202000
//#define 	THEME_TYPE_FILTER_ATTRIB 	"Filter"///Forest 03/10/05, USE STR_THEME_TYPE_ATTRIB
		
//#define	STR_ATTRIB_QUERY_COND	"QueryCond"
//#define	MAX_CACHE_SIZE	10
//#define	CACHE_FILE_NAME_PREFIX	"Cache_"


///DG 3/11/05 FB_STRUCTURE_REWRITE
#define STR_FB_DLG_NAME 					"Function Browser"
//#define	STR_FB_THEME_PATH					okutil_get_origin_path(USER_FOLDER) + "Themes\\FunctionBrowser\\"
//#define STR_FUNCTION_FILE_EXT				".XML"
#define STR_OCGF_FILENAME					"OCGFsubset.xml"
#define STR_GLOBAL_FUNCTION_FILE			STR_OCGF_PATH + STR_OCGF_FILENAME
//#define STR_LAST_USE_FUNCTION_FILE			STR_FB_THEME_PATH+"LastUseFBList"+STR_FUNCTION_FILE_EXT

#define STR_FUNCTION_ATTRIB					"F"
///end FB_STRUCTURE_REWRITE

///Forest 03/08/05 QA70-7345 NEW_DESIGN_FOR_FILTER_GUI		
//#define	CHAR_VALUE_SEP	';'
//#define	STR_RESET_VALUES	"<Reset values list>"
//#define	STR_ADD_VALUE		"<Add>..."

///End NEW_DESIGN_FOR_FILTER_GUI

#define  _DMSG(_str)  out_str(_str);
#define  _DMSG_S(_str) out_str(_str);
///Frank	3/1/05			CHANGED_BOXES_TO_SPLITTER_AND_ADD_FILTER
class GridTreeFunctionBrw : public GridTreeControl
{
public:
	void Init(int nID, WndContainer& dlg)
	{
		GridTreeControl::Init(nID, dlg);
		m_flx.SelectionMode = flexSelectionByRow;
		m_flx.Editable = flexEDNone;
		m_flx.GridLines=flexGridFlatHorz;

	}
	void ClearAll()
	{
		GridTreeControl::ClearAll();
	}
	/// /// AW 03/16/05 v8.0205 CENTERLIZE_CODES_IN_FB
	/*
	bool 	DeleteRow(int nRow, int nCol =0)
	{
		if( m_flx.Rows < 1 )	//No row exist, return
			return FALSE;
		if(!IsInGrid( nRow,nCol ))
			return false;
		
		m_flx.RemoveItem(nRow);
		return true;
	}
	int FindChildRow(string strName, int nParentRow=-1)
	{
		int nChildLevel=GetLevel(nParentRow)+1;
		int nFind=FindRow(strName, 0, false, true, nParentRow);
		for(; (-1 != nFind) && (GetLevel(nFind) != nChildLevel || GetParent(nFind) != nParentRow); )
			nFind=FindRow(strName, 0, false, true, nFind+1);
		
		return nFind;
	}
	*/
	/// END CENTERLIZE_CODES_IN_FB
};
/*
class GridTreeFunctionBrw : public GridTreeControl
{
public:
	void Init(int nID, WndContainer& dlg)
	{
		GridTreeControl::Init(nID, dlg);
		m_flx.SelectionMode = flexSelectionByRow;
		m_flx.Editable = flexEDNone;
		m_flx.GridLines=flexGridFlatHorz;

	}
	~GridTreeFunctionBrw()
	{
		saveDefaultSettings();
	}
	bool IsReady()
	{
		return m_trFunctions.IsValid();
	}
	void ClearAll()
	{
		GridTreeControl::ClearAll();
	}
	bool UpdateCategoriesList()
	{
		ClearAll();
		m_trFunctions.Reset();
		TreeNode trCategory0=m_trFunctions.AddNode("Category0");

		bool bFauceSplittOCGFSubFile = true;
		separateOCGFTreeToFiles(bFauceSplittOCGFSubFile);	
		string strOCGFSubsetCategoryPath = get_origin_path(USER_FOLDER, STR_OC_WORK_AREA);
		string strOCGFSubsetCategoryFile = strOCGFSubsetCategoryPath + STR_OCGF_FILENAME;
		Tree trGF(strOCGFSubsetCategoryFile);
		
		if(!trGF)
			m_trFunctions = trCategory0;
		else
			m_trFunctions = trGF;
		
		if(!IsReady())
			return false;
		
		AddTreeNodes(m_trFunctions, ATRN_CHECK_STOP_ATTRIBUTE, -1, NULL, STR_STOP_ATTRIB);
		bool bCollapsed = true;
		SetAllCollapsed(bCollapsed); 
		
		vector<string> vsLastUseItem;
		if(loadDefaultSettings(vsLastUseItem))
		{
			int nDefaultCategoryRow = findFirstLevelDefaultRow(vsLastUseItem[1]);
			if( nDefaultCategoryRow >=0)
			{
				UpdateCategoryDetail(nDefaultCategoryRow);
				int nSecondRow =  findSecondLevelDefaultRow(vsLastUseItem[0], nDefaultCategoryRow);
				if(nSecondRow != nDefaultCategoryRow)
				{
					Window  Wnd =	*GetDialogWindow();
					_DMSG("Post message out when click");
					if(Wnd)
						Wnd.PostMessage( WM_USER_ON_FUNCTION_CHANGE );
				}
			}
		}

		return true;
	}
	
	void UpdateCategoryDetail(int nRow)
	{
		_DMSG("Get Category detail ok")
		string 		strTagInfo;
		TreeNode trCate;
		if(m_trFunctions.IsValid())
		{
			string strLabel;
			strLabel = GetCell(nRow, 0);
			//trCate = m_trFunctions.FindNodeByAttribute(STR_LABEL_ATTRIB, strLabel, false, true);
			trCate = tree_get_node(m_trFunctions, nRow, 1);
			if(trCate.IsValid())
			{
				bool bRet = trCate.GetAttribute(STR_READTREE_ATTRIB, strTagInfo ) ;
				if(	!bRet )
				{
					TreeNode trFunctions;
					if(!loadFunctionsTreeFromFile(trCate))//, trFunctions))
						return ;
					trCate.SetAttribute(STR_READTREE_ATTRIB, "Done");
					//---- CPY 2/1/05 why DeleteRow? also not compilable
					//DeleteRow(nRow);
					//DeleteRow(nRow+1);
					//----
					int nInsertRow = nRow+1;
					SetCollapsed(nRow, false);
					foreach(TreeNode trFunction in trCate.Children)
					{
						if(nInsertRow == nRow+1)
						{
							string strFirstFunctionName;
							trFunction.GetAttribute(STR_LABEL_ATTRIB, strFirstFunctionName);
							SetCell(nInsertRow, 0, strFirstFunctionName);
							nInsertRow++;
						}
						else			
						{
							///nInsertRow will auto add the added node count after AddTreeNodes.
							AddTreeNodes(trFunction, ATRN_STOP_LEVEL|1, 1, &nInsertRow);
						}
						trFunction.SetAttribute(STR_FUNCTION_FLAG_ATTRIB, "Funct");
					}
				}
			}
		}
		if(0 < nRow)
			SelRow(nRow);
	}
	
	string GetFunctionPrototypeStr(TreeNode &trFunction, bool bisFunctionPrototypeWithType = false)
	{
		string strFunctionPrototype;
		if(trFunction)
		{
			TreeNode trPrototype ;
			if(bisFunctionPrototypeWithType)
				trPrototype = trFunction.Prototype;
			else
				trPrototype = trFunction.Function;
			
			if( trPrototype)
				strFunctionPrototype = trPrototype.strVal;
		}
		return strFunctionPrototype;
	}
	//bool IstSelNodeFunction(TreeNode &trFunction)
	bool GetSelNode(TreeNode &trFunction)
	{
		int nRow, nCol;
		GetMouseCell(nRow, nCol);
		if(!IsInGrid(nRow, nCol))
			return false;
		
		trFunction=tree_get_node(m_trFunctions, nRow, 1);
		///Frank : Use the DataID is temp solutionn, because it was get from CHM parse function, not use here, 
		///so user the other attribute to check it.
		//if(trFunction.DataID != 8192)
		string strFunctionFlag;
		if(!trFunction.GetAttribute(STR_FUNCTION_FLAG_ATTRIB, strFunctionFlag))
			return false;
		return true;
	}
private:
	int findFirstLevelDefaultRow(const string &strCategoryLabel)
	{
		_DMSG("Get First level ok")
		int  nSelRow = -1;
		nSelRow=FindRow(strCategoryLabel);
		return nSelRow;
	}
	int findSecondLevelDefaultRow(const string &strFunctionLabel, int nDefaultFirstLevelRow)
	{
		int nSelRow = 0;
		if(-1 != nDefaultFirstLevelRow)
			nSelRow=FindRow(strFunctionLabel, 0, false, true, nDefaultFirstLevelRow);
		else
			nSelRow=0;
		
		if(-1 == nSelRow)
			nSelRow=nDefaultFirstLevelRow;
		
		_DMSG("Get Second level ok")
		SelRow(nSelRow);
		return nSelRow;
	}

	bool loadDefaultSettings(vector<string> &vsLastUseItem)
	{
		string strLastUse ;
		string strSaveItem = STR_LASTUSE_REG_ITEM;
		string strDlgName = STR_FB_DLG_NAME;
		if(!dlg_load_registry(strDlgName, strSaveItem, strLastUse ))
			return false;

		return 0 < strLastUse.GetTokens(vsLastUseItem, CHAR_LAST_USE_SEPARATOR_CHAR);
	}
	void saveDefaultSettings()
	{
		vector<string> vsLastUse;
		string strLastUse;
		int nCurRow = GetSelectedRow();
		for(int nParent=nCurRow; nParent>=0; nParent=GetParent(nParent))
		{
			strLastUse=GetCell(nParent, 0);
			strLastUse.TrimRight();
			vsLastUse.Add(strLastUse);
		}
		strLastUse.SetTokens(vsLastUse, CHAR_LAST_USE_SEPARATOR_CHAR);

		string strSaveItem = STR_LASTUSE_REG_ITEM;
		string strDlgName = STR_FB_DLG_NAME;
		dlg_save_to_registry(strDlgName,strSaveItem, strLastUse );
	}		
	bool loadFunctionsTreeFromFile(TreeNode &trCategory)
	{
		string strOCGFSubsetCategoryPath = get_origin_path(USER_FOLDER, STR_OC_WORK_AREA);
		string strCateName ; 
		
		if(!trCategory || !trCategory.GetAttribute(STR_LABEL_ATTRIB, strCateName))
			return false;
		string strFileName = getCategoryFileNameFromName(strCateName);

		string strOCGFSubsetCategoryFile = strOCGFSubsetCategoryPath + strFileName +STR_OCGF_CATEGORY_FILENAME_PRE;
		if(!strOCGFSubsetCategoryFile.IsFile())
			separateOCGFTreeToFiles(true);
		
		Tree tr;
		tr.Load(strOCGFSubsetCategoryFile);

		if(!tr.IsValid())
			return error_report("Functions File not found");
		
		trCategory.Replace(tr, true, true, true);
		return true;
	}
	string getCategoryFileNameFromName(LPCSTR lpcszCateName)
	{
		string strCateFileName = lpcszCateName;
		if(!is_str_valid_for_filename(strCateFileName))
			strCateFileName.MakeValidCName();
		return strCateFileName;
	}
	bool	separateOCGFTreeToFiles(bool bForceSeparate = false)
	{
		string strOCGFSubsetFile = STR_GLOBAL_FUNCTION_TREE_PATH;
		string strOCGFSubsetCategoryPath = get_origin_path(USER_FOLDER, STR_OC_WORK_AREA);
		//string strOCGFSubsetCategoryFile = strOCGFSubsetCategoryPath + STR_OCGF_FILENAME;
		bool	bNeedSeparateFile = false;
		
		if(!CheckMakePath(strOCGFSubsetCategoryPath))
			return  error_report("Make new file folder fail");
		if(!strOCGFSubsetFile.IsFile())
			return error_report("Global Function sub set file not found!!");

		bNeedSeparateFile = isOCGFTreeNeedSeparate(strOCGFSubsetCategoryPath, bForceSeparate);
		
		if(bNeedSeparateFile)
		{
			Tree	tr(strOCGFSubsetFile);
			Tree	trCategories;
			TreeNode trTemp;
			string strCategoryFile;
			string strCategoryLabel ;
			
			foreach(TreeNode trCate in tr.Children)
			{
				Tree	trCategory;
				trCategory = trCate;
				trTemp = trCategories.AddNode(trCate.tagName);
				trCate.GetAttribute(STR_LABEL_ATTRIB, strCategoryLabel);
				trTemp.SetAttribute(STR_LABEL_ATTRIB, strCategoryLabel);
				trTemp.AddNode("Temp");
				
				string strCateFileName = getCategoryFileNameFromName(strCategoryLabel);

				strCategoryFile = strOCGFSubsetCategoryPath + strCateFileName +STR_OCGF_CATEGORY_FILENAME_PRE;
				trCategory.Save(strCategoryFile);
			}
			
			strCategoryFile = strOCGFSubsetCategoryPath + STR_OCGF_FILENAME;
			trCategories.Save(strCategoryFile);
		}
		return true;
	}
	bool isOCGFTreeNeedSeparate(const string& strWorkAreaPath , bool bForceSepare = false)
	{
		if(bForceSepare)
			return true;
		bool bNeedSeparateFile = false;
		
		string strOCGFSubsetFile = STR_GLOBAL_FUNCTION_TREE_PATH;
		string strOCGFSubsetCategoryFile = strWorkAreaPath + STR_OCGF_FILENAME;
	
		if(!strOCGFSubsetCategoryFile.IsFile())
			bNeedSeparateFile = true;
		else
		{
			WIN32_FILE_ATTRIBUTE_DATA	fileInfoOfSubSet;
			WIN32_FILE_ATTRIBUTE_DATA	fileInfoOfCategory;
		
			GetFileAttributesEx(strOCGFSubsetFile, 0, &fileInfoOfSubSet);
			GetFileAttributesEx(strOCGFSubsetCategoryFile, 0, &fileInfoOfCategory);
			
			if(CompareFileTime(&fileInfoOfSubSet.ftLastWriteTime, &fileInfoOfCategory.ftLastWriteTime) > 0)
				bNeedSeparateFile = true;
		}
		return bNeedSeparateFile;
	}
private:
	Tree	m_trFunctions;
};
*/

///DG FB_STRUCTURE_REWRITE : rewrite, comment all
//class FunctionBListSplitter : public ListTreeEditSplitter
//{
//public:
	//FunctionBListSplitter() : ListTreeEditSplitter()
	//{
	//}
	//~FunctionBListSplitter(){saveDefaultSettings();}
//protected:
//EVENTS_BEGIN
//
	////------------- begin required events
	//// the following events are required for the splitter and related controls
	//ON_INIT(OnInitSplitter)
	//ON_DESTROY(OnDestroy)
	//ON_SIZE(OnCtrlResize)
	//ON_GETNDLG_MSGS(GetTreeEditPaneID())
	////------------- end required events
	//
	//ON_GRID_ROW_COL_CHANGE(GetMainPaneID(), OnListRowChange)
	////ON_GRID_BEFORE_MOUSE_DOWN(GetMainPaneID(), OnClickList)
	////ON_GRID_DBLCLICK(GetMainPaneID(), OnListDblClick)
	////ON_GRID_CLICK(GetMainPaneID(), OnClick)
	//ON_GRID_AFTER_COLLAPSE(GetMainPaneID(), OnAfterCollapse)
	////ON_USER_MSG(WM_USER_ON_FILTER_CHANGE, OnReconstructGrid) 
//
//EVENTS_END
	//BOOL OnInitSplitter()
	//{
		//ListTreeEditSplitter::OnInitSplitter(&m_trFBList);
 //
		//constructFunctionDetailGetN();
		//m_treeEditCntrl.Update(m_paramTree, true, true);
		/////Forest 03/09/05 NEW_DESIGN_FOR_FILTER
		////UpdateCategoriesList();
		//string strSourceXML;
		//if(_find_file(STR_OCGF_CURRENT, STR_FB_THEME_PATH))
			//strSourceXML = STR_FB_THEME_PATH + STR_OCGF_CURRENT;
		//else if(_find_file(STR_OCGF_FILENAME, STR_OCGF_PATH))
			//strSourceXML = STR_OCGF_PATH + STR_OCGF_FILENAME;
		//if(!strSourceXML.IsEmpty())
			//updateCategoryFromSourceXML(strSourceXML);
		//else
		//{
			//error_report("No source file found!");
			//return	false;
		//}
		/////End NEW_DESIGN_FOR_FILTER
		//SetReady();
		//LoadDefaultFunctionRow();
//
		//return true;
	//}
	//BOOL OnCtrlResize(int nType, int cx, int cy)
	//{
		//ListTreeEditSplitter::OnCtrlResize(nType, cx, cy);
		//return TRUE;
	//}
	//void OnAfterCollapse(Control cntrl, int nRow, short nState)
	//{
		//if( 2 != nState && 0 == nState && isFunctionListValid())
			//UpdateCategoryDetail(nRow);		
	//}
	//void OnListRowChange(Control ctrl)
	//{
		//if(!IsReady() || !isFunctionListValid())
			//return ;
		//
		//TreeNode trFunction;
		//GetSelNode(trFunction);
		//string strFunction = GetFunctionPrototypeStr(trFunction);
		//string strPrototype  = GetFunctionPrototypeStr(trFunction, true);
		//string strDescription = GetFunctionDescription(trFunction);
		////m_treeEditCntrl.SetCell(0, 1, strFunction);
		////m_treeEditCntrl.SetCell(1, 1, strPrototype);
		////m_treeEditCntrl.SetCell(2, 1, strDescription);
		//tree_copy_values(trFunction,m_paramTree, TREE_COPY_SKIP_HIDDEN | TREE_COPY_ATTRIB_ENABLE);
	//
		//OnReconstructGrid(GRID_CHANGE_SHOW |GRID_CHANGE_VALUE, 0);
	//}
	//BOOL 	OnReconstructGrid(UINT wParam, UINT lParam)
	//{
		//return m_treeEditCntrl.OnReconstructGrid(wParam, lParam);
	//}
//public:			
	//bool UpdateCategoriesList()
	//{
		//m_trFBList.ClearAll();
		//
		//m_trFunctions.Reset();
		//TreeNode trCategory0=m_trFunctions.AddNode("Category0");
//
		//////if bFauceSplittOCGFSubFile  = true, not matter the OCGFsubset.xml is newer or not, will splitt the xml file.
		//bool bFauceSplittOCGFSubFile = false;
		////separateOCGFTreeToFiles(bFauceSplittOCGFSubFile);	
		/////--Frank	3/2/05			HANDLE_FILE_NOT_EXIST
		////separateOCGFTreeToFiles(true);
		//if(!separateOCGFTreeToFiles(bFauceSplittOCGFSubFile))
			//return false;
		/////--End		HANDLE_FILE_NOT_EXIST
		//string strOCGFSubsetCategoryPath = okutil_get_origin_path(USER_FOLDER, STR_OC_WORK_AREA);
		//string strOCGFSubsetCategoryFile = strOCGFSubsetCategoryPath + STR_OCGF_FILENAME;
		//Tree trGF(strOCGFSubsetCategoryFile);
		//
		//if(!trGF)
			//m_trFunctions = trCategory0;
		//else
			//m_trFunctions = trGF;
		//
		////if(!IsReady())
		//if(!isFunctionListValid())
			//return false;
	//
		//m_trFBList.AddTreeNodes(m_trFunctions, ATRN_CHECK_STOP_ATTRIBUTE, -1, NULL, STR_STOP_ATTRIB);
		//bool bCollapsed = true;
		//m_trFBList.SetAllCollapsed(bCollapsed); 
		//
		//return true;
	//}
	//
	//bool LoadDefaultFunctionRow()
	//{
		//if(!IsReady())
			//return false;
		//
		//vector<string> vsLastUseItem;
		//if(loadDefaultSettings(vsLastUseItem))
		//{
			//if(vsLastUseItem.GetSize() == 1)
				//vsLastUseItem.InsertAt(0, "");
			//else
				//if(vsLastUseItem.GetSize() <= 0)
					//return false;
			//
			//int nDefaultCategoryRow = findFirstLevelDefaultRow(vsLastUseItem[1]);
			//int nSecondRow = nDefaultCategoryRow;
			////if( nDefaultCategoryRow >=0 )
			//if( nDefaultCategoryRow >=0 && !vsLastUseItem[0].IsEmpty())
			//{
				//UpdateCategoryDetail(nDefaultCategoryRow);
				////int nSecondRow =  findSecondLevelDefaultRow(vsLastUseItem[0], nDefaultCategoryRow);
				//nSecondRow =  findSecondLevelDefaultRow(vsLastUseItem[0], nDefaultCategoryRow);
				//
				////m_trFBList.SelRow(nSecondRow);				
			//}
			//m_trFBList.SelRow(nSecondRow);
		//}
		//return true;		
	//}
	//bool reconstructCategoryDetail(TreeNode &trCategoryDetail)
	//{
		//if(!trCategoryDetail)
			//return false;
		//
		//int nRow;
		//int nSelRow = m_trFBList.GetSelectedRow();
		//int nCurrentLevel = m_trFBList.GetLevel(nSelRow);
		//if( nCurrentLevel > 0)
			//nSelRow = m_trFBList.GetParent(nSelRow);
		//
		//
		//for(nRow = nSelRow+ 1 ; m_trFBList.GetLevel(nRow) > 0; )
			//m_trFBList.DeleteRow(nRow);
		//
		//int nInsertRow = nSelRow +1;
		//foreach(TreeNode trFunction in trCategoryDetail.Children)
		//{
			/////nInsertRow will auto add the added node count after AddTreeNodes.
			//m_trFBList.AddTreeNodes(trFunction, ATRN_STOP_LEVEL|1, 1, &nInsertRow);
			//trFunction.SetAttribute(STR_FUNCTION_FLAG_ATTRIB, "Funct");
		//}
		//return true;
	//}
	//bool UpdateCategoryDetail(int nRow)
	//{
		//_DMSG("Get Category detail ok")
		//string 		strTagInfo;
		//TreeNode trCate;
		////if(m_trFunctions.IsValid())
		//if(isFunctionListValid())
		//{
			//string strLabel;
			//strLabel = m_trFBList.GetCell(nRow, 0);
			////trCate = m_trFunctions.FindNodeByAttribute(STR_LABEL_ATTRIB, strLabel, false, true);
			//trCate = tree_get_node(m_trFunctions, nRow, 1);
			//if(trCate.IsValid())
			//{
				//bool bRet = trCate.GetAttribute(STR_READTREE_ATTRIB, strTagInfo ) ;
				//if(	!bRet )
				//{
					//TreeNode trFunctions;
					//if(!loadFunctionsTreeFromFile(trCate))//, trFunctions))
						//return false;///Frank	3/2/05			HANDLE_FILE_NOT_EXIST
					//trCate.SetAttribute(STR_READTREE_ATTRIB, "Done");
//
					//int nInsertRow = nRow+1;
					//m_trFBList.SetCollapsed(nRow, false);
					//foreach(TreeNode trFunction in trCate.Children)
					//{
						//if(nInsertRow == nRow+1)
						//{
							//string strFirstFunctionName;
							//trFunction.GetAttribute(STR_LABEL_ATTRIB, strFirstFunctionName);
							//m_trFBList.SetCell(nInsertRow, 0, strFirstFunctionName);
							//nInsertRow++;
						//}
						//else			
						//{
							/////nInsertRow will auto add the added node count after AddTreeNodes.
							//m_trFBList.AddTreeNodes(trFunction, ATRN_STOP_LEVEL|1, 1, &nInsertRow);
						//}
						//trFunction.SetAttribute(STR_FUNCTION_FLAG_ATTRIB, "Funct");
					//}
				//}
			//}
			//return true;///Frank	3/2/05			HANDLE_FILE_NOT_EXIST
		//}
	//}
	//
	//string GetFunctionPrototypeStr(TreeNode &trFunction, bool bisFunctionPrototypeWithType = false)
	//{
		//string strFunctionPrototype;
		//if(trFunction)
		//{
			//TreeNode trPrototype ;
			//if(bisFunctionPrototypeWithType)
				//trPrototype = trFunction.Prototype;
			//else
				//trPrototype = trFunction.Function;
			//
			//if( trPrototype)
				//strFunctionPrototype = trPrototype.strVal;
		//}
		//return strFunctionPrototype;
	//}
	//string GetFunctionDescription(TreeNode &trFunction)
	//{
		//string strFunctionDescription;
		//if(trFunction)
		//{
			//TreeNode trDescription ;
			//trDescription = trFunction.Description;
//
			//if( trDescription)
				//strFunctionDescription = trDescription.strVal;
		//}
		//return strFunctionDescription;
	//}
	////bool IstSelNodeFunction(TreeNode &trFunction)
	//bool GetSelNode(TreeNode &trFunction)
	//{
		//int nRow, nCol;
		//m_trFBList.GetMouseCell(nRow, nCol);
		//int nSelRow = m_trFBList.GetSelectedRow();
		////if(!m_trFBList.IsInGrid(nRow, nCol))
		//if(!m_trFBList.IsInGrid(nSelRow, 0))
			//return false;
		//
		////trFunction=tree_get_node(m_trFunctions, nRow, 1);
		//trFunction=tree_get_node(m_trFunctions, nSelRow, 1);
		/////Frank : Use the DataID is temp solutionn, because it was get from CHM parse function, not use here, 
		/////so user the other attribute to check it.
		//if(trFunction && trFunction.DataID != IDST_FB_FUNCTION)
			//return false;
		////string strFunctionFlag;
		////if(!trFunction.GetAttribute(STR_FUNCTION_FLAG_ATTRIB, strFunctionFlag))
			////return false;
		//return true;
	//}
	//string	GetSelFunctionString()
	//{
		//string str;
		//TreeNode trSelFunction;
		//GetSelNode(trSelFunction);
		//
		//str = GetFunctionPrototypeStr(trSelFunction);
		//
		//return str;
	//}
	////bool FilterFunctionsOfSelCategory()
	//bool FilterFunctions()
	//{
		//Tree tr;
		//TreeNode trGUI = tr.AddNode("GUI");
	//
		//constructFilterGetNTree(trGUI);
		////trGUI.SetAttribute(THEME_TYPE_FILTER_ATTRIB, "");///Forest 03/10/05, USE STR_THEME_TYPE_ATTRIB
		//tree_set_or_remove_attribute(trGUI, STR_SHOW_ADVANCED_ATTRIB,  true);
//
		//if(GetNBox(trGUI, STR_FILTER_DLG_NAME, "Please specify Query source, field, condition and values", NULL, NULL, GetWindow(OGW_DB_ACTIVE_DLG)))
		//{
			////out_int("Test Combo = ", tr.WhichDay.Use);
			//filterOperation(trGUI);
		//}	
		//return true;
	//}
//private:
	/////Forest 03/09/05 QA70-7345 NEW_DESIGN_FOR_FILTER_GUI
	////update category list from a given XML file, this XML file may be OCGFsubset.xml or some others of filtered result XML
	////can use OCGFsubset.xml for testing
	////1.show category only, when use open one category, show its child, same as the design before
	////2.if on child in category, remove it
	////3.can call other functions available in this class
	//bool	updateCategoryFromSourceXML(string& strFileName)
	//{
		//m_trFBList.ClearAll();
		//
		//m_trFunctions.Reset();
		//
		//TreeNode trCategory0=m_trFunctions.AddNode("Category0");
//
		//Tree trGF(strFileName);
		//foreach(TreeNode trCate in trGF.Children)
		//{
			//if(trCate.GetNodeCount() <= 0)
				//trCate.Remove();
		//}
		//
		//if(!trGF)
			//m_trFunctions = trCategory0;
		//else
			//m_trFunctions = trGF;
		//
		//if(!isFunctionListValid())
			//return false;
	//
		//DWORD	dwCntrl;
		//dwCntrl = ATRN_STOP_LEVEL | 1;
		//
		////m_trFBList.AddTreeNodes(m_trFunctions, dwCntrl,-1, NULL, STR_STOP_ATTRIB);
		////string strTemp = STR_OCGF_PATH + STR_OCGF_CURRENT;
		////m_trFunctions.Load(strTemp);
		////m_trFBList.AddTreeNodes(m_trFunctions, dwCntrl,-1, NULL, STR_STOP_ATTRIB);
		//m_trFBList.AddTreeNodes(m_trFunctions, dwCntrl,-1, NULL);
		//
		//bool bCollapsed = true;
		//m_trFBList.SetAllCollapsed(bCollapsed); 
		//
		//return true;
		//
	//}
	/////End NEW_DESIGN_FOR_FILTER_GUI
	//
	//bool filterOperation(TreeNode const &trFilterGUI)
	//{
		//if(!trFilterGUI)
			//return false;
		/////Forest 03/08/05 QA70-7345 NEW_DESIGN_FOR_FILTER_GUI
		///*
		//string strOCTypeList = get_origin_c_type_list();
		//vector<string> vsOCType;
		//int nRet = strOCTypeList.GetTokens( vsOCType, '|');
		//
		//vector<string> vsMustHaveReturntype;
		//vector<string> vsMustNotHaveReturntype;
		//vector<string> vsHaveOCTYPE;
		//vector<string> vsNotHaveOCTYPE;
		//
		//int nIncludeMode ;
		//int nExcludeMode ;
		//
		//
		//getFilterArgumentsTypeIndex(trFilterGUI,vsMustHaveReturntype, vsHaveOCTYPE , nIncludeMode);
		//
		//getFilterArgumentsTypeIndex(trFilterGUI,vsMustNotHaveReturntype, vsNotHaveOCTYPE, nExcludeMode , false);
		//
		//if(vsHaveOCTYPE.GetSize() <= 0 && vsNotHaveOCTYPE.GetSize() <= 0 && vsMustNotHaveReturntype.GetSize() <= 0 && vsMustHaveReturntype.GetSize() <= 0)
			//return false;
		//
		//
		//Tree tr;
		//TreeNode trAfterFilterReturn  = tr.AddNode("TnFiteredReturn");
		//TreeNode trAfterFilterArguments = tr.AddNode("TnFiteredArguments");
		//
		//TreeNode trCategory;
		//if(!getCurrentCategory(trCategory))
			//return false;
		//
		//if( !tree_copy_by_filter(trAfterFilterReturn, trCategory, IDST_FB_FUNCTION,
								//nIncludeMode, IDST_FB_ARGU_TYPE, vsMustHaveReturntype,
								//nExcludeMode, IDST_FB_ARGU_TYPE, vsMustNotHaveReturntype))
			//return false;
		//
		//if( !tree_copy_by_filter(trAfterFilterArguments, trAfterFilterReturn, IDST_FB_FUNCTION,
								//nIncludeMode, IDST_FB_ARGU_TYPE, vsHaveOCTYPE,
								//nExcludeMode, IDST_FB_ARGU_TYPE, vsNotHaveOCTYPE))
			//return false;
			//
		//trCategory.Replace( trAfterFilterArguments, true,true, true);
		//*/
		///*
		//GETN_BEGIN_BRANCH(QueryCond, "Query Condition")
				//GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
			//GETN_LIST(IncludeEx, "Include/Exclude", FB_QUERY_COND_INCLUDE, _L("Include|Exclude"))
				//GETN_OPTION_EVENT(FilterOnChangeCond)
			//GETN_CHECK(ExAllNotIn, "Exclude All Not Include", 1)
			//GETN_LIST(FindAll, "All/Any", FB_QUREY_VALUE_ALL, _L("Any value in the list|All values in the list"))
		//GETN_END_BRANCH(QueryCond)
		//GETN_BEGIN_BRANCH(QueryValue, "Query Values") 
				//GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
			//GETN_STRLIST(AddRemoveValue, "Add/Remove Value", "", strOCType)
				//GETN_OPTION_EVENT(FilterOnSelectType)
			//GETN_MULTILINE_TEXT(ValuesList, "Values List", "double;int")
				//GETN_READ_ONLY
	//}
//*/
///*
		//TreeNode trCategory;
		//if(!getCurrentCategory(trCategory))
			//return false;
//
		//int iUnitID = IDST_FB_FUNCTION;
		//int iDataID = trFilterGUI.QueryField.dVal == FB_QUERY_FIELD_ARGU ? IDST_FB_ARGU_TYPE : IDST_FB_ARGU_TYPE;
		//bool	bInclude = (trFilterGUI.QueryCond.IncludeEx.dVal == FB_QUERY_COND_INCLUDE);
		//vector<string> vsValues;
////		_filter_get_values(trFilterGUI, vsValues);
		//Tree trAfterFilter;
		//vector<string> vsNull;
		//int nIncludeMode, nExcludeMode;
		//if(bInclude)
		//{
			//nIncludeMode = trFilterGUI.QueryCond.FindAll.dVal == FB_QUREY_VALUE_ALL ? TCF_INCLUDE_ALL : TCF_INCLUDE_ANY;
			//nExcludeMode = TCF_EXCLUDE_ANY;
			//if(trFilterGUI.QueryCond.ExAllNotIn.dVal == 1)
				//nExcludeMode = TCF_EXCLUDE_ALL_NOT_INCLUDE;
			//tree_copy_by_filter(trAfterFilter, trCategory, iUnitID, nIncludeMode, iDataID, vsValues, nExcludeMode, iDataID, vsNull);
		//}
		//else
		//{
			//nIncludeMode = TCF_INCLUDE_ALL;
			//nExcludeMode = trFilterGUI.QueryCond.FindAll.dVal == FB_QUREY_VALUE_ALL ? TCF_EXCLUDE_ALL : TCF_EXCLUDE_ANY;	
			//tree_copy_by_filter(trAfterFilter, trCategory, iUnitID, nIncludeMode, 0, vsNull, nExcludeMode, iDataID, vsValues);
		//}
		//trCategory.Replace( trAfterFilter, true,true, true);
		/////End NEW_DESIGN_FOR_FILTER_GUI
		//
		//reconstructCategoryDetail(trCategory);
		//
		//trCategory.SetAttribute(STR_READTREE_ATTRIB, "Done");
//*/		
		//string	strSourceXML;
		//if(trFilterGUI.Scope.dVal == FB_FIND_SCOPE_CURRENT)
		//{
			//if(_find_file(STR_OCGF_CURRENT, STR_FB_THEME_PATH))
				//strSourceXML = STR_FB_THEME_PATH + STR_OCGF_CURRENT;
			//else
				//strSourceXML = STR_OCGF_PATH + STR_OCGF_FILENAME;
		//}
		//else
			//strSourceXML = STR_OCGF_PATH + STR_OCGF_FILENAME;
		//string	strDestXML = STR_FB_THEME_PATH + STR_OCGF_CURRENT;
		/////Forest 03/10/05 QA70-7345 CACHE_FILTER_RESULT
		//if(strSourceXML.Compare(STR_OCGF_PATH + STR_OCGF_FILENAME) == 0)//from source
		//{
			//Tree trResult;
			//if(GetResultFromCache(trFilterGUI, trResult))
			//{
				////---- CPY 3/10/05 FB_NOT_WORKING
				//string strPath = GetFilePath(strDestXML);
				//if(!CheckMakePath(strPath))
					//return error_report("failed create path for strDestXML");
				////---
				//trResult.Save(strDestXML);
				//updateCategoryFromSourceXML(strDestXML);
				//return true;
			//}
		//}
		/////End CACHE_FILTER_RESULT
		//Tree	trSource(strSourceXML);
		//if(!trSource)
		//{
			//error_report("No source file found");
			//return false;
		//}
		//int iUnitID = IDST_FB_FUNCTION;
		//vector<string> vsNull, vsValues;
		////filter return type
		//Tree	trFilterRet;
		//GetQueryValues(trFilterGUI.ReturnType, vsValues);
		//if(vsValues.GetSize() <= 0)
			//trFilterRet = trSource;
		//else if(trFilterGUI.ReturnType.IncludeEx.dVal == FB_QUERY_COND_INCLUDE)
		//{
			//tree_copy_by_filter(trFilterRet, trSource, IDST_FB_FUNCTION, 
							//TCF_INCLUDE_ANY, IDST_FB_ARGU_TYPE, vsValues, 
							//TCF_EXCLUDE_ANY, -1, vsNull);
		//}
		//else
		//{
			//tree_copy_by_filter(trFilterRet, trSource, IDST_FB_FUNCTION, 
							//TCF_INCLUDE_ANY, -1, vsNull, 
							//TCF_EXCLUDE_ANY, IDST_FB_ARGU_TYPE, vsValues);
		//}
		////filter argu type
		//Tree	trFilterArgu;
		//int 	nIncludeMode, nExcludeMode;
		//GetQueryValues(trFilterGUI.ArguType, vsValues);
		//if(vsValues.GetSize() <= 0)
			//trFilterArgu = trFilterRet;
		//else if(trFilterGUI.ArguType.IncludeEx.dVal == FB_QUERY_COND_INCLUDE)
		//{
			//nIncludeMode = trFilterGUI.ArguType.FindAll.dVal == FB_QUREY_VALUE_ALL ? TCF_INCLUDE_ALL : TCF_INCLUDE_ANY;
			//nExcludeMode = TCF_EXCLUDE_ANY;
			//if(trFilterGUI.ArguType.ExAllNotIn.dVal == 1)
				//nExcludeMode = TCF_EXCLUDE_ALL_NOT_INCLUDE;
			//tree_copy_by_filter(trFilterArgu, trFilterRet, IDST_FB_FUNCTION, 
							//nIncludeMode, IDST_FB_ARGU_TYPE, vsValues, 
							//nExcludeMode, -1, vsNull);
		//}
		//else
		//{
			//nIncludeMode = TCF_INCLUDE_ANY;
			//nExcludeMode = trFilterGUI.ArguType.FindAll.dVal == FB_QUREY_VALUE_ALL ? TCF_EXCLUDE_ALL : TCF_EXCLUDE_ANY;
			//tree_copy_by_filter(trFilterArgu, trFilterRet, IDST_FB_FUNCTION, 
							//nIncludeMode, -1, vsNull, 
							//nExcludeMode, IDST_FB_ARGU_TYPE, vsValues);			
		//}
		////save filter result
		/////Forest 03/10/05 QA70-7345 CACHE_FILTER_RESULT
		//if(strSourceXML.Compare(STR_OCGF_PATH + STR_OCGF_FILENAME) == 0)
			//SaveQueryToCache(trFilterGUI, trFilterArgu);
		/////End CACHE_FILTER_RESULT
		////---- CPY 3/10/05 FB_NOT_WORKING
		//string strPath = GetFilePath(strDestXML);
		//if(!CheckMakePath(strPath))
			//return error_report("failed create path for strDestXML");
		////---
//
		//trFilterArgu.Save(strDestXML);
		//updateCategoryFromSourceXML(strDestXML);
		//
		//return true;
	//}
//
	/////Forest 03/10/05 QA70-7345 CACHE_FILTER_RESULT
	////return false if no cache data found
	//static	string _get_cache_file_name(int iIndex, bool bIncludePath = true)
	//{
		//ASSERT(iIndex >= 0 && iIndex < MAX_CACHE_SIZE);
		//string strFile = CACHE_FILE_NAME_PREFIX + iIndex + ".xml";
		//if(bIncludePath)
			//strFile = STR_FB_THEME_PATH + strFile;
		//return strFile;
	//}
	//
	//bool	GetResultFromCache(const TreeNode& trGUI, TreeNode& trResult)
	//{
		//string strCond = make_query_condition_str(trGUI);
		//for(int ii = 0; ii < MAX_CACHE_SIZE; ii++)
		//{
			//string strFile = _get_cache_file_name(ii, false);
			//if(!_find_file(strFile, STR_FB_THEME_PATH))
				//return	false;
			//Tree tr;
			//tr.Load(STR_FB_THEME_PATH + strFile);
			//string str;
			//tr.GetAttribute(STR_ATTRIB_QUERY_COND, str);
			//if(str.Compare(strCond) == 0)
			//{
				//trResult.Replace(tr);
				//return	true;
			//}
		//}
	//}
	//void	SaveQueryToCache(const TreeNode& trGUI, const TreeNode& trResult)
	//{
		//Tree trTemp;
		//if(GetResultFromCache(trGUI, trTemp))//already saved to cache
			//return;
		//string str = make_query_condition_str(trGUI);
		//Tree	tr;
		//tr.Replace(trResult);
		//tr.SetAttribute(STR_ATTRIB_QUERY_COND, str);
		////save tree to cache file
		//for(int ii = 0; ii < MAX_CACHE_SIZE; ii++)
		//{
			//string strFileName = _get_cache_file_name(ii, false);
			//if(!_find_file(strFileName, STR_FB_THEME_PATH))
				//break;
		//}
		//if(ii < MAX_CACHE_SIZE)
		//{
			//tr.Save(_get_cache_file_name(ii));
		//}
		//else//already MAX_CACHE_SIZE cache files, need remove the first one
		//{
			//string strFirst = _get_cache_file_name(0);
			//DeleteFile(strFirst);
			//for(int jj = 1; jj < MAX_CACHE_SIZE; jj++)
			//{
				//string strOldName = _get_cache_file_name(jj);
				//string strNewName = _get_cache_file_name(jj - 1);
				//RenameFile(strNewName, strOldName);
			//}
			//string strLast = _get_cache_file_name(MAX_CACHE_SIZE - 2);
			//tr.Save(strLast);
		//}
	//}
//
	//static string	_make_str_from_value(const vector<string>& vsValues)
	//{
		//string strRet;
		//vsValues.Sort();
		//strRet.SetTokens(vsValues);
		//return	strRet;
	//}
	////make an exclusive string from query condition
	//static string	make_query_condition_str(const TreeNode& trGUI)
	//{
		//vector<string> vsRet;
		//vsRet.Add(trGUI.ReturnType.IncludeEx.dVal);
		//vector<string> vsValues;
		//GetQueryValues(trGUI.ReturnType, vsValues);
		//vsRet.Add(_make_str_from_value(vsValues));
		//vsRet.Add(trGUI.ArguType.IncludeEx.dVal);
		//vsRet.Add(trGUI.ArguType.ExAllNotIn.dVal);
		//vsRet.Add(trGUI.ArguType.FindAll.dVal);
		//GetQueryValues(trGUI.ArguType, vsValues);
		//vsRet.Add(_make_str_from_value(vsValues));
		//string strRet;
		//strRet.SetTokens(vsRet);
		//return	strRet;
	//}
	/////End CACHE_FILTER_RESULT
	//
	//void	GetQueryValues(const TreeNode& trBranch, vector<string>& vsValues)
	//{
		//vsValues.SetSize(0);
		//for(int ii = 0; ii < 3; ii++)
		//{
			//TreeNode trValue = trBranch.GetNode("Value" + (ii + 1));
			//if(trValue)
			//{
				//string strVal = trValue.strVal;
				//if(strVal.Compare(STR_FIRST_EMPTY_LABEL) == 0)
					//continue;
				//if(vsValues.Find(strVal) >= 0)
					//continue;
				//vsValues.Add(strVal);
			//}
		//}
	//}
	//
	////void getFilterArgumentsTypeIndex(TreeNode const &trFilterGUI, vector<string> &vecReturnType, vector<string> &vecArgusType, int &nFilterMode , bool bIsMustHaveNode = true)
	////{
		////if(!trFilterGUI)
			////return ;
		////
		////TreeNode trFilterItems;
		////
		////if(bIsMustHaveNode)
			////trFilterItems =	 trFilterGUI.GetNode("Include");
		////else
			////trFilterItems =	trFilterGUI.GetNode("Exclude");
		////
		////if(!trFilterItems)
			////return ;
		////
		////string strOCTypeList = get_origin_c_type_list();
		////vector<string> vsOCType;
		////int nRet = strOCTypeList.GetTokens( vsOCType, '|');
		////
		////string strOCTypeTemp;
		////int nTreeNodeIndex =0;
		////int nValue =0;
		////
		////TreeNode trReturnNode = trFilterItems.ReturnType;
		////int nReturnType = trReturnNode.nVal - 1 ;
		////
		////if(nReturnType > 0)
			////vecReturnType.Add(vsOCType[nReturnType]);
		////
		////TreeNode trArgumentsNode = getFilterArgumentNode(trFilterItems);
		////
		///////Branch combo had move to first level...
		//////nFilterMode = trArgumentsNode.Use;
		////nFilterMode = trFilterItems.Use;
		////
		////foreach(TreeNode trFilter in trArgumentsNode.Children)
		////{
			//////nTreeNodeIndex++;
			////nValue = trFilter.nVal - 1;
			////
			////if(nValue < 0)
				////continue;
			////
			////strOCTypeTemp = vsOCType[nValue];
			////
			//////if( nTreeNodeIndex == 1 )
				//////vecReturnType.Add(strOCTypeTemp);
			//////else
			////vecArgusType.Add(strOCTypeTemp);	
				////
		////}
	////}
	////bool getCurrentCategory(TreeNode &trCategory)
	////{
		////trCategory;
		////int nRow;
		////int nSelRow = m_trFBList.GetSelectedRow();
		////
		////if(!m_trFBList.IsInGrid(nSelRow, 0))
			////return false;
		////
		////TreeNode trTemp=tree_get_node(m_trFunctions, nSelRow, 1);
		///////Frank : Use the DataID is temp solutionn, because it was get from CHM parse function, not use here, 
		///////so user the other attribute to check it.
		//////if(trFunction.DataID != 8192)
		////string strFunctionFlag;
		///////Check is the treenode is category node, if not, get parent node.
		////if(trTemp.GetAttribute(STR_FUNCTION_FLAG_ATTRIB, strFunctionFlag))
			////trCategory = trTemp.Parent();
		////else
			////trCategory = trTemp;
	////
		///////Check the category node had load detail in, if not, load the detail in.
		////string strDetailLoaded ;
		////if(!trCategory.GetAttribute(STR_READTREE_ATTRIB, strDetailLoaded))
			////if(loadFunctionsTreeFromFile(trCategory))
				////m_trFBList.SetCollapsed(nSelRow, false);
			////else
				////return false;
////
		////return true;
	////}
	/////Forest 03/08/05 QA70-7345 NEW_DESIGN_FOR_FILTER_GUI
	////void constructFilterGetNTree(TreeNode &trGetN)
	////{
		/////*
		////GETN_USE(trGetN)
		////string strOCType =  get_origin_c_type_list();
		////GETN_BEGIN_BRANCH(Include, "Must Have") GETN_COMBO_BRANCH(0, STR_FILTER_INCLUDE_BASE_LABEL ) GETN_ID_BRANCH(IDST_FB_MUST_HAVE_VAR)
			////GETN_LIST(ReturnType, "Return Type",0, STR_FIRST_EMPTY_LABEL + "|"+ strOCType) GETN_ID(IDST_FB_MUST_HAVE_ITEM_BEGIN)
			////GETN_OPTION_EVENT(Filter_list_change_event)
		////GETN_END_BRANCH(Include)
		////
		////GETN_BEGIN_BRANCH(Exclude, "Must Not Have") GETN_COMBO_BRANCH(0,STR_FILTER_EXCLUDE_ADVANCE_LABEL + "|" + STR_FILTER_INCLUDE_BASE_LABEL) GETN_ID_BRANCH(IDST_FB_MUST_NOT_HAVE_VAR)
			////GETN_LIST(ReturnType, "Return Type",0, STR_FIRST_EMPTY_LABEL+ "|"+ strOCType) GETN_ID(IDST_FB_MUST_NOT_HAVE_ITEM_BEGIN)
			////GETN_OPTION_EVENT(Filter_list_change_event)
		////GETN_END_BRANCH(Exclude)	//Match GETN_BEGIN_BRANCH
		////
		///////Frank: just 3 filters now.
		////_add_branch_list_item(trGetN.Include.InArguments, 2, IDST_FB_MUST_HAVE_ITEM_BEGIN);
		////_add_branch_list_item(trGetN.Exclude.ExArguments, 2, IDST_FB_MUST_NOT_HAVE_ITEM_BEGIN);
		////*/
		////constructMustHaveGetNTree(trGetN);
		////constructMustNotHaveGetNTree(trGetN);	
		//////trGetN.SetAttribute(STR_THEME_TYPE_ATTRIB, THTYPE_FB_FILTER);///Forest 03/07/05, comment it temporarily, will uncomment when theme_utils.h&c is updated
		////trGetN.SetAttribute(STR_CLASS_OPTION_NAME_ATTRIB, "FunctionBrowser");
	////}
	////void constructMustHaveGetNTree(TreeNode &trMustGetN)
	////{
		////GETN_USE(trMustGetN)
		////string strOCType =  get_origin_c_type_list();
		////
		////GETN_BEGIN_BRANCH(Include, "Must Have" ) GETN_ID_BRANCH(IDST_FB_MUST_HAVE_VAR)
		////////Branch Combo should in first level branch.
		////GETN_COMBO_BRANCH(0, STR_FILTER_INCLUDE_BASE_LABEL ) GETN_ID_BRANCH(IDST_FB_MUST_HAVE_VAR)
			////GETN_LIST(ReturnType, "Return Type",0, STR_FIRST_EMPTY_LABEL + "|"+ strOCType) GETN_ID(IDST_FB_MUST_HAVE_ITEM_BEGIN)
			////GETN_OPTION_EVENT(Filter_list_change_event)
			////
			//////GETN_BEGIN_BRANCH(Arguments, "Arguments Must Have") GETN_COMBO_BRANCH(0, STR_FILTER_INCLUDE_BASE_LABEL ) GETN_ID_BRANCH(IDST_FB_MUST_HAVE_VAR)
			////GETN_BEGIN_BRANCH(Arguments, "Arguments Must Have") 
////
			////GETN_END_BRANCH(Arguments)
			////
		////GETN_END_BRANCH(Include)
		////
		///////Frank: just 3 filters now.
		//////_add_branch_list_item(trMustGetN.Include.Arguments, 2, IDST_FB_MUST_HAVE_ITEM_BEGIN);		
		////_add_branch_list_item(getFilterArgumentNode(trMustGetN.Include), 2, IDST_FB_MUST_HAVE_ITEM_BEGIN);		
	////}
	////void constructMustNotHaveGetNTree(TreeNode &trMustNotGetN)
	////{
		////GETN_USE(trMustNotGetN)
		////string strOCType =  get_origin_c_type_list();
		////
		////GETN_BEGIN_BRANCH(Exclude, "Must Not Have") GETN_ID_BRANCH(IDST_FB_MUST_NOT_HAVE_VAR)
		////GETN_COMBO_BRANCH(0,STR_FILTER_EXCLUDE_ADVANCE_LABEL + "|" + STR_FILTER_INCLUDE_BASE_LABEL) 
			////GETN_LIST(ReturnType, "Return Type",0, STR_FIRST_EMPTY_LABEL+ "|"+ strOCType) GETN_ID(IDST_FB_MUST_NOT_HAVE_ITEM_BEGIN)
			////GETN_OPTION_EVENT(Filter_list_change_event)
			////
			////GETN_BEGIN_BRANCH(Arguments, "Arguments Must Not Have") //GETN_COMBO_BRANCH(0,STR_FILTER_EXCLUDE_ADVANCE_LABEL + "|" + STR_FILTER_INCLUDE_BASE_LABEL) 
			////GETN_ID_BRANCH(IDST_FB_MUST_HAVE_VAR)
////
			////GETN_END_BRANCH(Arguments)
		////GETN_END_BRANCH(Exclude)	//Match GETN_BEGIN_BRANCH		
		////
		///////Frank: just 3 filters now.
		//////_add_branch_list_item(trMustNotGetN.Exclude.Arguments, 2, IDST_FB_MUST_NOT_HAVE_ITEM_BEGIN);		
		////_add_branch_list_item(getFilterArgumentNode(trMustNotGetN.Exclude), 2, IDST_FB_MUST_NOT_HAVE_ITEM_BEGIN);		
	////}
 //
	//void constructFilterGetNTree(TreeNode &trGetN)
	//{
		//string strOCType = get_origin_c_type_list();
		///*
		//GETN_USE(trGetN);
		//GETN_LIST(Scope, "Query Source", FB_FIND_SCOPE_CURRENT, _L("Find In Result|New Search"))
		//GETN_LIST(QueryField, "Query Field", FB_QUERY_FIELD_ARGU, _L("Argument Type|Return Type"))
			//GETN_OPTION_EVENT(FilterOnChangeField)
		//GETN_BEGIN_BRANCH(QueryCond, "Query Condition")
				//GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
			//GETN_LIST(IncludeEx, "Include/Exclude", FB_QUERY_COND_INCLUDE, _L("Include|Exclude"))
				//GETN_OPTION_EVENT(FilterOnChangeCond)
			//GETN_CHECK(ExAllNotIn, "Exclude All Not Include", 1)
			//GETN_LIST(FindAll, "All/Any", FB_QUREY_VALUE_ALL, _L("Any value in the list|All values in the list"))
		//GETN_END_BRANCH(QueryCond)
		//GETN_BEGIN_BRANCH(QueryValue, "Query Values") 
				//GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
			//GETN_STRLIST(AddRemoveValue, "Add/Remove Value", "", strOCType)
				//GETN_OPTION_EVENT(FilterOnSelectType)
			//GETN_MULTILINE_TEXT(ValuesList, "Values List", "double;int")
				//GETN_READ_ONLY
		//GETN_END_BRANCH(QueryValue)
		//*/
		//GETN_USE(trGetN);
		//GETN_LIST(Scope, "Query Source", FB_FIND_SCOPE_CURRENT, _L("Find In Result|New Search"))	GETN_ID(IDST_FB_SOURCE)
		//
		//GETN_BEGIN_BRANCH(ReturnType, "Return Type") GETN_OPTION_BRANCH(GETNBRANCH_OPEN) GETN_ID_BRANCH(IDST_FB_RETURN_TYPE_BRANCH)
			//GETN_LIST(IncludeEx, "Include/Exclude", FB_QUERY_COND_INCLUDE, _L("Include|Exclude")) GETN_ID(IDST_FB_RETU_INCLUDE)
			//GETN_STRLIST(Value1, "Value1", "double", strOCType) GETN_ID(IDST_FB_RETU_VALUE)
			//GETN_STRLIST(Value2, "Value2", STR_FIRST_EMPTY_LABEL, strOCType) GETN_ID(IDST_FB_RETU_VALUE + 1)
			//GETN_STRLIST(Value3, "Value3", STR_FIRST_EMPTY_LABEL, strOCType) GETN_ID(IDST_FB_RETU_VALUE + 2)
		//GETN_END_BRANCH(ReturnType)	
		//
		//GETN_BEGIN_BRANCH(ArguType, "Argument Type") GETN_OPTION_BRANCH(GETNBRANCH_OPEN) GETN_ID_BRANCH(IDST_FB_ARGU_TYPE_BRANCH)
			//GETN_LIST(IncludeEx, "Include/Exclude", FB_QUERY_COND_INCLUDE, _L("Include|Exclude")) GETN_ID(IDST_FB_ARGU_INCLUDE)
				//GETN_OPTION_EVENT(FilterOnChangeCond)
			//GETN_CHECK(ExAllNotIn, "Exclude All Not Include", 1) GETN_ID(IDST_FB_ARGU_EXCLUDE_ALL_NOT_INCLUDE)
			//GETN_LIST(FindAll, "All/Any", FB_QUREY_VALUE_ALL, _L("All values in the list|Any value in the list")) GETN_ID(IDST_FB_ARGU_ALL_ANY)
			//GETN_STRLIST(Value1, "Value1", "double", strOCType) GETN_ID(IDST_FB_ARGU_VALUE)
			//GETN_STRLIST(Value2, "Value2", STR_FIRST_EMPTY_LABEL, strOCType) GETN_ID(IDST_FB_ARGU_VALUE + 1)
			//GETN_STRLIST(Value3, "Value3", STR_FIRST_EMPTY_LABEL, strOCType) GETN_ID(IDST_FB_ARGU_VALUE + 2)
		//GETN_END_BRANCH(ArguType)	
//
		//trGetN.SetAttribute(STR_THEME_TYPE_ATTRIB, THTYPE_FB_FILTER);
		//trGetN.SetAttribute(STR_CLASS_OPTION_NAME_ATTRIB, "FunctionBrowser");
		//theme_set_commment_to_gui_tree(trGetN, "Description");
	//}
	/////End NEW_DESIGN_FOR_FILTER_GUI
	////TreeNode getFilterArgumentNode( TreeNode &trFilterItem )
	////{
		////TreeNode tn;
		////if(!trFilterItem)
			////return tn;
		////
		////return trFilterItem.GetNode("Arguments");
	////}
	//void constructFunctionDetailGetN( )
	//{
		//GETN_TREE(fbDetailTree)
		//GETN_MULTILINE_TEXT(Function, STR_INSERT_LABEL + ":" , "Click the list in the left to view the function or category detail")
		//GETN_MULTILINE_TEXT(Prototype, STR_FUNCTION_LABEL + " :" , "Click the list in the left to view the function or category detail")
		//GETN_MULTILINE_TEXT(Description, STR_DESCRIPTION_LABEL + " :" , "Click the list in the left to view the function or category detail")
				//
		//m_paramTree = fbDetailTree;
		//check_set_multiline_edit_range_display(m_paramTree, 3, 200);
	//}
	//int findFirstLevelDefaultRow(const string &strCategoryLabel)
	//{
		//_DMSG("Get First level ok")
		//int  nSelRow = -1;
		//nSelRow=m_trFBList.FindRow(strCategoryLabel);
		//return nSelRow;
	//}
	//int findSecondLevelDefaultRow(const string &strFunctionLabel, int nDefaultFirstLevelRow)
	//{
		//int nSelRow = 0;
		//if(-1 != nDefaultFirstLevelRow)
			//nSelRow=m_trFBList.FindRow(strFunctionLabel, 0, false, true, nDefaultFirstLevelRow);
		//else
			//nSelRow=0;
		//
		//if(-1 == nSelRow)
			//nSelRow=nDefaultFirstLevelRow;
		//
		//_DMSG("Get Second level ok")
		//return nSelRow;
	//}
//
	//bool loadDefaultSettings(vector<string> &vsLastUseItem)
	//{
		//string strLastUse ;
		//string strSaveItem = STR_LASTUSE_REG_ITEM;
		//string strDlgName = STR_FB_DLG_NAME;
		//if(!dlg_load_registry(strDlgName, strSaveItem, strLastUse ))
			//return false;
//
		//return 0 < strLastUse.GetTokens(vsLastUseItem, CHAR_LAST_USE_SEPARATOR_CHAR);
	//}
	//void saveDefaultSettings()
	//{
		//vector<string> vsLastUse;
		//string strLastUse;
		//int nCurRow = m_trFBList.GetSelectedRow();
		//for(int nParent=nCurRow; nParent>=0; nParent=m_trFBList.GetParent(nParent))
		//{
			//strLastUse=m_trFBList.GetCell(nParent, 0);
			//strLastUse.TrimRight();
			//vsLastUse.Add(strLastUse);
		//}
		//strLastUse.SetTokens(vsLastUse, CHAR_LAST_USE_SEPARATOR_CHAR);
//
		//string strSaveItem = STR_LASTUSE_REG_ITEM;
		//string strDlgName = STR_FB_DLG_NAME;
		//dlg_save_to_registry(strDlgName,strSaveItem, strLastUse );
	//}		
	//bool loadFunctionsTreeFromFile(TreeNode &trCategory)
	//{
		//string strOCGFSubsetCategoryPath = okutil_get_origin_path(USER_FOLDER, STR_OC_WORK_AREA);
		//string strCateName ; 
		//
		//if(!trCategory || !trCategory.GetAttribute(STR_LABEL_ATTRIB, strCateName))
			//return false;
		//string strFileName = getCategoryFileNameFromName(strCateName);
//
		//string strOCGFSubsetCategoryFile = strOCGFSubsetCategoryPath + strFileName +STR_OCGF_CATEGORY_FILENAME_PRE;
		////if(!strOCGFSubsetCategoryFile.IsFile())///Forest 03/10/05 USE_FIND_FILE
		////if(!_find_file(strFileName + STR_OCGF_CATEGORY_FILENAME_PRE, strOCGFSubsetCategoryPath))///Forest 03/10/05 TEMP_SOLUTION
			/////--Frank	3/2/05			HANDLE_FILE_NOT_EXIST
			////separateOCGFTreeToFiles(true);
			//if(separateOCGFTreeToFiles(true))
				//return false;
			/////--End		HANDLE_FILE_NOT_EXIST
		//
		//Tree tr;
		//tr.Load(strOCGFSubsetCategoryFile);
//
		//if(!tr.IsValid())
			//return error_report("Functions File not found");
		//
		//trCategory.Replace(tr, true, true, false);
		//return true;
	//}
	//string getCategoryFileNameFromName(LPCSTR lpcszCateName)
	//{
		//string strCateFileName = lpcszCateName;
		//if(!is_str_valid_for_filename(strCateFileName))
			//strCateFileName.MakeValidCName();
		//return strCateFileName;
	//}
	//bool	separateOCGFTreeToFiles(bool bForceSeparate = false)
	//{
		//string strOCGFSubsetFile = STR_GLOBAL_FUNCTION_TREE_PATH;
		//string strOCGFSubsetCategoryPath = okutil_get_origin_path(USER_FOLDER, STR_OC_WORK_AREA);
		////string strOCGFSubsetCategoryFile = strOCGFSubsetCategoryPath + STR_OCGF_FILENAME;
		//bool	bNeedSeparateFile = false;
		//
		//if(!CheckMakePath(strOCGFSubsetCategoryPath))
			//return  error_report("Make new file folder fail");
		////if(!strOCGFSubsetFile.IsFile())///Forest 03/10/05 USE_FIND_FILE
		//if(!_find_file(STR_OCGF_FILENAME, STR_OCGF_PATH))
			//return error_report("Global Function sub set file not found!!");
//
		//bNeedSeparateFile = isOCGFTreeNeedSeparate(strOCGFSubsetCategoryPath, bForceSeparate);
		//
		//if(bNeedSeparateFile)
		//{
			//Tree	tr(strOCGFSubsetFile);
			//Tree	trCategories;
			//TreeNode trTemp;
			//string strCategoryFile;
			//string strCategoryLabel ;
			//if(tr.GetNodeCount() == 1 )
				//tr = tr.FirstNode;
			//foreach(TreeNode trCate in tr.Children)
			//{
				//Tree	trCategory;
				//trCategory = trCate;
				//trTemp = trCategories.AddNode(trCate.tagName);
				//trCate.GetAttribute(STR_LABEL_ATTRIB, strCategoryLabel);
				//trTemp.SetAttribute(STR_LABEL_ATTRIB, strCategoryLabel);
				//trTemp.AddNode("Temp");
				//
				//string strCateFileName = getCategoryFileNameFromName(strCategoryLabel);
//
				//strCategoryFile = strOCGFSubsetCategoryPath + strCateFileName +STR_OCGF_CATEGORY_FILENAME_PRE;
				//trCategory.Save(strCategoryFile);
			//}
			//
			//strCategoryFile = strOCGFSubsetCategoryPath + STR_OCGF_FILENAME;
			//trCategories.Save(strCategoryFile);
		//}
		//return true;
	//}
	//bool isOCGFTreeNeedSeparate(const string& strWorkAreaPath , bool bForceSepare = false)
	//{
		//if(bForceSepare)
			//return true;
		//bool bNeedSeparateFile = false;
		//
		//string strOCGFSubsetFile = STR_GLOBAL_FUNCTION_TREE_PATH;
		//string strOCGFSubsetCategoryFile = strWorkAreaPath + STR_OCGF_FILENAME;
	//
		////if(!strOCGFSubsetCategoryFile.IsFile())///Forest 03/10/05 USE_FIND_FILE
		//if(!_find_file(STR_OCGF_FILENAME, strWorkAreaPath))
			//bNeedSeparateFile = true;
		//else
		//{
			//WIN32_FILE_ATTRIBUTE_DATA	fileInfoOfSubSet;
			//WIN32_FILE_ATTRIBUTE_DATA	fileInfoOfCategory;
		//
			//GetFileAttributesEx(strOCGFSubsetFile, 0, &fileInfoOfSubSet);
			//GetFileAttributesEx(strOCGFSubsetCategoryFile, 0, &fileInfoOfCategory);
			//
			//if(CompareFileTime(&fileInfoOfSubSet.ftLastWriteTime, &fileInfoOfCategory.ftLastWriteTime) > 0)
				//bNeedSeparateFile = true;
		//}
		//return bNeedSeparateFile;
	//}
	//bool isFunctionListValid()
	//{
		//return m_trFunctions.IsValid();
	//}
//private:
	//Tree	m_trFunctions;
	//
//private:
	//GridTreeFunctionBrw		m_trFBList;
//};


///DG 3/16/05 FB_STRUCTURE_REWRITE : rewrite
/*
typedef	struct
{
	bool	bSourceIsResult;//if query source is filtered result
	//conditions for return type
	vector<string> vsIncludeRet;
	vector<string> vsExcludeRet;
	//conditions for argument type
	int		nIncludeMode;
	int		nExcludeMode;
	vector<string> vsIncludeArgu;
	vector<string> vsExcludeArgu;
}FBFilterOptions;

#define	FB_CACHE_FILE_MAX_NUMBER	20
#define	STR_FB_CACHE_FILE_ORDER_ATTRIB	"CacheOrder"
#define	STR_FB_FILTER_CONDITION_ATTRIB	"FilterCond"
#define	STR_FB_FILTER_CACHE_PATH	okutil_get_origin_path(USER_FOLDER) + "FBCache\\"
#define	STR_FB_FILTER_CACHE_FILE_EXT	"xml"

class FBFilterGUI
{
public:
	bool	OpenGUI()
	{
		TreeNode trGUI = m_trGUI.AddNode("GUI");
		string strOCType = get_origin_c_type_list();
		GETN_USE(trGUI);
		GETN_LIST(Scope, "Query Source", FB_FIND_SCOPE_ALL, _L("Full Database|Current Function List"))	GETN_ID(IDST_FB_SOURCE)
		
		GETN_STRLIST(ReturnType, "Function Return", "double", strOCType) GETN_ID(IDST_FB_RETU_VALUE)
		
		GETN_BEGIN_BRANCH(ArguMustHave, "Function Argument Must Have") 
				GETN_COMBO_BRANCH(FB_QUREY_VALUE_ALL, "All the following|Any of the following")
				GETN_OPTION_BRANCH(GETNBRANCH_OPEN) GETN_ID_BRANCH(IDST_FB_ARGU_TYPE_MUST_BRANCH)
			GETN_STRLIST(Value1, "Type1", "double", strOCType) GETN_ID(IDST_FB_ARGU_VALUE)
			GETN_STRLIST(Value2, "Type2", STR_FIRST_EMPTY_LABEL, strOCType) GETN_ID(IDST_FB_ARGU_VALUE + 1)
			GETN_STRLIST(Value3, "Type3", STR_FIRST_EMPTY_LABEL, strOCType) GETN_ID(IDST_FB_ARGU_VALUE + 2)
		GETN_END_BRANCH(ArguMustHave)	
	
		GETN_BEGIN_BRANCH(ArguNotHave, "Function Argument Must Not Have") 
				GETN_COMBO_BRANCH(FB_QUERY_EX_ANY, "Any Not in Include List|Any of the following")
				GETN_OPTION_BRANCH(GETNBRANCH_OPEN) GETN_ID_BRANCH(IDST_FB_ARGU_TYPE_NOT_BRANCH)
			GETN_STRLIST(Value1, "Type1", STR_FIRST_EMPTY_LABEL, strOCType) GETN_ID(IDST_FB_ARGU_VALUE + 3)
			GETN_STRLIST(Value2, "Type2", STR_FIRST_EMPTY_LABEL, strOCType) GETN_ID(IDST_FB_ARGU_VALUE + 4)
			GETN_STRLIST(Value3, "Type3", STR_FIRST_EMPTY_LABEL, strOCType) GETN_ID(IDST_FB_ARGU_VALUE + 5)
		GETN_END_BRANCH(ArguNotHave)	
	
		tree_set_or_remove_attribute(trGUI, STR_SHOW_ADVANCED_ATTRIB, true);
		trGUI.SetAttribute(STR_THEME_TYPE_ATTRIB, THTYPE_FB_FILTER);
		trGUI.SetAttribute(STR_CLASS_OPTION_NAME_ATTRIB, "FunctionBrowser");
		theme_set_commment_to_gui_tree(trGUI, "Description");
		return	GetNBox(trGUI, STR_FILTER_DLG_NAME, "Please specify filter conditions", NULL, NULL, GetWindow(OGW_DB_ACTIVE_DLG));
	}
	
	void	GetFilterOptions(FBFilterOptions& sFilterOption)	
	{
		if(m_trGUI.GUI.Scope.Show && m_trGUI.GUI.Scope.dVal == FB_FIND_SCOPE_CURRENT)
			sFilterOption.bSourceIsResult = true;
		else
			sFilterOption.bSourceIsResult = false;
		
		sFilterOption.vsIncludeRet.SetSize(0);
		sFilterOption.vsExcludeRet.SetSize(0);
		string strReturn = m_trGUI.GUI.ReturnType.strVal;
		if(strReturn.Compare(STR_FIRST_EMPTY_LABEL) != 0)
			sFilterOption.vsIncludeRet.Add(strReturn);
		
		GetValuesFromBranch(m_trGUI.GUI.ArguMustHave, sFilterOption.vsIncludeArgu);
		if(m_trGUI.GUI.ArguMustHave.Use == FB_QUREY_VALUE_ALL)
			sFilterOption.nIncludeMode = TCF_INCLUDE_ALL;
		else
			sFilterOption.nIncludeMode = TCF_INCLUDE_ANY;
		
		GetValuesFromBranch(m_trGUI.GUI.ArguNotHave, sFilterOption.vsExcludeArgu);
		if(m_trGUI.GUI.ArguNotHave.Use == FB_QUERY_EX_ALL_NOT_INCLUDE)
			sFilterOption.nExcludeMode = TCF_EXCLUDE_ALL_NOT_INCLUDE;
		else
			sFilterOption.nExcludeMode = TCF_EXCLUDE_ANY;
	}
private:
	void	GetValuesFromBranch(TreeNode& trBranch, vector<string>& vsValues)
	{
		vsValues.SetSize(0);
		for(int ii = 0; ii < 3; ii++)
		{
			TreeNode trValue = trBranch.GetNode("Value" + (ii + 1));
			if(trValue)
			{
				string strVal = trValue.strVal;
				if(strVal.Compare(STR_FIRST_EMPTY_LABEL) == 0)
					continue;
				if(vsValues.Find(strVal) >= 0)
					continue;
				vsValues.Add(strVal);
			}
		}
		vsValues.Sort();
	}
	
private:
	Tree	m_trGUI;
};

class FBFile
{
public:
	FBFile(){CheckMakePath(STR_FB_FILTER_CACHE_PATH);}
	void	SetFilterOptions(FBFilterOptions& sFilterOption){m_sFilterOption = sFilterOption;}
	void	SaveToCache(Tree& trResult)
	{
		vector<string> vsFiles, vsCond;
		vector vOrder;
		getCacheFiles(vsFiles, vOrder, vsCond);
		double dbMin, dbMax;
		uint nIndexMin, nIndexMax;
		vOrder.GetMinMax(dbMin, dbMax, &nIndexMin, &nIndexMax);
		string strCurrentCond = getQueryCond();
		int i1 = vsCond.Find(strCurrentCond, 0, true);
		string strFileToSave;
		if(i1 >= 0)//already a cache file with the same query condition, update its order
		{
			strFileToSave = vsFiles[i1];
		}
		else
		{
			//otherwise, create a new cache file
			//first, check if reaches the maximum number of cache files
			int iSize = vsFiles.GetSize();
			if(iSize >= FB_CACHE_FILE_MAX_NUMBER)
				strFileToSave = vsFiles[nIndexMin];
			else
				strFileToSave = STR_FB_FILTER_CACHE_PATH + "Cache-" + (iSize + 1) + "." + STR_FB_FILTER_CACHE_FILE_EXT;
		}
		if(vsFiles.GetSize() <= 0)
			dbMax = 0;
		trResult.SetAttribute(STR_FB_CACHE_FILE_ORDER_ATTRIB, dbMax + 1);
		trResult.SetAttribute(STR_FB_FILTER_CONDITION_ATTRIB, strCurrentCond);
		trResult.Save(strFileToSave);
	}
	bool	GetFromCache(Tree& trResult, bool bUpdateOrder = true)
	{
		vector<string> vsFiles, vsCond;
		vector vOrder;
		getCacheFiles(vsFiles, vOrder, vsCond);
		string strCurrentCond = getQueryCond();
		int i1 = vsCond.Find(strCurrentCond, 0, true);
		if(i1 < 0)//not found cache
			return	false;
		if(!trResult.Load(vsFiles[i1]))
			return	false;
		if(bUpdateOrder)
		{
			double dbMin, dbMax;
			vOrder.GetMinMax(dbMin, dbMax);
			trResult.SetAttribute(STR_FB_CACHE_FILE_ORDER_ATTRIB, dbMax + 1);
			trResult.Save(vsFiles[i1]);
		}
		return	true;
	}
	//get last used cache, which will show when FB opens next time
	bool	GetLastUsed(Tree& trResult)
	{
		vector<string> vsFiles, vsCond;
		vector vOrder;
		if(getCacheFiles(vsFiles, vOrder, vsCond))
		{
			int iSize = vsFiles.GetSize();
			double dbMin, dbMax;
			uint nIndexMin, nIndexMax;
			vOrder.GetMinMax(dbMin, dbMax, &nIndexMin, &nIndexMax);
			return	trResult.Load(vsFiles[nIndexMax]);//get file whose order is max
		}
		return	false;
	}
	bool	GetWholeGF(Tree& trResult)
	{
		return	trResult.Load(STR_GLOBAL_FUNCTION_FILE);
	}
private:
	//get cache files, and creation order, query condition of each cache
	bool	getCacheFiles(vector<string> & vsFiles, vector& vOrder, vector<string>& vsCond)
	{
		if(!FindFiles(vsFiles, STR_FB_FILTER_CACHE_PATH, STR_FB_FILTER_CACHE_FILE_EXT))
			return	false;
		int iSize = vsFiles.GetSize();
		if(iSize <= 0)
			return	false;
		vOrder.SetSize(iSize);
		vsCond.SetSize(iSize);
		for(int ii = 0; ii < iSize; ii++)
		{
			vsFiles[ii] = STR_FB_FILTER_CACHE_PATH + vsFiles[ii];
			Tree	tr;
			if(!tr.Load(vsFiles[ii]))
				return	false;
			double dOrder;
			if(tr.GetAttribute(STR_FB_CACHE_FILE_ORDER_ATTRIB, dOrder))
				vOrder[ii] = dOrder;
			string strCond;
			if(tr.GetAttribute(STR_FB_FILTER_CONDITION_ATTRIB, strCond))
				vsCond[ii] = strCond;
		}
		return	true;
	}
	string	getQueryCond()
	{
		vector<String> vsCond(6);
		vsCond[0].SetTokens(m_sFilterOption.vsIncludeRet, '-');
		vsCond[1].SetTokens(m_sFilterOption.vsExcludeRet, '-');
		vsCond[2].SetTokens(m_sFilterOption.vsIncludeArgu, '-');
		vsCond[3].SetTokens(m_sFilterOption.vsExcludeArgu, '-');
		vsCond[4] = m_sFilterOption.nIncludeMode;
		vsCond[5] = m_sFilterOption.nExcludeMode;
		string str;
		str.SetTokens(vsCond, '|');
		return	str;
	}

private:
	FBFilterOptions m_sFilterOption;
};

class FBFunctionFilter
{
public:
	bool OpenFilter() 
	{
		FBFilterGUI	FilterGUI;
		if(!FilterGUI.OpenGUI())
			return	false;
		FilterGUI.GetFilterOptions(m_sFilterOptions);
		ApplyFilter();
		return	true;
	}
	void ApplyFilter() 
	{
		HOUR_GLASS
		FBFile FilterCache;
		FilterCache.SetFilterOptions(m_sFilterOptions);
		if(!FilterCache.GetFromCache(m_trResult))//get result from cache
		{
			//filter
			if(FilterOperation())
				FilterCache.SaveToCache(m_trResult);//save result to cache
		}
	}
	Tree GetResult() { return m_trResult; }
private:
	bool FilterOperation()
	{
		Tree	trSource;
		FBFile	FilterCache;
		if(!m_sFilterOptions.bSourceIsResult || !FilterCache.GetLastUsed(trSource))
		{
			FilterCache.SetFilterOptions(m_sFilterOptions);
			if(FilterCache.GetFromCache(m_trResult))//get result from cache
				return	true;
			if(!FilterCache.GetWholeGF(trSource))
				return	error_report("Fail to load source GF xml");
		}
		//filter return type
		Tree	trAfterFilterReturn;
		if( !tree_copy_by_filter(trAfterFilterReturn, trSource, IDST_FB_FUNCTION,
								TCF_INCLUDE_ANY, IDST_FB_RETURN_TYPE, m_sFilterOptions.vsIncludeRet,
								TCF_EXCLUDE_ANY, IDST_FB_RETURN_TYPE, m_sFilterOptions.vsExcludeRet))
			return false;
		Tree	trAfterFilterArgu;
		if( !tree_copy_by_filter(trAfterFilterArgu, trAfterFilterReturn, IDST_FB_FUNCTION,
								m_sFilterOptions.nIncludeMode, IDST_FB_ARGU_TYPE, m_sFilterOptions.vsIncludeArgu,
								m_sFilterOptions.nExcludeMode, IDST_FB_ARGU_TYPE, m_sFilterOptions.vsExcludeArgu))
			return false;
		m_trResult = trAfterFilterArgu;
		RemoveEmptyCategory();
		return	true;
	}
private:
	void	RemoveEmptyCategory()
	{
		//assume there are only two-level categories
		//first remove empty category of level 2
		//then remove empty category of level 1
		foreach(TreeNode trItem in m_trResult.Children)
		{
			foreach(TreeNode trSub in trItem.Children)
			{
				if(!IsFunctionNode(trSub) && trSub.GetNodeCount() <= 0)
					trItem.RemoveChild(trSub);
			}
			if(trItem.GetNodeCount() <= 0)
				m_trResult.RemoveChild(trItem);
		}
	}
private:
	Tree		m_trResult;
	FBFilterOptions	m_sFilterOptions;
};

#define STR_JUNK_NODE						"junk"	///DG FB_SPEED_UP_LOADING_MECHANISM
#define STR_EXPANDED_CATEGORY_ATTRIB		"Expanded"

class FunctionBListSplitter : public ListTreeEditSplitter
{
public:
	FunctionBListSplitter() : ListTreeEditSplitter()
	{
	}
	~FunctionBListSplitter() 
	{
		SaveDefaultSettings(CHAR_LAST_USE_SEPARATOR_CHAR, STR_FB_DLG_NAME);
	}
	
	string GetSelFunctionString()
	{
		string strFunction;
		if(IsFunctionNode(m_trSelNode))
			strFunction = m_trSelNode.Fu.strVal;
		return strFunction;
	}
	void FilterFunctions()
	{
		if(m_trFBFilter.OpenFilter())
		{
			m_trSrc = m_trFBFilter.GetResult();
			showList();
		}
	}
protected:
EVENTS_BEGIN

	//------------- begin required events
	// the following events are required for the splitter and related controls
	ON_INIT(OnInitSplitter)
	ON_DESTROY(OnDestroy)
	ON_SIZE(OnCtrlResize)
	ON_GETNDLG_MSGS(GetTreeEditPaneID())
	//------------- end required events
	
	ON_GRID_ROW_COL_CHANGE(GetMainPaneID(), OnListRowChange)
	ON_GRID_AFTER_COLLAPSE(GetMainPaneID(), OnAfterCollapse)

EVENTS_END
	BOOL OnInitSplitter()
	{
		HOUR_GLASS ///DG 3/11/05
		
		ListTreeEditSplitter::OnInitSplitter(&m_trList);
		
		SetReady();	//set splitter ready

		///Forest 03/14/05 INIT_SOURCE_TREE
		FBFile	fFile;
		if(!fFile.GetLastUsed(m_trSrc))
		{	
			if(!fFile.GetWholeGF(m_trSrc))
				return	false;
		}
		///End INIT_SOURCE_TREE
		showList();	///DG 3/14/05
		
		loadDefaultFunctionRow();
		return true;
	}
	void OnAfterCollapse(Control cntrl, int nRow, short nState)
	{
		if(!m_trList.IsReady())	///DG 3/14/05
			return;
		
		HOUR_GLASS
		
		///DG FB_SPEED_UP_LOADING_MECHANISM
		if( 2 != nState )
		{
			m_trList.SelRow(nRow);
			//if(0 == nState)
			{
				TreeNode trCate = ListTreeEditSplitter::GetTreeNode(nRow);
				string strTemp;
				if(!trCate.GetAttribute(STR_EXPANDED_CATEGORY_ATTRIB, strTemp))
				{
					if(trCate.RemoveChild(STR_JUNK_NODE))
						m_trList.DeleteRow(nRow+1);
					m_trList.DeleteRow(nRow);	//for reload
					loadSubCategory(trCate, nRow);
					trCate.SetAttribute(STR_EXPANDED_CATEGORY_ATTRIB, strTemp);
				}
			}
		}		
		///end FB_SPEED_UP_LOADING_MECHANISM
	}
	void OnListRowChange(Control ctrl)
	{
		//if(!IsReady())	///DG 3/14/05 list will be reload
		if(!m_trList.IsReady())
			return ;
		
		HOUR_GLASS	///DG 3/14/05
		
		int nNewSelRow=GetSelList();
		if(m_nSelRow != nNewSelRow)
		{
			m_nSelRow=nNewSelRow;
			m_trSelNode=ShowListContent(m_nSelRow);
		}
	}
	///---DG 3/14/05 save row text instead of number
	//virtual
	TreeNode GetTreeNode(int nRow)	///DG 3/15/05 FB_SPEED_UP_LOADING_MECHANISM
	{
		TreeNode trListNode=ListTreeEditSplitter::GetTreeNode(nRow);
		TreeNode trNode=searchSrcNode(trListNode, m_trSrc);
		return trNode;
	}
	void SaveDefaultSettings(char chDelimiter, LPCSTR lpcszDlgName=NULL)
	{
		string strRegItem(lpcszDlgName);
		strRegItem+=STR_LASTUSE_REG_ITEM;
		vector<string> vsRows;
		string str;
		//for(int nRow=m_nSelRow; nRow>=0; nRow=m_pList->GetParent(nRow))
			//vsRows.Add((string)nRow);
		for(TreeNode trParent=m_trSelNode; trParent.IsValid(); trParent=trParent.Parent())
		{
			if(!trParent.GetAttribute(STR_LABEL_ATTRIB, str) || str.IsEmpty())
				str=trParent.tagName;
			vsRows.Add(str);
		}
		str.SetTokens(vsRows, chDelimiter);
		SaveSetting(strRegItem, str, lpcszDlgName);
	}
	///---end
private:
	void showList()
	{
		m_nSelRow = -1;

		///DG FB_SPEED_UP_LOADING_MECHANISM
		m_trAllList.Reset();
		m_trShowList.Reset();
		tree_copy_remove_children(m_trAllList, m_trSrc, IDST_FB_FUNCTION);	///DG 3/15/05
		copySubCategory(m_trAllList, m_trShowList);
		///end FB_SPEED_UP_LOADING_MECHANISM
		///DG 3/15/05 FB_SPEED_UP_LOADING_MECHANISM
		//ShowList(m_trShowList,  ATRN_CHECK_STOP_ATTRIBUTE, STR_FUNCTION_ATTRIB);
		ShowList(m_trShowList);
		if(m_trShowList.GetNodeCount() < 1)
		{
			ListTreeEditSplitter::ConstructTree();
			m_treeEditCntrl.Update(m_paramTree, true, true);	//empty shown
			return;
		}
		//testAddTree(m_trShowList);
		///end FB_SPEED_UP_LOADING_MECHANISM
		SetAllCollapsed();
		
		m_trList.SelRow(0);
	}
	void testAddTree(TreeNode tr)	///DG 3/15/05 only use to test speed
	{
		foreach(TreeNode trNode in tr.Children)
		{
			m_trList.InsertRow();
			m_trList.SetCell(m_trList.GetRows()-1, 0, trNode.tagName);
			if(trNode.GetNodeCount() > 0)
				testAddTree(trNode);
		}
	}
	///DG FB_SPEED_UP_LOADING_MECHANISM
	void copySubCategory(TreeNode trSrc, TreeNode &trDest)
	{
		//string strTemp;
		foreach(TreeNode trNode in trSrc.Children)
		{
			//if(IsFunctionNode(trNode))	///DG FB_SPEED_UP_LOADING_MECHANISM
			if(trNode.GetNodeCount() < 1)
			{
				//copy function node
				trDest.AddNode(trNode);
			}
			else
			{
				//copy category node
				TreeNode trCate=trDest.AddNode();
				trCate.Replace(trNode, false);
				trCate.AddNode(STR_JUNK_NODE);	//junk node for list shown '+'
			}
		}
	}
	void loadSubCategory(TreeNode &trCategory, int nRow)
	{
		m_trList.SetReady(false);
		
		TreeNode trSrc=searchSrcNode(trCategory, m_trAllList);
		copySubCategory(trSrc, trCategory);
		
		int nSubLevel=tree_get_level(trCategory)-tree_get_level(m_trAllList)-1, nAddFromRow=nRow;
		AddTreeRows(trCategory, nSubLevel, &nAddFromRow);
		
		///---DG 3/14/05 bug, collapsed sub category as it has not been loaded before expanded
		int nIndex=0;
		foreach(TreeNode trFunction in trCategory.Children)
		{
			nIndex++;
			if(!IsFunctionNode(trFunction))
				m_trList.SetCollapsed(nRow+nIndex, flexOutlineCollapsed);
		}
		///---end
		m_trList.SetReady(true);
	}
	TreeNode searchSrcNode(TreeNode trList, TreeNode trSrc)
	{
		if(!trList || !trSrc)
			return trList;
		vector<string> vsCategoryTagNames;
		for(TreeNode trParent=trList; trParent.IsValid(); trParent=trParent.Parent())
			vsCategoryTagNames.InsertAt(0, trParent.tagName);

		TreeNode trCate=trSrc;
		for(int ii=1; ii<vsCategoryTagNames.GetSize(); ii++)
		{
			trCate=trCate.GetNode(vsCategoryTagNames[ii]);
			if(!trCate)
				return trCate;
		}
		return trCate;
	}
	///end FB_SPEED_UP_LOADING_MECHANISM
	void loadDefaultFunctionRow()
	{
		vector<string> vsLastUseItem;
		if(!LoadDefaultSettings(vsLastUseItem, CHAR_LAST_USE_SEPARATOR_CHAR, STR_FB_DLG_NAME))
		{
			m_trList.SelRow(0);
			return;
		}
		///DG 3/14/05 bug, save row text instead of number
		int nParentRow=-1, nSize=vsLastUseItem.GetSize(), nSelRow;
		for(int ii=nSize-2; ii>0; ii--)
		{
			nParentRow=m_trList.FindChildRow(vsLastUseItem[ii], nParentRow);
			if(-1 == nParentRow)
				break;
			else if(m_trList.GetLevel(nParentRow) < m_trList.GetLevel(nParentRow+1))
				m_trList.SetCollapsed(nParentRow, flexOutlineExpanded);
		}
		nSelRow=m_trList.FindChildRow(vsLastUseItem[0], nParentRow);
		if(-1 == nSelRow)
		{
			if(-1 == nParentRow)
				nParentRow=0;
			nSelRow=nParentRow;
		}
		m_trList.SelRow(nSelRow);
		///end
	}
private:
	FBFunctionFilter			m_trFBFilter;
	GridTreeFunctionBrw			m_trList;
	
	///DG 3/14/05 FB_SPEED_UP_LOADING_MECHANISM
	Tree						m_trShowList;
	Tree						m_trAllList;
	Tree						m_trSrc;
	///end FB_SPEED_UP_LOADING_MECHANISM
	
	//Tree						m_trFunctions;
	int							m_nSelRow;
	TreeNode					m_trSelNode;
};
*/
static	bool	IsFunctionNode(TreeNode& trNode)
{
	//function node has attribute STR_FUNCTION_ATTRIB
	string  strTemp;
	return	trNode.GetAttribute(STR_FUNCTION_ATTRIB, strTemp);
}

class OCFBListSplitter : public ListTreeEditSplitter
{
public:
	OCFBListSplitter() : ListTreeEditSplitter()
	{
	}
	~OCFBListSplitter() 
	{
		SaveDefaultSettings(CHAR_LAST_USE_SEPARATOR_CHAR, STR_FB_DLG_NAME);
	}
	string GetSelFunctionString()
	{
		string strFunction;
		if(IsFunctionNode(m_trSel))
			strFunction = m_trSel.Fu.strVal;
		return strFunction;
	}
	void FilterFunctions()
	{
		///Forest 03/25/05 USE_OLD_DESIGN_TEMP
		m_Filter.SetSource(m_trFunctions);
		if(m_Filter.OpenGUI() && m_Filter.GetResult(m_trFunctions))
		{
			//------------- CPY 9/2/05 GRAPH_TREE_SPLITTER_SAMPLE_CODE_CLEANUP
			//m_Cache.SaveCacheFile(m_trFunctions);//save filter result to file
			//SetListTree(m_trFunctions);
			m_Cache.SaveCacheFile(GetListTree());
			UpdateListTree();
			//-------------
			SetReady();
			UpdateList(STR_FUNCTION_ATTRIB);			
		}
		///End USE_OLD_DESIGN_TEMP
	}
protected:
EVENTS_BEGIN

	//------------- begin required events
	// the following events are required for the splitter and related controls
	ON_INIT(OnInitSplitter)
	ON_DESTROY(OnDestroy)
	ON_SIZE(OnCtrlResize)
	ON_GETNDLG_MSGS(GetTreeEditPaneID())
	//------------- end required events
	
	ON_GRID_ROW_COL_CHANGE(GetMainPaneID(), OnListRowChange)
	
EVENTS_END
	BOOL OnInitSplitter()
	{
		HOUR_GLASS
		ListTreeEditSplitter::OnInitSplitter(&m_trList);
		
		/// AW 03/16/05 v8.0205 CENTERLIZE_CODES_IN_FB
		/*
		//get function list
		//m_Filter.GetLastUsed(m_trFunctions);	//something like this
		m_trFunctions.Load(STR_GLOBAL_FUNCTION_FILE);	//just for test, will be replaced
		showlist();
		
		SetReady();
		loadDefaultRow();
		return true;
		*/
		//ListTreeEditSplitter::OnInitSplitter(&m_trList);
		if ( LoadListSource(STR_GLOBAL_FUNCTION_FILE) )
		{
			SetReady();
			UpdateList(STR_FUNCTION_ATTRIB);
			loadDefaultRow(CHAR_LAST_USE_SEPARATOR_CHAR, STR_FB_DLG_NAME);
			return TRUE;
		}
		return FALSE;
		/// END CENTERLIZE_CODES_IN_FB
	}
	/// AW 03/16/05 v8.0205 CENTERLIZE_CODES_IN_FB
	/*
	void OnListRowChange(Control ctrl)
	{
		if(!m_trList.IsReady())
			return ;
		
		HOUR_GLASS
		
		int nNewSelRow=GetSelList();
		if(m_nSelRow != nNewSelRow)
		{
			m_nSelRow=nNewSelRow;
			m_trSel=ShowListContent(m_nSelRow);
		}
	}
	
	//virtual
	TreeNode GetTreeNode(int nRow)
	{
		return tree_get_node(m_trFunctions, nRow, -1, true, STR_FUNCTION_ATTRIB);
	}
private:
	void showlist()
	{
		m_trList.SetReady(false);
		
		m_trList.AddSimpleTreeNodes(m_trFunctions, -1, STR_FUNCTION_ATTRIB);
		if(m_trFunctions.GetNodeCount() < 1)
		{
			ListTreeEditSplitter::ConstructTree();
			m_treeEditCntrl.Update(m_paramTree, true, true);	//empty shown
		}
		//SetAllCollapsed();	//this function takes more time to run, wait...
		m_trList.SetReady(true);
	}
	void loadDefaultRow()
	{
		vector<string> vsRows;
		if(!LoadDefaultSettings(vsRows, CHAR_LAST_USE_SEPARATOR_CHAR, STR_FB_DLG_NAME))
		{
			m_trList.SelRow(0);
			return;
		}
		int nParentRow=-1, nSize=vsRows.GetSize(), nSelRow;
		for(int ii=nSize-1; ii>0; ii--)
		{
			nParentRow=atof(vsRows[ii]);
			if(0 > nParentRow)
				break;
			m_trList.SetCollapsed(nParentRow, flexOutlineExpanded);
		}
		nSelRow=atof(vsRows[0]);
		if(m_trList.GetParent(nSelRow) != nParentRow)
			nSelRow=nParentRow;
		m_trList.SelRow(nSelRow);
	}
	*/
	void OnListRowChange(Control ctrl)
	{
		HOUR_GLASS
		ListRowChange();
	}
	/// END CENTERLIZE_CODES_IN_FB
private:
	//OCFBFunctionFilter		m_Filter;
	GridTreeFunctionBrw			m_trList;
	OCFBFilter					m_Filter;
	OCFBCache					m_Cache;
	/// AW 03/16/05 v8.0205 CENTERLIZE_CODES_IN_FB
	//int							m_nSelRow;
	//Tree						m_trFunctions;
	/// END CENTERLIZE_CODES_IN_FB
};
///end FB_STRUCTURE_REWRITE
#endif	//_FB_LIST_H
