/*------------------------------------------------------------------------------*
 * File Name: 				 													*
 * Creation: Sim 03-20-2007														*
 * Purpose: OriginC Source C file												*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	Sim 08-21-2008 QA80-12054 CAN_NOT_DELETE_OWN_OBJECT_ON_BASE_CLASS			*
 *	Sim 08-27-2008 QA80-12076 FIX_PA_MAKE_PLOT_WITH_REPORT_DATA_RANGE			*
 *	Folger 09/02/08 STORE_PEAK_FIT_HELPER_POINTER_IN_PA_WIZ_CORE				*
 *  Sandy  2008-9-4 ADD_UTIL_FUNC_construct_tree_from_xyrange_FOR_FITTING		*
 *	Kyle 09/26/08 ADD_FUNCTION_TO_SET_AND_GET_THE_STATUS_OF_FINISH_BUTTON_CLICKED*
 *	Folger 10/15/08 NEED_TO_KNOW_IF_THERE_IS_BASELINE_IN_PEAK_FITTING			*
 *	Sim 10-13-2008 NEW_PA_81_THEME_FILTER_SETTING								*
 *	Folger 10/16/08 SAVE_PLOT_UIDS_IN_PA_CORE_TO_WORKAROUND_MISSING_PREVIEW_PLOT_IN_PA_FIT
 *	Sophy 10/17/2008 FIX_FAIL_TO_ATTACH_ANCHOR_TO_CORRECT_PEAKS_AT_FIRST_TIME_CLICK_MODIFY
 *	Sophy 10/21/2008 FIX_FAIL_TO_APPLY_THEME_FOR_DUPLICATED_NODE_DATAID_IN_THEME_WITH_BASELINE_MODE
 *	Sim 10-22-2008 FIX_RECURSIVE_DESTROY_ATTACHED_PAGE_AND_WIZ_DLG				*
 *  Iris 10/23/2008 v8.0959b SET_PA_FIT_LINE_NOT_SELECTABLE						*
 *	Folger 11/01/08 QA80-12509 v8.0964 SUPPORT_PEAK_LABEL_SWITCHING_IN_PA_FIT_CONTROL_DIALOG
 *  Iris 11/04/2008 v8.0965b PA_FIT_ADD_INPUT_REPORT_TABLE						*
 *  Iris 11/04/2008 v8.0965b SAVE_DEFAULT_FUNC_TO_THEME							*
 *  Sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE				*
 *  Iris 11/06/2008 v8.0966b IMPROVE_GET_SOURCE_GRAPH_CODES						*
 *	Sim 11-07-2008 FIX_REOPEN_PA_OPJ_FILE_TO_RECALCULATE						*
 *	Sophy 11/10/2008 CENTRALIZE_CODE_PEAK_LABEL_TYPE_FROM_NLFPREVIEW_AND_PAWIZCORE
 *	Folger 11/10/08 QA80-12509 v8.0968 ONLY_SET_PLOT_LABEL_TYPE_IN_PEAK_FIT_DIALOG_EXCLUDE_ROTATION
 *	Sophy 11/12/2008 SUPPORT_USE_EXISTING_DATARANGE_AS_BASELINE_IN_NEW_PA		*
 *	Folger 11/12/08 QA80-12488 v8.0969 PA_FITTING_AUTO_UPDATE_SUPPORT			*
 *	Kyle 11/13/2008 KEEP_TREE_DATA_ID_SAME_AS_THE_OLD_XF						*
 *	Folger 11/13/08 QA80-12488 v8.970 PA_FITTING_AUTO_UPDATE_SUPPORT_USE_VECTOR_FOR_UIDS_STORAGE
 *	Sim 11-14-2008 SUPPORT_PA_THEME_SR4_CONVERT_TO_SR5							*
 *  Iris 11/15/2008 FIX_FROM_PAFIT_XF_BACKTO_PABASETREAT_XF_SUBTRACTED_PLOT_COLOR_CHANGED*
 *  Iris 11/15/2008 FIX_INCORRECT_PA_THEME_VERSION_NUMBER						*
 *  Iris 11/15/2008 QA80-12584_P7 FIX_ALWAYS_NEW_REPORT_GRAPH_WHEN_RECALCULATE	*
 *	Folger 11/15/08 QA80-12488 v8.0972 NEED_TO_BRING_BACK_REPORT_GRAPHS_UID_FOR_AUTO_UPDATE
 *	Kyle 11/17/2008 SUBTRACTED_DATA_IS_STORED_IN_TEMPORARY_WORKSHEET			*
 *	Jasmine 11/17/08 v8.0973 CENTRALIZE_FIT_CODE_TO_SHARE_WITH_NANOSIZER		*
 *	Sim 11-17-2008 FIX_SAVE_SHARED_VALUE_ON_PA_WIZ_THEME_TREE					*
 *	Hong 11/18/08 QA80-12603 v8.0974 PA_SUPPORT_LEGEND_UPDATE_OPTION			*
 *	Jasmine 11/19/08 v8.0975b CENTRALIZE_FIT_CODE_TO_SHARE_WITH_NANOSIZER		*
 *	Sophy 11/26/2008 v8.980 PA_CHANGE_PARAMS_SHOULD_DISABLE_OUTPUT_DESTINATION_AS_OTHER_FITTING_TOOLS
 *	Folger 12/03/08 v8.0982 CHECK_CREATE_BASELINE_SHOULD_BE_MEMBER_OF_PAWIZCORE	*
 *	Folger 12/03/08 QA80-12701 v8.0982 THEME_SETTING_CONTROL_FOR_BASELINE_FUNCTION_APPLIED_IN_PA_FIT
 *	Folger 12/04/08 v8.0982b LASE_USED_FOR_PA_FIT_FAIL_TO_CREATE_NEW_REPORT_SHEETS
 *	Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK										*
 *	Sim 12-10-2008 IMPLEMENT_ASYMMETRIC_WINDOW_WIDTH							*
 *	Folger 12/11/08 QA80-12765 v8.0985 CHANGE_PARAMETER_FAILS_TO_REMEMBER_SETTINGS_FROM_LAST_CLOSE_IN_PA_FITTING
 *	Kyle 12/24/2008 ADD_COMMENTS_FOR_OUTPUT_DATA								*
 *	Folger 12/30/08 v8.0992 NANOSIZER_USING_NEW_XFWIZARD_FRAMEWORK				*
 *	Sim 01-12-2009 QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE				*
 *	Folger 01/13/09 v8.0995d PA_CREATE_BASELINE_FAILS_TO_APPLY_RANGE_SETTINGS	*
 *	Sim 01-13-2009 XFWIZ_CHANGE_PARAM_MAY_CHANGE_THEME_AND_IO_RANGE				*
 *	Sim 01-15-2009 QA80-12969 TEMP_FIX_RUN_XFWIZ_OP_ON_TEMPLATE_BOOK			*
 *	Folger 01/19/09 QA80-12969 PA_FITTING_SUPPORT_ANALYSIS_TEMPLATE				*
 *	Folger 02/04/09 QA80-12962 ADD_OPTION_IN_PA_FIT_TO_SWTICH_BACK_TO_OLD_FIT_CURVE_DATA_GENERATION_MECHANISM
 *	Folger 02/12/09 QA80-12962 PROPER_ASSIGN_ID_FOR_NEW_ADDED_NODES				*
 *	Sim 02-12-2009 FIX_SET_RANGE_AS_INPUT_INPUT_CAUSE_CREATE_OP_FAIL_AND_PA_FINISH_BROKEN
 *	Jasmine 02/19/09 QA80-13131 RECEIVE_MSG_TO_CLOSE_GRAPHDONEDLG				*
 *	Folger 02/24/09 FITWORKAREA_SHOULD_CONTAIN_BASELINE_PARAMETERS_NUMBER_INFO_INORDER_TO_CORRECTLY_APPLY
 *	Folger 02/25/09 QA80-13181 SHARE_BASELINE_FIX_STATUS_BETWEEN_BASELINE_TREATMENT_AND_FITTING
 *	Folger 05/12/09 PROPER_CHECKING_FOR_FIT_CONTROL_DATAIDS						*
 *	Folger 05/26/09 PEAK_CENTER_PLOT_FAILS_TO_SHOW_LEGEND_SYMBOL_AFTER_CALCULATE*
 *	Folger 06/08/09 QA80-12603-P1 PA_FIT_FAILS_NOT_TO_UPDATE_LEGNED_ON_SOURCE_GRAPH
 *	Sim 06-23-2009 NANOSIZER_WIZ_AUTO_UPDATE_SUPPORT							*
 *	Folger 07/01/09 THEME_SAVED_IN_SR5_FAILS_TO_BE_APPLIED_AFTER_NEW_RESULTS_NODE_ADDED_IN_PA
 *	Sim 07-16-2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6								*
 *	Folger 08/07/09 QA80-13998 SUPPORT_GET_GOAL_AND_FITTING_REPORT_GRAPH_UID_FROM_PAWIZMANAGER
 *	Folger 08/07/09 QA80-13998-P1 OUTPUT_RANGE_LT_STRING_FAILS_TO_UPDATE_WHEN_RUN_PA_WITHOUT_AUTOUPDATE
 *	Folger 09/05/09 FAILS_TO_PASTE_RESULTS_TABLE_TO_REPORT_GRAPH_DURING_CHANGE_PARAM_IN_PA
 *	Folger 09/10/09 PEAK_LABEL_PLOT_IN_PA_SHOULD_HAVE_CERTAIN_OFFSET			*
 *	Folger 09/27/09 QA80-14380 FIT_PEAK_PARAMETERS_DIALOG_FAILS_TO_BE_MODALESS_WHEN_SWITCH_TO_OTHER_PAGES
 *	Folger 10/20/09 NANOSIZER_FAILS_TO_SWITCH_LABEL_PLOT						*
 *	Folger 11/24/09 SHOULD_NOT_RESCALE_PREIVEW_AFTER_CHANGE_FUNCTION_IN_PA_FITTING
 *	Kyle 03/11/2010 PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA			*
 *------------------------------------------------------------------------------*/
 
#include <Origin.h>
#include <GetNBox.h>
////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////
// Include your own header files here.
///---Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK
/*
///---Sim 11-07-2008 FIX_REOPEN_PA_OPJ_FILE_TO_RECALCULATE
#ifdef _FOR_SMART_LOADING_ONLY
#include <..\OriginLab\XFCore.h>
#include <..\OriginLab\FitWizCoreBase.h>	
#include <..\OriginLab\XFWiz.h>

#include <..\OriginLab\XFWizard_utils.h>
#include <..\OriginLab\XFGraph_Utils.h>
#endif
///---END FIX_REOPEN_PA_OPJ_FILE_TO_RECALCULATE
*/
///---END IMPROVE_XF_WIZ_FRAMEWORK

///---Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK
/*
#include <..\OriginLab\WizOperation.h>
#include <..\OriginLab\XFWizNavigation.h>
///---Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK
//#include <..\OriginLab\XFWizDlgNavigation.h>
#include <..\OriginLab\XFWizScript.h>
#include <..\OriginLab\XFWizDlg.h>
#include <..\OriginLab\XFWizManager.h>
///---END IMPROVE_XF_WIZ_FRAMEWORK
*/
#include <o8dlg.h>
///---END IMPROVE_XF_WIZ_FRAMEWORK

#include <..\OriginLab\nlsf_utils.h>
#include <..\OriginLab\curve_utils.h>
#include <..\OriginLab\grobj_utils.h>
#include <ReportTree.h>

#include "Graph_utils.h"
#include "PFM_utils.h"	/// Iris 9/17/2008 PeakFitHelper need PLOT_TO_ enum

#include <..\OriginLab\PeakFitHelper.h>
#include <..\OriginLab\PAWizCore.h>

///---Sim 11-14-2008 SUPPORT_PA_THEME_SR4_CONVERT_TO_SR5
//#include <..\OriginLab\PAThemeConvert.h> // no need load if no version convert, it will dynamic load from someplace

/// Iris 11/15/2008 FIX_INCORRECT_PA_THEME_VERSION_NUMBER, checked old theme files, version start from 2 begin from SR2.
//#define PA_VERSION_NUMBER_SR2 1.0
//#define PA_VERSION_NUMBER_SR3 1.0
//#define PA_VERSION_NUMBER_SR4 1.0
//#define PA_VERSION_NUMBER_SR5 2.0
#define PA_VERSION_NUMBER_SR2 2.0
#define PA_VERSION_NUMBER_SR3 2.0
#define PA_VERSION_NUMBER_SR4 2.0
///---Sim 12-10-2008 IMPLEMENT_ASYMMETRIC_WINDOW_WIDTH
//#define PA_VERSION_NUMBER_SR5 3.0
///---Sim 01-15-2009 QA80-12969 TEMP_FIX_RUN_XFWIZ_OP_ON_TEMPLATE_BOOK
// XFWiz Operation Input Output structure is updated
//#define PA_VERSION_NUMBER_SR5 4.0
#define PA_VERSION_NUMBER_SR5 5.0
///---END QA80-12969 TEMP_FIX_RUN_XFWIZ_OP_ON_TEMPLATE_BOOK
///---END IMPLEMENT_ASYMMETRIC_WINDOW_WIDTH
///end FIX_INCORRECT_PA_THEME_VERSION_NUMBER
#define PA_VERSION_NUMBER_SR6 6.0 ///---Sim 07-16-2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6

///---Sim 07-16-2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6
//#define PA_VERSION_NUMBER PA_VERSION_NUMBER_SR5
#define PA_VERSION_NUMBER			PA_VERSION_NUMBER_SR6
///---END CONVERT_PA_THEME_FROM_SR5_TO_SR6
///---END SUPPORT_PA_THEME_SR4_CONVERT_TO_SR5

///---Sim 12-09-2008 IMPROVE_XF_WIZ_FRAMEWORK
#define STR_PA_CLASS_NAME "PA"   ///Sandy 2008-10-15 fix for no fly out theme
///---END IMPROVE_XF_WIZ_FRAMEWORK

#define _STR_TEMP_PA_WKS_PAGE_NAME  		"tempPA"
#define _PA_BASELINE_ANCHORS_WKS_NAME 		"tempBaseAcr1"
#define _PA_BASELINE_WKS_NAME 				"tempBaseline1"
#define _PA_SUBTRACTED_WKS_NAME 			"tempSubtracted1"
#define _PA_SUBTRACTED_OUT_WKS_NAME 		"Subtracted_Data1"
#define _PA_PEAKS_WKS_NAME 					"tempPeaks1"
#define _PA_PEAKS_CENTER_WKS_NAME 			"tempPeakCenter1"
#define _PA_PEAKS_MARKER_WKS_NAME   		"tempPeakM1"
#define _PA_LOCAL_BASELINE_WKS_NAME			"tempLocalBase1" ///Sandy 2008-9-11 add local baseline temp sheet

#define 	STR_PA_FIRST_XF 				STR_PA_XFNAME_GOAL /// Iris 11/06/2008 v8.0966b IMPROVE_GET_SOURCE_GRAPH_CODES

///Sandy add 2008-11-20 
#define  _STR_PA_2ND_DERIV_COL_NAME			"Derivative"
#define  _STR_PA_SMOOTH_2ND_DERIV_COL_NAME  "Smoothed"

enum{
	MANUAL_MODE_FOR_BASELINE_ANCHOR,
	MANUAL_PEAK_FOR_PEAKS_CENTER,
};

enum{
	PA_PEAKSINFO_SHEET_PK_XCOL = 0,
	PA_PEAKSINFO_SHEET_PK_YCOL,
	//PA_PEAKSINFO_SHEET_PK_LABELCOL, ///Sandy 2008-9-12 remove L col and replace with #12141
};

////////////////////////////////////////////////////////////////////////////////////
// Start your functions here.
//virtual
//################################## Until-functions #####################################//
/*
static int run_pa_wiz(UINT msg, TreeNode &tnWizTheme, TreeNode &tnWizIOs, DWORD dwOPUID, int nExeMode)
{
	switch ( msg )
	{
	case WIZOPH_EXECUTE:
		run_pa_nodlg(tnWizTheme, tnWizIOs, dwOPUID);
		return 0;
		
	case WIZOPH_DO_CHANGE_PARAMS_WIZDLG:
		run_pa_dlg(tnWizTheme, tnWizIOs, dwOPUID);
		return 0;
		
	}
	
	return -1;		// failed	
}


int run_pa_nodlg(TreeNode &tnWizTheme, TreeNode &tnWizIOs, DWORD dwOPUID) // = NULL, NULL, 0
{
	///---Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK
	//PAWizScript paScript;
	//if ( !paScript.Run(tnWizTheme, tnWizIOs, dwOPUID) )
		//return -1;
	//return 0;
	PAWizManager paWizManager(tnWizTheme, tnWizIOs, dwOPUID);
	XFWizScript xfwizSpt(paWizManager);
	if ( !xfwizSpt.Run() )
		return -1;
	return 0;
	///---END IMPROVE_XF_WIZ_FRAMEWORK
}

int run_pa_dlg(TreeNode &tnWizTheme, TreeNode &tnWizIOs, DWORD dwOPUID) // = NULL, NULL, 0
{
	///---Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK
	//PAWizDlg *paDlg = new PAWizDlg;
	//if ( NULL == paDlg )
		//return -1;
	//
	//if ( paDlg->Create(GetWindow(), tnWizTheme, tnWizIOs, dwOPUID) )
	//{
		//paDlg->Show(true);
	//}
	//
	//return 0;
	PAWizManager *pPAWizManager = new PAWizManager(tnWizTheme, tnWizIOs, dwOPUID);
	if ( NULL == pPAWizManager )
		return -1;
	
	XFWizDlg *pXFWizDlg = new XFWizDlg(pPAWizManager); // modeless dialog hold this pointer
	if ( NULL == pXFWizDlg )
		return -1;
	
	if ( pXFWizDlg->Create(GetWindow()) )
	{
		pXFWizDlg->Show(true);
	}
	
	return 0;
	///---END IMPROVE_XF_WIZ_FRAMEWORK
}
*/
///---END IMPROVE_XF_WIZ_FRAMEWORK
void output_baseline_if_create_baseline(XYRange& iy, XYRange oyb, PAWizCore* paCore, vector& vbx, vector& vby)
{
	int goal = paCore->GetCurrGoal();
	if(goal == PA_GOAL_CREATE_BASELINE )//if goal is create baseline, baseline should output to user assigned dataset
	{
		if(oyb)
		{
			oyb.SetData(&vby, &vbx, 0, NULL, DRS_SET_COL_DESIGNATIONS);
			_set_output_range_comments(iy, oyb);		///Kyle 12/24/2008 ADD_COMMENTS_FOR_OUTPUT_DATA
		}
	}
}

///Sandy 2008-12-30 move from pa_create
///Kyle 12/24/2008 ADD_COMMENTS_FOR_OUTPUT_DATA
static void	_set_output_range_comments(const XYRange& iy, XYRange& oy)
{
	string	strComments;
	strComments.Format("Baseline of %s", get_input_data_range_string(iy));
	oy.SetOutputComment(strComments);
}
///End ADD_COMMENTS_FOR_OUTPUT_DATA

//#ifndef _CAT_PA
//#define _CAT_PA "Peak Analyzer"
//#endif
/////Sandy 2008-12-30 return true is create baseline
////#define PA_BASELINE_STR_BUTTON_SUBTRACT ("Subtract")
////#define PA_BASELINE_STR_BUTTON_NO_SUBTRACT ("No Subtract")
//#define PA_BASELINE_STR_BUTTON_SUBTRACT _LC("Subtract", _CAT_PA)
//#define PA_BASELINE_STR_BUTTON_NO_SUBTRACT _LC("No Subtract", _CAT_PA)
void process_create_baseline_before_execute(TreeNode trGetN, DWORD dwCntrl, PAWizCore* paCore)
{
		///if goal is create baseline, the xf will the end of wizard, baseline output should come out
		int goal = paCore->GetCurrGoal();
		//string strRTvalue = STR_DEFAULT_TEXT_FOR_REPORT_DATA_NODE;
		//okutil_convert_localized_PDS(&strRTvalue);
		if(goal == PA_GOAL_CREATE_BASELINE)
		{
			//trGetN.rd_oyb.Show = true;//Sandy 2008-11-11 change to XYRange output, keep same format with subtracted data
			trGetN.oyb.Show = true;
			
			//if(!(dwCntrl & LTXF_CHANGE_PARAM) || !(dwCntrl & LTXF_EXEC_RECALCULATE))
			if(!(dwCntrl & LTXF_CHANGE_PARAM) && !(dwCntrl & LTXF_EXEC_RECALCULATE) )
			//	trGetN.rd_oyb.strVal = strRTvalue;//Sandy 2008-11-11 change to XYRange output, keep same format with subtracted data
			{
				///------ Folger 01/13/09 v8.0995d PA_CREATE_BASELINE_FAILS_TO_APPLY_RANGE_SETTINGS
				//trGetN.oyb.SetAttribute(STR_DATA_ATTRIB, STR_NEW);//trGetN.oyb.strVal = strRTvalue;
				//int	nn = okutil_getn_update_ranges(&trGetN);
				int		nCheck = 0;
				if ( trGetN.oyb.GetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, nCheck) )
				{
					trGetN.oyb.RemoveAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK);
				}
				///------ End PA_CREATE_BASELINE_FAILS_TO_APPLY_RANGE_SETTINGS
			}
			
			trGetN.btn_subtract.Show = true;//2008-8-14 Sandy add for easwar's suggestion
			
			///subtract preview button format
			TreeNode tr = trGetN.btn_subtract;
			if(tr)
			{
				tr.SetAttribute(STR_ID_ATTRIB, ONODETYPE_PUSHBUTTON_GROUP);
				tr.SetAttribute(STR_COMBO_ATTRIB, PA_BASELINE_STR_BUTTON_SUBTRACT);			
				DWORD dwDisplyBits = DISPLAY_EDITOR_HORZ;
				tr.SetAttribute(STR_ATTRIB_DISPFMT, (string)dwDisplyBits);
				trGetN.btn_subtract.nVal = 0;
			}
		}
		else
		{
			//trGetN.rd_oyb.strVal = STR_OPTIONAL;//Sandy 2008-11-11 change to XYRange output, keep same format with subtracted data
			///------ Folger 01/13/09 v8.0995d PA_CREATE_BASELINE_FAILS_TO_APPLY_RANGE_SETTINGS
			//trGetN.oyb.SetAttribute(STR_DATA_ATTRIB, STR_OPTIONAL);//trGetN.oyb.strVal = STR_OPTIONAL;
			trGetN.oyb.SetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, 0);
			///------ End PA_CREATE_BASELINE_FAILS_TO_APPLY_RANGE_SETTINGS
			//trGetN.rd_oyb.Show = false;//Sandy 2008-11-11 change to XYRange output, keep same format with subtracted data
			trGetN.oyb.Show = false;
			trGetN.btn_subtract.Show = false;
		}
}


bool	process_create_baseline_handler(TreeNode trGetN, int nEventID, LPCSTR lpcszNodeName, PAWizCore * paCore)
{
	int goal = paCore->GetCurrGoal();
	if( goal == PA_GOAL_CREATE_BASELINE && 0 == lstrcmp(lpcszNodeName, "btn_subtract") || nEventID == GETNE_ON_UNDO)
	{
		bool bUndoSubtract = ((nEventID == GETNE_ON_UNDO)? true : (bool)(trGetN.subtract.nVal));
		if(!create_subtracted_plot(paCore, bUndoSubtract))
		{
			error_report("fail to create subtracted plot");
		}
			
		if(bUndoSubtract)
		{
			trGetN.subtract.nVal = false;
			trGetN.btn_subtract.SetAttribute(STR_COMBO_ATTRIB, PA_BASELINE_STR_BUTTON_SUBTRACT);
		}
		else
		{
			trGetN.subtract.nVal = true;
			trGetN.btn_subtract.SetAttribute(STR_COMBO_ATTRIB, PA_BASELINE_STR_BUTTON_NO_SUBTRACT);
		}
		
		return true;
	}
	
	return false;
}

///Sandy 2008-11-18 should move outside later
void	remap_combo_indexes(TreeNode& trCombo, vector<int>& vnIndexes)
{
	if(!trCombo||vnIndexes.GetSize() <= 0)
	{
		error_report("Invalid TreeNode in remap_combo_list_indexes()!");
		return;
	}

	string strMapping;
	vector vIndex;
	vIndex = vnIndexes;
	vector_to_str_list(vIndex, strMapping, false, false, '|');
	trCombo.SetAttribute(STR_INTMAP_ATTRIB, strMapping);
}


int get_all_steps_from_wizard_navigation(StringArray &saXFNames, XFWizNavigation *pXFWizNavg)
{
	if(!pXFWizNavg)
		return -1;
	
	saXFNames.SetSize(0);//clean up

	int nSteps = pXFWizNavg->GetNumSteps();
	for(int ii=0; ii<nSteps; ii++)
	{
		int	nStep = pXFWizNavg->GetStep();
		saXFNames.Add( pXFWizNavg->GetXFName(ii));	
	}
	
	return saXFNames.GetSize();
}

///------ Folger 10/20/09 NANOSIZER_FAILS_TO_SWITCH_LABEL_PLOT
// bool get_plot_from_xyr_in_gl(GraphLayer gl, XYRange& xy, DataPlot& dp, int nPlotType)
// {
// 	if(!xy||!gl)
// 	{
// 		//error_report("In PAWizCore.c, get_plot_from_xyr_in_gl(), Invalid xyrange or gl!");
// 		return false;
// 	}
// 	
// 	vector<int> vnPlotIndices;	
// 	
// 	///Sandy 2008-10-9 waitting for yuri
// 	//if(0>check_has_plotted_in_graph(xy, gl, vnPlotIndices) || vnPlotIndices.GetSize() <= 0)
// 	if(0>check_has_plotted_in_graph(xy, gl, vnPlotIndices, NTYPE_BOOKSHEET_XY_RANGE) || vnPlotIndices.GetSize() <= 0)
// 	{
// 		//error_report("In PAWizCore.c, get_plot_from_xyr_in_gl(), no dataplot!");
// 		return false;
// 	}
// 	
// 	if(nPlotType == -1)
// 	{
// 		int nplot = vnPlotIndices[0];
// 		dp = gl.DataPlots(nplot);
// 		return true;
// 	}
// 	else
// 	{
// 		for(int ii = 0; ii < vnPlotIndices.GetSize(); ii++)
// 		{
// 			DataPlot dpTemp;
// 			int nplot = vnPlotIndices[ii];
// 			dpTemp = gl.DataPlots(nplot);
// 			int nType = dpTemp.GetPlotType();
// 			if(nType == nPlotType)
// 			{
// 				dp = dpTemp;
// 				return true;
// 			}
// 		}
// 	}
// 	return false;
// }
///------ End NANOSIZER_FAILS_TO_SWITCH_LABEL_PLOT

#define _STR_PA_MODIFY_ANCHORS_XF	 "pa_anchors"

///---Sim 03-11-2008 STORE_PEAK_INFO_SETTING_TO_FILE
static void _set_double_array_to_string_array(vector& vv, vector<string>& vs)
{
	vs.SetSize(vv.GetSize());
	for ( int ii = 0; ii < vv.GetSize(); ii++ )
	{
		vs[ii] = vv[ii];
	}
}
#define CHAR_DELIMITER	' '
bool store_peak_info(LPCSTR lpcszFile, bool bSave, vector& vxc, vector& vh)
{
	stdioFile ff;
	if ( bSave )
	{
		if ( !ff.Open(lpcszFile, file::modeCreate | file::modeReadWrite) )
			return false;
		
		string str;
		vector<string> vs;
		
		_set_double_array_to_string_array(vxc, vs);
		str.SetTokens(vs, CHAR_DELIMITER);
		ff.WriteString(str);
		
		_set_double_array_to_string_array(vh, vs);
		str.SetTokens(vs, CHAR_DELIMITER);
		ff.WriteString(str);
	}
	else
	{
		if ( !ff.Open(lpcszFile, file::modeRead) )
			return false;
			
		string str;
		if ( ff.ReadString(str) )
			str.GetTokens(vxc, CHAR_DELIMITER);
		
		if ( ff.ReadString(str) )
			str.GetTokens(vh, CHAR_DELIMITER);
	}
	
	ff.Close();
	return true;
}


bool anchors_to_tree(vector& vebx, vector& veby, TreeNode& tr, bool bSetToTree)
{
	TreeNode& trXs = tr.GetNode(STR_GETN_VAR_SHARED_BASE_ANCHORS_XS);
	TreeNode& trYs = tr.GetNode(STR_GETN_VAR_SHARED_BASE_ANCHORS_YS);
	if(!tr.IsValid()||!trXs.IsValid()||!trYs.IsValid())
		return false;
	
	if(bSetToTree)
	{
		trXs.dVals = vebx;
		trYs.dVals = veby;
	}
	else
	{	
		vebx = trXs.dVals;
		veby = trYs.dVals;
	}
	
	return true;
}

///Jasmine 02/19/09 QA80-13131 RECEIVE_MSG_TO_CLOSE_GRAPHDONEDLG
//bool attach_anchors_on_dataplot(DataPlot dp, int nContext)
bool attach_anchors_on_dataplot(PAWizCore * paCore, DataPlot dp, int nContext)
///End RECEIVE_MSG_TO_CLOSE_GRAPHDONEDLG
{
	if(!dp)
		return false;
	
	GraphLayer gl;
	dp.GetParent(gl);
	if(!gl)
		return false;	

	Tree trAuxInfo;
	TreeNode trContext = tree_check_get_node(trAuxInfo, PA_MODIFY_DELETE_CONTEXT_TAGNAME);
	trContext.nVal = nContext;

	///Jasmine 02/19/09 PRESS_ENTER_TO_CLOSE_GRAPHDONEDLG
	DWORD dw = (DWORD)paCore;
	
	TreeNode trCore = tree_check_get_node(trAuxInfo, PA_CORE_POINTER_TAGNAME);
	trCore.nVal = dw;					
	///End PRESS_ENTER_TO_CLOSE_GRAPHDONEDLG
	
	return dp.AttachXFunction(_STR_PA_MODIFY_ANCHORS_XF, trAuxInfo);	
}

bool resume_peaks_centers_plot_after_modify_done(PAWizCore * paCore, TreeNode& trPeaksVector, bool bUpdate/* = true*/, bool bForceDialogShow/* = true*/)
{
	ASSERT(paCore);
	vector vpx, vpy;	
	//XYRange xyPeaks;
	//if(!_get_peaks_data_from_pacore(trGetN,  vpx, vpy, xyPeaks))
		//return false;	
	XYRange xyPeaksCenter;
	paCore->GetPeaksCenterRange(xyPeaksCenter);	
	xyPeaksCenter.GetData(vpy, vpx);
		
	GraphLayer gl;
	paCore->GetPreviewLayer(gl);
	if(!gl)
		return false;
	
	GraphPage gp;
	if(!paCore->GetTargetPage(gp) || !gp.IsValid())
		return false;	
	
	if ( bUpdate )
	{
		vector<int> vnPlotIndices;
		if ( 0 < check_has_plotted_in_graph(xyPeaksCenter, gl, vnPlotIndices) )
		{
			/// Folger, 10/20/08, check_has_plotted_in_graph will return two plots here, both anchor plot and corresponding label plot.
			/// Since they have the same range string, this is the correct behavior. However, we should correctly detach xf from anchor plot,
			/// but the plot index is not always reliable, so detath xf from both of them is safe here.
			for ( int ii=0; ii<vnPlotIndices.GetSize(); ++ii )
			{
				int nplot = vnPlotIndices[ii];
				DataPlot dp = gl.DataPlots(nplot);
				dp.AttachXFunction("");
			}
		}
	}

	peaks_center_to_tree(trPeaksVector,  vpx, vpy, true);
	if ( bForceDialogShow )
		page_xf_dynadlg_shown_control(gp, 1, false);
	
	return true;
}

bool resume_anchor_plot_after_modify_done(PAWizCore * paCore,  bool bForceDialogShow/* = true*/)
{
	ASSERT(paCore);
	Page pg;
	paCore->GetTargetPage(pg);
	if(!pg)//open again after get points sucessfully
	{
		error_report("fail to get source page!");
	}
	
	if ( bForceDialogShow )//sandy add 2008-10-21
		page_xf_dynadlg_shown_control(pg, 1, false);
	
	XYRange xyAnchors;
	if(!paCore->GetBaseAnchorsRange(xyAnchors))
	{
		error_report("fail in get xyrange in PACore!");
		return false;
	}
	
	GraphLayer gl;
	paCore->GetPreviewLayer(gl);
	DataPlot dp;
	if(!get_plot_from_xyr_in_gl(gl, xyAnchors, dp) || !dp.IsValid())
	{
		error_report("fail to get anchor plot!");
		return false;
	}
	
	return dp.AttachXFunction("");
}

////void   clean_up_baseline_anchors_data(PAWizCore * paCore)
//void   clean_up_baseline_data(PAWizCore * paCore)
//{
	//ASSERT(paCore);
	//
	//vector vEmpty;
	//XYRange xyAnchors;
	//if(paCore->GetBaseAnchorsRange(xyAnchors) && xyAnchors.IsValid())
	//{
	//
		//xyAnchors.SetData(&vEmpty, &vEmpty , 0, NULL, DRS_SET_COL_DESIGNATIONS);
	//}
	//
	//XYRange xyBaseline;	
	//if(paCore->GetBaselineRange(xyBaseline) && xyBaseline.IsValid())
	//{
		//vector vEmpty;
		//xyBaseline.SetData(&vEmpty, &vEmpty , 0, NULL, DRS_SET_COL_DESIGNATIONS);
	//}
//}
//
//void  clean_up_peaks_data(PAWizCore * paCore)
//{
	//ASSERT(paCore);
	//
	//vector vEmpty;
	//XYRange xyPeaks;
	//if(paCore->GetPeaksRange(xyPeaks) && xyPeaks.IsValid())
	//{
		//xyPeaks.SetData(&vEmpty, &vEmpty , 0, NULL, DRS_SET_COL_DESIGNATIONS);
	//}
	//
	//XYRange xyPeaksCenter;	
	//if(paCore->GetPeaksCenterRange(xyPeaksCenter) && xyPeaksCenter.IsValid())
	//{
		//xyPeaksCenter.SetData(&vEmpty, &vEmpty , 0, NULL, DRS_SET_COL_DESIGNATIONS);
	//}	
	//
	//XYRange xySubtracted;
	//if(paCore->GetSubtractedRange(xySubtracted) && xySubtracted.IsValid())
	//{
		//xySubtracted.SetData(&vEmpty, &vEmpty , 0, NULL, DRS_SET_COL_DESIGNATIONS);
	//}
	//
	//XYRange xyPeaksMarker;	
	//if(paCore->GetPeaksMarkerRange(xyPeaksMarker) && xyPeaksMarker.IsValid())
	//{
		//xyPeaksMarker.SetData(&vEmpty, &vEmpty , 0, NULL, DRS_SET_COL_DESIGNATIONS);
	//}	
//}

//------ Folger 12/03/08 v8.0982 CHECK_CREATE_BASELINE_SHOULD_BE_MEMBER_OF_PAWIZCORE
/*
/// rewrite as PAWizCore::CheckCreateBaselinePlot
bool  create_baseline_plot(PAWizCore *paCore, bool bCleanData )
{
	ASSERT(paCore);
	XYRange xyBaseline;
	if(!paCore->GetBaselineRange(xyBaseline))
		return false;
	
	if(bCleanData)
	{
		vector vEmpty;
		xyBaseline.SetData(&vEmpty, &vEmpty, 0, NULL, DRS_SET_COL_DESIGNATIONS);
	}

	GraphPage gp;
	if(!paCore->GetTargetPage(gp) || !gp)
		return false;
	
	GraphLayer gl = gp.Layers(PA_INDEX_ORIGIN_LAYER);
	if(!gl)
		return false;
	
	DataPlot dp;
	if(!get_plot_from_xyr_in_gl(gl, xyBaseline, dp))
	{
		int nPlot = gl.AddPlot(xyBaseline, IDM_PLOT_LINE);
		DataPlot dp = gl.DataPlots(nPlot);
		if(!dp)
			return false;
		
		/// Iris 10/23/2008 v8.0959b SET_PA_FIT_LINE_NOT_SELECTABLE
		//dp.Info.System.Parameters.Selectable = FALSE;
		set_dataplot_selectable(dp, false);
		///end SET_PA_FIT_LINE_NOT_SELECTABLE
		dp.SetColor(1);		
	}

	return true;	
}
*/
//------ End CHECK_CREATE_BASELINE_SHOULD_BE_MEMBER_OF_PAWIZCORE


//bool	create_subtracted_plot(PAWizCore *paCore, bool bUndo)///Sandy 2009-3-6  RYAN_SUGGEST_RESCALE_SAVE_TO_THEME
bool	create_subtracted_plot(PAWizCore *paCore, bool bUndo, bool bRescale)
{
	ASSERT(paCore);
	
	XYRange xySubtracted;
	paCore->GetSubtractedRange(xySubtracted);	
	bool bHasSubtracted;
	if(bUndo)	
	{
		vector vEmpty;
		xySubtracted.SetData(&vEmpty, &vEmpty, 0, NULL, DRS_SET_COL_DESIGNATIONS);
		bHasSubtracted = false;
		paCore->SetSubtractedMode(bHasSubtracted);
	}
	else
	{
		XYRange xyOriginal, xyBaseline;
		vector vxo, vyo, vbx, vby;
		if(!paCore->GetOriginalRange(xyOriginal) || !paCore->GetBaselineRange(xyBaseline) )
			return false;
		
		bool bb = xyOriginal.GetData(vyo, vxo);
		ASSERT(bb);
		bb = xyBaseline.GetData(vby, vbx);
		ASSERT(bb);
		
		if(!subtract_baseline(vxo, vyo, vbx, vby))
			return false;
		
		xySubtracted.SetData(&vyo, &vxo, 0, NULL, DRS_SET_COL_DESIGNATIONS);
		bHasSubtracted = true;
		paCore->SetSubtractedMode(bHasSubtracted);
		
	}
	
	GraphLayer gl;
	if(!paCore->GetPreviewLayer(gl))
		return true;	
	
	if(bHasSubtracted)	
	{
		///Sandy 2009-2-3 use the type of origin plot to create the subtracted plot
		XYRange xyOriginal;
		DataPlot dpOrigin;
		
		///Sandy 2009-2-18 IMPROVEMENT_COPY_PLOT_FORMAT_TO_SUBTRACTED_AS_SNOW_COMPLAINT
		int nPlotType = IDM_PLOT_LINE;
		Tree trPlotFmt;
		
		GraphPage gpPreview = gl.GetPage();
		GraphLayer gl1 = gpPreview.Layers(PA_INDEX_ORIGIN_LAYER);
		if(!paCore->GetOriginalRange(xyOriginal) || !get_plot_from_xyr_in_gl(gl1, xyOriginal, dpOrigin))
		{
			return error_report("Invalid Original DataPlot in create_subtracted_plot");
		}
		
		///Sandy 2009-2-18 IMPROVEMENT_COPY_PLOT_FORMAT_TO_SUBTRACTED_AS_SNOW_COMPLAINT
		nPlotType = dpOrigin.GetPlotType();
		trPlotFmt = dpOrigin.GetFormat(FPB_ALL, FOB_PLOT,true, true);
		//end IMPROVEMENT_COPY_PLOT_FORMAT_TO_SUBTRACTED_AS_SNOW_COMPLAINT

		
		DataPlot dp;
		/// Iris 11/15/2008 FIX_FROM_PAFIT_XF_BACKTO_PABASETREAT_XF_SUBTRACTED_PLOT_COLOR_CHANGED, here always replot subtracted data. Default dwCntrl including GAP_ALLOW_DUPLICATE_COL bit, the following dwCntrl NOT include this bit.
		//int nPlot = gl.AddPlot(xySubtracted, IDM_PLOT_LINE);
		uint dwCntrl = GAP_GROUP_PLOTS | GAP_USE_TEMPLATE;
		//int nPlot = gl.AddPlot(xySubtracted, IDM_PLOT_LINE, dwCntrl);
		int nPlot = gl.AddPlot(xySubtracted, nPlotType, dwCntrl);///Sandy 2009-2-3 use the type of origin plot to create the subtracted plot
		///end FIX_FROM_PAFIT_XF_BACKTO_PABASETREAT_XF_SUBTRACTED_PLOT_COLOR_CHANGED
		dp = gl.DataPlots(nPlot);
		
		///Sandy 2009-2-18 IMPROVEMENT_COPY_PLOT_FORMAT_TO_SUBTRACTED_AS_SNOW_COMPLAINT
		if(dp && trPlotFmt && !trPlotFmt.IsEmpty())
		dp.ApplyFormat(trPlotFmt, true, true);
		//end IMPROVEMENT_COPY_PLOT_FORMAT_TO_SUBTRACTED_AS_SNOW_COMPLAINT

		///Sandy 2008-11-11 before rescale, should break the y-linking with the original layer
		if(dp && is_plot_requir_rescale(dp, 0))//0 means no other control, need rescale only when no overlap of dp and gl.
		{
			if(!layer_set_link(gl, PA_INDEX_ORIGIN_LAYER, 1, 0))
				error_report("Fail to break y-linking of Layers!");
			gl.Rescale(ANL_CHK_DATA_OUTSIDE); 
		}
		//end

	}
	
	///Sandy 2008-11-11 if undo, should setup the y-link again
	if(bUndo)
	{
		GraphPage gpPreview = gl.GetPage();
		GraphLayer gl2 = gpPreview.Layers(PA_INDEX_PARENT_LAYER);
		if(!gl2 || !layer_set_link(gl2, PA_INDEX_ORIGIN_LAYER, 1, 1))
			error_report("Fail to re-linking y of Layers!");		
	}
	//end
	
	///Sandy 2009-3-6  RYAN_SUGGEST_RESCALE_SAVE_TO_THEME
	if(bRescale)
	{
		gl.Rescale(); 
	}
	
	return true;
}

bool create_anchor_plot(PAWizCore *paCore, TreeNode& trBranch, bool bFromTree)
{
	ASSERT(paCore);
	
	XYRange xyBaseAnchors;
	if( !paCore->GetBaseAnchorsRange(xyBaseAnchors) )
		return false;

	
	if(bFromTree)
	{
		vector vebx,  veby;
		anchors_to_tree(vebx, veby, trBranch, false);
		
		//Sandy 2009-1-22 don't clean tree since it still useful for script mode
		//vector vempty;
		//anchors_to_tree(vempty, vempty, trBranch);
	
		xyBaseAnchors.SetData(&veby, &vebx, 0, NULL, DRS_SET_COL_DESIGNATIONS);
	}
		
	
	GraphPage gp;
	if(!paCore->GetTargetPage(gp) || !gp)
		return false;
	
	GraphLayer gl = gp.Layers(PA_INDEX_ORIGIN_LAYER);
	if(!gl)
		return true;
	
	DataPlot dp;
	if(!get_plot_from_xyr_in_gl(gl, xyBaseAnchors, dp))
	{
		 int nplot = gl.AddPlot(xyBaseAnchors, IDM_PLOT_SCATTER);
		 DataPlot dp = gl.DataPlots(nplot);
		 if(!dp)
		 {
			error_report("Invalid anchor plot  when init anchor plot!");
			return false;
		 }
		 dp.SetColor(1);		
	}
	
	return dp.IsValid();
}

bool xf_get_data_vectors_from_xyrange_treenode(TreeNode& trInput, vector& vx, vector& vy, string& strErrMsg)
{
	XYRange iy;
	if(!trInput)
	{
		if(strErrMsg != NULL)
			strErrMsg = CER_INVALID_TREENODE;
		return false;
	}
	
	if(!okxf_resolve_tree_construct_range(&trInput, &iy))
	{
		if(strErrMsg != NULL)
			strErrMsg = CER_INVALID_TREENODE;
		return false;
	}
	
	if(!iy.GetData(vy, vx))
	{
		if(strErrMsg != NULL)
			strErrMsg = XFERR_INVALID_RANGE;
		return false;
	}
	return true;	
}



bool pa_vParams2tr(vector& vParams, TreeNode& trParams, vector<string>& vsParamsName)
{
	
	int iNum = vParams.GetSize();
	
	if(!trParams ||iNum <=0)
		return false;
	
	Collection<TreeNode> trs;
	trs = trParams.Children;
	int ii = 0;
	foreach(TreeNode tr in trs)
	{
		if (ii>=iNum || ii>=trs.Count())
			break;

		tr.dVal = vParams[ii];
		
		if(vsParamsName != NULL)
			tr.SetAttribute(STR_LABEL_ATTRIB, vsParamsName[ii]);
		ii++;
	}
	
	return true;
}

bool pa_tr2vParams(TreeNode& trParams, vector& vParams, vector<string>& vsParamsName)
{
	if(!trParams)
		return false;
	
	int iNum = trParams.Children.Count();
	
	if(iNum <=0)
		return false;
	
	vParams.SetSize(iNum);
	if(vsParamsName != NULL)
		vsParamsName.SetSize(iNum);
	
	Collection<TreeNode> trs;
	trs = trParams.Children;
	int ii = 0;
	foreach(TreeNode tr in trs)
	{
		string strLabel;
		tr.GetAttribute(STR_LABEL_ATTRIB, strLabel);
		if(strLabel == "")
			break;
		else
		{
			vParams[ii] = tr.dVal;
			if(vsParamsName != NULL)
				vsParamsName[ii] = strLabel;
		}
		ii++;
	}
	vParams.SetSize(ii);
	
	return true;
}

bool peaks_center_to_tree(const TreeNode& tr, vector& vxc, vector& vh, bool bSetToTree)
{
	if(!tr.xc || !tr.h)
		return false;
	
	if(bSetToTree)
	{
		tr.xc.dVals = vxc;
		tr.h.dVals = vh;
	}
	else
	{
		vxc = tr.xc.dVals;
		vh = tr.h.dVals;
	}
	return true;
}



bool pa_make_baseline_param_tree(TreeNode& treeParams, string strFuncName, vector& vParams)
{
	int nNum = vParams.GetSize();
	vector<string> vstrParamNames;
	/// Iris 12/24/2008 v8.0990c CLEANUP_NLSF_GET_PARAM_NAMES_CODES
	//if(!nlsf_get_param_names(strFuncName, vstrParamNames, STR_PA_NLSF_CAT_BASELINE))
	if(0 == nlsf_get_param_names(strFuncName, STR_PA_NLSF_CAT_BASELINE, vstrParamNames))
	///end CLEANUP_NLSF_GET_PARAM_NAMES_CODES
	{
		error_report("PAWizCore.c: get nlsf parameters' name error!");
		return false;
	}
	ASSERT(nNum == vstrParamNames.GetSize());
	
	treeParams.SetAttribute(STR_LABEL_ATTRIB, strFuncName);//2008-9-27 Sandy
	
	for(int ii = 0; ii<nNum; ii++)
	{
		TreeNode trSubNode = treeParams.AddNumericNode(vParams[ii] , ("p"+ii));
		if(trSubNode)
			trSubNode.SetAttribute(STR_LABEL_ATTRIB, vstrParamNames[ii]);
	}
	
	return true;

}

bool get_peaks_ascending_data_from_pacore(PAWizCore* paCore, vector& vx, vector& vy, XYRange& xy)	
{
	
	ASSERT(paCore);	
	XYRange xyPeaks;
	if( !paCore->GetPeaksRange(xyPeaks) )
		return false;	

	if(!xyPeaks.GetData(vy, vx) || vx.GetSize() <= 0)
		return false;
	
	vector<uint> vnIndex;		
	vx.Sort(SORT_ASCENDING, TRUE, vnIndex);
	vy.Reorder(vnIndex);
	
	if(xy)
		xy = xyPeaks;
	return true;	
}

bool modify_peaks_centers_buttons(PAWizCore* paCore, TreeNode& trPeakVectors, TreeNode& trDisablePeakVectors, int nButtonID, bool bAttachAnchorsOnPlotOnly/* = false*/)
{
	ASSERT(paCore);

	GraphPage gp;
	if(!paCore->GetTargetPage(gp) || !gp.IsValid())
		return false;
	
	GraphLayer gl;
	paCore->GetPreviewLayer(gl);
	if(!gl)
		return false;

	vector vxi, vyi;	
	if(!get_peaks_ascending_data_from_pacore(paCore,  vxi, vyi))
		return false;
	
	XYRange xyPeaksCenter;
	paCore->GetPeaksCenterRange(xyPeaksCenter);	
	vector vxp, vyp;
	xyPeaksCenter.GetData(vyp, vxp);
	
	switch ( nButtonID )
	{				
	case STR_BTN_ADD:
		page_xf_dynadlg_shown_control(gp, 0, false); //close dlg during getting points from graph			
	
		vector vxNew, vyNew;
		graph_get_points(vxNew, vyNew, STR_GRAPH_ADD_PTS_MSG1, STR_GRAPH_ADD_PTS_MSG2, NULL, NULL, -1, CURSOR_VERTICAL_GRID_LINES);

		//snap_points_to_source_data(vxi,vyi, vxNew, vyNew);
		
		vxp.Append(vxNew);
		vyp.Append(vyNew);
		xyPeaksCenter.SetData(&vyp, &vxp,  0, NULL, DRS_SET_COL_DESIGNATIONS);
		
		peaks_center_to_tree(trPeakVectors, vxp, vyp);
		page_xf_dynadlg_shown_control(gp, 1, false); //open again after get points sucessfully
		
		
		break;
		

	case STR_BTN_MODIFY:
		page_xf_dynadlg_shown_control(gp, 0, false);//close dlg during getting points from graph
		///Sophy 10/17/2008 FIX_FAIL_TO_ATTACH_ANCHOR_TO_CORRECT_PEAKS_AT_FIRST_TIME_CLICK_MODIFY
		/*
		vector<int> vnPlotIndices;
		if ( 0 < check_has_plotted_in_graph(xyPeaksCenter, gl, vnPlotIndices) )
		{					
			int nplot = vnPlotIndices[0];
			DataPlot dp = gl.DataPlots(nplot);

			attach_anchors_on_dataplot(dp, MDC_PEAKS);
		}
		*/
		DataPlot dp;
		
		///Jasmine 02/19/09 QA80-13131 RECEIVE_MSG_TO_CLOSE_GRAPHDONEDLG
		//if(!get_plot_from_xyr_in_gl(gl, xyPeaksCenter, dp, IDM_PLOT_SCATTER)||!attach_anchors_on_dataplot(dp, MDC_PEAKS))
		if( !get_plot_from_xyr_in_gl(gl, xyPeaksCenter, dp, IDM_PLOT_SCATTER) || !attach_anchors_on_dataplot(paCore, dp, MDC_PEAKS) )
		{
			error_report("fail in attach anchors!");
		}
		///end FIX_FAIL_TO_ATTACH_ANCHOR_TO_CORRECT_PEAKS_AT_FIRST_TIME_CLICK_MODIFY
		
		if ( !bAttachAnchorsOnPlotOnly )
		{
			//graph_done_window(STR_PA_MODIFY_PEAKS, STR_PA_MOFIGY_PEAK_TITLE);
			DWORD dw;
			if( graph_done_window(dw, STR_PA_MODIFY_PEAKS, STR_PA_MOFIGY_PEAK_TITLE) )
				paCore->m_dwGetDoneDlg = dw;
		}
		///End RECEIVE_MSG_TO_CLOSE_GRAPHDONEDLG
		return true;
	
		break;
			
			
	case STR_BTN_CLEARALL:
		vector  vEmpty;
		xyPeaksCenter.SetData(&vEmpty, &vEmpty); //clean data
		peaks_center_to_tree(trPeakVectors, vEmpty, vEmpty);
		peaks_center_to_tree(trDisablePeakVectors, vEmpty, vEmpty);
		break;
		
	default:
		break;
	}
	
	
	return true;
}


bool modify_baseline_points_buttons(PAWizCore* paCore, int nButtonID)
{
	ASSERT(paCore);

	GraphPage gp;
	if(!paCore->GetTargetPage(gp) || !gp.IsValid())
		return false;
	
	GraphLayer gl;
	paCore->GetPreviewLayer(gl);
	if(!gl)
		return false;
	
	XYRange xyOrigin, xyAnchors;
	if(!paCore->GetOriginalRange(xyOrigin) || !paCore->GetBaseAnchorsRange(xyAnchors))
	{
		error_report("fail in get xyrange in PACore!");
		return false;
	}
	
	switch ( nButtonID )
	{
		case STR_BTN_ADD:
			{
				vector vxAnchors, vyAnchors;
				
				if(!xyAnchors || !xyAnchors.GetData(vyAnchors, vxAnchors))
				{
					return false;
				}
				page_xf_dynadlg_shown_control(gp, 0, false);//close dlg during getting points from graph				
				active_gl_to_add_points_and_sort(gl, vxAnchors, vyAnchors);
				//page_xf_dynadlg_shown_control(gp, 1, false);//open again after get points sucessfully
		
			    if(!xyAnchors.SetData(&vyAnchors, &vxAnchors, 0, NULL, DRS_SET_COL_DESIGNATIONS))
			    {
			    	error_report("fail in update anchors!");
			    	return false;
			    }
			}
			return resume_anchor_plot_after_modify_done(paCore);
			break;
			
			
		case STR_BTN_MODIFY:
			{
				DataPlot dp;	
				
				///Jasmine 02/19/09 QA80-13131 RECEIVE_MSG_TO_CLOSE_GRAPHDONEDLG
				//if(!get_plot_from_xyr_in_gl(gl, xyAnchors, dp)||!attach_anchors_on_dataplot(dp))
				if( !get_plot_from_xyr_in_gl(gl, xyAnchors, dp) || !attach_anchors_on_dataplot(paCore, dp) )
				{
					error_report("fail in attach anchors!");
				}
				page_xf_dynadlg_shown_control(gp, 0, false);//close dlg during getting points from graph		
				
				//graph_done_window(STR_PA_MODIFY_BASE_ANCHORS, STR_PA_MOFIGY_BASELN_TITLE);
				DWORD dw;
				if( graph_done_window(dw, STR_PA_MODIFY_BASE_ANCHORS, STR_PA_MOFIGY_BASELN_TITLE) )
					paCore->m_dwGetDoneDlg = dw;
				///End RECEIVE_MSG_TO_CLOSE_GRAPHDONEDLG
			}
			
			return true;// only "modify" need turn back to xf when finish
			break;
		case STR_BTN_CLEARALL:
			vector vEmpty;
		    if(!xyAnchors.SetData(&vEmpty, &vEmpty, 0, NULL, DRS_SET_COL_DESIGNATIONS))
		    {
		    	error_report("fail in clean-up anchors!");
		    	return false;
		    }
			break;
	default:
		break;
	}	
	
	
	return true;
}

///Sandy 2008-9-12 should not use L column as well if #12141 is ready
//static DataPlot _add_label_plot(GraphLayer& gl, Curve& curPeaks, Column& colLabel, bool bRotateLabel = false)
//{
	//if(!gl)
		//return NULL;
	//
	//int nn = gl.AddLabelPlot(curPeaks, colLabel);
	//DataPlot dpLabel = gl.DataPlots(nn);
	//int nRotate = (bRotateLabel? 90:0);
	//rotate_offset_resize_label_plot(dpLabel, nRotate, 20, 20);
	//
	//return dpLabel;
//}
///Sophy 11/10/2008 CENTRALIZE_CODE_PEAK_LABEL_TYPE_FROM_NLFPREVIEW_AND_PAWIZCORE to nlsf_utils.h
//enum{
	//LABEL_X_VAL_GUI = 0,//the label text is going to come from x dataset,
	//LABEL_Y_VAL_GUI = 1,//the label text is going to come from y dataset,
	//LABEL_ROW_NUM_GUI = 2,//the label text is going to be the row number;
//};
///end CENTRALIZE_CODE_PEAK_LABEL_TYPE_FROM_NLFPREVIEW_AND_PAWIZCORE
///Kyle 03/11/2010 PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA
/*
///------ Folger 09/10/09 PEAK_LABEL_PLOT_IN_PA_SHOULD_HAVE_CERTAIN_OFFSET
//static DataPlot _add_label_plot(GraphLayer& gl, XYRange& xy, int nLabelXYType = LABEL_Y_VAL_GUI, int nOffset = 0,  bool bRotateLabel = false)
static DataPlot _add_label_plot(GraphLayer& gl, XYRange& xy, int nLabelXYType = LABEL_Y_VAL_GUI, int nYOffset = 0,  int nXOffset = 0,  bool bRotateLabel = false)
///------ End PEAK_LABEL_PLOT_IN_PA_SHOULD_HAVE_CERTAIN_OFFSET
{
	if(!gl)
		return NULL;
	
	int nplot = gl.AddPlot(xy, IDM_PLOT_TEXT);//IDM_PLOT_SCATTER);
	DataPlot dp = gl.DataPlots(nplot);
	if(!dp)
		return NULL;
	
	//------ Folger 11/10/08 QA80-12509 v8.0968 ONLY_SET_PLOT_LABEL_TYPE_IN_PEAK_FIT_DIALOG_EXCLUDE_ROTATION
	//dp.LabTalk("tts", &nLabelXYType, true);
	dp.LabTalk(STR_PLOT_DATA_LABEL_TYPE, &nLabelXYType, true);
	//------

	///Sandy waitting for 12141 to use Y value

	int nRotate = (bRotateLabel? 90:0);
	///------ Folger 09/10/09 PEAK_LABEL_PLOT_IN_PA_SHOULD_HAVE_CERTAIN_OFFSET
	//if(!rotate_offset_resize_label_plot(dp, nRotate ,  nOffset))
	if(!rotate_offset_resize_label_plot(dp, nRotate, nYOffset, nXOffset))
	///------ End PEAK_LABEL_PLOT_IN_PA_SHOULD_HAVE_CERTAIN_OFFSET
		error_report("Fail to modify format of plot");

	return dp;

}
*/
///End PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA

bool  clear_peaks_labels_plot(PAWizCore* paCore)
{
	ASSERT(paCore);
	
	GraphLayer gl;
	if(!paCore->GetPreviewLayer(gl))
		return false;

	XYRange xyPeaksCenter;
	if( !paCore->GetPeaksCenterRange(xyPeaksCenter) )
		return false;	
		
	if(xyPeaksCenter)
	{
		vector vEmpty;
		xyPeaksCenter.SetData(&vEmpty, &vEmpty, 0, NULL, DRS_SET_COL_DESIGNATIONS);
	}
	return true;
}

//bool create_peaks_labels_plot(PAWizCore* paCore, int nLabelXYType, bool bShowLabel,  bool bRotateLabel, bool bShowCenter)
//{
	//ASSERT(paCore);
	//
	//GraphLayer gl;
	//if(!paCore->GetPreviewLayer(gl))
		//return false;
//
	//XYRange xyPeaksCenter;
	//if( !paCore->GetPeaksCenterRange(xyPeaksCenter) )
		//return false;
	//
	////create peak plot
	//if( bShowCenter )
	//{
		//DataPlot dp;
		//
		/////Sandy 2008-9-12 after the change of #12141, peak centers should be plotted twice, but marker("|") plot be detected
		////if(!get_plot_from_xyr_in_gl(gl, xyPeaksCenter, dp))
		//if(!get_plot_from_xyr_in_gl(gl, xyPeaksCenter, dp, IDM_PLOT_LINE))
		//{
			//if(!plot_peak_center_to_graph(xyPeaksCenter,gl))
				//return false;
		//}
	//}
	//
	//// create label plot
	////Worksheet wks = paCore->CheckGetInterimResult(_PA_PEAKS_CENTER_WKS_NAME);
	////
	////if(!_update_peaks_center_label_data(gl, wks, nLabelXYType, bRotateLabel, bShowLabel))
		////return false;
	//if(bShowLabel)
	//{
		//DataPlot dp;
		//if(!get_plot_from_xyr_in_gl(gl, xyPeaksCenter, dp, IDM_PLOT_TEXT) )
		//{
			//dp = _add_label_plot(gl, xyPeaksCenter, nLabelXYType, 0,  bRotateLabel);
			//if(!dp)
				//error_report("fail to add label plot!");
		//}
	//}
//
	//return true;
//}

//static bool _update_peaks_center_label_data(GraphLayer& gl, Worksheet& wks,  int nLabelXYType, bool bRotateLabel, bool bShowLabel)
//{
	//if(!wks ||!gl)
	//{
		//error_report("Invalid worksheet or graphlayer in update_peaks_center_label_data()");
		//return false;
	//}
	//
	//Dataset  dsX(wks, PA_PEAKSINFO_SHEET_PK_XCOL), dsY(wks, PA_PEAKSINFO_SHEET_PK_YCOL);
	//Dataset  dsLabel(wks, PA_PEAKSINFO_SHEET_PK_LABELCOL);
	//
	//dsLabel.SetSize(0);
	//if(!dsX || !dsY || !dsLabel)
	//{
		//error_report("Invalid dataset in update_peaks_center_label_data()");
		//return false;
	//}
	//if(bShowLabel)
	//{
		//switch(nLabelXYType)
		//{
		//case 0://show x of peak as label
			//dsLabel = dsX;
			//break;
		//case 1://show y of peak as label
			//dsLabel = dsY;	
			//break;
		//default://doing nothing
			//error_report("Invalid nLabelXYType in update_peaks_center_label_data()");
			//break;
		//};
		//
	//
		//if( dsLabel.GetSize()>0)
		//{
			//Curve curPeaks(wks, PA_PEAKSINFO_SHEET_PK_YCOL);
			//if ( curPeaks )//&& curPeaks.GetSize() > 0
			//{
				//Column colLabel(wks, PA_PEAKSINFO_SHEET_PK_LABELCOL);
				//if ( colLabel )
				//{
					//DataPlot dpLabel = _add_label_plot(gl, curPeaks, colLabel, bRotateLabel);
				//}
			//}
		//}
		
	//}
	//return true;
//}
//

///-------Sandy 2008-12-12 include to pawizcore memeber function
/*
bool update_peaks_center_label(PAWizCore* paCore, bool bShowCenter,  bool bShowLabel, int nLabelXYType, bool bRotateLabel )
{
	ASSERT(paCore);
	//Worksheet wks = paCore->CheckGetInterimResult(_PA_PEAKS_CENTER_WKS_NAME);	
	//if(!wks)
		//return false;
	
	GraphLayer gl;
	if(!paCore->GetPreviewLayer(gl) || !gl)
		return false;
	
	XYRange xyPeaksCenter;
	if(!paCore->GetPeaksCenterRange(xyPeaksCenter))
	{
		return false;
	}
	

	//return _update_peaks_center_label_data(gl, wks, nLabelXYType, bRotateLabel, bShowLabel);
	//_update_peaks_center_label( bool bShowCenter,  bool bShowLabel, int nLabelXYType, bool bRotateLabel)
	DataPlot dp;
	if(get_plot_from_xyr_in_gl(gl, xyPeaksCenter, dp, IDM_PLOT_TEXT))
	{
		dp.Destroy();
	}
	if(bShowLabel)
	{
		dp = _add_label_plot(gl, xyPeaksCenter, nLabelXYType, 0,  bRotateLabel);
		if(!dp)
			error_report("fail to add label plot!");
	}
	
	//create peak plot
	if( bShowCenter )
	{
		DataPlot dp;
		
		///Sandy 2008-9-12 after the change of #12141, peak centers should be plotted twice, but marker("|") plot be detected
		//if(!get_plot_from_xyr_in_gl(gl, xyPeaksCenter, dp))
		if(!get_plot_from_xyr_in_gl(gl, xyPeaksCenter, dp, IDM_PLOT_LINE))
		{
			if(!plot_peak_center_to_graph(xyPeaksCenter,gl))
				return false;
		}
	}	
	
	return true;
}
*/

///Kyle 03/11/2010 PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA, moved to curve_utils.* and renamed to update_peaks_labels
/*
static bool   _update_peaks_labels(GraphLayer gl, XYRange xyPeaksCenter,  bool bShowCenter, bool bShowLabel, int nLabelXYType, bool bRotateLabel)
{
	if(!gl||!xyPeaksCenter)
		return false;
	
	DataPlot dp;
	if(get_plot_from_xyr_in_gl(gl, xyPeaksCenter, dp, IDM_PLOT_TEXT))
	{
		dp.Destroy();
	}
	if(bShowLabel)
	{
		///------ Folger 09/10/09 PEAK_LABEL_PLOT_IN_PA_SHOULD_HAVE_CERTAIN_OFFSET
		//dp = _add_label_plot(gl, xyPeaksCenter, nLabelXYType, 0,  bRotateLabel);
		dp = _add_label_plot(gl, xyPeaksCenter, nLabelXYType, 20,  30, bRotateLabel);
		///------ End PEAK_LABEL_PLOT_IN_PA_SHOULD_HAVE_CERTAIN_OFFSET
		if(!dp)
			error_report("fail to add label plot!");
	}
	
	//create peak plot
	if(bShowCenter )
	{
		DataPlot dp;
		
		///Sandy 2008-9-12 after the change of #12141, peak centers should be plotted twice, but marker("|") plot be detected
		//if(!get_plot_from_xyr_in_gl(gl, xyPeaksCenter, dp))
		if(!get_plot_from_xyr_in_gl(gl, xyPeaksCenter, dp, IDM_PLOT_LINE))
		{
			if(!plot_peak_center_to_graph(xyPeaksCenter,gl))
				return false;
		}
	}
	
	return true;
}
*/
///End PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA
bool pa_keep_dataplot_style_during_wiz(DataPlot& dp, TreeNode& trPlot)
{
	if(!dp || !trPlot)
		return false;
	
	Tree trFmt;
	trFmt = dp.GetFormat(FPB_ALL, FOB_PLOT,true, true);
	trPlot.Replace(trFmt, true, true, true); 
	
	trPlot.AddNumericNode(dp.GetPlotType(), "type");
	
	return true;

}
bool pa_create_dataplot_with_style_during_wiz(XYRange& xy, GraphLayer& gl, DataPlot& dp, TreeNode& trFormat, bool bRemoveAllExisted)
{
	if(!xy || !gl)
		return false;
	
	if(bRemoveAllExisted) // Sandy should be seen in the interface
	{
		//---Jasmine 03/04/08
		//not sure the exsiting plots have the same style, so destroy all and add new one
		vector<int> vnPlotIndex; 
		if(0 < check_has_plotted_in_graph(xy, gl, vnPlotIndex))
		{
			vnPlotIndex.Sort();
			for(int ii = vnPlotIndex.GetSize() - 1; ii >= 0; ii--)
			{
				int nPlotIndex = vnPlotIndex[ii];
				DataPlot dpExist = gl.DataPlots(nPlotIndex);
				dpExist.Destroy();
			}
		}
		//---end
	}
	
	int nPlotID = IDM_PLOT_SCATTER;
	if(trFormat && trFormat.type)
		nPlotID = trFormat.type.nVal;

	int ndp = gl.AddPlot(xy, nPlotID);
	dp = gl.DataPlots(ndp);
	
	if(dp && trFormat && !trFormat.IsEmpty())
		dp.ApplyFormat(trFormat, true, true);
	
	return dp.IsValid();
}
int get_find_peaks_xf_error_code(int nOCMathErr)
{
	switch (nOCMathErr)
	{
	case OE_BAD_PARAM:
		return XFERR_BAD_PARAM_FOR_FIND_PEAKS;
	case OE_NO_PEAK_FOUND:
		return XFERR_NO_PEAK_FOUND;
	case OE_TPS_INVALID_SMOOTH:
		return CER_TPS_INVALID_SMOOTH;
	}
	
	return XFERR_FINDPEAKS_FUNCTION_UNKNOWN_ERR;
}

///Kyle 03/11/2010 PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA
/*
static bool plot_xyr_to_graph(XYRange& xy,  GraphLayer gl, int nPlotType = IDM_PLOT_LINE, int nColor = SYSCOLOR_BLACK, DataPlot& dpXY = NULL)
{
	if(!xy.IsValid() || !gl.IsValid())
		return false;
	
	if(xy.IsValid())
	{
		DataPlot dp;
		//if(!get_plot_from_xyr_in_gl(gl, xy, dp))
		if(!get_plot_from_xyr_in_gl(gl, xy, dp, nPlotType))
		{
			 int nplot = gl.AddPlot(xy, nPlotType);//, GAP_USE_WKS_DESIGNATION);
			 dp = gl.DataPlots(nplot);
			 if(!dp)
			 {
				error_report("get plot from xyr fail in putResultToOriginalGraph()");
			 }
			 else
			 {
				dp.SetColor(nColor);
				int nplot = dp.GetIndex();
				legend_append_plot(gl, nplot);	
			 }
		}
		
		if(dpXY != NULL)
			dpXY = dp;
	}	
	
	return true;
}
*/
///End PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA
#define BASELINE_TABLE_ID 100
#define PEAK_CENTER_TABLE_ID 200
#define PEAK_MARKER_TABLE_ID 300

///Sandy 2009-2-24 RENAME_LEGEND_AND_COMMENT_FROM_PETER_DEMO_SUGGESTION
//#define STR_TABLE_RANGE_BASELINE _L("Baseline")
//#define STR_TABLE_RANGE_PEAK_CENTER _L("Peak Center")
//#define STR_TABLE_RANGE_PEAK_MARKER _L("Peak Marker")
/////Kyle 12/24/2008 ADD_COMMENTS_FOR_OUTPUT_DATA
//#define STR_TABLE_RANGE_PEAK_CENTER_EX _L("Peak Center of %s")
//#define STR_TABLE_RANGE_BASELINE_EX _L("Baseline of %s")
//#define STR_TABLE_RANGE_PEAK_MARKER_EX _L("Peak Marker of %s")

#define STR_TABLE_RANGE_BASELINE _L("Baseline")
#define STR_TABLE_RANGE_PEAK_CENTER _L("Peak Centers")
#define STR_TABLE_RANGE_PEAK_MARKER _L("Base Markers")
#define STR_TABLE_RANGE_PEAK_CENTER_EX _L("Peak Centers of %s")
#define STR_TABLE_RANGE_BASELINE_EX _L("Baseline of %s")
#define STR_TABLE_RANGE_PEAK_MARKER_EX _L("Base Markers of %s")
//end RENAME_LEGEND_AND_COMMENT_FROM_PETER_DEMO_SUGGESTION

///Sandy 2009-2-17 USE_SHORT_NAME_AS_INDICATE
#define STR_SHORTNAME_BASELINE_X 	("bx")
#define STR_SHORTNAME_BASELINE_Y 	("by")
#define STR_SHORTNAME_PEAK_CENTER_X ("pcx")
#define STR_SHORTNAME_PEAK_CENTER_Y ("pcy")
#define STR_SHORTNAME_PEAK_MARKER_X ("pmx")
#define STR_SHORTNAME_PEAK_MARKER_Y ("pmy")
///end USE_SHORT_NAME_AS_INDICATE

static bool temp_convert_peak_info_dr_to_xyrs(DataRange& dr, XYRange& xyCenter, XYRange& xyMarker, XYRange& xyBaseline)
{
	if(!dr.IsValid())
		return false;
	
	int nNumData = dr.GetNumData();
	
	for(int ii = 1; ii<nNumData; ii++)
	{
		Worksheet wks;
		int c1, c2;
		if(!dr.GetRange(wks, c1, c2, ii))
			return false;
		
		Column colX(wks, c1);
		Column colY(wks, c2);
		//string strCommentX = colX.GetComments();
		//string strCommentY = colY.GetComments();
		string strXCol = colX.GetName();///Sandy 2009-2-17 USE_SHORT_NAME_AS_INDICATE
		string strYCol = colY.GetName();
		
		///Sandy 2009-2-17 USE_SHORT_NAME_AS_INDICATE
		//if(strCommentX.CompareNoCase(strCommentY)==0 && strCommentX.Match(STR_TABLE_RANGE_BASELINE+"*"))
		if(strXCol.CompareNoCase(STR_SHORTNAME_BASELINE_X)==0 && strYCol.CompareNoCase(STR_SHORTNAME_BASELINE_Y)==0)
		{
			xyBaseline.Add(wks, c1, "X");
			xyBaseline.Add(wks, c2, "Y"); 			
		}
		
		///Sandy 2009-2-17 USE_SHORT_NAME_AS_INDICATE
		//if(strCommentX.CompareNoCase(strCommentY)==0 && strCommentX.Match(STR_TABLE_RANGE_PEAK_CENTER+"*"))
		if(strXCol.CompareNoCase(STR_SHORTNAME_PEAK_CENTER_X)==0 && strYCol.CompareNoCase(STR_SHORTNAME_PEAK_CENTER_Y)==0)
		{
			xyCenter.Add(wks, c1, "X");
			xyCenter.Add(wks, c2, "Y"); 			
		}
		
		///Sandy 2009-2-17 USE_SHORT_NAME_AS_INDICATE
		//if(strCommentX.CompareNoCase(strCommentY)==0 && strCommentX.Match(STR_TABLE_RANGE_PEAK_MARKER+"*"))
		if(strXCol.CompareNoCase(STR_SHORTNAME_PEAK_MARKER_X)==0 && strYCol.CompareNoCase(STR_SHORTNAME_PEAK_MARKER_Y)==0)
		{
			xyMarker.Add(wks, c1, "X");
			xyMarker.Add(wks, c2, "Y"); 			
		}
	}
	
	return true;
}

static bool temp_convert_simple_dr_to_xyr(DataRange& dr, XYRange& xy)
{

	if(!dr.IsValid())
		return false;
	
	Worksheet wks;
	int c1, c2;

	int nIndex = 1;
	//if(!dr.GetRange(wks, c1, c1, 0))
		//return false;
	
	if(!dr.GetRange(wks, c1, c2, nIndex))
		return false;

	xy.Add(wks, c1, "X");
	xy.Add(wks, c2, "Y");
	
	return xy.IsValid();

}

///Kyle 03/11/2010 PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA
/*
static bool plot_peak_center_to_graph(XYRange& yp, GraphLayer& gl )
{
	if( !yp.IsValid() || !gl.IsValid() )
		return false;
	
	DataPlot dpCenter;
	if(!plot_xyr_to_graph(yp,   gl, IDM_PLOT_SCATTER, SYSCOLOR_RED, dpCenter))
		return false;
	
	 if(!dpCenter)
	 {
		error_report("Invalid peak-center plot  when init peak-center plot!");
		return false;
	 }

	if(dpCenter.IsValid())
		set_dataplot_format(dpCenter, 16, 15);	//red color, hard code	
	
	return true;
}
*/
///End PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA

bool	create_baseline_table(PAWizCore* paCore, ReportData& rd_oyb)
{
	if(!paCore || !rd_oyb)
		return false;
	
	vector vbx, vby;
	XYRange xyBaseline;
	
	///Sandy 2008-9-16 add local baseline table
	if(PA_BM_LOCAL == paCore->GetBaseMode())
	{
		int ii, nn;
		do
		{
			XYRange xyTemp;
			vector vxTemp, vyTemp;
			if(!paCore->GetLocalBaselineRange(xyTemp, ++ii, nn))
			{
				error_report("get local baseline fail!");
			}
			xyTemp.GetData(vyTemp, vxTemp);
			vbx.Append(vxTemp);
			vby.Append(vyTemp);
		}
		while(ii<nn);
	}
	else if(PA_BM_None != paCore->GetBaseMode())
	{
		if(!paCore->GetBaselineRange(xyBaseline))
		{
			return false;
		}		
		xyBaseline.GetData(vby, vbx);
	}
	else
		return false;


	int nID = BASELINE_TABLE_ID; 
	//int nTableFormat = GETNBRANCH_OPEN | GETNBRANCH_HIDE_COL_HEADINGS| GETNBRANCH_HIDE_ROW_HEADINGS | GETNBRANCH_FIT_COL_WIDTH | GETNBRANCH_FIT_ROW_HEIGHT;
	//
	//rd_oyb.ID = nID++; 
	//rd_oyb.SetAttribute(STR_LABEL_ATTRIB, "Baseline"); //Table title
	//rd_oyb.SetAttribute(TREE_Table, nTableFormat);

	ReportTable rt;
	///Kyle 12/24/2008 ADD_COMMENTS_FOR_OUTPUT_DATA
	//rt = rd_oyb.CreateTable("baseline", STR_TABLE_RANGE_BASELINE, nID++);
	string strComments;
	XYRange xyOriginal;
	if(paCore->GetOriginalRange(xyOriginal))
		strComments.Format(STR_TABLE_RANGE_BASELINE_EX, get_input_data_range_string(xyOriginal));
	else
		strComments = STR_TABLE_RANGE_BASELINE;
	rt = rd_oyb.CreateTable("baseline", strComments, nID++);
	///End ADD_COMMENTS_FOR_OUTPUT_DATA
	rt.AddColumn(vbx, STR_SHORTNAME_BASELINE_X, nID++, "X", OKDATAOBJ_DESIGNATION_X);///Sandy 2009-2-17 USE_SHORT_NAME_AS_INDICATE
	rt.AddColumn(vby, STR_SHORTNAME_BASELINE_Y, nID++, "Y", OKDATAOBJ_DESIGNATION_Y);///Sandy 2009-2-17 USE_SHORT_NAME_AS_INDICATE	
	
	return true;
}

bool create_peak_center_table( PAWizCore* paCore, ReportData& rd_peakcenter)
{
	if(!paCore || !rd_peakcenter)
		return false;
	
	XYRange xyOriginal, xyPeaksCenter;
	if(!paCore->GetOriginalRange(xyOriginal) || !paCore->GetPeaksCenterRange(xyPeaksCenter))
	{
		return false;
	}	

	vector vpx, vpy;
	xyPeaksCenter.GetData(vpy, vpx);
	
	//Sandy 2008-9-1 As Max said, we should output the original peaks position in the source data
	vector vpox, vpoy, vxi, vyi;
	xyOriginal.GetData(vyi, vxi);
	vpox = vpx;
	vpoy.SetSize(vpox.GetSize());
	if(OE_NOERROR !=ocmath_interpolate(vpox, vpoy, vpox.GetSize(), vxi, vyi, vxi.GetSize(), INTERP_TYPE_LINEAR))
		return false;
	//end
	
	
	int nID = PEAK_CENTER_TABLE_ID; 
	ReportTable rt;
	///Kyle 12/24/2008 ADD_COMMENTS_FOR_OUTPUT_DATA
	//rt = rd_peakcenter.CreateTable("peakcenters", STR_TABLE_RANGE_PEAK_CENTER, nID++);
	string strComments;
	strComments.Format(STR_TABLE_RANGE_PEAK_CENTER_EX, get_input_data_range_string(xyOriginal));
	rt = rd_peakcenter.CreateTable("peakcenters", strComments, nID++);
	///End ADD_COMMENTS_FOR_OUTPUT_DATA
	rt.AddColumn(vpox, STR_SHORTNAME_PEAK_CENTER_X, nID++, "X", OKDATAOBJ_DESIGNATION_X);///Sandy 2009-2-17 USE_SHORT_NAME_AS_INDICATE
	rt.AddColumn(vpoy, STR_SHORTNAME_PEAK_CENTER_Y, nID++, "Y", OKDATAOBJ_DESIGNATION_Y);///Sandy 2009-2-17 USE_SHORT_NAME_AS_INDICATE
	
	return true;
}

bool    	create_peak_marker_table(PAWizCore* paCore, ReportData& rd_peakmarker)
{
	if(!paCore || !rd_peakmarker)
		return false;
	
	XYRange xyOriginal, xyPeaksMarker;
	if(!paCore->GetOriginalRange(xyOriginal) || !paCore->GetPeaksMarkerRange(xyPeaksMarker))
	{
		return false;
	}	

	vector vpx, vpy;
	xyPeaksMarker.GetData(vpy, vpx);
	
	int nID = PEAK_MARKER_TABLE_ID; 
	ReportTable rt;
	///Kyle 12/24/2008 ADD_COMMENTS_FOR_OUTPUT_DATA
	//rt = rd_peakmarker.CreateTable("peakmarkers", STR_TABLE_RANGE_PEAK_MARKER, nID++);
	string strComments;
	strComments.Format(STR_TABLE_RANGE_PEAK_MARKER_EX, get_input_data_range_string(xyOriginal));
	rt = rd_peakmarker.CreateTable("peakmarkers", strComments, nID++);
	///End ADD_COMMENTS_FOR_OUTPUT_DATA
	rt.AddColumn(vpx, STR_SHORTNAME_PEAK_MARKER_X, nID++, "X", OKDATAOBJ_DESIGNATION_X);///Sandy 2009-2-17 USE_SHORT_NAME_AS_INDICATE
	rt.AddColumn(vpy, STR_SHORTNAME_PEAK_MARKER_Y, nID++, "Y", OKDATAOBJ_DESIGNATION_Y);///Sandy 2009-2-17 USE_SHORT_NAME_AS_INDICATE
	
	return true;	
}


//////////////////////BEGIN: to construct pa_xf GetN tree used in make_tree//////////////////////
///Sophy 9/25/2008 NEW_PA move static tree s_trOp to xf
//bool 	construct_GUI_from_operation(TreeNode& tr, LPCSTR lpcszVarName)
bool 	construct_GUI_from_operation( TreeNode& trOp, TreeNode& tr, LPCSTR lpcszVarName)
///end NEW_PA
{
	TreeNode trGUI;
	///Sophy 9/25/2008 NEW_PA move static tree s_trOp to xf
	//if( !_create_op_get_gui_tree(trGUI) )
	if( !create_op_get_gui_tree(trOp, trGUI, "FitPeak") )//if( !_create_op_get_gui_tree( trOp, trGUI) )	///Jasmine 04/23/09 NANO_CENTRIALIZE_FUNCTION
	///end NEW_PA
		return false;
	
	//------ Folger 11/13/08 QA80-12488 v8.970 PA_FITTING_AUTO_UPDATE_SUPPORT_USE_VECTOR_FOR_UIDS_STORAGE
	
	/// IDs which are lower than this one cannot be changed since due to PA theme conversion working,
	/// however, new coming nodes' dataid should be started from PA_PEAK_FITTING_DATAID_START
		
	if ( lstrcmp(lpcszVarName, "trUID") == 0 )
	{
		tree_check_get_node_by_dataid(tr, "range_uid", PA_PEAK_FITTING_DATAID_RANGE_UID);
		//------ Folger 11/15/08 QA80-12488 v8.0972 NEED_TO_BRING_BACK_REPORT_GRAPHS_UID_FOR_AUTO_UPDATE
		tree_check_get_node_by_dataid(tr, "graph_uid", PA_PEAK_FITTING_DATAID_GRAPH_UID);
		//------
		///------ Folger 09/05/09 FAILS_TO_PASTE_RESULTS_TABLE_TO_REPORT_GRAPH_DURING_CHANGE_PARAM_IN_PA
		tree_check_get_node_by_dataid(tr, "result_table_uid", PA_PEAK_FITTING_DATAID_RESULT_TABLE_UID);
		///------ End FAILS_TO_PASTE_RESULTS_TABLE_TO_REPORT_GRAPH_DURING_CHANGE_PARAM_IN_PA
	}
	//------ End PA_FITTING_AUTO_UPDATE_SUPPORT_USE_VECTOR_FOR_UIDS_STORAGE	
	
	int nBeginID;
	if( 0 == lstrcmp(lpcszVarName, "FitControl") )  
	{
		///------ Folger 05/12/09 PROPER_CHECKING_FOR_FIT_CONTROL_DATAIDS
		//nBeginID = 1;
		//_construct_fit_control_branch(trGUI, tr, nBeginID);
		_construct_fit_control_branch(trGUI, tr, PEAK_FITTING_DATAID_FITCONTROL_TREE_BEGIN, PEAK_FITTING_DATAID_FITCONTROL_TREE_END);
		///------ End PROPER_CHECKING_FOR_FIT_CONTROL_DATAIDS
	}
	
	if( 0 == lstrcmp(lpcszVarName, "result") )  
	{
		nBeginID = 20;
		_construct_result_branch(trGUI, tr, nBeginID);
	}
	
	if( 0 == lstrcmp(lpcszVarName, "PFMParams") )  
	{
		octree_nlsf_add_params_node_DataID(&tr, 0);
		
		///Jasmine 04/15/08 LINEAR_CONSTRAINTS_CHECKBOX_UNDER_FIT_CONTROL_BRANCH
		if(tr.LinearConstraints)
			tr.LinearConstraints.Remove();
		///End LINEAR_CONSTRAINTS_CHECKBOX_UNDER_FIT_CONTROL_BRANCH
		
		TreeNode trFunction = tr.AddNode("Functions");
		///Jasmine 04/17/08 PEAK_FIT_USE_SAME_FUNCTION_ID_AS_NLFIT
		//trFunction.SetAttribute(STR_DATAID_ATTRIB, GET_USER_DATAID(10));
		trFunction.SetAttribute(STR_DATAID_ATTRIB, IDE_NLSF_FUNCTION);
		///end PEAK_FIT_USE_SAME_FUNCTION_ID_AS_NLFIT
		
		//------ Folger 12/03/08 QA80-12701 v8.0982 THEME_SETTING_CONTROL_FOR_BASELINE_FUNCTION_APPLIED_IN_PA_FIT
		TreeNode trBaselineFunctionUsingFitStep = tr.AddNode("BaselineFunction");
		trBaselineFunctionUsingFitStep.SetAttribute(STR_DATAID_ATTRIB, PA_PEAK_FITTING_DATAID_BASELINE_FUNCTION);
		//------
		
		nBeginID = 11;
		TreeNode trBLParams = tr.AddNode("BaselineParameters");
		trBLParams.SetAttribute(STR_DATAID_ATTRIB, GET_USER_DATAID(nBeginID));
		
		TreeNode trAutoInit = tr.GetNode("AutoParamsInit");
		if(trAutoInit)
			trAutoInit.nVal = true;
		
		/// Iris 11/04/2008 v8.0965b SAVE_DEFAULT_FUNC_TO_THEME	
		nBeginID = 13;
		TreeNode trDefaultFunction = tr.AddNode("DefaultFunction");
		trDefaultFunction.SetAttribute(STR_DATAID_ATTRIB, GET_USER_DATAID(nBeginID));
		trDefaultFunction.strVal = STR_GAUSSIAN_FUNC;
		///end SAVE_DEFAULT_FUNC_TO_THEME
	}
	
	//------ Folger 12/11/08 QA80-12765 v8.0985 CHANGE_PARAMETER_FAILS_TO_REMEMBER_SETTINGS_FROM_LAST_CLOSE_IN_PA_FITTING
	if( 0 == lstrcmp(lpcszVarName, "FitWorkArea") )
	{
		TreeNode trParams = tr.AddNode("Parameters");
		octree_nlsf_add_params_node_DataID(&trParams, 0);
		
		int		nDataID = PA_PEAK_FITTING_DATAID_FITWORKAREA_BEGIN;
		foreach ( TreeNode trNode in trParams.Children )
		{
			trNode.DataID = nDataID++;
		}
		
		///------ Folger 02/24/09 FITWORKAREA_SHOULD_CONTAIN_BASELINE_PARAMETERS_NUMBER_INFO_INORDER_TO_CORRECTLY_APPLY
		TreeNode trBLParams = trParams.AddNode("BaselineParameters");
		trBLParams.SetAttribute(STR_DATAID_ATTRIB, nDataID++);
		///------ End FITWORKAREA_SHOULD_CONTAIN_BASELINE_PARAMETERS_NUMBER_INFO_INORDER_TO_CORRECTLY_APPLY
		
		/// Iris 3/30/2009 QA80-13362 FIX_CHANGE_BASELINE_FUNC_FIT_STATUS_FROM_NONE_TO_FIT_INSERT_0_FOR_REDUNDANT_BASELINE_PARAM_VAL
		TreeNode trBLFunc = trParams.AddNode("BaselineFunction");
		trBLFunc.SetAttribute(STR_DATAID_ATTRIB, nDataID++);		
		///end FIX_CHANGE_BASELINE_FUNC_FIT_STATUS_FROM_NONE_TO_FIT_INSERT_0_FOR_REDUNDANT_BASELINE_PARAM_VAL
	}
	//------ End CHANGE_PARAMETER_FAILS_TO_REMEMBER_SETTINGS_FROM_LAST_CLOSE_IN_PA_FITTING
	
	if( 0 == lstrcmp(lpcszVarName, "trAdv") )  
	{				
		//not save in theme so no id
		/// Iris 4/25/2008 FIX_PA_NO_SOURCE_ENTRY_IN_OUTPUT_DESTINATION_COMBO
		//tr.AddNode("InputData");
		TreeNode	trInputData = tr.AddNode("InputData");
		//trInputData.DataID = IDST_INPUT_DATA_OPTIONS;
		///end FIX_PA_NO_SOURCE_ENTRY_IN_OUTPUT_DESTINATION_COMBO
		
		/// Iris 11/15/2008 QA80-12584_P7 FIX_ALWAYS_NEW_REPORT_GRAPH_WHEN_RECALCULATE, if not add subnodes, plot range in graph will be saved in trGetN when recalculate.
		nBeginID = 14;
		TreeNode trOutputGraph = tr.AddNode("OutputGraph");
		TreeNode trLayerUID = trOutputGraph.AddNode("LayerUID");
		trLayerUID.SetAttribute(STR_DATAID_ATTRIB, GET_USER_DATAID(nBeginID++));		
		///end FIX_ALWAYS_NEW_REPORT_GRAPH_WHEN_RECALCULATE
		
		/// Iris 12/01/2008 v8.0981 FIX_CHANGE_PARAM_ALWAYS_REPLOT_ON_SOURCE_GRAPH
		TreeNode trSourceGraphIDMap = tr.AddNode("SourceGraphIDMap");
		trSourceGraphIDMap.SetAttribute(STR_DATAID_ATTRIB, GET_USER_DATAID(nBeginID++));		
		TreeNode trSourceGraphUID = tr.AddNode("SourceGraphUID");
		trSourceGraphUID.SetAttribute(STR_DATAID_ATTRIB, GET_USER_DATAID(nBeginID++));		
		///end FIX_CHANGE_PARAM_ALWAYS_REPLOT_ON_SOURCE_GRAPH
	}	
	
	
	if( 0 == lstrcmp(lpcszVarName, STR_GETN_VAR_SHARED_PEAKS_INFO) )  
	{
		//tree_check_get_node_by_dataid(tr, "xc", PA_PEAK_XC_DATAID_IN_GETN_TREE);
		//tree_check_get_node_by_dataid(tr, "h",  PA_PEAK_H_DATAID_IN_GETN_TREE);
		tree_check_get_node_by_dataid(tr, STR_GETN_VAR_SHARED_PEAKS_XC, PA_PEAK_XC_DATAID_IN_GETN_TREE);
		tree_check_get_node_by_dataid(tr, STR_GETN_VAR_SHARED_PEAKS_H,  PA_PEAK_H_DATAID_IN_GETN_TREE);
	}	
	
	if( 0 == lstrcmp(lpcszVarName, "distr") )  
	{				
		//int nDataIDBase = 1;
		//tree_check_get_node_by_dataid(tr, "xc", GET_USER_DATAID(nDataIDBase++));
		//tree_check_get_node_by_dataid(tr, "h", GET_USER_DATAID(nDataIDBase++));
		tree_check_get_node_by_dataid(tr, "xc", PA_PEAK_FITTING_DATAID_DISABLED_CENTER);
		tree_check_get_node_by_dataid(tr, "h", PA_PEAK_FITTING_DATAID_DISABLED_HEIGHT);
	}
	
	return true;
}

///------ Folger 05/12/09 PROPER_CHECKING_FOR_FIT_CONTROL_DATAIDS
//static void _construct_fit_control_branch(TreeNode& trGUI, TreeNode& tr, int nBeginID)
static void _construct_fit_control_branch(TreeNode& trGUI, TreeNode& tr, int nBeginID, int nLastID)
///------ End PROPER_CHECKING_FOR_FIT_CONTROL_DATAIDS
{
	if( !trGUI || !tr)
		return;	
	
	if(trGUI.Fit && trGUI.Fit.Iterations)
	{
		TreeNode trMaxNum = trGUI.Fit.Iterations.MaxNum;
		if(trMaxNum)
		{
			TreeNode trNew = tr.AddNode();
			trNew.Replace(trMaxNum);
			trNew.nVal = LIMIT_MAX_ITERATIONS_OF_PEAK_FIT;	///Jasmine 04/07/08 MAX_ITER_SHARED_IN_PAFIT_AND_SPFMFIT
		}
		TreeNode trTolerance = trGUI.Fit.Iterations.Tolerance; 
		if(trTolerance)
		{
			TreeNode trNew = tr.AddNode();
			trNew.Replace(trTolerance);
			trNew.dVal =  LIMIT_TOLERANCE_OF_PEAK_FIT;	///Jasmine 04/08/08 HIGHER_TOLERANCE_BY_EASWAR_REQUEST
		}
	}	

//#ifdef MULTI_FUNC_CONSTRAINTS_READY		///Jasmine 04/30/08 MULTI_FUNC_CONSTRAINTS_IS_NOT_READY
	if(trGUI.Codes && trGUI.Codes.Constraints)
	{
		GETN_USE(tr)
		GETN_CHECK(EnableConstraints, _L("Enable Constraints"), false)  //GETN_OPTION_EVENT_EX(_enable_constraints_event)
		GETN_ID(IDE_NL_LINEAR_CONSTRAINTS)								///Jasmine 04/15/08 LINEAR_CONSTRAINTS_CHECKBOX_UNDER_FIT_CONTROL_BRANCH
		
		TreeNode trConstraints = trGUI.Codes.Constraints;
		TreeNode trNew = tr.AddNode();
		trNew.Replace(trConstraints);
	}	
//#endif//MULTI_FUNC_CONSTRAINTS_READY

	///------ Folger 05/12/09 PROPER_CHECKING_FOR_FIT_CONTROL_DATAIDS
	//assign_new_ID(tr, nBeginID);//id begins from 1 and maybe to 10
	int		nLastIDOut = assign_new_ID(tr, nBeginID);
	ASSERT(nLastIDOut - 1 <= nLastID);
	///------ End PROPER_CHECKING_FOR_FIT_CONTROL_DATAIDS
}

///Kyle 11/13/2008 KEEP_TREE_DATA_ID_SAME_AS_THE_OLD_XF
static void _construct_subtracted_baseline_data_output_branch(const TreeNode& trGUI, TreeNode& trOutput, int& nBeginID)
{
	if(!trGUI || !trOutput)
		return;
	
	TreeNode trOut = trGUI.Output;
	if(!trOut)
		return;

	foreach(TreeNode trBranch in trOut.Children)
	{
		if(	IDE_PFM_OUTPUT_SUBTRACTED_DATA_TO == trBranch.DataID ||
			IDE_PFM_OUTPUT_BASELINE_DATA_TO == trBranch.DataID ) 
		{
			TreeNode trBranchOut = trOutput.AddNode();
			ASSERT(trBranchOut);
			trBranchOut.Replace(trBranch.Clone());
			///------ Folger 07/01/09 THEME_SAVED_IN_SR5_FAILS_TO_BE_APPLIED_AFTER_NEW_RESULTS_NODE_ADDED_IN_PA
			trBranchOut.SetAttribute(STR_DELAY_DATAID_ASSIGN_ATTRIB, PA_DELAY_DATAID_ASSIGN_VER2);
			///------ End THEME_SAVED_IN_SR5_FAILS_TO_BE_APPLIED_AFTER_NEW_RESULTS_NODE_ADDED_IN_PA
			foreach(TreeNode trNode in trBranchOut.Children)
			{
				PeakFitOutputGUIManager outputManager;
				string	strDefault = outputManager.GetOutputDestinationDefaultSetting(trNode.DataID);
				if( !strDefault.IsEmpty() )
					trNode.strVal = strDefault;
				///------ Folger 07/01/09 THEME_SAVED_IN_SR5_FAILS_TO_BE_APPLIED_AFTER_NEW_RESULTS_NODE_ADDED_IN_PA
				trNode.SetAttribute(STR_DELAY_DATAID_ASSIGN_ATTRIB, PA_DELAY_DATAID_ASSIGN_VER2);
				///------ End THEME_SAVED_IN_SR5_FAILS_TO_BE_APPLIED_AFTER_NEW_RESULTS_NODE_ADDED_IN_PA
			}
			//assign_new_ID(trBranchOut, nBeginID);		///------ Folger 07/01/09 THEME_SAVED_IN_SR5_FAILS_TO_BE_APPLIED_AFTER_NEW_RESULTS_NODE_ADDED_IN_PA
		}
	}
}
///End KEEP_TREE_DATA_ID_SAME_AS_THE_OLD_XF

static void _construct_output_branch(const TreeNode trGUI, TreeNode& trOutput)
{
	if(!trGUI || !trOutput)
		return;
	
	TreeNode trOut = trGUI.Output;
	if(!trOut)
		return;
	
	trOutput.Replace(trOut.Clone());	

	foreach(TreeNode trBranch in trOutput.Children)
	{
		if(IDST_REPORT_SHEET_OPTIONS == trBranch.DataID 
			|| IDST_REPORT_CURVE_OPTIONS == trBranch.DataID 
			|| IDST_RESIDUAL_CURVE_OPTIONS == trBranch.DataID 
			|| IDST_PFM_REPORT_PEAK_CHAR_TO == trBranch.DataID
			|| IDE_OUTPUT_MANAGER_POINTER == trBranch.DataID /// Iris 4/14/2008 FAIL_TO_GET_OUTPUT_POINTER_IN_PA_FIT
			|| IDE_OPERATION_POINTER == trBranch.DataID /// Hong 04/14/08 v8.0842 GET_REAL_BOOK_SHEET_NAME_FROM_AUTO_TYPE
			/// Iris 11/12/2008 v8.0969 OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP
			///Kyle 11/13/2008 KEEP_TREE_DATA_ID_SAME_AS_THE_OLD_XF, construct these two branch after assign id, so the DataID can match to the old xf
			//|| IDE_PFM_OUTPUT_SUBTRACTED_DATA_TO == trBranch.DataID
			//|| IDE_PFM_OUTPUT_BASELINE_DATA_TO == trBranch.DataID
			///End KEEP_TREE_DATA_ID_SAME_AS_THE_OLD_XF
			///end OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP
			) 
		{
			foreach(TreeNode trNode in trBranch.Children)
			{
				/// Iris 3/26/2008 v8.0832 CLEANUP_OUTPUT_BOOK_SHEET_AREA_TO_CLASS
				//trNode.strVal = get_output_destination_default_setting(trNode.DataID);
				PeakFitOutputGUIManager outputManager;
				/// Iris 4/14/2008 FAIL_TO_GET_OUTPUT_POINTER_IN_PA_FIT
				// Output Pointer cannot get default val from PeakFitOutputGUIManager::GetOutputDestinationDefaultSetting
				//trNode.strVal = outputManager.GetOutputDestinationDefaultSetting(trNode.DataID);
				string	strDefault = outputManager.GetOutputDestinationDefaultSetting(trNode.DataID);
				if( !strDefault.IsEmpty() )
					trNode.strVal = strDefault;
				///end CLEANUP_OUTPUT_BOOK_SHEET_AREA_TO_CLASS
			}
			///end FAIL_TO_GET_OUTPUT_POINTER_IN_PA_FIT
			continue;
		}
		
		trBranch.Remove();
	}	
}

static void _construct_report_config_branch(const TreeNode trGUI, TreeNode& trWBConfig)
{
	if(!trGUI || !trWBConfig)
		return;
	
	if(trGUI.Quantities)
	{
		TreeNode trQuan = trWBConfig.AddNode("Quantities");
		trQuan.Replace(trGUI.Quantities.Clone());
		TreeNode trSummaryTable = trQuan.SummaryTable;
		if(trSummaryTable)
		{
			trSummaryTable.Use = 0;
			trSummaryTable.Show = false;
		}
	}
	if(trGUI.PeakReport)
	{
		TreeNode trPeakReport = trWBConfig.AddNode("PeakReport");
		trPeakReport.Replace(trGUI.PeakReport.Clone());
		//------ Folger 04/15/08 ADD_CHECK_BOX_TO_PEAKS_BRANCH
		/// Hong 05/27/08 v8.0871 FIX_SOME_NODE_EVENT_NOT_TRIGGER_CLICK_CHECK_ALL_CBX
		//trPeakReport.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_CHECK_CONTROL | GETNBRANCH_CHECK_CONTROL_ONE_EVENT);
		trPeakReport.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_CHECK_CONTROL);
		/// end FIX_SOME_NODE_EVENT_NOT_TRIGGER_CLICK_CHECK_ALL_CBX
		//------
	}
}

static void _construct_graph_config_branch(const TreeNode trGUI, TreeNode& trGraphConfig)
{
	if(!trGUI || !trGraphConfig)
		return;
	
	///Jasmine 05/20/08 REPORT_GRAPH_SHOULD_BE_BE_ABLE_TO_TURN_OFF
	if(trGUI.PlotCurveTo)
	{
		TreeNode trPlotCurveTo = trGraphConfig.AddNode("PlotCurveTo");
		trPlotCurveTo.Replace(trGUI.PlotCurveTo.Clone());
		trPlotCurveTo.nVal = PLOT_TO_NEW_GRAPH;	
	}
	///End REPORT_GRAPH_SHOULD_BE_BE_ABLE_TO_TURN_OFF
	
	if(trGUI.Output)
	{
		TreeNode trRt = tree_get_node_by_tagname(trGUI.Output, "PasteResultTable", true);
		if(trRt)
		{
			TreeNode trPasteResultTable = trGraphConfig.AddNode("PasteResultTable");
			trPasteResultTable.Replace(trRt.Clone());
			trPasteResultTable.SetAttribute(STR_LABEL_ATTRIB, _L("Paste Result Tables to Graph"));
			trPasteResultTable.SetAttribute(STR_USE_ATTRIB, 0);
			if(trPasteResultTable.TableTemplate) trPasteResultTable.TableTemplate.strVal = "PeakAnalyzer.otw";
			if(trPasteResultTable.ThemeRsltTable) trPasteResultTable.ThemeRsltTable.strVal = "PeakAnalyzer.ini";
		}
	}
	/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
	//if(trGUI.Graph1)
	if( OP_GUI_FITCURVE_PLOT_CHECKBOX(trGUI) )
	///end OP_DLG_NEW_STRUCTURE
	{
		TreeNode trFitCurve = trGraphConfig.AddNode("fitcurve");
		_construct_fit_curve_branch(trGUI, trFitCurve);
	}	
	///Jasmine 04/16/08 ADD_RESIDUAL_PLOT_TO_PA_FIT
	/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
	//if(trGUI.Residuals)
	if( OP_GUI_BRANCH_OF_RESIDUAL_PLOTS_CHECKBOX(trGUI) )
	///end OP_DLG_NEW_STRUCTURE
	{
		TreeNode trResidualplot = trGraphConfig.AddNode("residualplot");
		_construct_residual_plot_branch(trGUI, trResidualplot);
	}
	///End ADD_RESIDUAL_PLOT_TO_PA_FIT
	if(trGUI.PeakReportField)
	{
		TreeNode trPeakReportField = trGraphConfig.AddNode("PeakReportField");
		trPeakReportField.Replace(trGUI.PeakReportField.Clone());
	}
}

static void _construct_fit_curve_branch(const TreeNode trGUI, TreeNode& trGraph1)
{
	/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
	//trGraph1.Replace(trGUI.Graph1.Clone());
	trGraph1.Replace(OP_GUI_FITCURVE_PLOT_CHECKBOX(trGUI).Clone());
	///end OP_DLG_NEW_STRUCTURE
	
	/// Hong 11/18/08 QA80-12603 v8.0974 PA_SUPPORT_LEGEND_UPDATE_OPTION
	/*
	if(trGraph1.UpdateLegend) 
	{
		TreeNode trUpdateLegend = trGraph1.UpdateLegend;
		///Jasmine 03/20/08 REMOVE_LEGEND_IN_PA_GRAPH
		//trUpdateLegend.SetAttribute(STR_LABEL_ATTRIB, _L("Update Legend on Graph"));		
		trUpdateLegend.Show = false;
		///End REMOVE_LEGEND_IN_PA_GRAPH
		trUpdateLegend.nVal = false;	///Jasmine 02/01/08 PLOT_TO_SOURCE_GRAPH 		
	}
	*/
	/// end PA_SUPPORT_LEGEND_UPDATE_OPTION
	if(trGUI.AddBackBaseline && trGraph1.FirstNode)
	{
		//TreeNode trAddBackBaseline = trGraphConfig.AddNode("AddBackBaseline");
		TreeNode trAddBackBaseline = trGraph1.InsertNode(trGraph1.FirstNode, "AddBackBaseline");
		trAddBackBaseline.Replace(trGUI.AddBackBaseline.Clone());
		//trAddBackBaseline.Show = bShowAddBaseline; //Iris move show/hide this node to pa_fit event1
	}
	if(trGUI.PLotCurves && trGraph1.FirstNode)
	{
		//TreeNode trPLotCurves = trGraphConfig.AddNode("PLotCurves");
		TreeNode trPLotCurves = trGraph1.InsertNode(trGraph1.FirstNode, "PLotCurves");
		trPLotCurves.Replace(trGUI.PLotCurves.Clone());
	}
	///------ Folger 02/04/09 QA80-12962 ADD_OPTION_IN_PA_FIT_TO_SWTICH_BACK_TO_OLD_FIT_CURVE_DATA_GENERATION_MECHANISM
	if ( trGraph1.PLotCurves )
	{
		TreeNode trNext = trGraph1.PLotCurves.NextNode;
		if ( trNext )
		{
			TreeNode trXPtsForEachPeak = trGraph1.InsertNode(trNext, "XPtsForEachPeak", TRGP_DOUBLE);
			trXPtsForEachPeak.SetAttribute(STR_LABEL_ATTRIB, _L("X Data Points for Individual Peak"));
			trXPtsForEachPeak.nVal = 100;
						
			TreeNode trUseSepX = trGraph1.InsertNode(trXPtsForEachPeak, "UseSepX", TRGP_CHECK);
			trUseSepX.SetAttribute(STR_LABEL_ATTRIB, _L("Use Separate X Data for Individual Peak"));
			trUseSepX.nVal = 1;
			
			///------ Folger 02/12/09 QA80-12962 PROPER_ASSIGN_ID_FOR_NEW_ADDED_NODES
			trXPtsForEachPeak.SetAttribute(STR_DELAY_DATAID_ASSIGN_ATTRIB, PA_DELAY_DATAID_ASSIGN_VER1);		/// SR5
			trUseSepX.SetAttribute(STR_DELAY_DATAID_ASSIGN_ATTRIB, PA_DELAY_DATAID_ASSIGN_VER1);				/// SR5
			///------ End PROPER_ASSIGN_ID_FOR_NEW_ADDED_NODES
		}
	}
	///------ End ADD_OPTION_IN_PA_FIT_TO_SWTICH_BACK_TO_OLD_FIT_CURVE_DATA_GENERATION_MECHANISM
}

static void _construct_residual_plot_branch(const TreeNode trGUI, TreeNode& trResidual)
{
	/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
	//if(trResidual && trGUI && trGUI.Residuals)
	if(trResidual && trGUI && OP_GUI_BRANCH_OF_RESIDUAL_PLOTS_CHECKBOX(trGUI))
	///end OP_DLG_NEW_STRUCTURE
	{
		/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//TreeNode trRes = trGUI.Residuals.Graph2;
		TreeNode trRes = OP_GUI_BRANCH_OF_RESIDUAL_PLOTS_CHECKBOX(trGUI).Graph2;
		///end OP_DLG_NEW_STRUCTURE
		if(trRes)
			trResidual.Replace(trRes.Clone());
	}
}

static void _construct_result_branch(TreeNode& trGUI, TreeNode& tr,int nBeginID)
{
	if( !trGUI || !tr)
		return;	
		
	TreeNode trOutput = tree_check_get_node(tr, "Output", 0, STR_LABEL_ATTRIB, _L("Output Destination"));
	_construct_output_branch(trGUI, trOutput);
	
	TreeNode trWBConfig = tree_check_get_node(tr, "wbconfig", 0, STR_LABEL_ATTRIB, _L("Configure Report"));
	_construct_report_config_branch(trGUI, trWBConfig);
	
	//XYRange xyBL;
	//bool bHasBaseline = check_baseline_range(pg, xyBL);
	//bool bBaselineSubtrcted = bHasBaseline && !check_baseline_range(pg, xyBL, true);	
	TreeNode trGraphConfig = tree_check_get_node(tr, "gpconfig", 0, STR_LABEL_ATTRIB, _L("Configure Graph"));
	_construct_graph_config_branch(trGUI, trGraphConfig);
	
	//------ Folger 04/15/08 ADD_CHECK_BOX_TO_PEAKS_BRANCH
	//tree_remove_attribute(tr, STR_ATTRIB_BRANCH);
	octree_set_attribute_to_all_nodes(&tr, STR_ATTRIB_BRANCH, NULL, true);
	//------
	tr.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);
	
	///Kyle 11/13/2008 KEEP_TREE_DATA_ID_SAME_AS_THE_OLD_XF
	// when call _assign_new_ID, it will assign id one by one, so if these branches are inserted before, the ID will not match to the old version
	_construct_subtracted_baseline_data_output_branch(trGUI, trOutput, nBeginID);
	///End KEEP_TREE_DATA_ID_SAME_AS_THE_OLD_XF

	assign_new_ID(tr, nBeginID); //maybe to 80
}

///--- HARD_CODE_TO_REMOVE_REPEAT_ID
//////////////////////END: to construct pa_xf GetN tree used in make_tree//////////////////////

//################################## PAWizTheme #####################################//
///------ Folger 08/07/09 QA80-13998 SUPPORT_GET_GOAL_AND_FITTING_REPORT_GRAPH_UID_FROM_PAWIZMANAGER
//class PAWizTheme : public XFWizTheme
//{
//public:
	//PAWizTheme();
	/////---Sim 01-12-2009 QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	////virtual int		Update(const TreeNode& trGetN, LPCSTR lpcszXFName, bool bToGetN);
	/////---END QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
//
	/////---Sim 11-17-2008 FIX_SAVE_SHARED_VALUE_ON_PA_WIZ_THEME_TREE
	//virtual bool		SetTree(const TreeNode& trThemes);
	//virtual bool		Load(LPCSTR lpcszThemeName);
	/////---END FIX_SAVE_SHARED_VALUE_ON_PA_WIZ_THEME_TREE
	//
	/////---Sim 10-13-2008 NEW_PA_81_THEME_FILTER_SETTING
	//virtual	bool		IsThemeSettingSupported() {return true;}
	//virtual string		GetThemeFilterDlgTitle() {return STR_LABEL_PA_THEME_SETTING_TITLE;}
	/////---END NEW_PA_81_THEME_FILTER_SETTING
//protected:
	/////---Sim 01-12-2009 QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	////bool			UpdateSharedValues(TreeNode& trGetN, bool bToGetN);
	/////---END QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	/////---Sim 10-13-2008 NEW_PA_81_THEME_FILTER_SETTING
	//virtual	bool		ConstructThemeFilter(TreeNode& trThemeFilter);
	//virtual bool		GetThemeFilterMapIDs(vector<int>& vnGUIID, vector<int>& vnThemeFilterID, TreeNode& trGetN, LPCSTR lpcszXFName);
	/////---END NEW_PA_81_THEME_FILTER_SETTING
	/////---Sim 11-14-2008 SUPPORT_PA_THEME_SR4_CONVERT_TO_SR5
	//virtual bool		ConvertVersion(TreeNode& trThemes);
	/////---END SUPPORT_PA_THEME_SR4_CONVERT_TO_SR5
	/////---Sim 11-17-2008 FIX_SAVE_SHARED_VALUE_ON_PA_WIZ_THEME_TREE
	//void			TrimSharedValueByThemeFilter();
	/////---END FIX_SAVE_SHARED_VALUE_ON_PA_WIZ_THEME_TREE
//protected:
	/////---Sim 01-12-2009 QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	////StringArray		saSharedList;
	/////---END QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	////vector<int>  	vnShareDataID;
//};
///------ End SUPPORT_GET_GOAL_AND_FITTING_REPORT_GRAPH_UID_FROM_PAWIZMANAGER


PAWizTheme::PAWizTheme()
:XFWizTheme()
{
	///1, base anchor XYs, shared in Baseline mode and create baseline
	m_saSharedList.Add(STR_GETN_VAR_SHARED_BASE_ANCHORS);
	m_saSharedList.Add(STR_GETN_VAR_SHARED_BASE_ANCHORS_SNAP);
	m_saSharedList.Add(STR_GETN_VAR_SHARED_BASE_ANCHORS_XS);
	m_saSharedList.Add(STR_GETN_VAR_SHARED_BASE_ANCHORS_YS);	
	//vnShareDataID.Add(PA_BASE_ANCHOR_X_DATAID_IN_GETN_TREE);
	//vnShareDataID.Add(PA_BASE_ANCHOR_Y_DATAID_IN_GETN_TREE);
	m_saSharedList.Add(STR_GETN_VAR_SHARED_DERIVATIVE); /// Iris 10/31/2008 V8.0963d MOVE_2ND_DERVITIVE_PLOT_CODES_TO_PAWIZCORE
	
	m_saSharedList.Add(STR_GETN_VAR_SHARED_PEAKS_INFO);
	
	///------ Folger 02/25/09 QA80-13181 SHARE_BASELINE_FIX_STATUS_BETWEEN_BASELINE_TREATMENT_AND_FITTING
	m_saSharedList.Add(STR_GETN_VAR_SHARED_FIXBASE);
	///------ End SHARE_BASELINE_FIX_STATUS_BETWEEN_BASELINE_TREATMENT_AND_FITTING
}

///---Sim 01-12-2009 QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
////virtual
//int PAWizTheme::Update(const TreeNode& trGetN, LPCSTR lpcszXFName, bool bToGetN)
//{
	//int nRet = XFWizTheme::Update(trGetN, lpcszXFName, bToGetN);
	//if ( FAILED_APPLY_THEME != nRet )
	//{
		//if ( !UpdateSharedValues(trGetN, bToGetN) )
			//return FAILED_APPLY_THEME;
	//}
	//
	//return nRet;
//}
///---END QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE

///---Sim 01-12-2009 QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
// move to XFWizTheme
/*
bool PAWizTheme::UpdateSharedValues(TreeNode& trGetN, bool bToGetN)
{
	TreeNode trShared = GetShared(!bToGetN);
	if ( bToGetN && !trShared )
		return true; // only skip shared value at first aplly getn tree
	if ( !trShared || !trGetN )
		return false;
	
	int nSharedNum = saSharedList.GetSize();
	for (int ii = 0; ii < nSharedNum; ii++ )
	{
		TreeNode trGetNShared = trGetN.GetNode(saSharedList[ii]);
		TreeNode trThemeShared = trShared.GetNode(saSharedList[ii]);
		if ( !trThemeShared && trGetNShared && !bToGetN )
			trThemeShared = tree_check_get_node(trShared, saSharedList[ii]);
		
		if ( trThemeShared && trGetNShared )
		{
			///Sophy 10/21/2008 FIX_FAIL_TO_APPLY_THEME_FOR_DUPLICATED_NODE_DATAID_IN_THEME_WITH_BASELINE_MODE
			// When save theme with user-define baseline mode, trGetN has subnodes with duplicated DataID
			// This will cause apply theme failure, so just copy values here to avoid importing an existing DataID to different node
			/#
			if ( bToGetN )
				trGetNShared.Replace(trThemeShared);
			else
				trThemeShared.Replace(trGetNShared);
			#/
			if ( bToGetN )
				trGetNShared.Replace(trThemeShared, true, true, true );
			else
				trThemeShared.Replace(trGetNShared, true, true, true );
			///end FIX_FAIL_TO_APPLY_THEME_FOR_DUPLICATED_NODE_DATAID_IN_THEME_WITH_BASELINE_MODE
		}
		
		//TreeNode trGetNShared = tree_check_get_node_by_dataid(trGetN, saSharedList[ii], vnShareDataID[ii]);
		//TreeNode trThemeShared = tree_check_get_node_by_dataid(trShared, saSharedList[ii], vnShareDataID[ii]);
		//
		//if ( trThemeShared && trGetNShared )
		//{
			//if ( bToGetN )
				//trGetNShared.Replace(trThemeShared);
			//else
				//trThemeShared.Replace(trGetNShared);
		//}
	}
	
	return true;
}
*/
///---END QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE

///---Sim 10-13-2008 NEW_PA_81_THEME_FILTER_SETTING
static bool OnShowHint(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nCntrlType, WndContainer& getNContainer)
{
	// Important!!!	// Assume Hint treenode is next to Checkbox
	TreeNode trHint = trNode.NextNode;
	if ( trHint )
	{
		trHint.Show = trNode.nVal;
	}
	return true;
}

//------ Folger 12/03/08 QA80-12701 v8.0982 THEME_SETTING_CONTROL_FOR_BASELINE_FUNCTION_APPLIED_IN_PA_FIT
static bool OnBaseFuncUsingChange(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nCntrlType, WndContainer& getNContainer)
{
	TreeNode trActualValue = trNode.NextNode;
	TreeNode trHint = trActualValue.NextNode;
	TreeNode trHint1 = trHint.NextNode;
	
	if ( trNode.nVal )
	{
		trActualValue.nVal = 0;
		trHint.Show = true;
		trHint1.Show = false;
	}
	else
	{
		trActualValue.nVal = 1;
		trHint.Show = false;
		trHint1.Show = true;
	}
	
	return true;
}
//------ End THEME_SETTING_CONTROL_FOR_BASELINE_FUNCTION_APPLIED_IN_PA_FIT

//virtual
bool PAWizTheme::ConstructThemeFilter(TreeNode& trThemeFilter)
{
	if ( !trThemeFilter )
		return false;
	
	GETN_USE(trThemeFilter)
	GETN_BEGIN_BRANCH(Baseline, _L("Baseline Options")) GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
	GETN_CHECK(BaseAnchor, _L("Baseline Anchor Points"), 1)	GETN_ID(IDE_PA_THEME_FILTER_BASE_ANCHOR)
	///---Sim 04-22-2008 QA80-11371 THEME_SAVING_OPTIONS_HINT
		GETN_OPTION_EVENT_EX(OnShowHint)
	// Important!!! Hint must next to Checkbox treenode
	GETN_STR(BaseAnchorHint, _L("Basline Anchor Points will not take effect if Auto Find for Baseline option is checked"), "")	GETN_HINT
	///---END QA80-11371 THEME_SAVING_OPTIONS_HINT			
	//GETN_CHECK(BaseData, _L("Baseline Data Points"), 0)	GETN_ID(IDE_PA_THEME_FILTER_BASE_DATA)//Sandy 2008-4-15 no requirement
	
	//------ Folger 12/03/08 QA80-12701 v8.0982 THEME_SETTING_CONTROL_FOR_BASELINE_FUNCTION_APPLIED_IN_PA_FIT
	GETN_CHECK(BaseFunctionUsing, _L("Use Basline function in Create Baseline step"), 1)					GETN_ID(IDE_PA_THEME_FILTER_BASE_FUNC_USING)	GETN_OPTION_EVENT_EX(OnBaseFuncUsingChange)
	GETN_CHECK(BaseFunctionActualValue, "", 0)																GETN_ID(IDE_PA_THEME_FILTER_BASE_FUNC_ACTUAL_VALUE)	GETN_CURRENT_SUBNODE.Show = false;
	GETN_STR(BaseFunctionHint, _L("Baseline function change in Fit Control dialog will be ignored"), "")	GETN_HINT
	GETN_STR(BaseFunctionHint1, _L("Baseline function in Fit Control dialog will be used"), "")				GETN_HINT
	//------ End THEME_SETTING_CONTROL_FOR_BASELINE_FUNCTION_APPLIED_IN_PA_FIT
	
	GETN_END_BRANCH(Baseline)
	
	GETN_BEGIN_BRANCH(Peaks, _L("Peaks Options")) GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
	GETN_CHECK(PeakData, _L("Peak Centers and Heights"), 1)	GETN_ID(IDE_PA_THEME_FILTER_PEAK_DATA)
	///---Sim 04-22-2008 QA80-11371 THEME_SAVING_OPTIONS_HINT
		GETN_OPTION_EVENT_EX(OnShowHint)
	// Important!!! Hint must next to Checkbox treenode
	GETN_STR(PeakDataHint, _L("Peak Centers and Heights will not take effect if Auto Find for Peaks option is checked"), "")	GETN_HINT
	///---END QA80-11371 THEME_SAVING_OPTIONS_HINT			
	GETN_END_BRANCH(Peaks)
	
	GETN_BEGIN_BRANCH(Fit, _L("Fit Options")) GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
	nlsf_construct_theme_filter(trThemeFilter.Fit, false);
	// default checked "Auto Parameter Initialization Status" for PA
	TreeNode trAutoParamsInit = tree_get_node_by_id(trThemeFilter.Fit, IDE_NL_THEME_FILTER_AUTO_PARAM_INIT);
	if ( trAutoParamsInit )
		trAutoParamsInit.nVal = 1;
	///---Sim 04-22-2008 QA80-11371 THEME_SAVING_OPTIONS_HINT
	// change parameter values check box hint text
	TreeNode trParamValues = tree_get_node_by_id(trThemeFilter.Fit, IDE_NL_THEME_FILTER_PARAMS);
	if ( trParamValues )
	{
		// Important!!!	// Assume Hint treenode is next to Checkbox
		TreeNode trParamValuesHint = trParamValues.NextNode;
		if ( trParamValuesHint )
		{
			trParamValuesHint.SetAttribute(STR_LABEL_ATTRIB, _L("This option will not take effect if Auto Parameter Initialization from Peaks Info is enabled in your function or theme"));
		}
	}		
	///---END QA80-11371 THEME_SAVING_OPTIONS_HINT
	
	///---Sim 05-14-2008 HIDE_CONSTRAINTS_THEME_SAVING_OPTIONS_FOR_PA Max said in email
	TreeNode trLinearConstraints = tree_get_node_by_id(trThemeFilter.Fit, IDE_NL_THEME_FILTER_ENABLE_LINEAR_CONSTRAINTS);
	if ( trLinearConstraints )
		trLinearConstraints.Show = true;	///Jasmine 08/12/08 CONSTRAINTS_IS_READY_FOR_MULTI_FUNC_AND_REPLICA
	TreeNode trConstraints = tree_get_node_by_id(trThemeFilter.Fit, IDE_NL_THEME_FILTER_CONSTRAINTS);
	if ( trConstraints )
		trConstraints.Show = true;	///Jasmine 08/12/08 CONSTRAINTS_IS_READY_FOR_MULTI_FUNC_AND_REPLICA
	///---END HIDE_CONSTRAINTS_THEME_SAVING_OPTIONS_FOR_PA
	
	///---Sim 05-14-2008 HIDE_PARAM_INIT_THEME_SAVING_OPTIONS_FOR_PA Max said in email
	TreeNode trParamInitCode = tree_get_node_by_id(trThemeFilter.Fit, IDE_NL_THEME_FILTER_CODES_PARAINIT);
	if ( trParamInitCode )
		trParamInitCode.Show = 0;
	///---END HIDE_PARAM_INIT_THEME_SAVING_OPTIONS_FOR_PA
	
	///Jasmine 08/25/08 PA_CAN_ONLY_RUN_AFTER_FIT_SCRIPT_OF_FIRST_FUNCTION
	TreeNode trAfterFit = tree_get_node_by_id(trThemeFilter.Fit, IDE_NL_THEME_FILTER_SCRIPT);
	if ( trAfterFit )
		trAfterFit.Show = 0;
	///End PA_CAN_ONLY_RUN_AFTER_FIT_SCRIPT_OF_FIRST_FUNCTION
	
	GETN_END_BRANCH(Fit)
	
	//GETN_CHECK(OtherSettings, _L("Other Settings"), 1)	GETN_ID(IDE_THEME_FILTER_OTHER)
	GETN_CHECK(OtherSettings, _L("All Other Settings"), 1)	GETN_ID(IDE_THEME_FILTER_OTHER)///Sandy 2008-4-29 Snow's suggestion
	///end
	
	//updateThemeFilterGetNHelpID(trThemeFilter);	//------ Folger 06/12/08 UPDATE_CONTEXT_HELP_FOR_PA_FIT_CONTROL_AND_THEME_SETTING	
	trThemeFilter.SetAttribute(STR_HELPID_ATTRIB, IDD_THEME_SETTING);
	
	return true;
}

// move from nlsf_utils.c
static bool _pa_fit_convert_data_id_for_theme_saving(const TreeNode& trGetN, vector<int>& vnIDs)
{
	if(!trGetN)
		return false;
	
	vector<int> vnIDsNeedConvert = {IDE_NLSF_CATEGORY, IDE_NLSF_CODES_AFTERFIT, IDE_NLSF_CODES_CONSTRAINTS,	IDE_NL_LINEAR_CONSTRAINTS, IDE_NLSF_CODES_PARAINIT};

	for(int ii = 0; ii < vnIDs.GetSize(); ii++)
	{
		vector<uint> vecIndex;
		if( vnIDsNeedConvert.Find(vecIndex, vnIDs[ii]) <= 0 )
			continue;
		int nConvertID = vnIDsNeedConvert[vecIndex[0]];
		
		int nDataID = -1;
		TreeNode trNode = trGetN.FindNodeByAttribute(STR_BACKUP_ID_ATTRIB, nConvertID);
		if(trNode)
			trNode.GetAttribute(STR_DATAID_ATTRIB, nDataID);
		
		vnIDs[ii] = nDataID;
	}
	
	return true;
}

//virtual
bool PAWizTheme::GetThemeFilterMapIDs(vector<int>& vnGUIID, vector<int>& vnThemeFilterID, TreeNode& trGetN, LPCSTR lpcszXFName)
{
	string strXFName(lpcszXFName);
	
	if ( 0 == strXFName.CompareNoCase(STR_PA_XFNAME_FIT) )
	{
		nlsf_get_theme_filter_id_array(vnGUIID, vnThemeFilterID);
		_pa_fit_convert_data_id_for_theme_saving(trGetN, vnGUIID);
		
		//------ Folger 12/03/08 QA80-12701 v8.0982 THEME_SETTING_CONTROL_FOR_BASELINE_FUNCTION_APPLIED_IN_PA_FIT
		vnGUIID.Add(PA_PEAK_FITTING_DATAID_BASELINE_FUNCTION);
		vnThemeFilterID.Add(IDE_PA_THEME_FILTER_BASE_FUNC_ACTUAL_VALUE);
		//------
	}
	
	if ( 0 == strXFName.CompareNoCase(STR_PA_XFNAME_BASEMODE) )
	{
		vnGUIID.Add(PA_BASE_ANCHOR_X_DATAID_IN_GETN_TREE);
		vnThemeFilterID.Add(IDE_PA_THEME_FILTER_BASE_ANCHOR);
		
		vnGUIID.Add(PA_BASE_ANCHOR_Y_DATAID_IN_GETN_TREE);
		vnThemeFilterID.Add(IDE_PA_THEME_FILTER_BASE_ANCHOR);
	}
	
	if ( 0 == strXFName.CompareNoCase(STR_PA_XFNAME_PEAKS) )
	{
		vnGUIID.Add(PA_PEAK_XC_DATAID_IN_GETN_TREE);
		vnThemeFilterID.Add(IDE_PA_THEME_FILTER_PEAK_DATA);
		
		vnGUIID.Add(PA_PEAK_H_DATAID_IN_GETN_TREE);
		vnThemeFilterID.Add(IDE_PA_THEME_FILTER_PEAK_DATA);
	}
	
	//------ Folger 12/03/08 QA80-12701 v8.0982 THEME_SETTING_CONTROL_FOR_BASELINE_FUNCTION_APPLIED_IN_PA_FIT
	if ( 0 == strXFName.CompareNoCase(STR_PA_XFNAME_BASECREATE) )
	{
		vnGUIID.Add(PA_BASE_CREATE_DATAID_FUNCTION_USING);
		vnThemeFilterID.Add(IDE_PA_THEME_FILTER_BASE_FUNC_ACTUAL_VALUE);
	}
	//------ End THEME_SETTING_CONTROL_FOR_BASELINE_FUNCTION_APPLIED_IN_PA_FIT
	
	return true;
}
///---END NEW_PA_81_THEME_FILTER_SETTING

///---Sim 11-14-2008 SUPPORT_PA_THEME_SR4_CONVERT_TO_SR5
typedef int (*FUNC_PA_THEME_CONVERT)(TreeNode& trTheme);

//virtual
bool PAWizTheme::ConvertVersion(TreeNode& trThemes)
{
	if ( !trThemes )
		return false;
	
	///---Sim 07-16-2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6
	//// SR2, SR3, SR4 to SR5
	//if ( PA_VERSION_NUMBER_SR2 <= GetVersion(trThemes) && GetVersion(trThemes) <= PA_VERSION_NUMBER_SR4 && GetVersion() == PA_VERSION_NUMBER_SR5 )
	//{
		//FUNC_PA_THEME_CONVERT pfn = Project.FindFunction("convert_pa_theme", "OriginLab\\PAThemeConvert.c", true);
		//if ( pfn )
			//return ( 0 == pfn(trThemes) );
	//}
	
	//return false;
	
	double dOldVer = GetVersion(trThemes);
	double dNewVer = GetVersion();
	
	if ( dOldVer > dNewVer )
		return false;
	else
	if ( dOldVer < dNewVer )
	{
		if ( dOldVer < PA_VERSION_NUMBER_SR2 ) // don't support from SR0, SR1
			return false;
		
		if ( dNewVer > PA_VERSION_NUMBER_SR6 ) // don't support to SR7 or higher
			return false;
		
		// SR2, SR3, SR4 to SR5
		if ( dOldVer < PA_VERSION_NUMBER_SR5 && dNewVer >= PA_VERSION_NUMBER_SR5 )
		{
			FUNC_PA_THEME_CONVERT pfn = Project.FindFunction("convert_pa_theme", "OriginLab\\PAThemeConvert.c", true);
			if ( pfn )
			{
				if ( 0 != pfn(trThemes) )
					return false;
			}
			dOldVer = PA_VERSION_NUMBER_SR5;
		}
		
		// SR5 to SR6
		if ( dOldVer < PA_VERSION_NUMBER_SR6 && dNewVer >= PA_VERSION_NUMBER_SR6 )
		{
			FUNC_PA_THEME_CONVERT pfn = Project.FindFunction("convert_pa_theme_sr5_to_sr6", "OriginLab\\PAThemeConvert.c", true);
			if ( pfn )
			{
				if ( 0 != pfn(trThemes) )
					return false;
			}
			dOldVer = PA_VERSION_NUMBER_SR6;
		}
		
	}
	
	return true;
	///---END CONVERT_PA_THEME_FROM_SR5_TO_SR6	
}
///---END SUPPORT_PA_THEME_SR4_CONVERT_TO_SR5

///---Sim 11-17-2008 FIX_SAVE_SHARED_VALUE_ON_PA_WIZ_THEME_TREE
//virtual
bool PAWizTheme::SetTree(const TreeNode& trThemes)
{
	if ( XFWizTheme::SetTree(trThemes) )
	{
		TrimSharedValueByThemeFilter();
		return true;
	}
	return false;
}
//virtual
bool PAWizTheme::Load(LPCSTR lpcszThemeName)
{
	if ( XFWizTheme::Load(lpcszThemeName) )
	{
		TrimSharedValueByThemeFilter();
		return true;
	}
	return false;
}
void PAWizTheme::TrimSharedValueByThemeFilter()
{
	TreeNode trShared = GetShared();
	if ( !trShared )
		return;
	
	vector<int> vnGUIID;
	vector<int> vnThemeFilterID;
	GetThemeFilterMapIDs(vnGUIID, vnThemeFilterID, NULL, STR_PA_XFNAME_BASEMODE);
	GetThemeFilterMapIDs(vnGUIID, vnThemeFilterID, NULL, STR_PA_XFNAME_PEAKS);

	ASSERT( vnGUIID.GetSize() == vnThemeFilterID.GetSize() );
	for ( int ii = 0; ii < vnThemeFilterID.GetSize(); ii++ )
	{
		TreeNode trSetting = tree_get_node_by_id(m_trLoadedThemeFilter, vnThemeFilterID[ii], true);
		TreeNode trSharedNode = tree_get_node_by_id(trShared, vnGUIID[ii], true);
		if ( trSetting && trSharedNode )
		{
			if ( !(trSetting.nVal) )
				trSharedNode.Remove();
		}
	}
	
	// prevent restore empty (removed by theme filter) treenode value to trGetN
	foreach ( TreeNode tr in trShared.Children )
	{
		if ( tr.IsEmpty() )
			tr.Remove();
	}
}
///---END FIX_SAVE_SHARED_VALUE_ON_PA_WIZ_THEME_TREE

///------ Folger 08/07/09 QA80-13998 SUPPORT_GET_GOAL_AND_FITTING_REPORT_GRAPH_UID_FROM_PAWIZMANAGER
#define		CHECK_GET_VALUE_FROM_THEME(_xfname, _id, _nRet)								\
			if ( NULL != lpcszThemeName )												\
				Load(lpcszThemeName);													\
			else if ( NULL != trThemes )												\
				SetTree(trThemes);														\
			else																		\
			{																			\
				ASSERT(false);															\
				return _nRet;															\
			}																			\
																						\
			TreeNode		_trXF = GetXFTheme(_xfname);								\
			if ( _trXF )																\
			{																			\
				string	_strNode;														\
				_strNode.Format("%s%d", STR_THEME_NODE_TAGNAME_PREFIX, _id);			\
																						\
				TreeNode	_trNode = tree_get_node_by_tagname(_trXF, _strNode, true);	\
				if ( _trNode )															\
					return _trNode.nVal;												\
			}																			\
																						\
			return _nRet;

int		PAWizTheme::GetGoal(LPCSTR lpcszThemeName/* = NULL*/, TreeNode& trThemes/* = NULL*/)
{
	CHECK_GET_VALUE_FROM_THEME(STR_PA_XFNAME_GOAL, 0x00060032, -1)
}

int		PAWizTheme::GetFittingReportGraphUID(LPCSTR lpcszThemeName/* = NULL*/, TreeNode& trThemes/* = NULL*/)
{
	CHECK_GET_VALUE_FROM_THEME(STR_PA_XFNAME_FIT, 0x000a400e, 0)
}
///------ End SUPPORT_GET_GOAL_AND_FITTING_REPORT_GRAPH_UID_FROM_PAWIZMANAGER

///------ Folger 08/07/09 QA80-13998-P1 OUTPUT_RANGE_LT_STRING_FAILS_TO_UPDATE_WHEN_RUN_PA_WITHOUT_AUTOUPDATE
class PAWizInputOutputRange : public XFWizInputOutputRange
{
public:
	/// virtual
	void		UpdateOutputsGlobalRangeStrings(LPCSTR lpcszXFName);
};

#include "XFunctionEx.h"

/// virtual
void	PAWizInputOutputRange::UpdateOutputsGlobalRangeStrings(LPCSTR lpcszXFName)
{
	Array<DataRange&>	arrOutputs;
	if ( !Get(&arrOutputs, lpcszXFName, false) )
		return;

	/// !!! three vectors must be kept same size !!!
	vector<string>	vsXFNames = {
		STR_PA_XFNAME_INT,
		STR_PA_XFNAME_BASECREATE,
		STR_PA_XFNAME_BASESUBTR,
		STR_PA_XFNAME_PEAKS
	};
	
	vector<int>		vnOffsets = {
		REPORT_TREE_VARS_IN_OUTPUT_ARRAY_BEGIN,
		INDEX_OF_NON_REPORT_TREE_VARS_IN_OUTPUT_ARRAY,
		INDEX_OF_NON_REPORT_TREE_VARS_IN_OUTPUT_ARRAY,
		REPORT_TREE_VARS_IN_OUTPUT_ARRAY_BEGIN
	};
	
	///------ Folger 08/03/09 QA80-13998 PA_LAST_REPORT_LT_STRING_CLEANUP
	//char	cSeparator = '|';
	//vector<string>	vsVariableNames = {
	//"__PAINTEGPEAK|__PAINTEGCURVE",
	//"__PABASELINE",
	//"__PASUBTRACTED|__PABASELINE",
	//"__PABASELINE|__PAPEAKCENTER"
	//};
#define	STR_SEPARATOR	"|"
	LPCSTR	lpcszSeparator = STR_SEPARATOR;
	char	cSeparator = lpcszSeparator[0];
	vector<string>	vsVariableNames = {
		LTVAR_PA_INTEGRATE_PEAK STR_SEPARATOR LTVAR_PA_INTEGRATE_CURVE,
		LTVAR_PA_BASELINE,
		LTVAR_PA_SUBTRACTED_DATA STR_SEPARATOR LTVAR_PA_BASELINE,
		LTVAR_PA_BASELINE STR_SEPARATOR LTVAR_PA_PEAK_CENTER
	};
	///------ End PA_LAST_REPORT_LT_STRING_CLEANUP
	/// !!! three vectors must be kept same size !!!
	
	int		nGoal = vsXFNames.Find(lpcszXFName);
	if ( nGoal < 0  )
		return;
	
	Datasheet	ds;
	int			c1, c2;
	if ( REPORT_TREE_VARS_IN_OUTPUT_ARRAY_BEGIN == vnOffsets[nGoal] )		/// report data
	{
		for( int ii = REPORT_TREE_VARS_IN_OUTPUT_ARRAY_BEGIN; ii < arrOutputs.GetSize(); ++ii )
		{
			if ( ii - REPORT_TREE_VARS_IN_OUTPUT_ARRAY_BEGIN >= vsVariableNames[nGoal].GetNumTokens(cSeparator) )
				return;
			
			DataRange& dr = arrOutputs.GetAt(ii);
			if ( !dr || dr.GetNumData() <= 0 )
				continue;
			
			dr.GetRange(ds, c1, c2);
			///------ Folger 03/26/09 ANALYSIS_OUTPUT_REPORT_SHEET_NAME_SHOULD_BE_EXCLAMATION_CHAR_ENDING
			//LT_set_str(vsVariableNames[nGoal].GetToken(ii - REPORT_TREE_VARS_IN_OUTPUT_ARRAY_BEGIN, cSeparator), ds.m_strBookSheet);
			LT_set_str(vsVariableNames[nGoal].GetToken(ii - REPORT_TREE_VARS_IN_OUTPUT_ARRAY_BEGIN, cSeparator), convert_str_with_exclamation_char_endding(ds.m_strBookSheet));
			///------ End ANALYSIS_OUTPUT_REPORT_SHEET_NAME_SHOULD_BE_EXCLAMATION_CHAR_ENDING
		}
	}
	else
	{
		DataRange	dr;
		int			ii = 0;
		do
		{
			dr = arrOutputs.GetAt(ii++);
		} while ( !dr || dr.GetNumData() <= 0 );
		
		DWORD		dwRules = DRR_NO_FACTORS | DRR_NO_WEIGHTS | DRR_GET_DEPENDENT;
		for ( ii=0; ii<dr.GetNumData(dwRules); ++ii )
		{
			if ( ii >= vsVariableNames[nGoal].GetNumTokens(cSeparator) )
				return;
			
			DataRange	drSub;
			dr.GetSubRange(drSub, dwRules, ii);
			drSub.GetRange(ds, c1, c2);
			///------ Folger 03/26/09 ANALYSIS_OUTPUT_REPORT_SHEET_NAME_SHOULD_BE_EXCLAMATION_CHAR_ENDING
			//LT_set_str(vsVariableNames[nGoal].GetToken(ii, cSeparator), ds.m_strBookSheet);
			LT_set_str(vsVariableNames[nGoal].GetToken(ii, cSeparator), convert_str_with_exclamation_char_endding(ds.m_strBookSheet));
			///------ End ANALYSIS_OUTPUT_REPORT_SHEET_NAME_SHOULD_BE_EXCLAMATION_CHAR_ENDING
		}
	}
}
///------ End OUTPUT_RANGE_LT_STRING_FAILS_TO_UPDATE_WHEN_RUN_PA_WITHOUT_AUTOUPDATE

///---Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK
/*
//################################## PAWizScript #####################################//
class PAWizScript : public XFWizScript
{
protected:
	virtual XFCore*						CreateXFCore();
	virtual XFWizTheme*					CreateXFWizTheme();
	virtual XFWizInputOutputRange*		CreateXFWizInputOutputRange();
	
	//virtual int							UpdateOperation(DWORD dwUIDOp);
};

//virtual
XFCore* PAWizScript::CreateXFCore()
{
	XFCore *p = new PAWizCore;
	return p;
}

//virtual
XFWizTheme* PAWizScript::CreateXFWizTheme()
{
	XFWizTheme *p = new PAWizTheme;
	return p;
}

//virtual
XFWizInputOutputRange* PAWizScript::CreateXFWizInputOutputRange()
{
	XFWizInputOutputRange *p = new XFWizInputOutputRange;
	return p;
}

////virtual
//int PAWizScript::UpdateOperation(DWORD dwUIDOp)
//{
	//return 0;
//}

//################################## PAWizDlg #####################################//
class PAWizDlg : public XFWizDlg
{
protected:
	virtual BOOL 						OnDestroy();

protected:
	virtual bool						CreatePreview(Page& pg);
	
	virtual XFCore*						CreateXFCore();
	virtual XFWizTheme*					CreateXFWizTheme();
	virtual XFWizInputOutputRange*		CreateXFWizInputOutputRange();
	
	//virtual int							UpdateOperation(DWORD dwUIDOp);
	
	///---Sim 10-13-2008 NEW_PA_81_THEME_FILTER_SETTING
	virtual BOOL	IsShowThemeSetting();
	virtual void	ShowThemeSetting();
	virtual bool GetThemeFilterTree(TreeNode& trThemeFilter, TreeNode& trGetN);
	virtual bool SetThemeFilterTree(TreeNode& trThemeFilter, TreeNode& trGetN);
	///---END NEW_PA_81_THEME_FILTER_SETTING
protected:
	GraphPage							m_gpPreview;
};

//virtual
BOOL PAWizDlg::OnDestroy()
{
	///---Sim 10-22-2008 FIX_RECURSIVE_DESTROY_ATTACHED_PAGE_AND_WIZ_DLG
	/#*
	if ( m_gpPreview )
		m_gpPreview.Destroy();
	*#/
	///---END FIX_RECURSIVE_DESTROY_ATTACHED_PAGE_AND_WIZ_DLG
	
	///---Sim 08-21-2008 QA80-12054 CAN_NOT_DELETE_OWN_OBJECT_ON_BASE_CLASS
	//return XFWizDlg::OnDestroy();
	bool bRet = XFWizDlg::OnDestroy();
	///---Sim 10-22-2008 FIX_RECURSIVE_DESTROY_ATTACHED_PAGE_AND_WIZ_DLG
	// should unattach page first, then destroy page will don't affect wizdlg
	if ( m_gpPreview )
		m_gpPreview.Destroy();
	///---END FIX_RECURSIVE_DESTROY_ATTACHED_PAGE_AND_WIZ_DLG
	delete this;
	return bRet;
	///---END QA80-12054 CAN_NOT_DELETE_OWN_OBJECT_ON_BASE_CLASS
}
	
//virtual
bool PAWizDlg::CreatePreview(Page& pg)
{
	/// Iris 11/06/2008 v8.0966b IMPROVE_GET_SOURCE_GRAPH_CODES
	// after create preview graph, input range iy will be changed to active data plot on preview. If want to keep soure data range, need backup original iy before create preivew.
	Array<DataRange&> arrdr;
	m_pXFWizIO->Get(&arrdr, STR_PA_FIRST_XF, true);
	DataRange& drSource = arrdr.GetAt(0);
	
	PAWizCore *pCore = (PAWizCore*)(m_pXFWizDlgNavg->GetXFCore());
	ASSERT(pCore);	
	if( drSource )
	{		
		pCore->SetSourceRange(drSource);
	}
	else		
		error_report("Fail to get source data range in PAWizDlg::CreatePreview");
	///end IMPROVE_GET_SOURCE_GRAPH_CODES
	
	// This code for how to create preview graph page
	m_gpPreview;
	if ( !m_gpPreview.Create("PeakAnalyzerPreview") )
		return false;

	DWORD dwNoClicks = NOCLICK_AXES|NOCLICK_LAYER|NOCLICK_TICKLABEL;
	set_gp_noclick(m_gpPreview, dwNoClicks);
	
	GraphLayer gl = m_gpPreview.Layers(PA_INDEX_ORIGIN_LAYER);
	if( !gl )
		error_report("No Preview Layer!");
	
	
	GraphLayer gl2 = m_gpPreview.Layers(PA_INDEX_PARENT_LAYER);
	
	///Sandy 2008-9-8 Easwar suggested: if the axis is set differently such as log, desending whatever, can we apply same settings to preview
	GraphPage gp = pg;
	if(gp)
	{
		GraphLayer glSource = gp.Layers(-1);
		
		if(glSource.IsValid())
		{
			///Sandy 2008-9-11 Copy axises' format but not the whole layer format
			//Tree tr;
			//tr = glSource.GetFormat(FPB_ALL, FOB_ALL,true, true);
			//gl.UpdateThemeIDs(tr.Root);
			//if(!gl.ApplyFormat(tr, true, true))
				//error_report("copy Layer format fail!");
			//if(!gl2.ApplyFormat(tr, true, true))
				//error_report("copy Layer format fail!");
			
			///Sandy 2008-11-11 centralize code
			copy_xy_axises_format(gl, glSource);
			//Axis xa, ya, xa1, ya1;
			//xa = glSource.XAxis;
			//ya = glSource.YAxis;
			//xa1 = gl.XAxis;
			//ya1 = gl.YAxis;
//
			//Tree trX, trY;
			//trX = xa.GetFormat(FPB_ALL, FOB_ALL,true, true);
			//trY = ya.GetFormat(FPB_ALL, FOB_ALL,true, true);
			//
			//if(!xa1.ApplyFormat(trX, true, true) )
				//error_report("copy axis format fail!");
			//if(!ya1.ApplyFormat(trY, true, true) )
				//error_report("copy axis format fail!");
	}
	

	}
	//end
	if(!copy_xy_axises_format(gl2, gl))
		error_report("Fail to copy the parent plot from original plot!");
	if(!layer_set_link(gl2, PA_INDEX_ORIGIN_LAYER, 1, 1))
		error_report("Fail to set link of Layers!");
	
	pg = m_gpPreview;
	
	return true;
}

//virtual
XFCore* PAWizDlg::CreateXFCore()
{
	XFCore *p = new PAWizCore;
	return p;
}
//virtual
XFWizTheme* PAWizDlg::CreateXFWizTheme()
{
	XFWizTheme *p = new PAWizTheme;
	return p;
}
//virtual
XFWizInputOutputRange* PAWizDlg::CreateXFWizInputOutputRange()
{
	XFWizInputOutputRange *p = new XFWizInputOutputRange;
	return p;
}

////virtual
//int PAWizDlg::UpdateOperation(DWORD dwUIDOp)
//{
	////PFNDoWizOp pfn = GetDoWizOp();
	////if ( pfn )
	////{
		////Tree trTheme;
		////m_pXFWizTheme->GetTree(trTheme);
		////
		////Tree trIOs;
		////m_pXFWizIO->GetTree(trIOs);
		////
		////return pfn(dwUIDOp, trTheme, trIOs, __FILE__, "run_pa_wiz");
	////}
	//
	//return 0;
//}

///---Sim 10-13-2008 NEW_PA_81_THEME_FILTER_SETTING
//virtual
BOOL PAWizDlg::IsShowThemeSetting()
{
	return true;
}
//virtual
void PAWizDlg::ShowThemeSetting()
{
	if ( m_pXFWizTheme )
	{
		//Tree trThemeFilter;
		Tree tmp;
		TreeNode trThemeFilter = tmp.AddNode("trThemeFilter"); // Sim, fix runtime error, I don't know why it was broken for normal tree
		if ( m_pXFWizTheme->GetThemeFilterTree(trThemeFilter) )
		{
			if ( GetNBox(trThemeFilter, _L("Peak Analyzer Theme Setting"), NULL, NULL, NULL, GetSafeHwnd()) )
			{
				m_pXFWizTheme->SetThemeFilterTree(trThemeFilter);
			}
		}
	}
}

//virtual
bool PAWizDlg::GetThemeFilterTree(TreeNode& trThemeFilter, TreeNode& trGetN)
{
	if ( !trThemeFilter )
		return false;
	
	if ( m_pXFWizTheme )
		return m_pXFWizTheme->GetThemeFilterTree(trThemeFilter);
	
	return false;
}
//virtual
bool PAWizDlg::SetThemeFilterTree(TreeNode& trThemeFilter, TreeNode& trGetN)
{
	if ( !trThemeFilter )
		return false;
	
	if ( m_pXFWizTheme )
		return m_pXFWizTheme->SetThemeFilterTree(trThemeFilter);
	
	return false;
}
///---END NEW_PA_81_THEME_FILTER_SETTING
*/
///---Sim 12-09-2008 IMPROVE_XF_WIZ_FRAMEWORK
/*
class PAWizManager : public XFWizManager
{
public:
	PAWizManager(const TreeNode& trThemes = NULL, const TreeNode& trInputsOutputs = NULL, DWORD dwUIDOp = 0);
public:
	virtual void	Destroy();
	virtual bool	CreatePreview(Page& pg);
protected:
	virtual double	GetVersion() {return PA_VERSION_NUMBER;}
	
	virtual XFCore*						CreateXFCore() 					{ return new PAWizCore; }
	virtual XFWizTheme*					CreateXFWizTheme() 				{ return new PAWizTheme; }
	virtual XFWizInputOutputRange*		CreateXFWizInputOutputRange() 	{ return new XFWizInputOutputRange; }
 
	virtual string	GetClassName() { return STR_PA_CLASS_NAME; }
	///---Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK
	//virtual bool	GetOPEntry(string &strFile, string &strFunc) { strFile = GetFileName(__FILE__); strFunc = "run_pa_wiz"; return true; }
	virtual bool	GetOPEntry(string &strFile, string &strFunc) { strFile = GetFileName("PAWiz.c"); strFunc = "run_pa_wiz"; return true; }
	///---END IMPROVE_XF_WIZ_FRAMEWORK
	
protected:
	GraphPage m_gpPreview;
};
*/
///---END IMPROVE_XF_WIZ_FRAMEWORK

///---Sim 01-13-2009 XFWIZ_CHANGE_PARAM_MAY_CHANGE_THEME_AND_IO_RANGE
//PAWizManager::PAWizManager(const TreeNode& trThemes, const TreeNode& trInputsOutputs, DWORD dwUIDOp) // = NULL, NULL, 0
//: PeakWizManager(trThemes, trInputsOutputs, dwUIDOp)
PAWizManager::PAWizManager(LPCSTR lpcszThemeName, const XFWizTheme *pXFWizTheme, const XFWizInputOutputRange *pXFWizIO, DWORD dwUIDOp) // = NULL, NULL, NULL, 0
: XFWizManager(lpcszThemeName, pXFWizTheme, pXFWizIO, dwUIDOp)
///---END XFWIZ_CHANGE_PARAM_MAY_CHANGE_THEME_AND_IO_RANGE
{
	StringArray saMapXFNames = {STR_PA_XFNAME_GOAL, 
								STR_PA_XFNAME_BASEMODE, 
								STR_PA_XFNAME_BASECREATE,
#ifdef PA_WITH_XPS_BASELINE 
								STR_PA_XFNAME_XPS,/////sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE 
#endif
								STR_PA_XFNAME_BASESUBTR,///Sandy 2008-10-16 add
								STR_PA_XFNAME_BASETREAT,
								STR_PA_XFNAME_PEAKS,
								STR_PA_XFNAME_INT,
								STR_PA_XFNAME_FIT
								};
	/* -------Sandy 2008-10-23 string localize function could n't used in constructor
	StringArray saMapXFLabels = {STR_LABEL_XFNAME_GOAL, 
								STR_LABEL_XFNAME_BASEMODE, 
								STR_LABEL_XFNAME_BASECREATE, 
								STR_LABEL_XFNAME_BASESUBTR, ///Sandy 2008-10-16 add
								STR_LABEL_XFNAME_BASETREAT,
								STR_LABEL_XFNAME_PEAK,
								STR_LABEL_XFNAME_INT,
								STR_LABEL_XFNAME_FIT
								};
	*/
	//StringArray saMapXFLabels = {STR_LABEL_XFNAME_GOAL, 
								//STR_LABEL_XFNAME_BASEMODE, 
								//STR_LABEL_XFNAME_BASECREATE, 
//#ifdef PA_WITH_XPS_BASELINE 
								//STR_LABEL_XFNAME_XPS, /////sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE 
//#endif
								//STR_LABEL_XFNAME_BASESUBTR, ///Sandy 2008-10-16 add
								//STR_LABEL_XFNAME_BASETREAT,
								//STR_LABEL_XFNAME_PEAK,
								//STR_LABEL_XFNAME_INT,
								//STR_LABEL_XFNAME_FIT
								//};
	
	// change to this style as _L("string") can't be used to constructor
	StringArray saMapXFLabels;
	saMapXFLabels.Add(STR_LABEL_XFNAME_GOAL);
	saMapXFLabels.Add(STR_LABEL_XFNAME_BASEMODE);	
	saMapXFLabels.Add(STR_LABEL_XFNAME_BASECREATE);
#ifdef PA_WITH_XPS_BASELINE 
	saMapXFLabels.Add(STR_LABEL_XFNAME_XPS);/////sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE 
#endif
	saMapXFLabels.Add(STR_LABEL_XFNAME_BASESUBTR);
	saMapXFLabels.Add(STR_LABEL_XFNAME_BASETREAT);
	saMapXFLabels.Add(STR_LABEL_XFNAME_PEAK);	
	saMapXFLabels.Add(STR_LABEL_XFNAME_INT);
	saMapXFLabels.Add(STR_LABEL_XFNAME_FIT);	
	
	m_saMapXFNames = saMapXFNames;
	m_saMapXFLabels = saMapXFLabels;
	ASSERT( m_saMapXFNames.GetSize() == m_saMapXFLabels.GetSize() );
	
	StringArray saDefaultXFNames = {STR_PA_XFNAME_GOAL,
									STR_PA_XFNAME_BASEMODE,
									//STR_PA_XFNAME_BASECREATE,
									STR_PA_XFNAME_BASETREAT,
									STR_PA_XFNAME_PEAKS,
									STR_PA_XFNAME_INT};
	m_saDefaultXFNames = saDefaultXFNames;
	
	m_strRunDlgName = _L("Peak Analyzer");
}

//virtual
void PAWizManager::Destroy()
{
	if ( m_gpPreview )
		m_gpPreview.Destroy();
	
	PeakWizManager::Destroy();
}

//virtual
bool PAWizManager::CreatePreview(Page& pg)
{
	/// Iris 11/06/2008 v8.0966b IMPROVE_GET_SOURCE_GRAPH_CODES
	// after create preview graph, input range iy will be changed to active data plot on preview. If want to keep soure data range, need backup original iy before create preivew.
	Array<DataRange&> arrdr;
	m_pXFWizIO->Get(&arrdr, STR_PA_FIRST_XF, true);
	DataRange& drSource = arrdr.GetAt(0);
	
	PAWizCore *pCore = (PAWizCore*)m_pXFCore;
	ASSERT(pCore);	
	if( drSource )
	{		
		pCore->SetSourceRange(drSource);
	}
	else		
		error_report("Fail to get source data range in PAWizDlg::CreatePreview");
	///end IMPROVE_GET_SOURCE_GRAPH_CODES
	
	// This code for how to create preview graph page
	m_gpPreview;
	if ( !m_gpPreview.Create("PeakAnalyzerPreview") )
	//	return false;
	{
		error_report("Fail to load the Preview Template of PA!");
		return false;
	}

	DWORD dwNoClicks = NOCLICK_AXES|NOCLICK_LAYER|NOCLICK_TICKLABEL;
	set_gp_noclick(m_gpPreview, dwNoClicks);
	
	GraphLayer gl = m_gpPreview.Layers(PA_INDEX_ORIGIN_LAYER);
	if( !gl )
		error_report("No Preview Layer!");
	
	
	GraphLayer gl2 = m_gpPreview.Layers(PA_INDEX_PARENT_LAYER);
	
	///Sandy 2008-9-8 Easwar suggested: if the axis is set differently such as log, desending whatever, can we apply same settings to preview
	GraphPage gp = pg;
	if(gp)
	{
		GraphLayer glSource = gp.Layers(-1);
		
		if(glSource.IsValid())
		{
			///Sandy 2008-9-11 Copy axises' format but not the whole layer format
			//Tree tr;
			//tr = glSource.GetFormat(FPB_ALL, FOB_ALL,true, true);
			//gl.UpdateThemeIDs(tr.Root);
			//if(!gl.ApplyFormat(tr, true, true))
				//error_report("copy Layer format fail!");
			//if(!gl2.ApplyFormat(tr, true, true))
				//error_report("copy Layer format fail!");
			
			///Sandy 2008-11-11 centralize code
			copy_xy_axises_format(gl, glSource);
			//Axis xa, ya, xa1, ya1;
			//xa = glSource.XAxis;
			//ya = glSource.YAxis;
			//xa1 = gl.XAxis;
			//ya1 = gl.YAxis;
//
			//Tree trX, trY;
			//trX = xa.GetFormat(FPB_ALL, FOB_ALL,true, true);
			//trY = ya.GetFormat(FPB_ALL, FOB_ALL,true, true);
			//
			//if(!xa1.ApplyFormat(trX, true, true) )
				//error_report("copy axis format fail!");
			//if(!ya1.ApplyFormat(trY, true, true) )
				//error_report("copy axis format fail!");
		}
	}
	//end
	////----Sandy 2008-12-5 prepare scale from range if there isn't source graphlayer
	else
	{
		double x1, x2, y1, y2;
		get_data_range_xy_scale(drSource, x1, x2, y1, y2, DRR_GET_DEPENDENT | DRR_NO_FACTORS);
		Scale sX(gl.X);
		Scale sY(gl.Y);
		sX.From = x1 - (x2-x1)*0.1;
		sX.To = x2 +  (x2-x1)*0.1;
		sY.From = y1 - (y2-y1)*0.1;
		sY.To = y2 + (y2-y1)*0.1;
	}
	///----end
	
	
	if(!copy_xy_axises_format(gl2, gl))
		error_report("Fail to copy the parent plot from original plot!");
	if(!layer_set_link(gl2, PA_INDEX_ORIGIN_LAYER, 1, 1))
		error_report("Fail to set link of Layers!");
	
	pg = m_gpPreview;
	
	return true;	
}
///---END IMPROVE_XF_WIZ_FRAMEWORK
///---Sim 12-09-2008 IMPROVE_XF_WIZ_FRAMEWORK
//virtual
double PAWizManager::GetVersion()
{
	return PA_VERSION_NUMBER;
}
//virtual
XFCore* PAWizManager::CreateXFCore()
{
	return new PAWizCore;
}
//virtual
XFWizTheme* PAWizManager::CreateXFWizTheme()
{
	return new PAWizTheme; 
}
//virtual
XFWizInputOutputRange* PAWizManager::CreateXFWizInputOutputRange()
{
	///------ Folger 08/07/09 QA80-13998-P1 OUTPUT_RANGE_LT_STRING_FAILS_TO_UPDATE_WHEN_RUN_PA_WITHOUT_AUTOUPDATE
	//return new XFWizInputOutputRange; 
	return new PAWizInputOutputRange; 
	///------ End OUTPUT_RANGE_LT_STRING_FAILS_TO_UPDATE_WHEN_RUN_PA_WITHOUT_AUTOUPDATE
}
//virtual
string PAWizManager::GetClassName()
{
	return STR_PA_CLASS_NAME; 
}
///---END IMPROVE_XF_WIZ_FRAMEWORK



//################################## PAWizCore #####################################//
PAWizCore::PAWizCore() : FitWizCoreBase()	///Jasmine 11/17/08 v8.0973 CENTRALIZE_FIT_CODE_TO_SHARE_WITH_NANOSIZER
{
	///---Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK
	/*
	StringArray saMapXFNames = {STR_PA_XFNAME_GOAL, 
								STR_PA_XFNAME_BASEMODE, 
								STR_PA_XFNAME_BASECREATE,
#ifdef PA_WITH_XPS_BASELINE 
								STR_PA_XFNAME_XPS,/////sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE 
#endif
								STR_PA_XFNAME_BASESUBTR,///Sandy 2008-10-16 add
								STR_PA_XFNAME_BASETREAT,
								STR_PA_XFNAME_PEAKS,
								STR_PA_XFNAME_INT,
								STR_PA_XFNAME_FIT
								};
	/#* -------Sandy 2008-10-23 string localize function could n't used in constructor
	StringArray saMapXFLabels = {STR_LABEL_XFNAME_GOAL, 
								STR_LABEL_XFNAME_BASEMODE, 
								STR_LABEL_XFNAME_BASECREATE, 
								STR_LABEL_XFNAME_BASESUBTR, ///Sandy 2008-10-16 add
								STR_LABEL_XFNAME_BASETREAT,
								STR_LABEL_XFNAME_PEAK,
								STR_LABEL_XFNAME_INT,
								STR_LABEL_XFNAME_FIT
								};
	*#/
	StringArray saMapXFLabels;
	saMapXFLabels.Add(STR_LABEL_XFNAME_GOAL);
	saMapXFLabels.Add(STR_LABEL_XFNAME_BASEMODE);	
	saMapXFLabels.Add(STR_LABEL_XFNAME_BASECREATE);
#ifdef PA_WITH_XPS_BASELINE 
	saMapXFLabels.Add(STR_LABEL_XFNAME_XPS);/////sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE 
#endif
	saMapXFLabels.Add(STR_LABEL_XFNAME_BASESUBTR);
	saMapXFLabels.Add(STR_LABEL_XFNAME_BASETREAT);
	saMapXFLabels.Add(STR_LABEL_XFNAME_PEAK);	
	saMapXFLabels.Add(STR_LABEL_XFNAME_INT);
	saMapXFLabels.Add(STR_LABEL_XFNAME_FIT);	
	
	SetMapStepLabels(saMapXFNames, saMapXFLabels);
	*/
	///---END IMPROVE_XF_WIZ_FRAMEWORK
	
	/// Iris 11/06/2008 v8.0966b IMPROVE_GET_SOURCE_GRAPH_CODES
	/*
	GraphPage gp = Project.Pages();
	if(gp.IsValid())
	{
		GraphLayer gl = gp.Layers();
		if(gl.IsValid())
			m_glOriginal = gl;
	}
	*/
	///end IMPROVE_GET_SOURCE_GRAPH_CODES
	
	///---Sim 01-12-2009 QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	StringArray vsXFsRecalculateShown = {STR_PA_XFNAME_GOAL};
	m_vsXFsRecalculateShown = vsXFsRecalculateShown;
	///---END QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	
	//SetPeakFitHelper(NULL);		//------ Folger 09/02/08 STORE_PEAK_FIT_HELPER_POINTER_IN_PA_WIZ_CORE
	m_pPeakFitHelper = NULL;
	
	m_bFixBaseParam = true;  //Iris 10/30/2008, From Max, fix baseline parameter as default same as SR4
}
///---Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK
/*
//virtual
string  PAWizCore::GetClassName()
{
	return STR_PA_CLASS_NAME;
}

//virtual
bool PAWizCore::GetDefaultSteps(StringArray &saXFNames)
{
	saXFNames.SetSize(0);
	saXFNames.Add(STR_PA_XFNAME_GOAL);
	saXFNames.Add(STR_PA_XFNAME_BASEMODE);
	//saXFNames.Add(STR_PA_XFNAME_BASECREATE);
	saXFNames.Add(STR_PA_XFNAME_BASETREAT);
	saXFNames.Add(STR_PA_XFNAME_PEAKS);
	saXFNames.Add(STR_PA_XFNAME_INT);
	return true;
}

//virtual
bool  PAWizCore::GetOPEntry(string &strFile, string &strFunc)
{
	///---Sim 11-07-2008 FIX_REOPEN_PA_OPJ_FILE_TO_RECALCULATE
	//strFile = __FILE__;
	strFile = GetFileName(__FILE__); // full path will due to hard code for shard .opj file
	///---END FIX_REOPEN_PA_OPJ_FILE_TO_RECALCULATE
	strFunc = "run_pa_wiz";
	
	return true;
}
*/
//------ Folger 12/30/08 v8.0992 NANOSIZER_USING_NEW_XFWIZARD_FRAMEWORK
/*
bool PAWizCore::GetTargetPage(Page& pg)
{
	XFWizNavigation *pXFWizNavg = (XFWizNavigation *)GetXFWizNavigation();
	if ( !pXFWizNavg )
	{
		ASSERT(FALSE);
		return error_report("Can't get navigation for xfcore");
	}
	
	XFWizInputOutputRange *pIORange = pXFWizNavg->GetXFWizInputOutputRange();
	if ( !pIORange )
	{
		ASSERT(FALSE);
		return error_report("Can't get io range for xfcore");
	}
	
	return pIORange->GetTargetPage(pg);
}
*/
//------ End NANOSIZER_USING_NEW_XFWIZARD_FRAMEWORK
///---END IMPROVE_XF_WIZ_FRAMEWORK


//private

///Sandy 2008-10-16 add insert steps, the insert Steps must leaded by an existing step.
//void PAWizCore::removeSteps(const 	vector<string>& vstrRemoveSteps)
void PAWizCore::updateSteps(const 	vector<string>& vstrRemoveSteps, const vector<string>& vstrInsertSteps)
{
	XFWizNavigation *pXFWizNavg = (XFWizNavigation *)GetXFWizNavigation();
	if(!pXFWizNavg)
	{
		error_report("In PAWizCore::RemoveSteps(), GetXFWizNavigation fail");
		return;
	}
	
	
	if ( pXFWizNavg )
	{
		StringArray saXFNames;
		///--Sandy 2008-10-17 rollback since sim set when apply theme should not remove steps after loading default pathes.
		if( 0>= get_all_steps_from_wizard_navigation(saXFNames, pXFWizNavg))
		{
			error_report("In PAWizCore::RemoveSteps(), step-list is empty or invalid!");
			return;
		}
		//getDefaultPathsByGoal(saXFNames);
		//--end
		////remove
		for(int ii=0; ii<vstrRemoveSteps.GetSize(); ii++)
		{
			vector<int> vnFoundIndex;
			int nFound = saXFNames.Find(vstrRemoveSteps[ii]);
			if(nFound>=0)
			{
				int nRemoveAtStep = (nFound);// nFound is 1 offset of the array
				
				//only allow remove the step after current and before the end
				if( nRemoveAtStep <= pXFWizNavg->GetStep() || nRemoveAtStep > pXFWizNavg->GetNumSteps())
					continue;
	
				saXFNames.RemoveAt(nRemoveAtStep);		
			}
		}
		
		////Sandy 2008-10-16 Insert step after one existing step and skip the duplicate step
		if(vstrInsertSteps.GetSize()>0)
		{
			for(int ii = 0; ii<saXFNames.GetSize(); ii++)
			{
				if( 0 == lstrcmp(saXFNames[ii],  vstrInsertSteps[0]) )
				{
					int nCount = 1;
					for(int jj= 1; jj < vstrInsertSteps.GetSize(); jj++)
					{
						
						if( !((ii+jj)<saXFNames.GetSize() && 0 == lstrcmp(saXFNames[ii+jj],  vstrInsertSteps[jj])) )
							if(0>=saXFNames.Find(vstrInsertSteps[jj]))//skip the duplicate step
							{
								saXFNames.InsertAt(ii+nCount, vstrInsertSteps[jj]);
								nCount++;
							}
					}
					break;
				}
			}
		}
		
		pXFWizNavg->SetSteps(saXFNames);
		
		///---Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK
		/*
		try
		{
		XFWizDlgNavigation *pXFWizDlgNavg = (XFWizDlgNavigation *)pXFWizNavg;
		if ( pXFWizDlgNavg )
			pXFWizDlgNavg->UpdateWizardControl();
		}
		catch( int nErr )
		{
			// Sim, 11-13-2008, Need to DEBUG in VC.
			// After (and On) IR969, it go to here as Class Casting cause rumtime error
			// Before IR969, no rumtime error, maybe no invoked this function without dialog
		}
		*/
		///---Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK
	}
}

///---Sim 06-23-2009 NANOSIZER_WIZ_AUTO_UPDATE_SUPPORT
// move to FitWizBaseCore.c
/*
Worksheet PAWizCore::CheckGetInterimResult(string strInterimSheet)
{
	
	if ( !m_wpInterim )
	{
		string strPageName = _STR_TEMP_PA_WKS_PAGE_NAME + (string)m_nInstanceID;
		WorksheetPage wp(strPageName);
		if(!wp.IsValid())
		{
#ifdef _DEBUG
			wp.Create("Origin",  CREATE_HIDDEN);
#else
			wp.Create("Origin",  CREATE_HIDDEN|CREATE_SET_MISSING_IN_MANAGER);
#endif			
			wp.Rename(strPageName);
		}
		m_wpInterim = wp;
	}
	
	Worksheet wks = m_wpInterim.Layers(strInterimSheet);	
	if(!wks)
	{
		int nSheet = m_wpInterim.AddLayer(strInterimSheet);	
		wks = m_wpInterim.Layers(nSheet);
	}
	
	return wks;
		
}
*/
// virtual
string PAWizCore::GetTempBookPrefix()
{
	return _STR_TEMP_PA_WKS_PAGE_NAME;
}
///---END NANOSIZER_WIZ_AUTO_UPDATE_SUPPORT

void PAWizCore::getDefaultPathsByGoal(StringArray& saXFNames)
{
	saXFNames.SetSize(0);
	saXFNames.Add(STR_PA_XFNAME_GOAL);
	
	///Sandy 2008-9-5 modify xf label when goal change
	StringArray saMapXFLabels;  
	saMapXFLabels.Add(STR_LABEL_XFNAME_GOAL);
	//end 
	switch (m_nGoal)
	{
	case PA_GOAL_INTEGRATE_PEAK:
		saXFNames.Add( STR_PA_XFNAME_BASEMODE);
		//saXFNames.Add( STR_PA_XFNAME_BASECREATE);
		saXFNames.Add( STR_PA_XFNAME_BASETREAT);
		saXFNames.Add( STR_PA_XFNAME_PEAKS);
		saXFNames.Add( STR_PA_XFNAME_INT);
		
		/*
		///Sandy 2008-9-5 modify xf label when goal change
		saMapXFLabels.Add( STR_LABEL_XFNAME_BASEMODE);
		saMapXFLabels.Add( STR_LABEL_XFNAME_BASECREATE);
		saMapXFLabels.Add( STR_LABEL_XFNAME_BASETREAT);
		saMapXFLabels.Add( STR_LABEL_XFNAME_PEAK);
		saMapXFLabels.Add( STR_LABEL_XFNAME_INT);
		//end
		*/
		break;
	case PA_GOAL_CREATE_BASELINE:
		saXFNames.Add(STR_PA_XFNAME_BASEMODE);
		saXFNames.Add(STR_PA_XFNAME_BASECREATE);
		/*
		///Sandy 2008-9-5 modify xf label when goal change
		saMapXFLabels.Add( STR_LABEL_XFNAME_BASEMODE);
		saMapXFLabels.Add( STR_LABEL_XFNAME_BASECREATE);
		//end
		*/
		break;
	case PA_GOAL_SUBTRACT_BASELINE://sandy add 2008-10-16
		saXFNames.Add(STR_PA_XFNAME_BASEMODE);
		//saXFNames.Add(STR_PA_XFNAME_BASECREATE);
		saXFNames.Add(STR_PA_XFNAME_BASESUBTR);
		
		/*
		saMapXFLabels.Add( STR_LABEL_XFNAME_BASEMODE);
		saMapXFLabels.Add( STR_LABEL_XFNAME_BASECREATE);
		saMapXFLabels.Add( STR_LABEL_XFNAME_BASESUBTR);
		*/
		break;
		
	case PA_GOAL_FIND_PEAK:
		saXFNames.Add(STR_PA_XFNAME_BASEMODE);
		//saXFNames.Add(STR_PA_XFNAME_BASECREATE);
		saXFNames.Add(STR_PA_XFNAME_BASETREAT);
		saXFNames.Add(STR_PA_XFNAME_PEAKS);
		
		/*
		///Sandy 2008-9-5 modify xf label when goal change
		saMapXFLabels.Add( STR_LABEL_XFNAME_BASEMODE);
		saMapXFLabels.Add( STR_LABEL_XFNAME_BASECREATE);
		saMapXFLabels.Add( STR_LABEL_XFNAME_BASETREAT);
		saMapXFLabels.Add( STR_LABEL_XFNAME_PEAK);
		//end
		*/
		break;
		
	case PA_GOAL_FIT_PEAK:	
		saXFNames.Add( STR_PA_XFNAME_BASEMODE);
		//saXFNames.Add( STR_PA_XFNAME_BASECREATE);
		saXFNames.Add( STR_PA_XFNAME_BASETREAT);
		saXFNames.Add( STR_PA_XFNAME_PEAKS);
		//saXFNames.Add( STR_PA_XFNAME_INT);//Sandy 2008-9-5 add rectangles to extract data while baseline mode is local baseline
		saXFNames.Add( STR_PA_XFNAME_FIT);	
		
		/*
		///Sandy 2008-9-5 modify xf label when goal change
		saMapXFLabels.Add( STR_LABEL_XFNAME_BASEMODE);
		saMapXFLabels.Add( STR_LABEL_XFNAME_BASECREATE);
		saMapXFLabels.Add( STR_LABEL_XFNAME_BASETREAT);
		saMapXFLabels.Add( STR_LABEL_XFNAME_PEAK);
		//saMapXFLabels.Add( STR_LABEL_XFNAME_REG);//Sandy 2008-9-5 add rectangles to extract data while baseline mode is local baseline
		saMapXFLabels.Add( STR_LABEL_XFNAME_FIT);
		//end
		*/
		break;
	}
	
	///------Sandy 2008-10-16 since no label need change for a same xf, so always use the map of beginning
	///Sandy 2008-9-5 modify xf label when goal change
	//SetMapStepLabels(saXFNames, saMapXFLabels);
	//end
	//------end
}

void PAWizCore::ChangeGoal(int nGoal)
{
	XFWizNavigation *pXFWizNavg = (XFWizNavigation *)GetXFWizNavigation();
	ASSERT(pXFWizNavg);
	
	if ( pXFWizNavg )
	{
		m_nGoal = nGoal;
		StringArray saXFNames;
		getDefaultPathsByGoal(saXFNames);
	
		pXFWizNavg->SetSteps(saXFNames);
		
		///---Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK
		/*
		XFWizDlgNavigation *pXFWizDlgNavg = (XFWizDlgNavigation *)pXFWizNavg;
		if ( pXFWizDlgNavg )
			pXFWizDlgNavg->UpdateWizardControl();
		*/
		///---END IMPROVE_XF_WIZ_FRAMEWORK
	}
}

bool PAWizCore::GetSteps(vector<string> &vsXFNames, vector<string> &vsXFLabels)
{
	XFWizNavigation *pXFWizNavg = (XFWizNavigation *)GetXFWizNavigation();
	ASSERT(pXFWizNavg);
	
	if ( !pXFWizNavg )
		return error_report("In PAWizCore::GetSteps(), fail to get XFWizNavigation object!");
	
	if( 0 >= get_all_steps_from_wizard_navigation(vsXFNames, pXFWizNavg))
	{
		return error_report("In PAWizCore::GetSteps(), step-list is empty or invalid!");
	}	
	
	//return GetStepLabels(vsXFNames, vsXFLabels);	
	return pXFWizNavg->GetStepLabels(vsXFNames, vsXFLabels);
}
//bool PAWizCore::GetStepLabels(const StringArray& saXFNames, StringArray& saXFLables)
//{
	////Sim, need to do
	//saXFLables = saXFNames; // temporary behavior
	//return true;
//}

int PAWizCore::GetBaseModeList(vector<int>& vnBaseModeList, string& strComboList)
{
	vnBaseModeList.SetSize(0);
	
	switch(m_nGoal)
	{
	case PA_GOAL_CREATE_BASELINE:
	{
		if(strComboList != NULL)
			
			///---Sandy 2008-12-30 Greg suggested add xps baseline when create baseline
			//strComboList =  _L("User Defined");
#ifdef PA_WITH_XPS_BASELINE 
			strComboList =  _L("User Defined|XPS");
#else
			strComboList =  _L("User Defined");	
#endif
			//--- end 
			
		vnBaseModeList.Add(PA_BM_USERDEF);
		
			///---Sandy 2008-12-30 Greg suggested add xps baseline when create baseline
#ifdef PA_WITH_XPS_BASELINE 
		vnBaseModeList.Add(PA_BM_XPS);///Sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE
#endif
			//--- end
	
	}
		break;
	case PA_GOAL_INTEGRATE_PEAK:
		if(strComboList != NULL)
		{
		
#ifdef PA_WITH_XPS_BASELINE 
			//strComboList =  _L("Constant|User Defined|Use Existing Dataset|Local Baseline|XPS|None");///Sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE
			strComboList =  _L("Constant|User Defined|Use Existing Dataset|XPS|None");///Sandy 2009-2-12 REMOVE_LOCAL_BASELINE_TEMP_FOR_SR5_RELEASE
#else
			//strComboList =  _L("Constant|User Defined|Use Existing Dataset|Local Baseline|None");///Sandy 2009-2-12 REMOVE_LOCAL_BASELINE_TEMP_FOR_SR5_RELEASE
			strComboList =  _L("Constant|User Defined|Use Existing Dataset|None");
#endif			
		}
		vnBaseModeList.Add(PA_BM_CONSTANT);
		vnBaseModeList.Add(PA_BM_USERDEF);
		vnBaseModeList.Add(PA_BM_USE_EX);
		//vnBaseModeList.Add(PA_BM_LOCAL);	///Sandy 2009-2-12 REMOVE_LOCAL_BASELINE_TEMP_FOR_SR5_RELEASE	

#ifdef PA_WITH_XPS_BASELINE 
		vnBaseModeList.Add(PA_BM_XPS);///Sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE
#endif
		vnBaseModeList.Add(PA_BM_None);
		break;
	
	case PA_GOAL_SUBTRACT_BASELINE:
		if(strComboList != NULL)
		{
#ifdef PA_WITH_XPS_BASELINE 
			strComboList =  _L("Constant|User Defined|Use Existing Dataset|XPS");///Sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE
#else
			strComboList =  _L("Constant|User Defined|Use Existing Dataset");
#endif
		}
		vnBaseModeList.Add(PA_BM_CONSTANT);
		vnBaseModeList.Add(PA_BM_USERDEF);
		vnBaseModeList.Add(PA_BM_USE_EX);
#ifdef PA_WITH_XPS_BASELINE 
		vnBaseModeList.Add(PA_BM_XPS);///Sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE
#endif
		break;
	case PA_GOAL_FIND_PEAK:
	case PA_GOAL_FIT_PEAK:	
		if(strComboList != NULL)
		{
#ifdef PA_WITH_XPS_BASELINE 
			strComboList = _L("Constant|User Defined|Use Existing Dataset|XPS|None");///Sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE
#else
			strComboList = _L("Constant|User Defined|Use Existing Dataset|None");
#endif
		}
		vnBaseModeList.Add(PA_BM_CONSTANT);
		vnBaseModeList.Add(PA_BM_USERDEF);
		vnBaseModeList.Add(PA_BM_USE_EX);
#ifdef PA_WITH_XPS_BASELINE 
		vnBaseModeList.Add(PA_BM_XPS);///Sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE
#endif
		vnBaseModeList.Add(PA_BM_None);
		break;
	default:
		break;
	}

	return vnBaseModeList.GetSize();
}

void PAWizCore::ChangeBaseMode(int nBaseMode)
{

	vector<string> vstrRemoveSteps;
	vector<string> vstrInsertSteps;
	switch(nBaseMode)
	{
	case PA_BM_USE_EX:
	case PA_BM_CONSTANT:
		
		vstrInsertSteps.Add( STR_PA_XFNAME_BASEMODE);
		if(m_nGoal != PA_GOAL_SUBTRACT_BASELINE)
			vstrInsertSteps.Add( STR_PA_XFNAME_BASETREAT);

#ifdef PA_WITH_XPS_BASELINE 
		vstrRemoveSteps.Add( STR_PA_XFNAME_XPS);//Sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE	
#endif
		vstrRemoveSteps.Add( STR_PA_XFNAME_BASECREATE);	
		break;
	
	case PA_BM_LOCAL:
	case PA_BM_None:

#ifdef PA_WITH_XPS_BASELINE 
		vstrRemoveSteps.Add( STR_PA_XFNAME_XPS);//Sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE	
#endif
		vstrRemoveSteps.Add(STR_PA_XFNAME_BASECREATE);
		vstrRemoveSteps.Add( STR_PA_XFNAME_BASETREAT);
		break;
	case PA_BM_USERDEF:///Sandy 2008-10-16 add since the current list isn't default pathes.
		
		vstrInsertSteps.Add( STR_PA_XFNAME_BASEMODE);
		vstrInsertSteps.Add( STR_PA_XFNAME_BASECREATE);
		
		if(m_nGoal != PA_GOAL_CREATE_BASELINE && m_nGoal != PA_GOAL_SUBTRACT_BASELINE)
			vstrInsertSteps.Add(STR_PA_XFNAME_BASETREAT);
#ifdef PA_WITH_XPS_BASELINE 		
		vstrRemoveSteps.Add( STR_PA_XFNAME_XPS);//Sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE	
#endif
		break;
		
#ifdef PA_WITH_XPS_BASELINE 
	//Sandy 2008-11-4 QA80-12518 v8.0965 BRING_BACK_SPECIAL_BASELINE	
	case PA_BM_XPS:
		vstrInsertSteps.Add( STR_PA_XFNAME_BASEMODE);
		vstrInsertSteps.Add( STR_PA_XFNAME_XPS);
		
		vstrRemoveSteps.Add( STR_PA_XFNAME_BASECREATE);	
		
		if(m_nGoal != PA_GOAL_CREATE_BASELINE && m_nGoal != PA_GOAL_SUBTRACT_BASELINE)
			vstrInsertSteps.Add(STR_PA_XFNAME_BASETREAT);
		
	
		break;	
#endif
	default:
		break;
	}
	
	updateSteps(vstrRemoveSteps, vstrInsertSteps);
	m_nBaseMode = nBaseMode;
}

/// Iris 11/06/2008 v8.0966b IMPROVE_GET_SOURCE_GRAPH_CODES
/*
bool PAWizCore::GetSourceRange(DataRange& drSource)
{ 
	if( !m_drSource )
		return false;
	drSource = m_drSource;
	return true;
}
*/
virtual bool PAWizCore::GetSourceRange(DataRange& drSource)
{	
	//---Jasmine 11/17/08 v8.0973 CENTRALIZE_FIT_CODE_TO_SHARE_WITH_NANOSIZER
	if( !FitWizCoreBase::GetSourceRange(drSource) )
	//---
	{
		XFWizInputOutputRange	*pIORange = getIORange();
		if(!pIORange)
		{
			return error_report("invalid input output range in FitWizCoreBase!");
		}
		Array<DataRange&> arrdr;
		if ( pIORange->Get(&arrdr, STR_PA_FIRST_XF, true) )
			drSource = arrdr.GetAt(0);
		else
			return error_report("invalid input output range in FitWizCoreBase!");
	}
	
	return drSource.IsValid();
}	
///end IMPROVE_GET_SOURCE_GRAPH_CODES	

bool PAWizCore::GetOriginalRange(XYRange& xyOrigin)
{
	if(!m_xyOriginal || !m_xySource)
	{
	if(!getContextRange(xyOrigin, STR_PA_XFNAME_GOAL, true))
		return false;
	
	if(!xyOrigin.IsValid())
		return false;
	m_xyOriginal = xyOrigin;
		m_xySource = xyOrigin;//Sandy 2008-11-4 Iris need a really born input range without any change(after plot)
	m_nInstanceID = xyOrigin.GetUID(true);
	}
	
	xyOrigin = m_xyOriginal;
	return true;
		
}
bool PAWizCore::GetBaseAnchorsRange(XYRange& xyAnchors)
{
	if(!m_xyBaseAnchors)
	{
		Worksheet wks = CheckGetInterimResult(_PA_BASELINE_ANCHORS_WKS_NAME);
	
		m_xyBaseAnchors.Add(wks, 0, "X");
		m_xyBaseAnchors.Add(wks, 1, "Y");	
	}
	xyAnchors = m_xyBaseAnchors;
	return xyAnchors.IsValid();
}	
bool PAWizCore::GetBaselineRange(XYRange& xyBaseline)
{
	if(!m_xyBaseline)
	{
		Worksheet wks = CheckGetInterimResult(_PA_BASELINE_WKS_NAME);

		m_xyBaseline.Add(wks, 0, "X");
		m_xyBaseline.Add(wks, 1, "Y");	
	}
	xyBaseline = m_xyBaseline;
	return xyBaseline.IsValid();
}

bool PAWizCore::GetLocalBaselineRange(XYRange& xyLocalBaseline, int nIndex, int& nCurrNum)
{
	if(nIndex<1)
		return false;
	
	Worksheet wks = CheckGetInterimResult(_PA_LOCAL_BASELINE_WKS_NAME);
	
	if(wks.GetNumCols()<nIndex*2)
		wks.SetSize(-1, nIndex*2);

	xyLocalBaseline.Add(wks, (nIndex-1)*2, "X");
	xyLocalBaseline.Add(wks, (nIndex-1)*2+1, "Y");
	
	if(nCurrNum!=NULL)
		nCurrNum = (wks.GetNumCols()/2);

	return xyLocalBaseline.IsValid();
}
///Sophy 11/12/2008 SUPPORT_USE_EXISTING_DATARANGE_AS_BASELINE_IN_NEW_PA
bool	PAWizCore::GetExistingBaselineRange(XYRange& xyExistBaseline )
{
	xyExistBaseline = m_xyExistBaseline;
	return xyExistBaseline.IsValid();
}
bool	PAWizCore::SetExistingBaselineRange(XYRange& xyExistBaseline )
{
	m_xyExistBaseline = xyExistBaseline;
	return m_xyExistBaseline.IsValid();
}
///end SUPPORT_USE_EXISTING_DATARANGE_AS_BASELINE_IN_NEW_PA
bool PAWizCore::GetSubtractedRange(XYRange& xySubtracted)
{
	///Sandy 2008-11-18 This usage has been removed by kyle
	///Sandy 2008-10-24 add. When goal for fitting, the subtracted range should take from a visible datasheet
	//if(m_wksOutSubtracted && m_xyOutSubtracted)
	//{
		//xySubtracted = m_xyOutSubtracted;
		//return true;
	//}	
	
	vector vx, vy;
	if(!m_xySubtracted)
	{
	
		Worksheet wks = CheckGetInterimResult(_PA_SUBTRACTED_WKS_NAME);
		m_xySubtracted.Add(wks, 0, "X");
		m_xySubtracted.Add(wks, 1, "Y");	
		
	}
	xySubtracted = m_xySubtracted;
	return xySubtracted.IsValid();
}

///Kyle 11/17/2008 SUBTRACTED_DATA_IS_STORED_IN_TEMPORARY_WORKSHEET
////----Sandy 2008-10-24 if goal = fit peaks, the subtracted data should output to the source page and take as input of fitting
//bool PAWizCore::UpdateSubtractedDataToSourcePage(bool bDestroy)
//{
	//if(bDestroy)
	//{
		//m_xyOutSubtracted.Destroy();
		//if(!m_wksOutSubtracted)
		//{
			//error_report("Invalid output workseet!");
			//return false;
		//}
		//m_wksOutSubtracted.Destroy();
	//}
	//else
	//{
		//if(!m_wksOutSubtracted)
		//{
			//Worksheet wks;
			//int r1, c1, r2, c2;
			//m_xyOriginal.GetRange(0, r1, c1, r2, c2, wks);			
			//if(!wks)
			//{
				//error_report("Invalid original input workseet!");
				//return false;
			//}
			//WorksheetPage wkp = wks.GetPage();
			//if(!wkp)
			//{
				//error_report("Invalid original input workseet page!");
				//return false;
			//}
			//int nLayer = wkp.AddLayer(_PA_SUBTRACTED_OUT_WKS_NAME);
			//if(nLayer<0)
			//{
				//error_report("Invalid new workseet!");
				//return false;
			//}
			//m_wksOutSubtracted = wkp.Layers(nLayer);
			//if(!m_wksOutSubtracted)
			//{
				//error_report("Invalid new workseet!");
				//return false;
			//}
		//}
		//m_wksOutSubtracted.SetSize( -1, 2);
		//
		//m_xyOutSubtracted.Add(m_wksOutSubtracted, 0, "X");
		//m_xyOutSubtracted.Add(m_wksOutSubtracted, 1, "Y");	
		//
		//
		//vector vx, vy;
		//if(!m_xySubtracted || !m_xySubtracted.GetData(vy,vx) || vx.GetSize() == 0 )
		//{
			//error_report("Invalid Subtracted Range!");
			//return false;
		//}
		//m_xyOutSubtracted.SetData(&vy,&vx);
		//
	//}
	//return true;
//}
///End SUBTRACTED_DATA_IS_STORED_IN_TEMPORARY_WORKSHEET

bool PAWizCore::GetPeaksRange(XYRange& xyPeaks)
{
	
	if(!m_xyPeaks)
	{
		
		Worksheet wks = CheckGetInterimResult(_PA_PEAKS_WKS_NAME);
		if(!wks)
			return false;
		m_xyPeaks.Add(wks, 0, "X");
		m_xyPeaks.Add(wks, 1, "Y");	
		
		vector vx, vy;
		
		if(m_bHasSubtracted)
		{
			if(!m_xySubtracted)
				return false;
			//m_xyPeaks = m_xySubtracted;
			
			m_xySubtracted.GetData(vy, vx);
			m_xyPeaks.SetData(&vy, &vx,  0, NULL, DRS_SET_COL_DESIGNATIONS);
		}
		else
		{
			vector vxTemp, vyTemp;
			m_xyOriginal.GetData(vy, vx);
			
			vxTemp = vx;
			vyTemp = vy;
				
			if(m_xyBaseline.IsValid())//has baseline but no subtract
			{
				vector vbx, vby;
				if(m_xyBaseline.GetData(vby, vbx))
				{
					subtract_baseline(vxTemp, vyTemp, vbx, vby);
				}		
			}		
	
			m_xyPeaks.SetData(&vyTemp, &vxTemp,  0, NULL, DRS_SET_COL_DESIGNATIONS);
		}

	}	
	


	xyPeaks = m_xyPeaks;
	return xyPeaks.IsValid();
}
bool PAWizCore::GetPeaksCenterRange(XYRange& xyPeaksCenter)
{
	if(!m_xyPeaksCenter)
	{
		Worksheet wks = CheckGetInterimResult(_PA_PEAKS_CENTER_WKS_NAME);

		Column colX(wks, PA_PEAKSINFO_SHEET_PK_XCOL);
		Column colY(wks, PA_PEAKSINFO_SHEET_PK_YCOL);
		
		//Sandy 2008-9-12 remove L col for PeaksCenter, and replace with label plot of #12141 
		//Column colLabel(wks, PA_PEAKSINFO_SHEET_PK_LABELCOL);
		//if ( !colLabel )
		//{
			//if ( wks.SetSize(-1, PA_PEAKSINFO_SHEET_PK_LABELCOL + 1) )
			//{
				//colLabel = wks.Columns(PA_PEAKSINFO_SHEET_PK_LABELCOL);
				//colLabel.SetType(OKDATAOBJ_DESIGNATION_L);
				//colLabel.SetLongName(_L("Label"));
				//colLabel.SetComments(_L("Peak"));
			//}
		//}
		
		//if ( !colX || !colY || !colLabel )
		if ( !colX || !colY )
			return false;	
								     
		m_xyPeaksCenter.Add("X", wks, 0, PA_PEAKSINFO_SHEET_PK_XCOL, -1, PA_PEAKSINFO_SHEET_PK_XCOL);
		m_xyPeaksCenter.Add("Y", wks, 0, PA_PEAKSINFO_SHEET_PK_YCOL, -1, PA_PEAKSINFO_SHEET_PK_YCOL);
		//m_xyPeaksCenter.Add("L", wks, 0, PA_PEAKSINFO_SHEET_PK_LABELCOL, -1, PA_PEAKSINFO_SHEET_PK_LABELCOL);
		//end of Sandy 2008-9-12
		
	}
	xyPeaksCenter = m_xyPeaksCenter;
	return xyPeaksCenter.IsValid();
}			
bool PAWizCore::GetPeaksMarkerRange(XYRange& xyPeaksMarker)
{
	if(!m_xyPeaksMarker)
	{
		Worksheet wks = CheckGetInterimResult(_PA_PEAKS_MARKER_WKS_NAME);

		Column colX(wks, PA_PEAKSINFO_SHEET_PK_XCOL);
		Column colY(wks, PA_PEAKSINFO_SHEET_PK_YCOL);
		//Column colLabel(wks, PA_PEAKSINFO_SHEET_PK_LABELCOL);
		//if ( !colLabel )
		//{
			//if ( wks.SetSize(-1, PA_PEAKSINFO_SHEET_PK_LABELCOL + 1) )
			//{
				//colLabel = wks.Columns(PA_PEAKSINFO_SHEET_PK_LABELCOL);
				//colLabel.SetType(OKDATAOBJ_DESIGNATION_L);
				//colLabel.SetLongName(_L("Label"));
				//colLabel.SetComments(_L("PeakMarker"));
			//}
		//}
		
		if ( !colX || !colY )//|| !colLabel )
			return false;	
								     
		m_xyPeaksMarker.Add("X", wks, 0, PA_PEAKSINFO_SHEET_PK_XCOL, -1, PA_PEAKSINFO_SHEET_PK_XCOL);
		m_xyPeaksMarker.Add("Y", wks, 0, PA_PEAKSINFO_SHEET_PK_YCOL, -1, PA_PEAKSINFO_SHEET_PK_YCOL);
		//m_xyPeaksMarker.Add("L", wks, 0, PA_PEAKSINFO_SHEET_PK_LABELCOL, -1, PA_PEAKSINFO_SHEET_PK_LABELCOL);
		
	}
	xyPeaksMarker = m_xyPeaksMarker;
	return xyPeaksMarker.IsValid();
}

bool	PAWizCore::CleanUpContextRange(int nContextRange)
{
	vector vEmpty;
	switch(nContextRange)
	{
	case PA_DR_BASEANCHORS:
		if(m_xyBaseAnchors)
		{
			m_xyBaseAnchors.SetData(&vEmpty, &vEmpty , 0, NULL, DRS_SET_COL_DESIGNATIONS);
			m_xyBaseAnchors.Destroy();
		}

		break;
	case PA_DR_BASELINE:
		if(m_xyBaseline)
		{
			m_xyBaseline.SetData(&vEmpty, &vEmpty , 0, NULL, DRS_SET_COL_DESIGNATIONS);
			m_xyBaseline.Destroy();
		}

		break;
	case PA_DR_SUBTRACTED:
		if(m_xySubtracted)
		{
			m_xySubtracted.SetData(&vEmpty, &vEmpty , 0, NULL, DRS_SET_COL_DESIGNATIONS);
			m_xySubtracted.Destroy();

		}

		break;
	case PA_DR_PEAKSRANGE:
		if(m_xyPeaks)
		{
			m_xyPeaks.SetData(&vEmpty, &vEmpty , 0, NULL, DRS_SET_COL_DESIGNATIONS);
			m_xyPeaks.Destroy();
		}

		break;
	case PA_DR_PEAK_CENTERS:
		if(m_xyPeaksCenter)
		{
			m_xyPeaksCenter.SetData(&vEmpty, &vEmpty , 0, NULL, DRS_SET_COL_DESIGNATIONS);
			m_xyPeaksCenter.Destroy();
		}

		break;
	case PA_DR_PEAK_MARKERS:
		if(m_xyPeaksMarker)
		{
			m_xyPeaksMarker.SetData(&vEmpty, &vEmpty , 0, NULL, DRS_SET_COL_DESIGNATIONS);
			m_xyPeaksMarker.Destroy();
		}

		break;
	case PA_DRS_LOCAL_BASELINE:
		Worksheet wks = CheckGetInterimResult(_PA_LOCAL_BASELINE_WKS_NAME);
		if( wks )
			wks.Destroy();
	default:
		return false;
	}
	
	return true;
}


bool PAWizCore::UpdateInfoTree(TreeNode& tr, int nTreeID, bool bSet)
{
	if(bSet && !tr)
		return false;	
		
	switch(nTreeID)
	{
	case PA_TREE_BASELINE_FIT_INFO:
		if(bSet)
			m_trBaselineFitInfo = tr.Clone(true);
		else
			tr = m_trBaselineFitInfo;
		break;
	case PA_TREE_PEAKS_CENTER_INFO:
		if(bSet)
			m_trPeaksCenterInfo = tr.Clone(true);
		else
			tr = m_trPeaksCenterInfo;
		break;
	default:
		return false;
	}
	
	/// Iris 4/09/2009 FAIL_GET_BASELINE_PARAM_IN_SCRIPT_MODE
	if( !bSet && !tr )
		return false;
	///end FAIL_GET_BASELINE_PARAM_IN_SCRIPT_MODE
	
	return true;
}

///Sandy 2008-10-23 add for output "[<input>]<new>" ReportData to source wks page
void PAWizCore::SetOriginalRangeToGetN(TreeNode& trInput)
{
	if(!m_xyOriginal.IsValid())
	{
		error_report("Invalid Original Range in PA!");
		return;
	}

	if(!construct_tree_from_xyrange(trInput, m_xyOriginal))
		error_report("Fail in construct original input range!");

}

//------ Folger 09/02/08 STORE_PEAK_FIT_HELPER_POINTER_IN_PA_WIZ_CORE
//void				PAWizCore::SetPeakFitHelper(PeakFitHelper *pPeakFitHelper)
//{
	//m_pPeakFitHelper = pPeakFitHelper;
//}
PeakFitHelper*		PAWizCore::CheckGetPeakFitHelper()
{
	if ( m_pPeakFitHelper == NULL )
		/// Iris 9/18/2008 NEED_ACCESS_PAWIZCORE_IN_PEAKFITHELPER
		//m_pPeakFitHelper = new PeakFitHelper();
		m_pPeakFitHelper = new PeakFitHelper(this);
		///end NEED_ACCESS_PAWIZCORE_IN_PEAKFITHELPER
	
	return m_pPeakFitHelper;
}
//------ End STORE_PEAK_FIT_HELPER_POINTER_IN_PA_WIZ_CORE

enum
{
	PA_INDEX_ORIGIN_LAYER = 0,
	PA_INDEX_PARENT_LAYER
};
bool	PAWizCore::GetPreviewLayer(GraphLayer& gl , bool bSetActive)
{
	if (!(m_dwXFMode & LTXF_SHOW_DIALOG))
		return false;
	
	GraphPage gp;
	if(!GetTargetPage(gp) || !gp)
		return false;
	
	int nIndexActivate, nIndexHide;
	if(m_bHasSubtracted)
	{
		nIndexActivate 	= PA_INDEX_PARENT_LAYER;
		nIndexHide 		= PA_INDEX_ORIGIN_LAYER;
	}
	else
	{
		nIndexActivate 	= PA_INDEX_ORIGIN_LAYER;
		nIndexHide 		= PA_INDEX_PARENT_LAYER;
	}
	
	gl = gp.Layers(nIndexActivate);
	if(bSetActive)
	{
		GraphLayer glHide = gp.Layers(nIndexHide);
		glHide.Show(false);
		
		gl.Show(true);
		if( !page_set_active_layer(gp, nIndexActivate, false) )
			error_report("PAWizCore::In GetPreviewLayer(), set active layer fail!");
	}
	return gl.IsValid();
	
}
/// Iris 11/01/2008 v8.0964 NEW_PA_SUPPORT_CREATE_REPORT_GRAPH_ON_SOURCE

bool PAWizCore::GetSourceDataPlot(DataPlot& dp)
{
	XYRange drSource;
	if( !GetSourceRange(drSource) || !drSource )
		return error_report("Fail to get source data range");
	
	if( !drSource.GetPlot(dp) ) 
		return false;
	
	return true; 
}
///end NEW_PA_SUPPORT_CREATE_REPORT_GRAPH_ON_SOURCE

/// Iris 11/06/2008 v8.0966b IMPROVE_GET_SOURCE_GRAPH_CODES
bool PAWizCore::GetSourceGraph(GraphLayer& glSource)
{
	DataPlot dp;
	if( !GetSourceDataPlot(dp) )
		return false;
	
	dp.GetParent(glSource);
	return glSource.IsValid();
}
///end IMPROVE_GET_SOURCE_GRAPH_CODES

void PAWizCore::~PAWizCore()
{	
	///---Sim 06-23-2009 NANOSIZER_WIZ_AUTO_UPDATE_SUPPORT
	// move to FitWizBaseCore.c
	/*
	if(m_wpInterim)
	{
		m_wpInterim.Destroy();
	}
	*/
	///---END NANOSIZER_WIZ_AUTO_UPDATE_SUPPORT
	
	/// Iris 10/31/2008 V8.0963d MOVE_2ND_DERVITIVE_PLOT_CODES_TO_PAWIZCORE
	if( m_wksDerivative )
		m_wksDerivative.Destroy();
	///end MOVE_2ND_DERVITIVE_PLOT_CODES_TO_PAWIZCORE	

	///---Sim 02-12-2009 FIX_SET_RANGE_AS_INPUT_INPUT_CAUSE_CREATE_OP_FAIL_AND_PA_FINISH_BROKEN
	/////--Sandy 2008-12-9 if not finish , not need to plot result
	//bool bFinish = false;
	//XFWizNavigation *pXFWizNavg = (XFWizNavigation *)GetXFWizNavigation();
	//ASSERT(pXFWizNavg);
	//if ( pXFWizNavg )
		//bFinish = pXFWizNavg->IsFinish();
	//
	//if(bFinish)
		//putResultToOriginalGraph();
	/////--end
	///---END FIX_SET_RANGE_AS_INPUT_INPUT_CAUSE_CREATE_OP_FAIL_AND_PA_FINISH_BROKEN
	
	if(m_pPeakFitHelper != NULL)
		delete m_pPeakFitHelper;
	m_pPeakFitHelper = NULL;	
}
///---Sim 02-12-2009 FIX_SET_RANGE_AS_INPUT_INPUT_CAUSE_CREATE_OP_FAIL_AND_PA_FINISH_BROKEN
//virtual
bool PAWizCore::Done(bool bFinish) // = true
{
	if(bFinish)
		putResultToOriginalGraph();
	
	return true;
}
///---END FIX_SET_RANGE_AS_INPUT_INPUT_CAUSE_CREATE_OP_FAIL_AND_PA_FINISH_BROKEN

//------ Folger 11/13/08 QA80-12488 v8.970 PA_FITTING_AUTO_UPDATE_SUPPORT_USE_VECTOR_FOR_UIDS_STORAGE
/*
//------ Folger 11/12/08 QA80-12488 v8.0969 PA_FITTING_AUTO_UPDATE_SUPPORT
#define PA_FIT_OUTPUT_OY1	0
#define PA_FIT_OUTPUT_OY2	1
#define PA_FIT_OUTPUT_OY3	2

static	bool	_update_fitting_output_range(Array<DataRange&>& arrdrOutputs, int nIndex, const TreeNode& trRange)
{
	int		nUID;
	trRange.GetAttribute(TREE_UID, nUID);
	
	DataRange *pdr = new DataRange;
	*pdr = (DataRange)Project.GetObject(nUID);
	
	if ( !pdr->IsValid() )
	{
		delete pdr;
		return false;
	}
	
	arrdrOutputs.SetAtGrow(nIndex, *pdr);
	return true;
}
*/

///---Sim 06-23-2009 NANOSIZER_WIZ_AUTO_UPDATE_SUPPORT
// move to FitWizCoreBase.c
/*
static	bool	_update_fitting_output_range(Array<DataRange&>& arrdrOutputs, const vector<int>& vnUIDs)
{
	arrdrOutputs.SetSize(0);
	for ( int ii=0; ii<vnUIDs.GetSize(); ++ii )
	{
		DataRange *pdr = new DataRange;
		*pdr = (DataRange)Project.GetObject(vnUIDs[ii]);
		
		if ( !pdr->IsValid() )
		{
			///------ Folger 01/19/09 QA80-12969 PA_FITTING_SUPPORT_ANALYSIS_TEMPLATE
			//delete pdr;
			//continue;
			pdr->Create();
			///------ End PA_FITTING_SUPPORT_ANALYSIS_TEMPLATE
		}
		
		pdr->SetName(PEAK_FITTING_OUTPUT_EMPTY_RANGE_NAME, FALSE);
		arrdrOutputs.Add(*pdr);
	}
	return true;
}
//------ End PA_FITTING_AUTO_UPDATE_SUPPORT_USE_VECTOR_FOR_UIDS_STORAGE

/// virtual
bool	PAWizCore::Apply()
{
	//------ Folger 12/04/08 v8.0982b LASE_USED_FOR_PA_FIT_FAIL_TO_CREATE_NEW_REPORT_SHEETS
	XFWizNavigation		*pXFWizNavg = (XFWizNavigation *)GetXFWizNavigation();
	bool				bIsPaFitStep = pXFWizNavg && pXFWizNavg->GetXFName(pXFWizNavg->GetStep()).CompareNoCase(STR_PA_XFNAME_FIT) == 0;
	
	if ( bIsPaFitStep )
	{
		if ( !IsAutoUpdated() )
		{
			vector<int>		vnEmpty;
			m_trGetN.trUID.range_uid.nVals = vnEmpty;
			m_trGetN.trUID.graph_uid.nVals = vnEmpty;
			m_trGetN.trAdv.OutputGraph.LayerUID.nVal = 0;
		}
	}
	//------ End LASE_USED_FOR_PA_FIT_FAIL_TO_CREATE_NEW_REPORT_SHEETS
	
	bool bRet = XFCore::Apply();
	
	if ( bRet )
	{
		//------ Folger 12/04/08 v8.0982b LASE_USED_FOR_PA_FIT_FAIL_TO_CREATE_NEW_REPORT_SHEETS
		//if ( pXFWizNavg && pXFWizNavg->GetXFName(pXFWizNavg->GetStep()).CompareNoCase(STR_PA_XFNAME_FIT) == 0 )
		if ( bIsPaFitStep )
		//------
		{
			//------ Folger 11/13/08 QA80-12488 v8.970 PA_FITTING_AUTO_UPDATE_SUPPORT_USE_VECTOR_FOR_UIDS_STORAGE
			//_update_fitting_output_range(m_arrdrOutputs, PA_FIT_OUTPUT_OY1, m_trGetN.oy1);
			//_update_fitting_output_range(m_arrdrOutputs, PA_FIT_OUTPUT_OY2, m_trGetN.oy2);
			//_update_fitting_output_range(m_arrdrOutputs, PA_FIT_OUTPUT_OY3, m_trGetN.oy3);
			vector<int>		vnUIDs;
			vnUIDs = m_trGetN.trUID.range_uid.nVals;
			_update_fitting_output_range(m_arrdrOutputs, vnUIDs);
			//------ End PA_FITTING_AUTO_UPDATE_SUPPORT_USE_VECTOR_FOR_UIDS_STORAGE
		}
	}
	
	return bRet;
}
*/
//virtual
bool PAWizCore::IsFitStep()
{
	XFWizNavigation		*pXFWizNavg = (XFWizNavigation *)GetXFWizNavigation();
	return ( pXFWizNavg && pXFWizNavg->GetXFName(pXFWizNavg->GetStep()).CompareNoCase(STR_PA_XFNAME_FIT) == 0 );
}
///---END NANOSIZER_WIZ_AUTO_UPDATE_SUPPORT
//------ End PA_FITTING_AUTO_UPDATE_SUPPORT

///---Sim 11-14-2008 SUPPORT_PA_THEME_SR4_CONVERT_TO_SR5
///---Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK
/*
//virtual
double PAWizCore::GetVersion()
{
	return PA_VERSION_NUMBER;
}
*/
///---END IMPROVE_XF_WIZ_FRAMEWORK
///---END SUPPORT_PA_THEME_SR4_CONVERT_TO_SR5

void PAWizCore::Destroy()
{
	///---Sim 12-04-2008 IMPROVE_XF_WIZ_FRAMEWORK
	/*
	bool bFinish = false;
	XFWizDlgNavigation *pXFWizDlgNavg = (XFWizNavigation *)GetXFWizNavigation();
	if ( pXFWizDlgNavg )
		bFinish = pXFWizDlgNavg->IsFinish();
	*/
	///---END IMPROVE_XF_WIZ_FRAMEWORK
}

void PAWizCore:: putResultToOriginalGraph()
{
	
	GraphLayer gl;
	/// Iris 11/06/2008 v8.0966b IMPROVE_GET_SOURCE_GRAPH_CODES
	//gl = GetOriginalGraph();
	GetSourceGraph(gl);
	///end IMPROVE_GET_SOURCE_GRAPH_CODES
	if(gl.IsValid())
	{
		
		XFWizInputOutputRange	*pIORange = getIORange();
		if(!pIORange)
		{
			error_report("invalid input output range in PAWizCore!");
			return;
		}

		string strEndXFName;
		Array<DataRange&>	drs;
		switch(m_nGoal)
		{
		case PA_GOAL_INTEGRATE_PEAK:
			if(pIORange->Get(&drs, STR_PA_XFNAME_INT, false))
			{
				/// Folger, 12/02/08, after invoke XFBase::Evaluate, parrOutputs will have a empty range in position 0
				/// for ReportData output variables. Here nrPlotIndex == 3 means get 3rd output in original XF, with
				/// REPORT_TREE_VARS_IN_OUTPUT_ARRAY_BEGIN (1) offset, see XFunction.h
				const int nrPlotIndex = 3;
				
				if(drs.GetSize() < nrPlotIndex+1)
				{
					error_report("putResultToOriginalGraph::IORange array size isn't correct!");
				}
				DataRange &rPlotData = drs.GetAt(nrPlotIndex);
				if ( rPlotData && rPlotData.GetNumData() > 0 )
				{
					
					///temp solution and waiting for Sim's util to convert datarange to xyrange
					XYRange xyCenter, xyMarker, xyBaseline;
					if(!temp_convert_peak_info_dr_to_xyrs(rPlotData, xyCenter, xyMarker, xyBaseline))
						error_report("fail to convert dr to xyr!");	
					else
					{
						if(xyBaseline.IsValid())
							if(!plot_xyr_to_graph(xyBaseline,  gl, IDM_PLOT_LINE, SYSCOLOR_RED))
								error_report("plot baseline fail!");
	
						///Sandy 2008-9-9 add labels without L col
						if(xyCenter.IsValid())
						{
							//_add_label_plot(gl, xyCenter);// nLabelXYType);	//this line will cause overlap labels in change parameters					
							//if(!plot_peak_center_to_graph(xyCenter, gl))
							///Kyle 03/11/2010 PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA
							//if(!_update_peaks_labels(gl, xyCenter, m_bShowCenter, m_bShowLabel, m_nLabelXYType, m_bRotateLabel))
							if(!update_peaks_labels(gl, xyCenter, m_bShowCenter, m_bShowLabel, m_nLabelXYType, m_bRotateLabel))
							///End PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA
								error_report("plot peak center fail!");
						}
						
	
						if(xyMarker.IsValid())
						{
							DataPlot dpMarker;
							if(!plot_xyr_to_graph(xyMarker,  gl, IDM_PLOT_SCATTER, SYSCOLOR_BLUE, dpMarker))
								error_report("plot peak mareker fail!");
							if(dpMarker.IsValid())
								set_dataplot_format(dpMarker, 16, 15);	
						}
					}

				}
				
			}		
			break;
		case PA_GOAL_FIND_PEAK:
			if(pIORange->Get(&drs, STR_PA_XFNAME_PEAKS, false))
			{
				//Sandy 2008-12-1 I don't know why the base offset was 1 here, wait folger to debug
				const int nrBaselineIndex = 1;
				const int nrPeakCenterIndex = 2;
				//if(drs.GetSize() < nrPeakCenterIndex+1)
				//{
					//error_report("putResultToOriginalGraph::IORange array size isn't correct!");
				//}
				DataRange &rBaseline = drs.GetAt(nrBaselineIndex);
				DataRange &rPeakCenters = drs.GetAt(nrPeakCenterIndex);
				if(rBaseline && rBaseline.GetNumData() > 0)
				{
					
					///temp solution and waiting for Sim's util to convert datarange to xyrange
					XYRange xy;
					if(!temp_convert_simple_dr_to_xyr(rBaseline, xy) || !rBaseline.IsValid())
						error_report("fail to convert dr to xyr!");	
					else
					{
						if(!plot_xyr_to_graph(xy,  gl, IDM_PLOT_LINE, SYSCOLOR_RED))
							error_report("plot baseline fail!");
					}

				}
				
				if(rPeakCenters && rPeakCenters.GetNumData() > 0)
				{
					
					///temp solution and waiting for Sim's util to convert datarange to xyrange
					XYRange xy;
					if(!temp_convert_simple_dr_to_xyr(rPeakCenters, xy))
						error_report("fail to convert dr to xyr!");	
					else
					{				
						///Sandy 2008-9-9 add labels without L col
						//_add_label_plot(gl, xy);// nLabelXYType);
						
						//if(!plot_peak_center_to_graph(xy, gl))
						///Kyle 03/11/2010 PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA
						//if(!_update_peaks_labels(gl, xy, m_bShowCenter, m_bShowLabel, m_nLabelXYType, m_bRotateLabel))
						if(!update_peaks_labels(gl, xy, m_bShowCenter, m_bShowLabel, m_nLabelXYType, m_bRotateLabel))
						///End PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA
							error_report("plot baseline fail!");
					}

				}

			}
			break;
		case PA_GOAL_CREATE_BASELINE:
		case PA_GOAL_SUBTRACT_BASELINE://sandy add 2008-10-16
			int nrBaselineIndex;
			bool bIsInput;
			///----Sandy 2008-12-30 centralize code for share code in create baseline mode(xps and create baseline, greg's suggestion)
			//if(pIORange->Get(&drs, STR_PA_XFNAME_BASECREATE, false))
			if(m_nBaseMode == PA_BM_XPS)
			{
				strEndXFName = STR_PA_XFNAME_XPS;
				nrBaselineIndex = 0;
				bIsInput = false;
			}
			else if(m_nBaseMode == PA_BM_USERDEF)
			{
				strEndXFName = STR_PA_XFNAME_BASECREATE;
				nrBaselineIndex = 0;
				bIsInput = false;
			}
			else
			{
				strEndXFName = STR_PA_XFNAME_BASEMODE;
				nrBaselineIndex = 0;
				bIsInput = true;
			}
			if(pIORange->Get(&drs, strEndXFName, bIsInput))
			///----end
			{
				//Sandy 2008-12-1 I don't know when the base offset was changed to 0, wait folger to debug
				//int nrBaselineIndex = 1;
				
				
				if(drs.GetSize() < nrBaselineIndex+1)
				{
					error_report("putResultToOriginalGraph::IORange array size isn't correct!");
				}
				
				DataRange &dr = drs.GetAt(nrBaselineIndex);
				if ( dr && dr.GetNumData() > 0 )
				{
					///-------Sandy 2008-12-2 create baseline has changed to output xyrange.
					/////temp solution and waiting for Sim's util to convert datarange to xyrange
					//XYRange xy;
					//if(!temp_convert_simple_dr_to_xyr(dr, xy) || !xy.IsValid())
						//error_report("fail to convert dr to xyr!");	
					//else
					//{
						//if(!plot_xyr_to_graph(xy,  gl, IDM_PLOT_LINE, SYSCOLOR_RED))
							//error_report("plot baseline fail!");
					//}
					XYRange xy;
					xy = dr;
					if(!plot_xyr_to_graph(xy,  gl, IDM_PLOT_LINE, SYSCOLOR_RED))
						error_report("plot baseline fail!");

				}
			}
			break;
		case PA_GOAL_FIT_PEAK:
			break;
		default:
			break;
		}
		///------ Folger 05/26/09 PEAK_CENTER_PLOT_FAILS_TO_SHOW_LEGEND_SYMBOL_AFTER_CALCULATE
		if ( PA_GOAL_FIT_PEAK != m_nGoal )			///------ Folger 06/08/09 QA80-12603-P1 PA_FIT_FAILS_NOT_TO_UPDATE_LEGNED_ON_SOURCE_GRAPH
			legend_update(gl);
		///------ End PEAK_CENTER_PLOT_FAILS_TO_SHOW_LEGEND_SYMBOL_AFTER_CALCULATE		
	}	
}

//------ Folger 10/15/08 NEED_TO_KNOW_IF_THERE_IS_BASELINE_IN_PEAK_FITTING
//virtual
bool			PAWizCore::HasBaseline()
{
	///Sandy 2008-10-16 
	//return	(GetCurrGoal() == PA_GOAL_INTEGRATE_PEAK && GetBaseMode() != PA_BM_None)
			//|| (GetCurrGoal() != PA_GOAL_INTEGRATE_PEAK && GetBaseMode() + 1 != PA_BM_None);
	if(GetBaseMode() == PA_BM_None || GetBaseMode() == PA_BM_LOCAL)
		return false;
	else
		return true;
}
//------ End NEED_TO_KNOW_IF_THERE_IS_BASELINE_IN_PEAK_FITTING

///------ Folger 10/20/09 NANOSIZER_FAILS_TO_SWITCH_LABEL_PLOT
////------ Folger 11/01/08 QA80-12509 v8.0964 SUPPORT_PEAK_LABEL_SWITCHING_IN_PA_FIT_CONTROL_DIALOG
// bool	PAWizCore::AccessPeakLabelSettings(int& nLabelXYType, bool bGet/* = true*/)
// {
// 	//------ Folger 11/10/08 QA80-12509 v8.0968 ONLY_SET_PLOT_LABEL_TYPE_IN_PEAK_FIT_DIALOG_EXCLUDE_ROTATION
// 	/*
// 	if ( bGet )
// 	{
// 		nLabelXYType = m_nLabelXYType;
// 		bRotateLabel = m_bRotateLabel;
// 	}
// 	else
// 	{
// 		m_nLabelXYType = nLabelXYType;
// 		m_bRotateLabel = bRotateLabel;
// 	}
// 	
// 	return true;
// 	*/
// 	GraphLayer gl;
// 	///------ Folger 09/27/09 QA80-14380 FIT_PEAK_PARAMETERS_DIALOG_FAILS_TO_BE_MODALESS_WHEN_SWITCH_TO_OTHER_PAGES
// 	//if(!GetPreviewLayer(gl) || !gl)
// 	if(!GetPreviewLayer(gl, !bGet) || !gl)
// 	///------ End FIT_PEAK_PARAMETERS_DIALOG_FAILS_TO_BE_MODALESS_WHEN_SWITCH_TO_OTHER_PAGES
// 		return false;
// 	
// 	XYRange xyPeaksCenter;
// 	if(!GetPeaksCenterRange(xyPeaksCenter))
// 	{
// 		return false;
// 	}
// 	
// 	DataPlot dp;
// 	if( !get_plot_from_xyr_in_gl(gl, xyPeaksCenter, dp, IDM_PLOT_TEXT) )
// 		return false;
// 	
// 	return dp.LabTalk(STR_PLOT_DATA_LABEL_TYPE, &nLabelXYType, bGet ? false : true) == 0 ? true : false;
// 	//------ End ONLY_SET_PLOT_LABEL_TYPE_IN_PEAK_FIT_DIALOG_EXCLUDE_ROTATION
// }
////------ End SUPPORT_PEAK_LABEL_SWITCHING_IN_PA_FIT_CONTROL_DIALOG
///------ End NANOSIZER_FAILS_TO_SWITCH_LABEL_PLOT

//------ Folger 12/03/08 v8.0982 CHECK_CREATE_BASELINE_SHOULD_BE_MEMBER_OF_PAWIZCORE
bool	PAWizCore::CheckCreateBaselinePlot(bool bCleanData/* = true*/, DataPlot* pBasePlot/* = NULL*/)
{
	XYRange xyBaseline;
	if(!GetBaselineRange(xyBaseline))
		return false;
	
	if(bCleanData)
	{
		vector vEmpty;
		xyBaseline.SetData(&vEmpty, &vEmpty, 0, NULL, DRS_SET_COL_DESIGNATIONS);
	}

	GraphPage gp;
	if(!GetTargetPage(gp) || !gp)
		return false;
	
	GraphLayer gl = gp.Layers(PA_INDEX_ORIGIN_LAYER);
	if(!gl)
		return false;
	
	DataPlot dp;
	if(!get_plot_from_xyr_in_gl(gl, xyBaseline, dp))
	{
		int nPlot = gl.AddPlot(xyBaseline, IDM_PLOT_LINE);
		DataPlot dp = gl.DataPlots(nPlot);
		if(!dp)
			return false;
		
		/// Iris 10/23/2008 v8.0959b SET_PA_FIT_LINE_NOT_SELECTABLE
		//dp.Info.System.Parameters.Selectable = FALSE;
		set_dataplot_selectable(dp, false);
		///end SET_PA_FIT_LINE_NOT_SELECTABLE
		dp.SetColor(1);		
	}
	
	if ( pBasePlot != NULL )
		*pBasePlot = dp;

	return true;
}
//------ End CHECK_CREATE_BASELINE_SHOULD_BE_MEMBER_OF_PAWIZCORE

int	PAWizCore::GetBaselineFitFunc(string& strFuncName)//rewrited by sandy for get fitting function from baseline info tree
{
	if(!m_trBaselineFitInfo)
		return -1;
	
	string strName;
	m_trBaselineFitInfo.GetAttribute(STR_LABEL_ATTRIB, strName);
	
	if(strName.IsEmpty())
		return -1;
	
	if(strFuncName)
		strFuncName = strName;
	
	vector<string> vsFuncNames, vsFileNames;
	if(!nslf_get_func_list(vsFuncNames, vsFileNames, STR_PA_NLSF_CAT_BASELINE))
		error_report("fail in getting fitting function list!");
	
	int nIndex = vsFuncNames.Find(strName, 0, true, true);

	return nIndex;
}

/// Iris 10/31/2008 V8.0963d MOVE_2ND_DERVITIVE_PLOT_CODES_TO_PAWIZCORE
// Must tell additional layers name to PAWizCore since maybe eixst other layers in preivew is hidden and no need to be arranged 
// in Find Peaks xf, additional preview layer only 2nd derivative preview; in Fit Peaks xf, has residual and 2nd derivative preview
bool PAWizCore::SetAdditionalLayersName(LPCSTR lpcszLayersName)
{
	if( NULL == lpcszLayersName)
		return false;
	
	m_strLayersName = lpcszLayersName;
	if( 0 == getNumberAdditionalLayers() )
		return false; 
	return true;
}

bool PAWizCore::SetAdditionalLayersShow(LPCSTR lpcszLayersShow)
{
	m_strLayersShow = lpcszLayersShow;
	
	if( !prepareAdditionalLayerForPreview() )
		return error_report("Fail to PrepareAdditionalLayerForPreview in PAWizCore::Update2ndDervitivePreivew");	
	return true;
}

bool PAWizCore::GetAdditionalLayersShow(LPCSTR lpcszLayerName)
{
	vector<string> vs;
	if( m_strLayersName.GetTokens(vs, '|') <= 0 )
		return error_report("m_strLayersName is empty!");
	
	int index;
	if( !is_in_list(lpcszLayerName, vs, false, &index) )
		return error_report("Not find specified layer name in m_strLayersName!");	
	
	string strShow = m_strLayersShow.GetToken(index, '|');	
	return atoi(strShow);
}

bool PAWizCore::GetAdditionalLayer(GraphLayer& glAdditional, LPCSTR lpcszLayerName)
{
	GraphLayer gl;
	if( !GetPreviewLayer(gl) )
		return false;
	GraphPage gp = gl.GetPage();
	
	glAdditional = gp.Layers(lpcszLayerName);
	if( glAdditional )
		return true;
	return false;
}

bool PAWizCore::Update2ndDervitivePreivew()
{
	GraphLayer gl;
	if( !GetAdditionalLayer(gl, _PREVIEW_2ND_DERVIA_LAYER) )
		return true; // if layer not ready means no need this preview, then no need contiune
	
	if( !update2ndDervitiveData() )
		return error_report("Update2ndDervitiveData returns false in PAWizCore::Update2ndDervitivePreivew");
	
	return plotDerivative() >= 0;
}

// if show then destroy; if hide then add this layer, and then arrange layers in page
bool PAWizCore::prepareAdditionalLayerForPreview()
{	
	GraphLayer glFitCurve;
	if( !GetPreviewLayer(glFitCurve) )
		return false;	
	GraphPage gp = glFitCurve.GetPage();
	
	stLayersGridFormat stOldFormat;
	getPreviewPageOriginalFormat(gp, glFitCurve, stOldFormat);
	

	vector<int> vnLayerIndex;
	vnLayerIndex.Add(glFitCurve.GetIndex());
	
	bool bNeedArrange = false;
	for(int nn = 0; nn < getNumberAdditionalLayers(); nn++)
	{
		string strLayerName = m_strLayersName.GetToken(nn, '|');
		string strLayerShow = m_strLayersShow.GetToken(nn, '|');
		bool bShow = (bool)atoi(strLayerShow);
		
		GraphLayer glAdditional;
		GetAdditionalLayer(glAdditional, strLayerName);
		
		if(!bShow && glAdditional.IsValid())
		{
			glAdditional.Destroy();
			bNeedArrange = true;
		}
		
		if(bShow && !glAdditional.IsValid())
		{
			glAdditional = gp.Layers( gp.AddLayer(strLayerName) );
			bNeedArrange = true;
		}
		
		if(glAdditional)
			vnLayerIndex.Add(glAdditional.GetIndex());
	}	

	if( bNeedArrange)
		page_arrange_layers(gp, vnLayerIndex.GetSize(), 1, &stOldFormat, false, false, vnLayerIndex);

	page_set_active_layer(gp, glFitCurve.GetIndex());
	return true;
}
	
int PAWizCore::getNumberAdditionalLayers()
{
	return m_strLayersName.GetNumTokens('|');
}

bool  PAWizCore::getPreviewPageOriginalFormat(GraphPage &gp, GraphLayer &glFitCurve, stLayersGridFormat& stOldFormat)
{
	if( !gp )
		return false;
	
	vector<int> vnLayerIndex;  
	vnLayerIndex.Add(glFitCurve.GetIndex());
	
	for(int nn = 0; nn < getNumberAdditionalLayers(); nn++)
	{
		string strLayerName = m_strLayersName.GetToken(nn, '|');
		
		GraphLayer glAdditional;
		GetAdditionalLayer(glAdditional, strLayerName);
		
		if(glAdditional)
			vnLayerIndex.Add(glAdditional.GetIndex());
	}
	
	double dTopLayer, dBottomLayer;
	vnLayerIndex.GetMinMax(dTopLayer, dBottomLayer);

	GraphLayer 	glTop 	= gp.Layers(dTopLayer);
	GraphLayer 	glBottom= gp.Layers(dBottomLayer);
	
	double xx[TOTAL_POS];
	
	glTop.GetPosition(xx);
	glTop.UnitsConvert(M_PERCENT, xx);
	int nLeftMargin 	= xx[LEFT_POS];
	int nRightMargin 	= 100 - xx[LEFT_POS] - xx[WIDTH_POS];
	int	nTopMargin		= xx[TOP_POS];
	
	glBottom.GetPosition(xx);
	glBottom.UnitsConvert(M_PERCENT, xx);
	int	nBottomMargin	= 100 - xx[TOP_POS] - xx[HEIGHT_POS];
	
	//stLayersGridFormat stOldFormat;
	stOldFormat.nXGap 		= 5;		
	stOldFormat.nYGap 		= 5;			
	stOldFormat.nLeftMg 	= nLeftMargin;//15
	stOldFormat.nRightMg 	= nRightMargin;//15
	stOldFormat.nTopMg 	= nTopMargin;//15
	stOldFormat.nBottomMg 	= nBottomMargin;//15
	
	return true;
}

int	PAWizCore::plotDerivative()
{
	XYRange xyRange;	
	xyRange.Add("X", m_wksDerivative, 0, 0, -1, 0);
	xyRange.Add("Y", m_wksDerivative, 0, 1, -1, 1);
	
	if(!xyRange.IsValid())
		return -1;
	
	///Sandy 2008-11-20 add plot smoohted derivative 
	XYRange xySmoothed;	
	Column colSmoothed = m_wksDerivative.Columns(_STR_PA_SMOOTH_2ND_DERIV_COL_NAME);
	if(colSmoothed)
	{
		int nCol = colSmoothed.GetIndex();
		if(nCol>=0)
		{
			xySmoothed.Add("X", m_wksDerivative, 0, 0, -1, 0);
			xySmoothed.Add("Y", m_wksDerivative, 0, nCol, -1,nCol);
		}
	}
	//end	
	
	
	GraphLayer gl;
	if( !GetAdditionalLayer(gl, _PREVIEW_2ND_DERVIA_LAYER) )
		return -1;
	
	//-----Sandy 2008-11-20 add plot smoohted derivative 
	//vector<int> 	vnPlotIndices;
	//if( check_has_plotted_in_graph(xyRange, gl, vnPlotIndices) > 0 )
		//return vnPlotIndices[0];
	//
	//int nRet = gl.AddPlot(xyRange, IDM_PLOT_LINE);
	vector<int> 	vnPlotIndices;
	int nRet;
	if( check_has_plotted_in_graph(xyRange, gl, vnPlotIndices) > 0 )
		nRet = vnPlotIndices[0];
	else
		nRet = gl.AddPlot(xyRange, IDM_PLOT_LINE);
	
	if(xySmoothed.IsValid())
	{
		if( !check_has_plotted_in_graph(xySmoothed, gl, vnPlotIndices) > 0 )
		{
			int nPlot = gl.AddPlot(xySmoothed, IDM_PLOT_LINE);	
			DataPlot dpSmoothed = gl.DataPlots(nPlot);
			dpSmoothed.SetColor(1);//red
			legend_append_plot(gl, nPlot);
		}
	}
	//-----end add plot smoohted derivative 
	
	//if( nRet >= 0)
		//gl.Rescale();

	///------ Folger 11/24/09 SHOULD_NOT_RESCALE_PREIVEW_AFTER_CHANGE_FUNCTION_IN_PA_FITTING
	layer_set_link(gl, -1);
	///------ End SHOULD_NOT_RESCALE_PREIVEW_AFTER_CHANGE_FUNCTION_IN_PA_FITTING
	gl.Rescale(ANL_NO_Y_EXPAND);
	layer_set_link(gl, 0, 1);
	
	return nRet;
}

///---Sandy 2008-11-19 add update2ndDervitiveData for allow apply derviative data after smoothing 
bool PAWizCore::update2ndDervitiveData()
{
	
	if( !m_wksDerivative.IsValid() )
	{
	#ifdef IS_PREVIEW_DEBUG_MODE
			m_wksDerivative.Create(NULL, CREATE_HIDDEN);
	#else
			m_wksDerivative.Create(NULL, CREATE_HIDDEN  | CREATE_SET_MISSING_IN_MANAGER);
	#endif
	
		init2ndDervitiveWks();
	}
	
	int nCol = m_wksDerivative.Columns(_STR_PA_SMOOTH_2ND_DERIV_COL_NAME).GetIndex();
	
	XYRange xyr;
	xyr.Add("X", m_wksDerivative, 0, 0, -1, 0);
	xyr.Add("Y", m_wksDerivative, 0, nCol, -1, nCol);	
	
	vector vx, vy;
	if(m_xyOriginal.GetData(vy, vx))
		return xyr.SetData(&m_v2ndDerivative, &vx);	
	else
		return false;

}

//bool PAWizCore::update2ndDervitiveData()//Sandy 2008-11-19 rename only 
bool PAWizCore::init2ndDervitiveWks()
{
	//CheckGetPeakFitHelper();
	//ASSERT(m_pPeakFitHelper);
	//ASSERT(m_pPeakFitHelper->GetFitSession());
	//if( NULL == m_pPeakFitHelper || NULL == m_pPeakFitHelper->GetFitSession() )
		//return false;
	//
	//vector vx, vy;
	//m_pPeakFitHelper->GetFitSession()->GetInputData( vx, vy );
	
	XYRange dr;
	if( !GetOriginalRange(dr) )
		return false;
	
	vector vx, vy;
	dr.GetData(vy, vx);
	
	///Sandy 2008-11-19 move to Update2ndDervitiveData
	/*
	if( !m_wksDerivative.IsValid() )
	{
	#ifdef IS_PREVIEW_DEBUG_MODE
			m_wksDerivative.Create(NULL, CREATE_HIDDEN);
	#else
			m_wksDerivative.Create(NULL, CREATE_HIDDEN  | CREATE_SET_MISSING_IN_MANAGER);
	#endif
	}
	*/
	
	XYRange xyr;
	xyr.Add("X", m_wksDerivative, 0, 0, -1, 0);
	xyr.Add("Y", m_wksDerivative, 0, 1, -1, 1);	
	
	Column col;
	xyr.GetYColumn(col);
	//col.SetLongName("2nd Derivative");//sandy 2008-11-20
	col.SetLongName(_STR_PA_2ND_DERIV_COL_NAME);

	vector v2ndDeriv;
	v2ndDeriv = vy;
	if(OE_NOERROR != ocmath_derivative(vx, v2ndDeriv, v2ndDeriv.GetSize()))
	{
		return false;
	}	
	
	if(OE_NOERROR != ocmath_derivative(vx, v2ndDeriv, v2ndDeriv.GetSize()))
	{
		return false;
	}
	
	xyr.SetData(&v2ndDeriv, &vx);
	
	//Sandy 2008-11-20 add for smoothed derivative
	if(!m_wksDerivative.Columns(_STR_PA_SMOOTH_2ND_DERIV_COL_NAME).IsValid())
	{
		int nCol = m_wksDerivative.AddCol(_STR_PA_SMOOTH_2ND_DERIV_COL_NAME);
	}	
	//end
	
	return true;
}
///end MOVE_2ND_DERVITIVE_PLOT_CODES_TO_PAWIZCORE

/// Iris 11/04/2008 v8.0965b PA_FIT_ADD_INPUT_REPORT_TABLE
void PAWizCore::SetInputDataTable(const TreeNode& trInputTable)
{
	TreeNode trInput = m_trInputTable.AddNode("junk");
	trInput.Replace(trInputTable.Clone());
}

bool PAWizCore::GetInputDataTable(TreeNode& trInputTable)
{
	if( m_trInputTable && m_trInputTable.FirstNode )
	{
		trInputTable.Replace(m_trInputTable.FirstNode.Clone(), true, true);
		return true;
	}
	return false;
}

bool PAWizCore::UpdatePeaksCenterLabels(bool bShowCenter,  bool bShowLabel, int nLabelXYType, bool bRotateLabel)
{

	///Sandy 2009-2-6 FIX_SCRIPT_MODE_NOT_SHOW_LABEL
	//GraphLayer gl;
	//if(!GetPreviewLayer(gl) || !gl || !m_xyPeaksCenter)
		//return false;

	m_bShowCenter = bShowCenter;
	m_bShowLabel = bShowLabel;
	m_nLabelXYType = nLabelXYType;
    m_bRotateLabel = bRotateLabel;
    
    if(!m_xyPeaksCenter)
    	return false;
    
    
    ///Sandy 2009-2-6 FIX_SCRIPT_MODE_NOT_SHOW_LABEL
    //return _update_peaks_labels(gl, m_xyPeaksCenter, m_bShowCenter, m_bShowLabel, m_nLabelXYType, m_bRotateLabel);
	GraphLayer gl;
	if(GetPreviewLayer(gl) && gl)
		///Kyle 03/11/2010 PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA
		//return _update_peaks_labels(gl, m_xyPeaksCenter, m_bShowCenter, m_bShowLabel, m_nLabelXYType, m_bRotateLabel);
		return update_peaks_labels(gl, m_xyPeaksCenter, m_bShowCenter, m_bShowLabel, m_nLabelXYType, m_bRotateLabel);
		///End PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA
    ///end FIX_SCRIPT_MODE_NOT_SHOW_LABEL
    
	
	//DataPlot dp;
	//if(get_plot_from_xyr_in_gl(gl, m_xyPeaksCenter, dp, IDM_PLOT_TEXT))
	//{
		//dp.Destroy();
	//}
	//if(m_bShowLabel)
	//{
		//dp = _add_label_plot(gl, m_xyPeaksCenter, nLabelXYType, 0,  bRotateLabel);
		//if(!dp)
			//error_report("fail to add label plot!");
	//}
	//
	////create peak plot
	//if( m_bShowCenter )
	//{
		//DataPlot dp;
		//
		/////Sandy 2008-9-12 after the change of #12141, peak centers should be plotted twice, but marker("|") plot be detected
		////if(!get_plot_from_xyr_in_gl(gl, xyPeaksCenter, dp))
		//if(!get_plot_from_xyr_in_gl(gl, m_xyPeaksCenter, dp, IDM_PLOT_LINE))
		//{
			//if(!plot_peak_center_to_graph(m_xyPeaksCenter,gl))
				//return false;
		//}
	//}	
	
	return true;	
}

///end PA_FIT_ADD_INPUT_REPORT_TABLE
/////////////////////////////////////////////////////////////////////////////////////////////////////////




