#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	scale_linear,
	scale_log,
	scale_srcgraph,
};

		
#include <..\OriginLab\nlsf_utils.h> 
#include <..\OriginLab\NLFitSession.h>
#include <..\OriginLab\graph_utils.h>		///Kyle 11/11/2008 QA80-12564 CREATE_X_Y_DATA_BASE_ON_GRAPY_SCALE

/*********************************************************************************
*	Modification Log :
*	Folger 07/07/08 QA80-11810-P3 SHOW_PROPER_INFO_WHEN_FIT_FUNCTION_FAIL_TO_COMPILE
*	Kyle 11/11/2008 QA80-12564 CREATE_X_Y_DATA_BASE_ON_GRAPY_SCALE
*	Kyle 01/13/2009 SET_PREVIEW_SCALE_TYPE_SAME_AS_SOURCE_LAYER
*	Kyle 03/05/2009 QA80-12564 ADD_OPTION_X_SCALE_TYPE
*	Kyle 03/12/2009 QA80-12564-P5 SET_GRAPH_NO_CLICK
*	Kyle 03/16/2009 QA80-12564-P6 SHOULD_UPDATE_GRID_BEFORE_CHECKING_SETTINGS
*	Kyle 03/16/2009 QA80-12564-S1 SET_SOURCE_SCALE_TYPE_AS_DEFAULT_X_SCALE_TYPE_IF_FROM_GRAPH
*	Kyle 03/17/2009 QA80-12564-P7 GENERAL_ERROR_MESSAGE_FOR_X_RANGE_ERROR
*	Kenny 8/25/2009 QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC
*	Jasmine 08/13/2010 ORG-172-S2 CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
*********************************************************************************/

///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
//#include <getnbox.h>
//#include <oErrMsg.h>
//#include <ocu.h>
//
//#define IDE_SIMULATE_PARA_BEGIN 1000
//#define IDST_SIMULATE_PARAS		(IDST_TREE_BRANCH_MASK + 1)
//
/////Arvin 02/11/07 INIT_PARAMS_BY_SETTING_FILE_AND_SAVE_USER_SETTING_TO_SETTING_FILE by max's suggestion
//#define STR_SETTING_FILE		"fdf_simulate.xml"
//#define USER_SETTING_FILE		okutil_get_origin_path(ORIGIN_PATH_USER, THEME_SUB_FOLDER)+STR_SETTING_FILE
//#define SYS_SETTING_FILE		okutil_get_origin_path(ORIGIN_PATH_SYSTEM, THEME_SUB_FOLDER)+STR_SETTING_FILE
///END INIT_PARAMS_BY_SETTING_FILE_AND_SAVE_USER_SETTING_TO_SETTING_FILE
//
////put your own support static functions here
//static void initNLFSelFun(TreeNode &trGetN)
//{
	//NLFitSelFunction nlf(trGetN);
	//nlf.Init("Origin Basic Functions", NULL, NULL, NULL, true, false);	///Jasmine 05/18/07 ADD_NEW_AT_LIST_BOTTOM_TO_OPEN_FO, no need <new...> here
//}
//static void updateFunctionWhenCateChange(TreeNode &trGetN)
//{
	//NLFitSelFunction nlf(trGetN);
	//nlf.OnChangeCategoryUpdateFunctionList(false);	///Jasmine 05/18/07 ADD_NEW_AT_LIST_BOTTOM_TO_OPEN_FO
//}
//static bool getFDF(TreeNode &trGetN, TreeNode &trFF)
//{
	//NLFitSelFunction nlf(trGetN);
	//string strCate, strFunc;
	//nlf.GetCategoryAndFunction(strCate, strFunc);	
	//return nlf.LoadEx(trFF, strFunc, strCate);		
//}
//static void getParamList(vector& vParams, TreeNode& trParams)
//{
	/////Arvin 04/04/07 v8.0596 CAN_NOT_GET_PARAMS_VALUES
	////vector<string> vs;
	////tree_get_values(trParams, vs);
	////convert_str_vector_to_num_vector(vs, vParams);
	//foreach(TreeNode trN in trParams.Children)
		//vParams.Add(trN.dVal);
	/////end CAN_NOT_GET_PARAMS_VALUES
//}
/////Arvin 04/04/07 v8.0596 CHECK_LEGALITY_OF_PARAMS
//static bool getParamsInfo(LPCSTR lpcszFunName, LPCSTR lpcszCateg, vector<string>& vParamNames, vector& vParamLowerBounds, vector& vParamUpperBounds)
//{
	//NLFunctionList nlf;
	//Tree trFF;
	//string strFunction = lpcszFunName, strCateg = lpcszCateg;	
	//if(!nlf.LoadEx(trFF, strFunction, strCateg))
		//return false;
	//
	//string 	strParamList = nlf.GetFittingPara(trFF, true, "Names").strVal;
	//int nNumParaInFunc = strParamList.GetTokens(vParamNames, ',');
	//
	//string strParaBoundList = nlf.GetFittingPara(trFF, true, "LowerBounds").strVal;
	////LowerBounds
	//nlf_set_param_bounds_vector(strParaBoundList, vParamLowerBounds, nNumParaInFunc);
	/////UpperBounds
	//strParaBoundList = nlf.GetFittingPara(trFF, true, "UpperBounds").strVal;
	//nlf_set_param_bounds_vector(strParaBoundList, vParamUpperBounds, nNumParaInFunc);
	//
	//return true;
//}
//
//static int checkParamsLegality(LPCSTR lpcszFunName, LPCSTR lpcszCateg, const vector& vParamValues, string& strErrFuncOrParam, double& dLowerOrUpperBound)
//{
	//vector<string> vParamNames;
	//vector vParamLowerBounds, vParamUpperBounds;
	//if(!getParamsInfo(lpcszFunName, lpcszCateg, vParamNames, vParamLowerBounds, vParamUpperBounds))
	//{
		//strErrFuncOrParam = lpcszFunName;
		//return XFERR_LOAD_FUNC_INFO;
	//}
	//
	//if(vParamNames.GetSize() != vParamValues.GetSize())
	//{
		//return XFERR_WRONG_PARAM_NUMBER;
	//}
	//
	//for(int ii = 0; ii < vParamNames.GetSize(); ii++)
	//{
		//string strParamName = vParamNames[ii];
		//double dLower = vParamLowerBounds[ii], dUpper = vParamUpperBounds[ii], dValue = vParamValues[ii];
		//if(dLower != NANUM && dValue != NANUM && dValue < dLower)
		//{
			//strErrFuncOrParam = strParamName;
			//dLowerOrUpperBound = dLower;
			////strErrMsg = XFERR_PARAM_VALUE_TOO_SMALL + ":" + strParamName + "|" + dLower;
			//return XFERR_PARAM_VALUE_TOO_SMALL;
		//}
		//
		//if(dUpper != NANUM && dValue != NANUM && dValue > dUpper)
		//{
			//strErrFuncOrParam = strParamName;
			//dLowerOrUpperBound = dUpper;
			////strErrMsg = XFERR_PARAM_VALUE_TOO_LARGE + ":" + strParamName + "|" + dUpper;
			//return XFERR_PARAM_VALUE_TOO_LARGE;
		//}	
	//}
	//
	//return 0;
//}
//
//static bool checkTreeSettings(TreeNode& trGetN, string& strErrMsg)
//{
	//vector vParams;
	//getParamList(vParams, trGetN.pvalue);
	//string strCategory = trGetN.categorylist.strVal;
	//string strFunc = trGetN.functionlist.strVal;
	//string strErrFuncOrParam;
	//double dLowerOrUpperBound;
	//int nRet = checkParamsLegality(strFunc, strCategory, vParams, strErrFuncOrParam, dLowerOrUpperBound);
	//if(nRet != 0)
	//{
		//switch(nRet)
		//{
		//case XFERR_LOAD_FUNC_INFO:
			//strErrMsg = XFERR_LOAD_FUNC_INFO;
			//strErrMsg = strErrMsg + ":" + strErrFuncOrParam;
			//break;
		//case XFERR_WRONG_PARAM_NUMBER:
			//strErrMsg = XFERR_WRONG_PARAM_NUMBER;
			//break;
		//case XFERR_PARAM_VALUE_TOO_SMALL:
			//strErrMsg = XFERR_PARAM_VALUE_TOO_SMALL;
			//strErrMsg = strErrMsg + ":" + strErrFuncOrParam + "|" + dLowerOrUpperBound;
			//break;
		//case XFERR_PARAM_VALUE_TOO_LARGE:
			//strErrMsg = XFERR_PARAM_VALUE_TOO_LARGE;
			//strErrMsg = strErrMsg + ":" + strErrFuncOrParam + "|" + dLowerOrUpperBound;
			//break;
		//}
		//
		//return false;
	//}
	//double dLevel = trGetN.noise.dVal;
	//if(dLevel < 0 || dLevel > 100)//set noise level in [0, 100] by max's suggestion
	//{
		//strErrMsg = XFERR_WRONG_NOISE_LEVEL;
		//strErrMsg = strErrMsg + ":" + 0 + "|" + 100;
		//return false;
	//}
	//return true;
//}
/////end CHECK_LEGALITY_OF_PARAMS

////static void getParaGetnBranch(TreeNode &trPara, string& strParams, int nParaCount)
//static void getParaGetnBranch(TreeNode &trPara, string& strParams)
//{
	//int nDataID =  IDE_SIMULATE_PARA_BEGIN;
	//int nParaCount = strParams.Count(',') ;
	//if(nParaCount >=0)
		//nParaCount++;
	//else
		//return;
	//
	//GETN_TREE(tr)
	//GETN_BEGIN_BRANCH(pvalue, "Parameters") GETN_OPTION_BRANCH(GETNBRANCH_OPEN) GETN_ID_BRANCH(IDST_SIMULATE_PARAS) //GETN_CHECKBOX_BRANCH(1)
	//for(int n =0 ; n< nParaCount; n++)
	//{
		//string str = strParams.GetToken(n, ',');
		//if (str.Compare("") == 0)
		//{
			//printf("Invalid Parameter Values!\n");
			//return;
		//}
		//string strParaName = "P" + n;
		////--- CPY 11/29/05 USE_SLIDER_EDIT
		///*
		//_tmpSubNode = _tmpNode.AddNumericNode(1, strParaName, TRGP_INTERACTIVE);
		//TREE_ADD_LABEL(str);	
		//_tmpSubNode.Enable = true;
		//_tmpSubNode.DataID = nDataID++;
		//_tmpSubNode.SetAttribute(STR_COMBO_ATTRIB, 0);
		//*/
		//// the following will need to be read from nlsf.oss
		/////Arvin 04/04/07 v8.0596 CHECK_LEGALITY_OF_PARAMS by larry's suggestion
		////string strRange = "-100|100|100";
		////double dDefault = 1;
		////GETN_SLIDEREDIT(strParaName, str, dDefault, strRange) GETN_ID(nDataID++)
		//double dDefault = 1;
		//GETN_NUM(strParaName, str, dDefault) GETN_ID(nDataID++)
		/////end CHECK_LEGALITY_OF_PARAMS
		////--- end USE_SLIDER_EDIT
	//}
	//GETN_END_BRANCH(pvalue)	//Match GETN_BEGIN_BRANCH
//
	//if(tr.pvalue.IsEmpty())
		//return;
	//trPara.Replace(tr.pvalue);
//}
//
//static bool UpdateSimuGraph(TreeNode &trGetN,  PageBase& CntrlGraph, Datasheet& CntrlGraphData)
//{
	////out_str("UpdateSimuGraph");
	//Tree trFF;
	//getFDF(trGetN, trFF);
	//
	//int		numParamsInFunction = trFF.GeneralInformation.NumberOfParameters.nVal;
	//int		numIndependentVariables = trFF.GeneralInformation.NumberOfIndependentVariables.nVal;
	//vector vX, vY, vZ, vParams;///Arvin 04/04/07 v8.0596 CAN_NOT_GET_PARAMS_VALUES
	//trGetN.pname.Show = false;
//
	//Worksheet wks(CntrlGraphData);
	//GraphPage gp(CntrlGraph);
//
	//if (!wks.IsValid())
		//wks.Create("Origin", CREATE_TEMP);
	//
	//GraphLayer gl;
	//
	//if (numIndependentVariables == 1)
	//{
		//getParamList(vParams, trGetN.pvalue);
		//createXYData(trFF, vX, vY, vParams, trGetN.x1.dVal, trGetN.x2.dVal, trGetN.nx.dVal);
		//add_white_noise(vY, trGetN.noise.dVal);
		//save_data_2_Wks(wks, vX, vY);
	//
		//if (!gp.IsValid())
			//gp.Create();
		//gl = gp.Layers(0);
		//Curve cv(wks, 0, 1);
		//int nPlot = gl.AddPlot(cv, IDM_PLOT_LINE);
		//DataPlot dp = gl.DataPlots(nPlot);
		//gl.Rescale();
	//}
	//else if (numIndependentVariables == 2)
	//{
		//string str = "Seleted two independent variables shoud use surfacemarker";
		//str.WriteLine(WRITE_COMPILER_OUTPUT);
	//}
	//return true;
//}
//
//static bool _str_to_range(LPCSTR lpcszRange, int& i1, int& i2 )
//{
	//string strTemp = lpcszRange;
	//int nPos = strTemp.Find('-');
	//i1 = i2 = -1;
	//if(nPos < 0)
		//return false;
	//
	//string strNum, strMin, strMax;
	//strNum = strTemp.Left(nPos);
	//if(strNum.IsEmpty())
	//{
		//nPos = strTemp.Find('-', nPos+1);
	//}
	//strMin = strTemp.Left(nPos);
	//strMax = strTemp.Mid(nPos+1);
	//if(is_numeric(strMin) && is_numeric(strMax))
	//{
		//i1 = atoi(strMin);
		//i2 = atoi(strMax);
		//if(i1 >= i2)
			//return false;
		//return true;
	//}
	//return false;
//}
//bool button_event(TreeNode& trGUI, int nRow, int nCol, TreeNode& trNode, DWORD dwCntrl, int nType, WndContainer& theDlg)
//{
	//if(dwCntrl & GETNEVENT_ON_INIT)
		//return false;	
	//string strRange;
	//int nMin, nMax;	
	//string strLabel;	
//
	//GETN_TREE(my)	
	//foreach(TreeNode node in trGUI.pvalue.Children)
	//{
		//node.GetAttribute(STR_COMBO_ATTRIB, strRange);
		//int nPos = strRange.Find('|');
		//nMin = atoi(strRange.Left(nPos));
		//nMax = atoi(strRange.Mid(nPos+1));
		//strRange = (string)nMin + " - " + (string)nMax;
		//node.GetAttribute(STR_LABEL_ATTRIB, strLabel);
		//GETN_STR(range,strLabel,strRange)
	//}
		//
	//if(GetNBox(my,"Set Range","Parameters..",NULL,NULL))
	//{
		//TreeNode trNode1 = trGUI.pvalue.FirstNode;
		//foreach(TreeNode trcNode in my.Children)
		//{
			//string strMin, strMax;
			//int nTemp;
			//strRange = trcNode.strVal;
			//if(!_str_to_range(strRange, nMin, nMax))
			//{
				//string str;
				//if(ocu_load_err_msg_str(CER_INVALID_RANGE, &str))
					//error_msg_box(str);
				//return false;
			//}
			//strMin = nMin;
			//strMax = nMax;
			//nTemp = atoi(trNode1.strVal);
			//if(nTemp < nMin)
				//trNode1.strVal = strMin;
			//if(nTemp > nMax)
				//trNode1.strVal = strMax;
			//strRange = strMin + "|" + strMax + "|" + "100";
			//trNode1.SetAttribute(STR_COMBO_ATTRIB,strRange);
			//trNode1 = trNode1.NextNode;
		//}
	//}
	//return true;
//}
//
//static bool _find_param_in_list(LPCSTR lpcszParam, string& lpcszList, char chDelimiter)
//{
	//vector<string> vsComboList;
	//lpcszList.GetTokens(vsComboList, chDelimiter);
	//return is_in_list(lpcszParam, vsComboList);
//}
//
//static int UpdateGridTree(TreeNode &trGetN, bool bInitGrid = false)
//{
	//string strCategoryList, strFuncList;
	//strCategoryList = trGetN.categorylist.strVal;
	//strFuncList = trGetN.functionlist.strVal;
	//strCategoryList.Remove('\"');
	//strFuncList.Remove('\"');
	//if(bInitGrid)
	//{
		//initNLFSelFun(trGetN);
		//if(!strCategoryList.IsEmpty())
		//{
			//string strComboList;
			//trGetN.categorylist.GetAttribute(STR_COMBO_ATTRIB, strComboList);
			//if(_find_param_in_list(strCategoryList, strComboList, '|'))
			//{
				//trGetN.categorylist.strVal = strCategoryList;
				//updateFunctionWhenCateChange(trGetN);
				//trGetN.functionlist.GetAttribute(STR_COMBO_ATTRIB, strComboList);
				//if(_find_param_in_list(strFuncList, strComboList, '|'))
					//trGetN.functionlist.strVal = strFuncList;
			//}
		//}
	//}
	//else
		//if(tree_node_changed(trGetN.categorylist))
			//updateFunctionWhenCateChange(trGetN);
	//
	//string strFunction = trGetN.functionlist.strVal;
	///// Iris 02/16/2007 v8.0654 SHOW_WRONG_DLG_IF_NO_FUNCTION_IN_SELECTED_CATEGORY
	//if(strFunction.IsEmpty())
		//return -1;
	/////end SHOW_WRONG_DLG_IF_NO_FUNCTION_IN_SELECTED_CATEGORY
	//
	//Tree trFF;
	//getFDF(trGetN, trFF);
	//
	//string	strParamNames = trFF.FittingParameters.Names.strVal;
	//trGetN.pname.strVal = strParamNames;
	//trGetN.pname.Enable = false;
	//
	////int		numParamsInFunction = trFF.GeneralInformation.NumberOfParameters.nVal;
	//int		numIndependentVariables = trFF.GeneralInformation.NumberOfIndependentVariables.nVal;
//
	//trGetN.pname.Show = false;
//
	/////justin 11/14/2006 TRGETN_SHOULD_NOT_BEEN_PERMITTED_TO_CHANGE_STRUCTURE  //temp solution
	////TreeNode trRNode;
	////if(!trGetN.range)
	////{
		////trRNode = trGetN.InsertNode(trGetN.pvalue, "range", ONODETYPE_PUSHBUTTON_GROUP);
		////trRNode.SetAttribute(STR_COMBO_ATTRIB, "Set Parameters Range");
		////trRNode.SetAttribute(STR_LABEL_ATTRIB, "range");
		////trRNode.Enable = true;
		////trRNode.Show = true;
		////PEVENT_NODE_FUNC __dfn = button_event;
		////DWORD _dw_fn = (DWORD)__dfn;
		////if(_dw_fn) 
		////{
			////string _strTemp = _dw_fn;
			////trRNode.SetAttribute(STR_ATTRIB_HANDLER_RC, _strTemp);}
	////}
	//////	out_str("UpdateGridTree");
	////if (numIndependentVariables == 1)
	////{
		////trGetN.y1.Show = false;
		////trGetN.y2.Show = false;
		////trGetN.ny.Show = false;
	////}
	////else if (numIndependentVariables == 2)
	////{
		////string str = "Seleted two independent variables shoud use surfacemarker";
		////str.WriteLine(WRITE_COMPILER_OUTPUT);
	////}
	/////end TRGETN_SHOULD_NOT_BEEN_PERMITTED_TO_CHANGE_STRUCTURE
	//bool bCateChanged = tree_node_changed( trGetN.categorylist);
	//bool bFunctChanged = tree_node_changed( trGetN.functionlist);
	//if(bFunctChanged || bCateChanged || bInitGrid)
	//{
		////out_str("Function or Category changed");
		//getParaGetnBranch(trGetN.pvalue,strParamNames);
		///*
		////loadFunctionSetting(trGetN );
		////--- CPY 12/30/2005 NLF_SIMULATE_SETTINGS_SAVE_LOAD
		//bCateChanged = tree_node_changed( trGetN.category);
		//bFunctChanged = tree_node_changed( trGetN.function);
		//if(bCateChanged || bFunctChanged)
			//out_str("This should never happen, after loading, func or cate should not be changed");
		//*/
		//Tree tr;
		/////Arvin 02/11/07 INIT_PARAMS_BY_SETTING_FILE_AND_SAVE_USER_SETTING_TO_SETTING_FILE by max's suggestion
		///*
		//if(nlf_load_simulate_settings(strFunction, &tr))
		//{
			////tree_copy_values_by_id(tr, trGetN);
			//octree_copy_values_by_id(&tr, &trGetN, false, STR_ID_ATTRIB, STR_DATAID_ATTRIB);
//
		//}
		//*/
		//if(!tr.Load(USER_SIMUALTE_FILE))
		//{
			//if(!tr.Load(SYS_SIMULATE_FILE))
				//return -1;
		//}
		//
		//TreeNode trFind = tr.GetNode(strFunction);//tr.FindNodeByAttribute(STR_NAME_ATTRIB, strFunction);
		//if(trFind.IsValid())
			//octree_copy_values_by_id(&trFind, &trGetN, false, STR_ID_ATTRIB, STR_DATAID_ATTRIB);
		/////end INIT_PARAMS_BY_SETTING_FILE_AND_SAVE_USER_SETTING_TO_SETTING_FILE
		////--- end NLF_SIMULATE_SETTINGS_SAVE_LOAD
		//return 1; //Need update GUI
	//}
	//return 0; //No need update GUI
//}
bool sim_xf_update_simu_graph(TreeNode &trGetN,  PageBase& CntrlGraph, Datasheet& CntrlGraphData)
{
	//out_str("UpdateSimuGraph");
	Tree trFF;
	sim_xf_get_FDF(trGetN, trFF);
	
	int		numParamsInFunction = trFF.GeneralInformation.NumberOfParameters.nVal;
	int		numIndependentVariables = trFF.GeneralInformation.NumberOfIndependentVariables.nVal;
	/// Max 12/10/07 CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	int		numDependentVariables = trFF.GeneralInformation.NumberOfDependentVariables.nVal;
	/// END CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	vector vX, vY, vZ, vParams;///Arvin 04/04/07 v8.0596 CAN_NOT_GET_PARAMS_VALUES
	trGetN.pname.Show = false;

	Worksheet wks(CntrlGraphData);
	GraphPage gp(CntrlGraph);

	if (!wks.IsValid())
		wks.Create("Origin", CREATE_TEMP);
	
	GraphLayer gl;
	/// Max 12/10/07 CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	//if (numIndependentVariables == 1)
	if (numIndependentVariables == 1 && numDependentVariables == 1)
	{
		sim_xf_get_param_list(vParams, trGetN.pvalue);
		///Kyle 11/11/2008 QA80-12564 CREATE_X_Y_DATA_BASE_ON_GRAPY_SCALE
		//createXYData(trFF, vX, vY, vParams, trGetN.x1.dVal, trGetN.x2.dVal, trGetN.nx.dVal);
		///Kyle 03/05/2009 QA80-12564 ADD_OPTION_X_SCALE_TYPE
		//GraphPage gpSrc(trGetN.page.strVal);
		//if ( !gpSrc )
			//gpSrc = Project.Pages();
		//GraphLayer glSrc;
		//if(gpSrc)
		//glSrc = gpSrc.Layers();
		//int nXScale = LINEAR_SPACE;
		//axis_get_scale_type( glSrc, &nXScale);
		int nXScale = _get_x_scale_type(trGetN);
		///End ADD_OPTION_X_SCALE_TYPE
		createXYData(trFF, vX, vY, vParams, trGetN.x1.dVal, trGetN.x2.dVal, trGetN.nx.dVal, nXScale);
		///End CREATE_X_Y_DATA_BASE_ON_GRAPY_SCALE
		/// Cloud 8/30/07 ADD_OPTION_OF_NOISE
		//add_white_noise(vY, trGetN.noise.dVal);
		add_white_noise(vY, trGetN.noise.dVal, NOISE_OVER_DIFFERENCE);
		/// End ADD_OPTION_OF_NOISE
		save_data_2_Wks(wks, vX, vY);
	
		if (!gp.IsValid())
			/// Kenny 08/25/2009 QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC
			//gp.Create("Origin");
			gp.Create("Origin", CREATE_DEFAULT_OPTIONS | CREATE_ENUM_EXIST_PAGE);
			/// End QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC
		gl = gp.Layers(0);
		Curve cv(wks, 0, 1);
		int nPlot = gl.AddPlot(cv, IDM_PLOT_LINE);
		DataPlot dp = gl.DataPlots(nPlot);
		gl.Rescale();
	}
	/// Max 12/10/07 CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	/*
	else if (numIndependentVariables == 2)
	{
		string str = "Seleted two independent variables shoud use simsurface";
		str.WriteLine(WRITE_COMPILER_OUTPUT);
	}
	*/
	else if (numIndependentVariables == 2 && numDependentVariables == 1)
	{	
		XF_THROW(CER_MULTI_INDEP_VAR_FOR_SIMCURVE);
	}
	else
	{
		XF_THROW(CER_MULTI_INDEP_AND_DEP_VAR_FOR_SIMULATION);
	}
	/// END CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	
	return true;
}
///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE

static void _sim_set_x_min_max(TreeNode &trGetN)
{
	GraphLayer gl = Project.ActiveLayer();
	if ( gl )
	{
		trGetN.x1.dVal = gl.X.From;
		trGetN.x2.dVal = gl.X.To;
	}
}



///Kyle 03/05/2009 QA80-12564 ADD_OPTION_X_SCALE_TYPE

static bool _is_from_graph(TreeNode& trGetN)
{
	GraphPage gpSrc(trGetN.page.strVal);
	if ( !gpSrc )
	{
		gpSrc = Project.Pages();
		if(gpSrc)
		{
			string strPage;
			if(gpSrc.GetName(strPage))
				trGetN.page.strVal = strPage;
		}
	}
	GraphLayer glSrc;
	if(gpSrc)
		glSrc = gpSrc.Layers();
	return glSrc.IsValid();
}

static int _get_x_scale_type(const TreeNode& trGetN)
{
	GraphPage gpSrc(trGetN.page.strVal);
	GraphLayer glSrc;
	if(gpSrc)
	glSrc = gpSrc.Layers();
	return _get_x_scale_type(trGetN.scale.nVal, glSrc);
}

static int _get_x_scale_type(int scale, const GraphLayer& gl)
{
	int nXScale = LINEAR_SPACE;
	switch(scale)
	{
	case scale_log:
		nXScale = LOG10_SPACE;
		break;
	case scale_srcgraph:
		axis_get_scale_type( gl, &nXScale);
		break;
	}
	return nXScale;
}

static bool _check_specified_x_range(TreeNode& trGetN, string& strErrMsg)
{
	int nXScale = _get_x_scale_type(trGetN);
	if(! _are_min_max_suitable(nXScale, trGetN.x1.dVal, trGetN.x2.dVal, strErrMsg))
		return false;
	
	if(trGetN.nx.nVal <= 0)
	{
		strErrMsg = CER_INVALID_DATA_NUM;
		return false;
	}
	return true;
}

static bool _are_min_max_suitable(int nXScale, double x1, double x2, string& strErrMsg = NULL)
{
	///Kyle 03/17/2009 QA80-12564-P7 GENERAL_ERROR_MESSAGE_FOR_X_RANGE_ERROR
	//if(nXScale == LOG10_SPACE || nXScale == LOGE_SPACE || nXScale == LOG2_SPACE)
	//{
		//if(x1 <= 0 || x2 <= 0)
		//{
			//if(strErrMsg)
				//strErrMsg = CER_LOG_X_DATATYPE_NOT_ALLOWED;
			//return false;
		//}
	//}
	if(	is_missing_value(real_space(x1, nXScale)) || is_missing_value(real_space(x2, nXScale)))
	{
		if(strErrMsg)
			strErrMsg = XFERR_RANGE_VIOLATE_SCALE_TYPE;
		return false;
	}
	///End GENERAL_ERROR_MESSAGE_FOR_X_RANGE_ERROR
	return true;
}

static bool _check_output(TreeNode& trGetN, string& strErrMsg)
{
	int nXScale = _get_x_scale_type(trGetN);
	if(nXScale == LOG10_SPACE || nXScale == LOGE_SPACE || nXScale == LOG2_SPACE)
	{
		bool bIsAuto = false;
		TreeNode trX = tree_get_node_by_tagname(trGetN.oy, "X", true);
		if(trX)
		{
			string strRange = trX.strVal;
			int nIndex = strRange.Find('<');
			if(nIndex > 0)
				strRange = strRange.Mid(nIndex);
			nIndex = strRange.Find('>');
			if(nIndex >= 0)
				strRange = strRange.Mid(0, nIndex + 1);
			int nType = okutil_cvt_str_to_predefined_type(strRange);
			if(nType == PDS_AUTO_X)
				bIsAuto = true;
		}
		else
			bIsAuto = true;
		if(	bIsAuto )
		{
			strErrMsg = CER_NONLINEAR_X_SCALE_TYPE;	// to do
			return false;
		}
	}
	return true;
}


static bool _update_preview_scale_type(TreeNode &trGetN,  PageBase& CntrlGraph)
{
	GraphPage gpPreview(CntrlGraph);
	if(!gpPreview)
		return false;
	GraphLayer glPreview = gpPreview.Layers();
	if(!glPreview)
		return false;

	if(_is_from_graph(trGetN))
	{
		GraphPage gpSrc(trGetN.page.strVal);
		GraphLayer glSrc;
		if(gpSrc)
			glSrc = gpSrc.Layers();
		if(glSrc)
		{
			int nXScale, nYScale;
			axis_get_scale_type( glSrc, &nXScale, &nYScale);
			axis_set_scale_type(glPreview, "X", nXScale);
			axis_set_scale_type(glPreview, "Y", nYScale);
			return true;
		}
	}

	int nXScale = _get_x_scale_type(trGetN);
	axis_set_scale_type(glPreview, "X", nXScale);

	return true;
}


///End ADD_OPTION_X_SCALE_TYPE




void simcurve(const string& categorylist, const string& functionlist, const string& pname, const TreeNode& pvalue, const int& scale, const double& x1, const double& x2, const int& nx, const double& noise, XYRange& oy, const string& page)
{
	
	// Prepare the function tree.
	Tree trGetN;
	trGetN.categorylist.strVal = categorylist;
	trGetN.functionlist.strVal = functionlist;
	
	Tree trFF;
	//getTreeOfFDF(strCategory, strFunction, trFF);
	///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	//getFDF(trGetN, trFF);
	sim_xf_get_FDF(trGetN, trFF);
	///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	
	// Prepare NumericFunction and NLFit classes.
	int		nRet;
	
	int		numParamsInFunction = trFF.GeneralInformation.NumberOfParameters.nVal;
	int		numIndependentVariables = trFF.GeneralInformation.NumberOfIndependentVariables.nVal;
	/// Max 12/10/07 CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	int		numDependentVariables = trFF.GeneralInformation.NumberOfDependentVariables.nVal;
	/// END CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	vector vX, vY, vZ, vParams;///Arvin 04/04/07 v8.0596 CHECK_LEGALITY_OF_PARAMS
	
	/// Max 12/10/07 CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	//if (numIndependentVariables == 1)
	if (numIndependentVariables == 1 && numDependentVariables == 1)
	/// END CHECK_NUMBER_OF_DEPENDENT_VARIABLES	
	{
		///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
		//getParamList(vParams, pvalue);
		sim_xf_get_param_list(vParams, pvalue);
		///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
		///Arvin 04/04/07 v8.0596 CHECK_LEGALITY_OF_PARAMS
		string strCategory = categorylist;
		string strFunc = functionlist;
		string strErrFuncOrParam;
		double dLowerOrUpperBound;
		///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
		//int nRet = checkParamsLegality(strFunc, strCategory, vParams, strErrFuncOrParam, dLowerOrUpperBound);
		int nRet = sim_xf_check_params_legality(strFunc, strCategory, vParams, strErrFuncOrParam, dLowerOrUpperBound);
		///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
		switch(nRet)
		{
		case XFERR_LOAD_FUNC_INFO:
			XF_THROW_EX(XFERR_LOAD_FUNC_INFO, strErrFuncOrParam);
			
		case XFERR_WRONG_PARAM_NUMBER:
			XF_THROW(XFERR_WRONG_PARAM_NUMBER);
			
		case XFERR_PARAM_VALUE_TOO_SMALL:
			XF_THROW_EX2(XFERR_PARAM_VALUE_TOO_SMALL, strErrFuncOrParam, dLowerOrUpperBound);
		
		case XFERR_PARAM_VALUE_TOO_LARGE:
			XF_THROW_EX2(XFERR_PARAM_VALUE_TOO_LARGE, strErrFuncOrParam, dLowerOrUpperBound);
		}
		///end CHECK_LEGALITY_OF_PARAMS
		///Kyle 11/11/2008 QA80-12564 CREATE_X_Y_DATA_BASE_ON_GRAPY_SCALE
		//createXYData(trFF, vX, vY, vParams, x1, x2, nx);
		GraphPage gp(page);
		bool bFromGraph = gp.IsValid();		///Kyle 11/11/2008 QA80-12564 CREATE_X_Y_DATA_BASE_ON_GRAPY_SCALE
		if ( !gp )
		{
			gp = Project.Pages();
			if( !gp )
			{
				/// Kenny 08/25/2009 QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC
				//gp.Create("Origin");
				gp.Create("Origin", CREATE_DEFAULT_OPTIONS | CREATE_ENUM_EXIST_PAGE);
				/// End QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC
				gp.SetLongName(functionlist);
			}
		}
		GraphLayer gl = gp.Layers();
		set_active_layer(gl);
		///Kyle 03/05/2009 QA80-12564 ADD_OPTION_X_SCALE_TYPE
		//int nXScale;
		//axis_get_scale_type( gl, &nXScale);
		int nXScale = _get_x_scale_type(scale, gl);
		if(!_are_min_max_suitable(nXScale, x1, x2))
			XF_THROW(XFERR_RANGE_VIOLATE_SCALE_TYPE);
		///Kyle 03/17/2009 QA80-12564-P7 GENERAL_ERROR_MESSAGE_FOR_X_RANGE_ERROR
		if(nx <= 0)
			XF_THROW(CER_INVALID_DATA_NUM);
		///End GENERAL_ERROR_MESSAGE_FOR_X_RANGE_ERROR
		if(!bFromGraph && scale == scale_log)
			axis_set_scale_type(gl, "X", nXScale);
		///End ADD_OPTION_X_SCALE_TYPE
		createXYData(trFF, vX, vY, vParams, x1, x2, nx, nXScale);
		///End CREATE_X_Y_DATA_BASE_ON_GRAPY_SCALE
		double dLevel = noise;
		if(dLevel < 0 || dLevel > 100)//set noise level in [0, 100] by max's suggestion
			XF_THROW_EX2(XFERR_WRONG_NOISE_LEVEL, 0, 100);
	
		/// Cloud 8/30/07 ADD_OPTION_OF_NOISE
		//add_white_noise(vY, noise);
		add_white_noise(vY, noise, NOISE_OVER_DIFFERENCE);
		/// End ADD_OPTION_OF_NOISE
		///Leo 2005-11-29 CHNAGE_WORKSHEET_OUTPUT_TO_XYZRANGE
		//save_data_2_Wks(result, vX, vY);
		oy.SetData(&vY, &vX);
		
		///Kyle 11/11/2008 QA80-12564 CREATE_X_Y_DATA_BASE_ON_GRAPY_SCALE
		//GraphPage gp(page);
		//if ( !gp )
		//{
			//gp = Project.Pages();
			//if( !gp )
			//{
				//gp.Create("Origin");
				//gp.SetLongName(functionlist);
			//}
		//}
		//GraphLayer gl = gp.Layers();
		//set_active_layer(gl);
		///End CREATE_X_Y_DATA_BASE_ON_GRAPY_SCALE
		
		gl.AddPlot(oy, IDM_PLOT_LINE);
		gl.Rescale();
		
		sim_xf_access_cate_and_func_last_used(categorylist, functionlist, false);
		
		//------ Folger 02/29/08 QA80-11155 IMRPOVE_SIMULATE_CURVE
		sim_generate_function_and_parameters_comments(oy, functionlist, pvalue);
		//------ End IMRPOVE_SIMULATE_CURVE
	}
	/// Max 12/10/07 CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	/*
	else
	{
		printf("Error occurs, incorrect number of independent variables!\n");
		return;
	}
	*/
	else if (numIndependentVariables == 2 && numDependentVariables == 1)
	{	
		XF_THROW(CER_MULTI_INDEP_VAR_FOR_SIMCURVE);
	}
	else
	{
		XF_THROW(CER_MULTI_INDEP_AND_DEP_VAR_FOR_SIMULATION);
	}
	/// END CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	
}

//nEventID < 0 on event, like GETNE_ON_INIT, GETNE_ON_OK etc, >0 on change from control
//return 0 to do nothing, return PEVENT_GETN_RET_TO_CLOSE to close dialog
//dwEnables = bOKEnable, bBTN1Enable, bBTN2Enable, bBTN3Enable, , can set to false to disable OK/Apply buttons
//lpcszNodeName = the trGetN TreeNode tag name that generates the event, or is  if GETNE_ON_OK etc
//strAux = optional string for XF Wizard Bar, like DLG_NEED_CHANGE_GRID etc, it will be invalid if from internal node value change event
//strErrMsg = allowing messages to be shown
int simcurve_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return simcurve_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	return true;
	

}

int simcurve_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	return true;
	
}
//nGetNDialog = 0,1,2, corresponding to the XF GetN dropdown, 0 = dialog is not used
//you can change nRet to be one of XFEVT_PROCEED (defualt), XFEVT_ABORT, XFEVT_PROCEED_NO_DLG or XFEVT_PROCEED_WITH_DLG(when nGetNDialog = 0)
//nGetNDialog = -1 when Ok on GetN dialog to allow handler to preocess <auto> etc variables
//dwCntrl is combination of bits
//LTXF_FROM_GUI_MENU, LTXF_FROM_GUI_PROMPT, LTXF_FROM_AUTO_UPDATE, LTXF_FROM_FUNCTION, LTXF_THEME_USED, LTXF_CHANGE_PARAM
void simcurve_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	///Kyle 03/05/2009 QA80-12564 ADD_OPTION_X_SCALE_TYPE
	if(is_xf_startup(nGetNDialog, dwCntrl))
	{
		string strCombo;
		trGetN.scale.GetAttribute(STR_COMBO_ATTRIB, strCombo);
		if(!_is_from_graph(trGetN))
		{
			vector<string> vsList;
			int nList = strCombo.GetTokens(vsList, '|');
			ASSERT(nList == 3);
			vsList.RemoveAt(scale_srcgraph);
			strCombo.SetTokens(vsList, '|');
			trGetN.scale.SetAttribute(STR_COMBO_ATTRIB, strCombo);
			if(trGetN.scale.nVal == scale_srcgraph)
				trGetN.scale.nVal = scale_linear;
		}
		///Kyle 03/16/2009 QA80-12564-S1 SET_SOURCE_SCALE_TYPE_AS_DEFAULT_X_SCALE_TYPE_IF_FROM_GRAPH
		else
		{
			trGetN.scale.nVal = scale_srcgraph;
		}
		///End SET_SOURCE_SCALE_TYPE_AS_DEFAULT_X_SCALE_TYPE_IF_FROM_GRAPH
	}
	///End ADD_OPTION_X_SCALE_TYPE
	
	//------ Folger 07/07/08 QA80-11810-P3 SHOW_PROPER_INFO_WHEN_FIT_FUNCTION_FAIL_TO_COMPILE
	Tree trFF;
	if ( !sim_xf_get_FDF(trGetN, trFF) )
		return;
	
	NumericFunction	NF(trFF);
	if ( !NF.CheckCompileOC() )
	{
		warning_msg_box(NLSF_ERR_COMPILE_NUMERIC_FUNCTION, true);
		nRet = XFEVT_ABORT;
		return;
	}
	//------
}
//nEventID < 0 on event, like GETNE_ON_INIT, GETNE_ON_OK etc, >0 on change from control
//return 0 to do nothing, return PEVENT_GETN_RET_TO_CLOSE to close dialog
//dwEnables = bOKEnable, bBTN1Enable, bBTN2Enable, bBTN3Enable, , can set to false to disable OK/Apply buttons
//lpcszNodeName = the trGetN TreeNode tag name that generates the event, or is  if GETNE_ON_OK etc
//strAux = optional string for XF Wizard Bar, like DLG_NEED_CHANGE_GRID etc, it will be invalid if from internal node value change event
//strErrMsg = allowing messages to be shown
int simcurve_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}


// put your grid initialization here
// you may also initialize wksTemp here
static void GetNGraphPreview_OnInitGrid(TreeNode& trGetN, PageBase& pgTemp, Datasheet& wksTemp,
PictureControl& pict, // optional tab for showing an image or EMF, as requested in OnDialogSetup 
DWORD& dwUpdateGraph,  // default to 0, UPDATE_GRAPH_CHANGED to cause graphs to be updated, UPDATE_GRAPH_INVALID to disable preview button
DWORD& dwUpdateGrid, // default to 0, set to UPDATE_GRID_SIMPLE to update the DynaControl grid, UPDATE_GRID_RESET to reset DynaControl grid
DWORD& dwEnables,// bOKEnable, bBTN1Enable, bBTN2Enable and bBTN3Enable :default to true, can set to false to disable buttons
string& strErrMsg) // optional err msg to be shown on dialog
{
	DECLARE_BUTTON_ENABLES
	DECLARE_UPDATE_GRAPH
	DECLARE_UPDATE_GRID
	bool bInitGrid = true;
	///Arvin 07/05/07 GUI_CAN_NOT_REMEMBER_USER_SETTINGS
	//bUpdateGrid = UpdateGridTree(trGetN, bInitGrid);
	///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	//int nRet = UpdateGridTree(trGetN, bInitGrid);
	
	string strCategory, strFunction;
	if ( sim_xf_access_cate_and_func_last_used(strCategory, strFunction) )
	{
		if ( trGetN.categorylist.strVal.CompareNoCase("0") == 0 )
			trGetN.categorylist.strVal = strCategory;
		if ( trGetN.functionlist.strVal.CompareNoCase("0") == 0 )
			trGetN.functionlist.strVal = strFunction;
	}
	
	int nRet = sim_xf_update_grid_tree(trGetN, bInitGrid);
	///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	bUpdateGrid = true;
	if(nRet != 0)
	{
		bUpdateGrid = false;
		strErrMsg = nRet;
		bOKEnable = false;
	}
	
	_sim_set_x_min_max(trGetN);
	
}

///////////////////////////////////////////////////////

// pgTemp is the graph for preview or control
// wksTemp is the the temp wks created to hold data to plot into pgTemp
static void GetNGraphPreview_OnInitGraph(TreeNode& trGetN, PageBase& pgTemp, Datasheet& wksTemp,
PictureControl& pict, // optional tab for showing an image or EMF, as requested in OnDialogSetup  
DWORD& dwUpdateGrid, // default to 0, set to UPDATE_GRID_SIMPLE to update the DynaControl grid, UPDATE_GRID_RESET to reset DynaControl grid
DWORD& dwEnables,// bOKEnable, bBTN1Enable, bBTN2Enable and bBTN3Enable :default to true, can set to false to disable buttons
string& strErrMsg) // optional err msg to be shown on dialog
{
	DECLARE_BUTTON_ENABLES
	DECLARE_UPDATE_GRID
	//printf("On Init, Graphname = %s \n",pgTemp.GetName()); 

	GraphPage gpPreview(pgTemp);
	if(gpPreview)
	{
		///Kyle 03/12/2009 QA80-12564-P5 SET_GRAPH_NO_CLICK
		//set_gp_noclick(gpPreview, 0);
		///Jasmine 08/13/2010 ORG-172-S2 CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
		//set_gp_noclick(gpPreview, NOCLICK_DATA_PLOT | NOCLICK_TICKLABEL | NOCLICK_LAYER | NOCLICK_LAYERICON | NOCLICK_AXES | NOCLICK_LABEL | NOCLICK_BUTTONS);
		set_gp_noclick(gpPreview, OC_PREVIEW_NOCLICK_NOZOOMPAN|NOCLICK_LABEL|NOCLICK_BUTTONS);
		///End CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
		///End SET_GRAPH_NO_CLICK
	}
	GraphLayer gl = gpPreview.Layers();
	/*
	Axis xa = gl.YAxis;
	Tree tr;
	tr = xa.Scale;
	
	tr.Type.nVal = LINEAR_SPACE;

	xa.Scale = tr;
	*/
	//gl.YAxis.Scale.Type.nVal = LINEAR_SPACE;
	///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	//UpdateSimuGraph(trGetN, pgTemp, wksTemp);
	///Kyle 03/05/2009 QA80-12564 ADD_OPTION_X_SCALE_TYPE
	/////Kyle 01/13/2009 SET_PREVIEW_SCALE_TYPE_SAME_AS_SOURCE_LAYER
	//GraphPage gpSrc(trGetN.page.strVal);
	//if ( !gpSrc )
	//{
		//gpSrc = Project.Pages();
		/////Kyle 03/05/2009 QA80-12564 ADD_OPTION_X_SCALE_TYPE
		//if(gpSrc)
		//{
			//string strPage;
			//if(gpSrc.GetName(strPage))
				//trGetN.page.strVal = strPage;
		//}
		/////End ADD_OPTION_X_SCALE_TYPE
	//}
	//GraphLayer glSrc;
	//if(gpSrc)
		//glSrc = gpSrc.Layers();
	//if(glSrc)
	//{
		//int nXScale, nYScale;
		//axis_get_scale_type( glSrc, &nXScale, &nYScale);
		//axis_set_scale_type(gl, "X", nXScale);
		//axis_set_scale_type(gl, "Y", nYScale);
	//}
//
	/////End SET_PREVIEW_SCALE_TYPE_SAME_AS_SOURCE_LAYER
	_update_preview_scale_type(trGetN, pgTemp);
	///End ADD_OPTION_X_SCALE_TYPE

	sim_xf_update_simu_graph(trGetN, pgTemp, wksTemp);
	///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	bBTN1Enable = false;
}

///////////////////////////////////////////////////////

static void GetNGraphPreview_OnUpdateGraph(TreeNode& trGetN, PageBase& pgTemp, Datasheet& wksTemp, PictureControl& pict)
{
	_update_preview_scale_type(trGetN, pgTemp);		///Kyle 03/05/2009 QA80-12564 ADD_OPTION_X_SCALE_TYPE

//	printf("On GetNGraphBox_OnUpdateControlGraph, Graphname = %s \n",pgGraph.GetName()); 
	//Tree trFF;
	//UpdateGridTree(trGetN, trFF);
	//getTreeOfFDF(trGetN.categorylist.strVal, trGetN.functionlist.strVal, trFF);
	//getFDF(trGetN, trFF);
	///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	///UpdateSimuGraph(trGetN, pgTemp, wksTemp);
	sim_xf_update_simu_graph(trGetN, pgTemp, wksTemp);
	///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	
}

///////////////////////////////////////////////////////

static void GetNGraphPreview_OnChange(TreeNode& trGetN, TreeNode& trNode, PageBase& pgTemp, Datasheet& wksTemp,
PictureControl& pict, // optional tab for showing an image or EMF that might be present, as requested in OnDialogSetup  
bool bChangedByGraph, // called when graph has been modified by user, like dragging a vertical line
DWORD& dwUpdateGraph,  // default to 0, UPDATE_GRAPH_CHANGED to cause graphs to be updated, UPDATE_GRAPH_INVALID to disable preview button
DWORD& dwUpdateGrid,  // default to 0, set to UPDATE_GRID_SIMPLE to update the DynaControl grid, UPDATE_GRID_RESET to reset DynaControl grid
DWORD& dwEnables,	// bOKEnable, bBTN1Enable, bBTN2Enable and bBTN3Enable :default to true, can set to false to disable buttons
string& strErrMsg) // optional err msg to be shown on dialog
{
	DECLARE_BUTTON_ENABLES
	DECLARE_UPDATE_GRAPH
	DECLARE_UPDATE_GRID
	///Arvin 07/05/07 GUI_CAN_NOT_REMEMBER_USER_SETTINGS
	//bUpdateGrid = UpdateGridTree(trGetN);
	//printf("On change, Graphname = %s\n",pgGraph.GetName()); 
	///Arvin 02/11/07 INIT_PARAMS_BY_SETTING_FILE_AND_SAVE_USER_SETTING_TO_SETTING_FILE by max's suggestion
	//bUpdateGraph = true;
	//bOKEnable = true; 
	//if(!bUpdateGrid)
	//{
	//	strErrMsg = XFERR_LOAD_XML_FAILED;
	//	bUpdateGraph = false;
	//	bOKEnable = false; 
	//}
	///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	//int nRet = UpdateGridTree(trGetN);
	bool bInitGrid = false;
	int nCtrl = 0;
	int nRet = sim_xf_update_grid_tree(trGetN, bInitGrid, true, &nCtrl);
	///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	bUpdateGraph = true;
	bOKEnable = true; 
	bUpdateGrid = true;
	bBTN1Enable = (nCtrl != 1);
	if(nRet != 0)
	{
		bUpdateGrid = false;
		strErrMsg = nRet;
		bUpdateGraph = false;
		bOKEnable = false; 
		bBTN1Enable = false;
		return;
	}
	else
		bUpdateGrid = (nCtrl > 0);
	///end GUI_CAN_NOT_REMEMBER_USER_SETTINGS

	///Kyle 03/16/2009 QA80-12564-P6 SHOULD_UPDATE_GRID_BEFORE_CHECKING_SETTINGS
	if ( trNode.tagName.CompareNoCase("categorylist") == 0 || trNode.tagName.CompareNoCase("functionlist") == 0 )
		_sim_set_x_min_max(trGetN);
	///End SHOULD_UPDATE_GRID_BEFORE_CHECKING_SETTINGS

	///Arvin 04/04/07 v8.0596 CHECK_LEGALITY_OF_PARAMS
	///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	//if(!checkTreeSettings(trGetN, strErrMsg))
	///Kyle 03/05/2009 QA80-12564 ADD_OPTION_X_SCALE_TYPE
	//if(!sim_xf_check_tree_settings(trGetN, strErrMsg))
	if(!sim_xf_check_tree_settings(trGetN, strErrMsg) || !_check_specified_x_range(trGetN, strErrMsg) || !_check_output(trGetN, strErrMsg))
	///End ADD_OPTION_X_SCALE_TYPE
	///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	{
		bUpdateGraph = false;
		bOKEnable = false; 
		bBTN1Enable = false;
	}
	///end CHECK_LEGALITY_OF_PARAMS
	///end INIT_PARAMS_BY_SETTING_FILE_AND_SAVE_USER_SETTING_TO_SETTING_FILE
	
	///Kyle 03/16/2009 QA80-12564-P6 SHOULD_UPDATE_GRID_BEFORE_CHECKING_SETTINGS
	//if ( trNode.tagName.CompareNoCase("categorylist") == 0 || trNode.tagName.CompareNoCase("functionlist") == 0 )
		//_sim_set_x_min_max(trGetN);
	///End SHOULD_UPDATE_GRID_BEFORE_CHECKING_SETTINGS
}

// called from OnInitDialog to allow options on setting up of dialog
// dwOptions = 0 (default) will create a line graph with data in a temp worksheet
// dwOptions = XFGSETUP_IMAGEGRAPH_CNTRL to create an image graph with data in a temp matrix book
// dwOptions = XFGSETUP_MATRIX_CNTRL to have a MatrixControl with data in a temp matrix book
// dwOptions = XFGSETUP_2_TABS | XFGSETUP_EMF_1ST to have a PictureControl on 1st tab and a GraphControl on 2nd tab
// vsTabTitles is empty on entering the event, but you can put tab title strings in this array.
static void GetNGraphPreview_OnDialogSetup(TreeNode& trGetN, WndContainer& theDlg, DWORD& dwOptions, vector<string>& vsTabTitles)
{

}

// called when dialog is being destroyed, either as OK button or as Cancel button being pressed
static void GetNGraphPreview_OnDestroy(TreeNode& trGetN, PageBase& pgTemp, Datasheet& wksTemp, PictureControl& pict)
{

}
//------------
//
static void GetNGraphPreview_OnCustomButton(TreeNode& trGetN, int nButton, PageBase& pgTemp, Datasheet& wksTemp,
PictureControl& pict, // optional tab for showing an image or EMF that might be present, as requested in OnDialogSetup  
bool bChangedByGraph, // called when graph has been modified by user, like dragging a vertical line
DWORD& dwUpdateGraph,  // default to 0, UPDATE_GRAPH_CHANGED to cause graphs to be updated, UPDATE_GRAPH_INVALID to disable preview button
DWORD& dwUpdateGrid,  // default to 0, set to UPDATE_GRID_SIMPLE to update the DynaControl grid, UPDATE_GRID_RESET to reset DynaControl grid
DWORD& dwEnables,	// bOKEnable, bBTN1Enable, bBTN2Enable and bBTN3Enable :default to true, can set to false to disable buttons
string& strErrMsg) // optional err msg to be shown on dialog
{
	DECLARE_BUTTON_ENABLES
	DECLARE_UPDATE_GRAPH
	DECLARE_UPDATE_GRID
	///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	/////Arvin 02/11/07 INIT_PARAMS_BY_SETTING_FILE_AND_SAVE_USER_SETTING_TO_SETTING_FILE by max's suggestion
	//Tree tr;
	//if(!tr.Load(USER_SIMUALTE_FILE)&& !tr.Load(SYS_SIMULATE_FILE))
	//{
		//strErrMsg = XFERR_LOAD_XML_FAILED;
		//bOKEnable = false;
	//}
//
	//string strFunction = trGetN.functionlist.strVal;
	//TreeNode trFind = tr.GetNode(strFunction);
	//if(trFind.IsValid())
	//{
		//octree_copy_values_by_id(&trGetN, &trFind, false, STR_DATAID_ATTRIB, STR_ID_ATTRIB);
		//tr.Save(USER_SIMUALTE_FILE);
	//}
	/////end INIT_PARAMS_BY_SETTING_FILE_AND_SAVE_USER_SETTING_TO_SETTING_FILE
	bOKEnable = sim_xf_on_save_button(trGetN, strErrMsg);
	bBTN1Enable = false;
	///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	
}
//


///////////////////////////////////////////////////////
	
int GetNGraphBox_simcurve(TreeNode& trGetN, int nRow, int nCol, TreeNode& trNode, DWORD dwCntrl, int nType, WndContainer& theDlg, PageBase& pgTemp, Datasheet& wksTemp, PictureControl& pict)
{
	return xf_GetNPreviewDlg_event_handler(trGetN, nRow, nCol, trNode, dwCntrl, nType, theDlg, pgTemp, wksTemp, pict,
	GetNGraphPreview_OnInitGrid, GetNGraphPreview_OnInitGraph,
	GetNGraphPreview_OnChange, GetNGraphPreview_OnUpdateGraph, GetNGraphPreview_OnDialogSetup, GetNGraphPreview_OnDestroy,
	GetNGraphPreview_OnCustomButton);	
}


//This file is the template for GetNEvent4

///////////////////////////////////////////////////////

