#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	stats_min,
	stats_max,
	stats_mean,
	stats_median,
	stats_sum,
	stats_count,
	stats_freq,
};
enum{
	base_x,
	base_y,
	base_specific,
};
//put additional include files here
#include <GetNBox.h>
#include <control.h>
#include <event_utils.h>
#include <report_utils.h>
#include <o8dlg.h>
#include <ReportTree.h>
//enum
//{
	//ERR_DATARANGE_GETDATA_FAILED = XF_LOCAL_ERR_BEGIN
//};
//
//
//data id for tree in 2d binning		

/*------------------------------------------------------------------------------*
///	Modification Log:
///	Kyle 03/11/2009 QA80-13251 ADD_NEW_2D_STATS_AND_OUTPUT_TO_WORKSHEET
///	Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
/// Max 3/12/09 v8.0953c_new QA70-13251 RENAME_VAR_coordinate_TO_bin
/// Kyle 03/18/2009 QA80-13251 BETTER_FORMAT_FOR_ftoa_TO_CONSTRUCT_BIN_ENDS
/// Kyle 03/20/2009 SET_NUMBER_OF_INTERVAL_AS_READ_ONLY
/// Kyle 03/25/2009 QA80-13251-P4 SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
/// Kyle 03/26/2009 ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
/// Kyle 03/26/2009 ADD_UTIL_FUNCTION_TO_GET_DESCRIPTION_FROM_XYRANGE
/// Kyle 03/28/2009 NEW_TABLE_FOR_SUB_TOTAL_COUNT
/// Kyle 04/09/2009 SHOW_MORE_INFO_ABOUT_INPUT_DATA_IN_THE_GROUP_BRANCH
/// Kyle 05/11/2009 QA80-13521 SUPPORT_PERIODICAL_BINS,, CPY 5/6/09 NEED_TO_REDO_PERIODICAL_SUPPORT
/// Kyle 05/15/2009 QA80-13521 ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
/// Iris 6/25/2009 QA80-13289-S1 CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT
/// Kyle 07/10/2009 QA80-13521-P1 SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
/// Kenny 08/25/2009 QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC
/// Hong 09/09/09 QA90-14287 2DBINNING_SUPPORT_HANDLE_MIN_MAX
/// Hong 12/08/09 QA80-14710 FIX_3D_BAR_WIDTH_CHANGED_AFTER_RECALCULATE
/// Kyle 06/30/2010 ORG-209 EXPAND_2D_BINNING_TO_SUPPORT_ADDITIONAL_Y_COLUMN
/// Kyle 07/01/2010 ORG-209-P1 UPDATE_INCLUDE_OUTLIERS_ON_CHECK_SEPARATELY_COUNT_MAXIMUM
 *------------------------------------------------------------------------------*/
/*	use enum created by XF frame
enum _2D_BINNING_COORDINATE{
	_2D_BINNING_COORDINATE_BIN_CENTER,
	_2D_BINNING_COORDINATE_BIN_END
};
*/
#define BAR_PLOT_ID	100
#define IMAGE_ID	110

/// Hong 09/09/09 QA90-14287 2DBINNING_SUPPORT_HANDLE_MIN_MAX
enum
{
	bin_center,
	bin_end,
	xbin_center = bin_center,
	xbin_end,
	ybin_center = bin_center,
	ybin_end,
};

enum{
	step_by_inc,
	step_by_interval
};

enum{
	order_ascend,
	order_descend,
};
/// end 2DBINNING_SUPPORT_HANDLE_MIN_MAX

	
//put your own support static functions here
/// Iris 6/25/2009 QA80-13289-S1 CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT
/*
static int	_get_include_outliers_type(const int nIncMin, const int nIncMax, int& iStart, int& iEnd)
{
	if(nIncMin && nIncMax)
	{
		iStart	= 1;
		iEnd	= 1;
		return FAB_INCLUDE_BOTH_OUTLIER_BIN;
	}
	else
	{
		if(nIncMin)
		{	
			iStart	= 1;
			iEnd	= 0;
			return FAB_INCLUDE_LESS_DMIN_BIN;
		}
		else if(nIncMax)
		{
			iStart	= 0;
			iEnd	= 1;
			return FAB_INCLUDE_MORE_DMAX_BIN;
		}
		else
		{		
			iStart	= 0;
			iEnd	= 0;
			return FAB_NOT_INCLUDE_OUTLIERS;
		}
	}

}

static void _update_initial_val_x_y(TreeNode& trGetN)
{
 	TreeNode trTemp = trGetN.iy;
	if( trTemp )
	{
		XYRange rgXY;
		okxf_resolve_tree_construct_range(&trTemp, &rgXY);
		if( rgXY )
		{
			vector vX;
			vector vY;
			rgXY.GetData(vY, vX);
			if (0 != vX.GetSize() || 0 != vY.GetSize())
			{
				///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
				//set_round_limits(vX, trGetN.xmin, trGetN.xmax, trGetN.xinc, trGetN.xintervals, trGetN.xstepby.nVal);
				//set_round_limits(vY, trGetN.ymin, trGetN.ymax, trGetN.yinc, trGetN.yintervals, trGetN.ystepby.nVal);
				/// Max 3/12/09 v8.0953c_new QA70-13251 RENAME_VAR_coordinate_TO_bin
				//set_round_limits(vX, trGetN.xmin, trGetN.xmax, trGetN.xinc, trGetN.xintervals, trGetN.xstepby.nVal, trGetN.coordinate.nVal == _2D_BINNING_COORDINATE_BIN_CENTER);
				//set_round_limits(vY, trGetN.ymin, trGetN.ymax, trGetN.yinc, trGetN.yintervals, trGetN.ystepby.nVal, trGetN.coordinate.nVal == _2D_BINNING_COORDINATE_BIN_CENTER);
				set_round_limits(vX, trGetN.xmin, trGetN.xmax, trGetN.xinc, trGetN.xintervals, trGetN.xstepby.nVal, trGetN.xbin.nVal == xbin_center);
				set_round_limits(vY, trGetN.ymin, trGetN.ymax, trGetN.yinc, trGetN.yintervals, trGetN.ystepby.nVal, trGetN.ybin.nVal == ybin_center);
				/// END RENAME_VAR_coordinate_TO_bin
				///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END	
			}
		}
	}	
}
*/
///end CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT

static int _safe_compare(double dVal1, double dVal2)
{
	if(is_equal(dVal1, dVal2))
		return 0;
	else if(dVal1 < dVal2)
		return -1;
	else
		return 1;
}

///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
//static bool check_inc(const double dMin, const double dMax, const double dInc)
static bool check_inc(const double dMin, const double dMax, const double dInc, bool bByBinCenter)
///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
{
	///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	//if(dInc <= 0.0 || dInc > (dMax - dMin)/2)
	///Kyle 03/25/2009 QA80-13251-P4 SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN, one bin should be allowed
	//if(dInc <= 0.0 || dInc > (bByBinCenter ? (dMax - dMin) : (dMax - dMin)/2))			// if dMin, dMax are bin centers, one bin is excluded
	if(dInc <= 0.0 || (bByBinCenter ? (_safe_compare(dMin, dMax) > 0) : (_safe_compare(dInc, dMax - dMin) > 0)))
	///End SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
	///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
		return false;
	
	return true;

}
static int _twodbinning_check_input(TreeNode& trGetN)
{
	///Kyle 06/30/2010 ORG-209 EXPAND_2D_BINNING_TO_SUPPORT_ADDITIONAL_Y_COLUMN
	bool bNeedRefCol = stats_count != trGetN.stats.nVal && stats_freq != trGetN.stats.nVal;
	bool bRefColSpe = bNeedRefCol && base_specific == trGetN.base.nVal;
	
	trGetN.base.Show = bNeedRefCol;
	trGetN.col.Show = bRefColSpe;
	///End EXPAND_2D_BINNING_TO_SUPPORT_ADDITIONAL_Y_COLUMN
	
	///Kyle 05/11/2009 QA80-13521 SUPPORT_PERIODICAL_BINS
	trGetN.x.period.Show = trGetN.x.periodical.nVal ? true : false;
	trGetN.y.period.Show = trGetN.y.periodical.nVal ? true : false;
	
	///Kyle 07/01/2010 ORG-209-P1 UPDATE_INCLUDE_OUTLIERS_ON_CHECK_SEPARATELY_COUNT_MAXIMUM
	/////Kyle 05/15/2009 QA80-13521 ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
	//trGetN.x.border.outleft.Show = trGetN.x.periodical.nVal ? false : true;
	//trGetN.y.border.outleft.Show = trGetN.y.periodical.nVal ? false : true;
	//
	//string strOutliersLabel = trGetN.x.periodical.nVal ? _L("Include Outliers") : _L("Include Outliers >= Maximum");
	//trGetN.x.border.outright.SetAttribute(STR_LABEL_ATTRIB, strOutliersLabel);
	//
	//strOutliersLabel = trGetN.y.periodical.nVal ? _L("Include Outliers") : _L("Include Outliers >= Maximum");
	//trGetN.y.border.outright.SetAttribute(STR_LABEL_ATTRIB, strOutliersLabel);
	/////End ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
	_update_include_outliers(trGetN.x);
	_update_include_outliers(trGetN.y);
	///End UPDATE_INCLUDE_OUTLIERS_ON_CHECK_SEPARATELY_COUNT_MAXIMUM

	///Kyle 03/11/2009 QA80-13251 ADD_NEW_2D_STATS_AND_OUTPUT_TO_WORKSHEET 
	int nMDynaUseChk, nWDynaUseChk;
	///Kyle 03/27/2009 USE_REPORTDATA
	//trGetN.ow.GetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, nWDynaUseChk);
	trGetN.rd.GetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, nWDynaUseChk);
	///End USE_REPORTDATA
	trGetN.om.GetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, nMDynaUseChk);
	
	///Kyle 03/28/2009 NEW_TABLE_FOR_SUB_TOTAL_COUNT
	trGetN.subcount.Show = nWDynaUseChk && (trGetN.stats.nVal == stats_sum || trGetN.stats.nVal == stats_count || trGetN.stats.nVal == stats_freq);
	///End NEW_TABLE_FOR_SUB_TOTAL_COUNT
	
	trGetN.bar.Show = nMDynaUseChk;
	trGetN.image.Show = nMDynaUseChk;


	if ( 1 != get_input_xyrange_num(trGetN.iy))
	{
		return CER_NOT_ONE_XYRANGE;		
	}
	
	///Kyle 06/30/2010 ORG-209 EXPAND_2D_BINNING_TO_SUPPORT_ADDITIONAL_Y_COLUMN
	//if (1 > get_input_xyrange_data_size(trGetN.iy))
	int nSize = get_input_xyrange_data_size(trGetN.iy);
	if (1 > nSize )
	///End EXPAND_2D_BINNING_TO_SUPPORT_ADDITIONAL_Y_COLUMN
	{
		return CER_NO_DATA;		
	}
	///Kyle 06/30/2010 ORG-209 EXPAND_2D_BINNING_TO_SUPPORT_ADDITIONAL_Y_COLUMN
	if( bRefColSpe )
	{
		Range rCol;
		TreeNode trCol = trGetN.col;
		if( !(okxf_resolve_tree_construct_range(&trCol, &rCol) && rCol.IsValid() && rCol.GetNumRanges()==1) )
			return XFERR_2D_BINNING_BASE_COLUMN;

		int nRefSize;
		int nErr = check_1_data(rCol, false, false, &nRefSize);
		if( nErr )
			return nErr;

		if( nRefSize != nSize )
			return XFERR_2D_BINNING_BASE_COL_SIZE;
	}
	///End EXPAND_2D_BINNING_TO_SUPPORT_ADDITIONAL_Y_COLUMN
	if (!check_min_max(trGetN.x.min.dVal, trGetN.x.max.dVal) || !check_min_max(trGetN.y.min.dVal, trGetN.y.max.dVal))
	{
		return CER_MIN_MAX;		
	}
	if (!check_intervals(trGetN.x.intervals) || !check_intervals(trGetN.y.intervals))
	{
		return CER_INVALID_INTERVAL_NUM;
	}
	///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	//if (!check_inc(trGetN.xmin.dVal, trGetN.xmax.dVal, trGetN.xinc.dVal) || !check_inc(trGetN.ymin.dVal, trGetN.ymax.dVal, trGetN.yinc.dVal))
	if (!check_inc(trGetN.x.min.dVal, trGetN.x.max.dVal, trGetN.x.inc.dVal, trGetN.x.bin.nVal == xbin_center) || 
		!check_inc(trGetN.y.min.dVal, trGetN.y.max.dVal, trGetN.y.inc.dVal, trGetN.y.bin.nVal == ybin_center))
	///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	{
		return CER_MAX_STEP_SIZE;
	}
	

	if(trGetN.x.periodical.nVal)
	{
		double dMin, dMax;
		dMin = trGetN.x.min.dVal - (trGetN.x.bin.nVal == xbin_center ? trGetN.x.inc.dVal / 2.0 : 0);
		dMax = trGetN.x.max.dVal + (trGetN.x.bin.nVal == xbin_center ? trGetN.x.inc.dVal / 2.0 : 0);
		///Kyle 07/10/2009 QA80-13521-P1 SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
		//if(!_check_min_max_period(trGetN.xperiod.dVal, dMin, dMax))
		if(!_check_min_max_period(trGetN.x.period.dVal, dMin, dMax, trGetN.x.inc.dVal))
		///End SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
			return XFERR_BINNING_CROSS_PERIOD_BOUNDARY;
	}
	if(trGetN.y.periodical.nVal)
	{
			double dMin, dMax;
			dMin = trGetN.y.min.dVal - (trGetN.y.bin.nVal == ybin_center ? trGetN.y.inc.dVal / 2.0 : 0);
			dMax = trGetN.y.max.dVal + (trGetN.y.bin.nVal == ybin_center ? trGetN.y.inc.dVal / 2.0 : 0);
		///Kyle 07/10/2009 QA80-13521-P1 SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
		//if(!_check_min_max_period(trGetN.yperiod.dVal, dMin, dMax))
		if(!_check_min_max_period(trGetN.y.period.dVal, dMin, dMax, trGetN.y.inc.dVal))
		///End SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
			return XFERR_BINNING_CROSS_PERIOD_BOUNDARY;
	}
	///End SUPPORT_PERIODICAL_BINS

	
	if(!nMDynaUseChk && !nWDynaUseChk)
		return XFERR_HILBERT_NO_OUTPUT;
	///End ADD_NEW_2D_STATS_AND_OUTPUT_TO_WORKSHEET
	
	
	return CER_NO_ERROR;
}

/// Iris 6/25/2009 QA80-13289-S1 CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT
/*
/// Max 6/2/08 v8.0875b RUN_WITH_FLYOUT_THEME_REQUIRE_SPECIFY_AUTO_VARIABLES_IN_BEFORE_EXECUTE
static void _init_tree_show(TreeNode& trGetN)
{
	_update_initial_val_x_y(trGetN);

	///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	//freq_update_inc(trGetN.xmin.dVal, trGetN.xmax.dVal, trGetN.xstepby.nVal, trGetN.xoutleft.nVal, trGetN.xoutright.nVal, trGetN.xinc, trGetN.xintervals);
	//freq_update_inc(trGetN.ymin.dVal, trGetN.ymax.dVal, trGetN.ystepby.nVal, trGetN.youtleft.nVal, trGetN.youtright.nVal, trGetN.yinc, trGetN.yintervals);
	freq_update_inc(trGetN.xmin.dVal, trGetN.xmax.dVal, trGetN.xstepby.nVal, trGetN.xoutleft.nVal, trGetN.xoutright.nVal, trGetN.xinc, trGetN.xintervals, trGetN.xbin.nVal == xbin_center);
	freq_update_inc(trGetN.ymin.dVal, trGetN.ymax.dVal, trGetN.ystepby.nVal, trGetN.youtleft.nVal, trGetN.youtright.nVal, trGetN.yinc, trGetN.yintervals, trGetN.ybin.nVal == ybin_center);
	///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	
	///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	_update_min_max_labels(trGetN);
	///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	
	///Kyle 05/11/2009 QA80-13521 SUPPORT_PERIODICAL_BINS
	_update_period(trGetN);
	///End SUPPORT_PERIODICAL_BINS
}
*/
///end CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT

///Kyle 05/11/2009 QA80-13521 SUPPORT_PERIODICAL_BINS
///Kyle 07/10/2009 QA80-13521-P1 SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
//static bool _check_min_max_period(double dPeriod, double dMin, double dMax)
static bool _check_min_max_period(double dPeriod, double dMin, double dMax, double dInc)
///End SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
{
	if(dMin >= dMax)
		return false;
	///Kyle 07/10/2009 QA80-13521-P1 SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
	int nSize = nint( (dMax - dMin) / dInc );
	dMax = dMin + nSize * dInc;
	///End SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
	///Kyle 05/15/2009 QA80-13521 ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
	//if(dMin < -dPeriod || dMax > dPeriod || (dMax-dMin) > dPeriod)
	if((dMax-dMin) > dPeriod)
	///End ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
		return false;

	return true;
}

/// Iris 6/25/2009 QA80-13289-S1 CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT
/*
static void _update_period(TreeNode& trGetN)
{
	if(trGetN.xperiodical.nVal)
	{
		TreeNode trPeriod = trGetN.xperiod;
		if( 1 == octree_get_auto_support(&trPeriod) )
		{
			double dMin, dMax;
			dMin = trGetN.xmin.dVal - (trGetN.xbin.nVal == xbin_center ? trGetN.xinc.dVal / 2.0 : 0);
			dMax = trGetN.xmax.dVal + (trGetN.xbin.nVal == xbin_center ? trGetN.xinc.dVal / 2.0 : 0);
			trPeriod.dVal = _get_auto_period(dMin, dMax);
		}
	}
	if(trGetN.yperiodical.nVal)
	{
		TreeNode trPeriod = trGetN.yperiod;
		if( 1 == octree_get_auto_support(&trPeriod) )
		{
			double dMin, dMax;
			dMin = trGetN.ymin.dVal - (trGetN.ybin.nVal == ybin_center ? trGetN.yinc.dVal / 2.0 : 0);
			dMax = trGetN.ymax.dVal + (trGetN.ybin.nVal == ybin_center ? trGetN.yinc.dVal / 2.0 : 0);
			trPeriod.dVal = _get_auto_period(dMin, dMax);
		}
	}
}

static double _get_auto_period(double dMin, double dMax)
{
	///Kyle 05/15/2009 QA80-13521 ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
	//// max(|dMin|, |dMax|, dMax-dMin)
	//if(dMin >= dMax)
		//return NANUM;
	//double dPeriod = max(dMax - dMin, abs(dMin));
	//dPeriod = max(dPeriod, abs(dMax));
	//return dPeriod;
	if(dMin < dMax)
		return dMax-dMin;
	return NANUM;
	///End ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
}
///End SUPPORT_PERIODICAL_BINS

static string _get_long_name_for_method(int stats)
{
	string strComments;
	switch(stats)
	{
	case stats_min:
		strComments = _L("Minimum");
		break;
	case stats_max:
		strComments = _L("Maximum");
		break;
	case stats_mean:
		strComments = _L("Mean");
		break;
	case stats_median:
		strComments = _L("Median");
		break;
	case stats_sum:
		strComments = _L("Sum");
		break;
	case stats_count:
		strComments = _L("Count");
		break;
	case stats_freq:
		strComments = _L("Percent Frequency");
		break;
	}
	return strComments;
}
//---

///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
static void _update_min_max_labels(TreeNode& trGetN)
{
	string strMinLabel, strMaxLabel;
	
	/// Max 3/12/09 v8.0953c_new QA70-13251 RENAME_VAR_coordinate_TO_bin
	// if(trGetN.coordinate.nVal == _2D_BINNING_COORDINATE_BIN_CENTER)	// bin center
	if(trGetN.xbin.nVal == xbin_center)
	/// ---
	{
		strMinLabel = _L("Minimum Bin Center");
		strMaxLabel = _L("Maximum Bin Center");
	}
	else						// bin end
	{
		strMinLabel = _L("Minimum Bin Beginning");
		strMaxLabel = _L("Maximum Bin End");
	}
	trGetN.xmin.SetAttribute(STR_LABEL_ATTRIB, strMinLabel);
	trGetN.xmax.SetAttribute(STR_LABEL_ATTRIB, strMaxLabel);

	if(trGetN.ybin.nVal == ybin_center)
	{
		strMinLabel = _L("Minimum Bin Center");
		strMaxLabel = _L("Maximum Bin Center");
	}
	else						// bin end
	{
		strMinLabel = _L("Minimum Bin Beginning");
		strMaxLabel = _L("Maximum Bin End");
	}
	trGetN.ymin.SetAttribute(STR_LABEL_ATTRIB, strMinLabel);
	trGetN.ymax.SetAttribute(STR_LABEL_ATTRIB, strMaxLabel);
}
///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END

///Kyle 03/18/2009 QA80-13251 BETTER_FORMAT_FOR_ftoa_TO_CONSTRUCT_BIN_ENDS
// put here for now, one problem
// if inc is much less than min, ftoa(vv[ii]) will get some string no diff
static		int		_calc_num_significant_digits(const vector& vv)
{
	int		nSignDigit = 0;
	for ( int ii = vv.GetSize()-1; ii >= 0; --ii )
	{
		string	str = ftoa(vv[ii], "*");
		int		nPos = str.ReverseFind('E');
		if ( nPos > 0 )
			str = str.Left(nPos);
		if ( (nPos = str.Find('.') ) < 0 )
			continue;

		str = str.Mid(nPos + 1);
		if ( str.GetLength() > nSignDigit )
			nSignDigit = str.GetLength();
	}

	return nSignDigit;
}
///End BETTER_FORMAT_FOR_ftoa_TO_CONSTRUCT_BIN_ENDS

///Kyle 03/27/2009 USE_REPORTDATA
#define TWO_D_BINNING_REPORT_TABLE		0x00000010
#define TWO_D_BINNING_SUBTOTAL_TABLE  	0x00000020
#define TWO_D_BINNING_SUBTOTAL_X		0x00020010
#define TWO_D_BINNING_SUBTOTAL_Y		0x00020011

enum
{
	TWO_D_BINNING_X	= 0x00010010,
	TWO_D_BINNING_Y_BEGIN,
};

static void _get_bin_ends_comments_label(double dMin, double dMax, double dInc, int nOrder, bool bOutLeft, bool bOutRight, vector<string>& vsLabels)
{
	int nDecimalPlaces = log(dInc);
	nDecimalPlaces = nDecimalPlaces >= 0 ? 5 : (- nDecimalPlaces + 5);

	vector vBinEnds;
	vBinEnds.Data(nOrder==0?dMin:dMax, nOrder==0?dMax:dMin, nOrder==0?dInc:-dInc);
	vBinEnds = round(vBinEnds, nDecimalPlaces);

	int nSignDigit = _calc_num_significant_digits(vBinEnds);
	string strFormat = nSignDigit == 0 ? "*" : ("." + nSignDigit);
	vector<string> vsBinEnds;
	vsBinEnds.SetSize(vBinEnds.GetSize());
	for(int ii=vBinEnds.GetSize()-1; ii>=0; ii--)
		vsBinEnds[ii] = ftoa(vBinEnds[ii], strFormat);
	
	int nSize = vsBinEnds.GetSize()-1+bOutLeft+bOutRight;
	vsLabels.SetSize(nSize);
	
	for(ii=vsLabels.GetSize()-1; ii>=0; ii--)
	{
		string strComments;
		if(bOutLeft && (ii==0&&!nOrder || ii==nSize-1&&nOrder))
		{
			if(nOrder)
				strComments.Format("< %s", vsBinEnds[vsBinEnds.GetSize()-1]);
			else
				strComments.Format("< %s", vsBinEnds[0]);
		}
		else if(bOutRight && (ii==nSize-1&&!nOrder || ii==0&&nOrder))
		{
			if(nOrder)
				strComments.Format(">= %s", vsBinEnds[0]);
			else
				strComments.Format(">= %s", vsBinEnds[vsBinEnds.GetSize()-1]);
		}
		else
		{
			int nIndex;
			if(nOrder)
			{
				nIndex = bOutRight ? ii-1 : ii;
				strComments.Format("%s - %s", vsBinEnds[nIndex + 1], vsBinEnds[nIndex]);
			}
			else
			{
				nIndex = bOutLeft ? ii-1 : ii;
				strComments.Format("%s - %s", vsBinEnds[nIndex], vsBinEnds[nIndex + 1]);
			}
		}
		vsLabels[ii] = strComments;
	}

}

static void _2d_binning_update_report_data(	const vector& vxBinEndsOrCenters, const string& strXLongName, 
												const vector& vyBenEndsOrCenters, const string& strUserParamName,
												const vector<string>& vsCommentLabels, int nMethod,
												const matrix& mdResult, const matrix<uint>& mnResult,
												ReportData& outData)
{
	if(!outData)
		return;

	ReportTable rtTwoDBinning = outData.CreateTable("TwoDBin1", "", TWO_D_BINNING_REPORT_TABLE, -1, 1);
	
	string strXColumnName = "A";
	TreeNode trX = rtTwoDBinning.AddColumn(vxBinEndsOrCenters, strXColumnName, TWO_D_BINNING_X, strXLongName, OKDATAOBJ_DESIGNATION_X);
	trX.SetAttribute(STR_USER_PARAM_ATTRIB_PREFIX, strUserParamName + "|");		// set name of suer parameter
	
	int nYCol;
	if(nMethod != stats_count)
		nYCol = mdResult.GetNumRows();
	else
		nYCol = mnResult.GetNumRows();

	string strMethod = _get_long_name_for_method(nMethod);
	for(int ii = 0; ii < nYCol; ii ++)
	{
		vector vdData;
		if(nMethod != stats_count)
			mdResult.GetRow(vdData, ii);
		else
			mnResult.GetRow(vdData, ii);

		string strYColumnName = "";//"TwoDBinning" + (ii>0 ? (string)ii : "");, use default: A,B,...
		TreeNode tr = rtTwoDBinning.AddColumn(vdData, strYColumnName, TWO_D_BINNING_Y_BEGIN + ii, strMethod, OKDATAOBJ_DESIGNATION_Y);
		tr.SetAttribute(STR_COMMENT_ATTRIB, vsCommentLabels[ii]);
		tr.SetAttribute(STR_USER_PARAM_ATTRIB_PREFIX, ftoa(vyBenEndsOrCenters[ii], "*"));
	}
}
///End USE_REPORTDATA


///Kyle 03/28/2009 NEW_TABLE_FOR_SUB_TOTAL_COUNT
static void _2d_binning_update_subtotal_count(const vector<string>& vsCommentLabels, matrix& mdResult, matrix<uint>& mnResult, int nMethod, ReportData& outData, const string& strXLongName)
{
	if(!outData)
		return;
	
	ReportTable rtTwoDBinning = outData.CreateTable("TwoDBin1", "", TWO_D_BINNING_SUBTOTAL_TABLE, -1, 1);
	
	string 	strXColumnName = "SubTotalX",
			strYColumnName = "SubTotalY",
			strMethod = _get_long_name_for_method(nMethod);
	rtTwoDBinning.AddColumn(vsCommentLabels, strXColumnName, TWO_D_BINNING_SUBTOTAL_X, strXLongName, OKDATAOBJ_DESIGNATION_X);

	vector vTotal;
	if(nMethod != stats_count)
	{
		mdResult.Transpose();
		mdResult.SumColumns(vTotal);
		mdResult.Transpose();
	}
	else
	{
		mnResult.Transpose();
		mnResult.SumColumns(vTotal);
		mnResult.Transpose();
	}
	if(nMethod == stats_sum)		// should skip some NANUM to get the sum
	{
		for(int ii=vTotal.GetSize()-1; ii>=0; ii--)
		{
			if(is_missing_value(vTotal[ii]))
			{
				vector vRow;
				mdResult.GetRow(vRow, ii);
				vRow.Trim();
				if(vRow.GetSize() > 0)
				{
					double dSum;
					vRow.Sum(dSum);
					vTotal[ii] = dSum;
				}
			}
		}
	}

	rtTwoDBinning.AddColumn(vTotal, strYColumnName, TWO_D_BINNING_SUBTOTAL_Y, strMethod, OKDATAOBJ_DESIGNATION_Y);
}
///End NEW_TABLE_FOR_SUB_TOTAL_COUNT
*/
///end CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT

///Kyle 04/09/2009 SHOW_MORE_INFO_ABOUT_INPUT_DATA_IN_THE_GROUP_BRANCH
static string _range_get_smart_name(const XYRange& irng, bool bIsX)
{
	Column col;
	if(bIsX)
		irng.GetXColumn(col);
	else
		irng.GetYColumn(col);
	
	string strName;
	if(col)
	{
		strName = col.GetLongName();
		if(strName.IsEmpty())
			col.GetName(strName);
		else
			strName.Format("\"%s\"", strName);
	}
	return strName;
}

static void _update_group_branch_label(TreeNode& trGetN)
{
	string strXLabel, strYLabel;
	XYRange irng;
	xy_range_from_GetN_data_node(trGetN.iy, irng);
	if(irng.IsValid() && get_input_xyrange_num(trGetN.iy) == 1)
	{
		vector vx, vy;
		irng.GetData(vy, vx,NULL, 0, 0);

		double dMin, dMax;
		string strName;
		vx.GetMinMax(dMin, dMax);
		strName = _range_get_smart_name(irng, true);
		if(strName.IsEmpty())
			strXLabel.Format("X [%s , %s]", ftoa(dMin, "*"), ftoa(dMax, "*"));
		else
			strXLabel.Format("%s(X) [%s , %s]", strName, ftoa(dMin, "*"), ftoa(dMax, "*"));
		
		vy.GetMinMax(dMin, dMax);
		strName = _range_get_smart_name(irng, false);
		ASSERT(!strName.IsEmpty());
		strYLabel.Format("%s(Y) [%s , %s]", strName, ftoa(dMin, "*"), ftoa(dMax, "*"));
	}
	else
	{
		strXLabel = "X";
		strYLabel = "Y";
	}
	
	
	string strXBranch, strYBranch;
	strXBranch.Format("1 %s", strXLabel);
	strYBranch.Format("1 %s", strYLabel);
	/// Hong 09/09/09 QA90-14287 2DBINNING_SUPPORT_HANDLE_MIN_MAX	
	//trGetN.xbin.SetAttribute(STR_GROUP_BRANCH_ATTRIB, strXBranch);
	//trGetN.ybin.SetAttribute(STR_GROUP_BRANCH_ATTRIB, strYBranch);
	trGetN.x.SetAttribute(STR_LABEL_ATTRIB, strXLabel);
	trGetN.y.SetAttribute(STR_LABEL_ATTRIB, strYLabel);
	/// end 2DBINNING_SUPPORT_HANDLE_MIN_MAX
}
///End SHOW_MORE_INFO_ABOUT_INPUT_DATA_IN_THE_GROUP_BRANCH

/// Hong 09/09/09 QA90-14287 2DBINNING_SUPPORT_HANDLE_MIN_MAX
/// code below copy from report_utils.c due to GetN tree structure diff
static void _init_two_binning_tree_show(TreeNode& trGetN)
{
	_update_initial_val_x_y(trGetN);

	///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	//freq_update_inc(trGetN.xmin.dVal, trGetN.xmax.dVal, trGetN.xstepby.nVal, trGetN.xoutleft.nVal, trGetN.xoutright.nVal, trGetN.xinc, trGetN.xintervals);
	//freq_update_inc(trGetN.ymin.dVal, trGetN.ymax.dVal, trGetN.ystepby.nVal, trGetN.youtleft.nVal, trGetN.youtright.nVal, trGetN.yinc, trGetN.yintervals);
	/// Iris 6/26/2009 QA80-13289-S1 CODES_FOR_WINDROSE_PLOT_XF
	//freq_update_inc(trGetN.xmin.dVal, trGetN.xmax.dVal, trGetN.xstepby.nVal, trGetN.xoutleft.nVal, trGetN.xoutright.nVal, trGetN.xinc, trGetN.xintervals, trGetN.xbin.nVal == bin_center);
	//freq_update_inc(trGetN.ymin.dVal, trGetN.ymax.dVal, trGetN.ystepby.nVal, trGetN.youtleft.nVal, trGetN.youtright.nVal, trGetN.yinc, trGetN.yintervals, trGetN.ybin.nVal == bin_center);
	int xstepby = trGetN.x.stepby? trGetN.x.stepby.nVal : step_by_inc;
	int xoutleft = trGetN.x.border.outleft? trGetN.x.border.outleft.nVal : 0;
	int xoutright = trGetN.x.border.outright? trGetN.x.border.outright.nVal : 1;
	/// Iris 7/23/2009 REMOVE_YBIN_CONTROL_FROM_PLOT_WINDROSE
	//bool bBinCenter = trGetN.xbin? trGetN.xbin.nVal == bin_center : false;
	bool bXBinCenter = trGetN.x.bin? trGetN.x.bin.nVal == bin_center : false;
	bool bYBinCenter = trGetN.y.bin? trGetN.y.bin.nVal == bin_center : false;
	///end REMOVE_YBIN_CONTROL_FROM_PLOT_WINDROSE
	int ystepby = trGetN.y.stepby? trGetN.y.stepby.nVal : step_by_inc;
	int youtleft = trGetN.y.border.outleft? trGetN.y.border.outleft.nVal : 0;
	int youtright = trGetN.y.border.outright? trGetN.y.border.outright.nVal : 1;
	if( trGetN.x.min.Show && trGetN.x.max.Show )
	{
		/// Iris 7/23/2009 REMOVE_YBIN_CONTROL_FROM_PLOT_WINDROSE
		//freq_update_inc(trGetN.xmin.dVal, trGetN.xmax.dVal, xstepby, xoutleft, xoutright, trGetN.xinc, trGetN.xintervals, bBinCenter);
		freq_update_inc(trGetN.x.min.dVal, trGetN.x.max.dVal, xstepby, xoutleft, xoutright, trGetN.x.inc, trGetN.x.intervals, bXBinCenter);
		///end REMOVE_YBIN_CONTROL_FROM_PLOT_WINDROSE
	}	
	/// Iris 7/23/2009 REMOVE_YBIN_CONTROL_FROM_PLOT_WINDROSE
	//freq_update_inc(trGetN.ymin.dVal, trGetN.ymax.dVal, ystepby, youtleft, youtright, trGetN.yinc, trGetN.yintervals, trGetN.ybin.nVal == bin_center);
	freq_update_inc(trGetN.y.min.dVal, trGetN.y.max.dVal, ystepby, youtleft, youtright, trGetN.y.inc, trGetN.y.intervals, bYBinCenter);
	///end REMOVE_YBIN_CONTROL_FROM_PLOT_WINDROSE
	///end CODES_FOR_WINDROSE_PLOT_XF
	///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	
	///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	_update_min_max_labels(trGetN);
	///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	
	///Kyle 05/11/2009 QA80-13521 SUPPORT_PERIODICAL_BINS
	_update_period(trGetN);
	///End SUPPORT_PERIODICAL_BINS
}

///Kyle 07/01/2010 ORG-209-P1 UPDATE_INCLUDE_OUTLIERS_ON_CHECK_SEPARATELY_COUNT_MAXIMUM
static void _update_include_outliers(TreeNode& trXYOption)
{
	if( !trXYOption )
		return;

	TreeNode trBorderOptions = trXYOption.border;
	if( !trBorderOptions )
	{
		ASSERT(0);
		return;
	}
	TreeNode trOutLeft = trBorderOptions.outleft;
	TreeNode trOutRight = trBorderOptions.outright;
	
	bool bPeriodical = trXYOption.periodical.nVal;
	
	trOutLeft.Show = !bPeriodical;
	
	string strLabel = bPeriodical ? _L("Include Outliers") : (trBorderOptions.cmax.nVal ? _L("Include Outliers > Maximum") : _L("Include Outliers >= Maximum"));
	trOutRight.SetAttribute(STR_LABEL_ATTRIB, strLabel);
}
///End UPDATE_INCLUDE_OUTLIERS_ON_CHECK_SEPARATELY_COUNT_MAXIMUM

static void _update_initial_val_x_y(TreeNode& trGetN)
{
 	TreeNode trTemp = trGetN.iy;
	if( trTemp )
	{
		XYRange rgXY;
		okxf_resolve_tree_construct_range(&trTemp, &rgXY);
		if( rgXY )
		{
			vector vX;
			vector vY;
			rgXY.GetData(vY, vX);
			if (0 != vX.GetSize() || 0 != vY.GetSize())
			{
				///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
				//set_round_limits(vX, trGetN.xmin, trGetN.xmax, trGetN.xinc, trGetN.xintervals, trGetN.xstepby.nVal);
				//set_round_limits(vY, trGetN.ymin, trGetN.ymax, trGetN.yinc, trGetN.yintervals, trGetN.ystepby.nVal);
				/// Max 3/12/09 v8.0953c_new QA70-13251 RENAME_VAR_coordinate_TO_bin
				//set_round_limits(vX, trGetN.xmin, trGetN.xmax, trGetN.xinc, trGetN.xintervals, trGetN.xstepby.nVal, trGetN.coordinate.nVal == _2D_BINNING_COORDINATE_BIN_CENTER);
				//set_round_limits(vY, trGetN.ymin, trGetN.ymax, trGetN.yinc, trGetN.yintervals, trGetN.ystepby.nVal, trGetN.coordinate.nVal == _2D_BINNING_COORDINATE_BIN_CENTER);
				if( trGetN.x.min.Show )/// Iris 6/26/2009 QA80-13289-S1 CODES_FOR_WINDROSE_PLOT_XF
					set_round_limits(vX, trGetN.x.min, trGetN.x.max, trGetN.x.inc, trGetN.x.intervals, trGetN.x.stepby.nVal, trGetN.x.bin.nVal == bin_center);
				///end CODES_FOR_WINDROSE_PLOT_XF
				/// Iris 7/23/2009 REMOVE_YBIN_CONTROL_FROM_PLOT_WINDROSE				
				//set_round_limits(vY, trGetN.ymin, trGetN.ymax, trGetN.yinc, trGetN.yintervals, trGetN.ystepby.nVal, trGetN.ybin.nVal == bin_center);
				set_round_limits(vY, trGetN.y.min, trGetN.y.max, trGetN.y.inc, trGetN.y.intervals, trGetN.y.stepby.nVal, trGetN.y.bin ? trGetN.y.bin.nVal == bin_center : false);
				///end REMOVE_YBIN_CONTROL_FROM_PLOT_WINDROSE
				/// END RENAME_VAR_coordinate_TO_bin
				///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END	
			}
		}
	}	
}

///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
static void _update_min_max_labels(TreeNode& trGetN)
{
	string strMinLabel, strMaxLabel;
	
	/// Max 3/12/09 v8.0953c_new QA70-13251 RENAME_VAR_coordinate_TO_bin
	// if(trGetN.coordinate.nVal == _2D_BINNING_COORDINATE_BIN_CENTER)	// bin center
	if(trGetN.x.bin && trGetN.x.bin.nVal == bin_center)
	/// ---
	{
		strMinLabel = _L("Minimum Bin Center");
		strMaxLabel = _L("Maximum Bin Center");
	}
	else						// bin end
	{
		strMinLabel = _L("Minimum Bin Beginning");
		strMaxLabel = _L("Maximum Bin End");
	}
	trGetN.x.min.SetAttribute(STR_LABEL_ATTRIB, strMinLabel);
	trGetN.x.max.SetAttribute(STR_LABEL_ATTRIB, strMaxLabel);

	/// Iris 7/23/2009 REMOVE_YBIN_CONTROL_FROM_PLOT_WINDROSE
	/*
	if(trGetN.ybin && trGetN.ybin.nVal == bin_center)
	{
		strMinLabel = _L("Minimum Bin Center");
		strMaxLabel = _L("Maximum Bin Center");
	}
	else						// bin end
	{
		strMinLabel = _L("Minimum Bin Beginning");
		strMaxLabel = _L("Maximum Bin End");
	}
	trGetN.ymin.SetAttribute(STR_LABEL_ATTRIB, strMinLabel);
	trGetN.ymax.SetAttribute(STR_LABEL_ATTRIB, strMaxLabel);
	*/
	if( trGetN.y.bin )
	{
		if( trGetN.y.bin.nVal == bin_center )
		{
			strMinLabel = _L("Minimum Bin Center");
			strMaxLabel = _L("Maximum Bin Center");
		}
		else
		{
			strMinLabel = _L("Minimum Bin Beginning");
			strMaxLabel = _L("Maximum Bin End");
		}
		trGetN.y.min.SetAttribute(STR_LABEL_ATTRIB, strMinLabel);
		trGetN.y.max.SetAttribute(STR_LABEL_ATTRIB, strMaxLabel);
	}
	//end REMOVE_YBIN_CONTROL_FROM_PLOT_WINDROSE
}
///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END

static void _update_period(TreeNode& trGetN)
{
	if(trGetN.x.periodical && trGetN.x.periodical.nVal)
	{
		TreeNode trPeriod = trGetN.x.period;
		if( trPeriod && 1 == octree_get_auto_support(&trPeriod) )
		{
			double dMin, dMax;
			dMin = trGetN.x.min.dVal - (trGetN.x.bin.nVal == bin_center ? trGetN.x.inc.dVal / 2.0 : 0);
			dMax = trGetN.x.max.dVal + (trGetN.x.bin.nVal == bin_center ? trGetN.x.inc.dVal / 2.0 : 0);
			///Kyle 07/10/2009 QA80-13521-P1 SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
			//trPeriod.dVal = _get_auto_period(dMin, dMax);
			trPeriod.dVal = _get_auto_period(dMin, dMax, trGetN.x.inc.dVal);
			///End SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
		}
	}
	if(trGetN.y.periodical && trGetN.y.periodical.nVal)
	{
		TreeNode trPeriod = trGetN.y.period;
		if( trPeriod && 1 == octree_get_auto_support(&trPeriod) )
		{
			double dMin, dMax;
			dMin = trGetN.y.min.dVal - (trGetN.y.bin.nVal == bin_center ? trGetN.y.inc.dVal / 2.0 : 0);
			dMax = trGetN.y.max.dVal + (trGetN.y.bin.nVal == bin_center ? trGetN.y.inc.dVal / 2.0 : 0);
			///Kyle 07/10/2009 QA80-13521-P1 SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
			//trPeriod.dVal = _get_auto_period(dMin, dMax);
			trPeriod.dVal = _get_auto_period(dMin, dMax, trGetN.y.inc.dVal);
			///End SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
		}
	}
}

///Kyle 07/10/2009 QA80-13521-P1 SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
//static double _get_auto_period(double dMin, double dMax)
static double _get_auto_period(double dMin, double dMax, double dInc)
///End SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
{
	///Kyle 05/15/2009 QA80-13521 ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
	//// max(|dMin|, |dMax|, dMax-dMin)
	//if(dMin >= dMax)
		//return NANUM;
	//double dPeriod = max(dMax - dMin, abs(dMin));
	//dPeriod = max(dPeriod, abs(dMax));
	//return dPeriod;
	if(dMin < dMax)
	{
		///Kyle 07/10/2009 QA80-13521-P1 SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
		//return dMax-dMin;
		ASSERT(dInc > 0.0);
		int nSize = nint( (dMax - dMin)/dInc );
		return dInc * nSize;
		///End SHOULD_SKIP_OR_EXTEND_THE_LAST_BIN_BEFORE_CHECKING_PERIODICAL
	}
	return NANUM;
	///End ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
}
/// end 2DBINNING_SUPPORT_HANDLE_MIN_MAX




void TwoDBinning(const XYRange& iy, const TreeNode& x, const TreeNode& y, const int& stats, const int& base, const Range& col, ReportData& rd, const int& subcount, MatrixObject& om, const int& bar, const int& image)
{
	
	vector vX, vY;
	
	if(!iy.IsValid() || !iy.GetData(vY, vX))
	{
		XF_THROW(XFERR_FAILED_GET_RANGE);
	}	
	
	///Kyle 06/30/2010 ORG-209 EXPAND_2D_BINNING_TO_SUPPORT_ADDITIONAL_Y_COLUMN
	vector vZ;
	if( stats_count != stats && stats_freq != stats )		// need ref col
	{
		ASSERT( vX.GetSize() == vY.GetSize() );
		switch(base)
		{
		case base_x:
			vZ = vX;
			break;
			
		case base_y:
			vZ = vY;
			break;
			
		case base_specific:
			{
				if( !(col && col.GetNumRanges()==1) )
					XF_THROW(XFERR_2D_BINNING_BASE_COLUMN);
	
				int nErr = check_1_data(col, false, false);
				if( nErr )
					XF_THROW(nErr);
	
				col.GetData(&vZ, 0);
			}
			break;
			
		default:
			ASSERT(0);
		}
		
		if( vZ.GetSize() != vX.GetSize() )
		{
			ASSERT( base == base_specific );
			XF_THROW(XFERR_2D_BINNING_BASE_COL_SIZE);
		}
	}
	///End EXPAND_2D_BINNING_TO_SUPPORT_ADDITIONAL_Y_COLUMN
	
	/// Iris 6/25/2009 QA80-13289-S1 CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT
	/*
	int iStart, iEnd;
	
	BinningOption   stOptionX;		
	///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	//stOptionX.dMax = xmax;	
	//stOptionX.dMin = xmin;
	/// Max 3/12/09 v8.0953c_new QA70-13251 RENAME_VAR_coordinate_TO_bin
	// the meaning and usage of "coordinate" is changed for #13251, so name should be changed
	//stOptionX.dMax = xmax + (coordinate == _2D_BINNING_COORDINATE_BIN_CENTER ? xinc / 2 : 0);
	//stOptionX.dMin = xmin - (coordinate == _2D_BINNING_COORDINATE_BIN_CENTER ? xinc / 2 : xinc);
	stOptionX.dMax = xmax + (xbin == xbin_center ? xinc / 2 : 0);
	stOptionX.dMin = xmin - (xbin == xbin_center ? xinc / 2 : 0);
	/// END RENAME_VAR_coordinate_TO_bin
	///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	stOptionX.dInc = xinc;
	
	///Kyle 05/15/2009 QA80-13521 ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
	//int nIncMin = xoutleft;
	//int nIncMax = xoutright;
	//stOptionX.wIncludeOutliers = _get_include_outliers_type(nIncMin, nIncMax, iStart, iEnd);
	int nIncMinX = xoutleft && !xperiodical;
	int nIncMaxX = xoutright;
	stOptionX.wIncludeOutliers = _get_include_outliers_type(nIncMinX, nIncMaxX, iStart, iEnd);
	///End ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
	///Kyle 03/25/2009 QA80-13251-P4 SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
	//int iSizeX = ceil( (stOptionX.dMax - stOptionX.dMin) / stOptionX.dInc ) + iStart + iEnd;
	int iSizeX = (int)( (stOptionX.dMax - stOptionX.dMin) / stOptionX.dInc + 0.5) + iStart + iEnd;
	///End SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
	stOptionX.dPeriod = xperiodical ? xperiod : -1;			///Kyle 05/11/2009 QA80-13521 SUPPORT_PERIODICAL_BINS
	
	BinningOption   stOptionY;
	///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	//stOptionY.dMax = ymax;	
	//stOptionY.dMin = ymin;
	/// Max 3/12/09 v8.0953c_new QA70-13251 RENAME_VAR_coordinate_TO_bin
	//stOptionY.dMax = ymax + (coordinate == _2D_BINNING_COORDINATE_BIN_CENTER ? yinc / 2 : 0);	
	//stOptionY.dMin = ymin - (coordinate == _2D_BINNING_COORDINATE_BIN_CENTER ? yinc / 2 : yinc);
	stOptionY.dMax = ymax + (ybin == ybin_center ? yinc / 2 : 0);	
	stOptionY.dMin = ymin - (ybin == ybin_center ? yinc / 2 : 0);
	/// END RENAME_VAR_coordinate_TO_bin
	///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	stOptionY.dInc = yinc;
	
	///Kyle 05/15/2009 QA80-13521 ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
	//nIncMin = youtleft;
	//nIncMax = youtright;
	//
	//
	//stOptionY.wIncludeOutliers = _get_include_outliers_type(nIncMin, nIncMax, iStart, iEnd);
	int nIncMinY = youtleft && !yperiodical;
	int nIncMaxY = youtright;
	stOptionY.wIncludeOutliers = _get_include_outliers_type(nIncMinY, nIncMaxY, iStart, iEnd);
	///End ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
	///Kyle 03/25/2009 QA80-13251-P4 SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
	//int iSizeY = ceil( (stOptionY.dMax - stOptionY.dMin) / stOptionY.dInc ) + iStart + iEnd;
	int iSizeY = (int)( (stOptionY.dMax - stOptionY.dMin) / stOptionY.dInc + 0.5) + iStart + iEnd;
	///End SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
	stOptionY.dPeriod = yperiodical ? yperiod : -1;			///Kyle 05/11/2009 QA80-13521 SUPPORT_PERIODICAL_BINS
	*/
	///end CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT
	
	
	///Kyle 03/11/2009 QA80-13251 ADD_NEW_2D_STATS_AND_OUTPUT_TO_WORKSHEET
	//BinningResult	stResult; 
	//
	//om.SetNumRows(iSizeX);
	//om.SetNumCols(iSizeY);	
	//matrixbase& mat = om.GetDataObject();
	//
	//matrix<uint> mResult;
	//
	//mResult.SetSize(iSizeY, iSizeX);
	//
	//stResult.iMatSize = iSizeX * iSizeY;
	//
	//stResult.pMatrix = mResult;
	//
	//int nSize = vY.GetSize();
	//int nRet = ocmath_2d_binning(nSize, vX, vY, &stResult, &stOptionX, &stOptionY);
	//if (nRet != OE_NOERROR)
	//{
		//XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
	//}
	//
	//mat = mResult;
	//
	//MatrixLayer ml;
	//om.GetParent(ml);
	//MatrixPage mp;
	//ml.GetParent(mp);
	////mp.SetLongName(_L("TwoD FreqCounts"));	// no need
	//
	//if (_2D_BINNING_COORDINATE_BIN_CENTER == coordinate)
	//{
		//double dMinX = (xoutleft) ? stOptionX.dMin - stOptionX.dInc/2 : stOptionX.dMin + stOptionX.dInc/2;
		//double dMaxX = (xoutright) ? stOptionX.dMax + stOptionX.dInc/2 : stOptionX.dMax - stOptionX.dInc/2;
		//double dMinY = (youtleft) ? stOptionY.dMin - stOptionY.dInc/2 : stOptionY.dMin + stOptionY.dInc/2;
		//double dMaxY = (youtright) ? stOptionY.dMax + stOptionY.dInc/2 : stOptionY.dMax - stOptionY.dInc/2;
		//om.SetXY(dMinX, dMinY, dMaxX, dMaxY);
		//
	//}else
	//{
		//double dMinX = (xoutleft) ? stOptionX.dMin : stOptionX.dMin + stOptionX.dInc;
		//double dMaxX = (xoutright) ? stOptionX.dMax + stOptionX.dInc : stOptionX.dMax;
		//double dMinY = (youtleft) ? stOptionY.dMin : stOptionY.dMin + stOptionY.dInc;
		//double dMaxY = (youtright) ? stOptionY.dMax + stOptionY.dInc : stOptionY.dMax;
		//om.SetXY(dMinX, dMinY, dMaxX, dMaxY);
	//}
	
	/// Iris 6/25/2009 QA80-13289-S1 CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT
	/*
	matrix<uint> mnResult;
	matrix<double> mdResult;
	if(stats == stats_count)
	{
		mnResult.SetSize(iSizeY, iSizeX);
		
		BinningResult	stResult;
		stResult.iMatSize = iSizeX * iSizeY;
		stResult.pMatrix = mnResult;
		int nSize = vY.GetSize();
		int nRet = ocmath_2d_binning(nSize, vX, vY, &stResult, &stOptionX, &stOptionY);
		if (nRet != OE_NOERROR)
		{
			XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
		}
		///Kyle 03/26/2009 ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
		if(xorder)
		{
			mnResult.Transpose();
			vector<uint> vnIndices;
			vnIndices.Data(mnResult.GetNumRows()-1, 0, -1);
			mnResult.ReorderRowWise(vnIndices);
			mnResult.Transpose();
		}
		if(yorder)
		{
			vector<uint> vnIndices;
			vnIndices.Data(mnResult.GetNumRows()-1, 0, -1);
			mnResult.ReorderRowWise(vnIndices);
		}
		///End ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
	}
	else
	{
		int nStats;
		switch(stats)
		{
		case stats_min:
			nStats = OCMATH_2D_BINNING_MIN;
			break;
		case stats_max:
			nStats = OCMATH_2D_BINNING_MAX;
			break;
		case stats_mean:
			nStats = OCMATH_2D_BINNING_MEAN;
			break;
		case stats_median:
			nStats = OCMATH_2D_BINNING_MEDIAN;
			break;
		case stats_sum:
			nStats = OCMATH_2D_BINNING_SUM;
			break;
		case stats_freq:
			nStats = OCMATH_2D_BINNING_PERCENTAGES;
			break;
		}
		
		mdResult.SetSize(iSizeY, iSizeX);
		
		BinningStatsResult	stResult;
		stResult.iMatSize = iSizeX * iSizeY;
		stResult.pMatrix = mdResult;
		int nSize = vY.GetSize();
		int nRet = ocmath_2d_binning_stats(nSize, vX, vY, &stResult, nStats, &stOptionX, &stOptionY);
		if (nRet != OE_NOERROR)
		{
			XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
		}
		
		///Kyle 03/26/2009 ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
		if(xorder)
		{
			mdResult.Transpose();
			vector<uint> vnIndices;
			vnIndices.Data(mdResult.GetNumRows()-1, 0, -1);
			mdResult.ReorderRowWise(vnIndices);
			mdResult.Transpose();
		}
		if(yorder)
		{
			vector<uint> vnIndices;
			vnIndices.Data(mdResult.GetNumRows()-1, 0, -1);
			mdResult.ReorderRowWise(vnIndices);
		}
		///End ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
	}
	double dMinX, dMaxX, dMinY, dMaxY;
	///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	//if (_2D_BINNING_COORDINATE_BIN_CENTER == coordinate)
	//{
		//dMinX = (xoutleft) ? stOptionX.dMin - stOptionX.dInc/2 : stOptionX.dMin + stOptionX.dInc/2;
		//dMaxX = (xoutright) ? stOptionX.dMax + stOptionX.dInc/2 : stOptionX.dMax - stOptionX.dInc/2;
		//dMinY = (youtleft) ? stOptionY.dMin - stOptionY.dInc/2 : stOptionY.dMin + stOptionY.dInc/2;
		//dMaxY = (youtright) ? stOptionY.dMax + stOptionY.dInc/2 : stOptionY.dMax - stOptionY.dInc/2;
	//}else
	//{
		//dMinX = (xoutleft) ? stOptionX.dMin : stOptionX.dMin + stOptionX.dInc;
		//dMaxX = (xoutright) ? stOptionX.dMax + stOptionX.dInc : stOptionX.dMax;
		//dMinY = (youtleft) ? stOptionY.dMin : stOptionY.dMin + stOptionY.dInc;
		//dMaxY = (youtright) ? stOptionY.dMax + stOptionY.dInc : stOptionY.dMax;
	//}
	if(xbin == xbin_center)
	{
		///Kyle 05/15/2009 QA80-13521 ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
		//dMinX = xmin - (xoutleft ? xinc : 0);
		dMinX = xmin - (nIncMinX ? xinc : 0);
		///End ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
		///Kyle 03/25/2009 QA80-13251-P4 SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
		//dMaxX = xmax + (xoutright ? xinc : 0);
		///End SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
	}
	else
	{
		///Kyle 05/15/2009 QA80-13521 ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
		//dMinX = xmin + (xoutleft ? 0 : xinc);
		dMinX = xmin + (nIncMinX ? 0 : xinc);
		///End ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
		///Kyle 03/25/2009 QA80-13251-P4 SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
		//dMaxX = xmax + (xoutright ? xinc : 0);
		///End SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
	}
	dMaxX = dMinX + (iSizeX - 1) * xinc;			///Kyle 03/25/2009 QA80-13251-P4 SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
	if(ybin == ybin_center)
	{
		///Kyle 05/15/2009 QA80-13521 ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
		//dMinY = ymin - (youtleft ? yinc : 0);
		dMinY = ymin - (nIncMinY ? yinc : 0);
		///End ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
		///Kyle 03/25/2009 QA80-13251-P4 SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
		//dMaxY = ymax + (youtright ? yinc : 0);
		///End SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
	}
	else
	{
		///Kyle 05/15/2009 QA80-13521 ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
		//dMinY = ymin + (youtleft ? 0 : yinc);
		dMinY = ymin + (nIncMinY ? 0 : yinc);
		///End ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
		///Kyle 03/25/2009 QA80-13251-P4 SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
		//dMaxY = ymax + (youtright ? yinc : 0);
		///End SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
	}
	dMaxY = dMinY + (iSizeY - 1) * yinc;			///Kyle 03/25/2009 QA80-13251-P4 SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
	///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	if(om)
	{
		om.SetNumRows(iSizeY);
		om.SetNumCols(iSizeX);	
		matrixbase& mat = om.GetDataObject();
		if(stats == stats_count)
			mat = mnResult;
		else
			mat = mdResult;
		
		///Kyle 03/26/2009 ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
		//om.SetXY(dMinX, dMinY, dMaxX, dMaxY);
		om.SetXY(xorder ? dMaxX : dMinX, yorder ? dMaxY : dMinY, xorder ? dMinX : dMaxX, yorder ? dMinY : dMaxY);
		///End ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
	}
	*/
	///end CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT
	
	
	///Kyle 03/27/2009 USE_REPORTDATA
	/*
	if(ow)
	{
		string strYLongName;
		strYLongName = get_input_data_range_string(iy);
		
		ow.SetSize(iSizeX, iSizeY + 1, WSS_CLEAR_DATA);
		ow.SetColDesignations("X", false, 0, 0);
		ow.CheckAddLabelByType(RCLT_UDL);
		string strPara;
		/// Max 3/12/09 v8.0953c_new QA70-13251 RENAME_VAR_coordinate_TO_bin
		//strPara.Format(_L("Bin %s of %s"), _2D_BINNING_COORDINATE_BIN_CENTER == coordinate ? _L("Center") : _L("End"), strYLongName);
		strPara.Format(_L("Bin %s of %s"), ybin_center == ybin ? _L("Centers") : _L("Ends"), strYLongName);
		/// ---
		Grid gg;
		gg.Attach(ow);
		vector<string> vsUDLs(1);// = {"Description", "Test OK"};
		vsUDLs[0] = strPara;
		gg.SetUserDefinedLabelNames(vsUDLs);
	
		vector vd;
		///Kyle 03/26/2009 ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
		//vd.Data(dMinX, dMaxX, xinc);
		vd.Data(xorder ? dMaxX :dMinX, xorder ? dMinX : dMaxX, xorder ? -xinc : xinc);
		///End ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
		Dataset ds(ow, 0);
		ds = vd;
		Column colX = ow.Columns(0);
		if(colX)
		{
			///Kyle 03/26/2009 ADD_UTIL_FUNCTION_TO_GET_DESCRIPTION_FROM_XYRANGE
			//string strXName;
			//Column ciX;
			//if(iy.GetXColumn(ciX))
				//ciX.GetName(strXName);
			string strXName = get_xy_range_string(iy, "X");
			///End ADD_UTIL_FUNCTION_TO_GET_DESCRIPTION_FROM_XYRANGE
			
			string strLabelXComment;
			/// Max 3/12/09 v8.0953c_new QA70-13251 RENAME_VAR_coordinate_TO_bin
			//strLabelXComment.Format(_L("Bin %s of %s"), _2D_BINNING_COORDINATE_BIN_CENTER == coordinate ? _L("Center") : _L("End"), strXName);
			strLabelXComment.Format(_L("Bin %s of %s"), xbin_center == xbin ? _L("Centers") : _L("Ends"), strXName);
			/// ---
			///Kyle 03/26/2009 ADD_UTIL_FUNCTION_TO_GET_DESCRIPTION_FROM_XYRANGE
			//colX.SetExtendedLabel(strLabelXComment, RCLT_COMMENT);
			colX.SetLongName(strLabelXComment);
			///End ADD_UTIL_FUNCTION_TO_GET_DESCRIPTION_FROM_XYRANGE
		}
		
		string strLongName = _get_long_name_for_method(stats), strComments;
		///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
		/// Max 3/12/09 v8.0953c_new QA70-13251 RENAME_VAR_coordinate_TO_bin
		//double 	dYBeg = ymin - (coordinate == _2D_BINNING_COORDINATE_BIN_CENTER ? yinc / 2 : yinc),
				//dYEnd = ymax + (coordinate == _2D_BINNING_COORDINATE_BIN_CENTER ? yinc / 2 : 0);
		int nDecimalPlaces = log(yinc);										// to round the bin ends
		
		// to show the different of bin ends caused by yinc, at lest 5 significant digits after the effective figure of yinc will be shown, somewhere 2 might be fine
		nDecimalPlaces = nDecimalPlaces >= 0 ? 5 : (- nDecimalPlaces + 5);
		double 	dYBeg = ymin - (ybin == ybin_center ? yinc / 2 : 0),
				///Kyle 03/25/2009 QA80-13251-P4 SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
				//dYEnd = ymax + (ybin == ybin_center ? yinc / 2 : 0);
				dYEnd = dYBeg + (iSizeY - youtleft - youtright) * yinc;
				///End SKIP_OR_EXTEND_THE_LAST_BIN_IF_IT_IS_NOT_A_FULL_BIN
		/// END RENAME_VAR_coordinate_TO_bin
		///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
		///Kyle 03/18/2009 QA80-13251 BETTER_FORMAT_FOR_ftoa_TO_CONSTRUCT_BIN_ENDS
		vector vyBinEnds;
		vyBinEnds.Data(dYBeg, dYEnd, yinc);
		vyBinEnds = round(vyBinEnds, nDecimalPlaces);
		///Kyle 03/26/2009 ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
		if(yorder)
			vyBinEnds.Sort(SORT_DESCENDING);
		///End ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
		
		int nSignDigit = _calc_num_significant_digits(vyBinEnds);			// get the max significant digits in default format string
		string strFormat = nSignDigit == 0 ? "*" : ("." + nSignDigit);		// if all without significant digits, use default, otherwise specify significant digits
		///End BETTER_FORMAT_FOR_ftoa_TO_CONSTRUCT_BIN_ENDS
		for(int ii = 0; ii< iSizeY; ii++)
		{
			if(stats == stats_count)
				mnResult.GetRow(vd, ii);
			else
				mdResult.GetRow(vd, ii);
			
			Dataset ds(ow, ii+1);
			ds = vd;
			
			Column colY = ow.Columns(ii+1);
			if(colY)
			{
				colY.SetLongName(strLongName);
	
				///Kyle 03/26/2009 ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
				//if(youtleft && ii==0)
				if(youtleft && (ii==0&&!yorder || ii==iSizeY-1&&yorder))
				///End ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
				{
					///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
					//strComments.Format("<%s", (string)ymin);
					///Kyle 03/18/2009 QA80-13251 BETTER_FORMAT_FOR_ftoa_TO_CONSTRUCT_BIN_ENDS
					//strComments.Format("< %s", ftoa(round(dYBeg, nDecimalPlaces), "*"));
					///Kyle 03/26/2009 ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
					//strComments.Format("< %s", ftoa(vyBinEnds[0], strFormat));					// first one in vyBinEnds
					if(yorder)
						strComments.Format("< %s", ftoa(vyBinEnds[vyBinEnds.GetSize()-1], strFormat));
					else
						strComments.Format("< %s", ftoa(vyBinEnds[0], strFormat));
					///End ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
					///End BETTER_FORMAT_FOR_ftoa_TO_CONSTRUCT_BIN_ENDS
					///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
				}
				///Kyle 03/26/2009 ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
				//else if(youtright && ii==iSizeY-1)
				else if(youtright && (ii==iSizeY-1&&!yorder || ii==0&&yorder))
				///End ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
				{
					///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
					//strComments.Format(">=%s", (string)ymax);
					///Kyle 03/18/2009 QA80-13251 BETTER_FORMAT_FOR_ftoa_TO_CONSTRUCT_BIN_ENDS
					//strComments.Format(">= %s", ftoa(round(dYEnd, nDecimalPlaces), "*"));
					///Kyle 03/26/2009 ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
					//strComments.Format(">= %s", ftoa(vyBinEnds[vyBinEnds.GetSize()-1], strFormat));	// last one in vyBinEnds
					if(yorder)
						strComments.Format(">= %s", ftoa(vyBinEnds[0], strFormat));	// last one in vyBinEnds
					else
						strComments.Format(">= %s", ftoa(vyBinEnds[vyBinEnds.GetSize()-1], strFormat));	// last one in vyBinEnds
					///End ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
					///End BETTER_FORMAT_FOR_ftoa_TO_CONSTRUCT_BIN_ENDS
					///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
				}
				else
				{
					///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
					//double dBinFrom = ymin + yinc * (youtleft ? (ii-1):ii);
					///Kyle 03/18/2009 QA80-13251 BETTER_FORMAT_FOR_ftoa_TO_CONSTRUCT_BIN_ENDS
					//double dBinFrom = dYBeg + yinc * (youtleft ? (ii-1):ii);
					/////End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
					//strComments.Format("%s - %s", ftoa(round(dBinFrom, nDecimalPlaces), "*"), ftoa(round(dBinFrom + yinc, nDecimalPlaces), "*"));
					///Kyle 03/26/2009 ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
					//int nIndex = youtleft ? ii-1 : ii;
					//strComments.Format("%s - %s", ftoa(vyBinEnds[nIndex], strFormat), ftoa(vyBinEnds[nIndex + 1], strFormat));
					int nIndex;
					if(yorder)
					{
						nIndex = youtright ? ii-1 : ii;
						strComments.Format("%s - %s", ftoa(vyBinEnds[nIndex + 1], strFormat), ftoa(vyBinEnds[nIndex], strFormat));
					}
					else
					{
						nIndex = youtleft ? ii-1 : ii;
						strComments.Format("%s - %s", ftoa(vyBinEnds[nIndex], strFormat), ftoa(vyBinEnds[nIndex + 1], strFormat));
					}
					///End ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
					///End BETTER_FORMAT_FOR_ftoa_TO_CONSTRUCT_BIN_ENDS
				}
				colY.SetExtendedLabel(strComments, RCLT_COMMENT);
				
				///Kyle 03/26/2009 ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
				//double dBin = dMinY + ii * yinc;
				double dBin;
				if(yorder)
					dBin = dMinY + (iSizeY - ii - 1) * yinc;
				else
					dBin = dMinY + ii * yinc;
				///End ADD_OPTION_TO_OUTPUT_RESULT_ASC_OR_DES
				string strLabel = ftoa(dBin, "*");
				colY.SetExtendedLabel(strLabel, RCLT_UDL);
			}
		}
	}
	*/
	
	/// Iris 6/25/2009 QA80-13289-S1 CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT
	/*
	if(rd)
	{
		vector vxBinEndsOrCenters, vyBenEndsOrCenters;
		string strXLongName, strUserParamName;
		vector<string> vsCommentLabels;
		
		vxBinEndsOrCenters.Data(xorder ? dMaxX :dMinX, xorder ? dMinX : dMaxX, xorder ? -xinc : xinc);
		vyBenEndsOrCenters.Data(yorder ? dMaxY :dMinY, yorder ? dMinY : dMaxY, yorder ? -yinc : yinc);
	
		//strXLongName.Format(_L("Bin %s of %s"), xbin_center == xbin ? _L("Centers") : _L("Ends"), get_xy_range_string(iy, "X"));
		string strInputXName = get_xy_range_string(iy, "X");
		if(strInputXName.IsEmpty())
			strXLongName.Format(_L("Bin %s of X"), xbin_center == xbin ? _L("Centers") : _L("Ends"));
		else
			strXLongName.Format(_L("Bin %s of %s"), xbin_center == xbin ? _L("Centers") : _L("Ends"), get_xy_range_string(iy, "X"));
		strUserParamName.Format(_L("Bin %s of %s"), ybin_center == ybin ? _L("Centers") : _L("Ends"), get_input_data_range_string(iy));
		
		double dYBeg = ymin - (ybin == ybin_center ? yinc / 2 : 0);
		///Kyle 05/15/2009 QA80-13521 ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
		//_get_bin_ends_comments_label(dYBeg, dYBeg + (iSizeY - youtleft - youtright) * yinc, yinc, yorder, youtleft, youtright, vsCommentLabels);
		_get_bin_ends_comments_label(dYBeg, dYBeg + (iSizeY - nIncMinY - nIncMaxY) * yinc, yinc, yorder, nIncMinY, nIncMaxY, vsCommentLabels);
		///End ONLY_ONE_OUTLIERS_IS_NEED_WHEN_PERIODICAL_CHECKED
	
		_2d_binning_update_report_data(	vxBinEndsOrCenters, strXLongName,
											vyBenEndsOrCenters, strUserParamName,
											vsCommentLabels, stats,
											mdResult, mnResult,
											rd);
		
		///Kyle 03/28/2009 NEW_TABLE_FOR_SUB_TOTAL_COUNT
		if(subcount && (stats==stats_sum || stats==stats_count || stats==stats_freq) )
		{
			string strXLongName;
			strXLongName.Format(_L("Bins of %s"), get_input_data_range_string(iy));
			_2d_binning_update_subtotal_count(vsCommentLabels, mdResult, mnResult, stats, rd, strXLongName);
		}
		///End NEW_TABLE_FOR_SUB_TOTAL_COUNT
	}
	///End USE_REPORTDATA
	///End ADD_NEW_2D_STATS_AND_OUTPUT_TO_WORKSHEET
	*/
	/// Hong 09/09/09 QA90-14287 2DBINNING_SUPPORT_HANDLE_MIN_MAX
	//report_2d_binning(rd, iy, 
	//					xbin, xmin, xmax, xstepby, xinc, xintervals, xperiodical, xperiod, xoutleft, xoutright, xorder,
	//					ybin, ymin, ymax, ystepby, yinc, yintervals, yperiodical, yperiod, youtleft, youtright, yorder, 
	//					stats, subcount, om);
	///Kyle 06/30/2010 ORG-209 EXPAND_2D_BINNING_TO_SUPPORT_ADDITIONAL_Y_COLUMN
	//report_2d_binning(rd, iy, 
	//					x.bin.nVal, x.min.dVal, x.max.dVal, x.stepby.nVal, x.inc.dVal, x.intervals.dVal, x.periodical.nVal, x.period.dVal, x.border.outleft.nVal, x.border.outright.nVal, x.order.nVal,
	//					y.bin.nVal, y.min.dVal, y.max.dVal, y.stepby.nVal, y.inc.dVal, y.intervals.dVal, y.periodical.nVal, y.period.dVal, y.border.outleft.nVal, y.border.outright.nVal, y.order.nVal, 
	//					stats, subcount, om, wind_rose_orientation_invalid, x.border.cmin.nVal, x.border.cmax.nVal, y.border.cmin.nVal, y.border.cmax.nVal);
	report_2d_binning(rd, iy, vZ,
						x.bin.nVal, x.min.dVal, x.max.dVal, x.stepby.nVal, x.inc.dVal, x.intervals.dVal, x.periodical.nVal, x.period.dVal, x.border.outleft.nVal, x.border.outright.nVal, x.order.nVal,
						y.bin.nVal, y.min.dVal, y.max.dVal, y.stepby.nVal, y.inc.dVal, y.intervals.dVal, y.periodical.nVal, y.period.dVal, y.border.outleft.nVal, y.border.outright.nVal, y.order.nVal, 
						stats, subcount, om, wind_rose_orientation_invalid, x.border.cmin.nVal, x.border.cmax.nVal, y.border.cmin.nVal, y.border.cmax.nVal);
	///End EXPAND_2D_BINNING_TO_SUPPORT_ADDITIONAL_Y_COLUMN
	/// end 2DBINNING_SUPPORT_HANDLE_MIN_MAX
	///end CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT
	
	XFExeContext* pxfexectxt = Project.GetCurrentXFExeCtxt();
	if(!pxfexectxt)
		XF_THROW(CER_UNKNOWN_ERROR);	
	
	GraphPage gp;
	gp = pxfexectxt->GetGraph(BAR_PLOT_ID);
	///Kyle 03/11/2009 QA80-13251 ADD_NEW_2D_STATS_AND_OUTPUT_TO_WORKSHEET
	//if (bar)
	if (bar && om)
	///End ADD_NEW_2D_STATS_AND_OUTPUT_TO_WORKSHEET
	{
		/// Hong 12/08/09 QA80-14710 FIX_3D_BAR_WIDTH_CHANGED_AFTER_RECALCULATE
		/*
		if ( !gp )
		{
			/// YuI 07/29/08 QA70-11896 CRASH_IN_2DBINNING_UNDO
			//	gp.Create("3Dbars");
			/// Kenny 08/25/2009 QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC
			//gp.Create("3Dbars", CREATE_VISIBLE | CREATE_KEEP_LAYER_NAMES | CREATE_UNDOABLE);
			gp.Create("3Dbars", CREATE_VISIBLE | CREATE_KEEP_LAYER_NAMES | CREATE_UNDOABLE | CREATE_ENUM_EXIST_PAGE);
			/// End QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC
			/// end CRASH_IN_2DBINNING_UNDO
			gp.SetLongName(_L("3D Bar"));
		}	
		GraphLayer glay = gp.Layers();
		int nPlot = glay.AddPlot(om, IDM_PLOT_3D_MESH);
		glay.Rescale();	
		pxfexectxt->SetGraph(gp, BAR_PLOT_ID);
		*/
		GraphLayer		gl;
		xf_check_plot_output_matrix_in_graph(om, gl, BAR_PLOT_ID, NULL, IDM_PLOT_3D_MESH, "3Dbars");
		if ( !gp && gl )
		{
			gl.GetParent(gp);
			gp.SetLongName(_L("3D Bar"));
		}
		/// end FIX_3D_BAR_WIDTH_CHANGED_AFTER_RECALCULATE
	}else
	{
		if (gp)
			gp.Destroy();
	}
	gp = pxfexectxt->GetGraph(IMAGE_ID);
	///Kyle 03/11/2009 QA80-13251 ADD_NEW_2D_STATS_AND_OUTPUT_TO_WORKSHEET
	//if (image)
	if (image && om)
	///End ADD_NEW_2D_STATS_AND_OUTPUT_TO_WORKSHEET
	{
		/// Hong 12/08/09 QA80-14710 FIX_3D_BAR_WIDTH_CHANGED_AFTER_RECALCULATE
		/*
		if ( !gp )
		{
			/// YuI 07/29/08 QA70-11896 CRASH_IN_2DBINNING_UNDO
			//	gp.Create("IMAGE");
			/// Kenny 08/25/2009 QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC
			//gp.Create("IMAGE", CREATE_VISIBLE | CREATE_KEEP_LAYER_NAMES | CREATE_UNDOABLE);
			gp.Create("IMAGE", CREATE_VISIBLE | CREATE_KEEP_LAYER_NAMES | CREATE_UNDOABLE | CREATE_ENUM_EXIST_PAGE);
			/// End QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC
			/// end CRASH_IN_2DBINNING_UNDO
			gp.SetLongName(_L("Image Plot"));
		}
		GraphLayer glay1 = gp.Layers();
		int nPlot = glay1.AddPlot(om, IDM_PLOT_MATRIX_IMAGE);
		glay1.Rescale();	
		pxfexectxt->SetGraph(gp, IMAGE_ID);
		*/
		GraphLayer		gl;
		xf_check_plot_output_matrix_in_graph(om, gl, IMAGE_ID, NULL, IDM_PLOT_MATRIX_IMAGE, "IMAGE");
		if ( !gp && gl )
		{
			gl.GetParent(gp);
			gp.SetLongName(_L("Image Plot"));
		}
		/// end FIX_3D_BAR_WIDTH_CHANGED_AFTER_RECALCULATE
	}else
	{
		if (gp)
			gp.Destroy();
	}
	
	
}

//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 TwoDBinning_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return TwoDBinning_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	
	/// Max 6/2/08 v8.0875b RUN_WITH_FLYOUT_THEME_REQUIRE_SPECIFY_AUTO_VARIABLES_IN_BEFORE_EXECUTE
	/*
	_update_initial_val_x_y(trGetN);
	
	
	freq_update_inc(trGetN.xmin.dVal, trGetN.xmax.dVal, trGetN.xstepby.nVal, trGetN.xoutleft.nVal, trGetN.xoutright.nVal, trGetN.xinc, trGetN.xintervals);
	freq_update_inc(trGetN.ymin.dVal, trGetN.ymax.dVal, trGetN.ystepby.nVal, trGetN.youtleft.nVal, trGetN.youtright.nVal, trGetN.yinc, trGetN.yintervals);
	*/
	/// Iris 6/25/2009 QA80-13289-S1 CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT
	//_init_tree_show(trGetN);
	/// Hong 09/09/09 QA90-14287 2DBINNING_SUPPORT_HANDLE_MIN_MAX
	//init_two_binning_tree_show(trGetN);
	_init_two_binning_tree_show(trGetN);
	/// end 2DBINNING_SUPPORT_HANDLE_MIN_MAX
	///end CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT
	/// END RUN_WITH_FLYOUT_THEME_REQUIRE_SPECIFY_AUTO_VARIABLES_IN_BEFORE_EXECUTE
	
	///Kyle 03/20/2009 SET_NUMBER_OF_INTERVAL_AS_READ_ONLY
	trGetN.x.intervals.Enable = ENABLE_READ_ONLY;
	trGetN.y.intervals.Enable = ENABLE_READ_ONLY;
	///End SET_NUMBER_OF_INTERVAL_AS_READ_ONLY
	
	
	int nErr = _twodbinning_check_input(trGetN);
	if( nErr != CER_NO_ERROR)
	{
		strErrMsg = nErr;
		bOKEnable = false;
	}
	
	///Kyle 04/09/2009 SHOW_MORE_INFO_ABOUT_INPUT_DATA_IN_THE_GROUP_BRANCH
	if(lpcszNodeName && 0==lstrcmpi(lpcszNodeName,"iy"))
		_update_group_branch_label(trGetN);
	///End SHOW_MORE_INFO_ABOUT_INPUT_DATA_IN_THE_GROUP_BRANCH
	
	return true;
	

}

int TwoDBinning_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	/// Hong 09/09/09 QA90-14287 2DBINNING_SUPPORT_HANDLE_MIN_MAX
	// the whole GUI is reconstruct with TreeNode due to variable number limitation, according tree access is updated without code mark
	if ( 0 == lstrcmpi("X", lpcszVarName) || 0 == lstrcmpi("Y", lpcszVarName) )
	{
		int			nDataID = GET_USER_DATAID(1);
		GETN_USE(tr) GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
		GETN_LIST(bin, _L("Specify Binning Range by"), 1, _L("Bin Centers|Bin Ends")) GETN_ID(nDataID++)
		GETN_NUM(min, _L("Minimum Bin Beginning"), 0.0) GETN_ADD_AUTO(1) GETN_ID(nDataID++)
		tr.min.strVal = STR_AUTO;
		GETN_NUM(max, _L("Maximum Bin End"), 0.0) GETN_ADD_AUTO(1) GETN_ID(nDataID++)
		tr.max.strVal = STR_AUTO;
		GETN_RADIO_INDEX(stepby, 0, _L("Increment|Intervals")) TREE_ADD_LABEL(_L("Step by")); GETN_ID(nDataID++)
		GETN_NUM(inc, _L("Increment"), 0) GETN_ADD_AUTO(1) GETN_ID(nDataID++)
		tr.inc.strVal = STR_AUTO;
		GETN_NUM(intervals, _L("Number of Intervals"), 0) GETN_ID(nDataID++)
		tr.intervals.strVal = STR_AUTO;
		GETN_CHECK(periodical, _L("Periodical"), 0) GETN_ID(nDataID++)
		GETN_NUM(period, _L("Period"), 0.0) GETN_ADD_AUTO(1) GETN_ID(nDataID++)
		tr.period.strVal = STR_AUTO;
		GETN_BEGIN_BRANCH(border, _L("Border Options"))
			GETN_CHECK(outleft, _L("Include Outliers < Minimum"), 0) GETN_ID(nDataID++)
			GETN_CHECK(outright, _L("Include Outliers >= Maximum"), 0) GETN_ID(nDataID++)
			GETN_CHECK(cmin, _L("Separately Count Minimum"), 0) GETN_ID(nDataID++)
			GETN_CHECK(cmax, _L("Separately Count Maximum"), 0) GETN_ID(nDataID++)
		GETN_END_BRANCH(border)
		GETN_LIST(order, _L("Output Binning Order"), 0, _L("Ascending|Descending")) GETN_ID(nDataID++)
	}
	/// end 2DBINNING_SUPPORT_HANDLE_MIN_MAX
	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 TwoDBinning_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	///Kyle 02/20/2009 QA80-13149 TEMPORARY_HIDE_INTERVALS_SINCE_ROUND_LIMITS_DOES_NOT_SUPPORT_FIXED_STEPS
	if(is_xf_startup(nGetNDialog, dwCntrl))
	{
		trGetN.x.stepby.nVal = 0;
		trGetN.x.stepby.Show = false;
	
		trGetN.y.stepby.nVal = 0;
		trGetN.y.stepby.Show = false;
	
		///Kyle 03/20/2009 SET_NUMBER_OF_INTERVAL_AS_READ_ONLY
		//trGetN.xintervals.Enable = ENABLE_READ_ONLY;
		//trGetN.yintervals.Enable = ENABLE_READ_ONLY;
		///End SET_NUMBER_OF_INTERVAL_AS_READ_ONLY
		
		_update_group_branch_label(trGetN);			///Kyle 04/09/2009 SHOW_MORE_INFO_ABOUT_INPUT_DATA_IN_THE_GROUP_BRANCH
	}
	///End TEMPORARY_HIDE_INTERVALS_SINCE_ROUND_LIMITS_DOES_NOT_SUPPORT_FIXED_STEPS
	
	
	/// Max 6/2/08 v8.0875b RUN_WITH_FLYOUT_THEME_REQUIRE_SPECIFY_AUTO_VARIABLES_IN_BEFORE_EXECUTE
	if(0 == nGetNDialog || -1 == nGetNDialog)
	{
		/// Iris 6/25/2009 QA80-13289-S1 CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT
		//_init_tree_show(trGetN);
		/// Hong 09/09/09 QA90-14287 2DBINNING_SUPPORT_HANDLE_MIN_MAX
		//init_two_binning_tree_show(trGetN);
		_init_two_binning_tree_show(trGetN);
		/// end 2DBINNING_SUPPORT_HANDLE_MIN_MAX
		///end CENTRLIZE_CODE_FOR_WIND_ROSE_PLOT
	
	}
	/// END RUN_WITH_FLYOUT_THEME_REQUIRE_SPECIFY_AUTO_VARIABLES_IN_BEFORE_EXECUTE
	
	//------ fisher 11/16/07 ADD_MAP_ID_TO_CHM
	if(is_use_origin_chm())
		trGetN.SetAttribute(STR_HELPID_ATTRIB, IDD_XF_TwoDBinning);
	
	if (CER_NO_ERROR != _twodbinning_check_input(trGetN) && (dwCntrl&LTXF_THEME_USED) && nGetNDialog <= 0)
		nRet = XFEVT_PROCEED_WITH_DLG;			
		
	///Kyle 06/30/2010 ORG-209 EXPAND_2D_BINNING_TO_SUPPORT_ADDITIONAL_Y_COLUMN
	if( nGetNDialog == 0 && (dwCntrl & LTXF_EXECUTE) )
	{
		if( stats_count == trGetN.stats.nVal || stats_freq == trGetN.stats.nVal || base_specific != trGetN.base.nVal )
			trGetN.col.strVal = STR_OPTIONAL;
	}
	///End EXPAND_2D_BINNING_TO_SUPPORT_ADDITIONAL_Y_COLUMN
	
}
//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 TwoDBinning_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
