/*------------------------------------------------------------------------------*
 * File Name: FitLinear.cpp	 													*
 * Creation: CPY 5/17/2003														*
 * Purpose: OriginC Class for Linear Regression									*
 * Copyright (c) Originlab Corp. 2003, 2004, 2005								*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	ML 3/3/2004 RANGE_BASED_REGRESSIONS											*
 *	ML 11/11/2004 QA70-6845 CELL_VALUE_LINKING									*
 *	ML 12/17/2004 PROGRAMMATICALLY_PUTTING_A_REPORT_TABLE_INTO_A_GRAPH			*
 *	Kevin 10/14/05 ADD_ELLIPSE_GRAPH_FOR_LR										*
 *	Kevin 11/02/05	MOVE_ELLIPSE_GRAPH_INTO_FIT_CURVE							*
 *	Kevin 11/09/05 REMOVE_TREENODE_WHEN_UNCHECK_ELLIPSE_BOX						*
 *	ML 4/28/2006 FRIENDLY_CUSTOM_TABLE_THEME_GENERATION							*
 *	ML 7/20/2006 QA70-4434 CUSTOM_TABLES_FOR_FIND_XY							*
 *	ML 8/4/2006 REMOVING_CUSTOM_TABLE											*
 *	CPY 10/14/06 SEPARATE_OUT_OPERATION_BASE_INTO_SEPARATE_HEADER				*
 *	Echo 2/12/07 ADD_ERROR_REPORT												*
 * 	Arvin 03/23/07 LABELS_LOST_IN_RESULT_TABLE_WHEN_NOT_PLOT_FITTED_CURVE		*
 *	Cheney 2007-5-16 NLFIT_SHOULD_CHECK_IF_EXIST_EMPTY_SUBRANGE					*
 *	Cheney 2007-5-17 LINEAR_FIT_SHOULD_CONSISTENT_WITH_FIT_NL					*
 *	Cheney 2007-5-28 IF_EMPTY_DATA_SET_SHOULD_SET_MISSING_AS_RESULT				*
 *	Cheney 2007-6-7 SHOULD_CHECK_EVENT_ID_IN_EVENT_FUNC							*
 *	Cheney 2007-6-19 ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT		*
 *	Arvin 07/12/07 	QA70-3300-P4 WRONG_PRECISION_COVERTED_TO_STRING				*
 *	Arvin 07/20/07 WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT							*
 *	Arvin 08/02/07 CHECK_WEIGHT_DATA_HAS_MISSING_AND_NEGATIVE_VALUES			*
 *	Arvin 08/28/07 QA70-10073-P4 KEEP_CUSTOMIZATION_COLOR_OF_ELLIPSE_AFTER_RECALCULATE
 *	TD 10-04-2007 QA80-10478 LOCALISED_REPORTTREE_ISSUE							*
 *	Fisher 11/14/07 ADD_MAP_ID_TO_CHM											*
 *	Arvin 01/31/08 QA70-10948 SHOW_CORRELATION_COEFICIENT_IN_LR					*
 *	Arvin 02/14/08 QA70-11094 SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
 *  Iris 3/21/2008 v8.0829 QA80-10934 ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME*
 *	Sophy 11/21/2008 v8.976 QA80-12591-P3 ADD_ERRMSG_WHEN_FITCURVE_XDATATYPE_IS_LOG_WITH_NEGATIVE_INPUT
 *	Sophy 11/28/2008 v8.0980d QA80-12591-P5 ADD_AUTO_SUPPORT_FOR_LR_AND_PR_FITCURVE_XDATATYPE
 *	Kyle 03/31/2009 QA80-3224 NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR	*
 *	Kyle 04/09/2009 QA80-3224-P2 SHOW_SELECTED_METHOD_IN_REPORT_NOTES			*
 *	Folger 04/14/09 QA80-12786-P2 DATE_TIME_FORMAT_NOT_PROPERLY_UPDATED_FOR_X_DATA_TYPE_WHEN_CHANGE_PARAM
 *	Hong 08/07/09 QA80-13894 FIX_ORIGIN_CRASH_DUE_TO_TOO_LESS_DATA_PTS_OF_ELLIPSE
 *  Iris 8/13/2009 QA80-14134 FIX_FIND_INCORRECT_X_FROM_Y_FOR_APPARENT_FIT		*
 *	Hong 09/04/09 QA80-14258 HISTOGRAM_NEED_SPECIAL_HINT_FOR_DOING_NLFITTING	*
 *	Folger 10/21/09 UPDATE_HELPID_FOR_FITLINEAR_WITH_X_ERROR					*
 *  Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
 *  Iris 10/28/2009 QA81-14546 CHANGE_GUI_REPORT_TABLE_LABEL					*
 *  Iris 11/24/2009 QA81-3224-P5 FIX_ERRBARWEIGHT_IS_ENABLE_WHEN_CHANGE_PARAM	*
 *	Hong 02/26/10 QA80-15148 IMPROVE_LINEAR_FIT_DLG_OPEN_SPEED					*
 *------------------------------------------------------------------------------*/

#include <origin.h>
#include <event_utils.h>
#include <report_utils.h>
#include "FitCommon.h"
#include <o8dlg.h>

#ifdef _FOR_SMART_LOADING_ONLY
#include "wksOperation.h" //---- CPY 10/14/06 SEPARATE_OUT_OPERATION_BASE_INTO_SEPARATE_HEADER
#include "analysis_utils.h"
#include <stats_utils.h>
#include "stats_guis.h"
#include "stats_operations.h"
#include "nlsf_utils.h" /// Iris 7/08/2008 CLEAN_DUP_CALC_AVE_DATA_CODE_IN_NLSF_PREVIEW_AND_OP
#include "graph_utils.h" //---- Iris 11/19/2008 v8.0975 QA80-12591-P2 FIX_APPARENT_FIT_ON_GRAPH_CUSTOM_RANGE_GET_INCORRECT_X
#endif

#include <xfutils.h>  ///Echo 2/12/07 ADD_ERROR_REPORT

//////////////////////////////////////////////
// naming convention
// protected:
// VirtualImplementation
// private:
// localHelperFunction
///////////////////////////////////////////////
/*
void lr_data(double a = 0.3, double b = 2.5, double xinc = 0.023)
{
	Worksheet wks = Project.ActiveLayer();
	if(!wks)
		return;
	
	Dataset aa(wks, 0);
	Dataset bb(wks, 1);
	
	int nSize = 100;
	
	aa.SetSize(nSize);
	bb.SetSize(nSize);
	double x;
	
	for(int ii = 0; ii < nSize; ii++)
	{
		x = ii * xinc;
		aa[ii] = x;
		bb[ii] = a*x + b;
	}
}
*/

/*
static	void	add_link_offsets(string &str, int *pnFirst, int *pnSecond, BOOL bPrefix)
{
	string		strOffsets;
	
	if ( pnFirst )
	{
		if ( pnSecond )
			strOffsets.Format("[%d,%d]", *pnFirst, *pnSecond);
		else
			strOffsets.Format("[%d]", *pnFirst);
	}
	else if ( pnSecond )
	{
		strOffsets.Format("[,%d]", *pnSecond);
	}
	
	if ( bPrefix )
		str += STR_LINK_CELL_VALUE_PREFIX;

	str += strOffsets;
}
*/

///Kyle 03/31/2009 QA80-3224 NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR
///Iris 11/24/2009 QA81-3224-P5 FIX_ERRBARWEIGHT_IS_ENABLE_WHEN_CHANGE_PARAM_MORE
// moved to fitteroperation.h
/*
enum
{
	FIT_LINEAR_NO_X_ERROR,
	FIT_LINEAR_WITH_X_ERROR,
};
*/
///End FIX_ERRBARWEIGHT_IS_ENABLE_WHEN_CHANGE_PARAM_MORE

enum
{
	method_york,
	method_fv,
	method_ripley,
};

#define NULL_DOUBLE_POINTER		(double*)0
///End NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR

///Iris 11/24/2009 QA81-3224-P5 FIX_ERRBARWEIGHT_IS_ENABLE_WHEN_CHANGE_PARAM_MORE
// moved to FitterOperation.h
//#define STR_FIT_LINEAR_TYPE		"FitLinearType" /// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
///End FIX_ERRBARWEIGHT_IS_ENABLE_WHEN_CHANGE_PARAM_MORE

///Echo 2/12/07 ADD_ERROR_REPORT
static bool _check_data_pts(double dPoints)
{
	if (dPoints < 0)
		return false;
	
	if (dPoints - (int)dPoints != 0)
		return false;
	
	return true;
}
static bool _check_conf_level(TreeNode trConfLev)
{
	if (trConfLev.Enable)
		return check_conf_level(trConfLev);
	
	return true;		
}
static int fitlinear_event1(TreeNode& tr, int nRow, int nEvent, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& getNCountainer, string& strAux, string& strErrMsg)
{
	DECLARE_BUTTON_ENABLES   //support more buttons enable/disable
	
	int nErr = CER_NO_ERROR;
	
	///Cheney 2007-6-7 SHOULD_CHECK_EVENT_ID_IN_EVENT_FUNC	
	///Cheney 2007-7-6 SHOULD_CHECK_ERR_WHEN_THEME_CHANGE_ALSO
	//if(GETNE_ON_VALUE_CHANGE == nEvent  || GETNE_ON_INIT == nEvent)
	if(GETNE_ON_VALUE_CHANGE == nEvent  || GETNE_ON_INIT == nEvent || GETNE_ON_THEME == nEvent)
	///end SHOULD_CHECK_ERR_WHEN_THEME_CHANGE_ALSO
	///end SHOULD_CHECK_EVENT_ID_IN_EVENT_FUNC
	{
		///Kyle 03/31/2009 QA80-3224 NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR
		/// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
		//if(tr.option && tr.option.nVal)
		int nFitType;
		if( tr.InputData.GetAttribute(STR_FIT_LINEAR_TYPE, nFitType) && FIT_LINEAR_WITH_X_ERROR == nFitType )
		///end FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
		{
			TreeNode trMethod = tr.Fit.method;
			tr.Fit.ErrBarWeight.nVal = trMethod.nVal == method_york || trMethod.nVal == method_ripley ? ERRBARWEIGHT_INSTRUMENTAL : ERRBARWEIGHT_DIRECT_WEIGHTING;		//york or ripley will use Instrumental, otherwise Direct Weighting
			tr.Fit.ErrBarWeight.Enable = false; /// Iris 11/24/2009 QA81-3224-P5 FIX_ERRBARWEIGHT_IS_ENABLE_WHEN_CHANGE_PARAM
		}
		///End NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR
		///Cheney 2007-5-16 NLFIT_SHOULD_CHECK_IF_EXIST_EMPTY_SUBRANGE	
		//if(get_input_xyrange_num(tr.InputData) < 1)
		//	nErr = CER_XY_LS_ONE;
		TreeNode trInput = tr.InputData;
		if(!okutil_is_fitter_data_node_ready(&trInput) )
			nErr = CER_INPUT_RANGE_EMPTY;
		///end NLFIT_SHOULD_CHECK_IF_EXIST_EMPTY_SUBRANGE
		
		///Cheney 2007-7-11 SHOULD_CHECK_DATARANGE_IF_IS_VALID
		if(nErr == CER_NO_ERROR)
		{
			DataRange dr;
			dr.Create(trInput, FALSE);
			if( !dr.IsValid() )
				nErr = XFERR_INVALID_RANGE;
		}
		///end SHOULD_CHECK_DATARANGE_IF_IS_VALID
		
		///Cheney 2007-5-17 LINEAR_FIT_SHOULD_CONSISTENT_WITH_FIT_NL
		//else if(0>= get_input_xyrange_data_size(tr.InputData))
			//nErr = CER_NO_DATA;
		/////end LINEAR_FIT_SHOULD_CONSISTENT_WITH_FIT_NL
	
		if (nErr == CER_NO_ERROR)
		{
			TreeNode trParamConf = tr.Quantities.Parameters.Confidence;
			/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
			/*
			TreeNode trFitConf = tr.Graph1.Confidence;
			TreeNode trEllipseMean = tr.Graph1.Ellipse.Mean.confidence;
			TreeNode trEllipsePred = tr.Graph1.Ellipse.Pred.confidence;
			*/
			TreeNode trFitConf = OP_GUI_FITCURVE_PLOT_SETTINGS(tr).Confidence;
			TreeNode trEllipseMean = OP_GUI_FITCURVE_PLOT_SETTINGS(tr).Ellipse.Mean.confidence;
			TreeNode trEllipsePred = OP_GUI_FITCURVE_PLOT_SETTINGS(tr).Ellipse.Pred.confidence;
			///end OP_DLG_NEW_STRUCTURE
			if (!_check_conf_level(trParamConf) || !_check_conf_level(trEllipseMean) || !_check_conf_level(trEllipsePred) || !_check_conf_level(trFitConf))
			{
				nErr = CER_INVALID_CONF_LEV;
			}
		}
		/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//if (nErr == CER_NO_ERROR && !_check_data_pts(tr.Graph1.Ellipse.DataPoints.dVal))
		if (nErr == CER_NO_ERROR && !_check_data_pts(OP_GUI_FITCURVE_PLOT_SETTINGS(tr).Ellipse.DataPoints.dVal))
		///end OP_DLG_NEW_STRUCTURE
		{
			nErr = CER_INVALID_DATA_NUM;
		}
		
		///Sophy 04/11/2008 CHECK_REPORT_DATA_BOOK_NAME_DIFFERENT
		string 	strRet = "";
	    if(CER_NO_ERROR == nErr)
	    {
	    	nErr = check_report_book_curve_book( tr, strRet );	    	
	    }
	    ///end CHECK_REPORT_DATA_BOOK_NAME_DIFFERENT	    
		
	    /// Hong 08/07/09 QA80-13894 FIX_ORIGIN_CRASH_DUE_TO_TOO_LESS_DATA_PTS_OF_ELLIPSE
	#ifdef		__FIX_FITLINEAR_CRASH_WHEN_TOO_LESS_ELLIPSE_DATA_PITS__
		/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		TreeNode trEllipse = OP_GUI_FITCURVE_PLOT_SETTINGS(tr).Ellipse;
		///end OP_DLG_NEW_STRUCTURE
		if ( nErr == CER_NO_ERROR && trEllipse.DataPoints.nVal < 2 )
		{
			TreeNode 		trDataPoints = trEllipse.DataPoints;
			nErr = CER_INPUT_ARGUMENT_LESS_THAN_SPECIFIED_VALUE;
			string		strLabel = _L("Data Points");
			trDataPoints.GetAttribute(STR_LABEL_ATTRIB, strLabel);
			strRet = strLabel + "|2";
		}
	#endif		//__FIX_FITLINEAR_CRASH_WHEN_TOO_LESS_ELLIPSE_DATA_PITS__
		/// end FIX_ORIGIN_CRASH_DUE_TO_TOO_LESS_DATA_PTS_OF_ELLIPSE
		
		/// Iris 5/29/2008 AVOID_NEGATIVE_IN_ARRANGE_GRAPHS_INTO_COL
		/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//TreeNode	trGraphNumCols = tr.Output.PlotSettings.GraphNumCols;
		TreeNode	trGraphNumCols = OP_GUI_GRAPH_ARRANGEMENT_NODE(tr).GraphNumCols;
		///end OP_DLG_NEW_STRUCTURE
		if(nErr == CER_NO_ERROR && trGraphNumCols && (! check_is_positive_integer(trGraphNumCols)))
		{
			nErr = CER_INVALID_POSITIVE_INTEGER;
			strRet = STR_GRAPH_INTO_NUM_COLS + " ";
		}
		///end AVOID_NEGATIVE_IN_ARRANGE_GRAPHS_INTO_COL
		
		///Sophy 11/21/2008 v8.976 QA80-12591-P3 ADD_ERRMSG_WHEN_FITCURVE_XDATATYPE_IS_LOG_WITH_NEGATIVE_INPUT
		if( nErr == CER_NO_ERROR )
		{
			/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
			//nErr = check_input_logx_datatype(tr.InputData, tr.Graph1.XDataType);
			nErr = check_input_logx_datatype(tr.InputData, OP_GUI_FIT_X_DATA_BRANCH(tr));
			///end OP_DLG_NEW_STRUCTURE
		}
		
		if( CER_NO_ERROR == nErr )
		{
			/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
			//nErr = check_logx_customize_x_range(tr.Graph1.XDataType);
			nErr = check_logx_customize_x_range(OP_GUI_FIT_X_DATA_BRANCH(tr));
			///end OP_DLG_NEW_STRUCTURE
		}
		///end ADD_ERRMSG_WHEN_FITCURVE_XDATATYPE_IS_LOG_WITH_NEGATIVE_INPUT
		
		if (nErr != CER_NO_ERROR)
		{
			bOKEnable = false;
			strErrMsg = nErr;
			if( !strRet.IsEmpty() )
			{
				strErrMsg += ":" + strRet;
			}
		}		
		
		///Arvin 08/02/07 CHECK_WEIGHT_DATA_HAS_MISSING_AND_NEGATIVE_VALUES
		if(nErr == CER_NO_ERROR)
		{
			check_get_weight_data_err_msg(tr, strErrMsg);
			///------ Folger 04/14/09 QA80-12786-P2 DATE_TIME_FORMAT_NOT_PROPERLY_UPDATED_FOR_X_DATA_TYPE_WHEN_CHANGE_PARAM
			/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
			//stats_update_xdatatype_min_max_by_auto(tr.InputData, tr.Graph1.XDataType);
			stats_update_xdatatype_min_max_by_auto(tr.InputData, OP_GUI_FIT_X_DATA_BRANCH(tr));
			///end OP_DLG_NEW_STRUCTURE
			///------ End DATE_TIME_FORMAT_NOT_PROPERLY_UPDATED_FOR_X_DATA_TYPE_WHEN_CHANGE_PARAM
		}
		///end CHECK_WEIGHT_DATA_HAS_MISSING_AND_NEGATIVE_VALUES
		
	}
	///Sophy 10/9/2008 QA80-10536-P12 REMOVE_FITTEDVALUE_FROM_RESIDUAL_AND_FINDXY_IF_NO_FITTED_CURVES_PLOT
	string strNodeName( lpcszNodeName );
	if( strNodeName.CompareNoCase("Graph1") == 0 )
		fitlinear_fitted_curves_option_changed( tr );
	///end REMOVE_FITTEDVALUE_FROM_RESIDUAL_AND_FINDXY_IF_NO_FITTED_CURVES_PLOT
	
	///Sophy 11/28/2008 v8.0980d QA80-12591-P5 ADD_AUTO_SUPPORT_FOR_LR_AND_PR_FITCURVE_XDATATYPE
	///------ Folger 04/14/09 QA80-12786-P2 DATE_TIME_FORMAT_NOT_PROPERLY_UPDATED_FOR_X_DATA_TYPE_WHEN_CHANGE_PARAM
	//if( strNodeName.CompareNoCase("Min") == 0 || strNodeName.CompareNoCase("Max") == 0 || strNodeName.CompareNoCase("Range") == 0 )
	if( strNodeName.CompareNoCase("InputData") == 0 || strNodeName.CompareNoCase("Min") == 0 || strNodeName.CompareNoCase("Max") == 0 || strNodeName.CompareNoCase("Range") == 0 )
	///------ End DATE_TIME_FORMAT_NOT_PROPERLY_UPDATED_FOR_X_DATA_TYPE_WHEN_CHANGE_PARAM
	{
		/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//stats_update_xdatatype_min_max_by_auto(tr.InputData, tr.Graph1.XDataType);
		stats_update_xdatatype_min_max_by_auto(tr.InputData, OP_GUI_FIT_X_DATA_BRANCH(tr));
		///end OP_DLG_NEW_STRUCTURE
	}
	///end ADD_AUTO_SUPPORT_FOR_LR_AND_PR_FITCURVE_XDATATYPE
	return true;

}
///end ADD_ERROR_REPORT

enum
{	
	GRAPH_CONFIDENCE_ELLIPSE_PREDICTION_PLOT,
	GRAPH_CONFIDENCE_ELLIPSE_MEAN_PLOT
};

class OC_REGISTERED FitLinear : public FitRegression
{
protected:
	/// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
	/*
	// Virtual 
	string GetClassName() {return "FitLinear";}
	*/
	BOOL	SetInfoFromXF(int nOption, LPCSTR lpcszClass, StringArray &saOptions, StringArray &saNames, LPCSTR lpcszStr2 = NULL)
	{
		Tree trOp;
		GetTree(trOp);
		
		TreeNode		trSpec = tree_check_get_node(trOp, "SpecInfo");
		string			strClass(lpcszClass);
		int nFitType = get_fit_type(strClass);
		trSpec.FitType.nVal = nFitType;
		trOp.GUI.InputData.SetAttribute(STR_FIT_LINEAR_TYPE, nFitType);
		trSpec.ClassName.strVal = strClass;	
			
		trSpec.Options.strVals = saOptions;
		trSpec.Option.nVal = nOption;
		if (0 < saNames.GetSize())
			trSpec.Names.strVals = saNames;
		if (lpcszStr2)
			trSpec.Categ.strVal = lpcszStr2;
		
		
		SetTree(trOp);
		return TRUE;
	}
	
	string GetClassName()
	{
		Tree trOp;
		GetTree(trOp);
		
		TreeNode	trSpecInfo = trOp.SpecInfo;
		if ( trSpecInfo && trSpecInfo.ClassName )
			return trSpecInfo.ClassName.strVal;
			
		return STR_FITTEROPERATION_CLASS_FITLINEAR;
	}
	///end FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
	
	//virtual 
	///Cheney 2007-9-28 MODIFY_TITLE_AS_MAX_SAID
	///Kyle 03/31/2009 QA80-3224 NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR
	//string GetAnalysisName(int nOption) {return _L("Linear Fit");}
	string GetAnalysisName(int nOption)
	{
		/// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
		//if(FIT_LINEAR_WITH_X_ERROR == nOption)
		Tree trOp;
		GetTree(trOp);
		if( FIT_LINEAR_WITH_X_ERROR == GetFitLinearType(trOp) )	
		///end FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
			return _L("Linear Fit with X Error");
		return _L("Linear Fit");
	}
	///End NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR
	string GetDlgDescription(int nOption) {return _L("Perform Linear Fitting");}
	///end MODIFY_TITLE_AS_MAX_SAID
	
	// virtual 
	// fisher 11/14/2007 ADD_MAP_ID_TO_CHM
	int GetHelpID()
	{
		///------ Folger 10/21/09 UPDATE_HELPID_FOR_FITLINEAR_WITH_X_ERROR
		//return IDD_FIT_LINEAR;
		Tree trOp;
		GetTree(trOp);
		
		/// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
		//return FIT_LINEAR_WITH_X_ERROR == GetOptionIndex(trOp.GUI) ? IDD_FIT_LINEAR_WITH_X_ERROR : IDD_FIT_LINEAR;
		return FIT_LINEAR_WITH_X_ERROR == GetFitLinearType(trOp) ? IDD_FIT_LINEAR_WITH_X_ERROR : IDD_FIT_LINEAR;
		///end FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
		///------ End UPDATE_HELPID_FOR_FITLINEAR_WITH_X_ERROR
	}

	/// Iris 6/04/05 ADD_FILTER_FITTING_GUI
	//virtual
	void    FilterFittingGUI(TreeNode& trOp)
	{
		FitRegression::FilterFittingGUI(trOp);
	///Kevin 10/17/05 ADD_ELLIPSE_GRAPH_FOR_LR
		ConstructAddEllipseGUI(trOp.GUI);
		
		//vector<int> vnNodesToHide = {IDE_POLY_ORDER, IDE_FIT_CORRELATION};		
		vector<int> vnNodesToHide = {IDE_POLY_ORDER, 
		IDE_PARAM_FIX,	///Iris 10/13/05 REMOVE_FIX_FOR_LR_PR_MR Leo said "there is no place to "Fix" the parameter in LR, PR, MR, so should remove this"
		///Arvin 01/31/08 QA70-10948 SHOW_CORRELATION_COEFICIENT_IN_LR
		//IDE_PARAM_DEPENDENCY, ///Arvin 05/22/07 REMOVE_DEPENDENCY_FOR_LR_PR_MR as larry's suggestion
		//IDE_FIT_CORRELATION};
		IDE_PARAM_DEPENDENCY};
		///END SHOW_CORRELATION_COEFICIENT_IN_LR
		///End REMOVE_FIX_FOR_LR_PR_MR
		
		tree_set_attributes(trOp.GUI, vnNodesToHide, "0");
		///Cheney 2007-8-31 QA70-10330 CLEAN_UP_PLOT_SETTING_BRANCH_IN_OUTPUT_RESULT_NODE
		/////Arvin 05/22/07 HIDE_PLOT_SETTING_BRANCH_FOR_LR_PR_WHILE_FROM_DATA_SHEET by larry's suggestion
		//TreeNode trPlotSettings = trOp.GUI.Output.PlotSettings;
		//if(trPlotSettings)
		//{
			//GraphLayer gl = Project.ActiveLayer();
			//trPlotSettings.Show = gl.IsValid() ? true : false;
		//}
		/////end HIDE_PLOT_SETTING_BRANCH_FOR_LR_PR_WHILE_FROM_DATA_SHEET
		///end CLEAN_UP_PLOT_SETTING_BRANCH_IN_OUTPUT_RESULT_NODE
	}
	///----
	
	/// Iris 10/28/2009 QA81-14546 CHANGE_GUI_REPORT_TABLE_LABEL
	/*
	/// Iris 4/17/2008 SPECIAL_REPORT_TABLE_NAME_FOR_DIFF_TOOLS
	//virtual	
	string	GetReportTableGUIName(TreeNode& trGUI)
	{
		return STR_OUTPUT_LR_FIT_REPORT_TABLE;
	}
	///end SPECIAL_REPORT_TABLE_NAME_FOR_DIFF_TOOLS
	*/
	///END CHANGE_GUI_REPORT_TABLE_LABEL

	//virtual 
	string 	GetResultBookName(TreeNode& trGUI) { return E_STR_LR_REPORT_TABLE_BOOK_SHORT_NAME; } /// Iris 3/21/2008 v8.0829 QA80-10934 ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME

	//virtual
	void 	FilterStatsReport(TreeNode& trOp)
	{	
		FitterOperation::FilterStatsReport(trOp);
		
		vector<int> vnNodesToHide = {IDE_FIT_CORRELATION};
		tree_set_attributes(trOp.Calculation, vnNodesToHide, "0");
	}
	
	//virtual
	BOOL Construct(TreeNode& tr, int nOption = 0)
	{
		if( FitRegression::Construct(tr, nOption) )
		{
			/// Iris 6/04/05 ADD_FILTER_FITTING_GUI
			/////Iris 01/05/2005
			////tr.GUI.Fit.RemoveChild("Order");
			//tr.GUI.Order.Remove();
			///end ADD_FILTER_FITTING_GUI
			
			///Kyle 03/31/2009 QA80-3224 NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR
			// hidden TreeNode to keep the option
			tr.GUI.option.nVal = nOption;
			tr.GUI.option.Show = false;
			
			/// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
			/*
			if(nOption == FIT_LINEAR_WITH_X_ERROR)
			{
				filterGUIWithXError(tr.GUI);
			}
			*/
			if( FIT_LINEAR_WITH_X_ERROR == GetFitLinearType(tr) )
			{
				filterGUIWithXError(tr);
			}
			///end FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
			///End NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR

			return TRUE;
		}
		return FALSE;
	}

	//virtual 
	bool GetDisplayFormula(TreeNode& trOp, string& strFormula)
	{
		strFormula ="y = a + b*x";
		return true;
	}
	

	
	///Iris 4/21/05 MAKEFITY_SUPPORT_MULTI_REGRESSION
	/// YuI 8/30/04 QA70-4387 NLFITTER_OPERATION_IMPLEMENTATION
	//	bool MakeFitY(const vector& vFitX, vector& vFitY, FitParameter* sFitParameter)
	//bool MakeFitY(int index, const vector& vFitX, vector& vFitY, FitParameter* sFitParameter)
	bool MakeFitY(int index, TreeNode &trOp, const vector& vFitX, vector& vFitY, FitParameter* sFitParameter, const matrix& mXs = NULL, int nPeak = 0)
	/// end NLFITTER_OPERATION_IMPLEMENTATION
	///end MAKEFITY_SUPPORT_MULTI_REGRESSION
	{
		double dSlope = sFitParameter[1].Value;	
		double dIntercept = sFitParameter[0].Value;
		if(vFitX.GetSize() > 0)///Cheney 2007-5-28 IF_EMPTY_DATA_SET_SHOULD_SET_MISSING_AS_RESULT	
			vFitY = vFitX * dSlope + dIntercept;
		return true;
	}
	
	///Arvin 11/09/07 SUPPORT_FIX_SLOPE_IN_FITLINEAR
	bool  RemoveFixedInterceptAndSlope(TreeNode& trGUI, vector<string>& vStrParams)
	{
		bool bRet = FitterOperation::RemoveFixedInterceptAndSlope(trGUI, vStrParams);
		if(!bRet)
			return false;
		
		TreeNode trSlope = trGUI.Fit.FixSlope;
		if(trSlope)
		{
			bool bFixSlope = trSlope.nVal;
			if(bFixSlope && vStrParams.GetSize() > 1)
				vStrParams.RemoveAt(1);//Remove the parameter called "Slope"
		}
		
		return true;
	}
	///end SUPPORT_FIX_SLOPE_IN_FITLINEAR
	///Kyle 03/31/2009 QA80-3224 NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR
	// virtual
	int	GetOptionIndex(const TreeNode& trGUI)
	{
		/// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
		// should always returns 0 here just same in FitNL. option.nVal will return 1 for FitLRXErr, 
		// then ClassOptionName will be "FitLRXErr_1", so theme filename will like 0-FitLinear_1-Last used.ois
		// this format class option name will cause will display theme on flat-out menu.
		//return trGUI.option ? trGUI.option.nVal : 0;		
		return 0;
		///end FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
	}
	
	/// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
	int		GetFitLinearType(TreeNode& trOp)
	{
		TreeNode		trSpec = trOp.SpecInfo;
		if(trSpec && trSpec.FitType)
		{
			return trSpec.FitType.nVal;
		}
		
		TreeNode trGUI = trOp.GUI;
		return trGUI.option ? trGUI.option.nVal : 0;
	}
	///end FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
	
	///Iris 2/03/2010 QA81-15018 FIX_LRXERR_SHOW_INCORRECT_MISSING_DATA_IN_MISSING_TABLE
	// Can make the data rules of LRXRR to the same as LR, the current diff only LRXRR not include 
	// DRR_DEPERR_TO_WEIGHT bit, this is the reason of this bug.
	/*
	// virtual
	DWORD	GetDataRules(const TreeNode& trOperation, bool bIgnoreCombineInfo = false)
	{		
		/// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
		//if(FIT_LINEAR_NO_X_ERROR == GetOptionIndex(trOperation.GUI))
		if(FIT_LINEAR_NO_X_ERROR == GetFitLinearType(trOperation))
		///end FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
			return FitRegression::GetDataRules(trOperation, bIgnoreCombineInfo);
		
		// FIT_LINEAR_WITH_X_ERROR
		DWORD		dw = DRR_GET_DEPENDENT | DRR_NO_FACTORS;
		if(IsApparentFit(trOperation))
			dw |= DRR_APPARENT;
		return CheckDataRules(trOperation, dw, bIgnoreCombineInfo);
	}
	*/
	///End FIX_LRXERR_SHOW_INCORRECT_MISSING_DATA_IN_MISSING_TABLE
	
	// virtual
	void	UpdateDataSourceInReportingHeader(TreeNode &trInputTable, const vector<string> &vstrFactors, int ii, LPCSTR lpcszXLabel = NULL, int numSubRanges = 0, DWORD dwRules = 0)
	{
		FitRegression::UpdateDataSourceInReportingHeader(trInputTable, vstrFactors, ii, lpcszXLabel, numSubRanges, dwRules);

		TreeNode		trOp;
		GetTree(trOp);
		
		/// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
		//if(FIT_LINEAR_WITH_X_ERROR == GetOptionIndex(trOp.GUI))
		if(FIT_LINEAR_WITH_X_ERROR == GetFitLinearType(trOp))
		///end FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
		{
			TreeNode	trInputData = trOp.GUI.InputData;
			string		strXError;
			if ( IsDatasetHasXError( trInputData, ii, strXError) )
			{
				int indexLT = ii + 1;
				TreeNode trRow = trInputTable.FirstNode;
				while(trRow && ii)
				{
					trRow = trRow.NextNode;
					ii--;
				}
				if(trRow.W)
					trRow.W.SetAttribute(STR_LABEL_ATTRIB, WKSH_OPERATION_INFO_Y_WEIGHT_DATA_SOURCE);
				AddOneInputDataTableCell( trRow, WKSH_OPERATION_INFO_X_WEIGHT_DATA_SOURCE, indexLT, FALSE, 'P', 'T');
			}
		}
		
		return;
	}
	
	bool IsDatasetHasXError(TreeNode& trInput, int nIndex = 0, string& strXError = NULL)
	{
		bool		bHasErr = false;
		int ii = 0;
		foreach(TreeNode trRange in trInput.Children)
		{
			if(ii == nIndex)
			{
				if(trRange.EI && !trRange.EI.IsEmpty() )
				{
					if(strXError)
						strXError = trRange.EI.strVal;
					return true;
				}
				else
					return false;
			}
			ii++;
		}
		return false;
	}
	///End NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR

public:
	//virtual
	/*int ConstructGraphNumber()
	{
		return GRAPH_FITTING_MAX_NODES_IN_LR_REPORT - 1;
	}*/


	//virtual 
	///Iris 4/15/05 ADD_MATRIX_ARG
	/////Iris 4/02/05 ADD_OPERATION_ARGU
	////bool GetYFromX(const vector& vx, vector& vy, int nOuputIndex = 0)
	//bool GetYFromX(const vector& vx, vector& vy, int nOuputIndex = 0, TreeNode& trOp = NULL)
	///Cheney 2007-6-19 ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
	//bool GetYFromX(const vector& vx, vector& vy, int nOuputIndex = 0, TreeNode& trOp = NULL, const matrix& mXs = NULL)
	bool GetYFromX(const vector& vx, vector& vy, int nOuputIndex = 0, TreeNode& trOp = NULL, const matrix& mXs = NULL, int nPeaks = 1, vector& vParams = NULL)
	///end ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
	{
		double a, b;
		if(getFitParams(a, b, nOuputIndex, trOp))
		{
			convertByAxis(trOp, nOuputIndex, vx, OKAXISTYPE_X, true); /// Iris 8/13/2009 QA80-14134 FIX_FIND_INCORRECT_X_FROM_Y_FOR_APPARENT_FIT
			vy = a + vx * b;
			convertByAxis(trOp, nOuputIndex, vy, OKAXISTYPE_Y, false); /// Iris 8/13/2009 QA80-14134 FIX_FIND_INCORRECT_X_FROM_Y_FOR_APPARENT_FIT
			return true;
		}
		return false;
	}
	//virtual 
	///Iris 4/02/05 ADD_OPERATION_ARGU
	//bool GetXFromY(vector& vx, const vector& vy, int nOuputIndex = 0)
	bool GetXFromY(vector& vx, const vector& vy, int nOuputIndex = 0, TreeNode& trOp = NULL)
	{
		double a, b;
		if(getFitParams(a, b, nOuputIndex, trOp))
		{
			convertByAxis(trOp, nOuputIndex, vy, OKAXISTYPE_Y, true); /// Iris 8/13/2009 QA80-14134 FIX_FIND_INCORRECT_X_FROM_Y_FOR_APPARENT_FIT
			vx = (vy - a) / b;	
			convertByAxis(trOp, nOuputIndex, vx, OKAXISTYPE_X, false); /// Iris 8/13/2009 QA80-14134 FIX_FIND_INCORRECT_X_FROM_Y_FOR_APPARENT_FIT	 		
			return true;
		}
		return false;
	}
	
	// For each x-value in vx evaluate as many y-values as possible, up to a maximum of c2Dest - c1Dest + 1,
	// and put the results into the columns c1Dest to c2Dest of wksDest.  
	//virtual	
	bool	GetXFromY(vector &vx, int index, Worksheet &wksDest, int c1Dest, int c2Dest, TreeNode &trOp = NULL)
	{
		// By default it has only one output (like in LR):
		vector		vOut;
		if (GetXFromY(vOut, vx, index, trOp))
		{
			Dataset		ds(wksDest, c1Dest);	// the first and only putput goes into c1Dest 
			if (ds.IsValid())
				ds = vOut;
		}
		
		return false;
	}
	
	///Arvin 12/12/06 ADD_RESIDUAL_ANALYSIS_FOR_FITTING
	bool GetAllTypeResidualData(const TreeNode &trOp, const vector& vX, const vector& vRegularRes, vector& vStand, vector& vStud, vector& vStudDel, int index = 0, int nPeak = 0, vector &vY = NULL, vector &vWeights = NULL, matrix &mXs = NULL)
	{
		TreeNode		trGUI = trOp.GUI;
		TreeNode		trFit = trGUI.Fit;
		
		LROptions		sLROptions;
		sLROptions = trGUI.Fit;
		sLROptions.Confidence = trGUI.Quantities.Parameters.Confidence.dVal; 
		sLROptions.Confidence /= 100;		
		
		matrix mx;
		mx.SetSize(vX.GetSize(), 1);
		mx.SetColumn(vX, 0);
		int				nNumCols = mx.GetNumCols();
		trOp.Input.nParams.nVal = nNumCols + 1; 		
		int nSizeFitParams = nNumCols + 1;
		
		FitParameter	sFitParameter[MAX_MR_PARAMS + 1];	
		RegStats		sRegStats;
		RegANOVA		sRegANOVA;
		RegCalcInternal	sReg;
		vector vSerr;
		vector vH;
		int nRet = stats_multiple_linear_regression(mx, vY, vWeights, sLROptions, &sFitParameter, nSizeFitParams, &sRegStats, &sRegANOVA, NULL, NULL, vH, vSerr);
		if(nRet != STATS_NO_ERROR)
			return false;
		
		int nNumPts = mx.GetNumRows();
		vector vTemp(nNumPts);
		vTemp = 1;
		mx.SetSize(nNumPts, 2, true);
		mx.SetColumn(vTemp, 1);
		int nParam = nSizeFitParams;
		vStand.SetSize(nNumPts); vStud.SetSize(nNumPts); vStudDel.SetSize(nNumPts);
		vector vCook(nNumPts), vAtkinson(nNumPts);
		nRet = ocmath_diagnostic_residuals(nNumPts, nParam, sRegStats.ReducedChiSq, vRegularRes.GetSize(), vRegularRes, mx, vStand, vStud, vStudDel, vCook, vAtkinson, vH);
		if (nRet != STATS_NO_ERROR)
				return false;
		
		return true;
	}
	///end ADD_RESIDUAL_ANALYSIS_FOR_FITTING
	
	///Echo 2/12/07 ADD_ERROR_REPORT
	//virtual 
	PEVENT_GETN GetNewEventFunction()
	{
		return fitlinear_event1;
	}
	///end ADD_ERROR_REPORTprivate:
	
	///Iris 4/02/05 ADD_OPERATION_ARGU
	//bool getFitParams(double& a, double& b, int nOuputIndex)
	bool getFitParams(double& a, double& b, int nOuputIndex, TreeNode& trOp = NULL)
	{
		///Iris 4/02/05 ADD_OPERATION_ARGU
		//Tree trOp;
		//GetTree(trOp);
		if(NULL == trOp)
			GetTree(trOp);
		///end ADD_OPERATION_ARGU
		
		Tree trParams;
		if(!GetFitParameters(trOp, trParams))
			return error_report("GetYFromX failed to get Parameters tree");
		
		FitParameter	sFitParameter[2];		// max num parameters (9 + 1 for constant term)
		if(GetFitParameters(trOp, trParams, nOuputIndex, sFitParameter, 2) == 2)
		{
			a = sFitParameter[0].Value;
			b = sFitParameter[1].Value;
			return true;
		}
		return false;
	}
	
	/// Hong 02/26/10 QA80-15148 IMPROVE_LINEAR_FIT_DLG_OPEN_SPEED
	bool ApplyTheme(LPCSTR lpcszClassName, TreeNode& trGUI, LPCSTR lpcszThemeName, bool bLoadFactDefault = true)
	{
		if ( theme_is_factory_default(lpcszThemeName) )
			return true;
		return FitRegression::ApplyTheme(lpcszClassName, trGUI, lpcszThemeName, bLoadFactDefault);
	}
	/// end IMPROVE_LINEAR_FIT_DLG_OPEN_SPEED

	
protected:
	//virtual 
	
	/// YuI 03/23/09 QA70-12160 XYRANGE_XERROR_SUPPORT
	/// Hong 09/04/09 QA80-14258 HISTOGRAM_NEED_SPECIAL_HINT_FOR_DOING_NLFITTING
	//bool InitFromSelection(TreeNode &trOperation)
	int 	InitFromSelection(TreeNode &trOperation)
	/// end HISTOGRAM_NEED_SPECIAL_HINT_FOR_DOING_NLFITTING
	{
		TreeNode trInputData = trOperation.GUI.InputData;
		/// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
		//if( trInputData.IsValid() && FIT_LINEAR_WITH_X_ERROR == GetOptionIndex(trOperation.GUI) )
		if( trInputData.IsValid() && FIT_LINEAR_WITH_X_ERROR == GetFitLinearType(trOperation) )
		///end FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
		{
			int nICOPT = 0;
			trInputData.GetAttribute(STR_INTERACTIVE_CONTROL_OPTIONS_ATTRIB, nICOPT);
			nICOPT |= ICOPT_SUPPORT_XERROR;
			trInputData.SetAttribute(STR_INTERACTIVE_CONTROL_OPTIONS_ATTRIB, nICOPT);
		}
		bool bRet =  init_input_data_branch_from_selection(trInputData, GetDataRules(trOperation));	
		OnInputDataSelectionChange(trOperation);	
		return bRet;
	}
	/// end XYRANGE_XERROR_SUPPORT

	
	// virtual
	// Returns the total count.
	int		GetStatisticsTablePropertiesForCustomTable(vector<int> &vn)
	{
		int			nCount = 2;
		vn.SetSize(nCount);
		
		vn[0] = IDE_FIT_ROOT_MSE;
		vn[1] = IDE_FIT_RVALUE;
		
		return nCount;
	}

	
	/// ML 8/4/2006 REMOVING_CUSTOM_TABLE
	////--- CPY 11/19/04 QA70-7121 CUSTOM_REPORT_TABLES
	////virtual
	//void FillCustomTableInReportTree(TreeNode& trCustomTable, TreeNode& trOperation, int nCustomTable = 0)
	//{
	//	return;
	//}
	////---
	/// end REMOVING_CUSTOM_TABLE
	/*
	/// ML 11/11/2004 QA70-6845 CELL_VALUE_LINKING
	// virtual
	BOOL		AddToCustomTables(TreeNode &trOp, int index, int nTotalNumData, int nTableID)
	{
		TreeNode		trCal = trOp.Calculation;
		// One custom table for now:
		TreeNode		trCustom = tree_check_get_node(trCal, "MyCustom", nTableID, STR_LABEL_ATTRIB, "My Custom Table With Links");
		trCustom.SetAttribute(TREE_Table, GetTableStringMain(false));
		int				nCustomLinkIDs[3];
		nCustomLinkIDs[0] = IDST_FIT_PARAMETER;		// the Parameters table
		nCustomLinkIDs[2] = IDE_PARAM_VALUE;		// the paramater value
		int				nParams = 2;
		//int				nNodeIndexStart = index * nParams;
		// The custom table is for now 1D:		
		for(int ii = 0; ii < nParams; ii++)
		{
			string		strLabel;
			if ( 0 == ii )
				strLabel = "Custom Intercept";
			else
				strLabel = "Custom Slope";
			
			nCustomLinkIDs[1] = make_one_set_ID(IDST_FIT_PARAMETER_ONE_SET + ii, index);		// a row from "Parameters" table (see stats_tree_add_Parameters())
			
			TreeNode	trNode = check_add_enumerated_node(trCustom, "C", index + ii + 1, IDE_CUSTOM_NODE_1 + index + ii, STR_LABEL_ATTRIB, strLabel);
			string		strLink;
			build_report_nodes_link_string(strLink, nCustomLinkIDs, 3);
			trNode.strVal = strLink;
		}
 
		return TRUE;
	}
	/// end CELL_VALUE_LINKING
	*/
	

	/// ML 3/3/2004 RANGE_BASED_REGRESSIONS
	/// Iris 9/23/04 ADD_COV_AND_CORR_REPORT
	//int		CallLLOC(TreeNode &trOp, vector &vY, vector &vX, matrix &mMultiIndep, vector &vWeights,
	//		FitParameter* psFitParameter, uint nSizeFitParams, RegStats* psRegStats, RegANOVA* psRegANOVA, RegCalcInternal* psInternal)
	///Arvin 12/04/06 ADD_CONF_PRED_BANDS_FOR_MR
	//int		CallLLOC(TreeNode &trOp, vector &vY, vector &vX, matrix &mMultiIndep, vector &vWeights,
	//			FitParameter* psFitParameter, uint nSizeFitParams, RegStats* psRegStats, RegANOVA* psRegANOVA, 
	//			RegCalcInternal* psInternal, matrix& mCov, matrix& mCorr)
	///Arvin 05/18/07 USE_REDUCED_CHISQ_CHECKBOX_NOT_WORK
	//int		CallLLOC(TreeNode &trOp, vector &vY, vector &vX, matrix &mMultiIndep, vector &vWeights,
	//			FitParameter* psFitParameter, uint nSizeFitParams, RegStats* psRegStats, RegANOVA* psRegANOVA, 
	//			RegCalcInternal* psInternal, matrix& mCov, matrix& mCorr, vector& vSerr = NULL)
	int		CallLLOC(TreeNode &trOp, vector &vY, vector &vX, matrix &mMultiIndep, vector &vWeights,
				FitParameter* psFitParameter, uint nSizeFitParams, RegStats* psRegStats, RegANOVA* psRegANOVA, 
				RegCalcInternal* psInternal, matrix& mCov, matrix& mCorr, vector& vSerr = NULL, int index = 0)
	///end USE_REDUCED_CHISQ_CHECKBOX_NOT_WORK
	///end ADD_CONF_PRED_BANDS_FOR_MR
	{
		TreeNode		trGUI = trOp.GUI;
		
		TreeNode		trFit = trGUI.Fit;
		
		///Kyle 03/31/2009 QA80-3224 NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR
		/// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
		//if( FIT_LINEAR_WITH_X_ERROR == GetOptionIndex(trGUI) )
		if( FIT_LINEAR_WITH_X_ERROR == GetFitLinearType(trOp) )
		///end FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
		{
			vector vxError, vyError;
			DataRange dr;
			if(!GetInput(dr))
			{
				return error_report("executeWithRange found no input range");
			}
			DWORD dwRules = GetDataRules(trOp), dwPlotUID;
			dr.GetData(dwRules, index, &dwPlotUID, NULL, NULL, NULL, NULL, NULL, NULL, &vyError, &vxError);
			
			int nMethod = getComputationMethod(trGUI);

			return linearFitXYError(	nMethod, vY, vX, vyError, vxError,
										psFitParameter, nSizeFitParams);
		}
		///End NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR
		
		////////////////////////		
		// Input settings:  
		LROptions		sLROptions;
		sLROptions = trGUI.Fit;
			sLROptions.Confidence = trGUI.Quantities.Parameters.Confidence.dVal; /// Iris 8/11/06 v8.0460 QA70-7735-10 Confidence node has been move into Quantities to Compute branch
			sLROptions.Confidence /= 100;
		///Arvin 05/18/07 USE_REDUCED_CHISQ_CHECKBOX_NOT_WORK
		TreeNode trInput = trGUI.InputData;
		if(!IsDatasetHasWeight(trInput, index))
			sLROptions.UseReducedChiSq = true;
		///end USE_REDUCED_CHISQ_CHECKBOX_NOT_WORK
		return stats_linear_fit(vX, vY, vWeights, sLROptions, psFitParameter, psRegStats, psRegANOVA, psInternal, mCov, mCorr);
	}

	int		GetParameters(TreeNode &trOp, int index = 0, vector<string> &vstrParameterNames = NULL, bool bIncNumPostfix = false, bool bIncDerivedParams = false, vector<bool>& vbIsDerived = NULL)
	{
		if(vstrParameterNames)
		{
			vstrParameterNames.SetSize(2);
			/// TD 10-04-2007 QA80-10478 LOCALISED_REPORTTREE_ISSUE
			//vstrParameterNames[0] = _L("Intercept");
			//vstrParameterNames[1] = _L("Slope");
			vstrParameterNames[0] = _LE("Intercept");
			vstrParameterNames[1] = _LE("Slope");
			/// end LOCALISED_REPORTTREE_ISSUE
			
			/// Iris 12/29/2006 v8.0534 PARAM_NAME_AS_TAGNAME_FOR_CELL_LINKING 
			if(bIncNumPostfix)
			{
				ParamsNamesAddPostfix(vstrParameterNames, index);
			}
			///end PARAM_NAME_AS_TAGNAME_FOR_CELL_LINKING
		}
		
		return 2;		// intercept and slope
	}

	/// TD 10-04-2007 QA80-10478 LOCALISED_REPORTTREE_ISSUE
	virtual string	getTranslatedParamStr(LPCSTR lpcszParam)
	{
		//----- CPY 10/23/2007 QA70-10577 COMBO_STR_STAY_AS_E_INTERNALLY_IN_DYNA_CNTRL
		//return _L(lpcszParam);
		return GetLocalized(lpcszParam);
		//-----
	}
	/// end LOCALISED_REPORTTREE_ISSUE

	/// end RANGE_BASED_REGRESSIONS
	
	/// ML 4/28/2006 FRIENDLY_CUSTOM_TABLE_THEME_GENERATION
	/*
	/// ML 12/17/2004 PROGRAMMATICALLY_PUTTING_A_REPORT_TABLE_INTO_A_GRAPH
	// virtual
	int	getTableIdForGraph(string *pstr, TreeNode& trOp)
	{
		/// ML 12/22/2004 temp until Roman is done with the label work
		//return 0;
		// Custom for now:
		TreeNode		tr = getOrCreateCustomTable(trOp);
		if( !tr.IsValid() )
			return 0;

		int				nID = tr.ID;
		/// 
		if ( pstr )
		{
			*pstr = "RegrTable";
		}
		return nID;
	}
	/// end PROGRAMMATICALLY_PUTTING_A_REPORT_TABLE_INTO_A_GRAPH
	*/
	/// end FRIENDLY_CUSTOM_TABLE_THEME_GENERATION

	///Arvin 07/20/07 WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT
	//bool AddConfidenceEllipseTable(TreeNode &trOp, int index, int nTotalNumData, vector &vX, vector &vY, vector &vWeights)
	bool AddConfidenceEllipseTable(TreeNode &trOp, int index, int nTotalNumData, vector &vX, vector &vY, vector &vWeights, DWORD dwPlotObjUID)
	///END WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT
	{
		///Arvin 07/20/07 WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT
		GraphLayer	grLayAppar;
		if ( dwPlotObjUID && IsApparentFit(trOp) )
		{
			DataPlot		dpl;
			dpl = Project.GetObject(dwPlotObjUID);
			if (dpl.IsValid())
				dpl.GetParent(grLayAppar);
		}
		///END WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT
		

		///Arvin 11/02/07 CLEAN_UP_LOCALIZATION_STRINGS
		//string strNodeName = "Mean";
		string strDataLabel = _LE("Mean");
		///end CLEAN_UP_LOCALIZATION_STRINGS
		bool bDo = IsAddEllipsePlot(trOp, IDE_FIT_MEAN);
		//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS		
		/*
		///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
		string			strDataLabelCurves = _L("Fit Curve");
		strDataLabelCurves += " ";
		strDataLabelCurves += index + 1;		
		///end CENTRALIZE_FITTING_RESULT_LABELS
		*/
		string			strData;
		GetEscapedMainDataString(trOp, strData, index + 1);
		string strDataLabelCurves = GetResultCurveMainTableLabel(trOp, nTotalNumData, strData);
		//---end CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
		if(bDo) ///Arvin 03/23/07 LABELS_LOST_IN_RESULT_TABLE_WHEN_NOT_PLOT_FITTED_CURVE
			///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
			//AddEllipseTable(trOp, index, nTotalNumData, "Mean", vX, vY, vWeights, IDST_FIT_CURVES, GRAPH_CONFIDENCE_ELLIPSE_MEAN_PLOT, bDo);
			///Arvin 07/20/07 WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT
			//AddEllipseTable(trOp, index, nTotalNumData, "Mean", vX, vY, vWeights, IDST_FIT_CURVES, GRAPH_CONFIDENCE_ELLIPSE_MEAN_PLOT, bDo, strDataLabelCurves);
			AddEllipseTable(trOp, index, nTotalNumData, strDataLabel, vX, vY, vWeights, IDST_FIT_CURVES, GRAPH_CONFIDENCE_ELLIPSE_MEAN_PLOT, bDo, strDataLabelCurves, grLayAppar);
			///end WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT
			///end CENTRALIZE_FITTING_RESULT_LABELS
		///Arvin 11/02/07 CLEAN_UP_LOCALIZATION_STRINGS
		//strNodeName = "Pred";
		strDataLabel = _LE("Pred");
		///end CLEAN_UP_LOCALIZATION_STRINGS
		bDo = IsAddEllipsePlot(trOp, IDE_FIT_PREDICTION);
		if(bDo) ///Arvin 03/23/07 LABELS_LOST_IN_RESULT_TABLE_WHEN_NOT_PLOT_FITTED_CURVE
			///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
			//AddEllipseTable(trOp, index, nTotalNumData, "Pred", vX, vY, vWeights, IDST_FIT_CURVES, GRAPH_CONFIDENCE_ELLIPSE_PREDICTION_PLOT, bDo);
			///Arvin 07/20/07 WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT
			//AddEllipseTable(trOp, index, nTotalNumData, "Pred", vX, vY, vWeights, IDST_FIT_CURVES, GRAPH_CONFIDENCE_ELLIPSE_PREDICTION_PLOT, bDo, strDataLabelCurves);
			AddEllipseTable(trOp, index, nTotalNumData, strDataLabel, vX, vY, vWeights, IDST_FIT_CURVES, GRAPH_CONFIDENCE_ELLIPSE_PREDICTION_PLOT, bDo, strDataLabelCurves, grLayAppar);
			///end WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT
			///end CENTRALIZE_FITTING_RESULT_LABELS
		return true;
	}


	bool	IsAddEllipsePlot(TreeNode &trOp, int nNodeID)
	{
		TreeNode trNode = tree_get_node_by_id(trOp.GUI, nNodeID, true);
		if(!trNode)
			return false;
		TreeNode trEllipse = trNode.Parent();
		if(!trEllipse)
			return false;
		
		if(trNode.Use && trEllipse.Use)
			return true;

		return false;
	}
	///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
	//bool AddEllipseTable(TreeNode &trOp, int index, int nTotalNumData, LPCSTR lpcszDataLabel, vector &vX, vector &vY, vector &vWeights, int nTableID, int nGraphType, bool bDo)
	///Arvin 07/20/07 WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT
	//bool AddEllipseTable(TreeNode &trOp, int index, int nTotalNumData, LPCSTR lpcszDataLabel, vector &vX, vector &vY, vector &vWeights, int nTableID, int nGraphType, bool bDo, LPCSTR lpcszDataLabelCurves)
	bool AddEllipseTable(TreeNode &trOp, int index, int nTotalNumData, LPCSTR lpcszDataLabel, vector &vX, vector &vY, vector &vWeights, int nTableID, int nGraphType, bool bDo, LPCSTR lpcszDataLabelCurves, GraphLayer& grLayAppar)
	///END WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT
	///end CENTRALIZE_FITTING_RESULT_LABELS
	{
		///Cheney 2007-10-27 CLEAN_UP_LOCALIZATION_THINGS
		//string strNodeName = "Ellipse";
		string strNodeName = _LE("Ellipse");
		///end CLEAN_UP_LOCALIZATION_THINGS
		
		/// Iris 11/02/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//TreeNode trTemp = tree_check_get_node(trOp.GUI.Graph1, strNodeName);
		TreeNode trFitCurves = OP_GUI_FITCURVE_PLOT_SETTINGS(trOp.GUI);
		ASSERT(trFitCurves);
		TreeNode trTemp = tree_check_get_node(trFitCurves, strNodeName);
		///end OP_DLG_NEW_STRUCTURE
		TreeNode trPlot = tree_check_get_node(trTemp, lpcszDataLabel);
	
		double dConfidenceLevel = trPlot.confidence.dVal;
		double dConLevel = 1 -  dConfidenceLevel / 100;
	
		int		nPoints = trTemp.DataPoints.nVal;

		vector vEllipseX(nPoints), vEllipseY(nPoints);
		int nRet = ocmath_ellipse(vX, vY, vWeights, vX.GetSize(), dConLevel, nPoints, vEllipseX, vEllipseY, nGraphType);
		
		///Arvin 07/12/07 	QA70-3300-P4 WRONG_PRECISION_COVERTED_TO_STRING
		//string strPlotLabel = (string)dConfidenceLevel + "% conf. ellipse (" + lpcszDataLabel + ")";
		///Cheney 2007-10-27 CLEAN_UP_LOCALIZATION_THINGS
		//string strPlotLabel = ftoa(dConfidenceLevel) + "% conf. ellipse (" + lpcszDataLabel + ")";
		///Arvin 11/02/07 CLEAN_UP_LOCALIZATION_STRINGS
		//string strPlotLabel = ftoa(dConfidenceLevel) + "% " + _L("conf") + ". " + _L("ellipse") + " (" + lpcszDataLabel + ")";
		/// Hong 11/07/07 v.8.0742 FIX_ERROR_LOCALIZED
		//string strPlotLabel = ftoa(dConfidenceLevel) + "% " + _L("conf") + ". " + _L("ellipse") + "(" + _L(lpcszDataLabel) + ")";
		string strPlotLabel = ftoa(dConfidenceLevel) + "% " + _L("conf") + ". " + _L("ellipse") + "(" + GetLocalized(lpcszDataLabel) + ")";
		/// end FIX_ERROR_LOCALIZED
		///end CLEAN_UP_LOCALIZATION_STRINGS
		///end CLEAN_UP_LOCALIZATION_THINGS
		///end WRONG_PRECISION_COVERTED_TO_STRING
		///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
		//AddGraphDataTable(trOp, index, nTotalNumData, lpcszDataLabel, "FitCurves", "FitCurves"/*strNodeName*/, nTableID, IDST_TEMP_ONE_SET, vEllipseX, lpcszDataLabel + "X", vEllipseY, strPlotLabel, 0, nGraphType, bDo);///Arvin 11/15/06 LR_RESULT_TABLE_HAS_WRONG_COMMENT
		
		//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
		// label of all sub tables of ResultCurves will be put to column parameters label when report, need remove Parameters row, see #13285-P2 a. point. 
		/*
		string strTableLabel;
		if(IsSeparateSheetForDataset(trOp))
			strTableLabel = _L("Fit Curve"); //Corresponding to columns' comment
		else
			strTableLabel = _L("Fitted Values"); //Corresponding to columns' parameters
		*/
		string strTableLabel = ""; 
		//---end CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
		//Arvin 07/20/07 WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT
		if (grLayAppar)
		{
			grLayAppar.ConvertByAxis(vEllipseX, vEllipseX.GetSize(), OKAXISTYPE_X, FALSE);
			grLayAppar.ConvertByAxis(vEllipseY, vEllipseY.GetSize(), OKAXISTYPE_Y, FALSE);
		}
		///end WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT
		///Cheney 2007-10-27 CLEAN_UP_LOCALIZATION_THINGS
		//AddGraphDataTable(trOp, index, nTotalNumData, lpcszDataLabel, "FitCurves", strTableLabel/*strNodeName*/, nTableID, IDST_TEMP_ONE_SET, vEllipseX, lpcszDataLabel + "X", vEllipseY, strPlotLabel, 0, nGraphType, bDo, lpcszDataLabelCurves);///Arvin 11/15/06 LR_RESULT_TABLE_HAS_WRONG_COMMENT
		/// Hong 11/07/07 v.8.0742 FIX_ERROR_LOCALIZED
		//AddGraphDataTable(trOp, index, nTotalNumData, lpcszDataLabel, "FitCurves", strTableLabel/*strNodeName*/, nTableID, IDST_TEMP_ONE_SET, vEllipseX, _L(lpcszDataLabel) + _L("X"), vEllipseY, strPlotLabel, 0, nGraphType, bDo, lpcszDataLabelCurves);///Arvin 11/15/06 LR_RESULT_TABLE_HAS_WRONG_COMMENT
		AddGraphDataTable(trOp, index, nTotalNumData, lpcszDataLabel, "FitCurves", strTableLabel/*strNodeName*/, nTableID, IDST_TEMP_ONE_SET, vEllipseX, GetLocalized(lpcszDataLabel) + _L("X"), vEllipseY, strPlotLabel, 0, nGraphType, bDo, lpcszDataLabelCurves);///Arvin 11/15/06 LR_RESULT_TABLE_HAS_WRONG_COMMENT
		/// end FIX_ERROR_LOCALIZED
		///end CLEAN_UP_LOCALIZATION_THINGS
		///end CENTRALIZE_FITTING_RESULT_LABELS
		return true;
	}
	
	///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
	//void AddGraphDataTable(TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, 
		//LPCSTR lpcszTableName, LPCSTR lpcszTableLabel, int nTableID, int nSubTableID, vector &vX, LPCSTR lpcszXLabel, vector &vY, LPCSTR lpcszYLabel, int nGraphIndex = 0, int nGraphType = 0, bool bDo = true)
	void AddGraphDataTable(TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, 
		LPCSTR lpcszTableName, LPCSTR lpcszTableLabel, int nTableID, int nSubTableID, vector &vX, LPCSTR lpcszXLabel, vector &vY, LPCSTR lpcszYLabel, int nGraphIndex = 0, int nGraphType = 0, bool bDo = true, LPCSTR lpcszDataLabelCurves = NULL)
	///end CENTRALIZE_FITTING_RESULT_LABELS
	{		
		///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion	
		//TreeNode	trOneTable =
		//	CheckCreateOneResultCurvesTable(trOp, index, nTotalNumData, nGraphIndex, lpcszTableName, nTableID, lpcszTableLabel, strDataLabel);
		TreeNode	trOneTable =
			CheckCreateOneResultCurvesTable(trOp, index, nTotalNumData, nGraphIndex, lpcszTableName, nTableID, lpcszTableLabel, lpcszDataLabelCurves);
		///end CENTRALIZE_FITTING_RESULT_LABELS
		if(trOneTable)
		{
			TreeNode  	trRow; 
			string strNodeX = strDataLabel + "X"; 
			string strNodeY = strDataLabel + "Y";
			trRow = tree_check_get_node(trOneTable, strNodeX, IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, lpcszXLabel);
			if(bDo)
			{
				trRow.dVals = vX;
				trRow.ID = make_one_set_ID(nSubTableID + nGraphType * 2 + 1, index);	
				trRow.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_X);  ///Iris 9/17/05 INCLUDE_RESIDUAL_IN_FIT_CURVE_BRANCH
			}
			else
			{
				trRow.Remove();
			}
			
			trRow = tree_check_get_node(trOneTable, strNodeY, IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, lpcszYLabel);
			if(bDo)
			{
				trRow.dVals = vY;	
				trRow.ID = make_one_set_ID(nSubTableID + nGraphType * 2 + 2, index);		
				trRow.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);  ///Iris 9/17/05 INCLUDE_RESIDUAL_IN_FIT_CURVE_BRANCH
			}
			else
			{
				trRow.Remove();
			}
		}
	}
	
	
	BOOL	CalcOneData(TreeNode &trOp, int index, int nTotalNumData, const vector<int> &vFactorSizes,
		const vector<string> &vsFactors, vector &vY, vector &vX, matrix &mMultiIndep, vector &vWeights, DWORD dwPlotObjUID, int nRowColIndex, const vector<int>& vintRowsInSource = NULL)
	{
		if(  FitRegression::CalcOneData(trOp, index, nTotalNumData, vFactorSizes, vsFactors, vY, vX, mMultiIndep, vWeights, dwPlotObjUID, nRowColIndex, vintRowsInSource) )
			///Arvin 07/20/07 WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT
			//return AddConfidenceEllipseTable(trOp, index, nTotalNumData, vX, vY, vWeights);
		///Kyle 04/09/2009 QA80-3224-P2 SHOW_SELECTED_METHOD_IN_REPORT_NOTES
			//return AddConfidenceEllipseTable(trOp, index, nTotalNumData, vX, vY, vWeights, dwPlotObjUID);
		{
			bool bRet = AddConfidenceEllipseTable(trOp, index, nTotalNumData, vX, vY, vWeights, dwPlotObjUID);
			/// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
			//if(bRet && GetOptionIndex(trOp.GUI) )
			if(bRet && GetFitLinearType(trOp) )	
			///end FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
				uppdateNotesMethod(trOp);
			return bRet;
		}
		///End SHOW_SELECTED_METHOD_IN_REPORT_NOTES
			///end WRONG_CONF_ELLIPSE_FOR_APPARENT_FIT
		else
			return false;
	}
	
	///Arvin 08/28/07 QA70-10073-P4 KEEP_CUSTOMIZATION_COLOR_OF_ELLIPSE_AFTER_RECALCULATE
	/*
	bool SetupPlotDetails(const TreeNode& trOp, GraphLayer& gl, int nFittedPlot, int nNumPlots = 1, int nGraphIndex = 0, int nDataIndex = 0, bool bIsSourceGraph = false, bool bUpdateExistedReportGraph = false)
	{		
		if( !FitterOperation::SetupPlotDetails(trOp, gl, nFittedPlot, nNumPlots, nGraphIndex, nDataIndex, bIsSourceGraph, bUpdateExistedReportGraph) )
			return false;

		if(GRAPH_FIT_CURVE == nGraphIndex)
		{
			DataPlot dp;
			int nIndex = gl.DataPlots.Count() - 1;
			if( IsAddEllipsePlot(trOp, IDE_FIT_MEAN) ) 
			{
				
				dp = gl.DataPlots( nIndex-- );
				dp.SetColor(4, true);
			}

			if( IsAddEllipsePlot(trOp, IDE_FIT_PREDICTION) ) 
			{
				dp = gl.DataPlots( nIndex-- );
				dp.SetColor(6, true);
			}
		}
		
		return true;
	}
	*/
	///END KEEP_CUSTOMIZATION_COLOR_OF_ELLIPSE_AFTER_RECALCULATE
	
	///Arvin 02/14/08 QA70-11094 SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
	DWORD GetOutputOptions(const TreeNode& trOp)
	{
		DWORD dwOptions = FitterOperation::GetOutputOptions(trOp);
		dwOptions |= REPORT_PLOT_ALL_PLOTS_IN_ONE_GRAPH; 
		return dwOptions;
	}
	///end SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
	
///Kyle 03/31/2009 QA80-3224 NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR
private:
	/// Iris 8/13/2009 QA80-14134 FIX_FIND_INCORRECT_X_FROM_Y_FOR_APPARENT_FIT
	bool convertByAxis(TreeNode& trOp, int nIndex, vector& vData, int nAxis, bool bForward)
	{
		DataRange dr;
		GetInput(dr);
		
		DWORD dwRules = GetDataRules(trOp);
		DWORD dwPlotObjUID;
		dr.GetData(dwRules, nIndex, &dwPlotObjUID, NULL, NULL);
		
		GraphLayer	grLayAppar;
		if ( dwPlotObjUID && IsApparentFit(trOp) )
		{
			DataPlot		dpl;
			dpl = Project.GetObject(dwPlotObjUID);
			if (dpl.IsValid())
				dpl.GetParent(grLayAppar);
			
			vector vTransf(vData.GetSize());
			if ( grLayAppar && grLayAppar.ConvertByAxis(vData, vData.GetSize(), nAxis, bForward, vTransf) )
			{
				vData = vTransf;
				return true;
			}
			return false;
		}
		return true;
	}
	///end FIX_FIND_INCORRECT_X_FROM_Y_FOR_APPARENT_FIT
	
	int 	linearFitXYError(int nMethod, vector &vY, vector &vX, vector &vyError, vector& vxError,
				FitParameter* psFitParameter, uint nSizeFitParams)
	{
		// Equation : y = da * x + db
		double da, db, dae, dbe;
		int nRet;
		bool 	bHasXErr = vxError.GetSize()>0,
				bHasYErr = vyError.GetSize()>0;
		switch(nMethod)
		{
		case method_york:
			nRet = ocmath_linear_fit_xyerror_york(vX, vX.GetSize(),
											vY, vY.GetSize(),
											bHasXErr ? vxError : NULL_DOUBLE_POINTER, vxError.GetSize(),
											bHasYErr ? vyError : NULL_DOUBLE_POINTER, vyError.GetSize(),
											&db, &da, &dae, &dbe);
			break;
			
		case method_fv:
			nRet = ocmath_linear_fit_xyerror_fv(vX, vY, bHasXErr ? vxError : NULL_DOUBLE_POINTER, bHasYErr ? vyError : NULL_DOUBLE_POINTER, vX.GetSize(), 0.0001, 500,
												&da, &db, NULL, &dae, &dbe, NULL, NULL);
			break;
			
		case method_ripley:
			nRet = ocmath_linear_fit_xyerror_ripley(vX, vY, bHasXErr ? vxError : NULL_DOUBLE_POINTER, bHasYErr ? vyError : NULL_DOUBLE_POINTER, vX.GetSize(),
													&db, &da, &dae, &dbe);
			break;
			
		default:
			ASSERT(FALSE);
		}
		
		if(nSizeFitParams < 2)
		{
			ASSERT(FALSE);
			return 1;
		}
		psFitParameter[0].Value = db;
		psFitParameter[0].Error = dbe;
		psFitParameter[1].Value = da;
		psFitParameter[1].Error = dae;
		
 		return nRet;

	}
	int 	getComputationMethod(const TreeNode& trGUI)
	{
		return (trGUI.Fit && trGUI.Fit.method) ? trGUI.Fit.method.nVal : 0;
	}
	
	/// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
	/*
	BOOL 	filterGUIWithXError(TreeNode& trGUI)
	{
		if( FIT_LINEAR_WITH_X_ERROR != GetOptionIndex(trGUI) )
			return FALSE;
	*/	
	BOOL 	filterGUIWithXError(TreeNode& trOp)
	{
		if( FIT_LINEAR_WITH_X_ERROR != GetFitLinearType(trOp) )	
			return FALSE;
		TreeNode	trGUI = trOp.GUI;
	///end FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
		
		TreeNode 	trFit 			= trGUI.Fit,
					trQuantities 	= trGUI.Quantities,
					trResAnalysis 	= trGUI.ResAnalysis,
					trOutput 		= trGUI.Output,
					trGraph1 		= trGUI.Graph1,
					trCalibration 	= trGUI.Calibration,
					trResiduals 	= trGUI.Residuals;

		if(trFit)
		{
			TreeNode trMethod = trFit.InsertNode( trFit.ErrBarWeight, "method", TRGP_ENUM_LIST);
			trMethod.DataID = IDE_FIT_WITH_X_ERROR_METHOD;
			trMethod.nVal = 0;
			trMethod.SetAttribute(STR_LABEL_ATTRIB, _L("Computation Method"));
			trMethod.SetAttribute(STR_COMBO_ATTRIB, "York|FV|Ripley");
			
			trFit.ErrBarWeight.Enable = false;					// change with method changed,
			//trFit.ErrBarWeight.SetAttribute(STR_COMBO_ATTRIB, _L("Direct Weighting|Instrumental"));
			
			TreeNode trn = trFit.YWeight;
			while(trn)
			{
				trn.Show = false;
				trn = trn.NextNode;
			}
		}

		if(trQuantities)
		{
			TreeNode trParameters = trQuantities.Parameters;
			if(trParameters)
			{
				trParameters.Shared.Show = false;
				trParameters.Fix.Show = false;
				TreeNode tr = trParameters.LCL;
				while(tr)
				{
					tr.Show = false;
					tr = tr.NextNode;
				}
			}
			TreeNode trn = trQuantities.Statistics;
			while(trn)
			{
				trn.Show = false;
				trn = trn.NextNode;
			}
		}
		
		if(trResAnalysis)
			trResAnalysis.Show = false;

		if(trGraph1)
		{
			TreeNode trn = trGraph1.ConfBands;
			while(trn)
			{
				trn.Show = false;
				trn = trn.NextNode;
			}
		}

		if(trResiduals)
			trResiduals.ResType.Show = false;

		tree_uncheck_all_hidden_check_boxes(trGUI);

		return true;
		
	}
///End NEW_OPTION_TO_SUPPORT_LINEAR_FIT_WITH_ERROR_BAR

	///Kyle 04/09/2009 QA80-3224-P2 SHOW_SELECTED_METHOD_IN_REPORT_NOTES
	void uppdateNotesMethod(TreeNode& trOp)
	{
		TreeNode trNotes = trOp.Calculation.Notes;
		TreeNode trMethod = trNotes.Method;
		if(!trMethod)
		{
			TreeNode	trOutWT = trNotes.Weight;
			if(trOutWT)
				trMethod = trNotes.InsertNode(trOutWT.NextNode, "Method");
			else
				trMethod = trNotes.AddNode("Method");
		}
		trMethod.DataID = IDE_NOTES_METHOD;
		trMethod.SetAttribute(STR_LABEL_ATTRIB, _L("Method"));
		trMethod.Show = true;
		
		int nMethod = getComputationMethod(trOp.GUI);
		string strMethod;
		switch(nMethod)
		{
		case method_york:
			strMethod = "York";
			break;
	
		case method_fv:
			strMethod = "FV";
			break;
			
		case method_ripley:
			strMethod = "Ripley";
			break;
		}
	
		trMethod.strVal = strMethod;
	
	}
	///End SHOW_SELECTED_METHOD_IN_REPORT_NOTES



};	  
