#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	bin_center,
	bin_end,
	bin_custom,
};
enum{
	stepby_increment,
	stepby_interval,
};
enum{
	show_fraction,
	show_percent,
};
#include <event_utils.h>
#include <GetNBox.h>
#include <stats_utils.h>
#include <o8dlg.h>
//put additional include files here

/*------------------------------------------------------------------------------*
 * Modification Log:															*
 *	Folger 02/02/09 QA80-12735-P2 FREQ_COUNTS_THROW_UNKNOW_ERROR_WHEN_VECTOR_BINS_HAS_MISSING_VALUE_ON_THE_RIGHT
 *	Kyle 02/20/2009 QA80-13149 FREQUENCY_COUNT_SHOULD_UPDATE_MIN_MAX_ACCORDING_TO_INCREMENT_CHANGES
 *	Kyle 02/20/2009 QA80-13149 TEMPORARY_HIDE_INTERVALS_SINCE_ROUND_LIMITS_DOES_NOT_SUPPORT_FIXED_STEPS
 *	Folger 02/24/09 QA80-13149 SET_INTERVAL_AS_READONLY_INSTEAD_OF_DISABLED		*
 *	Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END		*
 *	Hong 09/09/09 QA80-14287 FREQUENCY_COUNT_ADD_MIN_MAX_COUNT					*
 *	Kyle 11/02/2009 QA80-14492 ENABLE_USER_TO_SPECIFY_BIN_SETTING_VIA_WORKSHEET_COLUMN_IN_GUI
 *	Kyle 07/21/2010 ORG-209-P5 UPDATE_INCLUDE_OUTLIERS_ON_CHECK_SEPARATELY_COUNT_MAXIMUM
 *	Kyle 07/23/2010 ORG-209-P5 BIN_END_MAY_BE_CHANGED_IN_CALCULATION			*
 *------------------------------------------------------------------------------*/

//put your own support static functions here
#define FREQ_REPORT_TABLE	0x00000010
enum _FREQ_COUNTS_RES_ID
{
	_FREQ_COUNTS_BIN_CENTER	= 0x00010010,
	_FREQ_COUNTS_BIN_END,
	_FREQ_COUNTS_COUNT,
	_FREQ_COUNTS_CUMUL_COUNT,
	_FREQ_COUNTS_FREQ,
	_FREQ_COUNTS_CUMUL_FREQ,
	
};

enum _FREQ_SHOW_OPTION
{
	_FREQ_FRACTION,
	_FREQ_PERCENT,
};

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 bool _at_least_1_output(const TreeNode& trGetN)
{
	if (trGetN.center.nVal || trGetN.end.nVal || trGetN.count.nVal || trGetN.cumulcount.nVal || trGetN.freq.nVal || trGetN.cumulfreq.nVal)
		return true;
	else
		return false;
}

static void _get_bin_end(vector& vBinEnds, FreqCountOptions& fcoOptions)
{
	double dInc = fcoOptions.StepSize;
	
	int nStart=0, nEnd=vBinEnds.GetSize();
	if( fcoOptions.IncludeLTMin ) 
	{
		vBinEnds[0] = fcoOptions.FromMin;
		nStart++;
	}
	if( fcoOptions.IncludeGEMax )
	{
		vBinEnds[vBinEnds.GetSize()-1] = NANUM;
		nEnd--;
	}
	/// Hong 09/09/09 QA80-14287 FREQUENCY_COUNT_ADD_MIN_MAX_COUNT
	if( fcoOptions.IncludeMin )
		vBinEnds[nStart++] = fcoOptions.FromMin;
	if ( fcoOptions.IncludeMax )
	{
		///Kyle 07/23/2010 ORG-209-P5 BIN_END_MAY_BE_CHANGED_IN_CALCULATION
		//vBinEnds[--nEnd] = fcoOptions.ToMax;
		nEnd--;
		vBinEnds[nEnd] = fcoOptions.FromMin + (nEnd-nStart) * dInc;
		///End BIN_END_MAY_BE_CHANGED_IN_CALCULATION
	}
	/// end FREQUENCY_COUNT_ADD_MIN_MAX_COUNT
	
	int index=1;
	for( int ii=nStart; ii < nEnd; ii++ )
	{			
		vBinEnds[ii] = fcoOptions.FromMin + index * dInc;
		index++;
	}

}

static void _get_freq(vector& vFreq, const vector& vCount, const bool bCumulative)
{
	int nSize = vCount.GetSize(); 
	vFreq.SetSize(nSize);
	
	double dSumPts;	
	if (bCumulative)
	{
		dSumPts = vCount[nSize-1];
		
	}else
	{
		vCount.Sum(dSumPts);
		
	}
	vFreq = vCount / dSumPts;
	
}
static bool _freq_update_report_data(ReportData& outData, const vector* pvBinCenter, const vector* pvBinEnd, const vector* pvCounts, const vector* pvCumulCount, const vector* pvFreq, const vector* pvCulmulFreq, LPCSTR lpsczLabel, int iFormat)
{
	if (!outData)
		return false;
	
	//string strFreqCounts = "Frequency Counts of " + _L(lpsczLabel);	
	string strFreqCounts = "Frequency Counts of " + (string)lpsczLabel;	/// Hong 11/07/07 v.8.0742 FIX_ERROR_LOCALIZED
	ReportTable rtFreqCount = outData.CreateTable("FreqCount", strFreqCounts, FREQ_REPORT_TABLE);
	
	/// Fisher 12/08/08         QA80-12735       SUPPORT_USER_SUPPLIED_BIN_VECTOR_IN_FREQCOUNTS 
	//if (pvBinCenter)	rtFreqCount.AddColumn(*pvBinCenter, "BinCenter",_FREQ_COUNTS_BIN_CENTER, _L("Bin Center"), OKDATAOBJ_DESIGNATION_X);
	//if (pvBinEnd)	rtFreqCount.AddColumn(*pvBinEnd, "BinEnd",_FREQ_COUNTS_BIN_END, _L("Bin End"), OKDATAOBJ_DESIGNATION_Y);
	if (pvBinCenter)
	{
		TreeNode tr = rtFreqCount.AddColumn(*pvBinCenter, "BinCenter",_FREQ_COUNTS_BIN_CENTER, _L("Bin Center"), OKDATAOBJ_DESIGNATION_X);
		tr.SetAttribute(STR_COL_FORMAT_ATTRIB, iFormat);
	}
	if (pvBinEnd)
	{
		TreeNode tr = rtFreqCount.AddColumn(*pvBinEnd, "BinEnd",_FREQ_COUNTS_BIN_END, _L("Bin End"), OKDATAOBJ_DESIGNATION_Y);
		tr.SetAttribute(STR_COL_FORMAT_ATTRIB, iFormat);
	}
	/// End SUPPORT_USER_SUPPLIED_BIN_VECTOR_IN_FREQCOUNTS	
	
	if (pvCounts)	rtFreqCount.AddColumn(*pvCounts, "Counts",_FREQ_COUNTS_COUNT, _L("Count"), OKDATAOBJ_DESIGNATION_Y);
	if (pvCumulCount)	rtFreqCount.AddColumn(*pvCumulCount, "CumulCounts",_FREQ_COUNTS_CUMUL_COUNT, _L("Cumulative Count"), OKDATAOBJ_DESIGNATION_Y);
	if (pvFreq)	rtFreqCount.AddColumn(*pvFreq, "Freqs",_FREQ_COUNTS_FREQ, _L("Relative Frequency"), OKDATAOBJ_DESIGNATION_Y);
	if (pvCulmulFreq)	rtFreqCount.AddColumn(*pvCulmulFreq, "CumulFreq",_FREQ_COUNTS_CUMUL_FREQ, _L("Cumulative Frequency"), OKDATAOBJ_DESIGNATION_Y);
	
	return true;
	
}

static int freqcounts_check_input(TreeNode trGetN)
{
	int nErrCode;
	int nMin;
	nErrCode = check_1_data(trGetN.irng, false, false, &nMin);
	
	if (nErrCode == CER_NO_ERROR && nMin < 2)
		return CER_DATA_TOO_FEW;
	///Kyle 11/02/2009 QA80-14492 ENABLE_USER_TO_SPECIFY_BIN_SETTING_VIA_WORKSHEET_COLUMN_IN_GUI
	/*
	if (!check_min_max(trGetN.min.dVal, trGetN.max.dVal) )
	{
		if(CER_NO_ERROR == nErrCode)	nErrCode = CER_MIN_MAX;
	}
	if (!check_intervals(trGetN.intervals))
	{
		if(CER_NO_ERROR == nErrCode)	nErrCode = CER_INVALID_INTERVAL_NUM;
	}
	*/
	if( trGetN.bin.nVal != bin_custom )
	{
		if (!check_min_max(trGetN.min.dVal, trGetN.max.dVal) )
		{
			if(CER_NO_ERROR == nErrCode)	nErrCode = CER_MIN_MAX;
		}
		if (!check_intervals(trGetN.intervals))
		{
			if(CER_NO_ERROR == nErrCode)	nErrCode = CER_INVALID_INTERVAL_NUM;
		}
	}
	else
	{
		DWORD dwRules = DRR_NO_WEIGHTS;
		DataRange rngBins;
		TreeNode trBins = trGetN.bins;
		okxf_resolve_tree_construct_range(&trBins, &rngBins);
		if ( !rngBins || rngBins.GetNumData(dwRules) != 1 )
			nErrCode = XF_FREQ_INVALID_BINS;
		else
		{
			DWORD dwPlotID;
			vector vData;
			rngBins.GetData(dwRules, 0, &dwPlotID, NULL, &vData, NULL, NULL, NULL);
			if( vData.GetSize() < 2 )
			{
				nErrCode = XF_FREQ_SIZE_OF_BINS;
			}
			else if( MONO_INCREASE != ocmath_is_monotonic( vData, vData.GetSize(), true) )
			{
				nErrCode = XF_FREQ_BINS_MONOTONIC;
			}
		}
	}
	///End ENABLE_USER_TO_SPECIFY_BIN_SETTING_VIA_WORKSHEET_COLUMN_IN_GUI

	if ( !_at_least_1_output(trGetN) )
	{
		if(CER_NO_ERROR == nErrCode)	nErrCode = CER_SUPPRESS_ALL_OUTPUT;
	}
	
	return nErrCode;
}

///Kyle 07/21/2010 ORG-209-P5 UPDATE_INCLUDE_OUTLIERS_ON_CHECK_SEPARATELY_COUNT_MAXIMUM
static void _update_include_outliers(TreeNode& trGetN)
{
	if( !(trGetN && trGetN.outright && trGetN.cmax) )
		return;

	string strLabel = trGetN.cmax.nVal ? _L("Include Outliers > Maximum") : _L("Include Outliers >= Maximum");
	trGetN.outright.SetAttribute(STR_LABEL_ATTRIB, strLabel);
}
///End UPDATE_INCLUDE_OUTLIERS_ON_CHECK_SEPARATELY_COUNT_MAXIMUM


///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;
	
	if(trGetN.bin.nVal == bin_center)	// 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.min.SetAttribute(STR_LABEL_ATTRIB, strMinLabel);
	trGetN.max.SetAttribute(STR_LABEL_ATTRIB, strMaxLabel);
}
///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END



void freqcounts(const Range& irng, const int& bin, const double& min, const double& max, const int& stepby, const double& inc, const double& intervals, const int& outleft, const int& outright, const int& cmin, const int& cmax, const vector& bins, const int& center, const int& end, const int& count, const int& cumulcount, const int& freq, const int& cumulfreq, const int& show, ReportData& rd)
{
	
	if (1 != irng.GetNumData(DRR_NO_WEIGHTS))
	{
		XF_THROW(CER_COL_NUM_NOT_ONE);
	}
	///Kyle 11/02/2009 QA80-14492 ENABLE_USER_TO_SPECIFY_BIN_SETTING_VIA_WORKSHEET_COLUMN_IN_GUI
	/*
	if (!check_min_max(min, max) )
	{
		XF_THROW(CER_MIN_MAX);
	}
	if ( !check_intervals(intervals) )
	{
		XF_THROW(CER_INVALID_INTERVAL_NUM);
	}
	*/
	bool bUserBins = bin == bin_custom;
	if( bin != bin_custom )
	{
		if (!check_min_max(min, max) )
		{
			XF_THROW(CER_MIN_MAX);
		}
		if ( !check_intervals(intervals) )
		{
			XF_THROW(CER_INVALID_INTERVAL_NUM);
		}
	}
	else
	{
		if( !bins )
			XF_THROW(XF_FREQ_INVALID_BINS);
		if( bins.GetSize() < 2 )
			XF_THROW(XF_FREQ_SIZE_OF_BINS);
		if( MONO_INCREASE != ocmath_is_monotonic(bins, bins.GetSize(), true) )
			XF_THROW(XF_FREQ_BINS_MONOTONIC);
	}
	///End ENABLE_USER_TO_SPECIFY_BIN_SETTING_VIA_WORKSHEET_COLUMN_IN_GUI
	vector vData;
	irng.GetData(vData, 0);	
	vData.Trim();
	int nSize = vData.GetSize();
	if (0 == nSize )
	{
		XF_THROW(CER_NO_DATA);
	}
	FreqCountOptions stOption;
	///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	//stOption.FromMin = min;
	//stOption.ToMax = max;
	stOption.FromMin = min - (bin == bin_center ? inc / 2 : 0);
	stOption.ToMax = max + (bin == bin_center ? inc / 2 : 0);
	///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
	stOption.StepSize = inc;
	stOption.IncludeLTMin = outleft;
	stOption.IncludeGEMax = outright;
	/// Hong 09/09/09 QA80-14287 FREQUENCY_COUNT_ADD_MIN_MAX_COUNT
	stOption.IncludeMin = cmin;
	stOption.IncludeMax = cmax;
	/// end FREQUENCY_COUNT_ADD_MIN_MAX_COUNT
	
	vector vBinCenters, vCounts, vCumulCount;
	
	///------ Folger 02/02/09 QA80-12735-P2 FREQ_COUNTS_THROW_UNKNOW_ERROR_WHEN_VECTOR_BINS_HAS_MISSING_VALUE_ON_THE_RIGHT
	if ( bins )
	{
		bins.TrimLeft(TRUE);
		bins.TrimRight(TRUE);
	}
	///------ End FREQ_COUNTS_THROW_UNKNOW_ERROR_WHEN_VECTOR_BINS_HAS_MISSING_VALUE_ON_THE_RIGHT
	
	/// Fisher 12/08/08         QA80-12735       SUPPORT_USER_SUPPLIED_BIN_VECTOR_IN_FREQCOUNTS 
	///Kyle 11/02/2009 QA80-14492 ENABLE_USER_TO_SPECIFY_BIN_SETTING_VIA_WORKSHEET_COLUMN_IN_GUI
	//int nRet = stats_frequency_count(vData, stOption, vBinCenters, vCounts, vCumulCount, FC_STEPSIZE, bins);
	int nRet = stats_frequency_count(vData, stOption, vBinCenters, vCounts, vCumulCount, FC_STEPSIZE, bin==bin_custom ? bins : NULL);
	///End ENABLE_USER_TO_SPECIFY_BIN_SETTING_VIA_WORKSHEET_COLUMN_IN_GUI
	//int nRet = stats_frequency_count(vData, stOption, vBinCenters, vCounts, vCumulCount);
	/// End SUPPORT_USER_SUPPLIED_BIN_VECTOR_IN_FREQCOUNTS	
	if (nRet != STATS_NO_ERROR)
	{
		XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
	}
	
	
	vector vBinEnd, vFreq, vCulmulFreq;
	vBinEnd.SetSize(vBinCenters.GetSize());
	
	/// Fisher 12/08/08         QA80-12735       SUPPORT_USER_SUPPLIED_BIN_VECTOR_IN_FREQCOUNTS 
	///Kyle 11/02/2009 QA80-14492 ENABLE_USER_TO_SPECIFY_BIN_SETTING_VIA_WORKSHEET_COLUMN_IN_GUI
	//bool bUserBins = bins && bins.GetSize()>1;
	///End ENABLE_USER_TO_SPECIFY_BIN_SETTING_VIA_WORKSHEET_COLUMN_IN_GUI
	if(bUserBins)
	{
		int intervals = bins.GetSize()-1;
		ASSERT(vBinEnd.GetSize() == intervals);
		for(int ii=0; ii<intervals; ++ii)
			vBinEnd[ii] = bins[ii+1];		
	}
	else
		_get_bin_end(vBinEnd, stOption);
	//_get_bin_end(vBinEnd, stOption);
	/// End SUPPORT_USER_SUPPLIED_BIN_VECTOR_IN_FREQCOUNTS	
	
	
	_get_freq(vFreq, vCounts, false);
	_get_freq(vCulmulFreq, vCumulCount, true);
	
	if (show == _FREQ_PERCENT)
	{
		vFreq = vFreq * 100;
		vCulmulFreq = vCulmulFreq * 100;
	}
	
	/// Fisher 12/08/08         QA80-12735       SUPPORT_USER_SUPPLIED_BIN_VECTOR_IN_FREQCOUNTS
	Column cc;
	range_get_col(irng, 0, cc);
	int iFormat = cc.GetFormat();
	/// End SUPPORT_USER_SUPPLIED_BIN_VECTOR_IN_FREQCOUNTS	
	
	string strLab = range_get_col_name(irng);
	
	vector* pvBinCenters = NULL;
	vector* pvBinEnd = NULL;
	vector* pvCounts = NULL;
	vector* pvCumulCount = NULL;
	vector* pvFreq = NULL;
	vector* pvCulmulFreq = NULL;
	
	if (center )	pvBinCenters = &vBinCenters;
	if (end )	pvBinEnd = &vBinEnd;
	if (count )	pvCounts = &vCounts;
	if (cumulcount )	pvCumulCount = &vCumulCount;
	if (freq )	pvFreq = &vFreq;
	if (cumulfreq )	pvCulmulFreq = &vCulmulFreq;
	
	_freq_update_report_data(rd, pvBinCenters, pvBinEnd, pvCounts, pvCumulCount, pvFreq, pvCulmulFreq, strLab, iFormat);
	
}

//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 freqcounts_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return freqcounts_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	
	///Kyle 11/02/2009 QA80-14492 ENABLE_USER_TO_SPECIFY_BIN_SETTING_VIA_WORKSHEET_COLUMN_IN_GUI
	bool bUserBins = (trGetN.bin.nVal == bin_custom);
	trGetN.bins.Show = bUserBins;
	trGetN.min.Show = !bUserBins;		// show/hide the first one of the grouped
	///End ENABLE_USER_TO_SPECIFY_BIN_SETTING_VIA_WORKSHEET_COLUMN_IN_GUI
	
	Range rData;
	TreeNode tr = trGetN.irng;
	okxf_resolve_tree_construct_range(&tr, &rData);
	if (rData)
	{
		vector vData;
		rData.GetData(vData, 0);
		///Kyle 02/20/2009 QA80-13149 FREQUENCY_COUNT_SHOULD_UPDATE_MIN_MAX_ACCORDING_TO_INCREMENT_CHANGES
		//set_round_limits(vData, trGetN.min, trGetN.max, trGetN.inc, trGetN.intervals);
		///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
		//set_round_limits(vData, trGetN.min, trGetN.max, trGetN.inc, trGetN.intervals, trGetN.stepby.nVal);
		set_round_limits(vData, trGetN.min, trGetN.max, trGetN.inc, trGetN.intervals, trGetN.stepby.nVal, trGetN.bin.nVal == bin_center);
		///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
		///End FREQUENCY_COUNT_SHOULD_UPDATE_MIN_MAX_ACCORDING_TO_INCREMENT_CHANGES
	}
	
	///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 07/21/2010 ORG-209-P5 UPDATE_INCLUDE_OUTLIERS_ON_CHECK_SEPARATELY_COUNT_MAXIMUM
	_update_include_outliers(trGetN);
	///End UPDATE_INCLUDE_OUTLIERS_ON_CHECK_SEPARATELY_COUNT_MAXIMUM
	
	freq_update_inc(trGetN);
	
	///------ Folger 02/24/09 QA80-13149 SET_INTERVAL_AS_READONLY_INSTEAD_OF_DISABLED
	trGetN.intervals.Enable = ENABLE_READ_ONLY;
	///------ End SET_INTERVAL_AS_READONLY_INSTEAD_OF_DISABLED
	
	trGetN.show.Enable = trGetN.freq.nVal || trGetN.cumulfreq.nVal;
	
	int nErrCode = freqcounts_check_input(trGetN);
	//----- CPY 10/26/06 QA70-9063 DYNAMIC_ERR_MSG_IN_GETN_DIALOGS
	/*
	DynaCntrlContainer.PostMessage(WM_USER_MSG_BOX, nErrCode);
	*/
	if(CER_NO_ERROR != nErrCode)
	{
		strErrMsg = nErrCode;
		if (nErrCode == CER_DATA_TOO_FEW)
			strErrMsg += ":" + 2;
		bOKEnable = false;
	}
	//----- end DYNAMIC_ERR_MSG_IN_GETN_DIALOGS
	/*
	if(GETNE_ON_OK == nEventID) // set bOKEnable to determine if to allow continue OK processing to execute and close dialog 
	{
		int nErr = check_1_data(trGetN.irng);
		if ( OE_NOERROR != nErr )
		{
			DynaCntrlContainer.PostMessage(WM_USER_MSG_BOX, nErr);
			bOKEnable = false;		
		}
		if (!check_min_max(trGetN.min.dVal, trGetN.max.dVal) )
		{
			DynaCntrlContainer.PostMessage(WM_USER_MSG_BOX, CER_MIN_MAX);
			bOKEnable = false;
			
		}
		if (!check_intervals(trGetN.intervals))
		{
			DynaCntrlContainer.PostMessage(WM_USER_MSG_BOX, CER_INVALID_INTERVAL_NUM);
			bOKEnable = false;
		}
	
		if ( !_at_least_1_output(trGetN) )
		{
			DynaCntrlContainer.PostMessage(WM_USER_MSG_BOX, CER_SUPPRESS_ALL_OUTPUT);
			bOKEnable = false;
		}
	}
	*/
		
	return true;
	

}

int freqcounts_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 freqcounts_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_freqcounts);
	
	///Kyle 02/20/2009 QA80-13149 TEMPORARY_HIDE_INTERVALS_SINCE_ROUND_LIMITS_DOES_NOT_SUPPORT_FIXED_STEPS
	if(is_xf_startup(nGetNDialog, dwCntrl))
	{
		trGetN.stepby.nVal = 0;
		trGetN.stepby.Show = false;
		///------ Folger 02/24/09 QA80-13149 SET_INTERVAL_AS_READONLY_INSTEAD_OF_DISABLED
		//trGetN.intervals.Enable = ENABLE_READ_ONLY;
		trGetN.intervals.RemoveAttribute(STR_ATTRIB_AUTO);
		///------ End SET_INTERVAL_AS_READONLY_INSTEAD_OF_DISABLED
	}
	///End TEMPORARY_HIDE_INTERVALS_SINCE_ROUND_LIMITS_DOES_NOT_SUPPORT_FIXED_STEPS
	
	if(0 == nGetNDialog || -1 == nGetNDialog)
	{
		Range rData;
		TreeNode tr = trGetN.irng;
		okxf_resolve_tree_construct_range(&tr, &rData);
		if (rData)
		{
			vector vData;
			rData.GetData(vData, 0);
			///Kyle 02/20/2009 QA80-13149 FREQUENCY_COUNT_SHOULD_UPDATE_MIN_MAX_ACCORDING_TO_INCREMENT_CHANGES
			//set_round_limits(vData, trGetN.min, trGetN.max, trGetN.inc, trGetN.intervals);
			///Kyle 03/12/2009 QA80-13251 ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
			//set_round_limits(vData, trGetN.min, trGetN.max, trGetN.inc, trGetN.intervals, trGetN.stepby.nVal);
			set_round_limits(vData, trGetN.min, trGetN.max, trGetN.inc, trGetN.intervals, trGetN.stepby.nVal, trGetN.bin.nVal == bin_center);
			///End ADD_OPTION_TO_SPECIFY_BIN_BY_CENTER_OR_END
			///End FREQUENCY_COUNT_SHOULD_UPDATE_MIN_MAX_ACCORDING_TO_INCREMENT_CHANGES
		}
		///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
	
		freq_update_inc(trGetN);
		if (CER_NO_ERROR != freqcounts_check_input(trGetN) && (dwCntrl&LTXF_THEME_USED) && (dwCntrl&LTXF_FROM_GUI_MENU))
			nRet = XFEVT_PROCEED_WITH_DLG;			
			
	}
	///Kyle 11/02/2009 QA80-14492 ENABLE_USER_TO_SPECIFY_BIN_SETTING_VIA_WORKSHEET_COLUMN_IN_GUI
	if(nGetNDialog == 0 && (dwCntrl & LTXF_EXECUTE) && trGetN.bin.nVal != bin_custom )
		trGetN.bins.strVal = STR_OPTIONAL;
	///End ENABLE_USER_TO_SPECIFY_BIN_SETTING_VIA_WORKSHEET_COLUMN_IN_GUI
	
}
//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 freqcounts_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
