#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	method_ave,
	method_concatenate,
};
enum{
	avex_same,
	avex_common,
	avex_full,
	avex_custom,
	avex_trace,
};
enum{
	interp_linear,
	interp_spline,
	interp_bspline,
};
enum{
	sortx_none,
	sortx_ascend,
	sortx_descend,
};
//put additional include files here
#include	<XFbase.h>
#include	<ReportTree.h>
#include	<analysis_utils.h>
#include	<o8dlg.h>

/***************************************************************************************
/// Modification Log :
/// Folger 07/23/08 BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS
/// CPY 10/30/08 QA70-12411-P3 AVECURVES_XF_CREATES_HIDDEN_REPORT_WHEN_TREE_AS_OUTPUT
/// Hong 03/10/09 QA80-13243 RECONSTRUCT_GUI_SUGGESTED_BY_EASWAR
/// Hong 03/13/09 FIX_RUN_FROM_LT_WITHOUT_DLG_FAIL_GET_AUTO_VALUE
///	Hong 03/13/09 QA80-13243 CONCATENATE_NEED_SORT_X_OPTION
/// Hong 03/13/09 QA80-13243 AVE_CURVE_USE_DIFF_COLOR_FOR_MORE_DISTINGUISHABLE
/// Hong 03/13/09 FIX_CHANGE_THEME_AND_CHECK_AUTO_OF_NPTS_FAIL_AUTU_VALUE
/// Sandy 03/13/09  QA80-13260 ADD_PREVIEW
/// Hong 03/13/09 MIN_MAX_SHOULD_BE_AUTO_WHEN_DISABLE
/// Hong 03/16/09 MIN_MAX_SHOULD_BE_AUTO_WHEN_DISABLE
/// Kyle 03/13/2009 QA80-13260-S1 ADD_OPTION_TO_COPY_FORMAT_FROM_SOURCE_LAYER
/// Hong 03/16/09 QA80-13281 XF_AVECURVES_NEED_ACTION_FILTER_TAG_SUPPORT_TO_IGNORE_AVERAGE_CURVE
/// Hong 03/17/09 QA80-13260 FIX_AUTO_VALUE_NOT_UPDATE_WHEN_INPUT_CHANGE
/// Hong 03/18/09 FIX_PREVIEW_FAIL_RECOVERY_AFTER_CORRECT_ERROR_OF_NPTS
/// Hong 03/18/09 ADD_ERROR_CHECKING_OF_NPTS
/// Kyle 03/20/2009 SAME_COLOR_FOR_SOURCE_AND_RED_FOR_RESULT_IN_PREVIEW_GRAPH
/// Kyle 03/20/2009 ADD_OPTION_TO_SPECIFY_FORMAT_OF_DATA_PLOT
/// Hong 04/02/09 FIX_FAIL_AUTO_XMAN_IF_OPEN_DLG_WITH_THEME_WHICH_IS_FULL_RANGE_AUTO_UNCEHCK
/// Kyle 07/28/2009 QA80-14026 FIX_WRONG_LEGEND_FOR_PREVIEW
/// Kyle 10/09/2009 CENTRALIZE_ERROR_CEHCKING
/// Iris 10/13/09 QA70-14403 PREVIEW_GRAPH_SHOULD_NEVER_RESCALE_ON_CHANGE
///	Hong 10/22/09 NO_NEED_CHECK_NPTS_IF_NOT_USED
/// Folger 01/22/09 QA81-15004 AVERAGE_CURVES_CREATE_EMPTY_SHEET_IF_INPUT_INVALID
/// Kyle 02/09/2010 CHECK_X_MIN_MAX_ONLY_WHEN_IT_IS_AVAIABLE
/// Kyle 04/06/2010 QA80-13243-P1 BEFORE_EXECUTE_TAKE_CARE_OF_THE_ERROR
/// Kyle 04/06/2010 QA80-13243-P2 ONINITGRID_NEEDS_MORE_ERROR_CHECKING
///	Jasmine 08/13/2010 ORG-172-S2 CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
***************************************************************************************/
static bool s_bInit = false;
static string s_strErrMsg = "";
static bool s_bIsFromUpdatePreview = false;		///Kyle 03/20/2009 SAME_COLOR_FOR_SOURCE_AND_RED_FOR_RESULT_IN_PREVIEW_GRAPH
//put your own support static functions here
/*
enum{
	AVE_REPULICA,
	AVE_BY_INTERP_OR_TOLER,
	CONCATENATE
};
*/
enum _AVE_RDID {
	_AVE_RDID_TABLE	= 100,
	_AVE_RDID_AVEX,		
	_AVE_RDID_AVEY, 	
	_AVE_RDID_SD, 
	_AVE_RDID_SE, 
	_AVE_RDID_N
};

static void _update_tree_shown(TreeNode& trGetN)
{
	/// Hong 03/10/09 QA80-13243 RECONSTRUCT_GUI_SUGGESTED_BY_EASWAR
	/*
	trGetN.sd.Show 		 = true;
	trGetN.se.Show 		 = true;
	trGetN.n.Show 		 = true;
	trGetN.interp.Show 	 = true;
	trGetN.toler.Show 	 = true;
	trGetN.segments.Show = true;
	
	if(trGetN.method.nVal == method_concatenate)
	{
		trGetN.sd.Show 		 = false;
		trGetN.se.Show 		 = false;
		trGetN.n.Show 		 = false;
		trGetN.interp.Show 	 = false;
		trGetN.toler.Show 	 = false;
		trGetN.segments.Show = false;
	}
	else if(trGetN.method.nVal == method_ave)
	{
		trGetN.interp.Show 	 = false;
		trGetN.toler.Show 	 = false;
		trGetN.segments.Show = false;
	}
	else
	{
		trGetN.toler.Show = trGetN.interp.nVal == interp_none? true : false;
	}
	*/
	bool		bShowOpts = (method_ave == trGetN.method.nVal) ? true : false;
	/// Hong 03/13/09 QA80-13243 CONCATENATE_NEED_SORT_X_OPTION
	trGetN.sortx.Show	= !bShowOpts;
	/// end CONCATENATE_NEED_SORT_X_OPTION

	trGetN.avex.Show	= bShowOpts;
	trGetN.sd.Show 		= bShowOpts;
	trGetN.se.Show 		= bShowOpts;
	trGetN.n.Show 		= bShowOpts;
	
	bool	bShowOpt = (avex_same == trGetN.avex.nVal) ? true : false;
	bShowOpt &= bShowOpts;
	trGetN.toler.Show	= bShowOpt;
	
	bShowOpt = (avex_same != trGetN.avex.nVal && avex_trace != trGetN.avex.nVal) ? true : false;
	bShowOpt &= bShowOpts;
	trGetN.xmin.Show	= bShowOpt;
	trGetN.xmax.Show	= bShowOpt;
	
	bShowOpt = (avex_same != trGetN.avex.nVal) ? true : false;
	bShowOpt &= bShowOpts;
	trGetN.npts.Show	= bShowOpt;
	trGetN.interp.Show	= bShowOpt;
	
	bool	bEnable = (avex_custom == trGetN.avex.nVal) ? true : false;
	trGetN.xmin.Enable	= bEnable;
	trGetN.xmax.Enable	= bEnable;
	/// Hong 03/16/09 MIN_MAX_SHOULD_BE_AUTO_WHEN_DISABLE
	/* Hong, the following fix have refreshing problem, as in VC level, only set the auto status when create control.
	/// Hong 03/13/09 MIN_MAX_SHOULD_BE_AUTO_WHEN_DISABLE
	if ( !bEnable )
	{
		TreeNode	trXMin = trGetN.xmin;
		TreeNode	trXMax = trGetN.xmax;
		octree_set_auto_support(&trXMin);
		octree_set_auto_support(&trXMax);
	}
	/// end MIN_MAX_SHOULD_BE_AUTO_WHEN_DISABLE
	*/
	/// end MIN_MAX_SHOULD_BE_AUTO_WHEN_DISABLE
	/// end RECONSTRUCT_GUI_SUGGESTED_BY_EASWAR
}

///Cheney 2007-6-7 ADD_AN_ERR_CHECK_FUNC
static int _check_err_condition(TreeNode& trGetN)
{
	int nErr = CER_NO_ERROR;

	/// Max 7/11/07 QA70-6073 should support only 1 curve averaging
	/*
	if(2 > get_input_xyrange_num(trGetN.iy))
		nErr = CER_XY_TOO_FEW;
	*/
	/// Max 7/26/07 QA70-6073 AVE_MULTI_CURVES_SUPPORT_ONE_CURVE
	/*
	///Cheney 2007-7-18 AVE_MULTI_CURVES_NEED_TWO_CURVES_INPUT
	//if(1 > get_input_xyrange_num(trGetN.iy))
	//	nErr = XFERR_AT_LEAST_ONE_XYRANGE;
	if(get_input_xyrange_num(trGetN.iy) < 2)
		nErr = XFERR_AT_LEAST_TWO_XYRANGES;
	///end AVE_MULTI_CURVES_NEED_TWO_CURVES_INPUT
	*/
	if(1 > get_input_xyrange_num(trGetN.iy))
		nErr = XFERR_AT_LEAST_ONE_XYRANGE;
	/// END AVE_MULTI_CURVES_SUPPORT_ONE_CURVE
	return nErr;
}
///end ADD_AN_ERR_CHECK_FUNC

/// Hong 03/10/09 QA80-13243 RECONSTRUCT_GUI_SUGGESTED_BY_EASWAR
static bool _get_data_tirm_both_end(vector& vx, vector& vy, const XYRange& rg, int indexData, DWORD dwDataRules)
{
	DataRange	drSub;
	if ( !rg.GetSubRange(drSub, dwDataRules, indexData) )
	{
		ASSERT(FALSE);
		return false;
	}
	XYRange		xySub(drSub);
	if ( !xySub )
		return false;
	// Hong QA80-13243, trim missing value at both end as easwar said
	Curve		crv(0, xySub);
	crv.TrimLeft(TRUE);
	crv.TrimRight(TRUE);

	if ( !crv.CopyData(vx, vy) )
		return false;
	
	return true;
}

/// Hong 03/18/09 ADD_ERROR_CHECKING_OF_NPTS
static int _get_min_npts()
{
	return 2;
}
/// end ADD_ERROR_CHECKING_OF_NPTS

/// Hong 03/17/09 QA80-13260 FIX_AUTO_VALUE_NOT_UPDATE_WHEN_INPUT_CHANGE
//static int _check_init_auto(TreeNode& trGetN)
static int _check_init_auto(TreeNode& trGetN, bool* pbGetNChanged = NULL)
/// end FIX_AUTO_VALUE_NOT_UPDATE_WHEN_INPUT_CHANGE
{
	/// Hong 03/17/09 QA80-13260 FIX_AUTO_VALUE_NOT_UPDATE_WHEN_INPUT_CHANGE
	if ( pbGetNChanged )
		*pbGetNChanged = false;
	/// end FIX_AUTO_VALUE_NOT_UPDATE_WHEN_INPUT_CHANGE
	/// Hong 03/16/09 MIN_MAX_SHOULD_BE_AUTO_WHEN_DISABLE
	/*
	TreeNode		trXMin = trGetN.xmin;
	bool			bAutoXMin = (1 == octree_get_auto_support(&trXMin)) ? true : false;
	TreeNode		trXMax = trGetN.xmax;
	bool			bAutoXMax = (1 == octree_get_auto_support(&trXMax)) ? true : false;
	TreeNode		trNPts = trGetN.npts;
	bool			bAutoNPts = (1 == octree_get_auto_support(&trNPts)) ? true : false;
	if ( (!tree_is_visible(trXMin) && !tree_is_visible(trXMax) && !tree_is_visible(trNPts)) || ( !bAutoXMin && !bAutoXMax && !bAutoNPts) )
		return CER_NO_ERROR;
	*/
	TreeNode		trXMin = trGetN.xmin, trXMax = trGetN.xmax, trNPts = trGetN.npts;
	bool			bAutoXMin = ( (1 == octree_get_auto_support(&trXMin) || !tree_is_editable(trXMin)) && tree_is_visible(trXMin) ) ? true : false;
	bool			bAutoXMax = ( (1 == octree_get_auto_support(&trXMax) || !tree_is_editable(trXMax)) && tree_is_visible(trXMax) ) ? true : false;
	bool			bAutoNPts = (1 == octree_get_auto_support(&trNPts) && tree_is_visible(trNPts) ) ? true : false;
	if ( !(bAutoXMin || bAutoXMax || bAutoNPts) )
		return CER_NO_ERROR;
	/// end MIN_MAX_SHOULD_BE_AUTO_WHEN_DISABLE
	XYRange 		iy;
	TreeNode		trInput = trGetN.iy;
	if ( !okxf_resolve_tree_construct_range(&trInput, &iy) )
		return CER_INVALID_RANGE;
	
	DWORD			dwDataRules = DRR_GET_MISSING | DRR_BAD_WEIGHT_TREATMENT | DRR_GET_DEPENDENT | DRR_NO_FACTORS;
	int				nNumData = iy.GetNumData(dwDataRules);
	if ( 0 == nNumData )
		return CER_INVALID_RANGE;
	
	bool			bIntersect = (avex_same == trGetN.avex.nVal || avex_common == trGetN.avex.nVal) ? true : false;
	bool			bNoValidData = true;
	double			dXMin, dXMax;
	int				nNumTotalPts(0);
	vector			vx, vy;
	for ( int ii = 0; ii < nNumData; ii++ )
	{
		if ( !_get_data_tirm_both_end(vx, vy, iy, ii, dwDataRules) || 0 == vy.GetSize() )
			continue;
		
		nNumTotalPts += vy.GetSize();
		
		double		dMin, dMax;
		int			nMinIdx;
		vx.GetMinMax(dMin, dMax, &nMinIdx);
		if ( -1 == nMinIdx )
			continue;
		
		if ( !bNoValidData )
			dXMin = bIntersect ? max(dXMin, dMin) : min(dXMin, dMin);
		else
			dXMin = dMin;
			
		if ( !bNoValidData )
			dXMax = bIntersect ? min(dXMax, dMax) : max(dXMax, dMax);
		else
			dXMax = dMax;
		bNoValidData = false;
	}
	if ( bAutoXMin )
		trXMin.dVal = dXMin;
	if ( bAutoXMax )
		trXMax.dVal = dXMax;
	if ( bAutoNPts )
	{
		/// Hong 03/18/09 ADD_ERROR_CHECKING_OF_NPTS
		//trNPts.nVal = min(1000, nNumTotalPts / nNumData * 5);
		trNPts.nVal = max(min(1000, nNumTotalPts / nNumData * 5), _get_min_npts());
		/// end ADD_ERROR_CHECKING_OF_NPTS
	}
	
	/// Hong 03/17/09 QA80-13260 FIX_AUTO_VALUE_NOT_UPDATE_WHEN_INPUT_CHANGE
	if ( pbGetNChanged )
		*pbGetNChanged = true;
	/// end FIX_AUTO_VALUE_NOT_UPDATE_WHEN_INPUT_CHANGE
	
	if ( bNoValidData )
		return CER_NO_DATA;
	
	if ( trXMin.dVal > trXMax.dVal )
		return (avex_same == trGetN.avex.nVal) ? XFERR_NO_COMMON_X_RANGE: CER_MIN_MAX;
	
	return CER_NO_ERROR;
}
/// end RECONSTRUCT_GUI_SUGGESTED_BY_EASWAR

///Kyle 10/09/2009 CENTRALIZE_ERROR_CEHCKING
static bool _check_input(TreeNode& trGetN, string& strErrMsg)
{
	if(1 > get_input_xyrange_num(trGetN.iy))
	{
		strErrMsg = XFERR_AT_LEAST_ONE_XYRANGE;
		return false;
	}

	///Kyle 02/09/2010 CHECK_X_MIN_MAX_ONLY_WHEN_IT_IS_AVAIABLE
	if( tree_is_visible(trGetN.xmin) && tree_is_visible(trGetN.xmax) )
	///End CHECK_X_MIN_MAX_ONLY_WHEN_IT_IS_AVAIABLE
	{
		if(trGetN.xmin.dVal > trGetN.xmax.dVal)
		{
			strErrMsg = (avex_same == trGetN.avex.nVal) ? XFERR_NO_COMMON_X_RANGE: CER_MIN_MAX;
			return false;
		}
	}

	int			nMinPts = _get_min_npts();
	///	Hong 10/22/09 NO_NEED_CHECK_NPTS_IF_NOT_USED
	//if ( trGetN.npts.nVal < nMinPts )
	if ( tree_is_visible(trGetN.npts) && trGetN.npts.nVal < nMinPts )
	/// end NO_NEED_CHECK_NPTS_IF_NOT_USED
	{
		strErrMsg = CER_INPUT_ARGUMENT_LESS_THAN_SPECIFIED_VALUE;
		strErrMsg += ":" + _L("Number of Points")+ "|" + nMinPts;
		return false;
	}
	return true;
}
///End CENTRALIZE_ERROR_CEHCKING

//------ Folger 07/23/08 BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS
static	string	_get_output_comments(const XYRange& iy, int nMethod)
{
	vector<string>	vsMethods = {
		"Average",
		"Interpolated average",
		"Concatenate"
	};
	
	string	strRange;
	DWORD	dwRules = DRR_NO_FACTORS | DRR_GET_DEPENDENT;
	int		nNumData = iy.GetNumData(dwRules);
	for ( int ii=0; ii<nNumData; ++ii )
	{
		DataRange drSub;
		iy.GetSubRange(drSub, dwRules, ii);
		if ( drSub )
		{
			strRange += get_input_data_range_string(drSub);
			if ( ii != nNumData - 1 )
				strRange += ", ";
		}
	}
	
	string	strComments;
	strComments.Format("%s of %s", vsMethods[nMethod], strRange);
	return strComments;
}
//------ End BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS

/// Hong 03/13/09 QA80-13243 HARD_TO_GET_DATAPLOT_COLOR_BY_GET_FORMAT
/*
/// Hong 03/13/09 QA80-13243 AVE_CURVE_USE_DIFF_COLOR_FOR_MORE_DISTINGUISHABLE
static bool _check_get_unused_color(const GraphLayer& gl, int& nColor)
{
	Tree			trFmt;
	int				nMinIndexColor = SYSCOLOR_BLACK, nMaxIndexColor = SYSCOLOR_DKGRAY;
	vector<int>		vnIndexColorUsed(nMaxIndexColor - nMinIndexColor + 1);
	vnIndexColorUsed = 0;
	foreach ( DataPlot dp in gl.DataPlots )
	{
		trFmt = dp.GetFormat(FPB_STYLE_COLOR, FOB_ALL, TRUE, TRUE);
		if ( !trFmt.Root || trFmt.Root.IsEmpty() )
			continue;
		ASSERT(trFmt.Root.Symbol.EdgeColor);
		int	 		nClr = trFmt.Root.Symbol.EdgeColor.nVal;
		if ( nMinIndexColor <= nClr && nClr <= nMaxIndexColor )
			vnIndexColorUsed[nClr] = 1;
	}
	int				nPos = find_in_list(0, vnIndexColorUsed, false);
	if ( -1 != nPos )
	{
		nColor = nPos;
		return true;
	}
	return false;
}
/// end AVE_CURVE_USE_DIFF_COLOR_FOR_MORE_DISTINGUISHABLE
*/
/// end HARD_TO_GET_DATAPLOT_COLOR_BY_GET_FORMAT
static void	_run_avecurves_on_current_data(TreeNode& trGetN, PageBase& pgTemp, Worksheet& wksTemp)
{
	XYRange xy, xySim;	
	///Kyle 03/20/2009 SAME_COLOR_FOR_SOURCE_AND_RED_FOR_RESULT_IN_PREVIEW_GRAPH
	//if(!init_preview_graph(trGetN.iy, pgTemp, wksTemp, NULL, &xy, &xySim))
		//return;
	xy_range_from_GetN_data_node(trGetN.iy, xy);
	///End SAME_COLOR_FOR_SOURCE_AND_RED_FOR_RESULT_IN_PREVIEW_GRAPH
	int method = trGetN.method.nVal;
	int avex = trGetN.avex.nVal;
	double toler = trGetN.toler.dVal;
	int npts = trGetN.npts.nVal;
	
	double xmin = trGetN.xmin.dVal;
	double xmax = trGetN.xmax.dVal;
	
	int interp = trGetN.interp.nVal;

 	int sortx = trGetN.sortx.nVal;
 	int sd = trGetN.sd.nVal;
 	int se = trGetN.se.nVal;
 	int n  = trGetN.n.nVal;
 	
 	int			nOldNumCols = 0; /// Hong 03/18/09 FIX_PREVIEW_FAIL_RECOVERY_AFTER_CORRECT_ERROR_OF_NPTS
	Tree trReport;
	ReportData rdTemp(trReport);
	if(wksTemp)
	{
		nOldNumCols = wksTemp.GetNumCols(); /// Hong 03/18/09 FIX_PREVIEW_FAIL_RECOVERY_AFTER_CORRECT_ERROR_OF_NPTS
		wksTemp.SetSize(-1, 0);
	}
	rdTemp.SetWorksheet(wksTemp);

	s_bIsFromUpdatePreview = true;		///Kyle 03/20/2009 SAME_COLOR_FOR_SOURCE_AND_RED_FOR_RESULT_IN_PREVIEW_GRAPH
	try {
		avecurves(xy,method, avex, toler, npts, xmin, xmax, interp, sortx, sd, se, n, rdTemp);
	}
	catch(int nErr)
	{
		/// Hong 03/18/09 FIX_PREVIEW_FAIL_RECOVERY_AFTER_CORRECT_ERROR_OF_NPTS
		if ( wksTemp )
			wksTemp.SetSize(-1, nOldNumCols);
		/// end FIX_PREVIEW_FAIL_RECOVERY_AFTER_CORRECT_ERROR_OF_NPTS
	}
	
	///Kyle 03/20/2009 SAME_COLOR_FOR_SOURCE_AND_RED_FOR_RESULT_IN_PREVIEW_GRAPH, Column in wksTemp will be removed before run the body, so add plot after the body
	s_bIsFromUpdatePreview = false;
	if(!init_preview_graph(trGetN.iy, pgTemp, wksTemp, NULL, &xy, &xySim))
		return;
	///End SAME_COLOR_FOR_SOURCE_AND_RED_FOR_RESULT_IN_PREVIEW_GRAPH

	/// Iris 10/13/09 QA70-14403 PREVIEW_GRAPH_SHOULD_NEVER_RESCALE_ON_CHANGE
	/*
	// Kyle 09/22/2009 rescale preview
	GraphPage gp = pgTemp;
	GraphLayer gl = gp.Layers(0);
	if(gl)
		gl.Rescale();
	*/
	///end PREVIEW_GRAPH_SHOULD_NEVER_RESCALE_ON_CHANGE
	
}

void avecurves(const XYRange& iy, const int& method, const int& avex, const double& toler, const int& npts, const double& xmin, const double& xmax, const int& interp, const int& sortx, const int& sd, const int& se, const int& n, ReportData& rd)
{
	/// Max 06/10/08 v8.0881 RENAME_XF_AVERAGE_TO_AVERAGEXY_DUE_TO_CONFLICT_WITH_LT
	//string		strXFNameInner = "average";
	string		strXFNameInner = "averagexy";
	///---
	
	XFBase		xf(strXFNameInner);
	if ( !xf )
		XF_THROW(XFERR_FAIL_LOAD_XF);
	
	vector vx, vy, vsd, vse, vn;
	/// Hong 03/10/09 QA80-13243 RECONSTRUCT_GUI_SUGGESTED_BY_EASWAR
	//if ( !xf.SetArgs(iy, method, interp, toler, segments, vx, vy, vsd, vse, vn) )
	/// Hong 03/13/09 QA80-13243 CONCATENATE_NEED_SORT_X_OPTION
	//if ( !xf.SetArgs(iy, method, avex, toler, npts, xmin, xmax, interp, vx, vy, vsd, vse, vn) )
	if ( !xf.SetArgs(iy, method, avex, toler, npts, xmin, xmax, interp, sortx, vx, vy, vsd, vse, vn) )
	/// end CONCATENATE_NEED_SORT_X_OPTION
	/// end RECONSTRUCT_GUI_SUGGESTED_BY_EASWAR
		XF_THROW(XFERR_FAIL_SET_ARG);
	
	if ( !xf.Evaluate() )
		XF_THROW(XFERR_FAIL_EVAL);
	
	
	//output reslut
	//------ Folger 07/23/08 BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS
	//ReportTable rtAve = rd.CreateTable("Result", _L("Averaged Curve"), _AVE_RDID_TABLE);
	ReportTable rtAve = rd.CreateTable("Result", _get_output_comments(iy, method), _AVE_RDID_TABLE);
	//------
	rtAve.AddColumn(vx, "AveX", _AVE_RDID_AVEX, "Averaged X", OKDATAOBJ_DESIGNATION_X);
	rtAve.AddColumn(vy, "AveY", _AVE_RDID_AVEY, "Averaged Y");
	
	if (sd && vsd.GetSize() > 0)  // check vector size for forbidding user input wrong thing by script window
		rtAve.AddColumn(vsd, "SD", _AVE_RDID_SD, "Standard Deviation", OKDATAOBJ_DESIGNATION_ERROR);
	
	if(se && vse.GetSize() > 0)
		rtAve.AddColumn(vse, "SE", _AVE_RDID_SE, "Standard Error",OKDATAOBJ_DESIGNATION_ERROR);
	
	if (n && vn.GetSize() > 0)
		rtAve.AddColumn(vn, "N", _AVE_RDID_N, "Count");
	
	//plot average curve
	ReportTree rpTree;
	//------ Folger 07/23/08 BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS
	//rpTree = rd.FindNodeByAttribute(STR_LABEL_ATTRIB, _L("Averaged Curve"));
	rpTree = rd.GetNode("Result");
	//------
	int nTableID = rpTree.ID;
	int nXID = nTableID + 1, nYID = nTableID + 2;
	DataRange dr;
	//----- CPY 10/30/08 QA70-12411-P3 AVECURVES_XF_CREATES_HIDDEN_REPORT_WHEN_TREE_AS_OUTPUT
	//if(!rd.GetDataRange(dr, nTableID, nXID, &nYID))
	//	XF_THROW(XFERR_GET_DATA_FAILED);
	///Sophy 3/16/2009 v8.0956 FIX_AVECURVES_NOT_SHOW_FULL_RANGE_ON_CHANGE_PARAM
	//int nErr = rd.GetDataRange(dr, nTableID, nXID, &nYID);
	int nErr = rd.GetDataRange(dr, nTableID, nXID, &nYID, 1, TRUE, false, TRUE);
	///end FIX_AVECURVES_NOT_SHOW_FULL_RANGE_ON_CHANGE_PARAM
	///------ Folger 01/22/09 QA81-15004 AVERAGE_CURVES_CREATE_EMPTY_SHEET_IF_INPUT_INVALID
	//if(0 == nErr)
		//return; // no actual wks to hold report data, must be Tree or loose dataset
	//if(nErr < 0)
	if ( nErr <= 0 )
	///------ End AVERAGE_CURVES_CREATE_EMPTY_SHEET_IF_INPUT_INVALID
		XF_THROW(XFERR_GET_DATA_FAILED);
	//----- end AVECURVES_XF_CREATES_HIDDEN_REPORT_WHEN_TREE_AS_OUTPUT
	
	/// Hong 03/16/09 QA80-13281 XF_AVECURVES_NEED_ACTION_FILTER_TAG_SUPPORT_TO_IGNORE_AVERAGE_CURVE
	tag_columns_in_data_range(dr, "AveCurves"); // Hong, should be the same as options string "FT" of iy
	/// end XF_AVECURVES_NEED_ACTION_FILTER_TAG_SUPPORT_TO_IGNORE_AVERAGE_CURVE
	
	DataPlot dpData;
	///Kyle 03/20/2009 SAME_COLOR_FOR_SOURCE_AND_RED_FOR_RESULT_IN_PREVIEW_GRAPH
	//if(iy.GetPlot(dpData))	// check If data is from a graph
	vector<uint> vUID;
	if(iy.GetPlots(vUID) > 0 && !s_bIsFromUpdatePreview)	// check If data is from a graph, and no need to do the option if from update preview graph
	///End SAME_COLOR_FOR_SOURCE_AND_RED_FOR_RESULT_IN_PREVIEW_GRAPH
	{
		///Kyle 03/20/2009 SAME_COLOR_FOR_SOURCE_AND_RED_FOR_RESULT_IN_PREVIEW_GRAPH
		dpData = (DataPlot)Project.GetObject(vUID[0]);
		if(!dpData.IsValid())
			return;
		///End SAME_COLOR_FOR_SOURCE_AND_RED_FOR_RESULT_IN_PREVIEW_GRAPH
		/// Hong 03/13/09 QA80-13243 AVE_CURVE_USE_DIFF_COLOR_FOR_MORE_DISTINGUISHABLE
		//if(!xf_check_plot_output_rng_in_source_rng_graph(iy, dr, NULL, dpData.GetPlotType()))
		GraphLayer	gl;
		dpData.GetParent(gl);
		ASSERT(gl);
		
		///Kyle 03/20/2009 ADD_OPTION_TO_SPECIFY_FORMAT_OF_DATA_PLOT
		///// Hong 03/13/09 QA80-13243 HARD_TO_GET_DATAPLOT_COLOR_BY_GET_FORMAT
		////int			nColor = SYSCOLOR_RED;
		////_check_get_unused_color(gl, nColor);
		//int			nCountIndexColor = SYSCOLOR_DKGRAY - SYSCOLOR_BLACK + 1;
		//int			nOffset = 2; // Hong, our system theme have skip some color for group increment, like green, so this offset is necessary
		//int			nColor = (gl.DataPlots.Count() + nOffset) % nCountIndexColor;
		///// end HARD_TO_GET_DATAPLOT_COLOR_BY_GET_FORMAT
		//if(!xf_check_plot_output_rng_in_source_rng_graph(iy, dr, NULL, dpData.GetPlotType(), nColor))
		///// end AVE_CURVE_USE_DIFF_COLOR_FOR_MORE_DISTINGUISHABLE
		bool bRet;
		if( iy.GetNumData(DRR_NO_FACTORS | DRR_GET_DEPENDENT) > 1 )
			bRet = xf_check_plot_output_rng_in_source_rng_graph(iy, dr, NULL, dpData.GetPlotType(), SYSCOLOR_RED, GAP_GROUP_PLOTS | GAP_USE_TEMPLATE | GAP_ALLOW_DUPLICATE_COL, false, NULL, PLOT_OUTPUT_FORMAT_THICKNESS);
		else
			bRet = xf_check_plot_output_rng_in_source_rng_graph(iy, dr, NULL, dpData.GetPlotType(), SYSCOLOR_RED);
		if(!bRet)
		///End ADD_OPTION_TO_SPECIFY_FORMAT_OF_DATA_PLOT
			XF_THROW(XFERR_FAILED_ADD_PLOT)
	}
	/// END SUPPORT_WKS_DATA_SOURCE
}

//nEventID < 0 on event, like GETNE_ON_INIT, GETNE_ON_OK etc, >0 on change from control
//return 0 to do nothing, return PEVENT_GETN_RET_TO_CLOSE to close dialog
//dwEnables = bOKEnable, bBTN1Enable, bBTN2Enable, bBTN3Enable, , can set to false to disable OK/Apply buttons
//lpcszNodeName = the trGetN TreeNode tag name that generates the event, or is  if GETNE_ON_OK etc
//strAux = optional string for XF Wizard Bar, like DLG_NEED_CHANGE_GRID etc, it will be invalid if from internal node value change event
//strErrMsg = allowing messages to be shown
int avecurves_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return avecurves_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	//_update_tree_shown(trGetN);
	//
	/////Cheney 2007-6-14 PROCEED_WITH_DLG_SHOULD_IF_ERR
	////int nErr = CER_NO_ERROR;	
	////if (2 > get_input_xyrange_num(trGetN.iy))
	////{
		////strErrMsg = CER_XY_TOO_FEW;		
		////bOKEnable = false;
	////}
	//int nErr = _check_err_condition(trGetN);
	//if(nErr != CER_NO_ERROR)
	//{
		//strErrMsg = nErr;		
		//bOKEnable = false;
	//}
	/////end PROCEED_WITH_DLG_SHOULD_IF_ERR
	//
	///// Hong 03/10/09 QA80-13243 RECONSTRUCT_GUI_SUGGESTED_BY_EASWAR
	///// Hong 03/13/09 FIX_RUN_FROM_LT_WITHOUT_DLG_FAIL_GET_AUTO_VALUE
	////if ( CER_NO_ERROR == nErr && (nEventID == GETNE_ON_INIT || !lstrcmpi(lpcszNodeName, "iy") || !lstrcmpi(lpcszNodeName, "method")
	////	 || !lstrcmpi(lpcszNodeName, "avex") || !lstrcmpi(lpcszNodeName, "xmin") || !lstrcmpi(lpcszNodeName, "xmax")) )
	///// Hong 03/13/09 FIX_CHANGE_THEME_AND_CHECK_AUTO_OF_NPTS_FAIL_AUTU_VALUE
	////if ( CER_NO_ERROR == nErr && (!lstrcmpi(lpcszNodeName, "iy") || !lstrcmpi(lpcszNodeName, "method")
	////		|| !lstrcmpi(lpcszNodeName, "avex") || !lstrcmpi(lpcszNodeName, "xmin") || !lstrcmpi(lpcszNodeName, "xmax")) )
	//if ( CER_NO_ERROR == nErr && (GETNE_ON_THEME == nEventID || !lstrcmpi(lpcszNodeName, "iy") || !lstrcmpi(lpcszNodeName, "method") || !lstrcmpi(lpcszNodeName, "npts")
		//|| !lstrcmpi(lpcszNodeName, "avex") || !lstrcmpi(lpcszNodeName, "xmin") || !lstrcmpi(lpcszNodeName, "xmax")) )
	///// end FIX_CHANGE_THEME_AND_CHECK_AUTO_OF_NPTS_FAIL_AUTU_VALUE
	///// end FIX_RUN_FROM_LT_WITHOUT_DLG_FAIL_GET_AUTO_VALUE
	//{
		//nErr = _check_init_auto(trGetN);
		//if ( CER_NO_ERROR != nErr )
		//{
			//strErrMsg = nErr;
			//bOKEnable = false;
		//}
	//}
	///// end RECONSTRUCT_GUI_SUGGESTED_BY_EASWAR
	//
	//return true;
	return false;

}

int avecurves_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	return false;
}
//nGetNDialog = 0,1,2, corresponding to the XF GetN dropdown, 0 = dialog is not used
//you can change nRet to be one of XFEVT_PROCEED (defualt), XFEVT_ABORT, XFEVT_PROCEED_NO_DLG or XFEVT_PROCEED_WITH_DLG(when nGetNDialog = 0)
//nGetNDialog = -1 when Ok on GetN dialog to allow handler to preocess <auto> etc variables
//dwCntrl is combination of bits
//LTXF_FROM_GUI_MENU, LTXF_FROM_GUI_PROMPT, LTXF_FROM_AUTO_UPDATE, LTXF_FROM_FUNCTION, LTXF_THEME_USED, LTXF_CHANGE_PARAM
void avecurves_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	
	//------ fisher 11/16/07 ADD_MAP_ID_TO_CHM
	if(is_use_origin_chm())
		trGetN.SetAttribute(STR_HELPID_ATTRIB, IDD_XF_avecurves);
	
	/// Hong 03/13/09 FIX_RUN_FROM_LT_WITHOUT_DLG_FAIL_GET_AUTO_VALUE
	/*
	//_update_tree_shown(trGetN);
	///Cheney 2007-6-14 PROCEED_WITH_DLG_SHOULD_IF_ERR
	if(0 == nGetNDialog && (dwCntrl&LTXF_THEME_USED) && (dwCntrl&LTXF_FROM_GUI_MENU)
		/// Hong 03/10/09 QA80-13243 RECONSTRUCT_GUI_SUGGESTED_BY_EASWAR
		//&& _check_err_condition(trGetN) != CER_NO_ERROR)
		&& (_check_err_condition(trGetN) != CER_NO_ERROR || CER_NO_ERROR != _check_init_auto(trGetN)) )
		/// end RECONSTRUCT_GUI_SUGGESTED_BY_EASWAR
		nRet = XFEVT_PROCEED_WITH_DLG;	
	///end PROCEED_WITH_DLG_SHOULD_IF_ERR
	*/
	if ( is_xf_startup(nGetNDialog, dwCntrl) )
	{
		int			nErr = _check_err_condition(trGetN);
		string		strErrMsg;		///Kyle 04/06/2010 QA80-13243-P1 BEFORE_EXECUTE_TAKE_CARE_OF_THE_ERROR
		if ( CER_NO_ERROR == nErr )
		{
			/// Hong 04/02/09 FIX_FAIL_AUTO_XMAN_IF_OPEN_DLG_WITH_THEME_WHICH_IS_FULL_RANGE_AUTO_UNCEHCK
			// Hong, function _check_init_auto depend on trNode Enable/Shown status, so need update before calling
			_update_tree_shown(trGetN);			
			/// end FIX_FAIL_AUTO_XMAN_IF_OPEN_DLG_WITH_THEME_WHICH_IS_FULL_RANGE_AUTO_UNCEHCK
			nErr = _check_init_auto(trGetN);
			
			///Kyle 10/09/2009 CENTRALIZE_ERROR_CEHCKING
			if(nErr == CER_NO_ERROR)
			{
				//string strErrMsg;		///Kyle 04/06/2010 QA80-13243-P1 BEFORE_EXECUTE_TAKE_CARE_OF_THE_ERROR
				if(!_check_input(trGetN, strErrMsg))
				{
					nErr = 1;			// an error, any one is fine
				}
			}
			///End CENTRALIZE_ERROR_CEHCKING
		}
	
		///Kyle 04/06/2010 QA80-13243-P1 BEFORE_EXECUTE_TAKE_CARE_OF_THE_ERROR
		//if ( CER_NO_ERROR != nErr && 0 == nGetNDialog && (dwCntrl&LTXF_THEME_USED) && (dwCntrl&LTXF_FROM_GUI_MENU) )
		//	nRet = XFEVT_PROCEED_WITH_DLG;
		if( CER_NO_ERROR != nErr )
		{
			if( (dwCntrl&LTXF_THEME_USED) && nGetNDialog <= 0 )
				nRet = XFEVT_PROCEED_WITH_DLG;
			else if( nGetNDialog <= 0 )
			{
				if( strErrMsg.IsEmpty() )
					strErrMsg = nErr;
				xf_warning_msg_box(strErrMsg, false);
				nRet = XFEVT_ABORT;
			}
		}
		///End BEFORE_EXECUTE_TAKE_CARE_OF_THE_ERROR
		
		s_bIsFromUpdatePreview = false;		///Kyle 03/20/2009 SAME_COLOR_FOR_SOURCE_AND_RED_FOR_RESULT_IN_PREVIEW_GRAPH
	}
	/// end FIX_RUN_FROM_LT_WITHOUT_DLG_FAIL_GET_AUTO_VALUE
}
//nEventID < 0 on event, like GETNE_ON_INIT, GETNE_ON_OK etc, >0 on change from control
//return 0 to do nothing, return PEVENT_GETN_RET_TO_CLOSE to close dialog
//dwEnables = bOKEnable, bBTN1Enable, bBTN2Enable, bBTN3Enable, , can set to false to disable OK/Apply buttons
//lpcszNodeName = the trGetN TreeNode tag name that generates the event, or is  if GETNE_ON_OK etc
//strAux = optional string for XF Wizard Bar, like DLG_NEED_CHANGE_GRID etc, it will be invalid if from internal node value change event
//strErrMsg = allowing messages to be shown
int avecurves_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}


// put your grid initialization here
// you may also initialize wksTemp here
static void GetNGraphPreview_OnInitGrid(TreeNode& trGetN, PageBase& pgTemp, Datasheet& wksTemp,
PictureControl& pict, // optional tab for showing an image or EMF, as requested in OnDialogSetup 
DWORD& dwUpdateGraph,  // default to 0, UPDATE_GRAPH_CHANGED to cause graphs to be updated, UPDATE_GRAPH_INVALID to disable preview button
DWORD& dwUpdateGrid, // default to 0, set to UPDATE_GRID_SIMPLE to update the DynaControl grid, UPDATE_GRID_RESET to reset DynaControl grid
DWORD& dwEnables,// bOKEnable, bBTN1Enable, bBTN2Enable and bBTN3Enable :default to true, can set to false to disable buttons
string& strErrMsg) // optional err msg to be shown on dialog
{
	DECLARE_BUTTON_ENABLES
	DECLARE_UPDATE_GRAPH
	DECLARE_UPDATE_GRID
	bUpdateGraph = true;
	
	///update gui
	_update_tree_shown(trGetN);
	
	int nErr = _check_err_condition(trGetN);
	///Kyle 04/06/2010 QA80-13243-P2 ONINITGRID_NEEDS_MORE_ERROR_CHECKING
	if( nErr == CER_NO_ERROR )
	{
		bool	bGetNChange;
		nErr = _check_init_auto(trGetN, &bGetNChange);
		bUpdateGrid |= bGetNChange;
	}
	///End ONINITGRID_NEEDS_MORE_ERROR_CHECKING
	if(nErr != CER_NO_ERROR)
	{
		strErrMsg = nErr;		
		bOKEnable = false;
	}
	///Kyle 04/06/2010 QA80-13243-P2 ONINITGRID_NEEDS_MORE_ERROR_CHECKING
	else
	{
		bOKEnable = _check_input(trGetN, strErrMsg);
	}
	///End ONINITGRID_NEEDS_MORE_ERROR_CHECKING
	
	//if ok, set data to temp worksheet
	///Kyle 07/28/2009 QA80-14026 FIX_WRONG_LEGEND_FOR_PREVIEW, always init the temp worksheet
	//if(bOKEnable)
	bUpdateGraph = bOKEnable;
	///End FIX_WRONG_LEGEND_FOR_PREVIEW
	{
		Worksheet wks = wksTemp;
		wks.SetSize(-1, 2, WSS_CLEAR_DATA);
		wks.SetColDesignations("XY");
		wks.Columns(1).SetLongName("avecurves");
	}

	s_bInit = false;
	s_strErrMsg = strErrMsg; //keep the err message for OnInitGraph;
}

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

// pgTemp is the graph for preview or control
// wksTemp is the the temp wks created to hold data to plot into pgTemp
static void GetNGraphPreview_OnInitGraph(TreeNode& trGetN, PageBase& pgTemp, Datasheet& wksTemp,
PictureControl& pict, // optional tab for showing an image or EMF, as requested in OnDialogSetup  
DWORD& dwUpdateGrid, // default to 0, set to UPDATE_GRID_SIMPLE to update the DynaControl grid, UPDATE_GRID_RESET to reset DynaControl grid
DWORD& dwEnables,// bOKEnable, bBTN1Enable, bBTN2Enable and bBTN3Enable :default to true, can set to false to disable buttons
string& strErrMsg) // optional err msg to be shown on dialog
{
	DECLARE_BUTTON_ENABLES
	DECLARE_UPDATE_GRID
	strErrMsg = s_strErrMsg; 
	///Jasmine 08/13/2010 ORG-172-S2 CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
	//GraphPage gp = pgTemp;
	//page_load(gp, "NonePreview"); 	
	//
	//load_text_for_nonepreview_graphpage(gp, TEMPLATE_NONE_PREVIEW_CONTENT, TEMPLATE_NONE_PREVIEW_HINTS);
	xf_load_nopreview(pgTemp);
	///End CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
}

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

static void GetNGraphPreview_OnUpdateGraph(TreeNode& trGetN, PageBase& pgTemp, Datasheet& wksTemp, PictureControl& pict)
{
	Worksheet wks = wksTemp;
	if(!s_bInit)
	{
		Worksheet wks = wksTemp;
		wks.SetSize(0,-1, true);

		///Kyle 03/13/2009 QA80-13260-S1 ADD_OPTION_TO_COPY_FORMAT_FROM_SOURCE_LAYER
		//init_preview_graph(trGetN.iy, pgTemp, wks, "CurvePreview");
		init_preview_graph(trGetN.iy, pgTemp, wks, "CurvePreview", NULL, NULL, 0, 0, 1, PREVIEW_LAYER_FORMAT_SCALE_TYPE);
		///End ADD_OPTION_TO_COPY_FORMAT_FROM_SOURCE_LAYER

		GraphPage gp = pgTemp;
		gp.Refresh(true);
		s_bInit = true;
	}

	_run_avecurves_on_current_data(trGetN, pgTemp, wks);
}

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

static void GetNGraphPreview_OnChange(TreeNode& trGetN, TreeNode& trNode, PageBase& pgTemp, Datasheet& wksTemp,
PictureControl& pict, // optional tab for showing an image or EMF that might be present, as requested in OnDialogSetup  
bool bChangedByGraph, // called when graph has been modified by user, like dragging a vertical line
DWORD& dwUpdateGraph,  // default to 0, UPDATE_GRAPH_CHANGED to cause graphs to be updated, UPDATE_GRAPH_INVALID to disable preview button
DWORD& dwUpdateGrid,  // default to 0, set to UPDATE_GRID_SIMPLE to update the DynaControl grid, UPDATE_GRID_RESET to reset DynaControl grid
DWORD& dwEnables,	// bOKEnable, bBTN1Enable, bBTN2Enable and bBTN3Enable :default to true, can set to false to disable buttons
string& strErrMsg) // optional err msg to be shown on dialog
{
	DECLARE_BUTTON_ENABLES
	DECLARE_UPDATE_GRAPH
	DECLARE_UPDATE_GRID
	_update_tree_shown(trGetN);
	
	int nErr = _check_err_condition(trGetN);
	if(nErr != CER_NO_ERROR)
	{
		strErrMsg = nErr;		
		bOKEnable = false;
	}
	
	/// Hong 03/13/09 FIX_CHANGE_THEME_AND_CHECK_AUTO_OF_NPTS_FAIL_AUTU_VALUE
	/*
	if(trNode && CER_NO_ERROR == nErr )
	{
		if (  trNode.tagName =="iy" ||  trNode.tagName =="method"||  trNode.tagName =="npts"
			|| trNode.tagName =="avex" ||  trNode.tagName =="xmin"||  trNode.tagName =="xmax")
		{
	*/
	if( CER_NO_ERROR == nErr )
	{
		// Hong, right now, in OnChange, seem no way to distingush GETNE_ON_THEME event, 
		// the only thing known is that in this event, trNode will be invalid, but seem other event like GETNE_ON_INIT will make it invalid too
		// code below should be updated once we have mechanism to determine it.
		if ( !trNode || trNode.tagName =="iy" ||  trNode.tagName =="method"||  trNode.tagName =="npts"
			|| trNode.tagName =="avex" ||  trNode.tagName =="xmin"||  trNode.tagName =="xmax")
		{
	/// end FIX_CHANGE_THEME_AND_CHECK_AUTO_OF_NPTS_FAIL_AUTU_VALUE
			/// Hong 03/17/09 QA80-13260 FIX_AUTO_VALUE_NOT_UPDATE_WHEN_INPUT_CHANGE
			//nErr = _check_init_auto(trGetN);
			bool	bGetNChange;
			nErr = _check_init_auto(trGetN, &bGetNChange);
			bUpdateGrid |= bGetNChange;
			/// end FIX_AUTO_VALUE_NOT_UPDATE_WHEN_INPUT_CHANGE
			if ( CER_NO_ERROR != nErr )
			{
				strErrMsg = nErr;
				bOKEnable = false;
			}
			///Kyle 10/09/2009 CENTRALIZE_ERROR_CEHCKING
			///// Hong 03/18/09 ADD_ERROR_CHECKING_OF_NPTS
			//if ( !trNode || trNode.tagName =="npts" )
			//{
				//int			nMinPts = _get_min_npts();
				//if ( trGetN.npts.nVal < nMinPts )
				//{
					//strErrMsg = CER_INPUT_ARGUMENT_LESS_THAN_SPECIFIED_VALUE;
					//strErrMsg += ":" + _L("Number of Points")+ "|" + nMinPts;
					//bOKEnable = false;
				//}
			//}
			///// end ADD_ERROR_CHECKING_OF_NPTS
			///End CENTRALIZE_ERROR_CEHCKING
		}
		///Kyle 10/09/2009 CENTRALIZE_ERROR_CEHCKING
		if(CER_NO_ERROR == nErr)
		{
			bOKEnable = _check_input(trGetN, strErrMsg);
		}
		///End CENTRALIZE_ERROR_CEHCKING
	
		if (trNode && trNode.tagName =="iy")
		{
			s_bInit = false;
		}
	}
	
	if(!bOKEnable)
		dwUpdateGraph = UPDATE_GRAPH_INVALID; //nUpdateGraph = UPDATE_GRAPH_ERROR;
	else
		bUpdateGraph = bOKEnable;
}

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

}

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

}
//------------
//
static void GetNGraphPreview_OnCustomButton(TreeNode& trGetN, int nButton, PageBase& pgTemp, Datasheet& wksTemp,
PictureControl& pict, // optional tab for showing an image or EMF that might be present, as requested in OnDialogSetup  
bool bChangedByGraph, // called when graph has been modified by user, like dragging a vertical line
DWORD& dwUpdateGraph,  // default to 0, UPDATE_GRAPH_CHANGED to cause graphs to be updated, UPDATE_GRAPH_INVALID to disable preview button
DWORD& dwUpdateGrid,  // default to 0, set to UPDATE_GRID_SIMPLE to update the DynaControl grid, UPDATE_GRID_RESET to reset DynaControl grid
DWORD& dwEnables,	// bOKEnable, bBTN1Enable, bBTN2Enable and bBTN3Enable :default to true, can set to false to disable buttons
string& strErrMsg) // optional err msg to be shown on dialog
{
	DECLARE_BUTTON_ENABLES
	DECLARE_UPDATE_GRAPH
	DECLARE_UPDATE_GRID

}
//


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


//This file is the template for GetNEvent4

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

