/*------------------------------------------------------------------------------*
 * File Name: FunctionsMenu.h													*
 * Creation: Kyle 12-17-08														*
 * Purpose: Origin C header	for Collection template class						*
 * Copyright (c) OriginLab Corp.2001											*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 * Kyle 12/25/2008 v8.0990e ADD_LT_DATE_TIME_FUNCTIONS							*
 * Iris 12/30/2008 v8.0992 FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU*
 * Kyle 12/30/2008 v8.0992 OKUTIL_FIND_LT_FUNCTIONS_ADD_MATRIX_AS_RETURN_TYPE	*
 * Iris 01/04/2009 v8.0993c RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS		*
 * Kyle 01/06/2009 v8.0993c LT_FUNCTION_DATE_HAS_SUPPORTED_CUSTOM_DATE_FORMAT	*
 *	Folger 01/08/09 v8.0994d SUPPORT_GETTING_NUMBER_OF_DEFAULT_ARGUMENTS_ABOUT_OCLT_FUNCTION
 *	Folger 01/09/09 v8.0995 BETTER_FORMAT_FOR_INSERTED_STRING					*
 *	Kyle 05/21/2009 NEW_STRUCTURE_OF_SET_COLUMN_VALUES_DIALOG_F_X_PULL_DOWN_MENU*
 *	Kyle 07/24/2009 DEFAULT_ARGUMENTS_SHOULD_BE_INSIDE_BRACKETS					*
 *	Kyle 07/29/2009 QA80-14038 FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY
 *	Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
 *	Kyle 08/20/2009 [i][j]_SHOULD_BE_[i,j]										*
 *	Kyle 09/14/2009 ADD_WCOL(_ThisColNum)_UNDER_VARIABLE_CONSTANT				*
 *	Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS						*
 *	Sophy 11/6/2009 QA80-14584 MORE_WORK_ON_SCV_FUTTING_FUNCTIONS_MENU			*
 *------------------------------------------------------------------------------*/

#ifndef _FUNCTIONS_MENU_H_
#define _FUNCTIONS_MENU_H_

#include <Control.h>
///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
#ifdef _ADD_FITTING_FUNCTIONS_TO_SCV
#include "SetValuesCommon.h"
#endif // _ADD_FITTING_FUNCTIONS_TO_SCV
///End SCV_ADD_FITTING_FUNCTIONS

#define STR_FUNCTIONS_MENU_FAVORITES_SETTING_FILE				okutil_get_origin_path(ORIGIN_PATH_USER) + STR_ORIGIN_INI_FILE_NAME
#define STR_FUNCTIONS_MENU_FAVORITES_SECTION					"Functions Menu Favorites"
#define STR_FUNCTIONS_MENU_FAVORITES_FUNCTIONS_PREFIX			"Func"
#define	FUNCTIONS_MENU_OC_CATEGORY_FUNCTION_SEPARATOR			':'
///------ Folger 01/09/09 v8.0995 BETTER_FORMAT_FOR_INSERTED_STRING
#define	FUNCTION_ARGUMENTS_SEPARATOR							','
///------ End BETTER_FORMAT_FOR_INSERTED_STRING

#define STR_FUNCTION_MENU_CATEGORY_STRING 			"String"
#define STR_FUNCTION_MENU_CATEGORY_MATH 			"Math"
#define STR_FUNCTION_MENU_CATEGORY_DATE_TIME 		"Date and Time"
#define STR_FUNCTION_MENU_CATEGORY_STATS 			"Statistics"
#define STR_FUNCTION_MENU_CATEGORY_DISTRIBUTIONS	"Distributions"
#define STR_FUNCTION_MENU_CATEGORY_DATA_GENERATION 	"Data Generation"
///Kyle 05/21/2009 NEW_STRUCTURE_OF_SET_COLUMN_VALUES_DIALOG_F_X_PULL_DOWN_MENU
#ifdef NEW_STRUCTURE_OF_SET_COL_VAL_F_X_POLL_DOWN_MENU
#define STR_FUNCTION_MENU_CATEGORY_DATASET_INFO		"Dataset Information"
#define STR_FUNCTION_MENU_CATEGORY_DATA_MANIPULATION "Data Manipulation"
#endif //NEW_STRUCTURE_OF_SET_COL_VAL_F_X_POLL_DOWN_MENU
///End NEW_STRUCTURE_OF_SET_COLUMN_VALUES_DIALOG_F_X_PULL_DOWN_MENU
#define STR_FUNCTION_MENU_CATEGORY_MISCELLANEOUS 	"Miscellaneous"

#define STR_FUNCTIONS_MENU_EMPTY_ITEM							_L("Empty")
#define STR_FUNCTIONS_MENU_FAVORITES_EMPTY 						STR_FUNCTIONS_MENU_EMPTY_ITEM
#define IDC_FUNCTIONS_MENU_FAVORITES_BEGIN						IDC_BASIC_FUNCTIONS_BEGIN + 0
#define FUNCTIONS_MENU_FAVORITES_MAX_NUM						10

///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
#ifdef _ADD_FITTING_FUNCTIONS_TO_SCV
#define IDC_FITTING_FUNC_CATEGORY_BEGIN							IDC_FUNCTIONS_MENU_FAVORITES_BEGIN + FUNCTIONS_MENU_FAVORITES_MAX_NUM
#define FITTING_FUNC_CATEGORY_NUM								max(_get_category_list(NULL), 10)

#define IDC_FUNCTIONS_MENU_ITEM_BEGIN							IDC_FITTING_FUNC_CATEGORY_BEGIN + FITTING_FUNC_CATEGORY_NUM
#else // _ADD_FITTING_FUNCTIONS_TO_SCV
///End SCV_ADD_FITTING_FUNCTIONS
/// Iris 01/04/2009 v8.0993c RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS
#define IDC_FUNCTIONS_MENU_ITEM_BEGIN							IDC_FUNCTIONS_MENU_FAVORITES_BEGIN + FUNCTIONS_MENU_FAVORITES_MAX_NUM
///Kyle 07/29/2009 QA80-14038 FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY
#endif // _ADD_FITTING_FUNCTIONS_TO_SCV					///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
//#define FUNCTIONS_MENU_ITEM_MAX_NUM								50
///End FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY
///end RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS

#define POS_FUNCS	3  // hard code like POS_COL1

/// Iris 12/30/2008 v8.0992 FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#ifdef __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
#define 	WKS_LT_STATS_FUNCTION		"ave(vd, n)|diff(vd)|cov(vd1, vd2, ave1, ave2)|histogram(vd, inc, min, max)|percentile(vd1, vd2)|qcd2(n)|qcd3(n)|qcd4(n)|ss(vd [, ref])|sum(vd)"
#define 	MAT_LT_STATS_FUNCTION		"qcd2(n)|qcd3(n)|qcd4(n)"

///Kyle 09/14/2009 ADD_WCOL(_ThisColNum)_UNDER_VARIABLE_CONSTANT
//#define 	WKS_COMMON_VARIABLE			"_ThisColNum|[i]|pi"
#define 	WKS_COMMON_VARIABLE			"[i]|pi|_ThisColNum|wcol(_ThisColNum)"
///End ADD_WCOL(_ThisColNum)_UNDER_VARIABLE_CONSTANT
///Kyle 08/20/2009 [i][j]_SHOULD_BE_[i,j]
//#define 	MAT_COMMON_VARIABLE			"_ThisMatNum|[i][j]|cell(n, m)|pi"
//Kyle 09/14/2009 ADD_WCOL(_ThisColNum)_UNDER_VARIABLE_CONSTANT, use cell(i, j) as an variable
//#define 	MAT_COMMON_VARIABLE			"_ThisMatNum|[i, j]|cell(n, m)|pi"
#define 	MAT_COMMON_VARIABLE			"pi|_ThisMatNum|[i, j]|cell(i, j)"
///End ADD_WCOL(_ThisColNum)_UNDER_VARIABLE_CONSTANT
///End [i][j]_SHOULD_BE_[i,j]
#else //__STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#define 	WKS_LT_STATS_FUNCTION		"ave(vd,n)|diff(vd)|cov(vd,vd,d,d)|histogram(vd,d,d,d)|percentile(vd,vd)|qcd2(n)|qcd3(n)|qcd4(n)|ss(vd[,])|sum(vd)"
#define 	MAT_LT_STATS_FUNCTION		"qcd2(n)|qcd3(n)|qcd4(n)"

#define 	WKS_COMMON_VARIABLE			"_ThisColNum|[i]|pi"
///Kyle 08/20/2009 [i][j]_SHOULD_BE_[i,j]
//#define 	MAT_COMMON_VARIABLE			"_ThisMatNum|[i][j]|cell(n,n)|pi"
#define 	MAT_COMMON_VARIABLE			"_ThisMatNum|[i, j]|cell(n,n)|pi"
///End [i][j]_SHOULD_BE_[i,j]
///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#endif //__STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES

#define		WKS_VAR_SKIP_TYPE			"matrix"
#define		MAT_VAR_SKIP_TYPE			"vector|string"

#define 	WKS_MISCELLANEOUS_FUNCTION  "sort(vd)"
#define 	MAT_MISCELLANEOUS_FUNCTION  ""
///end FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU

///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
#ifdef _ADD_FITTING_FUNCTIONS_TO_SCV

class CCategoryIDRangeMap
{
public:

	CCategoryIDRangeMap()
	{
		ClearAll();
	}

	void	ClearAll()
	{
		m_vnCategory.SetSize(0);
		m_vnIDBegin.SetSize(0);
		m_vnIDEnd.SetSize(0);
	}

	void	AddRange(int nCategory, int nIDBegin, int nIDEnd)
	{
		if( nCategory < 0 || nIDEnd < 0 || nIDBegin > nIDEnd )
			return;
		m_vnCategory.Add(nCategory);
		m_vnIDBegin.Add(nIDBegin);
		m_vnIDEnd.Add(nIDEnd);
	}

	int		FindCategory(int nID)
	{
		for(int ii = m_vnIDBegin.GetSize() - 1; ii >= 0; ii--)
		{
			if( nID >= m_vnIDBegin[ii] && nID <= m_vnIDEnd[ii] )
				return m_vnCategory[ii];
		}
		return -1;
	}

private:
	vector<uint>		m_vnCategory;
	vector<uint>		m_vnIDBegin;
	vector<uint>		m_vnIDEnd;
};

class CMapFitFuncCateID
{
public:
	CMapFitFuncCateID()
	{
		ClearAll();
	}
	
	void ClearAll()
	{
		m_vnIDs.SetSize(0);
		m_vsCate.SetSize(0);
	}
	void Add(int nID, LPCSTR lpcszCate)
	{
		vector<uint> vec;
		if( m_vnIDs.Find(vec, nID) > 0 )
		{
			m_vsCate[vec[0]] = lpcszCate;
		}
		else
		{
			m_vnIDs.Add(nID);
			m_vsCate.Add(lpcszCate);
		}
	}
	
	bool	Lookup(int nID, string& strCate)
	{
		vector<uint> vec;
		if( m_vnIDs.Find(vec, nID) > 0 )
		{
			strCate = m_vsCate[vec[0]];
			return true;
		}
		return false;
	}
	
	bool	Remove(int nID)
	{
		vector<uint> vec;
		if( m_vnIDs.Find(vec, nID) > 0 )
		{
			int nIndex = vec[0];
			m_vnIDs.RemoveAt(nIndex);
			m_vsCate.RemoveAt(nIndex);
			return true;
		}
		return false;
	}
	
private:
	vector<uint>			m_vnIDs;
	vector<string>			m_vsCate;

};

#endif // _ADD_FITTING_FUNCTIONS_TO_SCV

///End SCV_ADD_FITTING_FUNCTIONS

class FunctionsMenu : public Menu
{
public:
	FunctionsMenu(HMENU &hMenu, string strFavSection, vector<uint> vnCategoryIDs) : Menu(hMenu)
	{
		m_strFavSection = strFavSection;
		m_vnCategoryIDs = vnCategoryIDs;		
		
		m_nNextID = IDC_FUNCTIONS_MENU_ITEM_BEGIN;				///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
	}

	FunctionsMenu(HMENU &hMenu, string strFavSection) : Menu(hMenu)
	{
		m_strFavSection = strFavSection;
		m_vnCategoryIDs.SetSize(0);
	}	
	
	/// Iris 01/04/2009 v8.0993c RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS
	//void Construct()
	///Kyle 07/29/2009 QA80-14038 FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY, the menu is reloaded in ColValuesDlg::updateColumnList, so no need to clear it
	//void Construct(bool bClearList = false)
	void Construct()
	///End FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY
	///end RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS
	{
		///Kyle 07/29/2009 QA80-14038 FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY, the menu is reloaded in ColValuesDlg::updateColumnList, so no need to clear it
		///// Iris 01/04/2009 v8.0993c RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS
		//if(bClearList)
			//clearList();
		/////end RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS
		///End FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY
		
		/// Iris 01/04/2009 v8.0993c RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS
		//constructMenu(IDC_FUNCTIONS_MENU_FAVORITES_BEGIN + FUNCTIONS_MENU_FAVORITES_MAX_NUM);
		///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
		//constructMenu(IDC_FUNCTIONS_MENU_ITEM_BEGIN);
		constructMenu();
		///End SCV_ADD_FITTING_FUNCTIONS
		///end RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS
	}
	void UpdateFuncHistoryList(const string& strNew);
	string GetFunctionString(UINT uCmdID);
	
	///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
#ifdef _ADD_FITTING_FUNCTIONS_TO_SCV
	bool	OnUpdateFittingFunc(CmdUI cmd);
	string GetMenuString(UINT nIDItem);
	bool	GetFunctionInfo(FunctionInfo& funcInfo, UINT uCmdID);
#endif // _ADD_FITTING_FUNCTIONS_TO_SCV
	///End SCV_ADD_FITTING_FUNCTIONS

private:
	///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
	//void constructMenu(int nBeginID);
	void constructMenu();
	int getNextID(int nCount = 1);
	///End SCV_ADD_FITTING_FUNCTIONS
	///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
#ifdef _ADD_FITTING_FUNCTIONS_TO_SCV
	int conFittingFuncCateList();
	
	bool isFittingFunc(int nID);
#endif // _ADD_FITTING_FUNCTIONS_TO_SCV
	///End SCV_ADD_FITTING_FUNCTIONS
	/// Iris 12/30/2008 v8.0992 FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
	virtual void getOCTypes(vector<int>& vnOCTypes) { ASSERT(0); }
	virtual string getLTStatsFunction() { ASSERT(0); return ""; }
	virtual string getCommonVariables() { ASSERT(0); return ""; }
	virtual string getOCVarSkipTypes() { ASSERT(0); return ""; }
	virtual string getMiscellaneous() { ASSERT(0); return ""; } 
	///end FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
	
	//HMENU getMenuHandle(); // Iris 01/06/2009 a useful method, but no place use, so commented out.
	
	/// Iris 01/04/2009 v8.0993c RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS
	///Kyle 07/29/2009 QA80-14038 QA80-14038 FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY, the menu is reloaded in ColValuesDlg::updateColumnList, so no need to clear it
	//void clearList();
	//int getBeginID(int nCategoryID);
	///End FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY
	///end RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS

	
protected:
	string 				m_strFavSection;
	vector<uint> 		m_vnCategoryIDs;			// the resource id	
	
	int					m_nNextID;				///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
	
	///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
#ifdef _ADD_FITTING_FUNCTIONS_TO_SCV
	CCategoryIDRangeMap			m_mapCateRange;
	
	CMapFitFuncCateID			m_mapFitFuncCateID;
#endif // _ADD_FITTING_FUNCTIONS_TO_SCV
	///End SCV_ADD_FITTING_FUNCTIONS
};

/// Iris 12/30/2008 v8.0992 FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
class WksFunctionsMenu : public FunctionsMenu
{
public:
	WksFunctionsMenu(HMENU &hMenu, LPCSTR lpcszFavSection, const vector<uint> &vnCategoryIDs) : FunctionsMenu(hMenu, lpcszFavSection, vnCategoryIDs)
	{
	}
	
	WksFunctionsMenu(HMENU &hMenu, LPCSTR lpcszFavSection) : FunctionsMenu(hMenu, lpcszFavSection)
	{
	}
	
private:
	//virtual
	void getOCTypes(vector<int>& vnOCTypes)
	{
		vector<int> vn = {BFC_OC_RETURN_NUMERIC, BFC_OC_RETURN_STRING, BFC_OC_RETURN_VECTOR};
		vnOCTypes = vn;
	}
	
	//virtual 
	string getLTStatsFunction()	{ return WKS_LT_STATS_FUNCTION;	}
	
	//virtual 
	string getCommonVariables() { return WKS_COMMON_VARIABLE; }
	
	// virtual
	string getOCVarSkipTypes() { return WKS_VAR_SKIP_TYPE; }
	
	//virtual 
	string getMiscellaneous()
	{
		///Kyle 05/21/2009 NEW_STRUCTURE_OF_SET_COLUMN_VALUES_DIALOG_F_X_PULL_DOWN_MENU
		//return WKS_MISCELLANEOUS_FUNCTION; 
#ifdef NEW_STRUCTURE_OF_SET_COL_VAL_F_X_POLL_DOWN_MENU
		return "";
#else
		return WKS_MISCELLANEOUS_FUNCTION;
#endif //NEW_STRUCTURE_OF_SET_COL_VAL_F_X_POLL_DOWN_MENU
		///End NEW_STRUCTURE_OF_SET_COLUMN_VALUES_DIALOG_F_X_PULL_DOWN_MENU
	}
	
};

class MatFunctionsMenu : public FunctionsMenu
{
public:
	MatFunctionsMenu(HMENU &hMenu, string strFavSection, vector<uint> vnCategoryIDs) : FunctionsMenu(hMenu, strFavSection, vnCategoryIDs)
	{
	}	
	
	MatFunctionsMenu(HMENU &hMenu, string strFavSection) : FunctionsMenu(hMenu, strFavSection)
	{
	}	
private:
	//virtual
	void getOCTypes(vector<int>& vnOCTypes)
	{
		///Kyle 12/30/2008 v8.0992 OKUTIL_FIND_LT_FUNCTIONS_ADD_MATRIX_AS_RETURN_TYPE
		//vector<int> vn = {BFC_OC_RETURN_NUMERIC};
		vector<int> vn = {BFC_OC_RETURN_NUMERIC, BFC_OC_RETURN_MATRIX};
		///End OKUTIL_FIND_LT_FUNCTIONS_ADD_MATRIX_AS_RETURN_TYPE
		vnOCTypes = vn;
	}
	
	//virtual 
	string getLTStatsFunction() { return MAT_LT_STATS_FUNCTION; }
	
	//virtual 
	string getCommonVariables() { return MAT_COMMON_VARIABLE; }
	
	// virtual
	string getOCVarSkipTypes() { return MAT_VAR_SKIP_TYPE; }
	
	//virtual 
	string getMiscellaneous() { return MAT_MISCELLANEOUS_FUNCTION; } 	
};
///end FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU

class FunctionsFavoriteMenu : public Menu
{
public:
	FunctionsFavoriteMenu(HMENU &hMenu, string strFavSection) : Menu(hMenu)
	{
		m_strFavSection = strFavSection.IsEmpty() ? STR_FUNCTIONS_MENU_FAVORITES_SECTION : strFavSection;
	}
	void UpdateList(const string& strNew);

	FunctionsFavoriteMenu(string strFavSection)
	{
		m_strFavSection = strFavSection.IsEmpty() ? STR_FUNCTIONS_MENU_FAVORITES_SECTION : strFavSection;
	}
	void Load();
	
private:
	void saveini(const vector<string>& vsList);
	bool loadini(vector<string>& vsList);
	void clearini();
	
	void clearList();
	void getList(vector<string>& vsList);
	void addList(const vector<string>& vsList);
protected:
	string 				m_strFavSection;
};

void FunctionsMenu::UpdateFuncHistoryList(const string& strNew)
{
	HMENU hMenu= GetPopupHmenu(IDC_FUNCTIONS_MENU_FAVORITES_BEGIN);
	if ( NULL != hMenu )
	{
		FunctionsFavoriteMenu *pffm = new FunctionsFavoriteMenu(hMenu, m_strFavSection);
		if ( pffm )
			pffm->UpdateList(strNew);
	}
}

string FunctionsMenu::GetFunctionString(UINT uCmdID)
{
	string str;
	GetMenuString(uCmdID, str, MF_STRING);
	///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
#ifdef _ADD_FITTING_FUNCTIONS_TO_SCV
	if( isFittingFunc(uCmdID) )
	{
		str.TrimLeft();
		str = STR_FIT_FUNC_PREFIX + str;
	}
#endif //_ADD_FITTING_FUNCTIONS_TO_SCV
	///End SCV_ADD_FITTING_FUNCTIONS

	///Kyle 09/14/2009 ADD_WCOL(_ThisColNum)_UNDER_VARIABLE_CONSTANT, no need to trim the arg list if selected from Common Variables
	//_check_make_func_str(str);
	vector<string> vsCommonVariables;
	getCommonVariables().GetTokens(vsCommonVariables, '|');
	if(vsCommonVariables.Find(str) < 0)
		_check_make_func_str(str);
	///End ADD_WCOL(_ThisColNum)_UNDER_VARIABLE_CONSTANT
	return str;
}

/// Iris 01/04/2009 v8.0993c RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS
///Kyle 07/29/2009 QA80-14038 FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY
/*
void FunctionsMenu::clearList()
{
	for(int nCategory = 0; nCategory < m_vnCategoryIDs.GetSize(); nCategory++)
	{
		int nCategoryID = m_vnCategoryIDs[nCategory];
		int nBeginItemID = getBeginID(nCategoryID);
		
		HMENU hMenu = GetPopupHmenu(nBeginItemID);
		if( hMenu )
		{
			Menu menu(hMenu);
			menu.RemoveAllItems();				
			menu.Add(STR_FUNCTIONS_MENU_EMPTY_ITEM, nCategoryID, MF_STRING | MF_GRAYED | MF_DISABLED);  
		}
	}		
}

int FunctionsMenu::getBeginID(int nCategoryID)
{
	vector<uint> vnIndex;
	if(m_vnCategoryIDs.Find(vnIndex, nCategoryID) <= 0 && vnIndex.GetSize() > 0)
	{
		ASSERT(0);
		return 0;
	}
	
	ASSERT(1 == vnIndex.GetSize());
	return IDC_FUNCTIONS_MENU_ITEM_BEGIN + FUNCTIONS_MENU_ITEM_MAX_NUM * vnIndex[0];	
}
*/
///End FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY
///end RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS

// Iris 01/06/2009 a useful method, but no place use, so commented out.
/*
HMENU FunctionsMenu::getMenuHandle()
{
	HMENU hMainMenu = GetSafeHmenu();
	if(NULL == hMainMenu)
		return NULL;
	
	HMENU hmFuncs = GetSubMenu(hMainMenu, POS_FUNCS);
	return hmFuncs;	
}
*/

///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
#ifdef _ADD_FITTING_FUNCTIONS_TO_SCV

class FuncListMenu : public Menu
{
public:
	FuncListMenu(int nIDBegin, const vector<string>& vsLabels)
	{
		if(vsLabels.GetSize() == 0)
			Add(STR_FUNCTIONS_MENU_EMPTY_ITEM, nIDBegin, MF_GRAYED | MF_DISABLED);
		else
		{
			for(int ii=0; ii<vsLabels.GetSize(); ii++)
				Add(vsLabels[ii], nIDBegin++);
		}
	}
};

typedef int (*FUN_GET_CATEGORY_LIST) (vector<string>& vsCategorys, vector<int>& vnSeparatorIndices = NULL);

static int		_get_category_list(vector<string>& vsCategories, vector<int>& vnSeparatorIndices = NULL)
{
	FUN_GET_CATEGORY_LIST pfn_get_category_list = Project.FindFunction("nlsf_get_category_list", "OriginLab\\nlsf_utils.c", true);
	if( !pfn_get_category_list )
	{
		ASSERT(false);
		return -2;
	}

	int nRet = 0;
	if( vsCategories )
		nRet = pfn_get_category_list(vsCategories, vnSeparatorIndices);
	else
	{
		vector<string> vs;
		pfn_get_category_list(vs, vnSeparatorIndices);
		nRet = vs.GetSize();
	}
	return nRet;
}

int FunctionsMenu::conFittingFuncCateList()
{
	vector<string> vsCategories;
	vector<int> vnSeparatorIndices;
	_get_category_list(vsCategories, vnSeparatorIndices);
	
	Menu popupFitFuncs(GetPopupHmenu(IDC_FUNCTION_MENU_FIT_FUNC));
	popupFitFuncs.RemoveAllItems();
	if( !popupFitFuncs.GetSafeHmenu() )
	{
		ASSERT(false);
		return -1;			// error
	}

	ASSERT(vsCategories.GetSize() <= FITTING_FUNC_CATEGORY_NUM);
	int nCateIDBegin = IDC_FITTING_FUNC_CATEGORY_BEGIN;

	vector<string> vsFuncs;
	for(int nCate = 0; nCate < vsCategories.GetSize(); nCate++)
	{
		vector<uint> vec;
		if(vnSeparatorIndices.Find(vec, nCate) > 0)				// separate between cagegories
		{
			popupFitFuncs.Add(NULL, 0, MF_SEPARATOR);
			continue;
		}
		int nCateID = nCateIDBegin++;
		FuncListMenu func(nCateID, vsFuncs);
		
		popupFitFuncs.AddPopup(vsCategories[nCate], func);
		m_mapFitFuncCateID.Add(nCateID, vsCategories[nCate]);
	}

	return 0;
}

bool	FunctionsMenu::OnUpdateFittingFunc(CmdUI cmd)
{
	//return false;
	CmdUIInfo info;
	if( !cmd.GetMenuInfo(info) || !info.m_hMenu )
		return false;
	HMENU hMenu = info.m_hSubMenu ? info.m_hSubMenu : info.m_hMenu;
	if( !hMenu )
		return false;

	string strCategory;
	if( !m_mapFitFuncCateID.Lookup(info.m_nID, strCategory) )
		return false;

	Menu menu(hMenu);
	//HWND hPopup = GetPopupHmenu(info.m_nID);
	//if( menu.GetSafeHmenu() != hPopup )
		//return false;

	m_mapFitFuncCateID.Remove(info.m_nID);			// no need any more
	menu.RemoveAllItems();

	vector<string> vsFunctions;
	scan_fit_funcs(vsFunctions, strCategory);
	vsFunctions.Sort();
	if( vsFunctions.GetSize() > 0 )
	{
		int nBeginID = getNextID(vsFunctions.GetSize());
		m_mapCateRange.AddRange(IDC_FUNCTION_MENU_FIT_FUNC, nBeginID, nBeginID + vsFunctions.GetSize() - 1);

		for(int nFunc = 0; nFunc < vsFunctions.GetSize(); nFunc++)
			menu.Add(vsFunctions[nFunc], nBeginID++);
	}
	else
	{
		menu.Add(STR_FUNCTIONS_MENU_EMPTY_ITEM, getNextID(), MF_GRAYED | MF_DISABLED);
	}
	return true;
}

bool FunctionsMenu::isFittingFunc(int nID)
{
	int		nCategory = m_mapCateRange.FindCategory(nID);
	return nCategory == IDC_FUNCTION_MENU_FIT_FUNC;
}

string FunctionsMenu::GetMenuString(UINT uCmdID)
{
	string str;
	GetMenuString(uCmdID, str, MF_STRING);

	if( isFittingFunc( uCmdID ) )
	{
		str.TrimLeft();
		str = STR_FIT_FUNC_PREFIX + str;
		return str;
	}
	return str;
}

static	bool	_check_separate_func_info(LPCSTR lpcszFunc, bool bFitFunc, string& strFuncName, uint& nRetType, vector<string>& vsArgNames, vector<uint>& vnArgTypes, int& nDefArgs)
{
	// check remove junk
	string str(lpcszFunc);
	string	strName = str.GetToken(1, FUNCTIONS_MENU_OC_CATEGORY_FUNCTION_SEPARATOR);
	if ( !strName.IsEmpty() )
	{
		strName.TrimLeft();
		strName.TrimRight();
		str = strName;
	}
	int nSpacePos = str.Find(' ');
	int nLeftBracketPos = str.Find('(');
	if(nSpacePos > 0 && nSpacePos < nLeftBracketPos)	// space before (
	{
		int nLength = str.GetLength() - nSpacePos - 1;		// length after the space
		str = str.Right(nLength);
		str.TrimLeft();

		nLeftBracketPos = str.Find('(');
	}

	if(nLeftBracketPos <= 0 )
		return false;

	strFuncName = str.Left(nLeftBracketPos);
	if( strFuncName.IsEmpty() || !is_good_C_identifier(strFuncName) )
		return false;

	str = str.Right(str.GetLength() - nLeftBracketPos);				// arg list: "(...[...])" or "(...[...])$"
	if( str[str.GetLength()-1] == '$' )								// the last char must be ')'
	{
		str.TrimRight('$');
		nRetType = LTVAR_TYPE_VAR_STR;
	}
	else if(str[str.GetLength()-1] == ')' )
	{
		nRetType = LTVAR_TYPE_VAR_DOUBLE;				// default return type
	}
	else
		return false;

	str = str.Mid(1, str.GetLength() - 2);
	str.TrimLeft();
	str.TrimRight();
	if( str.Find('(') >= 0 || str.Find(')') >= 0 )					// no more '(' or ')'
		return false;

	vector<string> vsDefArgs;
	int		nLeftSquareBracketPos = str.Find('[');
	int		nRightSquareBracketPos = str.Find(']');
	if( nLeftSquareBracketPos >= 0 )
	{
		if( nRightSquareBracketPos != str.GetLength() -1 )			// ']' should be the last char
			return false;

		string strDefAgrs = str.Mid(nLeftSquareBracketPos + 1, nRightSquareBracketPos - nLeftSquareBracketPos - 1);
		strDefAgrs.TrimLeft(FUNCTION_ARGUMENTS_SEPARATOR);
		strDefAgrs.GetTokens(vsDefArgs, FUNCTION_ARGUMENTS_SEPARATOR);

		str = str.Left(nLeftSquareBracketPos);
		str.TrimRight();
	}
	nDefArgs = vsDefArgs.GetSize();

	str.GetTokens(vsArgNames, FUNCTION_ARGUMENTS_SEPARATOR);
	vsArgNames.Append(vsDefArgs);
	
	vnArgTypes.SetSize(vsArgNames.GetSize());
	vnArgTypes = LTVAR_TYPE_VAR_DOUBLE;				// default
	for ( int ii= vsArgNames.GetSize() - 1; ii >= 0; ii-- )
	{
	
	}

	
	return true;
}

bool	FunctionsMenu::GetFunctionInfo(FunctionInfo& funcInfo, UINT uCmdID)
{
	string str;
	if( GetMenuString(uCmdID, str, MF_STRING) <= 0 )
		return false;

	vector<string> vsCommonVariables;
	getCommonVariables().GetTokens(vsCommonVariables, '|');
	if(vsCommonVariables.Find(str) >= 0)					// constant
		return false;

	string strFuncName;
	uint nReturnType;
	vector<string> vsArgNames;
	vector<uint> vnArgTypes;
	int nDefArgs;
	
	bool bFitFunc = isFittingFunc(uCmdID);
	if( !_check_separate_func_info(str, bFitFunc, strFuncName, nReturnType, vsArgNames, vnArgTypes, nDefArgs) )
		return false;
	funcInfo.dwCtrl = bFitFunc ? FI_FIT_FUNCTION : 0;
	funcInfo.strFuncName = strFuncName;
	funcInfo.nReturnType = nReturnType;
	funcInfo.strDescription = "";
	funcInfo.vsArguNames.SetSize(0);
	funcInfo.vsArguNames.Append(vsArgNames);
	funcInfo.vnArguTypes.SetSize(0);
	funcInfo.vnArguTypes.Append(vnArgTypes);
	funcInfo.nNumDefArgs = nDefArgs;

	return true;
}

#endif //#ifdef _ADD_FITTING_FUNCTIONS_TO_SCV
///End SCV_ADD_FITTING_FUNCTIONS

///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
int FunctionsMenu::getNextID(int nCount)
{
	if(nCount <= 0)
		nCount = 1;
	int nBeginID = m_nNextID;
	m_nNextID += nCount;
	
	return nBeginID;
}
///End SCV_ADD_FITTING_FUNCTIONS

///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
//void FunctionsMenu::constructMenu(int nBeginID)
void FunctionsMenu::constructMenu()
///End SCV_ADD_FITTING_FUNCTIONS
{
	// prepare oc functions
	vector<string> vsCategories, vsRetTypes, vsFuncNames, vsArgs;
	/// Iris 12/30/2008 v8.0992 FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
	//vector<int> vnOCType = {BFC_OC_RETURN_NUMERIC, BFC_OC_RETURN_STRING, BFC_OC_RETURN_VECTOR};
	vector<int> vnOCType;
	getOCTypes(vnOCType);
	///end FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
	
	int nCount;
	for(int ii = 0; ii < vnOCType.GetSize(); ii++)
	{
		vector<string> vsCategoriesTmp, vsTempRetTypes, vsTempFuncs, vsTempArgs;
		/// Iris 12/30/2008 v8.0992 FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
		//nCount += _menu_Find_LT_functions(vsTempRetTypes, vsTempFuncs, vsTempArgs, vnOCType[ii], false, &vsCategoriesTmp);
		nCount += _menu_Find_LT_functions(vsTempRetTypes, vsTempFuncs, vsTempArgs, vnOCType[ii], false, &vsCategoriesTmp, getOCVarSkipTypes());
		///end FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
		vsCategories.Append(vsCategoriesTmp);
		vsRetTypes.Append(vsTempRetTypes);
		vsFuncNames.Append(vsTempFuncs);
		vsArgs.Append(vsTempArgs);
	}
	vector<string> vsOCTextFuncs, vsOCMathFuncs, vsOCDTFuncs, vsOCStatsFuncs, vsOCDistriFuncs, vsOCDataGenFuncs, vsOCMisFuncs, vsOCUserDefFuncs;
	///Kyle 05/21/2009 NEW_STRUCTURE_OF_SET_COLUMN_VALUES_DIALOG_F_X_PULL_DOWN_MENU
	//_make_oc_function_names_in_category(vsCategories, vsRetTypes, vsFuncNames, vsArgs,
										//vsOCTextFuncs, vsOCMathFuncs, vsOCDTFuncs,
										//vsOCStatsFuncs, vsOCDistriFuncs, vsOCDataGenFuncs,
										//vsOCMisFuncs, vsOCUserDefFuncs);
#ifdef NEW_STRUCTURE_OF_SET_COL_VAL_F_X_POLL_DOWN_MENU
	vector<string> vsOCDatasetInfoFuncs, vsOCDataManipuFuncs;
	_make_oc_function_names_in_category(vsCategories, vsRetTypes, vsFuncNames, vsArgs,
										vsOCTextFuncs, vsOCMathFuncs, vsOCDTFuncs,
										vsOCStatsFuncs, vsOCDistriFuncs, vsOCDataGenFuncs,
										vsOCDatasetInfoFuncs, vsOCDataManipuFuncs,
										vsOCMisFuncs, vsOCUserDefFuncs);
#else
	_make_oc_function_names_in_category(vsCategories, vsRetTypes, vsFuncNames, vsArgs,
										vsOCTextFuncs, vsOCMathFuncs, vsOCDTFuncs,
										vsOCStatsFuncs, vsOCDistriFuncs, vsOCDataGenFuncs,
										vsOCMisFuncs, vsOCUserDefFuncs);

#endif //NEW_STRUCTURE_OF_SET_COL_VAL_F_X_POLL_DOWN_MENU
	///End NEW_STRUCTURE_OF_SET_COLUMN_VALUES_DIALOG_F_X_PULL_DOWN_MENU

	//int nNewID = nBeginID; /// Iris 01/04/2009 v8.0993c RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS
	///Kyle 07/29/2009 QA80-14038 FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY
	//int nNewID = nBeginID;		Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
	///End FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY
	for(ii = 0; ii < m_vnCategoryIDs.GetSize(); ii++)
	{
		bool bSort = true;			///Kyle 09/14/2009 ADD_WCOL(_ThisColNum)_UNDER_VARIABLE_CONSTANT
		int nCategoryID = m_vnCategoryIDs[ii];
		
		///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
#ifdef _ADD_FITTING_FUNCTIONS_TO_SCV
		if( nCategoryID == IDC_FUNCTION_MENU_FIT_FUNC)
		{
			conFittingFuncCateList();
			continue;
		}
#endif//#ifdef _ADD_FITTING_FUNCTIONS_TO_SCV
		///End SCV_ADD_FITTING_FUNCTIONS

		vector<string> vsFuncLabels;
		switch(nCategoryID)
		{
		case IDC_FUNCTION_MENU_MATH:
			///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#ifdef __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
			vector<string> vsGeneralFunctions = {"abs(x)","acos(x)","angle(x, y)","asin(x)","atan(x)","cos(x)","cosh(x)","exp(x)","int(x)","ln(x)","log(x)","mod(n, m)","nint(x)","prec(x, n)",
										     "rmod(x, y)","round(x, n)","sin(x)","sinh(x)","sqrt(x)","tan(x)", "tanh(x)"};
			vector<string> vsSpecialFunctions = {"beta(a, b)","incbeta(x, a, b)","incf(x, m, n)","incgamma(x, a)","inverf(x)","j0(x)","j1(x)","jn(x, n)", "y0(x)","y1(x)","yn(x, n)"};
#else // __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
			///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
			vector<string> vsGeneralFunctions = {"abs(d)","acos(d)","angle(d,d)","asin(d)","atan(d)","cos(d)","cosh(d)","exp(d)","int(d)","ln(d)","log(d)","mod(n,n)","nint(d)","prec(d,n)",
										     "rmod(d,d)","round(d,n)","sin(d)","sinh(d)","sqrt(d)","tan(d)", "tanh(d)"};
			vector<string> vsSpecialFunctions = {"beta(d,d)","incbeta(d,d,d)","incf(d,n,n)","incgamma(d,d)","inverf(d)","j0(d)","j1(d)","jn(d,n)", "y0(d)","y1(d)","yn(d,n)"};
			///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#endif //__STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
			///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
			vsFuncLabels = vsGeneralFunctions;
			vsFuncLabels.Append(vsSpecialFunctions);
			vsFuncLabels.Append(vsOCMathFuncs);
			break;
			
		case IDC_FUNCTION_MENU_STATS:
			/// Iris 12/30/2008 v8.0992 FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
			//vector<string> vsStatisticsFunctions = {"ave(,)","diff()","cov(,,,)","histogram(,,,)","percentile(,)","qcd2()","qcd3()","qcd4()","ss(,)","sum()"};
			vector<string> vsStatisticsFunctions;
			getLTStatsFunction().GetTokens(vsStatisticsFunctions, '|');
			///end FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
			vsFuncLabels = vsStatisticsFunctions;
			vsFuncLabels.Append(vsOCStatsFuncs);
			break;
			
		case IDC_FUNCTION_MENU_CDF:
			vector<string> vsRetTypes, vsFuncNames, vsArgs;
			_menu_Find_LT_functions(vsRetTypes, vsFuncNames, vsArgs, BFC_CDF);
			for(int ii=0; ii<vsFuncNames.GetSize(); ii++)
				vsFuncNames[ii] += vsArgs[ii];
			vsFuncLabels = vsFuncNames;
			break;
			
		case IDC_FUNCTION_MENU_PDF:
			vector<string> vsRetTypes, vsFuncNames, vsArgs;
			_menu_Find_LT_functions(vsRetTypes, vsFuncNames, vsArgs, BFC_PDF);
			for(int ii=0; ii<vsFuncNames.GetSize(); ii++)
				vsFuncNames[ii] += vsArgs[ii];
			vsFuncLabels = vsFuncNames;
			break;
			
		case IDC_FUNCTION_MENU_INV:
			vector<string> vsRetTypes, vsFuncNames, vsArgs;
			_menu_Find_LT_functions(vsRetTypes, vsFuncNames, vsArgs, BFC_INV);
			for(int ii=0; ii<vsFuncNames.GetSize(); ii++)
				vsFuncNames[ii] += vsArgs[ii];
			vsFuncLabels = vsFuncNames;
			break;
			
		case IDC_FUNCTION_MENU_DATE_TIME:
			///Kyle 12/25/2008 v8.0990e ADD_LT_DATE_TIME_FUNCTIONS
			//vsFuncLabels = vsOCDTFuncs;
			///Kyle 01/06/2009 v8.0993c LT_FUNCTION_DATE_HAS_SUPPORTED_CUSTOM_DATE_FORMAT
			//vector<string> vsLTDateTimeFunctions = {"date(str)", "date(yy,mm,dd)", "time(str)", "time(hh,mm,ss)"};
			//---- CPY 1/8/09 BUILT_IN_LT_FUNC_NAMES_NEED_TO_MATCH_OC
			// others are changed without marking
			//vector<string> vsLTDateTimeFunctions = {"date(,)", "date(yy,mm,dd)", "time(str)", "time(hh,mm,ss)"};
#ifdef __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
			vector<string> vsLTDateTimeFunctions = {"Date(MM/dd/yy[, format])", "Date(yy,mm,dd)", "Time(HH:mm:ss)", "Time(HH,mm,ss)"};
#else // __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
			///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
			vector<string> vsLTDateTimeFunctions = {"Date(str[,format])", "Date(yy,mm,dd)", "Time(str)", "Time(hh,mm,ss)"};
			///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#endif //__STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
			///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
			//----
			///End LT_FUNCTION_DATE_HAS_SUPPORTED_CUSTOM_DATE_FORMAT
			vsFuncLabels = vsLTDateTimeFunctions;
			vsFuncLabels.Append(vsOCDTFuncs);
			///End ADD_LT_DATE_TIME_FUNCTIONS
			break;
			
		case IDC_FUNCTION_MENU_TEXT:
			vsFuncLabels = vsOCTextFuncs;
			break;
		
		///Kyle 05/21/2009 NEW_STRUCTURE_OF_SET_COLUMN_VALUES_DIALOG_F_X_PULL_DOWN_MENU
		//case IDC_FUNCTION_MENU_DATA_GENERATION:
			//vector<string> vsDataGeneration = {"Data(d,d,d)", "Errof(vd)", "FindMasks(vd)", "Peaks(vd,d,d)", "tReplace(vd,d,d[,n])", "Xof(vd)"}
			//vsFuncLabels = vsDataGeneration;
			//vector<string> vsRetTypes, vsFuncNames, vsArgs;
			//int nCount = _menu_Find_LT_functions(vsRetTypes, vsFuncNames, vsArgs, BFC_RNG);
			//for(int ii=0; ii<vsFuncNames.GetSize(); ii++)
				//vsFuncNames[ii] += vsArgs[ii];
			//vsFuncLabels.Append(vsFuncNames);
			//vsFuncLabels.Append(vsOCDataGenFuncs);
			//break;
#ifdef NEW_STRUCTURE_OF_SET_COL_VAL_F_X_POLL_DOWN_MENU
		case IDC_FUNCTION_MENU_DATA_GENERATION:
			///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#ifdef __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
			vector<string> vsDataGeneration = {"Data(x1, x2, inc)"};
#else // __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
		///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
			vector<string> vsDataGeneration = {"Data(d,d,d)"};
			///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#endif //__STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
			///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
			vsFuncLabels = vsDataGeneration;
			vector<string> vsRetTypes, vsFuncNames, vsArgs;
			int nCount = _menu_Find_LT_functions(vsRetTypes, vsFuncNames, vsArgs, BFC_RNG);
			for(int ii=0; ii<vsFuncNames.GetSize(); ii++)
				vsFuncNames[ii] += vsArgs[ii];
			vsFuncLabels.Append(vsFuncNames);
			vsFuncLabels.Append(vsOCDataGenFuncs);
			break;

		case IDC_FUNCTION_MENU_DATASET_INFORMATION:
			///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#ifdef __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
			vector<string> vsDatasetInfo = {"Errof(vd)", "Findmasks(vd)", "hasx(vd)", "IsMasked(n, vd)", "List(val, vd)", "Xindex(x, vd)", "Xof(vd)", "Xvalue(n, vd)"};
#else // __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
		///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
			vector<string> vsDatasetInfo = {"Errof(vd)", "Findmasks(vd)", "hasx(vd)", "IsMasked(i, vd)", "List(value, vd)", "Xindex(x, vd)", "Xof(vd)", "Xvalue(i, vd)"};
			///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#endif //__STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
			///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
			vsFuncLabels = vsDatasetInfo;
			vsFuncLabels.Append(vsOCDatasetInfoFuncs);
			break;
			
		case IDC_FUNCTION_MENU_DATA_MANIPULATION:
			///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#ifdef __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
			vector<string> vsDataManipulation = {"asc(str$)", "corr(vd1, vd2, k[, n])", "peaks(vd, width, minht)", "sort(vd)", "tReplace(vd, val1, val2[, cnd])"};
#else // __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
		///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
			vector<string> vsDataManipulation = {"asc(ch)", "corr(vd1, vd2, k, N)", "peaks(vd, d, d)", "sort(vd)", "tReplace(vd,d,d[,n])"};
			///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#endif //__STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
			///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
			vsFuncLabels = vsDataManipulation;
			vsFuncLabels.Append(vsOCDataManipuFuncs);
			break;
#else
		case IDC_FUNCTION_MENU_DATA_GENERATION:
			vector<string> vsDataGeneration = {"Data(d,d,d)", "Errof(vd)", "FindMasks(vd)", "Peaks(vd,d,d)", "tReplace(vd,d,d[,n])", "Xof(vd)"};
			vsFuncLabels = vsDataGeneration;
			vector<string> vsRetTypes, vsFuncNames, vsArgs;
			int nCount = _menu_Find_LT_functions(vsRetTypes, vsFuncNames, vsArgs, BFC_RNG);
			for(int ii=0; ii<vsFuncNames.GetSize(); ii++)
				vsFuncNames[ii] += vsArgs[ii];
			vsFuncLabels.Append(vsFuncNames);
			vsFuncLabels.Append(vsOCDataGenFuncs);
			break;

#endif //NEW_STRUCTURE_OF_SET_COL_VAL_F_X_POLL_DOWN_MENU
		///End NEW_STRUCTURE_OF_SET_COLUMN_VALUES_DIALOG_F_X_PULL_DOWN_MENU
	
		case IDC_FUNCTION_MENU_NAG:
			vector<string> vsRetTypes, vsFuncNames, vsArgs;
			int nCount = _menu_Find_LT_functions(vsRetTypes, vsFuncNames, vsArgs, BFC_NAG_SF);
			for(int ii=0; ii<vsFuncNames.GetSize(); ii++)
				vsFuncNames[ii] += vsArgs[ii];
			vsFuncLabels = vsFuncNames;
			break;
			
		case IDC_FUNCTION_MENU_MISCELLANEOUS:
			/// Iris 12/30/2008 v8.0992 FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
			//vsFuncLabels.Add("sort()");
			vector<string> vsMiscellaneousFunctions;
			getMiscellaneous().GetTokens(vsMiscellaneousFunctions, '|');
			vsFuncLabels.Append(vsMiscellaneousFunctions);
			///end FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
			vsFuncLabels.Append(vsOCMisFuncs);
			break;
			
		case IDC_FUNCTION_MENU_USER_DEFINED:
			vsFuncLabels = vsOCUserDefFuncs;
			break;
			
		case IDC_FUNCTION_MENU_VARIABLE_CONSTANT:
			/// Iris 12/30/2008 v8.0992 FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
			//vector<string> vsCommonVariables = {"_ThisColNum", "[i]", "pi"};
			vector<string> vsCommonVariables;
			getCommonVariables().GetTokens(vsCommonVariables, '|');
			///end FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
			vsFuncLabels = vsCommonVariables;
			bSort = false;			///Kyle 09/14/2009 ADD_WCOL(_ThisColNum)_UNDER_VARIABLE_CONSTANT
			break;
			
		case IDC_FUNCTION_MENU_DISTRIBUTIONS:
			vsFuncLabels = vsOCDistriFuncs;
			break;
		}
		///Kyle 09/14/2009 ADD_WCOL(_ThisColNum)_UNDER_VARIABLE_CONSTANT
		//vsFuncLabels.Sort();
		if(bSort)
			vsFuncLabels.Sort();
		///End ADD_WCOL(_ThisColNum)_UNDER_VARIABLE_CONSTANT
		int nCount = vsFuncLabels.GetSize();
		if(nCount > 0)
		{			
			///Kyle 07/29/2009 QA80-14038 FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY
			///// Iris 01/04/2009 v8.0993c RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS
			//int nNewID = getBeginID(nCategoryID);
			//ASSERT(nNewID >= nBeginID);
			/////end RECONSTRUCT_FUNCTION_MENU_SWITCH_MAT_AND_WKS
			///End FIX_ITEM_ID_DUPLICATED_IF_THERE_ARE_TOO_MANY_FUNCTIONS_IN_ONE_CATETORY

			///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
			int nNewID = getNextID(nCount);
#ifdef _ADD_FITTING_FUNCTIONS_TO_SCV
			m_mapCateRange.AddRange(nCategoryID, nNewID, nNewID + nCount - 1);
#endif // _ADD_FITTING_FUNCTIONS_TO_SCV
			///End SCV_ADD_FITTING_FUNCTIONS

			for(int jj=0; jj<nCount; jj++)
			{
				InsertMenu(nCategoryID, MF_STRING, nNewID++, vsFuncLabels[jj]);				
			}
			RemoveMenu(nCategoryID, MF_STRING); // remove Empty menu item
		}
	}

	HMENU hMenu = GetPopupHmenu(IDC_FUNCTION_MENU_FAVORITE);
	if ( hMenu )
	{
		FunctionsFavoriteMenu *pffm = new FunctionsFavoriteMenu(hMenu, m_strFavSection);
		if ( pffm )
		{
			pffm->Load();
		}
	}
}

void FunctionsFavoriteMenu::Load()
{
	vector<string> vsRecFunc;
	loadini(vsRecFunc);
	
	clearList();
	addList(vsRecFunc);
}

void FunctionsFavoriteMenu::UpdateList(const string& strNew)
{
	vector<string> vsRecFunc;
	getList(vsRecFunc);
	
	int nRemove = vsRecFunc.Find(strNew);
	if(nRemove < 0 && vsRecFunc.GetSize() >= FUNCTIONS_MENU_FAVORITES_MAX_NUM)
		nRemove = vsRecFunc.GetSize()-1;
	
	if(nRemove >= 0)
		vsRecFunc.RemoveAt(nRemove);
	vsRecFunc.InsertAt(0, strNew);

	clearList();
	addList(vsRecFunc);
	saveini(vsRecFunc);
}
void FunctionsFavoriteMenu::clearList()
{
	RemoveMenu(IDC_FUNCTION_MENU_FAVORITE, MF_STRING);
	for( int ii = 0; ii < FUNCTIONS_MENU_FAVORITES_MAX_NUM; ii++ )
		RemoveMenu(IDC_FUNCTIONS_MENU_FAVORITES_BEGIN + ii, MF_STRING);
}

void FunctionsFavoriteMenu::addList(const vector<string>& vsLabelList)
{
	int nNumList = vsLabelList.GetSize();
	if ( nNumList <= 0 )
	{
		Add(STR_FUNCTIONS_MENU_FAVORITES_EMPTY, IDC_FUNCTIONS_MENU_FAVORITES_BEGIN, MF_STRING | MF_GRAYED | MF_DISABLED);
	}
	else
	{
		for ( int ii = 0; ii < nNumList; ii++ )
		{
			Add(vsLabelList[ii], IDC_FUNCTIONS_MENU_FAVORITES_BEGIN + ii);
		}
	}
}

bool FunctionsFavoriteMenu::loadini(vector<string>& vsList)
{
	vsList.SetSize(0);
	
	if ( m_strFavSection.IsEmpty() )
		return false;

	vector<string> vsKeyNames;
	INIFile	iniFile(STR_FUNCTIONS_MENU_FAVORITES_SETTING_FILE);

	iniFile.GetKeyNames(vsKeyNames, m_strFavSection);
	for ( int ii = 0; ii < vsKeyNames.GetSize(); ii++ )
		vsList.Add(iniFile.ReadString(m_strFavSection, vsKeyNames[ii]));
	if(vsList.GetSize() > FUNCTIONS_MENU_FAVORITES_MAX_NUM)
		vsList.SetSize(FUNCTIONS_MENU_FAVORITES_MAX_NUM);
	return true;
}

void FunctionsFavoriteMenu::getList(vector<string>& vsList)
{
	vsList.SetSize(0);
	for(UINT nCmdID = IDC_FUNCTIONS_MENU_FAVORITES_BEGIN; nCmdID < IDC_FUNCTIONS_MENU_FAVORITES_BEGIN + FUNCTIONS_MENU_FAVORITES_MAX_NUM; nCmdID++)
	{
		string str;
		GetMenuString(nCmdID, str, MF_STRING);
		if(str.IsEmpty())
			break;
		vsList.Add(str);
	}
	
	// remove empty marker
	if ( vsList.GetSize() > 0 )
	{
		if ( vsList[0] == STR_FUNCTIONS_MENU_FAVORITES_EMPTY )
			vsList.RemoveAt(0);			
	}
}

void FunctionsFavoriteMenu::saveini(const vector<string>& vsList)
{
	INIFile	iniFile(STR_FUNCTIONS_MENU_FAVORITES_SETTING_FILE);
	
	//clear sections first
	clearini();

	for(int ii=0; ii<vsList.GetSize(); ii++)
		update_ini_line(iniFile, m_strFavSection, STR_FUNCTIONS_MENU_FAVORITES_FUNCTIONS_PREFIX + (string)ii, vsList[ii]);
}

void FunctionsFavoriteMenu::clearini()
{
	INIFile	iniFile(STR_FUNCTIONS_MENU_FAVORITES_SETTING_FILE);
	update_ini_line(iniFile, m_strFavSection, NULL, NULL );//clean functions
}
///Kyle 05/21/2009 NEW_STRUCTURE_OF_SET_COLUMN_VALUES_DIALOG_F_X_PULL_DOWN_MENU
//static	void	_make_oc_function_names_in_category(const vector<string>& vsCategories, const vector<string>& vsRetTypes, const vector<string>& vsFuncNames, const vector<string>& vsArgs,
													//vector<string>& vsTextFuncs, vector<string>& vsMathFuncs,
													//vector<string>& vsDTFuncs, vector<string>& vsStatsFuncs, 
													//vector<string>& vsDistriFuncs, vector<string>& vsDataGenFuncs,
													//vector<string>& vsMisFuncs, vector<string>& vsUserDefFuncs)
#ifdef NEW_STRUCTURE_OF_SET_COL_VAL_F_X_POLL_DOWN_MENU
static	void	_make_oc_function_names_in_category(const vector<string>& vsCategories, const vector<string>& vsRetTypes, const vector<string>& vsFuncNames, const vector<string>& vsArgs,
													vector<string>& vsTextFuncs, vector<string>& vsMathFuncs,
													vector<string>& vsDTFuncs, vector<string>& vsStatsFuncs, 
													vector<string>& vsDistriFuncs, vector<string>& vsDataGenFuncs,
													vector<string>& vsDatasetInfoFuncs, vector<string>& vsDataManipuFuncs,
													vector<string>& vsMisFuncs, vector<string>& vsUserDefFuncs)
#else
static	void	_make_oc_function_names_in_category(const vector<string>& vsCategories, const vector<string>& vsRetTypes, const vector<string>& vsFuncNames, const vector<string>& vsArgs,
													vector<string>& vsTextFuncs, vector<string>& vsMathFuncs,
													vector<string>& vsDTFuncs, vector<string>& vsStatsFuncs, 
													vector<string>& vsDistriFuncs, vector<string>& vsDataGenFuncs,
													vector<string>& vsMisFuncs, vector<string>& vsUserDefFuncs)
#endif //NEW_STRUCTURE_OF_SET_COL_VAL_F_X_POLL_DOWN_MENU
///End NEW_STRUCTURE_OF_SET_COLUMN_VALUES_DIALOG_F_X_PULL_DOWN_MENU
{
	ASSERT(vsRetTypes.GetSize() == vsCategories.GetSize());
	ASSERT(vsFuncNames.GetSize() == vsCategories.GetSize());
	ASSERT(vsArgs.GetSize() == vsCategories.GetSize());
	
	vsTextFuncs.SetSize(0);
	vsMathFuncs.SetSize(0);
	vsDTFuncs.SetSize(0);
	vsStatsFuncs.SetSize(0);
	vsDistriFuncs.SetSize(0);
	vsDataGenFuncs.SetSize(0);
	vsMisFuncs.SetSize(0);
	vsUserDefFuncs.SetSize(0);

	for(int ii=0; ii< vsCategories.GetSize(); ii++)
	{
		string strFuncName = vsFuncNames[ii] + vsArgs[ii];
		if(vsRetTypes[ii].CompareNoCase("string") == 0)
			strFuncName += "$";
		
		if(vsCategories[ii].IsEmpty())
			vsUserDefFuncs.Add(strFuncName);
		else if(vsCategories[ii].CompareNoCase(STR_FUNCTION_MENU_CATEGORY_STRING) == 0)
			vsTextFuncs.Add(strFuncName);
		else if(vsCategories[ii].CompareNoCase(STR_FUNCTION_MENU_CATEGORY_MATH) == 0)
			vsMathFuncs.Add(strFuncName);
		else if(vsCategories[ii].CompareNoCase(STR_FUNCTION_MENU_CATEGORY_DATE_TIME) == 0)
			vsDTFuncs.Add(strFuncName);
		else if(vsCategories[ii].CompareNoCase(STR_FUNCTION_MENU_CATEGORY_STATS) == 0)
			vsStatsFuncs.Add(strFuncName);
		else if(vsCategories[ii].CompareNoCase(STR_FUNCTION_MENU_CATEGORY_DISTRIBUTIONS) == 0)
			vsDistriFuncs.Add(strFuncName);
		else if(vsCategories[ii].CompareNoCase(STR_FUNCTION_MENU_CATEGORY_DATA_GENERATION) == 0)
			vsDataGenFuncs.Add(strFuncName);
		///Kyle 05/21/2009 NEW_STRUCTURE_OF_SET_COLUMN_VALUES_DIALOG_F_X_PULL_DOWN_MENU
#ifdef NEW_STRUCTURE_OF_SET_COL_VAL_F_X_POLL_DOWN_MENU
		else if(vsCategories[ii].CompareNoCase(STR_FUNCTION_MENU_CATEGORY_DATASET_INFO) == 0)
			vsDatasetInfoFuncs.Add(strFuncName);
		else if(vsCategories[ii].CompareNoCase(STR_FUNCTION_MENU_CATEGORY_DATA_MANIPULATION) == 0)
			vsDataManipuFuncs.Add(strFuncName);
#endif //NEW_STRUCTURE_OF_SET_COL_VAL_F_X_POLL_DOWN_MENU
		///End NEW_STRUCTURE_OF_SET_COLUMN_VALUES_DIALOG_F_X_PULL_DOWN_MENU
		else if(vsCategories[ii].CompareNoCase(STR_FUNCTION_MENU_CATEGORY_MISCELLANEOUS) == 0)
			vsMisFuncs.Add(strFuncName);
	}
}

static	void	_check_make_func_str(string& str)
{
	string	strName = str.GetToken(1, FUNCTIONS_MENU_OC_CATEGORY_FUNCTION_SEPARATOR);
	if ( !strName.IsEmpty() )
	{
		strName.TrimLeft();
		strName.TrimRight();
		str = strName;
	}
	int nSpaceIndex = str.Find(' ');
	int nParenIndex = str.Find('(');
	if(nSpaceIndex > 0 && nSpaceIndex < nParenIndex)	// space before (
	{
		int nLength = str.GetLength() - nSpaceIndex - 1;		// length after the space
		str = str.Right(nLength);
		str.TrimLeft();
	}
	
	///------ Folger 01/08/09 v8.0994d SUPPORT_GETTING_NUMBER_OF_DEFAULT_ARGUMENTS_ABOUT_OCLT_FUNCTION
	int		nLeftSquareBracketPos = str.Find('[');
	int		nRightSquareBracketPos = str.Find(']');
	
	///Kyle 07/24/2009 DEFAULT_ARGUMENTS_SHOULD_BE_INSIDE_BRACKETS
	//if ( nLeftSquareBracketPos >= 0 && nRightSquareBracketPos >= 0 )
	int		nLeftBracketPos = str.Find('(');
	int		nRightBracketPos = str.Find(')');
	if( nLeftBracketPos >= 0 && nRightBracketPos > nLeftBracketPos && nLeftSquareBracketPos > nLeftBracketPos && nRightSquareBracketPos < nRightBracketPos )
	///End DEFAULT_ARGUMENTS_SHOULD_BE_INSIDE_BRACKETS
		str.Delete(nLeftSquareBracketPos, nRightSquareBracketPos - nLeftSquareBracketPos + 1);
	///------ End SUPPORT_GETTING_NUMBER_OF_DEFAULT_ARGUMENTS_ABOUT_OCLT_FUNCTION
	
	///------ Folger 01/09/09 v8.0995 BETTER_FORMAT_FOR_INSERTED_STRING
	///Kyle 07/24/2009 DEFAULT_ARGUMENTS_SHOULD_BE_INSIDE_BRACKETS
	//int		nLeftBracketPos = str.Find('(');
	//int		nRightBracketPos = str.Find(')');
	nLeftBracketPos = str.Find('(');
	nRightBracketPos = str.Find(')');
	///End DEFAULT_ARGUMENTS_SHOULD_BE_INSIDE_BRACKETS
	int		nArgLength = nRightBracketPos - nLeftBracketPos - 1;
	string	strTmp = str.Mid(nLeftBracketPos + 1, nArgLength);
	str.Delete(nLeftBracketPos + 1, nArgLength);
	
	vector<string>		vsArgNames;
	strTmp.GetTokens(vsArgNames, FUNCTION_ARGUMENTS_SEPARATOR);
	///Kyle 11/04/2009 QA80-14584 SCV_ADD_FITTING_FUNCTIONS
#ifdef _ADD_FITTING_FUNCTIONS_TO_SCV
	if( vsArgNames.GetSize() == 1 )
#endif // _ADD_FITTING_FUNCTIONS_TO_SCV
	///End SCV_ADD_FITTING_FUNCTIONS
	{
		for ( int ii=0; ii<vsArgNames.GetSize(); ++ii )
		{
			vsArgNames[ii].Empty();
		}
	}
	strTmp.SetTokens(vsArgNames, FUNCTION_ARGUMENTS_SEPARATOR);
	str.Insert(nLeftBracketPos + 1, strTmp);
	///------ End BETTER_FORMAT_FOR_INSERTED_STRING
}

/// Iris 12/30/2008 v8.0992 FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
static bool _is_exist_skip_var_type(LPCSTR lpcszOCVarSkipTypes, LPCSTR lpcszVarTypeList)
{
	string strSkipTypes(lpcszOCVarSkipTypes);
	string strVarTypeList(lpcszVarTypeList);
	
	if(!strSkipTypes.IsEmpty() && !strVarTypeList.IsEmpty())
	{
		for(int nn=0; nn<strSkipTypes.GetNumTokens('|'); nn++)
		{
			if( strVarTypeList.Find(strSkipTypes.GetToken(nn, '|')) != -1 )
			{
				return true;
			}
		}
	}	
	return false;
}
///end FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU

/// Iris 12/30/2008 v8.0992 FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
//static int _menu_Find_LT_functions(vector<string>& vsRetTypes, vector<string>& vsNames, vector<string>& vsArg, int nCategory, bool bSimple = false, vector<string>* pvsCategories = NULL)
static int _menu_Find_LT_functions(vector<string>& vsRetTypes, vector<string>& vsNames, vector<string>& vsArg, int nCategory, bool bSimple = false, vector<string>* pvsCategories = NULL, LPCSTR lpcszOCVarSkipTypes = NULL)
///end FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
{
	if(BFC_RNG == nCategory)
	{
		///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#ifdef __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
		vector<string> vsN = {"grnd", "normal", "poisson", "rnd", "ran","uniform"};
		vsNames = vsN;
		vector<string> vsA = {"()", "(npts, seed)", "(n, mean[, seed])", "(seed)", "(seed)","(npts, seed)"};
		vsArg = vsA;
#else // __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
		///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
		vector<string> vsN = {"grnd", "normal", "poisson", "rnd", "ran","uniform"};
		vsNames = vsN;
		vector<string> vsA = {"()", "(n,n)", "(n,d,n)", "(n)", "(n)","(n,n)"};
		vsArg = vsA;
		///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#endif // __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
		///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
		return vsN.GetSize();
	}
	vector<string> vsArgTypes;
	///------ Folger 01/08/09 v8.0994d SUPPORT_GETTING_NUMBER_OF_DEFAULT_ARGUMENTS_ABOUT_OCLT_FUNCTION
	//int nCount = okutil_find_LT_functions(&vsNames, &vsRetTypes, &vsArg, &vsArgTypes, nCategory, pvsCategories);
	vector<int>		vnNumDefaultArgsTmp;
	int nCount = okutil_find_LT_functions(&vsNames, &vsRetTypes, &vsArg, &vsArgTypes, nCategory, pvsCategories, &vnNumDefaultArgsTmp);
	///------ End SUPPORT_GETTING_NUMBER_OF_DEFAULT_ARGUMENTS_ABOUT_OCLT_FUNCTION

	if(nCategory >= BFC_NAG_SF && nCategory <= BFC_RNG)		// build in functions category, may need to be improved to use shortening argument type for argument name
	{
		for(int ii = 0; ii < nCount; ii++)
		{
			string str = vsArg[ii];
			if(bSimple)
			{
				str.Empty();
				int nToken = vsArg[ii].GetNumTokens(FUNCTION_ARGUMENTS_SEPARATOR);
				for(int jj = 1; jj < nToken; jj++)
					str += ",";	//str = ",,"
			}
			str.TrimLeft('(');
			str.TrimRight(')');
			vsArg[ii] = "(" + str + ")";//vsArg[0] = "(a,b,c)" or "(,,)"
		}
	}
	else	// oc function category
	{
		for(int ii = nCount - 1; ii >= 0; ii--)  
		{			
			vector<string> vsArgNames;
			/// Iris 12/30/2008 v8.0992 FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
			//if(!_check_construct_shortening_argument_name(vsArgTypes[ii], vsArgNames))
			if(_is_exist_skip_var_type(lpcszOCVarSkipTypes, vsArgTypes[ii]) || !_check_construct_shortening_argument_name(vsArgTypes[ii], vsArgNames))
			///end FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
			{
				vsArgTypes.RemoveAt(ii); /// Iris 12/30/2008 v8.0992 FILTER_DISRELATED_FUNC_FROM_WKS_OR_MAT_SET_VALUE_MENU
				vsRetTypes.RemoveAt(ii);
				vsNames.RemoveAt(ii);
				vsArg.RemoveAt(ii);
				if ( pvsCategories )
					pvsCategories->RemoveAt(ii);
				nCount--;
				continue;
			}
			string str;
			if(bSimple)
			{
				int nToken = vsArg[ii].GetNumTokens(FUNCTION_ARGUMENTS_SEPARATOR);
				for(int jj = 1; jj < nToken; jj++)
					str += ",";	//str = ",,"
			}
			else
			{
				///------ Folger 01/08/09 v8.0994d SUPPORT_GETTING_NUMBER_OF_DEFAULT_ARGUMENTS_ABOUT_OCLT_FUNCTION
				if ( ii < vnNumDefaultArgsTmp.GetSize() )
				{
					if ( vnNumDefaultArgsTmp[ii] > 0 )
					{
						int		nPos = vsArgNames.GetSize() - vnNumDefaultArgsTmp[ii];
						if ( nPos == 0 )
							vsArgNames[0].Insert(0, '[');
						else
							vsArgNames[nPos-1] += '[';
						vsArgNames[vsArgNames.GetSize() - 1] += ']';
					}
				}
				///------ End SUPPORT_GETTING_NUMBER_OF_DEFAULT_ARGUMENTS_ABOUT_OCLT_FUNCTION
				str.SetTokens(vsArgNames, FUNCTION_ARGUMENTS_SEPARATOR);
			}
			vsArg[ii] = "(" + str + ")";
		}
	}
	return nCount;
}

static bool _check_construct_shortening_argument_name(string strArgTypes, vector<string>& vsArgNames)
{
	vector<string> vsArgTypes, vsName;
	int nNumArgs = strArgTypes.GetTokens(vsArgTypes, FUNCTION_ARGUMENTS_SEPARATOR);
	if(nNumArgs < 0)
		return false;
	vsArgNames.SetSize(nNumArgs);
	///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#ifdef __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
	static 	vector<string>	vsArgTypeList = {"bool", "double", "int", "uint", "string", "vector<string>", "vector<int>", "matrix", "vector", "vector<double>"};
	static	vector<string>	vsArgNameList = {"b", "d", "n", "n", "str$", "vs", "vn", "mat", "vd", "vd"};

	int nn;
	for(int ii=0; ii<nNumArgs; ii++)
	{
		if((nn = vsArgTypeList.Find(vsArgTypes[ii], 0, true)) < 0)
			return false;
		vsArgNames[ii] = vsArgNameList[nn];
	}
	vector<bool> vbChecked(nNumArgs);
	vbChecked = false;
	for(ii = 0; ii<nNumArgs; ii++)
	{
		if(vbChecked[ii])
			continue;
		
		int nIndex = vsArgNames.Find(vsArgNames[ii], ii+1, true);
		if(nIndex >= 0)		// at least two
		{
			string strName = vsArgNames[ii];
			int nCount = 1;
			nIndex = ii;
			while(nIndex >= 0)
			{
				if(strName.Find('$') >= 0)
					vsArgNames[nIndex] = "str" + nCount + "$";
				else
					vsArgNames[nIndex] = strName + (string)nCount;
				nCount++;

				nIndex = vsArgNames.Find(strName, nIndex+1, true);;
			}
		}
	}
#else // __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
	///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
	for(int ii=0; ii<nNumArgs; ii++)
	{
		string strArgType = vsArgTypes[ii], strArgName;
		if(strArgType.Compare("bool")==0)
			strArgName = "b";
		else if(strArgType.Compare("double")==0)
			strArgName = "d";
		else if(strArgType.Compare("int")==0 || strArgType.Compare("uint")==0)
			strArgName = "n";
		else if(strArgType.Find("string")==0)
			strArgName = "str";
		else if(strArgType.Find("vector<string>")==0)
			strArgName = "vs";
		else if(strArgType.Find("vector<int>")==0)
			strArgName = "vn";
		else if(strArgType.Find("vector<double>")==0)
			strArgName = "vd";
		///Kyle 12/30/2008 v8.0992 OKUTIL_FIND_LT_FUNCTIONS_ADD_MATRIX_AS_RETURN_TYPE
		else if(strArgType.Find("matrix")==0)
			strArgName = "mat";
		///End OKUTIL_FIND_LT_FUNCTIONS_ADD_MATRIX_AS_RETURN_TYPE
		else
			return false;
		
		vsArgNames[ii] = strArgName;
	}
	///Kyle 07/29/2009 QA80-14030 USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
#endif // __STANDARD_NOTATION_FOR_VARIVABLE_NAMES__
	///End USE_STANDARD_NOTATION_FOR_VARIABLE_NAMES_OF_FUNCTION_MENU_IN_SET_COLUMN_VALUES
	return true;
}

#endif //_FUNCTIONS_MENU_H_
