/*------------------------------------------------------------------------------*
 * File Name:				 													*
 * Creation: 																	*
 * Purpose: OriginC Source C file												*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 * Frank 05/12/04		CHANGE_SETYSCALE										*
 * Frank 5/29/04 	v8.0880	QA70-6086	CHANGE_SIMULATE_STRUCT					*
 * Frank 5/29/04	v8.0880	QA70-6086	COMMENT_FUNCTION_NOT_NEED				*
 * Frank 06/07/04	v8.0884 QA70-6086	CHANGE_SIMULATION_RANGE_FIXED_TO_PARA	*
 * Frank 06/07/04	v8.0884 QA70-6086	MODIFY_Y_SCALE_TYPE						*
 * Frank 06/10/04	v8.0884 QA70-6086	MODIFY_Y_SCALE_TYPE_DISPLAY				*
 * Frank 06/16/04	v8.0890	QA70-6086	DEAL_RIGHT_CLICK_CONTEXT_ASSESS			*
 * Frank 06/22/04	v8.0893 QA70-6086	REFRESH_GRID_SHOW_NOT_RECONSTRUCT_ALL_GRIL_ROW*
 * Frank 06/24/04	v8.0895	QA70-6086	DOUBLE_AND_RIGHT_CLICK_SIMULATE_PANE	*
 * Frank 7/6/04		v8.0901	QA70-6583	FEATURE_OF_SIMULATE_PLOT_CURVE_SETTINGS *
 * Frank 7/12/04	v8.0905	QA70-6583	FEATURE_OF_SIMULATE_PLOT_CURVE_LABEL	*
 * Frank 7/28/04	v8.0104 QA70-6729	SIMULATION_SETTING_SEPARATE_FILE		*
 * Frank 8/5/04 	v8.0111 			SIMULATION_PANEL_SHOW					*
 * Frank 8/27/04 	v8.0122				SIMILATE_UPDATE_SCALE_METHOD			*
 * Frank 8/30/04 	v8.0125b QA70-6086	APPLY_SIMULATE_SETTING_TO_CREATED_GRAPH	*
 * Frank 10/12/04 	v8.0147b QA70-6086	FIXED_PROBLEM_MESSAGE_CHANGED			*
 * Frank 11/04/04 	v8.0159 QA70-6583	CREATE_WITH_TEMP_NAME_AND_SAVE_GRAPH_SETTING_OF_SIMULATE		*
 * Frank 12/07/04 	v8.0170 QA70-6583	SAVE_TO_FDF_DIRECTLY					*
 * Frank v8.0174	12/15/04			SEPARATE_GUI_AND_ACTION					*
 * Danice 12/23/04 v8.0176 CODE_CLEAN_UP_REMOVE_DUPLICATE						*
 * Frank 03/03/05 DISABLE_BUTTON_STATE_WHEN_SYS_FUNCTION						*
 * AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO										*
 * DG 3/29/05 v8.0211 FUNCTION_PLOT_PARAMETER_LITTLE_BUG						*
 * DG 4/26/05 v8.0227 REWRITE_SIMULATE											*
 * DG 7/27/05 QA70-7488 FIX_LOST_PARAMETER_VALUE								*
 * Jasmine 09/27/05 v8.0310 SPLITTER_INIT_SIZE_ON_READY							*
 * Jasmine 09/27/05 QA70-8114 ALLOW_CLICK_AXES									*
 * Frank 10/16/05 COMMENT_NOT_USE_MARCO											*
 *	Kenny 08/25/2009 QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC				*
 *------------------------------------------------------------------------------*/
#ifndef	_FO_SIMULATE_SPLITTER_H_
#define _FO_SIMULATE_SPLITTER_H_
#include "GraphPageControl.h"
//#include <nlfit.h>
#include	<ONLSF.h>

#define SIMULATE_SETTING				_L("Simulate setting")
#define PARALIST_LABEL_PARAM_NAMES		_L("Parameters")
#define PARALIST_LABEL_PARAM_NUM		_L("Number of Points")	//"Num of Points"  //Frank 23/6/04 Change from "Num of Points" to "Number of Points"
#define PLOTTING_GETN_LABEL				_L("Plot Settings")		//Frank 23/6/04 Change from "Plotting Settings" to "Plot Settings"
#define PLOT_PARAMETERS_RANGES_LABEL	_L("Parameter Ranges: ")
///-----Frank 06/07/04	v8.0884 QA70-6086	CHANGE_SIMULATION_RANGE_FIXED_TO_PARA
#define SIMULATE_CURVE_UPDATE			"CurveUpdate"
#define SIMULATE_GRAPH_TEMPLATE_NAME	"FDFSimulate.otp"

enum
{
	RANGE_VALUE_FROM,
	RANGE_VALUE_TO,
	RANGE_VALUE_STEPS,
	
	RANGE_VALUE_TOTAL_SIZE	///DG 5/16/05
};

///DG 5/18/05 REWRITE_SIMULATE
/*
#define SIMULATE_DATA_X_FROM			"X From"
#define SIMULATE_DATA_X_TO				"X To"
#define PARAMETERS_RANGE_SECTION		3
#define SIMULATE_GRAPH_SETTING_PATH		GetAppPath(false) + "DefaultSettings\\" + "FOS_GS.xml"
enum
{
	COPY_SETTINGS_MENU,
	PASTE_SETTINGS_MENU	
};
enum
{
	IDE_SCALE_X 			= 500,
	IDE_SCALE_X_FROM 		= 501,
	IDE_SCALE_X_TO			= 502,
	IDE_SCALE_Y 			= 503,
	IDE_SCALE_Y_SCALE_TYPE 	= 504,
	IDE_SCALE_Y_FROM		= 505,
	IDE_SCALE_Y_TO			= 506,
	IDE_SCALE_NUM_OF_POINTS	
};
enum
{
	IDST_FO_FUNCTION_SETTING_OPTIONS			=  0x00300001,
	IDST_FO_PARAMETERS_OPTIONS					=  0x00300004,
	IDST_FO_PARAMETERS_RANGE_OPTIONS	=	0x00300002,
	IDST_FO_PLOTTING_SETTING		
};
///----End 
enum 
{
	ROW_CREATE_FUNCTION_PLOT,
	ROW_UPDATE_SAMPLE_CURVE,
	ROW_FUNCTION,
	ROW_SAVE_SETTINGS_TO_FDF,
	ROW_PARAMETERS
	//Because parameter counts can't know, so the follow row can't be foreknow.
};
enum
{
	IDE_GRAPH_SET_SHOWXAXIS = 700,
	IDE_GRAPH_SET_SHOWYAXIS ,
	IDE_GRAPH_SET_SHOWPARAMETERS ,
	IDE_GRAPH_SET_REALTIME ,
};
class  FOSimulateSplitter: public TreeEditSplitter
{
public:
	FOSimulateSplitter() : TreeEditSplitter(true, true)
	{
		m_nPlotIndex = -1;// to indicate no plot made yet
		//--- CPY 4/9/04
		m_dwNoClicks = NOCLICK_DATA_PLOT | NOCLICK_LABEL | NOCLICK_TICKLABEL | NOCLICK_LAYER;
		//---
		//m_strTempSettingFolder = getTempSettingsFolder();
	}
	//Frank 7/6/04		v8.0901	QA70-6583	FEATURE_OF_SIMULATE_PLOT_CURVE_SETTINGS
	~FOSimulateSplitter() 
	{
		saveGraphSettingsToUserSettingFile();
	}
	//End	FEATURE_OF_SIMULATE_PLOT_CURVE_SETTINGS
	BOOL GetFunction(TreeNode& trFunctionDetail)
	{
		//Frank 7/6/04		v8.0901	QA70-6583	FEATURE_OF_SIMULATE_PLOT_CURVE_SETTINGS
		string strAttribute;
		//if( m_trFunc && m_trFunc.GetAttribute(STR_CHANGED_ATTRIB,strAttribute))
		/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
		//if( m_trFunctionDetail &&  m_trSimulate.GetAttribute(STR_CHANGED_ATTRIB,strAttribute))
		//	saveLastSimulateSettingsToXMLFile(m_trSimulate);//Frank 7/28/04	v8.0104 QA70-6729	SIMULATION_SETTING_SEPARATE_FILE
		//	//saveLastSimulateSettingsToTempFile(m_trSimulate);
		////End
		//m_trFunctionDetail=trFunctionDetail;
		if( m_trSel &&  m_trSimulate.GetAttribute(STR_CHANGED_ATTRIB,strAttribute))
			saveLastSimulateSettingsToXMLFile(m_trSimulate);//Frank 7/28/04	v8.0104 QA70-6729	SIMULATION_SETTING_SEPARATE_FILE
		m_trSel = trFunctionDetail;  
		/// END CLEANING_CODES_IN_FO
		
		//if(!trFunc)
			//return false;
		m_strCreatedGraphName ="";
	
		return TRUE;
	}
	void ConstructNoPrevTree()
	{
		/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
		if(m_trSel)
		{
			TreeNode junk;
			m_trSel = junk;
		}
		ConstructWithoutTree();
		m_graphCntl.RemovePlot(m_nPlotIndex);		
		/// END CLEANING_CODES_IN_FO

	}
			
	void InitSpiliterResize(Control ctrl)
	{
		// 1st time too early, control not properly sized, but after 1st time, user will do resizing on their own
		RECT r1;
		ctrl.GetWindowRect(&r1);
		int nHight = RECT_HEIGHT(r1);
		SetColSize(0,nHight,false);
			
	}
	void	OnChangeFunction()
	{
		getCollapsedStates();///Frank 8/5/04 	v8.0111 			SIMULATION_PANEL_SHOW
		
		if(!isFuncTreeValid())
		{
			ConstructNoPrevTree();
			return;
		}
		/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
		//if (!m_NF.SetTree(m_trFunctionDetail))
		if (!m_NF.SetTree(m_trSel))
		/// END CLEANING_CODES_IN_FO
		{
			_DMSG("Invalid function");
			ConstructNoPrevTree();
			m_graphCntl.RemovePlot(0);
			return ;
		}
		m_bIsFunctGetFirstTime = false;
		m_bIsReadyParamList = true;
		
		if(!chcekSimulateSettinInFDF())
			//Frank 7/28/04	v8.0104 QA70-6729	SIMULATION_SETTING_SEPARATE_FILE
			if(!loadSimulationSetting(m_trSimulate))
			;
		//After loadSimulationSetting if not exist the default setting or saved setting, will create one
		checkSimulationTree(m_trSimulate);//Frank 7/15/04 v8.0908 QA70-6583   UPDATE_PARAMETERS_COUNT
			//if(!loadDefaultGridValue(m_trSimulate))
				//;
		//End	
		redrawGraph( true );
		
		ConstructSimulationTree();
	
		return ;		
	}
	//End 	FEATURE_OF_SIMULATE_PLOT_CURVE_SETTINGS
	///Frank v8.0174	12/15/04			SEPARATE_GUI_AND_ACTION		
	//void OnChangeSimulateByFunctionSelect(TreeNode trFunction, TreeNode trFunctionDetail, bool functDetailChanged = false)	///Danice CODE_CLEAN_UP_REMOVE_DUPLICATE
	void OnChangeSimulateByFunctionSelect(TreeNode trFunctionDetail, bool functDetailChanged = false)
	{
		///---Danice 12/24/04 : function detail change is not posted when it should be updated
		if(!GetFunction(trFunctionDetail))//Update Function Tree from Top panel to Bottom panel 
			return;
		OnChangeFunction();
		///---end
	}
	///End		SEPARATE_GUI_AND_ACTION		
protected:
EVENTS_BEGIN

	//------------- begin required events
	// the following events are required for the splitter and related controls
	ON_INIT(OnInitSplitter)
	ON_DESTROY(OnDestroy)
	ON_SIZE(OnCtrlResize)

	ON_GETNDLG_MSGS(GetTreeEditPaneID())
	ON_USER_MSG(WM_USER_ON_TRACK, OnTrackSlider)
	ON_USER_MSG(WM_USER_TREEEDITOR_VALUE_CHANGE, OnAfterValueChange)
	ON_GRID_DBLCLICK(GetTreeEditPaneID(), OnDblClick)
	//------------- end required events	
EVENTS_END

	BOOL OnInitSplitter()
	{
		m_bIsReadyParamList = false;

		//Create Tree Edit control
		CreateTreeEditPane(); // creation order dose not matter now, Tarak said
		GraphControl gctrl;
		CreateMainPane(gctrl);
		if(gctrl)
			m_graphCntl.Create(gctrl, m_dwNoClicks, SIMULATE_GRAPH_TEMPLATE_NAME, NULL, "FO Temp Graph", "FO Temp wks");////Frank 11/04/04 	v8.0159 QA70-6583	CREATE_WITH_TEMP_NAME_AND_SAVE_GRAPH_SETTING_OF_SIMULATE
		
				
		Window Wnd = GetParent();
		Control	cntr = Wnd.GetDlgItem(IDC_FO_SIMULATE_BOX);
		InitSpiliterResize(cntr);
		/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
		// no need redo this step
		// ConstructNoPrevTree();
		/// END CLEANING_CODES_IN_FO

		///Frank 11/04/04 	v8.0159 QA70-6583	CREATE_WITH_TEMP_NAME_AND_SAVE_GRAPH_SETTING_OF_SIMULATE
		if(!loadGraphSettingsFromUserSettingFile())
			createGraphSettingsNode();
		//createGraphSettingsNode();
		///Ene	CREATE_WITH_TEMP_NAME_AND_SAVE_GRAPH_SETTING_OF_SIMULATE
		return SetReady();
	}
	//Frank 06/24/04	v8.0895	QA70-6086	DOUBLE_AND_RIGHT_CLICK_SIMULATE_PANE
	void OnDblClick(Control flxControl)
	{
		//vector<byte> vn;
		//m_treeEditCntrl.GetCollapsed(vn);
		int nRow, nCol;
		m_treeEditCntrl.GetMouseCell(nRow,  nCol);
		if(nRow < 0)
			return ;
		//------- CPY 8/27/04 QA70-5890 v8.0125 BRANCH_ALLOW_CHECKBOX
		int nState = m_treeEditCntrl.GetCollapsed(nRow);
		if(nState >= 0)
			m_treeEditCntrl.SetCollapsed(nRow, nState>0? false:true);
		//------- end CPY 8/27/04 QA70-5890 v8.0125 BRANCH_ALLOW_CHECKBOX
	}
	
	void OnBeforeMouseDown(Control cntrl, short nButton, short nShift, float X, float Y, BOOL* pCancel)
	{
		int nClickRow, nClickCol;
		m_treeEditCntrl.GetMouseCell(nClickRow, nClickCol);
		
		if(MK_RBUTTON == nButton)// && *pCancel)
		{
			if(0 <= nClickRow && nClickRow != m_treeEditCntrl.GetSelectedRow())
			{
				m_treeEditCntrl.SelRow(nClickRow);	
				//m_trList.SelRow(nClickRow);
			}
		}
	}
	//End	DOUBLE_AND_RIGHT_CLICK_SIMULATE_PANE
	//Can't debug.
	BOOL OnTrackSlider(uint wParam, uint lParam)
	{
		int nPos = wParam;
		double* pVal = (double*) lParam;
		if(pVal)
		{
			int nEditRow = m_treeEditCntrl.GetEditRow();
			//printf("%d) Slider %d and %f\n", nEditRow, nPos, *pVal);
			TreeNode trEdit = m_treeEditCntrl.GetEditNode();
			trEdit.dVal = *pVal;
			//m_bSlideChage = true;
			redrawGraph(false);
			updateChange( nEditRow );
			//printf("%d\n", nEditRow);
			
		}
		else
			out_str("NULL lParam");
		
		return true;
	}
	
	void OnRowColChange(Control cntrl)
	{
		int nRow = m_treeEditCntrl.GetSelectedRow();
		//if( nRow > 0 && 0 != m_treeEditCntrl.GetLevel(nRow) && m_bIsFunctGetFirstTime)
		if( nRow > 0 && m_bIsFunctGetFirstTime)
		{
			m_treeEditCntrl.OnRowColChange();
		}
	}	
	//Frank 7/6/04		v8.0901	QA70-6583	FEATURE_OF_SIMULATE_PLOT_CURVE_SETTINGS
	void OnButtonClick(Control flxControl, int nRow, int nCol)
	{
		_DMSG_S("Button Click");
		if( nRow ==ROW_CREATE_FUNCTION_PLOT )
		{
			createFunctionPlot();
		}
		else
			if(nRow == ROW_UPDATE_SAMPLE_CURVE )
			{
				updateSampleCurve();
			}
			else
				if(nRow == ROW_SAVE_SETTINGS_TO_FDF )
					saveSettingsToFDF();
	}
	//End			FEATURE_OF_SIMULATE_PLOT_CURVE_SETTINGS
	void OnAfterValueChange(int nRow, DWORD lParam)
	{
		if(!m_bIsFunctGetFirstTime )
		{
			_DMSG_S("new");
			m_bIsFunctGetFirstTime = true;
		}
		///Frank 06/16/04	v8.0890	QA70-6086	DEAL_RIGHT_CLICK_CONTEXT_ASSESS	

		///Frank 10/12/04 	v8.0147b QA70-6086	FIXED_PROBLEM_MESSAGE_CHANGED
		//Change lParam ==0 to lParam > 0, and change lParam = 1 to lParam == 0. 
		///End	FIXED_PROBLEM_MESSAGE_CHANGED
		//If lParam > 0, just update one row; if lParam = 0, update whole section.
		//if(lParam == 0)		
		if(lParam > 0)		
		{
			updateChange( nRow );
		}
		else
			//if(lParam == 1)
			if(lParam == 0)
				updateSimulateTreeSectionChange( nRow );
			///End DEAL_RIGHT_CLICK_CONTEXT_ASSESS
	}	

	//1: Create an simulate GetN show template, not input value, 
	//2: Check and modify parameters section and parameter range section to fix current function.
	//3: Update grid show, not to reconstruct the GetN dialog
	void ConstructSimulationTree()
	{
		
		//vector<byte> vn;
		//int nGetCollRet = m_treeEditCntrl.GetCollapsed(vn, true);
		///Frank 03/03/05 DISABLE_BUTTON_STATE_WHEN_SYS_FUNCTION
		/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
		//bool bIsSystemFolder = m_NFO.IsSysFunction(m_trFunctionDetail);
		bool bIsSystemFolder = m_NFO.IsSysFunction(m_trSel);
		/// END CLEANING_CODES_IN_FO
		///End DISABLE_BUTTON_STATE_WHEN_SYS_FUNCTION
		
		GETN_TREE(trTemp)
		GETN_OPTION_GRIDLINE(flexGridFlatVert)	
		
		GETN_BUTTON(CreateFunctionPlot, "Create Function Plot", "Create")
		GETN_BUTTON(UpdateSampleCurve , "Update Sample Curve ", "Update")

		///Frank 03/03/05 DISABLE_BUTTON_STATE_WHEN_SYS_FUNCTION
		if(bIsSystemFolder)
			GETN_READ_ONLY
		///End DISABLE_BUTTON_STATE_WHEN_SYS_FUNCTION
		
		GETN_BEGIN_BRANCH(Function ,SIMULATE_SETTING )
		GETN_ID_BRANCH(IDST_FO_FUNCTION_SETTING_OPTIONS) GETN_OPTION_BRANCH(GETNBRANCH_SAVE_SETTINGS | GETNBRANCH_KEEP_SIZE_ON_EXPAND)

		GETN_BUTTON(SaveSettingstoFDF, "Save Settings to FDF", "Save") 

		///Frank 03/03/05 DISABLE_BUTTON_STATE_WHEN_SYS_FUNCTION
		if(bIsSystemFolder)
			GETN_READ_ONLY
		///End DISABLE_BUTTON_STATE_WHEN_SYS_FUNCTION
		
			GETN_BEGIN_BRANCH(Parameters, PARALIST_LABEL_PARAM_NAMES)
			GETN_OPTION_BRANCH(GETNBRANCH_KEEP_SIZE_ON_COLLAPSE) 
			GETN_END_BRANCH(Parameters)
			
			GETN_BEGIN_BRANCH(ParasRange, PLOT_PARAMETERS_RANGES_LABEL + "(From|To|#Steps)")  
			GETN_OPTION_BRANCH(GETNBRANCH_KEEP_SIZE_ON_COLLAPSE) 				
			GETN_END_BRANCH(ParasRange)
			
			GETN_BEGIN_BRANCH(Plotting, PLOTTING_GETN_LABEL)
			GETN_ID_BRANCH(IDST_FO_PLOTTING_SETTING) GETN_OPTION_BRANCH(GETNBRANCH_KEEP_SIZE_ON_EXPAND)//GETN_OPTION_BRANCH(GETNBRANCH_SAVE_SETTINGS | GETNBRANCH_KEEP_SIZE_ON_COLLAPSE)
	
				GETN_BEGIN_BRANCH(InDepen, "X")		GETN_ID_BRANCH(IDE_SCALE_X)
				GETN_OPTION_BRANCH(GETNBRANCH_KEEP_SIZE_ON_EXPAND) 		
					GETN_NUM(From, "From", 0)	GETN_ID(IDE_SCALE_X_FROM)
					GETN_NUM(To, 	"To",  0)		GETN_ID(IDE_SCALE_X_TO)
				GETN_END_BRANCH(InDepen)

				GETN_BEGIN_BRANCH(Depen, "Y")		GETN_ID_BRANCH(IDE_SCALE_Y)
				GETN_OPTION_BRANCH(GETNBRANCH_KEEP_SIZE_ON_EXPAND) 
	   				GETN_OPTION_DISPLAY_FORMAT( DISPLAY_RIGHT );		
					GETN_CHECK(Type, "Y-> Auto Scale",0)	GETN_ID(IDE_SCALE_Y_SCALE_TYPE)	
					int		nGetNTreeCount	= trTemp.GetNodeCount();
					int		nGetNTreeBranchCount ;
					nGetNTreeCount = tree_count_items(trTemp, &nGetNTreeBranchCount);
					GETN_NUM(From, "From", 0)							GETN_ID(IDE_SCALE_Y_FROM)
					GETN_NUM(To, 	"To",  0  )							GETN_ID(IDE_SCALE_Y_TO)		
				GETN_END_BRANCH(Depen)
	
				GETN_NUM(NumPts, PARALIST_LABEL_PARAM_NUM, 0)	GETN_ID(IDE_SCALE_NUM_OF_POINTS)		
			GETN_END_BRANCH(Plotting)
			
		GETN_END_BRANCH(Function)
	
		GETN_BEGIN_BRANCH(Graph, "Graph setting")			
		GETN_OPTION_BRANCH(GETNBRANCH_KEEP_SIZE_ON_COLLAPSE) 
			GETN_CHECK(ShowXAxis, "Show X Axis",1)					GETN_ID(IDE_GRAPH_SET_SHOWXAXIS)
			GETN_CHECK(ShowYAxis, "Show Y Axis",1)					GETN_ID(IDE_GRAPH_SET_SHOWYAXIS)
			GETN_CHECK(ShowParameters, "Show Parameters",0)			GETN_ID(IDE_GRAPH_SET_SHOWPARAMETERS)
			GETN_CHECK(RealTime, "Real Time",1)						GETN_ID(IDE_GRAPH_SET_REALTIME)
		GETN_END_BRANCH(Graph)	
		
		
		constructSlideList(trTemp.Function.Parameters, trTemp.Function.ParasRange);

		vector<int> vnIDs;
		vector<string> vsValue;
		tree_get_values_with_ids(m_trSimulate,vnIDs, vsValue);
		//tree_set_values_by_ids(trTemp.Function,vnIDs, vsValue);
		tree_set_values_by_ids(trTemp,vnIDs, vsValue);
		
		updateSlideRange(trTemp.Function.Parameters, trTemp.Function.ParasRange);
		m_paramTree = trTemp;
		int nParasCount = trTemp.Function.Parameters.GetNodeCount();
		int nYScaleRow = nGetNTreeCount+nGetNTreeBranchCount+nParasCount*2;
		updateYValueGridShowState(false, nYScaleRow+1, nYScaleRow+3);
		
		m_treeEditCntrl.Update(m_paramTree, true, true);
		//if(nGetCollRet> 1) //bigger than 1 because will get wrong collapsed first of the first time not simulate settings.
			//m_treeEditCntrl.SetCollapsed(vn, true);
		if(m_vecBCoallapedState.GetSize()>1)
			m_treeEditCntrl.SetCollapsed(m_vecBCoallapedState, true);
		
	}	
private:
	bool	updateSlideRange(TreeNode& trParameters, TreeNode& trParameterRanges )
	{
		if(!trParameters || !trParameterRanges)
			return false;
		
		//TreeNode trTempNode;
		string strDefaultValue;
		int nIndex =1;
		string strName  ;
		TreeNode trParaNode;
		foreach(TreeNode trRange in trParameterRanges.Children)
		{
			///DG 3/1/05 CODE_CLEAN_UP_REMOVE_DUPLICATE : should not use hard code
			trRange.GetAttribute(STR_LABEL_ATTRIB, strName);
			trParaNode=trParameters.FindNodeByAttribute(STR_LABEL_ATTRIB, strName);
			///end CODE_CLEAN_UP_REMOVE_DUPLICATE
			trParaNode.SetAttribute(STR_COMBO_ATTRIB, trRange.strVal);
			nIndex++;
		}
		return true;
	}
	//Frank 7/6/04		v8.0901	QA70-6583	FEATURE_OF_SIMULATE_PLOT_CURVE_SETTINGS
	bool constructSlideList(TreeNode& trParameters, TreeNode& trParameterRanges )
	{
		if(!trParameters || !trParameterRanges)
			return false;
		double 		dParaValue;
		string			strParaRange;
		vector<string> vsParaNames;
		vector<string> vsParasRange;
		string strValName;

		getParametersRange(vsParaNames);//, vsParasRange);
	
		TreeNode trTempNode;
		string strDefaultValue;
		for(int i=0; i < vsParaNames.GetSize() ; i++)
		{
			strValName = "P" + (i+1);
			//if( m_trSimulation.Parameters.GetNode(strValName).IsValid() )
			//{
				//dParaValue = m_trSimulation.Parameters.GetNode(strValName).dVal;
			//}
			//else
				dParaValue = 30;
				
			//GETN_SLIDER(strValName, vsParaNames[i], dParaValue, vsParasRange[i]);
			strDefaultValue = dParaValue; 
			trTempNode = trParameters.AddTextNode( strDefaultValue, strValName , TRGP_SLIDEREDIT);
			trTempNode.SetAttribute(STR_LABEL_ATTRIB, vsParaNames[i]) ;
			trTempNode.SetAttribute(STR_COMBO_ATTRIB, "0|500|200");//vsParasRange[i]);
			
			trTempNode.SetAttribute(STR_DATAID_ATTRIB,i+1 );			//			GETN_ID(i+1)
			
			strParaRange = vsParaNames[i] ;
			//GETN_STR(strValName,strParaRange, vsParasRange[j])
			trTempNode = trParameterRanges.AddTextNode("0|500|200",strValName , TRGP_STR);//vsParasRange[i]
			trTempNode.SetAttribute(STR_LABEL_ATTRIB, strParaRange) ;
			
			trTempNode.SetAttribute(STR_DATAID_ATTRIB,i + 1001 );			//GETN_ID(1000 + j + 1 )
		}
		
		return true;
	}
	bool updateChange( int nRow)
	{
		if( nRow > 0 && 0 != m_treeEditCntrl.GetLevel(nRow) )
		{
			Tree 	trChange;
			TreeNode trCellSimulation = tree_get_node(m_paramTree, nRow );
			trChange.AddNode(trCellSimulation);
			
			int nID;
			if( !trCellSimulation.IsValid() || trCellSimulation.GetNodeCount() )
				return	false;	//not need to update
			if( trCellSimulation.GetAttribute(STR_DATAID_ATTRIB, nID))
			{
				int nRelateChangedRow;
				bool bRedrawGraph, bUpdateGridShow;
				updateSimulationTree( nRow ,nRelateChangedRow, bRedrawGraph, bUpdateGridShow);
				if(nRow != nRelateChangedRow)
				{
					TreeNode trTempChange =  tree_get_node(m_paramTree, nRelateChangedRow );
					trChange.AddNode(trTempChange); 
				}
				updateSimulateSetting(trChange, m_trSimulate);
				
				if(bRedrawGraph)
					redrawGraph( false );
				else
					setYScale();
				
				if(bUpdateGridShow)
					updateYValueGridShowState(true,nRow+1, nRow+3);
				
				//postSimulateChagned();
			}
		}
		return true;
	}
	
	bool updateSimulateSetting(TreeNode &trGridValue, TreeNode &trSimulateSettings)
	{
		if(!trGridValue || !trSimulateSettings)
			return false;
		vector<int> vnIDs;
		vector<string> vsValue;
		tree_get_values_with_ids(trGridValue,vnIDs, vsValue);
		tree_set_values_by_ids(trSimulateSettings,vnIDs, vsValue);
		
		trSimulateSettings.SetAttribute(STR_CHANGED_ATTRIB,"Test");//Frank 7/28/04
		return true;
	}
	
	bool createFunctionPlot()
	{
		redrawGraph(false, true);
		return true;
	}
	
	bool updateSampleCurve()
	{
		/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
		//if(m_nPlotIndex == -1|| !m_trFunctionDetail)
		if(m_nPlotIndex == -1|| !m_trSel)
		/// END CLEANING_CODES_IN_FO
			return false;
		
		PictureHolder pictHolder;
		//string 	strGPname = m_graphCntl.GetName();
		GraphPage	gp = m_graphCntl.GetPage();
		if(!page_get_picture(gp, pictHolder, "EMF", 72, false))
			return error_report("failed to create Curve Preview from graph");
		
		/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
		//m_trFunctionDetail.Curve.pict = pictHolder;
		//m_trFunctionDetail.SetAttribute(SIMULATE_CURVE_UPDATE, 1);
		m_trSel.Curve.pict = pictHolder;
		m_trSel.SetAttribute(SIMULATE_CURVE_UPDATE, 1);
		/// END CLEANING_CODES_IN_FO
		postSimulateChagned();
		
		return true;
	}
	///Frank 12/07/04 	v8.0170 QA70-6583	SAVE_TO_FDF_DIRECTLY
	bool saveChangeToFDF(TreeNode &trFunction)
	{
		trFunction.SetAttribute( STR_CHANGED_ATTRIB, "" );
		//m_NFO.SaveFunction(trFunction);		///Danice 12/24/04 : move to NFO
		m_NFO.SaveSimulateTree(trFunction);
		return true;
	}
	///End	SAVE_TO_FDF_DIRECTLY
	bool saveSettingsToFDF()
	{
		PROFILE_HRGLASS	///DG 3/1/05 wait until finishing saving
		
		TreeNode trFunctionGridValue = m_paramTree.Function;
		if(!trFunctionGridValue)
			return false;

		updateSimulateSetting(trFunctionGridValue, m_trSimulate);
		return addSettingsNodeToFunctionTree(m_trSimulate.SimulateSetting);
	}
	
	bool addSettingsNodeToFunctionTree( TreeNode &trSettings )
	{
		if(!trSettings)
			return false;
		/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
		//TreeNode trSourceSettings = m_trFunctionDetail.SimulateSetting;
		TreeNode trSourceSettings = m_trSel.SimulateSetting;
		/// END CLEANING_CODES_IN_FO
		
		if(trSourceSettings)
			trSourceSettings.Replace(trSettings);
		else
			/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
			//m_trFunctionDetail.AddNode(trSettings);
			m_trSel.AddNode(trSettings);
			/// END CLEANING_CODES_IN_FO
			
		postSimulateChagned();
		return true;
	}
	//End	FEATURE_OF_SIMULATE_PLOT_CURVE_SETTINGS
	///---Frank 06/16/04	v8.0890	QA70-6086	DEAL_RIGHT_CLICK_CONTEXT_ASSESS
	void 	postSimulateChagned()
	{
		///Frank 12/07/04 	v8.0170 QA70-6583	SAVE_TO_FDF_DIRECTLY
		/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
		//saveChangeToFDF(m_trFunctionDetail);
		saveChangeToFDF(m_trSel);
		/// END CLEANING_CODES_IN_FO
	}
	//Frank 7/28/04	v8.0104 QA70-6729	SIMULATION_SETTING_SEPARATE_FILE
	bool	loadSimulationSetting(TreeNode &trSimulation)
	{
		if(!trSimulation)
			return false;
		
		string strFunctionName = getFunctionName();
		if(strFunctionName.Compare("") == 0)
			return false;
		TreeNode 	trSetting;
		
		//First step: Load simulation setting from user file nlsf.oss under user folder.
		string	strSettingPath;
		strSettingPath = GetAppPath(false) + "nlsf.oss";
		
		if(!strSettingPath.IsFile() || !loadSimulationSetting(strSettingPath, strFunctionName, trSetting))
		{
			//Second step: Load simulation setting from default nlsf.oss under theme folder.
			strSettingPath = GetAppPath(true)+"Themes\\" + "nlsf.oss";
			if(!strSettingPath.IsFile() || !loadSimulationSetting(strSettingPath, strFunctionName, trSetting))
				//return false;
				;
		}
		
		TreeNode trSimulationSetting = trSimulation.SimulateSetting;
		if(!trSimulationSetting)
			trSimulationSetting = trSimulation.AddNode(STR_SIMULATE_NODE);
		
		trSimulationSetting.Reset();
		trSimulationSetting.Replace(trSetting);
		
		if(trSimulationSetting.GetNodeCount()==0)
			trSimulationSetting.Remove();
		
		return true;
	}
	
	//Load simulation setting from xml file.	
	bool loadSimulationSetting(string &strFile, string &strFunctionName,TreeNode &trSimulationSetting )
	{
		Tree	trAllSimulateSetting;
		bool bRet = trAllSimulateSetting.Load(strFile);
		
		if(!trAllSimulateSetting)
			return false;
		try
		{
			trSimulationSetting = trAllSimulateSetting.GetNode(strFunctionName).SimulateSetting;
		}
		catch(int nErr)
		{
			return false;
		}
		
		if(!trSimulationSetting)
			return false;
		return true;
	}
	
	string getFunctionName()
	{
		/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
		//TreeNode  trNode =  m_trFunctionDetail.GeneralInformation.FunctionName;
		TreeNode  trNode =  m_trSel.GeneralInformation.FunctionName;
		/// END CLEANING_CODES_IN_FO
		if(!trNode)
			return "";
		return trNode.strVal;
	}
	bool loadGlobalSettings(TreeNode &trGlobalSettings)
	{
		string strGlobalSetting = GetAppPath(false) + "DefaultSettings\FO Settings";

		string strGlobalSettingFile = strGlobalSetting + "\FOGlobalSettings.xml";
		Tree	trGSettings;
		if(strGlobalSettingFile.IsFile() && trGSettings.Load(strGlobalSettingFile))
		{
			TreeNode	trGSTemp = trGSettings.GetNode("FOGlobalSettings");
			if(trGSTemp)
			{
				trGlobalSettings.Replace(trGSTemp);
				return true;
			}
		}
		return false;
	}
	
	bool saveGlobalSettings(TreeNode &trGlobalSettings)
	{
		string strGlobalSetting = GetAppPath(false) + "DefaultSettings\FO Settings";
		if(!CheckMakePath(strGlobalSetting))
			return false;
		string strGlobalSettingFile = strGlobalSetting + "\FOGlobalSettings.xml";
		Tree	trGSettings;
		if(strGlobalSettingFile.IsFile())
		{
			if(trGSettings.Load(strGlobalSettingFile))
			{
				TreeNode	trGSTemp = trGSettings.GetNode("FOGlobalSettings");
				if(trGSTemp)
					trGSTemp.Replace(trGlobalSettings);
			}
		}
		trGSettings.AddNode(trGlobalSettings);
		
		return trGSettings.Save(strGlobalSettingFile);
	}
	void 	getParametersRange(vector<string> &vsParaNames)//, vector<string> &vsParasRange)
	{
		//vector<string> vsParaLowBnds;
		//vector<string> vsParaUpBnds;
		
		/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
		//string strParas = m_trFunctionDetail.FittingParameters.Names.strVal;
		string strParas = m_trSel.FittingParameters.Names.strVal;
		/// END CLEANING_CODES_IN_FO
		
		strParas.GetTokens(vsParaNames, ','); 
	}
	int	getNumOfPointsToSimulate()
	{
		return 	m_trSimulate.SimulateSetting.Plotting.NumPts.nVal;
	}
	bool 	updateSimulateTreeSectionChange( uint nRow , bool bPostMessage = true )
	{
		if( 0 != m_treeEditCntrl.GetLevel(nRow))
			return false;
		
		TreeNode	trCellSectionNode	= tree_get_node(m_paramTree, nRow );
		if(!trCellSectionNode)
			return false;
		
		string		strTrName = trCellSectionNode.tagName;
		bool 		bValueChanged = false;
		
		if( lstrcmp(strTrName, "Function") == 0)
		{
			
			TreeNode    trGridParaValue =   trCellSectionNode.Parameters;
			TreeNode	trGridSection ;
			trGridSection = trCellSectionNode.ParasRange;

			int		nIndexOfParas = 1 ;
			foreach(TreeNode cNode in trGridSection.Children )
			{
				bool bTempValueChange;
				TreeNode trGridCellPara = tree_get_node(trGridParaValue, nIndexOfParas );
				setParaRange( cNode, trGridCellPara ,bTempValueChange);
				
				nIndexOfParas++;
				
				if(bTempValueChange)
					bValueChanged = true;
			}
			
			//int nYTypeRow = trCellSectionNode.GetNodeCount();
			//nYTypeRow = nRow + nYTypeRow - 9;
			
			int nYTypeRow ;
			int		nGetNTreeBranchCount ;
			nYTypeRow = tree_count_items(m_paramTree, &nGetNTreeBranchCount);
			nYTypeRow = nGetNTreeBranchCount + nYTypeRow - 8;

			
			updateSimulateSetting(trCellSectionNode, m_trSimulate);
			
			
			m_treeEditCntrl.UpdateGridValues(false, true, false);
			
			updateYValueGridShowState(true, nYTypeRow, nYTypeRow+2);
			//updateSimulateSetting(trCellSectionNode, m_trSimulate);
			
		}

		if(bValueChanged && bPostMessage)
		{ 
			redrawGraph( false );
			//postSimulateChagned();		
		}
		return true;
	}	
	
	bool	updateSimulationTree( uint nRow , int &nStartChangeRow , bool &bRedrawGraph = NULL, bool &bUpdateGridShow = NULL)
	{
		int nSelRow;
		TreeNode	trTemp;
		nStartChangeRow =  nRow ;
		
		if(0 != m_treeEditCntrl.GetLevel(nRow))
		{
			if(0 != nRow)	
			{
				//seach the parent node of the select row.
				//for( nSelRow = nRow-1; 1 != m_treeEditCntrl.GetLevel(nSelRow); nSelRow--)
					//;
				//trTemp = tree_get_node(m_paramTree, nSelRow , 1);
				TreeNode	trChangeCell	= tree_get_node(m_paramTree, nRow );
				trTemp = trChangeCell.Parent();
				string 	strTrName  = trTemp.tagName;
				bool bParaValueChanged = false;

				
				if( lstrcmp(strTrName, "ParasRange") == 0)
				{

					int nParentNodeCount;
					//for( nParentRow = nRow-1; 1 != m_treeEditCntrl.GetLevel(nParentRow); nParentRow--)
								//;
					nParentNodeCount = trTemp.GetNodeCount();
					TreeNode trGridCellPara = tree_get_node(m_paramTree, nRow-nParentNodeCount - 1);
					
					//trCellSimulation = tree_get_node(m_trSimulation, nRow-nParentNodeCount- 1 , 1);

					if(setParaRange(trChangeCell, trGridCellPara ,bParaValueChanged))// nRow-nParentNodeCount- 1
					{
						m_treeEditCntrl.UpdateGridValues(false, true, false);
					}
					else
						return false;
					
					nStartChangeRow =  nRow-nParentNodeCount-1 ;
					//saveParameterValue( trGridCellPara,trCellSimulation );
					//return	true;
				}
				else
					if(lstrcmp(strTrName, "Parameters") == 0)
					{
						//trCellSimulation = tree_get_node(m_trSimulation, nRow , 1);
						//return	saveParameterValue( trCell,trCellSimulation );
						//return true;
						bParaValueChanged = true;
					}
					else
						if(lstrcmp(strTrName, "Depen") == 0)
						{
							int nPlotID;
							if(trChangeCell.GetAttribute(STR_DATAID_ATTRIB,nPlotID) && nPlotID == IDE_SCALE_Y_SCALE_TYPE)
							//return updateYValueGridShowState(true,nRow+1, nRow+2);
							{
								if( bUpdateGridShow != NULL )
									bUpdateGridShow = true;
								///--Frank 8/27/04 	v8.0122				SIMILATE_UPDATE_SCALE_METHOD
								if(trChangeCell.nVal != 0)
									bParaValueChanged = true;
								else
								{
									bParaValueChanged = false;
									yScaleChangeFromAuto();
									return true;
								}
									
								///End	SIMILATE_UPDATE_SCALE_METHOD
							}
							else
								bParaValueChanged = true;
							
							//TreeNode	trTemp	= m_paramTree.GetNode("ParasRange");
							//int 		nCountRanges = trTemp.GetNodeCount();
							//trCellSimulation = tree_get_node(m_trSimulation, nRow - nCountRanges-1 );
							
							//bool bUpdateGridShow =false ;
							//savePlottingSetting(trCell,trCellSimulation ,bUpdateGridShow);
					
							//return true;
						}
						else
							if(lstrcmp(strTrName, "InDepen") == 0)
							{
								bParaValueChanged = true;
							};
				if( bRedrawGraph != NULL )
					bRedrawGraph	=  bParaValueChanged
				//if(bParaValueChanged)
					//redrawGraph( false );
			}
		}
		return true;
	}		
	void	yScaleChangeFromAuto()
	{
		double dsYmin, dsYmax;
		if(getYScale(dsYmin,dsYmax))
		{
			setGridYRange(dsYmin,dsYmax);
			updateYPlottingRange(dsYmin,dsYmax);
		}
	}

	bool 	setParaRange( TreeNode	&trCellRange,TreeNode	&trCellRangeValue , bool &bParaValueChange )//,int nParaIndex  
	{
		bParaValueChange = false;
		if( !trCellRange.IsValid() || !trCellRangeValue)
		return	false;
		string 	strRange = trCellRange.strVal;
		
		string 	strOldRange;
		if(trCellRangeValue.GetAttribute(STR_COMBO_ATTRIB, strOldRange) && strOldRange.CompareNoCase(strRange) != 0)
		{
			///---Frank 06/07/04	v8.0884 QA70-6086	CHANGE_SIMULATION_RANGE_FIXED_TO_PARA
			double	dCurrentValue ;//= atof(strRange);
			double	dRangeMax, dRangeMin;
			double  dTempValue;
			StringArray 	vsRangeValues;
			vsRangeValues.SetSize(3);
			
			if( PARAMETERS_RANGE_SECTION != strRange.GetTokens(vsRangeValues,'|') )
				return false;
			dRangeMax = atof(vsRangeValues[RANGE_VALUE_FROM]);
			dRangeMin = atof(vsRangeValues[RANGE_VALUE_TO]);
			dTempValue = dRangeMax;
			dRangeMax = max(dRangeMax, dRangeMin);
			dRangeMin = min(dTempValue, dRangeMin );
			dCurrentValue = trCellRangeValue.dVal;
			
			if( dCurrentValue<dRangeMin)
			{
				dCurrentValue = dRangeMin;
				trCellRangeValue.dVal = dCurrentValue;
				trCellRangeValue.SetAttribute(STR_COMBO_ATTRIB, "");
				
				bParaValueChange = true;
			}
			else
				if( dCurrentValue>dRangeMax )
				{
					dCurrentValue = dRangeMax;
					trCellRangeValue.dVal = dCurrentValue;
					trCellRangeValue.SetAttribute(STR_CHANGED_ATTRIB, "");
					
					bParaValueChange = true;
				}
			///---End

			trCellRangeValue.SetAttribute(STR_COMBO_ATTRIB, strRange);
			trCellRangeValue.SetAttribute(STR_COMBO_CHANGED, strOldRange);
			//m_treeEditCntrl.UpdateGridValues(false, true, false);
		}
		
		//int nNodeCount = trCellRange.Parent().GetNodeCount();
		//saveParaRangeToFunct(strRange,nNodeCount, nParaIndex-1);
		return true;
	}
	void	updateYValueGridShowState(bool bRefreshGrid = true, int nStartRow = 0 , int nEndRow = -1)
	{
		if(getYRescaleType())
		{
			//case Y_SCALE_AUTORESCALE: 
			m_paramTree.Function.Plotting.Depen.From.Show = false;
			m_paramTree.Function.Plotting.Depen.To.Show 	 = false;
		}
		else
		{
			//case Y_SCALE_FIXED:
			m_paramTree.Function.Plotting.Depen.From.Show = true;
			m_paramTree.Function.Plotting.Depen.To.Show 	 = true;
		}
		if(bRefreshGrid)
			m_treeEditCntrl.RefreashGridShow(m_paramTree,nStartRow, nEndRow );
	}
	bool setXScale(double dFrom, double dTo )
	{
		if(dFrom == NANUM)
			dFrom = 0;
		if(dTo == NANUM)
			dTo = 0;

		if( is_equal( round( dFrom, 3 ), round( dTo, 3 ) ) )

		{
			dTo = dFrom + 10;
		}
		return m_graphCntl.SetXAxisScale(dFrom, dTo );
	}
	///--Frank 8/27/04 	v8.0122				SIMILATE_UPDATE_SCALE_METHOD
	bool resetXYScale(double dFrom,double dTo )
	{
		if(!setXScale(dFrom, dTo))
			return false;

		return setYScale();
	}	
	bool setYScale()
	{
		double dFrom, dTo;
		getYRange(dFrom, dTo);					
		if(dFrom == NANUM)
			dFrom = 0;
		if(dTo == NANUM)
			dTo = 0;
		if( is_equal( round( dFrom, 3 ), round( dTo, 3 ) ) )
		{
			dTo = dFrom + 10;
		}
		if(getYRescaleType())
		{
			return m_graphCntl.SetYAxisScale(dFrom, dTo , LINEAR_SPACE , 1);		//Set y axis auto
		}
		else
		{
			return m_graphCntl.SetYAxisScale(dFrom, dTo , LINEAR_SPACE , 0);		///Set y axis scale as manual
		}
	}	
	///--End				SIMILATE_UPDATE_SCALE_METHOD

	bool setYScale(double &dFrom, double &dTo)//, int bYRescaleType = Y_SCALE_AUTORESCALE )
	{
		if(dFrom == NANUM)
			dFrom = 0;
		if(dTo == NANUM)
			dTo = 0;
		if( is_equal( round( dFrom, 3 ), round( dTo, 3 ) ) )
		{
			dTo = dFrom + 10;
		}
		if(getYRescaleType())
		{
			return m_graphCntl.SetYAxisScale(dFrom, dTo , LINEAR_SPACE , 1);		//Set y axis auto
		}
		else
		{
			//getYGridRange(dFrom, dTo);			//Get Y scale value from grid tree
			getYRange(dFrom, dTo);					//Frank 06/07/04	v8.0884 QA70-6086	MODIFY_Y_SCALE_TYPE	
			return m_graphCntl.SetYAxisScale(dFrom, dTo , LINEAR_SPACE , 0);		///Set y axis scale as manual
		}
	}
	///Frank 06/07/04	v8.0884 QA70-6086	MODIFY_Y_SCALE_TYPE	
	bool getYGridRange( double &dFrom, double &dTo)
	{
		if(!m_paramTree.Plotting.Depen)
			return false;
		dFrom 	= m_paramTree.Plotting.Depen.From.dVal;
		dTo	= m_paramTree.Plotting.Depen.To.dVal;
		return true;
	}
	///End
	//bool isFuncTreeValid(string *strFunctionName = NULL)	///DG 1/26/05 : no need function name
	bool isFuncTreeValid()
	{
		///DG 3/1/05 CODE_CLEAN_UP_REMOVE_DUPLICATE
		/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
		//return m_NFO.IsFunction(m_trFunctionDetail);
		return m_NFO.IsFunction(m_trSel);
		/// END CLEANING_CODES_IN_FO
		///end CODE_CLEAN_UP_REMOVE_DUPLICATE
	}
	///---Frank 29/5/04 v8.0880	QA70-6086 CHANGE_SIMULATE_STRUCT
	void redrawGraph( bool bNewGraph = true, bool bCreateGraphInWorkspace = false )
	{
		if(!m_bIsReadyParamList)
			return;
		
		//if(bNewGraph && m_nPlotIndex )
		if(bNewGraph && m_nPlotIndex && !bCreateGraphInWorkspace)
		{
			m_graphCntl.RemovePlot(m_nPlotIndex);
			m_nPlotIndex = -1;
			bNewGraph = true;
		}
		
		Dataset datX, datY;
		if(m_graphCntl.GetData(datX, 0) && m_graphCntl.GetData(datY, 1))
		{
			int nPts 		= getNumOfPointsToSimulate();
			double dXFrom, dXTo	;
			
			if(!getXRange(dXFrom, dXTo))
				return ;

			vector vXData;
			vector vdResult;
			vdResult.SetSize(nPts);
			vXData.Data( dXFrom, dXTo, ( dXTo - dXFrom )/(nPts-1));
			datX = vXData;
			vector vParameters;
			getParasValue(vParameters);
			
			vdResult = m_NF.Evaluate( vXData , vParameters);
			datY = vdResult;
			//double dR = m_NF.Eval(23,vParameters);		///Test Frank 
			int nPara = m_NF.NP;


			if(!bCreateGraphInWorkspace)
			{
				double dsYmin, dsYmax;
				vdResult.GetMinMax(dsYmin,dsYmax);
				if( bNewGraph )
				{
					m_nPlotIndex = m_graphCntl.AddPlot(0, 1, IDM_PLOT_LINE,true);			
				}
				///--Frank 8/27/04 	v8.0122				SIMILATE_UPDATE_SCALE_METHOD
				//else
				//{
					//m_graphCntl.PlotRescale();
				//}

				
				resetXYScale(dXFrom, dXTo);
				m_graphCntl.PlotRescale();
				
				if(getYRescaleType() )
				{   
					// Y_SCALE_AUTORESCALE 
					if(getYScale(dsYmin,dsYmax))
					{
						setGridYRange(dsYmin,dsYmax);
						updateYPlottingRange(dsYmin,dsYmax);
					}
				}
				///--End			SIMILATE_UPDATE_SCALE_METHOD
				if(getGetGraphSetting(3))
				{
					//if(lstrcmpi(m_strCreatedGraphName,"") != 0)
					if(!m_strCreatedGraphName.IsEmpty())
					{
						Worksheet wks(m_strCreatedGraphName);
						if(wks)
						{
							Dataset datX1, datY1;
							datX1.Attach(wks,0);
							datY1.Attach(wks,1);
							datX1	=	vXData;
							datY1	=	vdResult;
						}
							
					}
				}
			}
			else
			{
				////--Frank 8/30/04 	v8.0125b QA70-6086	APPLY_SIMULATE_SETTING_TO_CREATED_GRAPH
				Tree	trScale;
				getYAxisScaleSection(trScale);
				createPlotInOrigin(vXData, vdResult ,vParameters , trScale);
				//createPlotInOrigin(vXData, vdResult ,vParameters );
				////--End	APPLY_SIMULATE_SETTING_TO_CREATED_GRAPH
			}
		}
		else
			m_nPlotIndex = -1;			
	}
	////--Frank 8/30/04 	v8.0125b QA70-6086	APPLY_SIMULATE_SETTING_TO_CREATED_GRAPH
	bool getYAxisScaleSection(TreeNode &trN)
	{
		return m_graphCntl.GetAxisScale(trN, false);
		
	}
	////--End	APPLY_SIMULATE_SETTING_TO_CREATED_GRAPH

	///--Frank 8/27/04 	v8.0122				SIMILATE_UPDATE_SCALE_METHOD
	bool	getYScale(double &dFrom,double &dTo)
	{
		return 	m_graphCntl.GetYScaleValue(dFrom,dTo);
	}
	///End			SIMILATE_UPDATE_SCALE_METHOD

	///Frank 7/6/04		v8.0901	QA70-6583	FEATURE_OF_SIMULATE_PLOT_CURVE_SETTINGS
	void createPlotInOrigin(vector& vXData, vector& vdResult, vector &vParameters, TreeNode &trScaleSection)
	{
		WorksheetPage wp;
		wp.Create("origin.otw",CREATE_HIDDEN);
		Worksheet wks = wp.Layers(0);
		m_strCreatedGraphName = wp.GetName();
		
		string	strFunctionName;
		/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
		//m_trFunctionDetail.GetAttribute( STR_LABEL_ATTRIB, strFunctionName);
		m_trSel.GetAttribute( STR_LABEL_ATTRIB, strFunctionName);
		/// END CLEANING_CODES_IN_FO
		string strWksName = strFunctionName + " Simulation Curve";
		wp.SetLongName(strWksName);
		wp.Rename(strFunctionName + "WKS");///Frank 11/04/04 	v8.0159 QA70-6583	CREATE_WITH_TEMP_NAME_AND_SAVE_GRAPH_SETTING_OF_SIMULATE
		
		Dataset datX1, datY1;
		datX1.Attach(wks,0);
		datY1.Attach(wks,1);
		datX1	=	vXData;
		datY1	=	vdResult;
		
		//string strFOTemplatePath = GetAppPath() + "\\OriginC\OriginLab\FOTemplate.otp";
		GraphPage		grph;
		//BOOL bRet1	=	grph.Create("FDFSimulate.otp");
		BOOL bRet1	=	grph.Create(SIMULATE_GRAPH_TEMPLATE_NAME);
		
		///Frank 11/04/04 	v8.0159 QA70-6583	CREATE_WITH_TEMP_NAME_AND_SAVE_GRAPH_SETTING_OF_SIMULATE
		if(grph)
		{
			grph.SetLongName(strFunctionName + " Simulation Curve");
			grph.Rename(strFunctionName + "Graph");
		}
		else
			return ;
		///End	CREATE_WITH_TEMP_NAME_AND_SAVE_GRAPH_SETTING_OF_SIMULATE
		
		GraphLayer		lay;
		lay = grph.Layers(0);
		if(lay.AddPlot(wks, IDM_PLOT_LINE)>0)
			lay.Rescale();
		////--Frank 8/30/04 	v8.0125b QA70-6086	APPLY_SIMULATE_SETTING_TO_CREATED_GRAPH
		Axis	ya = lay.YAxis;
		if(trScaleSection)
			ya.Scale = trScaleSection;
		////--End	APPLY_SIMULATE_SETTING_TO_CREATED_GRAPH
		
		//Apply the Graph setting on the getN dialog.
		if(getGetGraphSetting(2))
		{
			vector<string>		vsParaName;
			getParametersRange(vsParaName);
			vector<string>	vsCommentParaList;
			///DG FUNCTION_PLOT_PARAMETER_LITTLE_BUG
			for(int nIndex = 0 ; nIndex <vsParaName.GetSize() ; nIndex++)
				vsCommentParaList.Add(vsParaName[nIndex]+"="+ftoa(vParameters[nIndex]));
			///end FUNCTION_PLOT_PARAMETER_LITTLE_BUG
			
			//string   strParaList = makeParaListString(vsCommentParaList, '\n');
			string   strParaList;
			strParaList.SetTokens(vsCommentParaList, '\n');
			string   strShowComment ;
			//strShowComment  = "FDF: " +  m_trFunctionDetail.GeneralInformation.FunctionPrev.strVal + "\r\nFunction: " + m_trFunctionDetail.GeneralInformation.FunctionName.strVal+ "\r\n\r\nParameters: \r\n" + strParaList;
			/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
			//strShowComment  = "Function: " + m_trFunctionDetail.GeneralInformation.FunctionName.strVal+ "\r\n\r\nParameters: \r\n" + strParaList;
			strShowComment  = "Function: " + m_trSel.GeneralInformation.FunctionName.strVal+ "\r\n\r\nParameters: \r\n" + strParaList;
			/// END CLEANING_CODES_IN_FO
			//out_str(strShowComment);
			wp.SetComments (strShowComment);
			grph.SetComments (strShowComment);
			
			//Frank 7/12/04	v8.0905	QA70-6583	FEATURE_OF_SIMULATE_PLOT_CURVE_LABEL
			string strLabelName = "GraphLabel";
			GraphObject goGTxt  ;
			goGTxt =  lay.GraphObjects(strLabelName);
			if(!goGTxt)
			{
				string strLT = "label -sa -n " + strLabelName + " %A";
				LT_execute(strLT);
				goGTxt.Text = strShowComment;
				
				strLT = "label -p 90 15";
				LT_execute(strLT);
			}
			else
			{
				goGTxt.Text = goGTxt.Text + "\n" +  strShowComment;
			}
			//End			FEATURE_OF_SIMULATE_PLOT_CURVE_LABEL
			
		}
		else
		{
			//If not need show parameters, hide the label.
			string strLabelName = "GraphLabel";
			GraphObject goGTxt  ;
			goGTxt =  lay.GraphObjects(strLabelName);
			if(goGTxt)
			{
				goGTxt.Show(false);
			}			
		}
		
		bool bShowXAxis = getGetGraphSetting(0);
		bool bShowYAxis = getGetGraphSetting(1);
		if(!bShowXAxis || !bShowYAxis)
		{
			//string strLT ;
			//strLT = lay.GetName() + ".X" + ".showAxes = 0";
			//bool bRet = LT_execute(strLT);
			//strLT = lay.GetName() + ".X" + ".showLabels=0";
			//bRet = LT_execute(strLT);
			Tree	trFormat;
			trFormat=grph.GetFormat(FPB_ALL,FOB_AXIS_TICKS);
			 ///Frank v8.0174	12/15/04			SEPARATE_GUI_AND_ACTION	
			 ///Modify function seachTreeWithID to tree_get_node_by_nodeid and move to tree_ultis.c
			//TreeNode trSection = seachTreeWithID(trFormat, 268435477,3);
			//TreeNode trGraphAxisShowSettings = seachTreeWithID(trSection, 32);
			TreeNode trSection = tree_get_node_by_nodeid(trFormat, 268435477, 3);
			TreeNode trGraphAxisShowSettings = tree_get_node_by_nodeid(trSection, 32);
			///End  	SEPARATE_GUI_AND_ACTION	
			if(!trGraphAxisShowSettings)
				return ;
			vector<int> vnIDs = { 34,35,36};
			vector<string> vStrVal(3) ;
			vStrVal[0] = 0;
			vStrVal[1] = ftoa(bShowXAxis);
			vStrVal[2] = ftoa(bShowYAxis);
			
			//treeNodeSetValuesByIds(trGraphAxisShowSettings,vnIDs,vStrVal);
			tree_set_values_by_nodeids(trGraphAxisShowSettings,vnIDs,vStrVal);
		
			grph.ApplyFormat(trFormat);
		
			//trFormat.Save("C:\Origin8.0\Themes\dd.oth");
		}
	}

	//Get Graph setting from getN dialog 
	bool getGetGraphSetting(int nRowSelect )
	{
		TreeNode trN = m_paramTree.Graph;
		if(!trN)
			return false;
		switch(nRowSelect)
		{
			case 0: return trN.ShowXAxis.nVal;
			case 1: return trN.ShowYAxis.nVal;
			case 2: return trN.ShowParameters.nVal;
			case 3: return trN.RealTime.nVal;
			default: return false;
		}
		return true;
	}
	///end 	FEATURE_OF_SIMULATE_PLOT_CURVE_SETTINGS
	//----- CPY 5/25/04 v7.5878 FO_ADD_PROFILE_DUE_TO_SLOW_LAUNCH
	//-------
	bool updateYPlottingRange(double dFrom, double dTo)
	{
		TreeNode trYScale = m_paramTree.Function.Plotting.Depen;
		if(!trYScale.IsValid())
			return false;
		string strOldVal;
		strOldVal= ftoa(trYScale.From.dVal);
		trYScale.From.SetAttribute(STR_CHANGED_ATTRIB, strOldVal);
		strOldVal = ftoa(trYScale.To.dVal);
		trYScale.To.SetAttribute(STR_CHANGED_ATTRIB, strOldVal);
		trYScale.From.dVal = dFrom;
		trYScale.To.dVal = dTo;
		return	m_treeEditCntrl.UpdateGridValues(true,false,true);
	}	
	bool 	getXRange(double &dXFrom, double &dXTo )
	{
		if(!m_trSimulate.SimulateSetting.Plotting.X)
			return false;
		dXFrom 	= m_trSimulate.SimulateSetting.Plotting.X.From.dVal;
		dXTo	=m_trSimulate.SimulateSetting.Plotting.X.To.dVal;
		return true;
	}	
	
	bool	getYRange(double &dYFrom, double &dYTo )
	{
		if(!m_trSimulate.SimulateSetting.Plotting.Y)
			return false;
		dYFrom 	= m_trSimulate.SimulateSetting.Plotting.Y.From.dVal;
		dYTo	=m_trSimulate.SimulateSetting.Plotting.Y.To.dVal;
		return true;
	}

	void setGridYRange(double &dYFromValue ,double &dYToValue )
	{
		if(!m_trSimulate.SimulateSetting.Plotting.Y)
			return ;
		m_trSimulate.SimulateSetting.Plotting.Y.From.dVal=dYFromValue;
		m_trSimulate.SimulateSetting.Plotting.Y.To.dVal =dYToValue;
	}
	bool	getParasValue( vector	&vParameters )
	{
		//string strParaName;
		if( !m_trSimulate.SimulateSetting.Parameters.IsValid())
			return false;
		vParameters.SetSize( m_trSimulate.SimulateSetting.Parameters.GetNodeCount() );
		int iIndex=0;
		foreach( TreeNode trPara in m_trSimulate.SimulateSetting.Parameters.Children )
		{
			vParameters[iIndex] = trPara.dVal;			
			iIndex++;
		};	
		return true;
	}
	
	bool getYRescaleType()
	{
		if( m_trSimulate.SimulateSetting.Plotting.Y.Type )
		{
			if(m_trSimulate.SimulateSetting.Plotting.Y.Type.nVal ==  Y_SCALE_FIXED)
				return false;
		}
		//Default to set Y scale to Y_SCALE_AUTORESCALE	
		return true;
	}
	//Frank 7/28/04	v8.0104 QA70-6729	SIMULATION_SETTING_SEPARATE_FILE
	void saveLastSimulateSettingsToXMLFile(TreeNode &trSimulate)
	{

		string strFunctionName; 
		TreeNode trNodeSimulate = trSimulate.SimulateSetting;
		//if(!isFuncTreeValid(&strFunctionName) || !trNodeSimulate)
		if(!isFuncTreeValid() || !trNodeSimulate)
			return ;
		
		strFunctionName = getFunctionName();
		
		string strFileName  = 	GetAppPath(false) + "nlsf.oss";
		
		Tree	myTree(strFileName);
		TreeNode trNode;
		if(!myTree)
		{
			//If not exist setting file, create one.
			Tree trTemp;
			trTemp = trTemp.AddNode( "SimulateSettings" );
			trNode = trTemp.AddNode(strFunctionName);
			trNode.AddNode(trNodeSimulate);
			
			trTemp.Save(strFileName);
			return ;
		}
		//If the file exist , seache the treeNode, if exist then replace; else add node
		trNode = myTree.GetNode(strFunctionName);
		if(!trNode)
			trNode = myTree.AddNode(strFunctionName);
		TreeNode trSetting = trNode.GetNode(STR_SIMULATE_NODE);
		
		if(!trSetting)
			trNode.AddNode(trNodeSimulate);
		else
			trSetting.Replace(trNodeSimulate);
		trSimulate.RemoveAttribute( STR_CHANGED_ATTRIB );
		myTree.Save(strFileName);
	}	
	
	//End	SIMULATION_SETTING_SEPARATE_FILE
	
	bool	chcekSimulateSettinInFDF()
	{
		/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
		//TreeNode	trSimulation = m_trFunctionDetail.SimulateSetting;
		TreeNode	trSimulation = m_trSel.SimulateSetting;
		/// END CLEANING_CODES_IN_FO
		if(!trSimulation)
			return false;
		TreeNode trTemp = m_trSimulate.SimulateSetting;
		if(trTemp)
			trTemp.Replace(trSimulation);
		else
			m_trSimulate.AddNode(trSimulation);
			//trTemp = trSimulation;
		return true;

	}
	//End	FEATURE_OF_SIMULATE_PLOT_CURVE_SETTINGS
	bool checkSimulationTree(TreeNode &trSimulate)
	{
		if(!trSimulate)
			return false;
		
		//m_trSimulation = m_trFunctionDetail.Simulation;
		m_bIsReadyParamList = true;
		int nParasNumber = m_NF.NP;
		vector<string> 		vsParameter;
		vsParameter.SetSize( nParasNumber );

		TreeNode trNodeSimulate = trSimulate.SimulateSetting;
		
		if(!trNodeSimulate.IsValid())
		{
			TreeNode trParameters;

			trNodeSimulate = trSimulate.AddNode(STR_SIMULATE_NODE);

			vector<string> vsDepen;
			vsDepen.SetSize(2);
			vsDepen[0] = "X";
			vsDepen[1] = "Y";
			
			trParameters = trNodeSimulate.AddNode("Parameters");
			
			TreeNode trParasRange = trNodeSimulate.AddNode("ParasRange");
			
			for(int nParaIndex = 0 ; nParaIndex <  vsParameter.GetSize( ); nParaIndex++ )
			{
				TreeNode  trNodeTemp;
				vsParameter[nParaIndex].Format("%s%d","P", nParaIndex+1 ) ;
				trNodeTemp = trParameters.AddNumericNode(35.0,vsParameter[nParaIndex], nParaIndex+1);
				trNodeTemp.SetAttribute(STR_DATAID_ATTRIB, nParaIndex + 1 );	
				
				trNodeTemp =trParasRange.AddTextNode("0|500|200",vsParameter[nParaIndex], nParaIndex + 1001);
				trNodeTemp.SetAttribute(STR_DATAID_ATTRIB, nParaIndex + 1001 );	
			}

			TreeNode		trPlotting = trNodeSimulate.AddNode("Plotting");
			TreeNode		trXAxesScale = trPlotting.AddNode(vsDepen[0]);	//Add 'X' axes scale in simulate page.
			trXAxesScale.From.dVal = -10;	
			trXAxesScale.From.SetAttribute(STR_DATAID_ATTRIB, IDE_SCALE_X_FROM );	
			trXAxesScale.To.dVal = 10;
			trXAxesScale.To.SetAttribute(STR_DATAID_ATTRIB, IDE_SCALE_X_TO );	
			
			TreeNode		trYAxesScale = trPlotting.AddNode(vsDepen[1]);	//Add 'Y' axes scale in simulate page.
			trYAxesScale.Type.nVal = Y_SCALE_AUTORESCALE;
			trYAxesScale.Type.SetAttribute(STR_DATAID_ATTRIB, IDE_SCALE_Y_SCALE_TYPE );	
			trYAxesScale.From.dVal = -10;	
			trYAxesScale.From.SetAttribute(STR_DATAID_ATTRIB, IDE_SCALE_Y_FROM );	
			trYAxesScale.To.dVal = 10;
			trYAxesScale.To.SetAttribute(STR_DATAID_ATTRIB, IDE_SCALE_Y_TO );	
			
			trPlotting.NumPts.nVal = 200;
			trPlotting.NumPts.SetAttribute(STR_DATAID_ATTRIB, IDE_SCALE_NUM_OF_POINTS );	
											
			return true;
		}
		else
		{
			TreeNode trTemp = trNodeSimulate.Parameters;
			TreeNode trTempRange = trNodeSimulate.ParasRange;
			
			int nExistNode = trTemp.GetNodeCount();
			
			string strParas ;
			
			if(nParasNumber == nExistNode)
			{
				return true;
			}
			else
				if(nParasNumber > nExistNode )
				{
					///addpara
					for(int nParaIndex = nExistNode ; nParaIndex <  nParasNumber; nParaIndex++ )
					{
						strParas.Format("%s%d","P", nParaIndex+1 ) ;
						TreeNode trNewNode = trTemp.AddNumericNode(35.0,strParas, nParaIndex+1);
						trNewNode.SetAttribute(STR_DATAID_ATTRIB, nParaIndex+1 );	
						
						trNewNode = trTempRange.AddTextNode("0|500|200",strParas, nParaIndex+1001);
						trNewNode.SetAttribute(STR_DATAID_ATTRIB, nParaIndex+1001 );	
					}
				}
				else
				{
					///del para
					for(int nParaIndex = nParasNumber ; nParaIndex <  nExistNode; nParaIndex++ )
					{
						strParas.Format("%s%d","P", nParaIndex+1 ) ;
						TreeNode trRemoveNode = trTemp.GetNode(strParas);
						trRemoveNode.Remove();
						
						trRemoveNode = trTempRange.GetNode(strParas);
						trRemoveNode.Remove();
					}
				}
		};
		
		return false;
	}
	
	bool createGraphSettingsNode()
	{
		if(!m_trSimulate)
			return false;
		
		TreeNode trGraphSettings = m_trSimulate.AddNode("GraphSettings");
		trGraphSettings.ShowXAxis.nVal = 1;
		trGraphSettings.ShowXAxis.SetAttribute(STR_DATAID_ATTRIB,IDE_GRAPH_SET_SHOWXAXIS );
		
		trGraphSettings.ShowYAxis.nVal = 1;
		trGraphSettings.ShowYAxis.SetAttribute(STR_DATAID_ATTRIB,IDE_GRAPH_SET_SHOWYAXIS );
		
		trGraphSettings.ShowParameters.nVal = 0;
		trGraphSettings.ShowParameters.SetAttribute(STR_DATAID_ATTRIB,IDE_GRAPH_SET_SHOWPARAMETERS );
		
		trGraphSettings.RealTime.nVal = 1;
		trGraphSettings.RealTime.SetAttribute(STR_DATAID_ATTRIB,IDE_GRAPH_SET_REALTIME );
		return true;
	}
	///Frank 11/04/04 	v8.0159 QA70-6583	CREATE_WITH_TEMP_NAME_AND_SAVE_GRAPH_SETTING_OF_SIMULATE
	bool loadGraphSettingsFromUserSettingFile()
	{
		//string strUserSettingPath ;
		//strUserSettingPath = GetAppPath(false) + "DefaultSettings\\" + "FOS_GS.xml";
		Tree	tr(SIMULATE_GRAPH_SETTING_PATH);
		if(!tr.GraphSettings || !m_trSimulate)
			return false;
		m_trSimulate.AddNode(tr.GraphSettings);
		return true;
	}
	bool saveGraphSettingsToUserSettingFile()
	{
		//string strUserSettingPath ;
		//strUserSettingPath = GetAppPath(false) + "DefaultSettings\\" + "FOS_GS.xml";
		
		if(!m_trSimulate.GraphSettings)
			return false;
		Tree	tr;
		tr.AddNode(m_trSimulate.GraphSettings);
		tr.Save(SIMULATE_GRAPH_SETTING_PATH);

		return true;
	}
	///End	CREATE_WITH_TEMP_NAME_AND_SAVE_GRAPH_SETTING_OF_SIMULATE
	//Frank 8/5/04 	v8.0111 			SIMULATION_PANEL_SHOW
	void	getCollapsedStates()
	{
		vector<byte>	vn;
		if(m_treeEditCntrl.GetCollapsed(vn, true)<=1)
			return;
		m_vecBCoallapedState = vn;		
	}
	//End		SIMULATION_PANEL_SHOW
	
private:
	//Grid tree for parameter list
	bool 							m_bIsReadyParamList;
	bool							m_bIsFunctGetFirstTime;
	GraphPageControl				m_graphCntl;
	DWORD							m_dwNoClicks;
	int								m_nPlotIndex;
	string 							m_strCreatedGraphName;
	//Function List
	//TreeNode						m_trFunc;		///Danice CODE_CLEAN_UP_REMOVE_DUPLICATE
	/// AW 03/17/05 v8.0206 CLEANING_CODES_IN_FO
	// need it, can reuse m_trSel in basic class
	//TreeNode						m_trFunctionDetail;
	/// END CLEANING_CODES_IN_FO
	
	vector<byte> 					m_vecBCoallapedState;
	string 							m_strCurrentFunctionFlag; 			 ///Frank v8.0174	12/15/04			SEPARATE_GUI_AND_ACTION	

	NumFunctionOrganizerEx			m_NFO;
	
	//Function simulation 
	//TreeNode						m_trSimulation;
	//string 						m_strTempSettingFolder;
	Tree							m_trSimulate;
	//Formular of  the Function tree
	NumericFunction					m_NF;
};
*/
///end REWRITE_SIMULATE

///DG 4/26/05 REWRITE_SIMULATE
enum { COL_PLOTDATA_X, COL_PLOTDATA_Y };

//
#define IDE_SIMULATION_PARAS_BEGEIN_ID				10
#define IDE_SIMULATION_PARASRANGE_BEGEIN_ID			1000

enum {
	IDE_SIMULATION_CREATE_PLOT			= 500,
	IDE_SIMULATION_UPDATE_SAMPLE		= 505,
	IDE_SIMULATION_SETTINGS				= 510,
	IDE_SIMULATION_SAVE_SETTINGS		= 515,
	IDE_SIMULATION_PARAS				= 520,
	IDE_SIMULATION_PARAS_RANGE			= 525,
	IDE_SIMULATION_PLOTTING				= 530,
	IDE_SIMULATION_PLOTTING_X			= 535,
	IDE_SIMULATION_PLOTTING_X_FROM		= 540,
	IDE_SIMULATION_PLOTTING_X_TO		= 545,
	IDE_SIMULATION_PLOTTING_Y			= 550,
	IDE_SIMULATION_PLOTTING_Y_AUTO		= 555,
	IDE_SIMULATION_PLOTTING_Y_FROM		= 560,
	IDE_SIMULATION_PLOTTING_Y_TO		= 565,
	IDE_SIMULATION_PLOTTING_NUM_PLOTS	= 570,
	
	IDE_SIMULATION_GRAPH				= 575,
	IDE_SIMULATION_GRAPH_SHOWXAXIS		= 580,
	IDE_SIMULATION_GRAPH_SHOWYAXIS		= 585,
	IDE_SIMULATION_GRAPH_SHOWPARAS		= 590,
	//IDE_SIMULATION_GRAPH_REALTIME		= 595,		//no sure if we will still use it
};

#define STR_SIMULATION_FILE		"nlsf.oss"
#define USER_SIMULATE_FILE		okutil_get_origin_path(ORIGIN_PATH_USER, THEME_SUB_FOLDER)+STR_SIMULATION_FILE
#define SYS_SIMULATE_FILE		okutil_get_origin_path(ORIGIN_PATH_SYSTEM, THEME_SUB_FOLDER)+STR_SIMULATION_FILE
#define THEME_TEMP_FILE			okutil_get_origin_path(ORIGIN_PATH_USER, "OCTemp")+"ThemeTempFile.oss";

#define STR_THEME_NODE		"Theme"

class  FOSimulateSplitter: public TreeEditSplitter
{
public:
	FOSimulateSplitter() : TreeEditSplitter(true, true)
	{
		//m_bFunctionReady = false;
	}
	~FOSimulateSplitter()
	{
		string strTempFile = THEME_TEMP_FILE;
		if(strTempFile.IsFile())
			DeleteFile(strTempFile);
	}
	///Jasmine 09/27/05 v8.0310 SPLITTER_INIT_SIZE_ON_READY
	void OnReady()
	{
		TreeEditSplitter::OnReady();
	}
	///End SPLITTER_INIT_SIZE_ON_READY
	void UpdateSimulate(TreeNode trFunction)
	{
		string strNewFileName, strOldFileName;
		strOldFileName = m_NFO.GetFuncFileName(m_trFunction, true);
		strNewFileName = m_NFO.GetFuncFileName(trFunction, true);
		bool bUpdateFunctionDetailOnly = false;
		if(strNewFileName == strOldFileName)
		{
			bUpdateFunctionDetailOnly = true;	//previous function has been show, only update curve data
			Functions.OnModifyFunction(strNewFileName, FALSE);	///DG 5/26/05 : announce function body change
		}
		getCollapsedStates();
		//before show new one, should save the settings for the last function
		//if(!bUpdateFunctionDetailOnly)	///DG FIX_LOST_PARAMETER_VALUE
			SaveSimulateSettings();
		
		if(!GetFunction(trFunction, bUpdateFunctionDetailOnly))
		{
			ConstructNoPrevTree();
			return;
		}
		OnFunctionChanged(bUpdateFunctionDetailOnly);
		applyCollasedStates();
	}
	bool SaveSimulateSettings()
	{
		if(!m_NFO.IsFunction(m_trFunction))
			return true;
		
		string strUserFile = USER_SIMULATE_FILE;
		if(!CheckMakePath(GetFilePath(strUserFile)))
			return false;
		
		Tree tr;
		if(strUserFile.IsFile())
			tr.Load(strUserFile);
		
		string strFunctionName = m_NFO.GetFunctionName(m_trFunction);
		TreeNode trDim = tree_check_get_node(tr, strFunctionName);
		
		Tree trTheme;
		trTheme = CreateThemeTree(m_trSimulate.Function);
		if(trTheme.GetNodeCount() > 0)
		{
			trDim.Replace(trTheme, true, true);
			return tr.Save(USER_SIMULATE_FILE);
		}
		return false;
	}
	void DuplicateSimulation(TreeNode trSrcFunction, TreeNode trDestFunction)
	{
		Tree trSimulate;
		if(1 < m_trSimulate.GetNodeCount())
			trSimulate = CreateThemeTree(m_trSimulate);
		else if(!searchSimulation(trSimulate, trSrcFunction))
		{
			error_report("can not find source function simulation");
			return;
		}
		
		string strUserFile = USER_SIMULATE_FILE;
		if(!CheckMakePath(GetFilePath(strUserFile)))
			return;
		
		Tree tr;
		if(strUserFile.IsFile())
			tr.Load(strUserFile);
		
		string strFunctionName = m_NFO.GetFunctionName(trDestFunction);
		TreeNode trDim = tree_check_get_node(tr, strFunctionName);
		
		trDim.Replace(trSimulate, true, true);
		tr.Save(USER_SIMULATE_FILE);
	}
protected:
EVENTS_BEGIN

	//------------- begin required events
	// the following events are required for the splitter and related controls
	ON_INIT(OnInitSplitter)
	ON_DESTROY(OnDestroy)
	ON_SIZE(OnCtrlResize)
	//------------- end required events	
	ON_GETNDLG_MSGS(GetTreeEditPaneID())
	ON_USER_MSG(WM_USER_ON_TRACK, OnTrackSlider)
	ON_USER_MSG(WM_USER_TREEEDITOR_VALUE_CHANGE, OnAfterValueChange)
	/*
	ON_GRID_DBLCLICK(GetTreeEditPaneID(), OnDblClick)
	*/
EVENTS_END

	BOOL OnInitSplitter()
	{
		CreateTreeEditPane(); // creation order dose not matter now, Tarak said
		GraphControl gctrl;
		CreateMainPane(gctrl);
		if(!gctrl)
			return error_report("Create graph pane fail, please check");
		
		//DWORD dwNoClicks = NOCLICK_DATA_PLOT | NOCLICK_TICKLABEL | NOCLICK_LAYER | NOCLICK_LAYERICON | NOCLICK_AXES;	///Jasmine 09/27/05 QA70-8114 ALLOW_CLICK_AXES
		DWORD dwNoClicks = NOCLICK_DATA_PLOT | NOCLICK_TICKLABEL | NOCLICK_LAYER | NOCLICK_LAYERICON ;
		m_graphCntl.Create(gctrl, dwNoClicks, SIMULATE_GRAPH_TEMPLATE_NAME, NULL, "FO Temp Graph", "FO Temp wks");
		
		//m_graphCntl.AddAllPlots(IDM_PLOT_LINE);	//plot Worksheet data to Graph, create a data link between them
		m_graphCntl.AddPlot(COL_PLOTDATA_X, COL_PLOTDATA_Y, IDM_PLOT_LINE);
		/*
		Window Wnd = GetParent();
		Control	ctrl = Wnd.GetDlgItem(IDC_FO_SIMULATE_BOX);
		// 1st time too early, control not properly sized, but after 1st time, user will do resizing on their own
		RECT r1;
		ctrl.GetWindowRect(&r1);
		int nHight = RECT_HEIGHT(r1);
		SetColSize(0,nHight,false); 
		*/
		return SetReady();
	}
	//Can't debug.
	BOOL OnTrackSlider(uint wParam, uint lParam)
	{
		out_str("Catch track slider change!!!");
		int nPos = wParam;
		double* pVal = (double*) lParam;
		if(pVal)
		{
			int nEditRow = m_treeEditCntrl.GetEditRow();
			TreeNode trEdit = m_treeEditCntrl.GetEditNode();
			trEdit.dVal = *pVal;
			
			updatePlotData();
		}
		else
			out_str("NULL lParam");
		
		return true;
	}
	//temp solution, as we can not receive click button event inside class
	void OnButtonClick(Control flxControl, int nRow, int nCol)
	{
		TreeNode trRow = m_treeEditCntrl.GetTreeNode(nRow);
		if(!trRow || false == trRow.Enable)
			return;
		
		int nID = trRow.DataID;
		switch(nID)
		{
		case IDE_SIMULATION_CREATE_PLOT:
			createFunctionPlot();
			break;
		case IDE_SIMULATION_UPDATE_SAMPLE:
			updateSampleCurve();
			break;
		case IDE_SIMULATION_SAVE_SETTINGS:
			saveSimulationToFDF();
			break;
		default:
			break;
		}
	}
	void OnAfterValueChange(int nRow, DWORD lParam)
	{
		if(!IsReady() || !m_treeEditCntrl.IsReady())
			return;
		
		//
		TreeNode trRow = m_treeEditCntrl.GetTreeNode(nRow);
		if(!trRow)
			return;
		
		int nID = trRow.DataID, nParentID;
		TreeNode trParent = trRow.Parent();
		if(trParent && (IDE_SIMULATION_PARAS_RANGE==(nParentID=trParent.DataID) || IDE_SIMULATION_PARAS == nParentID))
			nID = nParentID;	//parameter node id or parameter range node id
		switch(nID)
		{
		//case IDE_SIMULATION_CREATE_PLOT:
			//break;
		//case IDE_SIMULATION_UPDATE_SAMPLE:
			//break;
		//case IDE_SIMULATION_SAVE_SETTINGS:
			//break;
		case IDE_SIMULATION_PARAS_RANGE:
			updateParameterRange(trRow, nRow);
			break;
		case IDE_SIMULATION_PARAS:	//we find trackslider don't work, so use this to update change for temp
		case IDE_SIMULATION_PLOTTING_X_FROM:
		case IDE_SIMULATION_PLOTTING_X_TO:
		case IDE_SIMULATION_PLOTTING_NUM_PLOTS:
			updatePlotData();
			break;
		case IDE_SIMULATION_PLOTTING_Y_AUTO:
			onSetAutoScale(trRow, nRow);
		case IDE_SIMULATION_PLOTTING_Y_FROM:
		case IDE_SIMULATION_PLOTTING_Y_TO:
			setYScale();
			break;
		case IDE_SIMULATION_GRAPH_SHOWXAXIS:
		case IDE_SIMULATION_GRAPH_SHOWYAXIS:
		case IDE_SIMULATION_GRAPH_SHOWPARAS:
			GraphPage gp = m_graphCntl.GetPage();
			updateGraphFormat(gp);
			break;
		//case IDE_SIMULATION_GRAPH_REALTIME:
			//break;
		default:
			break;
		}
	}	
protected:
	Tree CreateThemeTree(TreeNode trSimulate)
	{
		Tree trTheme;
		string strTempFile = THEME_TEMP_FILE;
		if(theme_save_settings(trSimulate, strTempFile, true))
		{
			trTheme.Load(strTempFile);
			//save simulate settings into FDF file require complex tree structure(can't be so simple), so add a branch for it
			Tree trTemp;
			TreeNode trNode = trTemp.AddNode(STR_THEME_NODE);
			trNode.Replace(trTheme, true, true);
			trTheme = trTemp;
		}
		return trTheme;
	}
	bool LoadFromThemeTree(TreeNode trTheme)
	{
		TreeNode trSimulation = m_trSimulate.Function;
		Tree trSimulate;
		trSimulate = trTheme.GetNode(STR_THEME_NODE).Clone();
		string strTempFile = THEME_TEMP_FILE;
		if(trSimulate.Save(strTempFile) && theme_load_settings(trSimulation, strTempFile))
		{
			//we should update treenode status by current simulate settings
			updateYScaleNodeShown(1 != trSimulation.Plotting.y.Type.nVal, false);
			string strParaName;
			foreach(TreeNode trPara in getParametersNode().Children)
			{
				trPara.GetAttribute(STR_LABEL_ATTRIB, strParaName);
				TreeNode trParaRange = getParametersRangeNode().FindNodeByAttribute(STR_LABEL_ATTRIB, strParaName);
				trPara.SetAttribute(STR_COMBO_ATTRIB, trParaRange.strVal);
			}
			return true;
		}
	}
	void OnFunctionChanged(bool bUpdateFunctionDetail = false)
	{
		m_treeEditCntrl.SetReady(false);
		//show simulate tree
		m_treeEditCntrl.Update(m_trSimulate, true, true);
		m_treeEditCntrl.SetReady(true);
		
		updatePlotData();
		if(!bUpdateFunctionDetail)
		{
			GraphPage gp = m_graphCntl.GetPage();
			updateGraphFormat(gp);
		}
	}
	void ConstructNoPrevTree()
	{
		if(m_trFunction)
		{
			TreeNode junk;
			m_trFunction = junk;
			//m_trFunction.Reset();
		}
		ConstructWithoutTree();
		//empty plot
		vector vEmpty;
		m_graphCntl.SetData(vEmpty, COL_PLOTDATA_Y);
	}
	BOOL GetFunction(TreeNode &trFunction, bool bUpdateFunctionDetail = false)
	{
		if(!m_NFO.IsFunction(trFunction))
			return false;
		
		//m_trFunction.Reset();
		//m_trFunction.Replace(trFunction);
		m_trFunction = trFunction;
		
		UpdateSimulateTree(m_trFunction, bUpdateFunctionDetail);
		return true;
	}
	void UpdateSimulateTree(TreeNode trFunction, bool bUpdateFunctionDetail = false)
	{
		if(m_trSimulate.GetNodeCount() < 1)
			constructSimulateTree();
		
		constructParamtersList(trFunction, m_trSimulate);
		
		bool bIsSysFunction = m_NFO.IsSysFunction(trFunction);
		//m_trSimulate.CreateFunctionPlot.Enable = !bIsSysFunction;
		m_trSimulate.UpdateSampleCurve.Enable = !bIsSysFunction;
		m_trSimulate.Function.SaveSettingstoFDF.Enable = !bIsSysFunction;
		
		//if(!bUpdateFunctionDetail)	///DG FIX_LOST_PARAMETER_VALUE
			LoadSimulateSettings(); //1load exist settings
	}
	bool LoadSimulateSettings()
	{
		Tree trSettings;
		/*
		TreeNode trSimulationInFDF = m_trFunction.GetNode(STR_SIMULATE_NODE), trSource;
		string strUserFile = USER_SIMULATE_FILE, strSysFile = SYS_SIMULATE_FILE;
		
		string strFunctionName = m_NFO.GetFunctionName(m_trFunction);
		
		bool bFind=false;
		if(strUserFile.IsFile() && trSettings.Load(strUserFile) && (trSource=trSettings.GetNode(strFunctionName))) //load user last setting first
			bFind = true;
		else if(trSimulationInFDF) //second, check if function have simulate part
		{
			trSource = trSimulationInFDF;
			bFind = true;
		}
		else if(strSysFile.IsFile() && trSettings.Load(strSysFile) && (trSource=trSettings.GetNode(strFunctionName))) //Third, load from system settings
			bFind = true;
		if(bFind)
		{
			LoadFromThemeTree(trSource);
			return true;
		}
		*/
		if(searchSimulation(trSettings, m_trFunction))
		{
			LoadFromThemeTree(trSettings);
			return true;
		}
		return false;
	}
private:
	bool searchSimulation(Tree& trSettings, TreeNode trFunction)
	{
		TreeNode trSimulationInFDF = trFunction.GetNode(STR_SIMULATE_NODE), trSource;
		string strUserFile = USER_SIMULATE_FILE, strSysFile = SYS_SIMULATE_FILE;
		
		string strFunctionName = m_NFO.GetFunctionName(trFunction);
		
		bool bFind=false;
		if(strUserFile.IsFile() && trSettings.Load(strUserFile) && (trSource=trSettings.GetNode(strFunctionName))) //load user last setting first
			bFind = true;
		else if(trSimulationInFDF) //second, check if function have simulate part
		{
			trSource = trSimulationInFDF;
			bFind = true;
		}
		else if(strSysFile.IsFile() && trSettings.Load(strSysFile) && (trSource=trSettings.GetNode(strFunctionName))) //Third, load from system settings
			bFind = true;
		
		if(bFind)
			trSettings = trSource;
		return bFind;
	}
	TreeNode getPlottingNode()
	{
		TreeNode tr = m_trSimulate.Function.Plotting;
		return tr;
	}
	TreeNode getGraphNode()
	{
		TreeNode tr = m_trSimulate.Graph;
		return tr;
	}
	TreeNode getParametersNode()
	{
		TreeNode tr = m_trSimulate.Function.Parameters;
		return tr;
	}
	TreeNode getParametersRangeNode()
	{
		TreeNode tr = m_trSimulate.Function.ParasRange;
		return tr;
	}
	bool saveSimulationToFDF()
	{
		if(!m_trFunction)
			return error_report("Function tree is invalid, this should not happen, please check");
		
		TreeNode trSimulate = tree_check_get_node(m_trFunction, STR_SIMULATE_NODE);
		Tree trTheme;
		trTheme = CreateThemeTree(m_trSimulate.Function);
		
		trSimulate.Replace(trTheme, true, true);
		
		m_trFunction.SetAttribute( STR_CHANGED_ATTRIB, "" ); // for saving
		
		m_NFO.SaveSimulateTree(m_trFunction);
		return true;
	}
	//TreeNode getSimulateNode(TreeNode tr)
	//{
		//TreeNode trSimulate;
		//if(tr)
			//trSimulate = tr.GetNode(STR_SIMULATE_NODE);
		//return trSimulate;
	//}
	//get data from graph control, then plot it into origin
	bool createFunctionPlot()
	{
		WorksheetPage wp;
		wp.Create(SIMULATE_GRAPH_TEMPLATE_NAME, CREATE_HIDDEN);
		Worksheet wks = wp.Layers(0);
		Dataset dsX(wks, 0);
		Dataset dsY(wks, 1);
		
		vector vec;
		m_graphCntl.GetData(vec, COL_PLOTDATA_X);
		dsX = vec;
		m_graphCntl.GetData(vec, COL_PLOTDATA_Y);
		dsY = vec;
		
		GraphPage 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
		GraphLayer gl = gp.Layers(0);
		int nRet = gl.AddPlot(wks, IDM_PLOT_LINE);
		//apply graph format
		setYScale(&gl);
		updateGraphFormat(gp);
		return 0 <= nRet;
	}
	bool updateSampleCurve()
	{
		PictureHolder pictHolder;
		GraphPage	gp = m_graphCntl.GetPage();
		if(!page_get_picture(gp, pictHolder, "EMF", 72, false))
			return error_report("failed to create Curve Preview from graph");
		
		m_trFunction.Curve.pict = pictHolder;
		m_trFunction.SetAttribute(SIMULATE_CURVE_UPDATE, 1);
		
		saveSimulationToFDF();
		return true;
	}
	void applyCollasedStates()
	{
		if(m_vbRowCollapedState.GetSize() > 1)
			m_treeEditCntrl.SetCollapsed(m_vbRowCollapedState, true);
	}
	void getCollapsedStates()
	{
		vector<byte> vn;
		if(m_treeEditCntrl.GetCollapsed(vn, true)>1)
		{
			m_vbRowCollapedState.SetSize(vn.GetSize());
			m_vbRowCollapedState = vn;
		}
	}
	void updateParameterRange(TreeNode trRange, int nRow)
	{
		string strParaName;
		trRange.GetAttribute(STR_LABEL_ATTRIB, strParaName);
		TreeNode trParas = getParametersNode();
		TreeNode trPara = trParas.FindNodeByAttribute(STR_LABEL_ATTRIB, strParaName, false);
		if(!trPara)
		{
			error_report("Can find parameter node, please check");
			return;
		}
		
		bool bUpdateCurrentValue = false;
		setParameterRange(trRange, trPara, bUpdateCurrentValue);
		//update parameter
		m_treeEditCntrl.UpdateGridValues(false, true, true);
		
		if(bUpdateCurrentValue)
			updatePlotData();
	}
	bool setParameterRange(TreeNode& trRange, TreeNode& trPara, bool& bUpdateCurrentValue)
	{
		vector<string> vsRange;
		string strRange, strOldRange;
		strRange = trRange.strVal;
		
		trPara.GetAttribute(STR_COMBO_ATTRIB, strOldRange);
		if(0 == strOldRange.CompareNoCase(strRange))
			return true;
		
		if(RANGE_VALUE_TOTAL_SIZE != strRange.GetTokens(vsRange, '|'))
		{
			error_report("error in setting parameter range");
			trRange.strVal = strOldRange;
			trRange.SetAttribute(STR_CHANGED_ATTRIB, "");	//for updating GUI later
			return false;
		}
		double dMin, dMax, dStep;
		double dCurrentValue = atof(trPara.strVal);
		dMin = atof(vsRange[RANGE_VALUE_FROM]);
		dMax = atof(vsRange[RANGE_VALUE_TO]);
		dStep = atof(vsRange[RANGE_VALUE_STEPS]);
		
		if(dMin > dMax)
		{
			double dTemp = dMin;
			dMin = dMax;
			dMax = dTemp;
		}
		
		if(dCurrentValue < dMin)
		{
			trPara.strVal = dMin;
			trRange.SetAttribute(STR_CHANGED_ATTRIB, "");	//for updating GUI later
			bUpdateCurrentValue = true;
		}
		else if(dCurrentValue > dMax)
		{
			trPara.strVal = dMax;
			trRange.SetAttribute(STR_CHANGED_ATTRIB, "");	//for updating GUI later
			bUpdateCurrentValue = true;
		}
		
		trPara.SetAttribute(STR_COMBO_ATTRIB, strRange);
		trPara.SetAttribute(STR_COMBO_CHANGED, "");
		return true;
	}
	void updatePlotData()
	{
		vector vx, vy, vParas;
		double dBegin, dEnd, dNumPoints, dStep=1;
		//int nBegin, nEnd, nNumPlots, nStep=1; //default, step is 1
		
		NumericFunction NF;
		Tree tr;
		tr = m_trFunction.Clone();
		if(!NF.SetTree(tr))
		{
			error_report("Invalid function detail, please check");
			return;
		}
		TreeNode trPlotting = getPlottingNode();
		dBegin = trPlotting.x.From.dVal;
		dEnd = trPlotting.x.To.dVal;
		dNumPoints = trPlotting.NumPts.nVal;
		if(0 < dNumPoints)
		{
			dStep = abs(dEnd-dBegin)/dNumPoints;
			if(0 >= dStep)
				dStep = 1;
		}
		vx.Data(dBegin, dEnd, dStep);
		
		TreeNode trParas = getParametersNode();
		foreach(TreeNode trPara in trParas.Children)
			vParas.Add(trPara.dVal);
		
		vy = NF.Evaluate(vx, vParas);
		
		m_graphCntl.SetData(vx, COL_PLOTDATA_X);
		m_graphCntl.SetData(vy, COL_PLOTDATA_Y);
		
		setYScale();
		tr.Reset();
	}
	void onSetAutoScale(TreeNode trRow, int nRow)
	{
		bool bAutoScale = trRow.nVal;
		updateYScaleNodeShown(!bAutoScale);
		if(!bAutoScale)
		{
			double dFrom, dTo;
			m_graphCntl.GetYScaleValue(dFrom, dTo);
			TreeNode trY = getPlottingNode().y;
			trY.From.strVal = dFrom;
			trY.From.SetAttribute(STR_CHANGED_ATTRIB, "");	//for updating grid value
			trY.To.strVal = dTo;
			trY.To.SetAttribute(STR_CHANGED_ATTRIB, "");	//for updating grid value
			
			//update GUI
			m_treeEditCntrl.UpdateGridValues(false, false, true);
		}
		else
			setYScale();
	}
	void updateYScaleNodeShown(bool bShowYScaleNode, bool bUpdateShow = true)
	{
		TreeNode trY = getPlottingNode().y;
		trY.From.Show = bShowYScaleNode;
		trY.To.Show = bShowYScaleNode;
		
		if(bUpdateShow)
		{
			m_treeEditCntrl.SetReady(false);
			m_treeEditCntrl.Update(m_trSimulate, true, false);
			m_treeEditCntrl.SetReady(true);
		}
	}
	bool setYScale(GraphLayer* pLay = NULL)
	{
		double dFrom, dTo;
		getYRange(dFrom, dTo);
		
		bool bAutoRescaleY = isYAutoRescale();
		m_graphCntl.SetYAxisScale(dFrom, dTo, LINEAR_SPACE, bAutoRescaleY, pLay);
		m_graphCntl.PlotRescale();
		return true;
	}
	bool isYAutoRescale()
	{
		TreeNode trNode = getPlottingNode().y.Type;
		return true == trNode.nVal;
	}
	bool getYRange(double &dYFrom, double &dYTo )
	{
		TreeNode trY = getPlottingNode().y;
		dYFrom 	= trY.From.dVal;
		dYTo	= trY.To.dVal;
		
		if(dYFrom == NANUM)
			dYFrom = 0;
		if(dYTo == NANUM)
			dYTo = 0;
		if( is_equal( round( dYFrom, 3 ), round( dYTo, 3 ) ) )
			dYTo = dYFrom + 10;
		return true;
	}
	void updateGraphFormat(GraphPage& gp)
	{
		updateGraphAxisShow(gp);
		updateGraphText(gp);
	}
	void updateGraphAxisShow(GraphPage& gp)
	{
		TreeNode trGraph = getGraphNode();
		bool bShowXAxis, bShowYAxis, bShowParamters;
		bShowXAxis = trGraph.ShowXAxis.nVal;
		bShowYAxis = trGraph.ShowYAxis.nVal;
		
		Tree trFormat;
		trFormat=gp.GetFormat(FPB_ALL, FOB_AXIS_TICKS);
		TreeNode trSection = tree_get_node_by_nodeid(trFormat, 268435477, 3);	//...
		TreeNode trGraphAxisShowSettings = tree_get_node_by_nodeid(trSection, 32);
		if(!trGraphAxisShowSettings)
			return ;
		vector<int> vnIDs = { 35, 36 };
		vector<string> vStrVal(2) ;
		vStrVal[0] = ftoa(bShowXAxis);	//Show Axis X
		vStrVal[1] = ftoa(bShowYAxis);	//Show Axis Y
		
		tree_set_values_by_nodeids(trGraphAxisShowSettings,vnIDs,vStrVal);
		
		gp.ApplyFormat(trFormat);
	}
	void updateGraphText(GraphPage& gp)
	{
		string strLabelName = "GraphLabel";
		GraphLayer lay = gp.Layers(0);
		
		string strText, strHeader = "\\b(\\p118(Simulate:))\n";
		bool bShowParametersText = getGraphNode().ShowParameters.nVal;
		if(bShowParametersText)
		{
			vector<string> vsParasName, vsParasValue;
			int nSize = getParameters(m_trFunction, vsParasName);
			tree_get_values(getParametersNode(), vsParasValue);
			
			for(int ii=0; ii<nSize; ii++)
				vsParasName[ii] = vsParasName[ii] + "=" + vsParasValue[ii];
			
			string strFunctionName = m_NFO.GetFunctionName(m_trFunction);
			strText.SetTokens(vsParasName, '\n');
			strText = strHeader+"Function: " + strFunctionName+ "\r\n\r\nParameters: \r\n"+strText;
		}
		else
		{
			strText = strHeader;
		}
		bool bRet = page_insert_label(lay, strText, strLabelName, 82, 0);
		if(!bRet)
		{
			error_report("Set Graph label fail");
			ASSERT(0);
		}
	}
	void constructParamtersList(TreeNode trFunction, TreeNode &trSimulate)
	{
		TreeNode trParameters = getParametersNode();
		TreeNode trParasRange = getParametersRangeNode();
		trParameters.Reset(true);
		trParasRange.Reset(true);
		
		vector<string> vsParameters;
		int nSize=getParameters(trFunction, vsParameters);
		TreeNode trPara;
		for(int ii=0; ii<nSize; ii++)
		{
			trPara = trParameters.AddTextNode( "30", "P"+(string)ii, TRGP_SLIDEREDIT);
			trPara.SetAttribute(STR_LABEL_ATTRIB, vsParameters[ii]) ;
			trPara.SetAttribute(STR_COMBO_ATTRIB, "0|500|200");
			trPara.SetAttribute(STR_DATAID_ATTRIB, ii+IDE_SIMULATION_PARAS_BEGEIN_ID);
			
			trPara = trParasRange.AddTextNode("0|500|200", "P"+(string)ii, TRGP_STR);
			trPara.SetAttribute(STR_LABEL_ATTRIB, vsParameters[ii]);
			trPara.SetAttribute(STR_DATAID_ATTRIB, ii+IDE_SIMULATION_PARASRANGE_BEGEIN_ID);
		}
	}
	int getParameters(TreeNode trFunction, vector<string> &vsParams)
	{
		string strParas = trFunction.FittingParameters.Names.strVal;
		return strParas.GetTokens(vsParams, ',');
	}
	void constructSimulateTree()
	{
		GETN_TREE(trTemp)
		GETN_OPTION_GRIDLINE(flexGridFlatVert)	
		
		GETN_BUTTON(CreateFunctionPlot, "Create Function Plot", "Create") 	GETN_ID(IDE_SIMULATION_CREATE_PLOT)
		GETN_BUTTON(UpdateSampleCurve , "Update Sample Curve ", "Update") 	GETN_ID(IDE_SIMULATION_UPDATE_SAMPLE)
		
		GETN_BEGIN_BRANCH(Function, SIMULATE_SETTING )						GETN_ID_BRANCH(IDE_SIMULATION_SETTINGS)
		GETN_OPTION_BRANCH(GETNBRANCH_SAVE_SETTINGS | GETNBRANCH_KEEP_SIZE_ON_EXPAND)

			GETN_BUTTON(SaveSettingstoFDF, "Save Settings to FDF", "Save") 	GETN_ID(IDE_SIMULATION_SAVE_SETTINGS)
			
			GETN_BEGIN_BRANCH(Parameters, PARALIST_LABEL_PARAM_NAMES)		GETN_ID_BRANCH(IDE_SIMULATION_PARAS) GETN_OPTION_BRANCH(GETNBRANCH_KEEP_SIZE_ON_COLLAPSE) 
			GETN_END_BRANCH(Parameters)
			
			GETN_BEGIN_BRANCH(ParasRange, PLOT_PARAMETERS_RANGES_LABEL + "(From|To|#Steps)")	GETN_ID_BRANCH(IDE_SIMULATION_PARAS_RANGE)
			GETN_OPTION_BRANCH(GETNBRANCH_KEEP_SIZE_ON_COLLAPSE) 				
			GETN_END_BRANCH(ParasRange)
			
			GETN_BEGIN_BRANCH(Plotting, PLOTTING_GETN_LABEL)				GETN_ID_BRANCH(IDE_SIMULATION_PLOTTING)
			GETN_OPTION_BRANCH(GETNBRANCH_KEEP_SIZE_ON_EXPAND)//GETN_OPTION_BRANCH(GETNBRANCH_SAVE_SETTINGS | GETNBRANCH_KEEP_SIZE_ON_COLLAPSE)
	
				GETN_BEGIN_BRANCH(x, "X")								GETN_ID_BRANCH(IDE_SIMULATION_PLOTTING_X)
				GETN_OPTION_BRANCH(GETNBRANCH_KEEP_SIZE_ON_EXPAND) 		
					GETN_STR(From, "From", "-10")								GETN_ID(IDE_SIMULATION_PLOTTING_X_FROM)
					GETN_STR(To, 	"To",  "10")								GETN_ID(IDE_SIMULATION_PLOTTING_X_TO)
				GETN_END_BRANCH(x)

				GETN_BEGIN_BRANCH(y, "Y")								GETN_ID_BRANCH(IDE_SIMULATION_PLOTTING_Y)
				GETN_OPTION_BRANCH(GETNBRANCH_KEEP_SIZE_ON_EXPAND) 
					///Frank 10/16/05 COMMENT_NOT_USE_MARCO
	   				//GETN_OPTION_DISPLAY_FORMAT( DISPLAY_RIGHT );		
					GETN_OPTION_EDIT_ALIGN("0|1|1")
					///End COMMENT_NOT_USE_MARCO
					GETN_CHECK(Type, "Y-> Auto Scale", 1)					GETN_ID(IDE_SIMULATION_PLOTTING_Y_AUTO)	
					GETN_STR(From, "From", "-10")								GETN_ID(IDE_SIMULATION_PLOTTING_Y_FROM)
					GETN_CURRENT_SUBNODE.Show = false;
					GETN_STR(To, 	"To",  "10")								GETN_ID(IDE_SIMULATION_PLOTTING_Y_TO)		
					GETN_CURRENT_SUBNODE.Show = false;
				GETN_END_BRANCH(y)
	
				GETN_NUM(NumPts, PARALIST_LABEL_PARAM_NUM, 200)				GETN_ID(IDE_SIMULATION_PLOTTING_NUM_PLOTS)		
			GETN_END_BRANCH(Plotting)
		GETN_END_BRANCH(Function)
	
		GETN_BEGIN_BRANCH(Graph, "Graph setting")							GETN_ID_BRANCH(IDE_SIMULATION_GRAPH)
		GETN_OPTION_BRANCH(GETNBRANCH_KEEP_SIZE_ON_COLLAPSE) 
			GETN_CHECK(ShowXAxis, "Show X Axis",1)							GETN_ID(IDE_SIMULATION_GRAPH_SHOWXAXIS)
			GETN_CHECK(ShowYAxis, "Show Y Axis",1)							GETN_ID(IDE_SIMULATION_GRAPH_SHOWYAXIS)
			GETN_CHECK(ShowParameters, "Show Parameters",0)					GETN_ID(IDE_SIMULATION_GRAPH_SHOWPARAS)
			//GETN_CHECK(RealTime, "Real Time",1)								GETN_ID(IDE_SIMULATION_GRAPH_REALTIME)
		GETN_END_BRANCH(Graph)
		
		m_trSimulate = trTemp;
	}

private:
	GraphPageControl				m_graphCntl;
	NumFunctionOrganizer			m_NFO;
	
	Tree							m_trSimulate;
	TreeNode						m_trFunction;
	vector<byte> 					m_vbRowCollapedState;
};
///end REWRITE_SIMULATE
#endif //_FO_SIMULATE_SPLITTER_H_
