/*------------------------------------------------------------------------------*
 * File Name: NumFunctionOrganizer.h											*
 * Creation: Danice	 															*
 * Purpose: OriginC Source C file												*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 * DG 4/1/05 CREATE																*
 * DG 4/15/05 v8.0217 VC_FUNCTION_SUPPORT										*
 * Jasmine 10/10/05 QA70-8114 v8.0315 ADD_UPPER_LOWER_BOUNDS					*
 * Jasmine 10/11/05 QA70-8114 v8.0315 ADD_INIT_AND_AFTER_FITTING_SCRIPTS		*
 * Jasmine 11/15/05 QA70-8307 v8.0335 ADD_PARAMETERS_SETTINGS					*
 *	CPY 12/10/05 change this file into PCH and move all codes into .h and remove .c
 * Jasmine 03/16/06 v8.0375 UPDATE_NLSF_INI										*
 * Joe 8/16/06 MOVE_NLSF_FUNC_FROM_NLFITSESSION								*
 * Jasmine 10/30/06 CHANGE_FIND_FILE_MECHANISM_TO_NLFIT							*
 * Jasmine 11/02/06 FUNC_AND_FILE_NAME_ONE_TO_ONE								*
 * Jasmine 11/07/06 ALLOW_RENAME_USER_DEFINED_CATEGORY							*
 * Jasmine 11/14/06 CHANGE_BUILT_IN_TO_USER_DEFINED								*
 * Jasmine 11/15/06 INITIALIZATION_SCRIPT_TO_SCRIPT_BEFORE_FITTING				*
 * Jasmine 11/15/06 DELETE_PRECOMPILE_FILES										*
 * Hong 02/25/07 CHECK_VALID_C_FUNC_NAME										*
 * Jasmine 03/01/07 ADD_FO_HELP_TAB												*
 * Jasmine 03/05/07 ADD_EXTERNAL_DLL_SOURCE_EDIT_BOX							*
 * Cheney 2007-5-5 FUNC_FILE_TAB_BROKEN_IN_NLFIT_DLG							*
 *	ML 5/8/2007 WRONG_ARGUMENT_PASSED_PRODUCES_BAD_FITTING_FUNCTION_TREE		*
 * Cheney 2007-5-9 CLEAN_UP_CODE_FOR_NUMFUNC_LOAD								*
 * Jasmine 05/11/07 ADD_DERIVATIVES_CHECKBOX									*
 * Hong 05/17/07 QA80-9784 FIX_FUNCTION_FORM_CONFLICT_BETWEEN_75_80				*
 *	Cheney 2007-5-25 DO_SAVE_FDF												*
 * Jasmine 06/05/07 QA80-9853 NEED_CHECK_STR_COMPILE_PARAM_SCRIPT_FOR_75_FDF	*
 * Jasmine 06/07/07 QA80-9853 SET_FORM_ORIGIN_C_AND_COPILE_1_FOR_BUILT_IN		*
 * Jasmine 06/08/07 NEW_MECHANISM_TO_SAVE_BUILT_IN_FUNCTION						*
 * Jasmine 07/10/07 SET_ID_TO_NEW_DERIVED_PARAMETERS_TREENODE					*
 * Folger 07/11/07 CORRECT_DELETE_BEHAVIOR_ONLY_DELETE_CONTENT_OF_USER_FOLDER_INI*
 * Jasmine 07/25/07 SOME_FUNCTIONS_ARE_NOT_IN_SYSTEM_OR_USER_FILE_FOLDER		*
 * Folger 08/29/07 FIX_BUGS_IN_VECTOR_SIZE										*
 * Folger 09/03/07 SUPPORT_GET_ORIGIN75_PATH_IN_FILE_PUBLISH					*
 * Jasmine 10/08/07 CANNOT_REMOVE_SHARED_FUNCTION								*
 * Arvin 11/14/07 JUST_MOVE_FUNCTION_FROM_NUMFUNCTIONORGANIZER_TO_NLSF_UTILS	*
 * Folger 02/18/08 QA80-10976 ADD_MOVE_ETC_OPERATIONS_IN_FUNCTION_ORGANIZER_CONTEXTMENU
 *	CPY 4/10/08 CLEAN_CODE_NOT_CHECKING_RETURN_VALUE							*
 * Jasmine 07/08/08 QA80-9434 DEFINE_PEAK_FUNC_IN_FO							*
 *	Hong 07/25/08 QA80-11593 FIX_BUILD_IN_FDF_USER_ADDED_DERIVED_PARAMETERS_LOST_IN_FIT_REPORT
 * Jasmine 08/05/08 QA80-11917 KEEP_EXTERNAL_DLL_AFTER_DUPLICATE				*
 *	Kyle 09/24/08 SET_NO_NEED_TO_LOCALIZE										*
 *	ML 9/30/2008 QA70-11852 P2 GET_FDFNAMENODE_BY_DATAID						*
 *	Sophy 11/6/08 QA80-12442 SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE				*
 *	Sophy 11/7/08 QA80-12442 SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE				*
 *	Kyle 11/07/2008 QA80-12509-P1 ADD_PEAK_AMPLITUDE_INTO_CONTROL_SESSION_OF_FO	*
 *	Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
 *	Kyle 03/24/2009 QA80-13291-P4 ADD_NEW_TAB_TO_SHOW_REFERENCES_INFORMATION	*
 *	Kyle 03/26/2009 QA80-13291-P4 NEW_EDIT_BOX_FOR_REFERENCES_INFORMATION		*
 *	Jasmine 04/16/09 QA80-13424 FUNCTION_SOURCE_SHOULD_LEFT_TO_USER				*
 *	Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS					*
 *	Kyle 09/03/2009 QA80-14077 ADD_NODE_ID_FOR_NEW_ADDED_UNIT_SINCE_VC_WILL_GET_VALUES_BY_ID
 *	Kenny 11/11/2009 QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES		*
 *	Folger 11/28/09 QA81-14726-P2 80_HAS_MISSED_CONSTANTS_SECTION				*
 *	Jasmine 06/22/10 ORG-2-S2 WANT_DESTINATION_PATH								*
 *	Jasmine 06/23/10 ORG-2-S4 FUNCTION_WIZARD_ALLOW_USER_DEFINED_FUNC_CHANGE_FORM*
 *	Folger 06/24/10 ORG-390-P3 FDF_FILE_NAME_SHOULD_UPDATE_AFTER_FUNCTION_NAME_CHANGED
 *	Folger 07/13/10 ORG-543 PROMPT_USER_FOR_WHETHER_COPY_FDF_TO_UFF_WHEN_ADD_IN_FO
 *	Folger 07/14/10 ORG-543-P2 FAILED_TO_ADD_FDF_UNDER_ANY_SUBFOLDER_OF_UFF_EXCEPT_FITFUNC
 *	Folger 09/06/2010 ORG-958-P5 FAIED_TO_SAVE_FDF_NAME_NEW_FUNCION_IN_FFW_OPEN_FROM_FO
 *------------------------------------------------------------------------------*/

#pragma PCH

#ifndef _NFO_H_
#define _NFO_H_

#include <OC_Res.h> 
#include <FDFTree.h>
#include "FunctionGroup.h"
#include "nlsf_utils.h"  ///Iris 12/12/05 MOVE_NLF_TO_UTILS_FILE
#include <ocu.h>	///Sophy 11/6/08 QA80-12442 SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE


///DSC 2/8/05 DELETE_NODE_NAME_CONSTANTS these were duplicated. I replaced their use with equivalent constants defined elsewhere.
/*
#define STR_CATEGORY					"Category"
#define STR_FUNCTION					"Function"

#define STR_GENERAL_INFO				"GeneralInformation"
#define STR_FIT_PARAM					"FittingParameters"
#define STR_FORMULA						"Formula"
#define STR_CONSTRAINTS					"Constraints"
#define STR_DERIVED_PARAMS				"DerivedParameters"
#define STR_PARAM_INIT					"ParametersInitialization"
*/
///end DELETE_NODE_NAME_CONSTANTS

#define PARAM_SEPERATE_CHAR				','

#define STR_DEFAULT_FUNCTION_ATTRIB		"DefaultFunction"
#define STR_FDF_DELETE_FILE_FOLDER			"delete"
#define STR_FUNCTION_FORM_SHARE_FILE_ATTRIB		"ShareFunction"
//#define STR_CURRENT_SHARE_STATE_ATTRIB			"ShareSign"
#define STR_SIMULATE_SECTION_INIT		"Section_init"

#define STR_FUNCTION_TYPE_BUILD_IN		"Built-in"
#define STR_FUNCTION_TYPE_EXTERN_DLL 	"External DLL"
#define STR_FUNCTION_TYPE_USER_DEFINE	"User-Defined" //"user-defined" //see onlsf8.rc IDS_OPTION_PARA_NAME_USER
///Jasmine 03/05/07 ADD_EXTERNAL_DLL_SOURCE_EDIT_BOX
#define STR_FUNCTION_SOURCE				"Function Source"

#define STR_NO_DLL_SOURCE				"N/A"
///Kyle 09/24/08 SET_NO_NEED_TO_LOCALIZE
//#define STR_FUNCTION_DLL_SOURCE			_LE("DLL")
#define STR_FUNCTION_DLL_SOURCE			"DLL"
///End SET_NO_NEED_TO_LOCALIZE
///End ADD_EXTERNAL_DLL_SOURCE_EDIT_BOX
/// Hong 05/17/07 QA80-9784 FIX_FUNCTION_FORM_CONFLICT_BETWEEN_75_80
/* move to FDFTree.h for share use
#define STR_FUNCTION_FORM_ORIGIN_C		"Origin C"
#define STR_FUNCTION_FORM_EQUATIONS		"Equations"
#define STR_FUNCTION_FORM_EXPRESSION	"Expression"
#define STR_FUNCTION_FORM_Y_SCRIPT		"Y-Script"
*/
/// end FIX_FUNCTION_FORM_CONFLICT_BETWEEN_75_80

#define STR_FIT_FUNCTION_FILE_EXT		"FDF"
///DG CENTRALIZE_XFO_AND_NFO
#define STR_FIT_FUNCTION_FILE_EXT_SPEC	"[Function (*.FDF)] *.FDF"
/// Hong 11/06/07 v8.0741 MORE_LOCALIZATION
//#define STR_FIT_FUNCTION_LABEL			"Fitting Functions (*."STR_FIT_FUNCTION_FILE_EXT")"
#define STR_FIT_FUNCTION_LABEL			_LE("Fitting Functions (*.FDF)")
/// end MORE_LOCALIZATION
///end CENTRALIZE_XFO_AND_NFO

#define NOTIFY_FDF_FILE_CHANGE	okutil_find_files_from_map(NULL, NULL, SUPPORTFILE_FDF, FF_UPDATE_MAP); //okutil_find_file(NULL, SUPPORTFILE_FDF);

///DG CLEAN_DUPLICATE_MORE
#define	STR_FIT_FUNCTION_NODE			"FitFunctions"
///end CLEAN_DUPLICATE_MORE

#define STR_SIMULATE_NODE				"SimulateSetting"
#define STR_CURVE_NODE					"Curve"

//Function structure in GUI

///DSC 2/7/05 v8.0190 CONVERT_STRING_TO_TAG_NAME // see onlfs8.rc
// #define STR_FUNC_NAME						"Name"
//#define STR_FUNC_TYPE						"Type"
#define STR_FUNC_NAME						_LE("Function Name")
#define STR_FUNC_FORM						_LE("Function Form")
#define STR_FUNC_TYPE						_LE("Function Type")
///Jasmine 05/11/07 ADD_DERIVATIVES_CHECKBOX
#define STR_FUNC_ENABLE_DERIVATIVES			_LE("Derivatives")
#define STR_FUNC_ANALYTICAL_DERIVATIVES		"Analytical Derivatives for User-Defined"
#define	IDS_OPTION_USERDEF_ANALYT_DERIV		23561		//temp
#define	IDS_SECT_DERIVED_PARAMETERS			23572		///Jasmine 07/10/07 SET_ID_TO_NEW_DERIVED_PARAMETERS_TREENODE
///Kyle 09/03/2009 QA80-14077 ADD_NODE_ID_FOR_NEW_ADDED_UNIT_SINCE_VC_WILL_GET_VALUES_BY_ID
#define IDS_SECT_DERIV_PARA_SETTINGS		23582
#define	IDS_PARA_UNIT						23583
///End ADD_NODE_ID_FOR_NEW_ADDED_UNIT_SINCE_VC_WILL_GET_VALUES_BY_ID

///End ADD_DERIVATIVES_CHECKBOX

///Jasmine 07/14/10 ORG-486-S1 CENTRALIZE_PEAK_ATTRIB_TO_NLFIT
#define	IDS_CONTROL_NUM_REPLICATES		23544
#define	IDS_CONTROL_REPLICATE_FROM		23545
#define	IDS_CONTROL_REPLICATE_UNIT		23546


#define	IDS_CONTROL_PEAK_CENTER_ARG_INDEX	23575
#define	IDS_CONTROL_PEAK_WIDTH_ARG_INDEX	23576

#define	IDS_CONTROL_PEAK_CENTER_ARG_INDEX_2	23577
#define	IDS_CONTROL_PEAK_WIDTH_ARG_INDEX_2	23578

#define	IDS_CONTROL_PEAK_AMPLITUDE_ARG_INDEX	23580
///End CENTRALIZE_PEAK_ATTRIB_TO_NLFIT

#define	IDS_SECT_CONSTANTS				23511		///Jasmine 07/23/10 ORG-623-P2 NEWLY_CREATED_CONSTANTS_NODE_HAS_NO_ID_AND_FAIL_TO_WORK

///Joe 8/16/06 MOVE_NLSF_FUNC_FROM_NLFITSESSION
//#define STR_FUNC_GENERAL_INFO				"General Information"
//#define STR_FUNC_FIT_PARAM					"Fitting Parameters"
//#define STR_FUNC_FORMULA					"Formula"
//#define STR_FUNC_CONSTRAINTS				"Constraints"
//#define STR_FUNC_SCRIPT						"Script"
///End MOVE_NLSF_FUNC_FROM_NLFITSESSION
#define STR_FUNC_NUM_IND_VARS				"Number of Independent Variables"
#define STR_FUNC_NUM_DEP_VARS				"Number of Dependent Variables"
#define STR_FUNC_NUM_PARAMS					"Number of Parameters"
#define STR_FUNC_DERIVED_PARAMS				_LE("Derived Parameters")
#define STR_FUNC_DERIVED_PARAM_SETTINGS		_LE("Derived Parameter Settings")		///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
#define STR_FUNC_AFTER_FITTING				"After Fitting"
#define STR_FUNC_PREVIEW					"Function Preview"

///Jasmine 03/21/06 COMMENT_DUPLICATED_CODES
/*
#define STR_FUNCTION_TYPE_Y_SCRIPT			"Y-Script"
#define STR_FUNCTION_TYPE_EXPRESSION		"Expression"
#define STR_FUNCTION_TYPE_EQUATIONS			"Equations"
#define STR_FUNCTION_TYPE_ORIGINC			"Origin C"
#define STR_FUNC_BUILT_IN 					"Built-in"
#define STR_FUNC_EXTERN_DLL     			"External DLL"
*/
///End COMMENT_DUPLICATED_CODES
#define STR_FUNC_NAMES						"Names"
#define	STR_PARAM_SETTING_MEANINGS			"Meanings"
#define STR_PARAM_UNIT						"Unit"					///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
///Jasmine 10/10/05 QA70-8114 v8.0315 ADD_UPPER_LOWER_BOUNDS
#define STR_LOWER_BOUNDS					"Lower Bounds"
#define STR_UPPER_BOUNDS					"Upper Bounds"
///End ADD_UPPER_LOWER_BOUNDS

///Jasmine 10/11/05 QA70-8114 v8.0315 ADD_INIT_AND_AFTER_FITTING_SCRIPTS
#define STR_INIT_SCRIPT						"INITIALIZATIONS"
#define STR_SCRIPT_AFTER_FITTING			"AFTER FITTING"
///End ADD_INIT_AND_AFTER_FITTING_SCRIPTS

///Joe 8/16/06 MOVE_NLSF_FUNC_FROM_NLFITSESSION
//#define STR_FUNC_SCRIPT						"Script"   
///End   MOVE_NLSF_FUNC_FROM_NLFITSESSION
#define STR_FUNC_INITIALIZATIONS 			"Initializations"
#define STR_FUNC_CONSTANTS					_LE("Constants")
#define STR_FUNC_COMPILE_FUNC				"Compile Function"


#define STR_FUNC_COMPILE						"Compile"
#define STR_FUNC_PARAM_INIT_COMPILE				"CompileParametersInitialization"
#define STR_FUNC_ON_PARAM_CHANGE_SCRIPT_ENABLE	"OnParamChangeScriptsEnabled"



#define	ORIGINC_FUNCTION_TYPE_IN_COMBO		STR_FUNCTION_FORM_ORIGIN_C//STR_FUNCTION_TYPE_ORIGINC	///jasmine 03/21/06 ADD_FUNC_TYPE



///end CONVERT_STRING_TO_TAG_NAME

/// Hong 11/06/07 v8.0741 MORE_LOCALIZATION
//#define STR_FUNC_FILE_NAME					"File Name(."STR_FIT_FUNCTION_FILE_EXT")"
#define STR_FUNC_FILE_NAME					_LE("File Name(.FDF)")
/// end MORE_LOCALIZATION
#define STR_FUNC_DESCRIPTION				_LE("Brief Description")
#define STR_FUNC_REFERENCES					_LE("References")				///Kyle 03/26/2009 QA80-13291-P4 NEW_EDIT_BOX_FOR_REFERENCES_INFORMATION
#define STR_FUNC_INDEPENDENT_VARS			_LE("Independent Variables")
#define STR_FUNC_DEPENDENT_VARS				_LE("Dependent Variables")
#define STR_FUNC_PARAMETER_NAMES			_LE("Parameter Names")
#define STR_FUNC_FUNCTION					_LE("Function")
#define STR_FUNC_CONSTRAINTS				_LE("Constraints")
#define STR_FUNC_EQUATION_PREV				"Equation Prev"
#define STR_FUNC_CURVE_PREV					"Curve Prev"
#define STR_FUNC_SHARE_INFO					"Share Function?"
/// YuI 7/22/04 v7.5102 QA70-6404 NEW_FUNCTION_MANAGER
#define	STR_FUNC_PARA_INIT					"Parameters Initialization"
#define	STR_FUNC_PARA_INIT_GUI				_LE("Parameter Initialization")
///end NEW_FUNCTION_MANAGER

/// YuI 09/07/05 NLSF_CODE_BUILDER_COMMUNICATION_FIX
#define	STR_FUNC_OC_FUNC_HEADER				_LE("Origin C Function Header")
#define	STR_FUNC_OC_PARA_INIT_HEADER		_LE("Origin C Parameter Initialization Header")
/// end NLSF_CODE_BUILDER_COMMUNICATION_FIX

///Jasmine 11/15/05 QA70-8307 v8.0335 ADD_PARAMETERS_SETTINGS
/*///Jasmine 10/10/05  QA70-8114 v8.0315 ADD_UPPER_LOWER_BOUNDS
#define STR_FUNC_PARAMETER_LOWER_BOUNDS		"Lower bounds of parameters"
#define STR_FUNC_PARAMETER_UPPER_BOUNDS		"Upper bounds of parameters"
///End ADD_UPPER_LOWER_BOUNDS
*/
#define STR_FUNC_PARAMETERS_SETTINGS		_LE("Parameter Settings")
///End ADD_PARAMETERS_SETTINGS

///Jasmine 10/11/05 QA70-8114 v8.0315 ADD_INIT_AND_AFTER_FITTING_SCRIPTS
///Jasmine 11/15/06 INITIALIZATION_SCRIPT_TO_SCRIPT_BEFORE_FITTING
//#define STR_FUNC_INIT_SCRIPT				"Initialization Scripts"
#define STR_FUNC_SCRIPT_BEFORE_FITTING		_LE("Script Before Fitting")
#define	STR_FUNC_SCRIPT_AFTER_FITTING		_LE("Script After Fitting")
///End ADD_INIT_AND_AFTER_FITTING_SCRIPTS

///Jasmine 03/02/07 ADD_ENABLE_PARA_INIT_AND_ENABLE_CONSTRAINTS
#define STR_FUNC_CONTROLS					"Controls"
#define STR_FUNC_GENERAL_CONSTRAINTS		"General Linear Constraints"
//#define STR_FUNC_INIT_SCRIPT				"Initialization scripts"
#define STR_COMPILE_PARAM_SCRIPT			"Compile On Param Change Script"	///Jasmine 06/05/07 QA80-9853 NEED_CHECK_STR_COMPILE_PARAM_SCRIPT_FOR_75_FDF
#define STR_FUNC_ENABLE_PARAMETERS_INIT		"Enable Parameters Initialization"

#define STR_FUNC_ENABLE_INIT_SCRIPT			_LE("Enable Auto Initialization") //"Initialization Scripts"
#define STR_FUNC_PARAM_SCRIPT_USE_ORIGINC	_LE("Use OriginC") /// Iris 4/30/2008 QA80-11474 ADD_USE_ORIGINC_CHECKBOX_FOR_PARAM_INIT_SCRIPT
#define STR_FUNC_ENABLE_CONSTRAINTS			_LE("Enable Constraints") //"General Linear Constraints"
///End ADD_ENABLE_PARA_INIT_AND_ENABLE_CONSTRAINTS
///end MOVED_CONSTANTS_TO_FUNC_ORG_H

///Jasmine 07/08/08 QA80-9434 DEFINE_PEAK_FUNC_IN_FO
///Arvin 09/18/07 QA70-10356 PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
#define STR_OFFSET_PARAM_NAME_PFM				"y0"
#define	STR_OFFSET_PARAM_NAME_SPFM				"z0"
///END 	PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG

#define STR_DUPLICATE_NUM					"Number Of Duplicates"
#define STR_DUPLICATE_OFFSET				"Duplicate Offset"
#define STR_DUPLICATE_UNIT					"Duplicate Unit"
///End DEFINE_PEAK_FUNC_IN_FO

#define STR_PEAK_FUNC_CHECK_E				_LE("Peak Function")

///Sophy 7/27/2010 ORG-591-P3 PEAKFUNCTION_CHECKBOX_STATE_NOT_KEEP_FROM_FO_TO_FFW_WHEN_NOT_VALID_PEAKFUNCTION		
#define	STR_PEAK_CHECK_ATTRIB				"PeakFunction"
///end PEAKFUNCTION_CHECKBOX_STATE_NOT_KEEP_FROM_FO_TO_FFW_WHEN_NOT_VALID_PEAKFUNCTION

#define STR_CATEGORY_ATTRIB					"Category"	///DG CENTRALIZE_XFO_AND_NFO

#define	STR_NEW_DOT_DOT_DOT					_L("<New...>")	///Jasmine 05/18/07 ADD_NEW_AT_LIST_BOTTOM_TO_OPEN_FO

///Jasmine 03/01/07 ADD_FO_HELP_TAB
enum{
	FUNC_TREE_FUNC_NAME_ID = 1,
	FUNC_TREE_FILE_NAME_ID, 
	FUNC_TREE_DESCRIPTION_ID,
	FUNC_TREE_FUNC_TYPE_ID,
	FUNC_TREE_FUNC_SOURCE_ID,
	FUNC_TREE_INDEPENDENT_VARS_ID,
	FUNC_TREE_DEPENDENT_VARS_ID,
	FUNC_TREE_PARAMETER_NAMES_ID,
	FUNC_TREE_FUNC_FORM_ID,
	FUNC_TREE_ENABLE_DERIVATIVES_ID,	///Jasmine 05/11/07 ADD_DERIVATIVES_CHECKBOX
	FUNC_TREE_FUNCTION_ID,
	FUNC_TREE_OC_FUNC_HEADER_ID,
	FUNC_TREE_OC_PARA_INIT_HEADER_ID,
	FUNC_TREE_IS_PEAK_FUNC_ID,			///Jasmine 07/08/08 QA80-9434 DEFINE_PEAK_FUNC_IN_FO
	FUNC_TREE_PARAMETERS_SETTINGS_ID,
	FUNC_TREE_ENABLE_PARA_INIT_ID,
	FUNC_TREE_PARAM_USE_ORIGINC_ID,	/// Iris 4/30/2008 QA80-11474 ADD_USE_ORIGINC_CHECKBOX_FOR_PARAM_INIT_SCRIPT
	FUNC_TREE_PARA_INIT_ID,
	FUNC_TREE_INIT_SCRIPT_ID,
	FUNC_TREE_SCRIPT_AFTER_FITTING_ID,
	FUNC_TREE_CONSTANTS_ID,				///Jasmine 11/24/09 QA80-14726 80_HAS_MISSED_CONSTANTS_SECTION
	FUNC_TREE_ENABLE_CONSTRAINTS_ID,
	FUNC_TREE_CONSTRAINTS_ID,
	FUNC_TREE_DERIVED_PARAMS_ID,
	FUNC_TREE_REFERENCES_ID,			///Kyle 03/26/2009 QA80-13291-P4 NEW_EDIT_BOX_FOR_REFERENCES_INFORMATION
	FUNC_TREE_DERIV_PARAM_SETTINGS_ID,		///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
	
};
///End ADD_FO_HELP_TAB
/*
enum
{
	NLSF_SECTION_SAVE,
	NLSF_SECTION_DEL
};
*/
enum
{
	Y_SCALE_FIXED,
	Y_SCALE_AUTORESCALE
};

#define STR_MSG_CAPTION			_L("Attention")
#define STR_MSG_COPY_FILE		_L("Would you like selected file(s) to be copied to the default folder?\nSelect 'No' to use file(s) from the current location.")

#define	STR_MSG_FO_HOW_TO_SET_PEAK_ATTRIB		_L("Please set the Peak Attributes by clicking the button to the right of the Parameter Settings edit box.")///Jasmine 07/14/10 ORG-540-P3

#define ERROR_ATTENTION_DIAOLG				_L("Attention!")
#define STR_CANCEL_BTN_WARN_MESSAGE			_L("Save all the changes?")

/// ML 12/3/2004 QA70-6585 SETTING_NLSFTREE_ORIGINC_COMPILE
//Commetnts last updated by Frank on 1/11/05
/**
		find the correct range column range, row range, worksheet , range name out.
	Paramaters:
		trFDF =[input] Function tree.
		bSet =[input] If true, function will compile when using function NumericFunction::Evaluate.
	Example1:
		#include <..\originlab\functiongroup.h>
		void nlf_tree_set_oc_compile_ex1()
		{	
			Tree	tr;
			TreeNode trFunction = tr.AddNode("sine");
			NLFunctionList NFOList;
			string strFunctionName = "sine";
			string strCategoryName = "Waveform";
			NFOList.GetFunctionDetail(trFunction,strFunctionName, strCategoryName);
			nlf_tree_set_oc_compile( trFunction, true);
		}
	Return:
*/
void	nlf_tree_set_oc_compile(TreeNode &trFDF, bool bSet)
{
	int		nVal = bSet ? 1 : 0;
	trFDF.CompileFunction.Compile.nVal = nVal;
	trFDF.CompileFunction.ID = 23563;				// IDS_SECT_COMPILE
	trFDF.CompileFunction.Compile.ID = 23564;		// IDS_COMPILE
}
/**
		get the keys and values from sepcial section name from NLSF.ini file.
	Paramaters:
		lpcszSection = [input]section name of nlsf.ini want to read.
		saKeys =[output]Section keys.
		saValues =[output]Section keys value.
		pnDefaultSel =[output]default function of nlsf.ini function cateogry.
		nIniPath =[input] folder flag, you can use USER_FOLDER, ALL_USER_FOLDER, SYS_FOLDER.
	Example1:
		void nlf_get_section_keys_and_values_ex1()
		{	
			vector<string> vsFunction, vsFile;
			bool bRet = nlf_get_section_keys_and_values( "Waveform",vsFunction, vsFile );
		}
	Return:
		Return true if get it.
*/
///Arvin 11/14/07 JUST_MOVE_FUNCTION_FROM_NUMFUNCTIONORGANIZER_TO_NLSF_UTILS
//bool nlf_get_section_keys_and_values(LPCSTR lpcszSection, vector<string> &saKeys, vector<string> &saValues =NULL ,int* pnDefaultSel =NULL, int nIniPath = ORIGIN_PATH_USER)//=NULL = NULL, 
//{
	//int	nDefaultSel = 0;
	//saKeys.RemoveAll();
	//
	//string strNLSFIniFilePath =nlf_get_ini_filepath(nIniPath);
	////if(!strNLSFIniFilePath.IsFile())
		////return false;
	//
	//INIFile iniNLSF(strNLSFIniFilePath);// when full path given, no need to worry about 2nd arg
	//
	//
	//int nKeysCount = iniNLSF.GetKeyNames(saKeys, lpcszSection);
	////saValues.SetSize(nKeysCount);
	//
	//if(saValues != NULL)
	//{
		//saValues.RemoveAll();
		//for(int nIndex = 0 ; nIndex < nKeysCount ; nIndex++)
			//saValues.Add( iniNLSF.ReadString(lpcszSection, saKeys[nIndex]));
	//}
	//
	//if(pnDefaultSel != NULL )
	//{
		//int nDefaIndex = saKeys.Find("Default Function" , 0 , true);
		//if(nDefaIndex < 0 )
		//{
			//nDefaultSel = 0;
		//}
		//else
		//{
			//string strDefFunction;
			////strDefFunction = iniNLSF.ReadString( strSection , vsSectionkeys[ nDefaIndex ] );
			//strDefFunction = saValues[nDefaIndex];
			//saKeys.RemoveAt( nDefaIndex , 1);
			//saValues.RemoveAt( nDefaIndex , 1);
			//nDefaultSel = saKeys.Find( strDefFunction , 0 , true );
		//}
		//*pnDefaultSel = nDefaultSel;
	//}
	//return true;
//}
///END JUST_MOVE_FUNCTION_FROM_NUMFUNCTIONORGANIZER_TO_NLSF_UTILS

//class NLFunctionList
class NLFunctionList : public FunctionOrganizer
{
public:
	NLFunctionList() {;}
	~NLFunctionList() {;}
	
	/// Kenny 11/12/2009 QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
	//int			GetCategoryList(vector<string> &vsCategorys);
	int			GetCategoryList(vector<string> &vsCategorys, vector<int>& vnSeparatorIndices = NULL);
	/// End QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
	
	///DG 4/4/05
	bool		IsAllowedMultiLevelCategory() { return false; }
	bool		IsDetailTreeView() { return false; }
	bool		IsAllowSimulation() {return true;}	///DG CLOSE_FO_SIMULATION_FOR_XF
	///end

	///DG 12/31/04 NEW_MECHANISM_FOR_FUNCTION_LOAD : new mechanism will load all function include sys, user, all user(shared)
	int 		GetFunctionList(TreeNode &trCategory);
	int			GetFunctionList(vector<string> &vsFunctions, vector<string> &vsFunctionFullFileNames, vector<bool> &vbShared, LPCSTR lpcstrCategoryName , int *nDefaultFunctionIndex = NULL);
	string 		GetFunctionName(LPCSTR lpcstrFilePath);///Jasmine 11/02/06 FUNC_AND_FILE_NAME_ONE_TO_ONE	
	string 		GetFunctionName(TreeNode& trFunction, bool bPrefixIncluding = false);
	//void 		SetFunctionName(TreeNode& trFunction, string strFunctionName, string& strFilePath = NULL);  ///DG 2/6/05 : Don't pass NULL to refer
	void 		SetFunctionName(TreeNode& trFunction, string strFunctionName, const int *pnPath=NULL);
	///Cheney 2007-5-9 CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
	/////Cheney 2007-5-5 FUNC_FILE_TAB_BROKEN_IN_NLFIT_DLG
	//bool		Load(TreeNode &trFunction, string strFunctionName, string &strCategoryName);
	bool		LoadEx(TreeNode &trFunction, LPCSTR lpcszFunctionName, string &strCategoryName, bool bLoadFDF = true);
	/////end FUNC_FILE_TAB_BROKEN_IN_NLFIT_DLG
	///end CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
	//virtual
	///DG 4/15/05 VC_FUNCTION_SUPPORT
	//int			GetCategoryList(TreeNode &trCategoryList, bool bGetFunctionList = true);
	int			GetSupportFile();
	///end VC_FUNCTION_SUPPORT 
	int			GetMultiOpenBox(vector<string>& vsFilePaths, LPCSTR lpcszPath=NULL);
	///Cheney 2007-5-9 CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
	/////Cheney 2007-5-5 FUNC_FILE_TAB_BROKEN_IN_NLFIT_DLG
	////bool		Load(TreeNode &trFunction, LPCSTR lpcszFullpathFilename, string strName="");
	//bool		Load(TreeNode &trFunction, LPCSTR lpcszFullpathFilename, string strName="", bool bLoadFDF = true);
	bool		Load(TreeNode &trFunction, LPCSTR lpcszFullpathFilename, LPCSTR lpcszFunctionName = NULL, bool bLoadFDF = true);
	/////end FUNC_FILE_TAB_BROKEN_IN_NLFIT_DLG
	///end CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
	//------ Folger 09/03/07 SUPPORT_GET_ORIGIN75_PATH_IN_FILE_PUBLISH
	//string		GetFunctionFolder(int nPath=SYS_FOLDER, string strSubFolder="");
	virtual string		GetFunctionFolder(int nPath=SYS_FOLDER, string strSubFolder="");
	//------ End SUPPORT_GET_ORIGIN75_PATH_IN_FILE_PUBLISH
	string		GetFunctionFileFullPath(string strFileName, int nPath=SYS_FOLDER, string strSubFolder="");
	int			FindCategoryPath(const TreeNode &trCagetory, vector<int> &vnExistPathType);	///DG 3/3/05
public : 
	//visit function detail
	TreeNode 	GetGeneralInfo(const TreeNode& tr, bool bAddWhenNoExist=true, string strSubNode = "");
	void    	SetGeneralInfo(TreeNode& tr, bool bAddWhenNoExist, string strSubNode, string strSubNodeVal);  ///Iris 01/18/05 CLEANUP_CONSTRUCT_FUNC_GUITREE
	bool		SetTreeNodeVal(TreeNode& trDest, LPCSTR lpcszLabel, bool bAddWhenNoExist, const TreeNode& trSrc);///CPY 2/7/05 v8.0189 SET_TREE_NODE_VALUE
	bool		SetTreeNodeVal(TreeNode& trDest, LPCSTR lpcszLabel, bool bAddWhenNoExist, LPCTSTR lpszValue);///DSC 2/9/2005 v8.0191 SET_TREE_NODE_VALUE
	TreeNode 	GetFittingPara(const TreeNode& tr, bool bAddWhenNoExist=true, string strSubNode = "");
	TreeNode 	GetFormula(const TreeNode& tr, bool bAddWhenNoExist=true, string strSubNode = "");
	TreeNode	GetConstraints(const TreeNode& tr, bool bAddWhenNoExist=true, string strSubNode="");	///Danice 12/27/04
	///------ Folger 11/28/09 QA81-14726-P2 80_HAS_MISSED_CONSTANTS_SECTION
	TreeNode	GetConstants(const TreeNode& tr, bool bAddWhenNoExist=true, string strSubNode="");
	///------ End 80_HAS_MISSED_CONSTANTS_SECTION
	
	/// YuI 09/07/05 NLSF_CODE_BUILDER_COMMUNICATION_FIX
	TreeNode 	GetFunctionOCHeader(const TreeNode& tr, bool bAddWhenNoExist=true, string strSubNode = "");
	TreeNode 	GetParaInitOCHeader(const TreeNode& tr, bool bAddWhenNoExist=true, string strSubNode = "");
	/// end NLSF_CODE_BUILDER_COMMUNICATION_FIX
	
	//--- CPY 1/7/05 DERIVED_PARAMETERS_READ_SAVE_PROBLEM
	//TreeNode 	GetDerivedParams(const TreeNode& tr, bool bAddWhenNoExist=true, const string strSubNode = "text");
	TreeNode 	GetDerivedParams(const TreeNode& tr, bool bAddWhenNoExist=false, bool bAddSubNode = false)
	{
		string strSubNode = bAddSubNode? "text":"";
		// return GetNodeCheckAdd(tr, STR_DERIVED_PARAMS, bAddWhenNoExist, strSubNode);
		return GetNodeCheckAdd(tr, STR_FUNC_DERIVED_PARAMS, bAddWhenNoExist, strSubNode);
	}
	//---
	TreeNode	GetDeriParaSettings(const TreeNode& tr, bool bAddWhenNoExist=true, string strSubNode = "");		///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
	TreeNode	GetControls(const TreeNode& tr, bool bAddWhenNoExist=true, string strSubNode = "");	///Jasmine 03/02/07 ADD_ENABLE_PARA_INIT_AND_ENABLE_CONSTRAINTS
	TreeNode 	GetParaInit(const TreeNode& tr, bool bAddWhenNoExist=true, string strSubNode = "Script");
	TreeNode 	GetScripts(const TreeNode& tr, LPCSTR lpcszNode, bool bAddWhenNoExist=true, string strSubNode = "Script");///Jasmine 10/11/05 QA70-8114 v8.0315 ADD_INIT_AND_AFTER_FITTING_SCRIPTS
	TreeNode 	GetCompile(const TreeNode& tr, bool bAddWhenNoExist = true, string strSubNode = STR_FUNC_COMPILE);/// Iris 4/30/2008 QA80-11474 ADD_USE_ORIGINC_CHECKBOX_FOR_PARAM_INIT_SCRIPT
	
	TreeNode 	GetParaSettings(const TreeNode& tr, bool bAddWhenNoExist=true, string strSubNode = "");	///Jasmine 11/15/05 QA70-8307 v8.0335 ADD_PARAMETERS_SETTINGS
	
	/// Hong 05/17/07 QA80-9784 FIX_FUNCTION_FORM_CONFLICT_BETWEEN_75_80	
	bool	UpdateCompileByFunctionForm(TreeNode &trFunction);
	/// end FIX_FUNCTION_FORM_CONFLICT_BETWEEN_75_80

	///Jasmine 06/23/10 ORG-2-S4 FUNCTION_WIZARD_ALLOW_USER_DEFINED_FUNC_CHANGE_FORM
	bool 		IsSysFunc(TreeNode trFunc);
	bool		IsCurrentUserShared(TreeNode trFunctionDetail, bool &bSharedFunction);
	///End FUNCTION_WIZARD_ALLOW_USER_DEFINED_FUNC_CHANGE_FORM
	
	///Jasmine 07/14/10 ORG-486-S1 CENTRALIZE_PEAK_ATTRIB_TO_NLFIT
	bool 		CheckCopyPeakAttributeNodes(bool bPeakFunction, const TreeNode& trSource, TreeNode& trTarget);
	///End CENTRALIZE_PEAK_ATTRIB_TO_NLFIT
protected:
	TreeNode	LoadCategoryStructure(TreeNode &trCategory);	///DG 4/7/05
	
private:
	int			searchFunctionByFileName(string strFunctionFileName, bool bSharedFunction, string strFunctionName, vector<string> &vsOutputFunctionName, vector<string> &vsOutputFullFileNames);	
	TreeNode	addListNode(TreeNode &tr, string strtagName, string strLabelName, string strFileName="", bool bShareFunction=false);	
};

class NumFunctionOrganizer : public NLFunctionList
{
public:
	NumFunctionOrganizer();
	~NumFunctionOrganizer();
	
	bool 	Load(TreeNode &trFunction);
	///Sophy 11/6/08 QA80-12442 SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
	//bool 	SaveToFile(TreeNode &trFunction, LPCSTR lpcszFullpathFilename = NULL);
	///Jasmine 06/22/10 ORG-2-S2 WANT_DESTINATION_PATH
	//bool 	SaveToFile(TreeNode &trFunction, LPCSTR lpcszFullpathFilename = NULL, string* pstrErr = NULL );
	bool 	SaveToFile(TreeNode &trFunction, LPCSTR lpcszFullpathFilename = NULL, string* pstrErr = NULL, string* pstrDestinationFile = NULL);
	///End WANT_DESTINATION_PATH
	///end SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
	//virtual
	bool	New(TreeNode &trFunction, string strName="");
	//Cheney 2007-5-9 CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
	//bool	Load(TreeNode &trFunction, LPCSTR lpcszFullpathFilename, string strName="");
	bool	Load(TreeNode &trFunction, LPCSTR lpcszFullpathFilename, LPCSTR lpcszFunctionName = NULL, bool bLoadFDF = true);
	///end CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
	bool	Add(TreeNode &trFunction, LPCSTR lpcszFullpathFilename, string strName="");
	bool 	Delete(TreeNode &trFunction, bool bRemoveFile = true);
	bool	Duplicate(TreeNode &trFunction, TreeNode trSource, string strName="");
	///Sophy 11/6/08 QA80-12442 SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
	//bool	Save(TreeNode &trFunction, LPCSTR lpcszJunk = NULL);
	///Jasmine 06/22/10 ORG-2-S2 WANT_DESTINATION_PATH
	//bool	Save(TreeNode &trFunction, LPCSTR lpcszJunk = NULL, string* pstrErr = NULL );
	bool	Save(TreeNode &trFunction, LPCSTR lpcszJunk = NULL, string* pstrErr = NULL, string* pstrDestinationFile = NULL);
	///End WANT_DESTINATION_PATH
	///end SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
	//bool	SaveToCategory(TreeNode &trFunction, LPCSTR lpcszCategory);
	
	bool	NewCategory(TreeNode &trCategory, string strName="");
	int		LoadCategory(TreeNode &trCategory, vector<int> &vnInvalidFunctionIndex);
	bool 	DeleteCategory(TreeNode &trCategory, bool bRemoveFile = true);
	bool	DuplCategory(TreeNode &trCategory, TreeNode trSource, string strName="");
	bool	SaveCategoryName(TreeNode &trCategory, string strName);
	
	bool	SaveSimulateTree(TreeNode trFunction);
	///end CENTRALIZE_XFO_AND_NFO
	
	bool 	MoveDeleteFunctionFileToFolder(TreeNode &trDel);

	//bool 	CheckFdfFileExist( string &strFileName, bool bCreateNameWhenNoExist = false);
	bool 	CheckGetFunctionFilename( string &strFileName, bool bCreateNameWhenNoExist = false);	
	bool 	Reset(TreeNode& trFunction);	///Jasmine 06/11/07 INTERACTIVE_CHANGE_SAVING_BETWEEN_FO_AND_NLFIT
	bool	UpdateFunctionToNLSF(LPCSTR lpcszCategoryName, LPCSTR lpcszNewName, LPCSTR lpcszOldName, LPCSTR lpcszFileName, int nINIPath);
	bool	UpdateCategoryToNLSF(LPCSTR lpcszNewName, LPCSTR lpcszOldName, int nINIPath);
	///Jasmine 05/13/10 ORG-2 MOVE_FUNCTION_TO_BASE_CLASS_FOR_FITFUNCWIZ
	string 	CreateNewFunctionName(TreeNode &trFitFunctions, string strAttribute, string strPrefix, string strPostfix);
	
	string	GetSubNodeNameList(const TreeNode trSource, const string strSubNode, char chDelimiter);
	///End MOVE_FUNCTION_TO_BASE_CLASS_FOR_FITFUNCWIZ
private:
	void 	checkAndUpdateFunctionPreviewString(TreeNode &trFunction, LPCSTR lpcstrFunctionFile);
	bool 	changeFunctionShareState(TreeNode &trFunction,LPCSTR lpcstrCategoryName,  bool bChangeState, bool bUnsharing = false);
	//bool 	changeBuildInToUserDefine(TreeNode &trFunction);
	bool 	changeFunctionTypeToUserDefine(TreeNode &trFunction);
	bool 	CreateTempFileOfFunction(TreeNode &trNewFunction ,string strFunctionName, bool bCheck = true);///Jasmine 11/02/06 FUNC_AND_FILE_NAME_ONE_TO_ONE  
	void	createNewFileName(string &strNewFuncFilename) ;// 1
	//bool 	SetFunctionAttributes( TreeNode &trFunctionDim, LPCSTR lpcszFileName , bool bKeepOldFile = false); ///DG ADD_FULL_PATH_TO_FILE_NAME
	
	bool	canRemoveFromIniFile(TreeNode trFunction); ///DG 2/23/05
private:
	//vector<int> 		m_vnIndexRemove;		///DG CENTRALIZE_XFO_AND_NFO
	vector<string>		m_vsTempFileNoSave;
};

///------ Folger 09/06/2010 ORG-958-P5 FAIED_TO_SAVE_FDF_NAME_NEW_FUNCION_IN_FFW_OPEN_FROM_FO
typedef	bool (*FUNC_OPEN_FFW)(TreeNode& trFunc, HWND hWndParent = NULL, int nMode = 0, NumFunctionOrganizer* pNFO = NULL);
///------ End FAIED_TO_SAVE_FDF_NAME_NEW_FUNCION_IN_FFW_OPEN_FROM_FO

////////////////////////////////////////////////////////////////////////////////////
// Start your functions here.
///------DG CLEAN_DUPLICATE_MORE : move from FunctionGroup.h
string		FunctionOrganizer::GetFuncFileName(const TreeNode& trFunction, bool bGetFullpath, int* pType)
{
	/// ML 4/18/2005 XFUNCTION_TREE_MANIPULATION_IN_VC
	/*
	string strFileName;
	trFunction.GetAttribute(STR_FILENAME_ATTRIB, strFileName);

	if(strFileName.IsEmpty())
		return strFileName;
		
	if(NULL != pType)
		*pType = okutil_get_origin_path_type(strFileName);
	
	if( !bGetFullpath )
        strFileName = GetFileName(strFileName, true);
	
	return strFileName;
	*/
	///------ Folger 07/14/10 ORG-543-P2 FAILED_TO_ADD_FDF_UNDER_ANY_SUBFOLDER_OF_UFF_EXCEPT_FITFUNC
	//return okutil_fo_GetFuncFileName(&trFunction, bGetFullpath, pType);
	string		strFileName = okutil_fo_GetFuncFileName(&trFunction, bGetFullpath, pType);
	if ( pType && *pType != UNDEF_FOLDER )
	{
		string	strFolder = okutil_get_origin_path(*pType, STR_FDF_FILE_FOLDER);
		if ( GetFilePath(strFileName).CompareNoCase(strFolder) != 0 )
			*pType = UNDEF_FOLDER;
	}
	return strFileName;
	///------ End FAILED_TO_ADD_FDF_UNDER_ANY_SUBFOLDER_OF_UFF_EXCEPT_FITFUNC
	/// end XFUNCTION_TREE_MANIPULATION_IN_VC
}
// can use NULL lpcszFilename to remove STR_FILENAME_ATTRIB
void		FunctionOrganizer::SetFuncFileName(TreeNode& trFunction, LPCSTR lpcszFilename, bool bFullPathGiven)
{
	/// ML 4/18/2005 XFUNCTION_TREE_MANIPULATION_IN_VC
	/*
	string strFileName = lpcszFilename;
	if(strFileName.IsEmpty())
	{
		trFunction.RemoveAttribute(STR_FILENAME_ATTRIB);
		return;
	}		
	string strCurrentFileName = GetFuncFileName(trFunction, true);
	if( !bFullPathGiven )
	{
		//strFileName.Format("%s%s.%s", GetFilePath(strCurrentFileName), strFileName, STR_FUNCTION_FILE_EXT);	///DG keep old file ext
		string strTemp=GetFileName(strCurrentFileName, true), strExt=GetFileName(strCurrentFileName);
		strExt.TrimLeft(strTemp);
		strFileName.Format("%s%s%s", GetFilePath(strCurrentFileName), strFileName, strExt);
	}
	trFunction.SetAttribute(STR_FILENAME_ATTRIB, strFileName);
	*/
	okutil_fo_SetFuncFileName(&trFunction, lpcszFilename, bFullPathGiven);	
	/// end XFUNCTION_TREE_MANIPULATION_IN_VC
}

///Kyle 03/26/2009 QA80-13291-P4 NEW_EDIT_BOX_FOR_REFERENCES_INFORMATION
/////Kyle 03/24/2009 QA80-13291-P4 ADD_NEW_TAB_TO_SHOW_REFERENCES_INFORMATION
//string 		FunctionOrganizer::GetReferencesInfo(const TreeNode& tr)
//{
	//TreeNode trReference = GetNodeCheckAdd(tr, STR_FUNC_REFERENCES, false, STR_FUNC_SCRIPT);
	//if(trReference)
		//return trReference.strVal;
	//return "";
//}
/////End ADD_NEW_TAB_TO_SHOW_REFERENCES_INFORMATION
TreeNode 		FunctionOrganizer::GetReferences(const TreeNode& tr, bool bAddWhenNoExist)
{
	return GetNodeCheckAdd(tr, STR_FUNC_REFERENCES, bAddWhenNoExist, STR_FUNC_SCRIPT);
}

void		FunctionOrganizer::SetReferences(TreeNode& tr, string strRefInfo, bool bAddWhenNoExist)
{
	TreeNode trReferences = GetReferences(tr, bAddWhenNoExist);
	if(trReferences)
		trReferences.strVal = strRefInfo;
}
///End NEW_EDIT_BOX_FOR_REFERENCES_INFORMATION

string 		FunctionOrganizer::GetLabel(const TreeNode& tr)
{
	string strLabel;
	if(tr)
		tr.GetAttribute(STR_LABEL_ATTRIB, strLabel);
	return strLabel;
}
void 		FunctionOrganizer::SetLabel(TreeNode& tr, string strLabel)
{
	tr.SetAttribute(STR_LABEL_ATTRIB, strLabel);
}
///DG CENTRALIZE_XFO_AND_NFO
bool		FunctionOrganizer::SaveCategory(TreeNode &trCategory, vector<string> &vsSaveFail)
{
	foreach(TreeNode trNode in trCategory.Children)
	{
		if(!IsFunction(trNode))
		{
			SaveCategory(trNode, vsSaveFail);
		}
		else if(!Save(trNode))
			vsSaveFail.Add(GetFunctionName(trNode));
	}
	return true;
}
///DG VC_FUNCTION_SUPPORT
int			FunctionOrganizer::GetCategoryList(TreeNode &trCategoryList, bool bGetFunctionList) // = true
{
	if(!trCategoryList)
		return -1;
	//virtual
	TreeNode trCategorys=LoadCategoryStructure(trCategoryList);	//find files will lost empty category
	
	if(!bGetFunctionList)
		return 0;
	///Jasmine 10/30/06 CHANGE_FIND_FILE_MECHANISM_TO_NLFIT
	//xf is removed from FO
	////vc level find functions supported
	//int nSupportFile=GetSupportFile();
	//vector<string> vsNames, vsFiles;
	////get all function file
	//int nNums=okutil_find_files_from_map(&vsNames, &vsFiles, nSupportFile), nPathType;
	//
	/////Jasmine 10/18/05 QA70-8114 REMOVE_SORT_XF_LIST_OPTIONS
	///* functions shall be in the same order as readed from NLSF.ini
	/////DSC 6/16/05 ADD_SORT_XF_LIST_OPTIONS
	//sort_composite_name_vs(vsNames);
	/////end  ADD_SORT_XF_LIST_OPTIONS
	//*/
	/////End REMOVE_SORT_XF_LIST_OPTIONS
	//string strCategorys, strFuncName;
	//vector<string> vsCategorys;
	//TreeNode trCategory;
	//int ii, jj;
	//for(ii=0, jj; ii<nNums; ii++)
	//{
		//strFuncName=okutil_separate_composite_name(vsNames[ii], &nPathType, &strCategorys);
		//strCategorys.GetTokens(vsCategorys, '\\');
		//trCategory=trCategorys;
		//for(jj=0; jj<vsCategorys.GetSize(); jj++)
		//{
			//trCategory = trCategory.FindNodeByAttribute(STR_LABEL_ATTRIB, vsCategorys[jj], false);
			//if(!trCategory)
				//break;
		//}
		//if(!trCategory)
			//{
				//error_report("error, can not find function: "+strFuncName+"'s category");
			//continue;
		//}
		//TreeNode trFunction=trCategory.AddNode(tree_get_enum_node_name(trCategory, STR_NODE_FUNCTION));
		//SetLabel(trFunction, GetFunctionNameStr(strFuncName, nPathType));
		//
		/////DSC 6/16/05 ADD_SORT_XF_LIST_OPTIONS 
		//// can't use vsFiles[ii] anymore because vsNames has been sorted so these vectors are out of sinc.
		//// So use vsNames and okutil_find_file_from_composite_name instead.
		//// FunctionOrganizer::SetFuncFileName(trFunction, vsFiles[ii], true);
		//string strFullpath;
		//okutil_find_file_from_composite_name(&strFullpath, vsNames[ii], nSupportFile);
		//FunctionOrganizer::SetFuncFileName(trFunction, strFullpath, true);
		/////end ADD_SORT_XF_LIST_OPTIONS
		//
		//SetDisplayIcon(trFunction, IDR_IMPORTED_FILE);
	//}
	int nNums;
	foreach(TreeNode trCategory in trCategorys.Children)
	{
		nNums += GetFunctionList(trCategory);
	}
	///End CHANGE_FIND_FILE_MECHANISM_TO_NLFIT
	return nNums;
}
///end VC_FUNCTION_SUPPORT
void		FunctionOrganizer::SetDisplayIcon(TreeNode &tr, int nResID)
{
	/// ML 4/18/2005 XFUNCTION_TREE_MANIPULATION_IN_VC
	/*
	if(-1 == nResID)
		nResID = IsFunction(tr) ? IDR_IMPORTED_FILE : IDI_FOLDER_CLOSED;
	
	tr.SetAttribute(STR_DISPLAY_ATTRIB, nResID);
	*/
	okutil_xft_SetDisplayIcon(&tr, nResID);
	/// end XFUNCTION_TREE_MANIPULATION_IN_VC
}
bool		FunctionOrganizer::IsFunction(TreeNode tr)
{
	/// ML 4/18/2005 XFUNCTION_TREE_MANIPULATION_IN_VC
	/*
	if(!tr)
		return false;
	string strFile;
	if(!GetFuncFileName(tr, true).IsEmpty())
		return true;
	return false;
	*/
	return okutil_fo_IsFunction(&tr);
	/// end XFUNCTION_TREE_MANIPULATION_IN_VC
}
///Jasmine 10/08/07 CANNOT_REMOVE_SHARED_FUNCTION
bool		FunctionOrganizer::IsSharedFunction(TreeNode tr)
{
	if(!IsFunction(tr))
		return false;
	int nPath;
	GetFuncFileName(tr, true, &nPath);
	return ALL_USER_FOLDER == nPath;
}
///End CANNOT_REMOVE_SHARED_FUNCTION
bool		FunctionOrganizer::IsSysFunction(TreeNode tr)
{
	if(!IsFunction(tr))
		return false;
	int nPath;
	GetFuncFileName(tr, true, &nPath);
	return SYS_FOLDER == nPath;
}
///Jasmine 07/09/07 v8.0655 CHECK_INDEPENDENT_VARIABLE_NUMBER_TO_OPEN_SIMCURVE
int			FunctionOrganizer::GetSimulateType(TreeNode tr)
{
	int nSimulate = -1;
	if(!IsFunction(tr))
		return nSimulate;
	int nDepVar, nIndepVar;
	TreeNode  trDepVar = tr.GetNode(cvt_str_to_tag_name(STR_FUNC_DEPENDENT_VARS), false);
	if(trDepVar)
		nDepVar = trDepVar.strVal.GetNumTokens(',');
	TreeNode  trIndepVar = tr.GetNode(cvt_str_to_tag_name(STR_FUNC_INDEPENDENT_VARS), false);
	if(trIndepVar)
		nIndepVar = trIndepVar.strVal.GetNumTokens(',');
	
	if(1 == nDepVar)
	{
		switch(nIndepVar)
		{
		case 1://simcurve
			nSimulate = 0; break;
		case 2://simsuface
			nSimulate = 1; break;
		}
	}
	return nSimulate
}
///End CHECK_INDEPENDENT_VARIABLE_NUMBER_TO_OPEN_SIMCURVE
void		FunctionOrganizer::MarkChanged(TreeNode &tr, string *pstrVal) //=NULL
{
	string str;
	if(NULL != pstrVal)
		str=*pstrVal;
	tr.SetAttribute(STR_CHANGED_ATTRIB, str);
}
bool		FunctionOrganizer::CheckChanged(TreeNode &tr, string *pstrVal) //=NULL
{
	string strTemp;
	bool bRet=tr.GetAttribute(STR_CHANGED_ATTRIB, strTemp);
	if(bRet && pstrVal)
		*pstrVal=strTemp;
	return bRet;
}
void		FunctionOrganizer::ClearChanged(TreeNode &tr)
{
	tr.RemoveAttribute(STR_CHANGED_ATTRIB);
	tr.RemoveAttribute(STR_OLDFILENAME_ATTRIB);
}
TreeNode	FunctionOrganizer::GetNodeCheckAdd(const TreeNode& tr, LPCSTR lpcszNode, bool bAddWhenNoExist, string strSubNode) //=true, ""
{
	///DSC 2/7/05 v8.0190 CONVERT_STRING_TO_TAG_NAME
	string strNode = cvt_str_to_tag_name(lpcszNode);// replaced lpcszNode by strNode below 
	strSubNode = cvt_str_to_tag_name(strSubNode);
	///end CONVERT_STRING_TO_TAG_NAME
	
	
	TreeNode trN;	
	if(!tr)
		return trN;
	
	trN = tr.GetNode(strNode, false);
	if(bAddWhenNoExist && !trN.IsValid())	//check add
		trN = tr.AddNode(strNode);
	
	//-- if sub-node specified, get it
	bool bGetSub = !strSubNode.IsEmpty();
	if(bGetSub && trN.IsValid())
		trN = trN.GetNode(strSubNode, false);
	if(bAddWhenNoExist && bGetSub && !trN.IsValid())	//check add subnode
		trN = tr.GetNode(strNode, false).AddNode(strSubNode);
	
	return trN;
}
string		FunctionOrganizer::GetFunctionNameStr(const string strName, int nFuncFolder)
{
	/// ML 4/18/2005 XFUNCTION_TREE_MANIPULATION_IN_VC
	/*
	string strPrefix;
	switch(nFuncFolder)
	{
	case SYS_FOLDER:
		strPrefix=STR_PREFIX_SYSTEM_SEP;
		break;
	case ALL_USER_FOLDER:
		strPrefix=STR_PREFIX_ALL_USER_SEP;
		break;
	case USER_FOLDER:
		strPrefix=STR_PREFIX_USER_SEP;
		break;
	}
	///DSC 2/2/05 v8/0189 CENTRALIZE_PATH_PREFIX_CODES changed macros above to STR_PREFIX_SYSTEM_SEP, etc, which include the space after the colon
	//return strPrefix + " " + strName;
	return strPrefix + strName;
	///end CENTRALIZE_PATH_PREFIX_CODES
	*/
	//------ Folger 02/18/08 QA80-10976 ADD_MOVE_ETC_OPERATIONS_IN_FUNCTION_ORGANIZER_CONTEXTMENU
	// cannot figure out why should do it, but obviously ORIGIN_PATH_GROUP should not change to USER_FOLDER
	//if ( nFuncFolder != ORIGIN_PATH_SYSTEM )
	if ( nFuncFolder != ORIGIN_PATH_SYSTEM && nFuncFolder != ORIGIN_PATH_GROUP )
		nFuncFolder = USER_FOLDER;
	//------
	return okutil_xft_GetFunctionNameStr(strName, nFuncFolder);
	/// end XFUNCTION_TREE_MANIPULATION_IN_VC
}
///end CENTRALIZE_XFO_AND_NFO

///DG CLEAN_DUPLICATE_MORE
bool		FunctionOrganizer::UpdateFileName(TreeNode &trFileName, TreeNode &trFunction, string *pStrError)
{
	string strFileName = trFileName.strVal, strOldFileName = GetFuncFileName(trFunction, true);
	///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	//if(checkFileName(strFileName, trFunction, pStrError))
	if(checkFileName(trFileName, trFunction, pStrError))
	///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	{
		string strTemp;
		if(!trFunction.GetAttribute(STR_OLDFILENAME_ATTRIB, strTemp))
			trFunction.SetAttribute(STR_OLDFILENAME_ATTRIB, strOldFileName);
		
		SetFuncFileName(trFunction, strFileName, true);//false);///Jasmine 11/02/06 FUNC_AND_FILE_NAME_ONE_TO_ONE 
		return true;
	}
	else
	{
		//undo rename
		//trFileName.strVal = GetFileName(strOldFileName, true);///Jasmine 11/02/06 FUNC_AND_FILE_NAME_ONE_TO_ONE 
		trFileName.strVal = strOldFileName;
		return false;
	}
}
bool 		FunctionOrganizer::UpdateCateName(TreeNode &trName, TreeNode &trCategory, string *pStrError)
{
	string strCateName=trName.strVal;
	///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	//if(checkCateName(strCateName, trCategory, pStrError) && SaveCategoryName(trCategory, strCateName))
	///Sophy 7/20/2010 ORG-598-P1 PROPER_CHECK_AND_UPDATE_CATEGORY_NAME
	//if(checkCateName(trName, trCategory, pStrError) && SaveCategoryName(trCategory, strCateName))
	if(checkCateName(trName, trCategory.Parent(), pStrError) && SaveCategoryName(trCategory, strCateName))
	///end PROPER_CHECK_AND_UPDATE_CATEGORY_NAME
	///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	{
		SetLabel(trCategory, strCateName);
		for(TreeNode trParent=trCategory; trParent.IsValid(); trParent=trParent.Parent())
			ClearChanged(trParent);
		return true;
	}
	else //fail, undo
	{
		strCateName = GetLabel(trCategory);
		trName.strVal=strCateName;
		return false;
	}
}
///------ Folger 06/24/10 ORG-390-P3 FDF_FILE_NAME_SHOULD_UPDATE_AFTER_FUNCTION_NAME_CHANGED
//bool 		FunctionOrganizer::UpdateFuncName(TreeNode &trName, TreeNode &trFunction, string *pStrError)
bool 		FunctionOrganizer::UpdateFuncName(TreeNode &trName, TreeNode &trFunction, string *pStrError/* = NULL*/, string* pstrFile/* = NULL*/)
///------ End FDF_FILE_NAME_SHOULD_UPDATE_AFTER_FUNCTION_NAME_CHANGED
{
	///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	//string 		strNewName = trName.strVal;
	///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	
	int nPath;
	///Jasmine 11/02/06 FUNC_AND_FILE_NAME_ONE_TO_ONE 
	string strOldFileName = GetFuncFileName(trFunction, true, &nPath); //get function path type
	string strOldName=GetLabel(trFunction);
	
	//if(CheckFuncName(strNewName, trFunction, pStrError))
	///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	//if(CheckFuncName(strNewName, trFunction.Parent(), pStrError))
	if(CheckFuncName(trName, trFunction.Parent(), pStrError))
	///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	{
		string strNewName = trName.strVal;				///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
		SetFunctionName(trFunction, strNewName, &nPath);
		//file name changes with function name
		/// ML 9/30/2008 QA70-11852 P2 GET_FDFNAMENODE_BY_DATAID
		//TreeNode trFile = trFunction.FindNodeByAttribute(STR_LABEL_ATTRIB, STR_FUNC_FILE_NAME);
		TreeNode trFile = trFunction.FindNodeByAttribute(STR_DATAID_ATTRIB, FUNC_TREE_FILE_NAME_ID);	// must use DataID because the label is localized
		/// end GET_FDFNAMENODE_BY_DATAID
		///------ Folger 06/24/10 ORG-390-P3 FDF_FILE_NAME_SHOULD_UPDATE_AFTER_FUNCTION_NAME_CHANGED
		//trFile.strVal = GetFilePath(strOldFileName) + strNewName + "." + STR_FIT_FUNCTION_FILE_EXT;
		string		strFile = GetFilePath(strOldFileName) + strNewName + "." + STR_FIT_FUNCTION_FILE_EXT;
		if ( !trFile )
		{
			if ( pstrFile )
				*pstrFile = strFile;
			return true;
		}
		trFile.strVal = strFile;
		///------ End FDF_FILE_NAME_SHOULD_UPDATE_AFTER_FUNCTION_NAME_CHANGED
		if(!UpdateFileName(trFile, trFunction, pStrError))
		{
			trName.strVal=okutil_separate_composite_name(strOldName);
			return false;
		}
		
		if ( pstrFile )
			*pstrFile = strFile;
		
	///End FUNC_AND_FILE_NAME_ONE_TO_ONE
		string strTemp;
		if(!CheckChanged(trFunction, &strTemp) || strTemp.IsEmpty())
			MarkChanged(trFunction, &strOldName);
		
		return true;
	}
	else
	{
		trName.strVal=okutil_separate_composite_name(strOldName);
		return false;
	}
}
bool		FunctionOrganizer::IsUnEditableSysFunction(TreeNode trFunction)
{
	if(!IsSysFunction(trFunction))
		return false;
	string strUserFile=GetFuncFilePath(trFunction, USER_FOLDER);
	return strUserFile.IsFile();
}
///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
//bool 		FunctionOrganizer::checkFileName(string& strFileName, TreeNode &trFunction, string *pStrError)
bool 		FunctionOrganizer::checkFileName(TreeNode& trFileName, TreeNode &trFunction, string *pStrError)
///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
{
	int nPath;
	string strFileName = trFileName.strVal;		///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	GetFuncFileName(trFunction, true, &nPath);	//get current file path type
	string strError, strSubFolder=GetFilePath(GetFuncFilePath(trFunction, nPath));
	if(strFileName.IsEmpty())
		strError=STR_ERROR_NOT_EMPTY_NAME;
	else if(CheckFileNameExist(strFileName, strSubFolder))
	{
		//if file name exist, check if it is this function source file name
		string strOldFileName;
		if(!trFunction.GetAttribute(STR_OLDFILENAME_ATTRIB, strOldFileName) || 0 != strFileName.CompareNoCase(GetFileName(strOldFileName, true)))
			strError=STR_ERROR_FUNCTION_FILE_EXIST;
	}
	else
	{
		//check in current category as there maybe some unsave function
		vector<string> vsFileNames;
		tree_get_attributes(trFunction.Parent(), vsFileNames, STR_FILENAME_ATTRIB);
		for(int ii=0; ii<vsFileNames.GetSize(); ii++)
		{
			if(vsFileNames[ii].IsEmpty())
				continue;
			string strExistName=GetFileName(vsFileNames[ii], true);
			if(0 == strFileName.CompareNoCase(strExistName))
			{
				strError=STR_ERROR_FUNCTION_FILE_EXIST;
				break;
			}
		}
	}
	
	if(NULL != pStrError)
	{
		*pStrError=strError;
	}
	return strError.IsEmpty();
}
///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
/// Kenny 11/12/2009 QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
//bool 		FunctionOrganizer::CheckFuncName(string& strFuncName, TreeNode trParent, string *pStrError, LPCSTR lpcstrFile, bool bCheckParentOnly)// = NULL, = false)
bool 		FunctionOrganizer::CheckFuncName(string& strFuncName, 
											 TreeNode trParent, 
											 string *pStrError, 
											 LPCSTR lpcstrFile /*= NULL*/, 
											 bool bCheckParentOnly /*= false*/,
											 DWORD dwCtrl /*= 0*/)
/// End QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
{
	Tree trFunction;
	TreeNode trFuncName = trFunction.AddNode("TempFunc");
	trFuncName.strVal = strFuncName;
	/// Kenny 11/12/2009 QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
	//bool bRet = CheckFuncName(trFuncName, trParent, pStrError, lpcstrFile, bCheckParentOnly);
	bool bRet = CheckFuncName(trFuncName, trParent, pStrError, lpcstrFile, bCheckParentOnly, dwCtrl);
	/// End QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
	if(bRet)
		strFuncName = trFuncName.strVal;
	return bRet;
}
///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS

///Jasmine 11/02/06 FUNC_AND_FILE_NAME_ONE_TO_ONE	
//bool 		FunctionOrganizer::checkFuncName(string& strFuncName, TreeNode &trFunction, string *pStrError)
///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
//bool 		FunctionOrganizer::CheckFuncName(string& strFuncName, TreeNode trParent, string *pStrError, LPCSTR lpcstrFile, bool bCheckParentOnly)// = NULL, = false)
/// Kenny 11/12/2009 QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
//bool 		FunctionOrganizer::CheckFuncName(TreeNode& trFuncName, TreeNode trCategory, string *pStrError, LPCSTR lpcstrFile, bool bCheckParentOnly)// = NULL, = false)
bool 		FunctionOrganizer::CheckFuncName(TreeNode& trFuncName, 
											 TreeNode trParent, 
											 string *pStrError, 
											 LPCSTR lpcstrFile /*= NULL*/, 
											 bool bCheckParentOnly /*= false*/, 
											 DWORD dwCtrl /*= 0*/)
/// End QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
{
	string strFuncName = trFuncName.strVal;			///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	string strName = strFuncName;
	if(!is_str_valid_for_filename(strName, true) || strFuncName != strName)
	{
		strFuncName=strName;
		/// Kenny 11/12/2009 QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
// 		if(NULL != pStrError)
// 			//*pStrError = STR_ERROR_FUNCTION_NAME_INVALID;
// 			*pStrError = "InValid name has been auto corrected.";
		bool bReturnOnInvalid = dwCtrl & FO_NAME_CHECKING_RETURN_ON_INVALID;
		if ( NULL != pStrError )
		{
			*pStrError = bReturnOnInvalid ? STR_ERROR_INVALID_NAME : STR_ERROR_CORRECT_NAME;
		}
		if ( bReturnOnInvalid )
			return false;
		/// End QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
	}
	/// Hong 02/25/07 CHECK_VALID_C_FUNC_NAME
	strFuncName.MakeValidCName();
	/// end CHECK_VALID_C_FUNC_NAME
	//check if changed name exist in the same category
	///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	//return !isNameEmptyOrExist(strFuncName, true, trParent, pStrError, lpcstrFile, bCheckParentOnly); 
	trFuncName.strVal = strFuncName;
	return !isNameEmptyOrExist(trFuncName, true, trParent, pStrError, lpcstrFile, bCheckParentOnly); 
	///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
}

/// Kenny 11/12/2009 QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
bool		FunctionOrganizer::CheckCateName(string& strCateName, TreeNode trParent, string *pStrError /*= NULL*/)
{
	Tree trCategory;
	TreeNode trCateName = trCategory.AddNode("TempCate");
	trCateName.strVal = strCateName;
	bool bRet = checkCateName(trCateName, trParent, pStrError);
	if(bRet)
		strCateName = trCateName.strVal;
	return bRet;
}
/// End QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES

///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
//bool		FunctionOrganizer::checkCateName(string& strCateName, TreeNode &trParent, string *pStrError)
bool		FunctionOrganizer::checkCateName(TreeNode& trCateName, TreeNode &trParent, string *pStrError)
///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
{
	///Jasmine 11/07/06 ALLOW_RENAME_USER_DEFINED_CATEGORY
	///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	//if(!strCateName.CompareNoCase(STR_NODE_CATEGORY))
	if(!trCateName.strVal.CompareNoCase(STR_NODE_CATEGORY))
	///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	{
		/// Kenny 11/12/2009 QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
		//*pStrError = "This is not a valid category name.";
		if ( pStrError )
			*pStrError = _L("This is not a valid category name.");
		return false;
		/// End QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
	}
	///End Jasmine 11/07/06 ALLOW_RENAME_USER_DEFINED_CATEGORY
	///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	//return !isNameEmptyOrExist(strCateName, false, trParent, pStrError); 
	return !isNameEmptyOrExist(trCateName, false, trParent, pStrError); 
	///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
}
///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
//bool		FunctionOrganizer::isNameEmptyOrExist(string strName, bool bFunctionName, TreeNode &trParent, string *pStrError, LPCSTR lpcstrFile, bool bCheckParentOnly)// = NULL, = false)
bool		FunctionOrganizer::isNameEmptyOrExist(TreeNode& trName, bool bFunctionName, TreeNode &trParent, string *pStrError, LPCSTR lpcstrFile, bool bCheckParentOnly)// = NULL, = false)
{
	string strFile(lpcstrFile);
	string strName = trName.strVal;				///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
	string strTemp=strName, strError;
	strTemp.TrimLeft();	//trim space to check empty
	//TreeNode trParent=tr.Parent();
///End FUNC_AND_FILE_NAME_ONE_TO_ONE
	if(strTemp.IsEmpty())
		strError=STR_ERROR_INVALID_NAME;//STR_ERROR_NOT_EMPTY_NAME;
	else if(bFunctionName)
	{
		///------ Folger 06/24/10 ORG-390-P3 FDF_FILE_NAME_SHOULD_UPDATE_AFTER_FUNCTION_NAME_CHANGED
		if ( !trParent )
			return false;
		///------ End FDF_FILE_NAME_SHOULD_UPDATE_AFTER_FUNCTION_NAME_CHANGED
		
		///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS 
		TreeNode trFunction = trName.Parent();
		string strFuncTreePath;
		tree_get_level(trFunction, &strFuncTreePath);
		///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS

		for(int nPath=ORIGIN_PATH_TYPE_START; nPath<=ORIGIN_PATH_TYPE_END; nPath++)
		{
			strTemp=GetFunctionNameStr(strName, nPath);
			//if(tree_check_attribute_value_exist(trParent, strTemp, STR_LABEL_ATTRIB))
			TreeNode trFind=trParent.FindNodeByAttribute(STR_LABEL_ATTRIB, strTemp, true, false);
			if(trFind.IsValid())
			{
				///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
				string strFindTreePath;
				tree_get_level(trFind, &strFindTreePath);
				if(0 == strFindTreePath.Compare(strFuncTreePath))		// the same function
					continue;
				///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
				strError=STR_ERROR_NAME_EXIST;
				/// ML 9/30/2008 QA70-11852 P2 GET_FDFNAMENODE_BY_DATAID
				//TreeNode trFileName = trFind.FindNodeByAttribute(STR_LABEL_ATTRIB, STR_FUNC_FILE_NAME);
				TreeNode trFileName = trFind.FindNodeByAttribute(STR_DATAID_ATTRIB, FUNC_TREE_FILE_NAME_ID);
				/// end GET_FDFNAMENODE_BY_DATAID
				///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
				//if(trFileName.IsValid() && trFileName.strVal.CompareNoCase(strFile))
				if(trFileName.IsValid() && 0 == trFileName.strVal.CompareNoCase(strFile))
				///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
					strError=STR_ERROR_FUNCTION_FILE_EXIST;
				break;
			}
		}
		//can't use existing name even if in other category
		if ( !bCheckParentOnly )
		{
			///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
			TreeNode trCategory;
			if(trFunction)
				trCategory = trName.Parent();
			string strCateTreePath;
			tree_get_level(trCategory, &strCateTreePath);
			///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS

			trParent=trParent.Parent();
			for(nPath=ORIGIN_PATH_TYPE_START; !lstrlen(strError) && nPath<=ORIGIN_PATH_TYPE_END; nPath++)
			{
				strTemp=GetFunctionNameStr(strName, nPath);
				foreach(TreeNode trCate in trParent.Children)
				{
					//if(tree_check_attribute_value_exist(trParent, strTemp, STR_LABEL_ATTRIB))
					TreeNode trFind=trCate.FindNodeByAttribute(STR_LABEL_ATTRIB, strTemp, true, false);//find function node only
					if(trFind.IsValid())
					{
						///Kyle 01/13/2009 v8.0995d SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
						string strFindTreePath;
						tree_get_level(trFind, &strFindTreePath);
						if(0 == strFindTreePath.Compare(strCateTreePath))		// the same category
							continue;
						///End SHOW_ERROR_MESSAGE_WHEN_THE_FILE_WITH_THE_SAME_NAME_EXISTS
						strError=STR_ERROR_NAME_EXIST;//temp, user-defined function's name must be unique
						/// ML 9/30/2008 QA70-11852 P2 GET_FDFNAMENODE_BY_DATAID
						//TreeNode trFileName = trFind.FindNodeByAttribute(STR_LABEL_ATTRIB, STR_FUNC_FILE_NAME);
						TreeNode trFileName = trFind.FindNodeByAttribute(STR_DATAID_ATTRIB, FUNC_TREE_FILE_NAME_ID);
						/// end GET_FDFNAMENODE_BY_DATAID
						if(trFileName.IsValid() && trFileName.strVal.CompareNoCase(strFile))
						{
							strError=STR_ERROR_FUNCTION_FILE_EXIST;
							break;
						}
					}
				}
			}
		}
///End FUNC_AND_FILE_NAME_ONE_TO_ONE
	}
	else if(tree_check_attribute_value_exist(trParent, strName, STR_LABEL_ATTRIB))
		strError=STR_ERROR_NAME_EXIST;
	
	if(!strError.IsEmpty())
	{
		if(NULL != pStrError)
			*pStrError=strError;
		return true;
	}
	return false;
}
///end CLEAN_DUPLICATE_MORE

///DG 4/15/05 VC_FUNCTION_SUPPORT
/*
int		NLFunctionList::GetCategoryList(TreeNode &trCategoryList, bool bGetFunctionList) // = true
{
	TreeNode trCategorys=LoadCategoryStructure(trCategoryList);
	
	int	nNodeCount = 0; //nSize
	if(bGetFunctionList)
	{
		foreach(TreeNode trCategory in trCategorys.Children)
		{
			nNodeCount += GetFunctionList(trCategory);
		}
	}
	return nNodeCount;
}
*/
int		NLFunctionList::GetSupportFile()
{
	return SUPPORTFILE_FDF;
}
///end VC_FUNCTION_SUPPORT
TreeNode NLFunctionList::LoadCategoryStructure(TreeNode &trCategory)
{
	///------Frank 11/09/05 
	/*
	TreeNode trList=trCategory.AddNode(STR_FIT_FUNCTION_NODE);
	SetLabel(trList, STR_FIT_FUNCTION_LABEL);
	trList.DataID=ID_FIT_FUNCTION;
	SetDisplayIcon(trList, IDI_FOLDER_CLOSED);
	
	vector<string> vsCategorys;
	int nSize=GetCategoryList(vsCategorys);
	for(int ii=0; ii<nSize; ii++)
	{
		addListNode(trList, STR_NODE_CATEGORY+(string)ii, vsCategorys[ii]);
	}
	return trList;
	*/
	trCategory.DataID=ID_FIT_FUNCTION;
	SetDisplayIcon(trCategory, IDI_FOLDER_CLOSED);
	vector<string> vsCategorys;
	int nSize=GetCategoryList(vsCategorys);
	for(int ii=0; ii<nSize; ii++)
	{
		addListNode(trCategory, STR_NODE_CATEGORY+(string)ii, vsCategorys[ii]);
	}
	return trCategory;	
	///------
}

/// Kenny 11/12/2009 QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
// int		NLFunctionList::GetCategoryList(vector<string> &vsCategorys,)
// {
// 	///Jasmine 02/17/09 QA80-10378 SHARE_FUNCTION_ORGANIZER_CODE_WITH_SELECTCAT
// 	return nlsf_get_category_list(vsCategorys);
// 	///End SHARE_FUNCTION_ORGANIZER_CODE_WITH_SELECTCAT
// }

int		NLFunctionList::GetCategoryList(vector<string> &vsCategorys, vector<int>& vnSeparatorIndices /*= NULL*/)
{
	return nlsf_get_category_list(vsCategorys, vnSeparatorIndices);
}
/// End QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES

int 	NLFunctionList::GetFunctionList(TreeNode &trCategory)
{
	if(!trCategory)
		return -1;
	string strCategory = GetLabel(trCategory);
	if(strCategory.IsEmpty())
		return -1;
	vector<string> vsFunctions, vsFullFileNames;
	vector<bool> vbSharedFunction;
	int nDefaultFuncton = -1; //CPY 3/1/2007 FO_RUNTIME_ERR_WITH_VS_OUT_OF_BOUND, init to -1, was not init
	int nSize=GetFunctionList(vsFunctions, vsFullFileNames, vbSharedFunction, strCategory, &nDefaultFuncton);
	//----- CPY 3/1/2007 FO_RUNTIME_ERR_WITH_VS_OUT_OF_BOUND
	//if(nSize>0)
	if(nSize > 0 && nDefaultFuncton >=0 && nDefaultFuncton < vsFunctions.GetSize())
	//-----
		trCategory.SetAttribute(STR_DEFAULT_FUNCTION_ATTRIB, vsFunctions[nDefaultFuncton]);
		
	for(int ii=0; ii<nSize; ii++)
	{
		// addListNode(trCategory, STR_FUNCTION+(string)ii, vsFunctions[ii], vsFullFileNames[ii], vbSharedFunction[ii]);
		addListNode(trCategory, STR_NODE_FUNCTION+(string)ii, vsFunctions[ii], vsFullFileNames[ii], vbSharedFunction[ii]);
	}
	
	return nSize;
}
int		NLFunctionList::GetFunctionList(vector<string> &vsFunctions, vector<string> &vsFunctionFullFileNames, vector<bool> &vbShared, LPCSTR lpcstrCategoryName , int *nDefaultFunctionIndex)// = NULL
{
	vsFunctions.SetSize(0);
	vsFunctionFullFileNames.SetSize(0);
	vbShared.SetSize(0);
	vector<string> vsUserFunctions, vsUserFuncFileNames, vsSharedFunctions, vsSharedFuncFileNames, nDefaultFunction;
	nlf_get_section_keys_and_values(lpcstrCategoryName, vsUserFunctions, vsUserFuncFileNames, nDefaultFunctionIndex, USER_FOLDER);
	nlf_get_section_keys_and_values(lpcstrCategoryName, vsSharedFunctions, vsSharedFuncFileNames, NULL, ALL_USER_FOLDER);
	
	vector<bool> vbSharedTemp(vsUserFuncFileNames.GetSize());
	
	//------ Folger 08/29/07 FIX_BUGS_IN_VECTOR_SIZE
	//vbSharedTemp=false;
	if (vbSharedTemp.GetSize())
		vbSharedTemp = false;
	//------ End FIX_BUGS_IN_VECTOR_SIZE
	
	vsUserFunctions.Append(vsSharedFunctions);
	vsUserFuncFileNames.Append(vsSharedFuncFileNames);
	for(int ii=0; ii<vsSharedFunctions.GetSize(); ii++)
		vbSharedTemp.Add(true);
	
	vector<string> vsFunctionNames;	//with prefix : sys, user, or all user
	vector<string> vsFullFileNames;
	string strTemp;
	for(ii=0; ii<vsUserFunctions.GetSize(); ii++)
	{
		bool bShare=vbSharedTemp[ii];
		int nSize=searchFunctionByFileName(vsUserFuncFileNames[ii], bShare, vsUserFunctions[ii], vsFunctionNames, vsFullFileNames);
		vsFunctions.Append(vsFunctionNames);
		vsFunctionFullFileNames.Append(vsFullFileNames);
		for(int ii=0; ii<nSize; ii++)
			vbShared.Add(bShare);
	}
	return vsFunctions.GetSize();
}
int		NLFunctionList::GetMultiOpenBox(vector<string>& vsFilePaths, LPCSTR lpcszPath) //=NULL
{
	string strExt=STR_FIT_FUNCTION_FILE_EXT_SPEC;
	return GetMultiOpenBox(vsFilePaths, strExt, lpcszPath);
}
///Cheney 2007-5-9 CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
/////Cheney 2007-5-5 FUNC_FILE_TAB_BROKEN_IN_NLFIT_DLG
////bool 	NLFunctionList::Load(TreeNode &trFunction, string strFunctionName, string &strCategoryName)
//bool 	NLFunctionList::Load(TreeNode &trFunction, string strFunctionName, string &strCategoryName, bool bLoadFDF) // true
bool 	NLFunctionList::LoadEx(TreeNode &trFunction, LPCSTR lpcszFunctionName, string &strCategoryName, bool bLoadFDF) // true
/////end FUNC_FILE_TAB_BROKEN_IN_NLFIT_DLG
///end CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
{
	string strFullPath;
	///Cheney 2007-5-9 CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
	//nlf_get_fdf_filename(strFunctionName, &strCategoryName, NULL, &strFullPath);
	nlf_get_fdf_filename(lpcszFunctionName, &strCategoryName, NULL, &strFullPath);
	///end CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
	/// ML 5/8/2007 WRONG_ARGUMENT_PASSED_PRODUCES_BAD_FITTING_FUNCTION_TREE
	/////Cheney 2007-5-5 FUNC_FILE_TAB_BROKEN_IN_NLFIT_DLG
	////return NLFunctionList::Load(trFunction, strFullPath);
	//return NLFunctionList::Load(trFunction, strFullPath, bLoadFDF);
	/////end FUNC_FILE_TAB_BROKEN_IN_NLFIT_DLG
	///Cheney 2007-5-9 CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
	//return NLFunctionList::Load(trFunction, strFullPath, "", bLoadFDF);
	return NLFunctionList::Load(trFunction, strFullPath, NULL, bLoadFDF);
	///end CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
	/// end WRONG_ARGUMENT_PASSED_PRODUCES_BAD_FITTING_FUNCTION_TREE
}
///Cheney 2007-5-9 CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
/////Cheney 2007-5-5 FUNC_FILE_TAB_BROKEN_IN_NLFIT_DLG
////bool 	NLFunctionList::Load(TreeNode &trFunction, LPCSTR lpcstrFilePath, string strName) //=""
//bool 	NLFunctionList::Load(TreeNode &trFunction, LPCSTR lpcstrFilePath, string strName, bool bLoadFDF) //="", true
bool 	NLFunctionList::Load(TreeNode &trFunction, LPCSTR lpcstrFilePath, LPCSTR lpcszFunctionName, bool bLoadFDF) //=NULL, true
/////end FUNC_FILE_TAB_BROKEN_IN_NLFIT_DLG
///end CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
{
	if(!trFunction)
		return false;
	
	string	strFilePath(lpcstrFilePath);
	///DG FUNCTION_ONLY_LOAD_ITS_EXT_FILE
	/*
	if(!strFilePath.IsFile())
		return false;
	*/
	///Cheney 2007-5-9 CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
	string strName(lpcszFunctionName);
	///end CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
	
	char szExt[20], szFileName[150];
	lstrcat(szFileName, GetFileName(strFilePath));
	check_add_file_ext(szFileName, NULL, szExt);
	if(!strFilePath.IsFile() || lstrcmpi(szExt, STR_FIT_FUNCTION_FILE_EXT) != 0)//0 != strcmp(szExt, STR_FIT_FUNCTION_FILE_EXT))
		return false;
	///end FUNCTION_ONLY_LOAD_ITS_EXT_FILE
	
	///Jasmine 06/08/07 NEW_MECHANISM_TO_SAVE_BUILT_IN_FUNCTION
	///Cheney 2007-5-5 FUNC_FILE_TAB_BROKEN_IN_NLFIT_DLG
	//if( !nlsf_FDF_to_tree( strFilePath, &trFunction ))	//load fdf file, may be change functin name info	
	//if( bLoadFDF && !nlsf_FDF_to_tree( strFilePath, &trFunction, FDFT_CONVERT_BOOL_TO_01 ))	//load fdf file, may be change functin name info	
	if( bLoadFDF && !nlsf_load_FDF_to_tree( strFilePath, &trFunction, FDFT_CONVERT_BOOL_TO_01 ))	//load fdf file, may be change functin name info	
	///end 	FUNC_FILE_TAB_BROKEN_IN_NLFIT_DLG
		return false;
	///End NEW_MECHANISM_TO_SAVE_BUILT_IN_FUNCTION
	
	if(strName.IsEmpty())
		strName=NLFunctionList::GetFunctionName(trFunction);
	int nPath = okutil_get_origin_path_type(strFilePath);
	NLFunctionList::SetFunctionName(trFunction, okutil_separate_composite_name(strName), &nPath);
	NLFunctionList::SetFuncFileName(trFunction, strFilePath);
	SetDisplayIcon(trFunction, IDR_IMPORTED_FILE);	///DG 4/7/05 FOLDER_WITH_DISPLAY_ICON
	return true;
}
///Jasmine 11/02/06 FUNC_AND_FILE_NAME_ONE_TO_ONE
string 	NLFunctionList::GetFunctionName(LPCSTR lpcstrFilePath)
{
	string strFunctionName;
	Tree trFunction;
	Load(trFunction, lpcstrFilePath);
	strFunctionName = GetFunctionName(trFunction);
	return strFunctionName;
}
///End FUNC_AND_FILE_NAME_ONE_TO_ONE
string 	NLFunctionList::GetFunctionName(TreeNode& trFunction, bool bPrefixIncluding)
{
	string strFunctionName;
	if(!trFunction)
		return strFunctionName;
	
	TreeNode trNode = GetGeneralInfo(trFunction, false, STR_FUNC_NAME);
	
	if(trNode)
		strFunctionName = trNode.strVal;
	
	if( bPrefixIncluding && !strFunctionName.IsEmpty() )
	{
		int nFolder;
		string strFilePath = NLFunctionList::GetFuncFileName(trFunction, true, &nFolder);
		strFunctionName = GetFunctionNameStr(strFunctionName, nFolder);		
	}
	
	return strFunctionName;		
}

void 	NLFunctionList::SetFunctionName(TreeNode& trFunction, string strFunctionName, const int *pnPath) //= NULL
{
	if(NULL != pnPath)
		strFunctionName = GetFunctionNameStr(okutil_separate_composite_name(strFunctionName), *pnPath);
		
	TreeNode trNode = GetGeneralInfo(trFunction, true, STR_FUNC_NAME);
	trNode.strVal=okutil_separate_composite_name(strFunctionName);
	SetLabel(trFunction, strFunctionName); //addition
}

TreeNode	NLFunctionList::addListNode(TreeNode &tr, string strtagName, string strLabelName, string strFileName, bool bShareFunction) //="", false
{
	TreeNode trNew=tr.AddNode(strtagName);
	SetLabel(trNew, strLabelName);
	
	if(!strFileName.IsEmpty())
	{
		NLFunctionList::SetFuncFileName(trNew, strFileName);
		if(bShareFunction)
			trNew.SetAttribute(STR_FUNCTION_FORM_SHARE_FILE_ATTRIB, "");
		//trNew.SetAttribute(STR_DISPLAY_ATTRIB, IDR_IMPORTED_FILE); ///DG FOLDER_WITH_DISPLAY_ICON
		SetDisplayIcon(trNew, IDR_IMPORTED_FILE);
	}
	else
		//trNew.SetAttribute(STR_DISPLAY_ATTRIB, IDI_FOLDER_CLOSED); ///DG FOLDER_WITH_DISPLAY_ICON
		SetDisplayIcon(trNew, IDI_FOLDER_CLOSED);
	return trNew;
}
int		NLFunctionList::searchFunctionByFileName(string strFunctionFileName, bool bSharedFunction, string strFunctionName, vector<string> &vsOutputFunctionNames, vector<string> &vsOutputFullFileNames)
{
	string strFunctionFullPath;
	vsOutputFunctionNames.SetSize(0);
	vsOutputFullFileNames.SetSize(0);
	if(bSharedFunction)	//we should separate the share function, assum share function only in share folder
	{
		strFunctionFullPath=GetFunctionFileFullPath(strFunctionFileName, ALL_USER_FOLDER);
		if(strFunctionFullPath.IsFile())
		{
			vsOutputFunctionNames.Add(GetFunctionNameStr(strFunctionName, ALL_USER_FOLDER));
			vsOutputFullFileNames.Add(strFunctionFullPath);
		}
	}
	else
	{
		strFunctionFullPath=GetFunctionFileFullPath(strFunctionFileName, SYS_FOLDER);
		if(strFunctionFullPath.IsFile())
		{
			vsOutputFunctionNames.Add(GetFunctionNameStr(strFunctionName, SYS_FOLDER));
			vsOutputFullFileNames.Add(strFunctionFullPath);
		}
		strFunctionFullPath=GetFunctionFileFullPath(strFunctionFileName, USER_FOLDER);
		if(strFunctionFullPath.IsFile())
		{
			vsOutputFunctionNames.Add(GetFunctionNameStr(strFunctionName, USER_FOLDER));
			vsOutputFullFileNames.Add(strFunctionFullPath);
		}
		///Jasmine 07/25/07 SOME_FUNCTIONS_ARE_NOT_IN_SYSTEM_OR_USER_FILE_FOLDER
		if(strFunctionFileName.IsFile())
		{
			vsOutputFunctionNames.Add(GetFunctionNameStr(strFunctionName, UNDEF_FOLDER));
			vsOutputFullFileNames.Add(strFunctionFileName);
		}
		///End SOME_FUNCTIONS_ARE_NOT_IN_SYSTEM_OR_USER_FILE_FOLDER
	}
	return vsOutputFunctionNames.GetSize();
}
string		NLFunctionList::GetFunctionFolder(int nPath, string strSubFolder) //=SYS_FOLDER, ""
{
	string strPath=okutil_get_origin_path(nPath, STR_FDF_FILE_FOLDER);
	//---- CPY 4/10/08 CLEAN_CODE_NOT_CHECKING_RETURN_VALUE
	if(strPath.IsEmpty())
		return strPath;
	//----
	if(!strSubFolder.IsEmpty())
		strPath+=strSubFolder;
	
	strPath.TrimRight("\\");
	return strPath+"\\";
}
string		NLFunctionList::GetFunctionFileFullPath(string strFileName, int nPath, string strSubFolder) //=SYS_FOLDER, ""
{
	string strFileFullPath = GetFunctionFolder(nPath, strSubFolder);
	if(!strFileName.IsEmpty())
	{
		strFileName=GetFileName(strFileName, true); //
		strFileFullPath+=strFileName+".fdf";
	}
	return strFileFullPath;
}
int			NLFunctionList::FindCategoryPath(const TreeNode &trCagetory, vector<int> &vnExistPathType)
{
	string strName=GetLabel(trCagetory);
	vector<string> vsCategorys;
	for(int nPath=ORIGIN_PATH_TYPE_START; nPath<=ORIGIN_PATH_TYPE_END; nPath++)
	{
		nlf_get_section_keys_and_values(STR_NODE_CATEGORY, vsCategorys, NULL, NULL, nPath);
		if(-1 != vsCategorys.Find(strName))
			vnExistPathType.Add(nPath);
	}
	return vnExistPathType.GetSize();
}

//TreeNode 	NLFunctionList::GetGeneralInfo(const TreeNode& tr, bool bAddWhenNoExist, const string strSubNode)// = true, ""
TreeNode 	NLFunctionList::GetGeneralInfo(const TreeNode& tr, bool bAddWhenNoExist, string strSubNode)// = true, ""
{
	///DSC 2/7/05 v8.0190 CONVERT_STRING_TO_TAG_NAME Replaced node name constant STR_GENERAL_INFO by gui name STR_FUNC_GENERAL_INFO
	// return GetNodeCheckAdd(tr, STR_GENERAL_INFO, bAddWhenNoExist, strSubNode);
	return GetNodeCheckAdd(tr, STR_FUNC_GENERAL_INFO, bAddWhenNoExist, strSubNode);
	///end CONVERT_STRING_TO_TAG_NAME
}

void	 	NLFunctionList::SetGeneralInfo(TreeNode& tr, bool bAddWhenNoExist, string strSubNode, string strSubNodeVal)// = true, ""
{
	TreeNode trNode = GetGeneralInfo(tr, bAddWhenNoExist, strSubNode);
	if(trNode)
		trNode.strVal = strSubNodeVal;
}


///CPY 2/7/05 v8.0189 SET_TREE_NODE_VALUE
//--  transplants value from trSrc tree to same node on trDest tree
bool	 	NLFunctionList::SetTreeNodeVal(TreeNode& trDest, LPCSTR lpcszLabel, bool bAddWhenNoExist, const TreeNode& trSrc)// = true
{
	/// DSC 2/7/05 v8.0190 SET_TREE_NODE_VALUE in GetNodeCheckAdd(trDest, lpcszLabel, bAddWhenNoExist, strTag);, strTag is not the tag name of lpcszLabel, but a sub node tag name.
	/*
	string strTag = cvt_str_to_tag_name(lpcszLabel);
	TreeNode trNode = GetNodeCheckAdd(trDest, lpcszLabel, bAddWhenNoExist, strTag);
	if(trNode)
	{
		TreeNode trSrcSub = trSrc.GetNode(strTag);
		if(trSrcSub)
		{
			trNode.strVal = trSrcSub.strVal;
			return true;
		}
	}
	return error_report("SetTreeNodeVal failed");
	*/
	TreeNode trDestNode = GetNodeCheckAdd(trDest, lpcszLabel, bAddWhenNoExist, "");
	if(trDestNode)
	{
		string strTag = cvt_str_to_tag_name(lpcszLabel);
		TreeNode trSrcNode = trSrc.GetNode(strTag);
		if(trSrcNode)
		{
			trDestNode.strVal = trSrcNode.strVal;
			return true;
		}
	}
	
	//-- no value set, dest node did not exist and was not created, or src node did not exist in source
	return false;
	///end DSC 2/7/05 v8.0190 SET_TREE_NODE_VALUE
	
}
///end SET_TREE_NODE_VALUE

/// DSC 2/7/05 v8.0190 SET_TREE_NODE_VALUE
//-- sets a *string* value to given node, checks existance of node, allow creation of node.
//-- Need another prameter to set subnode...
//-- use instead of "GetNodeCheckAdd(tr, lpcszLabel, bAddWhenNoExist, "").strVal = str;"
bool	 	NLFunctionList::SetTreeNodeVal(TreeNode& tr, LPCSTR lpcszLabel, bool bAddWhenNoExist, LPCTSTR lpszValue)
{

	TreeNode trNode = GetNodeCheckAdd(tr, lpcszLabel, bAddWhenNoExist, "");
	if(trNode)
	{
			trNode.strVal = lpszValue;
			return true;
	}
	return false;// node not exist and not created or failed to create
	
}
/// end SET_TREE_NODE_VALUE



///DSC 2/8/05 v8.0190 CONVERT_STRING_TO_TAG_NAME
/*
TreeNode 	NLFunctionList::GetFittingPara(const TreeNode& tr, bool bAddWhenNoExist, const string strSubNode)// = true, ""
{
	return GetNodeCheckAdd(tr, STR_FIT_PARAM, bAddWhenNoExist, strSubNode); 
}
TreeNode 	NLFunctionList::GetFormula(const TreeNode& tr, bool bAddWhenNoExist, const string strSubNode)// = true, ""
{
	return GetNodeCheckAdd(tr, STR_FORMULA, bAddWhenNoExist, strSubNode); 
}
TreeNode	NLFunctionList::GetConstraints(const TreeNode& tr, bool bAddWhenNoExist, const string strSubNode) // = true, ""
{
	return GetNodeCheckAdd(tr, STR_CONSTRAINTS, bAddWhenNoExist, strSubNode);
}
TreeNode 	NLFunctionList::GetParaInit(const TreeNode& tr, bool bAddWhenNoExist, const string strSubNode)// = true, "Script"
{
	return GetNodeCheckAdd(tr, STR_PARAM_INIT, bAddWhenNoExist, strSubNode);
}
*/
TreeNode 	NLFunctionList::GetFittingPara(const TreeNode& tr, bool bAddWhenNoExist, string strSubNode)// = true, ""
{
	return GetNodeCheckAdd(tr, STR_FUNC_FIT_PARAM, bAddWhenNoExist, strSubNode);
}
TreeNode 	NLFunctionList::GetFormula(const TreeNode& tr, bool bAddWhenNoExist, string strSubNode)// = true, ""
{
	return GetNodeCheckAdd(tr, STR_FUNC_FORMULA, bAddWhenNoExist, strSubNode); 
}
TreeNode	NLFunctionList::GetConstraints(const TreeNode& tr, bool bAddWhenNoExist, string strSubNode) // = true, ""
{
	return GetNodeCheckAdd(tr, STR_FUNC_CONSTRAINTS, bAddWhenNoExist, strSubNode);
}

///------ Folger 11/28/09 QA81-14726-P2 80_HAS_MISSED_CONSTANTS_SECTION
TreeNode	NLFunctionList::GetConstants(const TreeNode& tr, bool bAddWhenNoExist/*=true*/, string strSubNode/*=""*/)
{
	return GetNodeCheckAdd(tr, STR_FUNC_CONSTANTS, bAddWhenNoExist, strSubNode);
}
///------ End 80_HAS_MISSED_CONSTANTS_SECTION

///Jasmine 03/02/07 ADD_ENABLE_PARA_INIT_AND_ENABLE_CONSTRAINTS
TreeNode 	NLFunctionList::GetControls(const TreeNode& tr, bool bAddWhenNoExist, string strSubNode)// = true, "Script"
{
	return GetNodeCheckAdd(tr, STR_FUNC_CONTROLS, bAddWhenNoExist, strSubNode);
}
///End ADD_ENABLE_PARA_INIT_AND_ENABLE_CONSTRAINTS
TreeNode 	NLFunctionList::GetParaInit(const TreeNode& tr, bool bAddWhenNoExist, string strSubNode)// = true, "Script"
{
	return GetNodeCheckAdd(tr, STR_FUNC_PARA_INIT, bAddWhenNoExist, strSubNode);
}
///end CONVERT_STRING_TO_TAG_NAME

/// Iris 4/30/2008 QA80-11474 ADD_USE_ORIGINC_CHECKBOX_FOR_PARAM_INIT_SCRIPT
TreeNode 	NLFunctionList::GetCompile(const TreeNode& tr, bool bAddWhenNoExist, string strSubNode)//= true, "Compile"
{
	return GetNodeCheckAdd(tr, STR_FUNC_COMPILE_FUNC, bAddWhenNoExist, strSubNode);
}
///end ADD_USE_ORIGINC_CHECKBOX_FOR_PARAM_INIT_SCRIPT

///Jasmine 11/15/05 QA70-8307 v8.0335 ADD_PARAMETERS_SETTINGS
TreeNode 	NLFunctionList::GetParaSettings(const TreeNode& tr, bool bAddWhenNoExist, string strSubNode)// = true, ""
{
	return GetNodeCheckAdd(tr, STR_FUNC_FIT_PARAM, bAddWhenNoExist, strSubNode);	
}
///End ADD_PARAMETERS_SETTINGS

///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
TreeNode	NLFunctionList::GetDeriParaSettings(const TreeNode& tr, bool bAddWhenNoExist, string strSubNode)
{
	return GetNodeCheckAdd(tr, STR_FUNC_DERIVED_PARAM_SETTINGS, bAddWhenNoExist, strSubNode);
}
///End ADD_UNIT_FOR_PARAMETER_SETTINGS

/// Hong 05/17/07 QA80-9784 FIX_FUNCTION_FORM_CONFLICT_BETWEEN_75_80
bool 	NLFunctionList::UpdateCompileByFunctionForm(TreeNode &trFunction)
{
	if(!trFunction)
		return false;
	
	string strFunctionFrom = trFunction.GeneralInformation.FunctionForm.strVal;
	if(0 == strFunctionFrom.CompareNoCase(STR_FUNCTION_FORM_ORIGIN_C))
	{
		nlf_tree_set_oc_compile(trFunction, true);
	}
	else
	{
		nlf_tree_set_oc_compile(trFunction, false);
	}
	
	return true;
}
/// end FIX_FUNCTION_FORM_CONFLICT_BETWEEN_75_80

///Jasmine 06/23/10 ORG-2-S4 FUNCTION_WIZARD_ALLOW_USER_DEFINED_FUNC_CHANGE_FORM
//mve from FunctionOrganizerEx.h
bool 		NLFunctionList::IsSysFunc(TreeNode trFunc)
{
	if(trFunc && trFunc.GeneralInformation.FunctionType)
	{
		string strFuncType = trFunc.GeneralInformation.FunctionType.strVal;
		return !strFuncType.Compare(STR_FUNCTION_TYPE_BUILD_IN);
	}
	return false;
}

static string _get_current_user_name()
{
	char szUserName[MAX_PATH];
	DWORD dwSize = MAX_PATH;
	if( !GetUserName(szUserName, &dwSize) )
		szUserName[0] = '\0';// caller will need to take care of empty str case

	return szUserName;
}

bool		NLFunctionList::IsCurrentUserShared(TreeNode trFunctionDetail, bool &bSharedFunction)
{
	string strTemp;
	bSharedFunction=trFunctionDetail.GetAttribute(STR_FUNCTION_FORM_SHARE_FILE_ATTRIB, strTemp);
	TreeNode trShareInfo = trFunctionDetail.ShareFunctInfo.CreatorName;
	if(bSharedFunction && trShareInfo.IsValid())
	{
		if(0 != trShareInfo.strVal.CompareNoCase(_get_current_user_name()))
			return false;
	}
	return true;
}
///End FUNCTION_WIZARD_ALLOW_USER_DEFINED_FUNC_CHANGE_FORM

///Jasmine 10/11/05 QA70-8114 v8.0315 ADD_INIT_AND_AFTER_FITTING_SCRIPTS
TreeNode 	NLFunctionList::GetScripts(const TreeNode& tr, LPCSTR lpcszNode, bool bAddWhenNoExist, string strSubNode)// = true, "Script"
{
	return GetNodeCheckAdd(tr, lpcszNode, bAddWhenNoExist, strSubNode);
}
///End ADD_INIT_AND_AFTER_FITTING_SCRIPTS

/// YuI 09/07/05 NLSF_CODE_BUILDER_COMMUNICATION_FIX
TreeNode 	NLFunctionList::GetFunctionOCHeader(const TreeNode& tr, bool bAddWhenNoExist, string strSubNode)
{
	return GetNodeCheckAdd(tr, STR_FUNC_OC_FUNC_HEADER, bAddWhenNoExist, strSubNode);
}

TreeNode 	NLFunctionList::GetParaInitOCHeader(const TreeNode& tr, bool bAddWhenNoExist, string strSubNode)
{
	return GetNodeCheckAdd(tr, STR_FUNC_OC_PARA_INIT_HEADER, bAddWhenNoExist, strSubNode);
}
/// end NLSF_CODE_BUILDER_COMMUNICATION_FIX

///end CENTRALIZE_FUNCTION_FILE_PATH_NAME_CODES






NumFunctionOrganizer::NumFunctionOrganizer()
{
	//check_user_folder(); //Create user fitfunct folder if there isn't exist
	//check_all_user_folder();//Create share folder and user fitfunct folder under alluser folder if there isn't exist
	//---- CPY 1/10/04 NLF_FILE_PATH_CLEANUP
	//CheckMakePath( GET_USER_FOLDER + STR_FDF_FILE_FOLDER+"\\" );
	//CheckMakePath( get_alluserfolder_path(true) + "fitfunc\\" );
	//CheckMakePath(get_origin_path(USER_FOLDER, STR_FDF_FILE_FOLDER));
	//CheckMakePath(get_origin_path(ALL_USER_FOLDER, STR_FDF_FILE_FOLDER));
	CheckMakePath(GetFunctionFolder(USER_FOLDER)); ///DG CENTRALIZE_XFO_AND_NFO
	CheckMakePath(GetFunctionFolder(ALL_USER_FOLDER));
	//----	
}
NumFunctionOrganizer::~NumFunctionOrganizer()
{
	string strTempFilePath;
	for(int nIndex = 0 ; nIndex < m_vsTempFileNoSave.GetSize(); nIndex++ )
	{
		strTempFilePath	= m_vsTempFileNoSave[nIndex];
		DeleteFile(strTempFilePath);
	}
}
//bool 	NumFunctionOrganizer::GetCategoryDetail(TreeNode &trCategory) ///DG CENTRALIZE_XFO_AND_NFO
int		NumFunctionOrganizer::LoadCategory(TreeNode &trCategory, vector<int> &vnInvalidFunctionIndex)
{
	if(!trCategory  || trCategory.GetNodeCount() <= 0)
		return false;
	
	int	nIndex =0;
	
	foreach(TreeNode trFunction in trCategory.Children)
	{
		nIndex ++;
		if( trFunction.GetNodeCount() > 0 )
		{
			///If count bigger than 0, mean function had read in, so skip it.
			continue;
		} 
		else
			///Iris 01/12/05 FO_CENTRALIZE_CODES
			//if(!GetFunctionDetail(trFunction))
			if(!NumFunctionOrganizer::Load(trFunction))
			{
				//m_vnIndexRemove.Add(nIndex);	//Frank 4/23/04	ADD_PARAMETER_TO_STORE_DELECT_FUNCT_INDEX 	///DG 3/4/05 CENTRALIZE_XFO_AND_NFO
				trFunction.Remove();
				continue;
			}
			
		///If after read function detail in function tree, also coutn smaller than 0, mean nothing in function tree.
		if( trFunction.GetNodeCount() <= 0 )
		{
			//m_vnIndexRemove.Add(nIndex);	///DG CENTRALIZE_XFO_AND_NFO
			trFunction.Remove();
			continue;
		};
	}
	return nIndex;
}

bool 	NumFunctionOrganizer::Load(TreeNode &trFunction)
{
	if(!trFunction)
		return false;
	//---- CPY 1/13/04 NLFIT_GETTING_WRONG_FDF_FILE
	////string strFunctionFileName = _get_FDF_path_file_name(trFunction);
	//string strFunctionFileName = GetFuncFileName(trFunction);
	//
	//int nType;
	//if(!trFunction || str_extract_path_type(GetName(trFunction), &nType).IsEmpty() || strFunctionFileName.IsEmpty())
	//	return false;
	//
	//string strFileFullPath = GetFunctionFilePath(nType, strFunctionFileName);
	string strFileFullPath = NumFunctionOrganizer::GetFuncFileName(trFunction, true);
	//----
	
	return NumFunctionOrganizer::Load(trFunction, strFileFullPath);
}
///Sophy 11/6/08 QA80-12442 SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
//bool	 NumFunctionOrganizer::Save(TreeNode &trFunction, LPCSTR lpcszJunk)// = NULL
///Jasmine 06/22/10 ORG-2-S2 WANT_DESTINATION_PATH
//bool	 NumFunctionOrganizer::Save(TreeNode &trFunction, LPCSTR lpcszJunk, string* pstrErr )// = NULL, = NULL
bool NumFunctionOrganizer::Save(TreeNode &trFunction, LPCSTR lpcszJunk/* = NULL*/, string* pstrErr/* = NULL*/, string* pstrDestinationFile/* = NULL*/)
///End WANT_DESTINATION_PATH
///end SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
{
	int nPath;
	string strModify, strCategoryName, strFileName=GetFuncFileName(trFunction, true, &nPath);
	trFunction.GetAttribute(STR_CATEGORY_ATTRIB, strCategoryName);
	if(strCategoryName.IsEmpty())
		return false;
	
	///Sophy 11/6/08 QA80-12442 SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
	//if(!SaveToFile(trFunction, NULL))
	if(!SaveToFile(trFunction, NULL, pstrErr, pstrDestinationFile))//if(!SaveToFile(trFunction, NULL, pstrErr))///Jasmine 06/22/10 ORG-2-S2 WANT_DESTINATION_PATH
	///end SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
		return false;
	string strOldFile;
	if(trFunction.GetAttribute(STR_OLDFILENAME_ATTRIB, strOldFile))
		DeleteFile(strOldFile);
	
	if(trFunction.GetAttribute(STR_CHANGED_ATTRIB, strModify))
	{
		string strFunctionName=NumFunctionOrganizer::GetFunctionName(trFunction);
		UpdateFunctionToNLSF(strCategoryName, strFunctionName, okutil_separate_composite_name(strModify), strFileName, nPath);
		///Cheney 2007-5-25 DO_SAVE_FDF
		/////Jasmine 11/15/06 DELETE_PRECOMPILE_FILES
		//string strFile = okutil_get_origin_path(ORIGIN_PATH_USER, NULL, TRUE) +"OriginC\NLSF\_nlf"+ strFunctionName + ".fit";
		//_delete_file(strFile);
		//strFile = okutil_get_origin_path(ORIGIN_PATH_USER, NULL, TRUE) +"OriginC\NLSF\_nlp"+ strFunctionName + ".fit";
		//_delete_file(strFile);
		/////End DELETE_PRECOMPILE_FILES
		nlf_delete_precompile_files(strFunctionName);
		/////end DO_SAVE_FDF
	}
	NOTIFY_FDF_FILE_CHANGE ///DG 4/8/05
	return true;
}
///end CENTRALIZE_XFO_AND_NFO
///Sophy 11/6/08 QA80-12442 SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
//bool 	NumFunctionOrganizer::SaveToFile(TreeNode &trFunction, LPCSTR lpcszFullpathFilename)// = NULL
///Jasmine 06/22/10 ORG-2-S2 WANT_DESTINATION_PATH
//bool 	NumFunctionOrganizer::SaveToFile(TreeNode &trFunction, LPCSTR lpcszFullpathFilename, string* pstrErr )// = NULL, = NULL
bool NumFunctionOrganizer::SaveToFile(TreeNode &trFunction, LPCSTR lpcszFullpathFilename/* = NULL*/, string* pstrErr/* = NULL*/, string* pstrDestinationFile/* = NULL*/)
///End WANT_DESTINATION_PATH
///end SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
{
	if (!trFunction)
		return false;
	
	string strFullFileName(lpcszFullpathFilename);
	if(strFullFileName.IsEmpty())
	{
		int nType;
		strFullFileName=NumFunctionOrganizer::GetFuncFileName(trFunction, true, &nType);
		/// Hong 07/25/08 QA80-11593 FIX_BUILD_IN_FDF_USER_ADDED_DERIVED_PARAMETERS_LOST_IN_FIT_REPORT
		/*
		///Jasmine 06/08/07 NEW_MECHANISM_TO_SAVE_BUILT_IN_FUNCTION
		if(SYS_FOLDER == nType)	//sys function should be saved as user
			//strFullFileName=GetFunctionFileFullPath(NumFunctionOrganizer::GetFuncFileName(trFunction), USER_FOLDER);
			return nlsf_save_to_customized_xml(trFunction);	
		///End NEW_MECHANISM_TO_SAVE_BUILT_IN_FUNCTION
		*/
		/// end FIX_BUILD_IN_FDF_USER_ADDED_DERIVED_PARAMETERS_LOST_IN_FIT_REPORT
	}
	///Sophy 11/7/08 QA80-12442 SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
	//if(!nlsf_tree_to_FDF(strFullFileName, &trFunction))
	string	strTargetFileName;
	if(!nlsf_tree_to_FDF( strFullFileName, &trFunction, &strTargetFileName ))
	///end SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
	///Sophy 11/6/08 QA80-12442 SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
		//return false;
	{
		///Sophy 11/7/08 QA80-12442 SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
		//if(pstrErr)
			//ocu_load_msg_str(CER_SAVE_READ_ONLY_FILE_FAIL, pstrErr, strTargetFileName);
		if( pstrErr )
		{
			if( strTargetFileName.IsEmpty() )
				*pstrErr = _L("Save Function Fail!!!");
			else
				ocu_load_msg_str(CER_SAVE_READ_ONLY_FILE_FAIL, pstrErr, strTargetFileName);
		}
		///end SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
		return false;
	}
	///end SHOW_WARNING_WHEN_SAVE_READ_ONLY_FILE
	
	NOTIFY_FDF_FILE_CHANGE //--- CPY 3/17/05

	if( m_vsTempFileNoSave.GetSize() != 0 )
	{
		int nFileIndex = m_vsTempFileNoSave.Find(strFullFileName);
		if(nFileIndex >= 0 )
			m_vsTempFileNoSave.RemoveAt(nFileIndex);
	}
	
	///Jasmine 06/22/10 ORG-2-S2 WANT_DESTINATION_PATH
	if(pstrDestinationFile)
	{
		*pstrDestinationFile = strTargetFileName.IsEmpty()? strFullFileName : strTargetFileName;
	}
	///End WANT_DESTINATION_PATH
	
	return true;
}
///Jasmine 06/11/07 INTERACTIVE_CHANGE_SAVING_BETWEEN_FO_AND_NLFIT
bool 	NumFunctionOrganizer::Reset(TreeNode& trFunction)
{
	return nlsf_remove_from_customized_xml(trFunction);
}
///End INTERACTIVE_CHANGE_SAVING_BETWEEN_FO_AND_NLFIT
bool	NumFunctionOrganizer::UpdateFunctionToNLSF(LPCSTR lpcszCategoryName, LPCSTR lpcszNewName, LPCSTR lpcszOldName, LPCSTR lpcszFileName, int nINIPath)
{
	//------ Folger 02/18/08 QA80-10976 ADD_MOVE_ETC_OPERATIONS_IN_FUNCTION_ORGANIZER_CONTEXTMENU
	//always should not saved in EXE folder
	if ( nINIPath == ORIGIN_PATH_SYSTEM )
		nINIPath = ORIGIN_PATH_USER;
	//------
	
	/// Kenny 11/11/2009 QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
/*
	string strINIFileUser=nlf_get_ini_filepath(nINIPath), strOldName(lpcszOldName), strNewName(lpcszNewName);
	string strFileName = UNDEF_FOLDER == nINIPath? lpcszFileName : GetFileName(lpcszFileName, true);///Jasmine 07/25/07 SOME_FUNCTIONS_ARE_NOT_IN_SYSTEM_OR_USER_FILE_FOLDER
	INIFile iniNLSF(strINIFileUser, USER_FOLDER == nINIPath);
	bool bRet=true;
	if(!strOldName.IsEmpty())
		bRet &= update_ini_line(iniNLSF, lpcszCategoryName, strOldName, NULL);
	if(bRet && !strNewName.IsEmpty())
		bRet &= update_ini_line(iniNLSF, lpcszCategoryName, strNewName, strFileName);
	return bRet;
*/
	return nlsf_update_function(lpcszCategoryName, lpcszNewName, lpcszOldName, lpcszFileName, nINIPath);
	/// End QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
}
bool	NumFunctionOrganizer::UpdateCategoryToNLSF(LPCSTR lpcszNewName, LPCSTR lpcszOldName, int nINIPath)
{
	/// Kenny 11/11/2009 QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
/*
	string strINIFileUser=nlf_get_ini_filepath(nINIPath), strOldName(lpcszOldName), strNewName(lpcszNewName);
	INIFile iniNLSF(strINIFileUser, USER_FOLDER == nINIPath);
	///Jasmine 11/07/06 ALLOW_RENAME_USER_DEFINED_CATEGORY 
	vector<string> vsKeys, vsValues, vsCKeys, vsCValues;
	int nPos;
	bool bRet=true;
	if(!strOldName.IsEmpty() && !strNewName.IsEmpty())
	{
		bRet &= nlf_get_section_keys_and_values(strOldName, vsKeys, vsValues, NULL, nINIPath);	//record old value
		bRet &= nlf_get_section_keys_and_values(STR_NODE_CATEGORY, vsCKeys, vsCValues, NULL, nINIPath);//record old value in category list to keep order
	}
	///Jasmine 03/16/06 UPDATE_NLSF_INI
	//if(strNewName.IsEmpty())
	if(!strOldName.IsEmpty())
	{
		bRet &= update_ini_line(iniNLSF, STR_NODE_CATEGORY, strOldName, NULL);	//delete old category in category list
		if(!strNewName.IsEmpty())
			bRet &= update_ini_line(iniNLSF, STR_NODE_CATEGORY, NULL, NULL);//delete the whole old category list 
		if(bRet)
			bRet &= update_ini_line(iniNLSF, strOldName, NULL, NULL);	//delete old category and the functions
		nPos = vsCKeys.Find(strOldName);
	}
	//else
	if(!strNewName.IsEmpty())
	///End UPDATE_NLSF_INI
	{
		//update_ini_line(iniNLSF, STR_NODE_CATEGORY, strNewName, STR_FDF_FILE_FOLDER);
		//nlf_set_section_keys_and_values(strNewName, vsKeys, vsValues, NULL, nINIPath);	//set new
		for(int nIndex =0 ;nIndex <  vsKeys.GetSize(); nIndex++)
			bRet &= update_ini_line(iniNLSF, strNewName, vsKeys[nIndex], vsValues[nIndex]);
		if(strOldName.IsEmpty())
			update_ini_line(iniNLSF, STR_NODE_CATEGORY, strNewName, STR_FDF_FILE_FOLDER);
		else
		{
			if(nPos > -1 && nPos < vsCKeys.GetSize())
				vsCKeys[nPos] = strNewName;
			for(nIndex =0 ;nIndex <  vsCKeys.GetSize(); nIndex++)
				bRet &= update_ini_line(iniNLSF, STR_NODE_CATEGORY, vsCKeys[nIndex], vsCValues[nIndex]);
		}
	}
	///End ALLOW_RENAME_USER_DEFINED_CATEGORY
	return bRet;
*/
	return nlsf_update_category(lpcszNewName, lpcszOldName, nINIPath);
	/// End QA81-14624 SUPPORT_DRAG_AND_DROP_MULTIPLE_ORIGIN_FILES
}
///end INI_FILE_CLEAN_UP
bool 	NumFunctionOrganizer::MoveDeleteFunctionFileToFolder(TreeNode &trDel)
{
	if(!trDel)
		return false;
	string strFileName;
	string strFilePath;
	int nFuncFolder;
	
	strFileName = NumFunctionOrganizer::GetFuncFileName(trDel, false, &nFuncFolder);
	if(SYS_FOLDER == nFuncFolder)	
		return true;
	
	if(trDel.GetAttribute(STR_CURRENT_SHARE_STATE_ATTRIB, strFilePath))
		nFuncFolder=ALL_USER_FOLDER;
	else
		nFuncFolder=USER_FOLDER;
	
	//string	strDeletePath = GetFunctionFilePath(nFuncFolder, "", true); ///DG CENTRALIZE_XFO_AND_NFO
	string	strDeletePath = GetFunctionFolder(nFuncFolder, STR_FDF_DELETE_FILE_FOLDER);
	
	if(!CheckMakePath( strDeletePath))
		return false;
	
	strDeletePath = GetFunctionFileFullPath(strFileName, nFuncFolder, STR_FDF_DELETE_FILE_FOLDER);
	strFilePath = GetFunctionFileFullPath(strFileName, nFuncFolder);
	
	if(strFilePath.IsFile())
	{
		CopyFile(strFilePath,strDeletePath);
		DeleteFile(strFilePath);
	}
	return true;
}

///Jasmine 11/02/06 FUNC_AND_FILE_NAME_ONE_TO_ONE
bool 	NumFunctionOrganizer::CreateTempFileOfFunction(TreeNode &trNewFunction ,string strFunctionName, bool bCheck)//true	
{
	///Remove the share info from function file.
	if(trNewFunction.ShareFunctInfo)
	{
		trNewFunction.ShareFunctInfo.Remove();
	}
	trNewFunction.RemoveAttribute(STR_CURRENT_SHARE_STATE_ATTRIB);
	trNewFunction.RemoveAttribute(STR_FUNCTION_FORM_SHARE_FILE_ATTRIB);
	
	string strFileName = strFunctionName;
	if(bCheck)
		CheckGetFunctionFilename(strFileName, true);
	string strFilePath = GetFunctionFileFullPath(strFileName, USER_FOLDER);
	if(!strFilePath.IsFile())//shouldn't delete file if it already exists
		m_vsTempFileNoSave.Add(strFilePath);	
	if(!nlsf_tree_to_FDF(strFilePath, &trNewFunction))
		return false;
	NumFunctionOrganizer::SetFuncFileName(trNewFunction, strFilePath);
///End FUNC_AND_FILE_NAME_ONE_TO_ONE	
	return true;
}
/**
Return value: If file exist and not create new file name will return false; if file not exist or create new file name will return true.
*/
bool 	NumFunctionOrganizer::CheckGetFunctionFilename( string &strFileName,  bool bCreateNameWhenNoExist )//= false
{
	string strUserFolderFileName = GetFunctionFileFullPath(strFileName, USER_FOLDER);
	string strSysFolderFileName = GetFunctionFileFullPath(strFileName, SYS_FOLDER);
	string strAllUsersFolderFileName = GetFunctionFileFullPath(strFileName, ALL_USER_FOLDER);
	
	//Check if this file exist in user folder or system folder
	if(strUserFolderFileName.IsFile() || strSysFolderFileName.IsFile() || strAllUsersFolderFileName.IsFile())
	{
		if(!bCreateNameWhenNoExist)
			return true;
		
		createNewFileName(strFileName);
		return false;
	}
	else
		return false;
	
	return true;
}
bool 	NumFunctionOrganizer::New(TreeNode &trNewFunction, string strFunctionName)//=""
{
	if(!trNewFunction)
		return false;
	
	if(strFunctionName.IsEmpty())
		strFunctionName=STR_NEW_FUNCTION_PREFIX;
	
	Tree trFunctionNew;
	
	if( !nlsf_create_FDF_tree( &trFunctionNew ))
	{
		return false;
	};
	//Constructor NODE_INDEPENDENT_VARIABLES
	TreeNode trNodeTemp;
	//trNodeTemp = trFunctionNew.GetNode("IndependentVariables", false);
	trNodeTemp = trFunctionNew.GetNode(cvt_str_to_tag_name(STR_FUNC_INDEPENDENT_VARS), false);
	trNodeTemp.AddNode("x");
	
	trNodeTemp = trFunctionNew.GetNode(cvt_str_to_tag_name(STR_FUNC_DEPENDENT_VARS), false);
	trNodeTemp.AddNode( "y");
	
	trNodeTemp = trFunctionNew.GetNode(cvt_str_to_tag_name(STR_FUNC_FORMULA), false);
	
	trNodeTemp = trFunctionNew.GetNode(cvt_str_to_tag_name(STR_FUNC_INITIALIZATIONS), false);
	trNodeTemp.AddNode( cvt_str_to_tag_name(STR_FUNC_SCRIPT) );//,2);
	
	trNodeTemp = trFunctionNew.GetNode(cvt_str_to_tag_name(STR_FUNC_AFTER_FITTING), false);
	trNodeTemp.AddNode( cvt_str_to_tag_name(STR_FUNC_SCRIPT) );//,3);

	trNodeTemp = trFunctionNew.GetNode(cvt_str_to_tag_name(STR_FUNC_CONSTANTS), false);
	
	trNodeTemp = trFunctionNew.GetNode(cvt_str_to_tag_name(STR_FUNC_PARA_INIT), false);
	trNodeTemp.AddNode( cvt_str_to_tag_name(STR_FUNC_SCRIPT));
	
	trNodeTemp = trFunctionNew.GetNode( cvt_str_to_tag_name(STR_FUNC_COMPILE_FUNC), false);
	//trNodeTemp.AddNumericNode(0, STR_FUNC_COMPILE, 23564);
	trNodeTemp.AddNumericNode(1, STR_FUNC_COMPILE, 23564);// YuI 11/09/04 changed default
	trNodeTemp.AddNumericNode(1, STR_FUNC_PARAM_INIT_COMPILE,23566);
	trNodeTemp.AddNumericNode(0, STR_FUNC_ON_PARAM_CHANGE_SCRIPT_ENABLE);
	//Init the new function value
	if(trFunctionNew.IsValid())
	{
		/// DSC 2/8/05 v8.0189 DELETE_NODE_NAME_CONSTANTS
		//Init the GeneralInformation
		trFunctionNew.GeneralInformation.FunctionName.strVal = strFunctionName;
		trFunctionNew.GeneralInformation.FunctionType.strVal = STR_FUNCTION_TYPE_USER_DEFINE;
		trFunctionNew.GeneralInformation.FunctionForm.strVal = STR_FUNCTION_FORM_ORIGIN_C; // YuI 10/28/04 changed default
		///---Frank 2/6/04	V8.0881	QA70-6086	ADD_SOURCE_IN_NEW_FUNCTION_TREE	
		trFunctionNew.GeneralInformation.FunctionSource.strVal = STR_NO_DLL_SOURCE;//"fgroup." + strFunctionName;	///Jasmine 04/16/09 QA80-13424 FUNCTION_SOURCE_SHOULD_LEFT_TO_USER
		///End 	ADD_SOURCE_IN_NEW_FUNCTION_TREE
		trFunctionNew.GeneralInformation.NumberOfParameters.nVal = 1;
		//trFunction.GeneralInformation.NumberOfParameters.nVal = 0;
		trFunctionNew.GeneralInformation.NumberOfIndependentVariables.nVal = 1;
		trFunctionNew.GeneralInformation.NumberOfDependentVariables.nVal = 1;
		
		//Init the Fitting Parameters
		trFunctionNew.FittingParameters.Names.strVal  = "A";
		trFunctionNew.Formula.Script.strVal  = "y = x + A";///Frank 12/04/04 add "y=x+a" default, because if empty will get compiler error when simulation.
		trFunctionNew.ParametersInitialization.Script.strVal  = "//Code to be executed to initialize parameters";
	    /// ML 5/11/2004
	    trFunctionNew.FittingParameters.NamingMethod.strVal  = STR_FUNCTION_TYPE_USER_DEFINE;
	    /// end ML 5/11/2004
	    /// ML 5/11/2004
	    //trFunction.Formula.Script.strVal  = "X+A";//"";//"X+A";
	   /// end ML 5/11/2004
	   /// YuI 7/22/04 v7.5102 QA70-6404 NEW_FUNCTION_MANAGER
	   trFunctionNew.OriginCFunctionHeader.Script.strVal = "";
	   trFunctionNew.OriginCParameterInitializationHeader.Script.strVal = "";
		/// end NEW_FUNCTION_MANAGER
	}
	else
		return false;
	
	nlf_tree_set_oc_compile(trFunctionNew, true); ///Frank 12/04/04 add this set compiler.
	
	trNewFunction.Replace(trFunctionNew, true, true,true);
	SetLabel(trNewFunction, GetFunctionNameStr(strFunctionName, USER_FOLDER));
	SetDisplayIcon(trNewFunction, IDR_IMPORTED_FILE);	///DG 4/7/05 FOLDER_WITH_DISPLAY_ICON
	///Hong 8/01/06 REMOVE_NUM_OF_FUNCTION_NAME
	int nLength = strFunctionName.GetLength()-1;
	char cTemp = strFunctionName.GetAt(nLength);
	while('0' <= cTemp && cTemp <= '9')
	{
		strFunctionName.Delete(nLength);
		nLength--;
		cTemp = strFunctionName.GetAt(nLength);
	}
	///end REMOVE_NUM_OF_FUNCTION_NAME
	if(!CreateTempFileOfFunction(trNewFunction, strFunctionName))
		return false;
	return true;
}

bool	NumFunctionOrganizer::Duplicate(TreeNode &trFunction, TreeNode trSource, string strName) //=""
{
	string strFileName;
	if(trSource.IsValid())
	{
		strFileName = NumFunctionOrganizer::GetFuncFileName(trSource);
		
		if(!trFunction.Replace(trSource, true, true))
			return false;
		
		if(strName.IsEmpty())
		{
			strName=STR_DUPLICATE_PREFIX+NumFunctionOrganizer::GetFunctionName(trSource);
		}
		NumFunctionOrganizer::SetFunctionName(trFunction, strName);
		changeFunctionTypeToUserDefine(trFunction);
	}
	checkAndUpdateFunctionPreviewString(trFunction,strFileName );
	string strNewFileName = "CopyOf" + strFileName;
	CreateTempFileOfFunction(trFunction, strNewFileName);
	return true;
}
bool 	NumFunctionOrganizer::Delete(TreeNode &trFunction, bool bRemoveFile)
{
	if(!trFunction)
		return false;
	string strCategoryName, strFuncName=GetFunctionName(trFunction);
	trFunction.GetAttribute(STR_CATEGORY_ATTRIB, strCategoryName);
	int nPath;
	//--------Folger 07/11/07 CORRECT_DELETE_BEHAVIOR_ONLY_DELETE_CONTENT_OF_USER_FOLDER_INI
	//NumFunctionOrganizer::GetFuncFileName(trFunction, true, &nPath);
	nPath = USER_FOLDER;
	//--------end CORRECT_DELETE_BEHAVIOR_ONLY_DELETE_CONTENT_OF_USER_FOLDER_INI
	
	if(canRemoveFromIniFile(trFunction) && !UpdateFunctionToNLSF(strCategoryName, NULL, strFuncName, NULL, nPath))
		return false;
	
	if ( bRemoveFile )
	{
		MoveDeleteFunctionFileToFolder(trFunction);
		NOTIFY_FDF_FILE_CHANGE ///DG 4/8/05
	}
	return true;
}
bool	NumFunctionOrganizer::canRemoveFromIniFile(TreeNode trFunction)
{
	string strFileName;
	int nFolder, nRelatedFolder;
	strFileName = GetFuncFileName(trFunction, false, &nFolder); //just for getting nFolder
	switch(nFolder)
	{
	case SYS_FOLDER:
		nRelatedFolder=USER_FOLDER;
		break;
	case USER_FOLDER:
		nRelatedFolder=SYS_FOLDER;
		break;
	default:
		return true;
	}
	strFileName=GetFunctionFileFullPath(strFileName, nRelatedFolder);
	return !strFileName.IsFile();
}
///end CENTRALIZE_XFO_AND_NFO
bool 	NumFunctionOrganizer::DeleteCategory( TreeNode &trCategory, bool bRemoveFile )
{
	if(!trCategory )
		return false;
	///DG INI_FILE_CLEAN_UP
	//if(!updateIniFile(trCategory,true,"", NLSF_SECTION_DEL))
	string strName=GetLabel(trCategory);
	//--------Folger 07/11/07 CORRECT_DELETE_BEHAVIOR_ONLY_DELETE_CONTENT_OF_USER_FOLDER_INI
	//vector<int> vnExistFunctionPathType;
	//FindCategoryPath(trCategory, vnExistFunctionPathType);
	//for(int ii=0; ii<vnExistFunctionPathType.GetSize(); ii++)
	//{
		//if(!UpdateCategoryToNLSF(NULL, strName, vnExistFunctionPathType[ii]))
			//return false;
	//}
	if (!UpdateCategoryToNLSF(NULL, strName, USER_FOLDER))
		return false;
	//--------Folger 07/11/07 CORRECT_DELETE_BEHAVIOR_ONLY_DELETE_CONTENT_OF_USER_FOLDER_INI
	///end INI_FILE_CLEAN_UP
	if ( bRemoveFile )
	{
		foreach(TreeNode trFunction in trCategory.Children)
		{
			MoveDeleteFunctionFileToFolder(trFunction);
		};
		NOTIFY_FDF_FILE_CHANGE ///DG 4/8/05
	}
	return true;
}
///Cheney 2007-5-9 CLEAN_UP_CODE_FOR_NUMFUNC_LOAD	
//bool		NumFunctionOrganizer::Load(TreeNode &trFunction, LPCSTR lpcszFullpathFilename, string strName) //=""
bool		NumFunctionOrganizer::Load(TreeNode &trFunction, LPCSTR lpcszFullpathFilename, LPCSTR lpcszFunctionName, bool bLoadFDF) //=NULL, true
///end CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
{
	if(!trFunction)
		return false;
	
	///Cheney 2007-5-9 CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
	//if(!NLFunctionList::Load(trFunction, lpcszFullpathFilename, strName))
	if(!NLFunctionList::Load(trFunction, lpcszFullpathFilename, lpcszFunctionName, bLoadFDF))
	///end CLEAN_UP_CODE_FOR_NUMFUNC_LOAD
		return false;
	
	checkAndUpdateFunctionPreviewString(trFunction,lpcszFullpathFilename );
	return true;
}
bool	NumFunctionOrganizer::Add(TreeNode &trFunction, LPCSTR lpcszFullpathFilename, string strName) //=""
{
	if(!NumFunctionOrganizer::Load(trFunction, lpcszFullpathFilename, strName))
		return false;
	
	if(strName.IsEmpty())
		strName=GetFunctionName(trFunction);
	//------ Folger 02/18/08 QA80-10976 ADD_MOVE_ETC_OPERATIONS_IN_FUNCTION_ORGANIZER_CONTEXTMENU
	//SetLabel(trFunction, GetFunctionNameStr(okutil_separate_composite_name(strName), USER_FOLDER));
	int nPath;
	SetLabel(trFunction, GetFunctionNameStr(okutil_separate_composite_name(strName), nPath = okutil_get_origin_path_type(lpcszFullpathFilename)));
	//------
	///Jasmine 11/02/06 FUNC_AND_FILE_NAME_ONE_TO_ONE
	string strFileName=GetFileName(lpcszFullpathFilename, true);
	//------ Folger 02/18/08 QA80-10976 ADD_MOVE_ETC_OPERATIONS_IN_FUNCTION_ORGANIZER_CONTEXTMENU
	///------ Folger 07/13/10 ORG-543 PROMPT_USER_FOR_WHETHER_COPY_FDF_TO_UFF_WHEN_ADD_IN_FO
	//if ( nPath != ORIGIN_PATH_SYSTEM )
	BOOL	bCopyToUFF = nPath != ORIGIN_PATH_SYSTEM && MessageBox(GetOwnerHwnd(), STR_MSG_COPY_FILE, STR_MSG_CAPTION, MB_YESNO) == IDYES;
	if ( bCopyToUFF )
	///------ End PROMPT_USER_FOR_WHETHER_COPY_FDF_TO_UFF_WHEN_ADD_IN_FO
	{
	//------
		if(!CreateTempFileOfFunction(trFunction, strName, false))//strFileName))
			return false;
	//------ Folger 02/18/08 QA80-10976 ADD_MOVE_ETC_OPERATIONS_IN_FUNCTION_ORGANIZER_CONTEXTMENU
	}
	//------
	///End FUNC_AND_FILE_NAME_ONE_TO_ONE
	NOTIFY_FDF_FILE_CHANGE ///DG 4/8/05
	return true;
}
void 	NumFunctionOrganizer::checkAndUpdateFunctionPreviewString(TreeNode &trFunction, LPCSTR lpcstrFunctionFile)
{
	if(!trFunction && !trFunction.GeneralInformation)
		return ;
	TreeNode trFunctionPrev= trFunction.GeneralInformation.FunctionPrev;
	if( !trFunctionPrev )
	{
		string strFileName = lpcstrFunctionFile;
		if(strFileName.GetToken(0,'\\').IsPath())
			strFileName = GetFileName(strFileName, true);
		
		trFunctionPrev = trFunction.GeneralInformation.AddNode("FunctionPrev");
		trFunctionPrev.strVal = strFileName;
	}
}


bool 	NumFunctionOrganizer::changeFunctionTypeToUserDefine(TreeNode &trFunction)
{
	///Jasmine 11/14/06 CHANGE_BUILT_IN_TO_USER_DEFINED
	//built-in function is un-editable, its type won't be changed.
	//But after duplicate a built-in function, we should change its type to user-defined
	///DG 1/4/05 : Don't allow change Build-in function
	if(!trFunction)
		return false;
	
	string strFuncType = trFunction.GeneralInformation.FunctionType.strVal;
	//if(0 == strFuncType.CompareNoCase(STR_FUNCTION_TYPE_BUILD_IN))
		//return false;
	///End CHANGE_BUILT_IN_TO_USER_DEFINED
	///Jasmine 06/05/07 QA80-9853 NEED_CHECK_STR_COMPILE_PARAM_SCRIPT_FOR_75_FDF
	if(!strFuncType.CompareNoCase(STR_FUNCTION_TYPE_BUILD_IN))
	{
		TreeNode trEnable  = GetControls(trFunction, false, STR_FUNC_ENABLE_PARAMETERS_INIT);
		TreeNode trComplie = GetControls(trFunction, false, STR_COMPILE_PARAM_SCRIPT);
		if(!trEnable && !trComplie)
		{
			GetControls(trFunction, true, STR_FUNC_ENABLE_PARAMETERS_INIT).nVal = 1;
			GetControls(trFunction, true, STR_COMPILE_PARAM_SCRIPT).nVal = 1;
		}
		///Jasmine 06/07/07 QA80-9853 SET_FORM_ORIGIN_C_AND_COPILE_1_FOR_BUILT_IN
		trFunction.GeneralInformation.FunctionForm.strVal =STR_FUNCTION_FORM_ORIGIN_C;
		nlf_tree_set_oc_compile(trFunction, true);
		///End SET_FORM_ORIGIN_C_AND_COPILE_1_FOR_BUILT_IN
	}
	///End NEED_CHECK_STR_COMPILE_PARAM_SCRIPT_FOR_75_FDF
	
	//if(0 != strFuncType.CompareNoCase(STR_FUNCTION_TYPE_USER_DEFINE))	///Jasmine 08/05/08 QA80-11917 KEEP_EXTERNAL_DLL_AFTER_DUPLICATE
	if(0 == strFuncType.CompareNoCase(STR_FUNCTION_TYPE_BUILD_IN))
		trFunction.GeneralInformation.FunctionType.strVal =STR_FUNCTION_TYPE_USER_DEFINE;
	///Jasmine 06/07/07 QA80-9853 SET_FORM_ORIGIN_C_AND_COPILE_1_FOR_BUILT_IN, no need
	/*
	string strFunctionFrom = trFunction.GeneralInformation.FunctionForm.strVal;
	if(0 == strFunctionFrom.CompareNoCase(STR_FUNCTION_FORM_ORIGIN_C))
	{
		nlf_tree_set_oc_compile(trFunction, true);
	}
	else
	{
		nlf_tree_set_oc_compile(trFunction, false);
		string strFormula = trFunction.Formula.Script.strVal;
		if(strFormula.Count('=')>0)
		{
			trFunction.GeneralInformation.FunctionForm.strVal =STR_FUNCTION_FORM_EQUATIONS;
			nlf_tree_set_oc_compile(trFunction, true);
		}
		else
			trFunction.GeneralInformation.FunctionForm.strVal =STR_FUNCTION_FORM_EXPRESSION;
	}
	*/
	///End SET_FORM_ORIGIN_C_AND_COPILE_1_FOR_BUILT_IN
	return true;
}

//TreeNode 	NumFunctionOrganizer::NewCategory( TreeNode &trCategory , bool bCreateNewFunction, string strCategoryName)
bool	NumFunctionOrganizer::NewCategory(TreeNode &trCategory, string strName) //=""
{
	if( !trCategory.IsValid())
		return false;
	//trCategory.SetAttribute(STR_DISPLAY_ATTRIB, IDI_FOLDER_CLOSED); ///DG FOLDER_WITH_DISPLAY_ICON
	SetDisplayIcon(trCategory, IDI_FOLDER_CLOSED);
	return NumFunctionOrganizer::SaveCategoryName(trCategory, strName);
}
//Dupli trCategory  
//bool 	NumFunctionOrganizer::DuplicateCategory( TreeNode &trCategory, TreeNode &trCategoryNew, string strCategoryName)	//="" ///DG CENTRALIZE_XFO_AND_NFO
bool	NumFunctionOrganizer::DuplCategory(TreeNode &trCategory, TreeNode trSource, string strName) //=""
{
	if( !trSource.IsValid())
		return false;
	
	string strFunctionName;
	strFunctionName = GetLabel(trSource);
	if(strName.IsEmpty())
		strName="CopyOf" + strFunctionName;
	
	//SetLabel(trCategory, strName);
	NumFunctionOrganizer::NewCategory(trCategory, strName);
	
	string  strDuplicateFunctionName ;
	TreeNode trDuplicateFunction;
	int nIndex =1;
	foreach(TreeNode trFunction in trSource.Children)
	{
		strDuplicateFunctionName = NumFunctionOrganizer::GetFunctionName(trFunction, true); //keep sub function name the same
		trDuplicateFunction = trCategory.AddNode("Function" + nIndex);
		NumFunctionOrganizer::Duplicate(trDuplicateFunction, trFunction, strDuplicateFunctionName);
		nIndex++;
	}
	return true;
}
bool	NumFunctionOrganizer::SaveCategoryName(TreeNode &trCategory, string strName)
{
	if(!trCategory)
		return false;
	///Sophy 7/20/2010 ORG-598-P1 PROPER_CHECK_AND_UPDATE_CATEGORY_NAME
	vector<int> vnINIGroup;
	FindCategoryPath(trCategory, vnINIGroup);
	if ( find_in_list(ORIGIN_PATH_USER, vnINIGroup, false) < 0 )
		vnINIGroup.Add(ORIGIN_PATH_USER);
	///end PROPER_CHECK_AND_UPDATE_CATEGORY_NAME
	string strOldName=GetLabel(trCategory);
	if(strOldName.IsEmpty() && strName.IsEmpty())
		return false;
	
	SetLabel(trCategory, strName);
	///Sophy 7/20/2010 ORG-598-P1 PROPER_CHECK_AND_UPDATE_CATEGORY_NAME
	//vector<int> vnINIGroup;
	//if(1 > FindCategoryPath(trCategory, vnINIGroup))
	//	vnINIGroup.Add(ORIGIN_PATH_USER);
	///end PROPER_CHECK_AND_UPDATE_CATEGORY_NAME
	for(int ii=0; ii<vnINIGroup.GetSize(); ii++)
	{
		UpdateCategoryToNLSF(strName, strOldName, vnINIGroup[ii]);
	}
	NOTIFY_FDF_FILE_CHANGE	///DG 4/8/05
	return true;
}
bool	NumFunctionOrganizer::SaveSimulateTree(TreeNode trFunction)
{
	Tree tr;
	string strFile = GetFuncFileName(trFunction, true);
	NumFunctionOrganizer::Load(tr, strFile);
	
	TreeNode trSimulate=trFunction.GetNode(STR_SIMULATE_NODE, false);
	TreeNode trCurve=trFunction.GetNode(STR_CURVE_NODE, false);
	///Frank 1/3/05 CHECK_SIMULATE_NODE_EXIST
	if(trSimulate)
		//tr.AddNode(trSimulate);
	{
		TreeNode trFDFSimulate = GetNodeCheckAdd(tr,STR_SIMULATE_NODE, true );
		trFDFSimulate.Replace(trSimulate); 	
	}
	if(trCurve)
		//tr.AddNode(trCurve);
	{
		TreeNode trFDFCurve = GetNodeCheckAdd(tr,STR_CURVE_NODE, true );
		trFDFCurve.Replace(trCurve);
	}
	///End CHECK_SIMULATE_NODE_EXIST
	
	return NumFunctionOrganizer::SaveToFile(tr);
}
void	NumFunctionOrganizer::createNewFileName(string &strNewFuncFilename  ) // 1
{
	int nIndex =1;
	string strTemp = strNewFuncFilename;
	string strUserFolderFileName ;
	string strSysFolderFileName ;
	string strAllUsersFolderFileName;
	do
	{
		strNewFuncFilename = strTemp + nIndex;
		strUserFolderFileName = GetFunctionFileFullPath(strNewFuncFilename, USER_FOLDER);
		strSysFolderFileName = GetFunctionFileFullPath(strNewFuncFilename, SYS_FOLDER);
		strAllUsersFolderFileName = GetFunctionFileFullPath(strNewFuncFilename, ALL_USER_FOLDER);
		///Sophy 7/15/2010 ORG-518 EMPTY_PATH_MAKE_FILE_CHECK_CONFUSING
		string strAllUsersFolder = GetFunctionFolder(ALL_USER_FOLDER, "");
		if ( strAllUsersFolder.IsEmpty() )
			strAllUsersFolderFileName.Empty(); //clean it.
		///end EMPTY_PATH_MAKE_FILE_CHECK_CONFUSING
		nIndex++;
	}while(strUserFolderFileName.IsFile() || strSysFolderFileName.IsFile() || strAllUsersFolderFileName.IsFile())
}
///------end CLEAN_DUPLICATE_MORE
///Jasmine 05/13/10 ORG-2 MOVE_FUNCTION_TO_BASE_CLASS_FOR_FITFUNCWIZ
///Jasmine 05/21/07 NEED_GET_ENUM_FROM_ALL_CATEGORY
string NumFunctionOrganizer::CreateNewFunctionName(TreeNode &trFitFunctions, string strAttribute, string strPrefix, string strPostfix)
{
	vector<string> vsAttribVals;
	foreach(TreeNode cNode in trFitFunctions.Children)
	{
		vector<string> vsAttribValsTemp;
		tree_get_attributes(cNode, vsAttribValsTemp, strAttribute, true);
		vsAttribVals.Append(vsAttribValsTemp);
	}
	int nNum=get_list_enum_number(vsAttribVals, strPrefix, strPostfix); 
	string strNum= 0==nNum ? "" : (string)nNum;
	return strPrefix+strNum;
}
///End NEED_GET_ENUM_FROM_ALL_CATEGORY

string	NumFunctionOrganizer::GetSubNodeNameList(const TreeNode trSource, const string strSubNode, char chDelimiter)
{
	if(!trSource)
		return "";
	string strNameList;
	vector<string> vsNodeNames;
	TreeNode trSubNode=GetNodeCheckAdd(trSource, strSubNode, false);
	if(trSubNode)
		tree_get_node_names(trSubNode, vsNodeNames, true);
	int nVariable = strNameList.SetTokens(vsNodeNames, chDelimiter);
	return strNameList;
}
///End MOVE_FUNCTION_TO_BASE_CLASS_FOR_FITFUNCWIZ
///Cheney 2007-5-25 DO_SAVE_FDF
/////Jasmine 11/15/06 DELETE_PRECOMPILE_FILES
//static void _delete_file(LPCSTR lpcszFile)
//{
	//string strFile(lpcszFile);
	//if(!strFile.IsFile())
		//return;
	//DWORD dwAttributes = GetFileAttributes(strFile);
	////remove read-only attribute
	//dwAttributes &= ~(FILE_ATTRIBUTE_READONLY);
	//BOOL bRet = SetFileAttributes(strFile, dwAttributes); 
	//bRet = DeleteFile(strFile);
//}
/////End DELETE_PRECOMPILE_FILES
///end DO_SAVE_FDF


///Jasmine 07/14/10 ORG-486-S1 CENTRALIZE_PEAK_ATTRIB_TO_NLFIT
bool NLFunctionList::CheckCopyPeakAttributeNodes(bool bPeakFunction, const TreeNode& trSource, TreeNode& trTarget)
{
	if(!trSource || !trSource.Controls || !trTarget)
		return false;
	
	vector<string> vsNodes = {STR_DUPLICATE_NUM, STR_DUPLICATE_OFFSET, STR_DUPLICATE_UNIT,
							STR_FUNC_PEAK_CENTER, STR_FUNC_PEAK_WIDTH,
							STR_FUNC_PEAK_CENTER2, STR_FUNC_PEAK_WIDTH2,
							STR_FUNC_PEAK_AMPLITUDE};
	vector<int>	 vnIDs = {	IDS_CONTROL_NUM_REPLICATES, IDS_CONTROL_REPLICATE_FROM, IDS_CONTROL_REPLICATE_UNIT,
							IDS_CONTROL_PEAK_CENTER_ARG_INDEX, IDS_CONTROL_PEAK_WIDTH_ARG_INDEX,
							IDS_CONTROL_PEAK_CENTER_ARG_INDEX_2, IDS_CONTROL_PEAK_WIDTH_ARG_INDEX_2,
							IDS_CONTROL_PEAK_AMPLITUDE_ARG_INDEX};
	
	for(int ii = 0; ii < vsNodes.GetSize(); ii++)
	{
		string strNodeName = vsNodes[ii];
		
		TreeNode trNode;
		if(bPeakFunction)
			trNode = GetControls(trSource, false, strNodeName);
		
		if(trNode)
		{
			GetControls(trTarget, true, strNodeName).strVal = trNode.strVal;
			GetControls(trTarget, true, strNodeName).ID = vnIDs[ii];
		}
		else
		{
			if(strNodeName.Compare(STR_DUPLICATE_NUM) == 0 || strNodeName.Compare(STR_DUPLICATE_OFFSET) == 0 || strNodeName.Compare(STR_DUPLICATE_UNIT) == 0)
				continue;
			
			TreeNode trTemp = GetControls(trTarget, false, strNodeName);
			if(trTemp)
				trTemp.Remove();
		}
	}
	
	return true;
}
///End CENTRALIZE_PEAK_ATTRIB_TO_NLFIT

#endif //_NFO_H_
