#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>


//put additional include files here
//#include <getnbox.h>

#include <..\OriginLab\nlsf_utils.h>

#include <..\OriginLab\NLFitSession.h>

///Arvin 01/24/08 QA70-10875 NEED_CLEAN_STATIC_MATRIXLAYER		
#define 	_X_COL	0
#define 	_Y_COL 	1	
#define 	_Z_COL 	2
static MatrixLayer ml;
///END NEED_CLEAN_STATIC_MATRIXLAYER

////put additional include files here
///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
//#define FO_SIMULATE_PARA_BEGIN_ID 10
////put your own support static functions here
//
//static void initNLFSelFun(TreeNode &trGetN)
//{
	//NLFitSelFunction nlf(trGetN);
	//string strSur = "Surface Fitting";
	//vector<string> vs;
	//vs.Add(strSur);
	//nlf.Init(strSur, NULL, NULL , vs, true, false);	///Jasmine 05/18/07 ADD_NEW_AT_LIST_BOTTOM_TO_OPEN_FO, no need <new...> here
//}
//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)
//{
	///*
	//int ii =0;
	//foreach(TreeNode cNode in trParams.Children)
	//{
		//string str = cNode.strVal;
		//if (str.Compare("") == 0)
		//{
			//printf("Invalid Parameter Values!\n");
			//return;
		//}
		//vParams[ii] = atof(str);
		//ii++;
	//}
	//*/
	//vector<string> vs;
	//tree_get_values(trParams, vs);
	//convert_str_vector_to_num_vector(vs, vParams);
//}
//static void getParaGetnBranch(TreeNode &trPara, string& strParams)
//{
	//int nDataID =  FO_SIMULATE_PARA_BEGIN_ID;
	//int nParaCount = strParams.Count(',');
	//if(nParaCount>=0)
		//nParaCount++;
	//else
		//return;
	//
	//GETN_TREE(tr)
	//GETN_BEGIN_BRANCH(pvalue, "Parameters") GETN_OPTION_BRANCH(GETNBRANCH_OPEN)//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;
		//_tmpSubNode = _tmpNode.AddNumericNode(1, strParaName, TRGP_INTERACTIVE);
		//TREE_ADD_LABEL(str);	
		//_tmpSubNode.Enable = true;
		//_tmpSubNode.DataID = nDataID++;
		//_tmpSubNode.SetAttribute(STR_COMBO_ATTRIB, 0);
	//}
	//GETN_END_BRANCH(pvalue)	//Match GETN_BEGIN_BRANCH
//
	//if(tr.pvalue.IsEmpty())
		//return;
	//trPara.Replace(tr.pvalue);	
//}
///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE

static void createXYZData(Tree trFF, vector& vX, vector& vY, vector& vZ, vector& vParams, double dXMin, double dXMax, double dYMin, double dYMax, int nXPts, int nYPts)
{
	NumericFunction	NF(trFF);
	vX.SetSize(nXPts*nYPts);
	vY.SetSize(nXPts*nYPts);
	vZ.SetSize(nXPts*nYPts);
	ocmath_mat_to_regular_xyz(NULL, nYPts, nXPts, dXMin, dXMax, dYMin, dYMax, vX, vY, NULL);
	NF.Evaluate(vParams, vZ, vX, vY, nXPts*nYPts)
}
static bool UpdateSimuGraph(TreeNode &trGetN,  PageBase& CntrlGraph, Datasheet& CntrlGraphData)
{
	//out_str("UpdateSimuGraph");
	Tree 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
	
	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
	
	///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	//vector vX, vY, vZ, vParams(numParamsInFunction);
	vector vX, vY, vZ, vParams;
	///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	trGetN.pname.Show = false;

	///Leo 2005-11-29 CHNAGE_WORKSHEET_OUTPUT_TO_XYZRANGE
	// 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)
	{
		string str = "Seleted one independent variables shoud use curvemarker";
		str.WriteLine(WRITE_COMPILER_OUTPUT);
	}
	else if (numIndependentVariables == 2)
	*/
	if (numIndependentVariables == 1 && numDependentVariables == 1)
	{	
		XF_THROW(CER_SINGLE_INDEP_VAR_FOR_SIMSURFACE);
	}
	else if (numIndependentVariables == 2 && numDependentVariables == 1)
	///END CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	{
		double dXMin = trGetN.x1.dVal;
		double dXMax = trGetN.x2.dVal;
		double dYMin = trGetN.y1.dVal;
		double dYMax = trGetN.y2.dVal;
		double dXStep = (dXMax - dXMin)/ (trGetN.nx.dVal - 1);
		double dYStep = (dYMax - dYMin)/ (trGetN.ny.dVal - 1);
		//getParamList(vParams, trGetN.pvalue.strVal);
		///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
		//getParamList(vParams, trGetN.pvalue);
		sim_xf_get_param_list(vParams, trGetN.pvalue);
		///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
		createXYZData(trFF, vX, vY, vZ, vParams, dXMin, dXMax, dYMin, dYMax, trGetN.nx.dVal, trGetN.ny.dVal);
		add_white_noise(vZ, trGetN.noise.dVal);
		///Leo 2005-11-29 CHNAGE_WORKSHEET_OUTPUT_TO_XYZRANGE
		// save_data_2_Wks(wks, vX, vY, vZ);
			
		//static MatrixLayer ml; ///Arvin 01/24/08 QA70-10875 NEED_CLEAN_STATIC_MATRIXLAYER	
		if (!ml.IsValid())
			ml.Create("Origin", CREATE_TEMP);
		MatrixObject mo = ml.MatrixObjects(0);
		mo.SetNumCols(trGetN.nx.dVal);
		mo.SetNumRows(trGetN.ny.dVal);
		Matrix& mat = mo.GetDataObject();
		ocmath_convert_regular_xyz_to_matrix(vX.GetSize(), vX, vY, vZ, mat, dXMin, dXStep, trGetN.nx.dVal, dYMin, dYStep, trGetN.ny.dVal);
		mo.SetXY(dXMin, dYMin, dXMax, dYMax);
		
		if(gp.IsValid())
			/// MAX 12/10/07 USE_PAGE_LOAD
			//gp.LoadTemplate("XYZ2MAT3D");
			///Jasmine 08/13/2010 ORG-172-S2 CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
			//page_load(gp, "XYZ2MAT3D");
			page_load(gp, "XYZ2MAT3D", OC_PREVIEW_NOCLICK_NOZOOMPAN|NOCLICK_LABEL|NOCLICK_BUTTONS);
			///End CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
			/// END USE_PAGE_LOAD
		gl = gp.Layers(0);
		gl.AddPlot(mo, IDM_PLOT_SURFACE_COLORMAP);
		gl.Rescale();
	}
	/// Max 12/10/07 CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	else
	{
		XF_THROW(CER_MULTI_INDEP_AND_DEP_VAR_FOR_SIMULATION);
	}
	/// END CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	
	return true;
}
///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
/*
static bool UpdateGridTree(TreeNode &trGetN, bool bInitGrid = false)
{
	if(bInitGrid)
		initNLFSelFun(trGetN);
	trGetN.categorylist.Enable = 0;

	string strFunction = trGetN.FunctionList.strVal;
	
	Tree trFF;
	getFDF(trGetN, trFF);
	
	string	strParamNames = trFF.FittingParameters.Names.strVal;
	trGetN.pname.strVal = strParamNames;
	trGetN.pname.Enable = false;
	
	int		numIndependentVariables = trFF.GeneralInformation.NumberOfIndependentVariables.nVal;

	trGetN.pname.Show = false;
	
	out_str("UpdateGridTree");
	if (numIndependentVariables == 1)
	{
		string str = "Seleted one independent variables shoud use curvemarker";
		str.WriteLine(WRITE_COMPILER_OUTPUT);
	}
	else if (numIndependentVariables == 2)
	{
		trGetN.y1.Show = true;
		trGetN.y2.Show = true;
		trGetN.ny.Show = true;
	}	
	
	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);
	}
	return true;
}
*/
///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
/*
static void create_theme_tree(TreeNode& trGetN, TreeNode& trTheme)
{	
	string strFunction = trGetN.FunctionList.strVal;
	int nID;
	string strNode = "node";
	Tree tr;
	tr.AddNode(strFunction, 0);
	TreeNode trFunc = tr.GetNode(strFunction);
	nID = 0x00050032;
	trFunc.AddNumericNode(trGetN.x1.dVal, strNode+ftoa(nID), nID);
	nID = 0x00060032;
	trFunc.AddNumericNode(trGetN.x2.dVal, strNode+ftoa(nID), nID);
	nID = 0x00070032;
	trFunc.AddNumericNode(trGetN.nx.dVal, strNode+ftoa(nID), nID);
	nID = 0x00080032;
	trFunc.AddNumericNode(trGetN.y1.dVal, strNode+ftoa(nID), nID);
	nID = 0x00090032;
	trFunc.AddNumericNode(trGetN.y2.dVal, strNode+ftoa(nID), nID);
	nID = 0x000a0032;
	trFunc.AddNumericNode(trGetN.ny.dVal, strNode+ftoa(nID), nID);
	nID = 0x000b0032;
	trFunc.AddNumericNode(trGetN.noise.dVal, strNode+ftoa(nID), nID);
	TreeNode trPValue = trGetN.pvalue;
	nID = IDE_SIMULATE_PARA_BEGIN;
	foreach(TreeNode trN in trPValue.Children)
	{
		trFunc.AddNumericNode(trN.dVal, strNode+ftoa(nID), nID);
		nID++;
	}
	
	trTheme.Replace(trFunc);
}
*/

void simsurface(const string& categorylist, const string& functionlist, const string& pname, const TreeNode& pvalue, const double& x1, const double& x2, const int& nx, const double& y1, const double& y2, const int& ny, const double& noise, XYZRange& z)
{
	
	// Prepare the category and function lists
	// 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
	
	///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	//vector vX, vY, vZ, vParams(numParamsInFunction);
	vector vX, vY, vZ, vParams;
	///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	
	/// Max 12/10/07 CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	//if (numIndependentVariables == 2)
	if (numIndependentVariables == 2 && 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);
		string strCategory = categorylist;
		string strFunc = functionlist;
		string strErrFuncOrParam;
		double dLowerOrUpperBound;
		
		int nRet = sim_xf_check_params_legality(strFunc, strCategory, vParams, strErrFuncOrParam, dLowerOrUpperBound);
		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 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
		
		createXYZData(trFF, vX, vY, vZ, vParams, x1, x2, y1, y2, nx, ny);
		///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
		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);
		///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
		add_white_noise(vZ, noise);
		///Leo 2005-11-29 CHNAGE_WORKSHEET_OUTPUT_TO_XYZRANGE
		// save_data_2_Wks(result, vX, vY, vZ);
		z.SetData(&vZ, &vY, &vX);
		
		//------ Folger 03/20/08 QA80-11155 CENTRALIZE_OUTPUT_PARAMETER_COMMENTS_FOR_SIMCURVE_AND_SIMSURFACE
		sim_generate_function_and_parameters_comments(z, functionlist, pvalue);
		//------
		
	}
	/// Max 12/10/07 CHECK_NUMBER_OF_DEPENDENT_VARIABLES
	/*
	else
	{
		printf("Error occurs, incorrect number of independent variables!\n");
		return;
	}
	*/
	else if (numIndependentVariables == 1 && numDependentVariables == 1)
	{	
		XF_THROW(CER_SINGLE_INDEP_VAR_FOR_SIMSURFACE);
	}
	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 simsurface_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return simsurface_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	return true;
	

}

int simsurface_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 simsurface_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{

}
//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 simsurface_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
	///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	//bool bInitGrid = true;
	//bUpdateGrid = UpdateGridTree(trGetN, bInitGrid);
	bool bInitGrid = true;
	int nRet = sim_xf_update_grid_tree(trGetN, bInitGrid, false);
	bUpdateGrid = true;
	if(nRet != 0)
	{
		bUpdateGrid = false;
		strErrMsg = nRet;
		bOKEnable = false;
	}
	bBTN1Enable = false;
	///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE

}

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

// 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
		///Jasmine 08/13/2010 ORG-172-S2 CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
		//set_gp_noclick(gpPreview, 0);
		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;
	UpdateSimuGraph(trGetN, pgTemp, wksTemp);
}

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

static void GetNGraphPreview_OnUpdateGraph(TreeNode& trGetN, PageBase& pgTemp, Datasheet& wksTemp, PictureControl& pict)
{
	///Arvin 07/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	UpdateSimuGraph(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/10/07 v8.0656 CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	//bUpdateGrid = UpdateGridTree(trGetN);
	//printf("On change, Graphname = %s\n",pgTemp.GetName()); 
	//bUpdateGraph = true;
	bool bInitGrid = false;
	int nCtrl = 0;
	int nRet = sim_xf_update_grid_tree(trGetN, bInitGrid, false, &nCtrl);
	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);	

	if(!sim_xf_check_tree_settings(trGetN, strErrMsg))
	{
		bUpdateGraph = false;
		bOKEnable = false;
		bBTN1Enable = false;
	}
	///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	
}

// 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)
{
//	printf("On GetNGraphBox_OnUpdateControlGraph, Graphname = %s \n",CntrlGraph.GetName()); 
//	UpdateSimuGraph(trGetN, CntrlGraph, CntrlGraphData);

}

// 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)
{
	///Arvin 01/24/08 QA70-10875 NEED_CLEAN_STATIC_MATRIXLAYER	
	if(ml.IsValid())
		ml.Destroy();
	///end NEED_CLEAN_STATIC_MATRIXLAYER
}
//------------
//
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
	bOKEnable = sim_xf_on_save_button(trGetN, strErrMsg);
	bBTN1Enable = false;
	///end CLEAN_CODE_FOR_XF_SIMCURVE_AND_SIMSURFACE
	/*
	Tree tr;
	if(!tr.Load(USER_SIMULATE_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_SIMULATE_FILE);
	}
	else
	{
		tr.AddNumericNode(0, strFunction, 0);
		TreeNode trTheme = tr.GetNode(strFunction);
		create_theme_tree(trGetN, trTheme);
		tr.Save(USER_SIMULATE_FILE);
	}
	*/
		
}
//


///////////////////////////////////////////////////////
	
int GetNGraphBox_simsurface(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

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

