#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	method_first,
	method_last,
	method_ave,
	method_min,
	method_max,
	method_sum,
	method_sd,
};


//put additional include files here
#include <event_utils.h>
#include <ReportTree.h>

/////////////////////////////////////////////////////////////////////////////
// Modification Log
//
// Kyle 12/22/2008 OPEN_DIALOG_WHEN_THEME_IS_USED_AND_ERROR_HAPPENS
// Kyle 12/22/2008 OUTPUT_COLUMN_COMMENTS
// Sim 10-09-2009 QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF
// Sim 10-09-2009 QA81-14428 FIX_COPY_COL_FORMAT_FOR_REDUCE_XF
// Kyle 10/10/2009 QA80-14187 REPORT_TREE_COPY_PROPERTY_FROM_SOURCE_COLUMN
// Kyle 10/19/2009 QA80-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
// Kyle 10/29/2009 QA80-14428-P2 COPY_ROW_HEADER_INFO
/////////////////////////////////////////////////////////////////////////////


//put your own support static functions here

#define REDUCE_ROWS_REPORT_TABLE		0x00000010
#define REDUCE_ROWS_COL_BEGIN			0x00010010

///Kyle 10/19/2009 QA80-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
/*
static double get_data(const vector& vIn, const int iOption)
{
	double dMin, dMax;
	vIn.GetMinMax(dMin, dMax);
	
	DescStatResults dsr;
	int nSize = vIn.GetSize();
	int nRet = ocmath_desc_stats(vIn, nSize, &dsr);
	if (nRet != STATS_NO_ERROR)
		return NANUM;
	
	switch (iOption)
	{
	case method_first:	
		return vIn[0];
		break;
	case method_last:
		return vIn[nSize - 1];
		break;
	case method_ave:
		return dsr.Mean;
		break;
	case method_min:
		return dMin;
		break;
	case method_max:
		return dMax;
		break;
	case 	method_sum:
		return dsr.Sum;
		break;
	case method_sd:
		return dsr.SD;
		break
	default:
		return NANUM;	
	}
	
	return NANUM;
}
*/
///End SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP

static bool merge_fixed_datapoints(const vector& vData, const int nNum, const int iOption, vector& vMerged)
{
	///Kyle 10/19/2009 QA80-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
	/*
	int nSize = vData.GetSize();
	if (nNum > nSize)
		return false;
	
	matrix mData(vData);
	matrix mSubData;
	int nBins = (int)(nSize/nNum);
	vMerged.SetSize(nBins);
	
	int iBegin, iEnd;
	vector vSubData;
	for (int ii = 0; ii < nBins; ii ++)
	{
		iBegin = ii * nNum;
		iEnd = (ii + 1) * nNum - 1;
		mData.GetSubMatrix(mSubData,0,-1,iBegin,iEnd);
		mSubData.GetColumn(vSubData, 0);
		vMerged[ii] = get_data(vSubData, iOption);	
	}
	
	if (mod(nSize, nNum) != 0)
	{
		mData.GetSubMatrix(mSubData,0,-1,iEnd + 1, nSize - 1);
		mSubData.GetColumn(vSubData, 0);
		vMerged.Add(get_data(vSubData, iOption));	
	}
	return true;	
	*/
	int nSize = vData.GetSize();
	if (nNum <= 0 || nNum > nSize)
		return false;
	
	int nMethodOption;
	switch(iOption)
	{
	case method_first:
		nMethodOption = REDUCE_XY_STATS_FIRST;
		break;
		
	case method_last:
		nMethodOption = REDUCE_XY_STATS_LAST;
		break;
		
	case method_ave:
		nMethodOption = REDUCE_XY_STATS_MEAN;
		break;
		
	case method_min:
		nMethodOption = REDUCE_XY_STATS_MIN;
		break;
		
	case method_max:
		nMethodOption = REDUCE_XY_STATS_MAX;
		break;
		
	case method_sum:
		nMethodOption = REDUCE_XY_STATS_SUM;
		break;
		
	case method_sd:
		nMethodOption = REDUCE_XY_STATS_SD;
		break;
		
	default:
		ASSERT(false);
		return false;
	}
	vMerged.SetSize(nSize/nNum + 1);			//

	int nMergedSize = ocmath_reducexy_n_points(vData, vMerged, nSize, nNum, nMethodOption);
	if(nMergedSize >= 0)
	{
		vMerged.SetSize(nMergedSize);
		return true;
	}
	return false;
	///End SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
}
///---Sim 10-09-2009 QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF
static bool merge_fixed_datapoints(const vector<string>& vsData, const int nNum, const int iOption, vector<string>& vsMerged)
{
	int nSize = vsData.GetSize();
	if (nNum > nSize)
		return false;
	
	if ( !( method_first == iOption || method_last == iOption ) )
		return false;
	bool bFirst = method_first == iOption;					///Kyle 10/19/2009 QA80-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
	int nBins = (int)(nSize/nNum);
	vsMerged.SetSize(nBins);
	
	int iBegin, iEnd;
	//vector<string> vsSubData;
	for (int ii = 0; ii < nBins; ii ++)
	{
		iBegin = ii * nNum;
		iEnd = (ii + 1) * nNum - 1;
		//vsData.GetSubVector(vsSubData, iBegin, iEnd);
		//vsMerged[ii] = (method_first == iOption) ? vsSubData[0] : vsSubData[vsSubData.GetSize()-1];
		///Kyle 10/19/2009 QA80-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
		//vsMerged[ii] = (method_first == iOption) ? vsData[iBegin] : vsData[iEnd];
		vsMerged[ii] = bFirst ? vsData[iBegin] : vsData[iEnd];
		///End SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
	}
	
	if (mod(nSize, nNum) != 0)
	{
		//vsData.GetSubVector(vsSubData, iEnd + 1, nSize - 1);
		//vsMerged.Add((method_first == iOption) ? vsSubData[0] : vsSubData[vsSubData.GetSize()-1]);
		///Kyle 10/19/2009 QA80-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
		//vsMerged.Add((method_first == iOption) ? vsData[iEnd + 1] : vsData[nSize - 1]);
		vsMerged.Add(bFirst ? vsData[iEnd + 1] : vsData[nSize - 1]);
		///End SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
	}
	return true;	
	
}
///---END QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF
///Kyle 12/22/2008 OUTPUT_COLUMN_COMMENTS
static int _get_column_designation(const DataRange& iy, int nIndex)
{
	int nDesignation = OKDATAOBJ_DESIGNATION_Y;//default

	Column col;
	range_get_col(iy, nIndex, col);
	if(col)
		nDesignation = col.GetType();

	return nDesignation;
}
static string _get_method_string(int nMethod)
{
	string strMethod;
	switch(nMethod)
	{
	case method_first:
		strMethod = "First Point";
		break;
	case method_last:
		strMethod = "Last Point";
		break;
	case method_ave:
		strMethod = "Average";
		break;
	case method_min:
		strMethod = "Min";
		break;
	case method_max:
		strMethod = "Max";
		break;
	case method_sum:
		strMethod = "Sum";
		break;
	case method_sd:
		strMethod = "SD";
		break;
	}
	return strMethod;
}
static	void	_set_output_range_comments(DataRange &oy, const DataRange& iy, int nPoints, int nMethod)
{
	DWORD dwRules = DRR_NO_WEIGHTS | DRR_NO_FACTORS | DRR_GET_MISSING;
	int nNumRanges = iy.GetNumData(dwRules);
	string strMethod = _get_method_string(nMethod);

	for( int ii = 0; ii < nNumRanges; ii++ )
	{
		string strColLongName = range_get_col_name(iy, ii, true);
		if(!strColLongName.IsEmpty())
		{
			string strComments;
			strComments.Format(_L("reduce every %d points with %s of %s"), nPoints, _L(strMethod), strColLongName);
			Column col;
			range_get_col(oy, ii, col);
			if(col)
				col.SetComments(strComments);
		}
	}
}
///End OUTPUT_COLUMN_COMMENTS

///Kyle 10/19/2009 QA80-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
static int _check_1_data(const Range& rData, int* nMinSize = NULL, int* nMaxSize = NULL)
{
	
	DWORD dwRules = DRR_NO_WEIGHTS | DRR_GET_MISSING;
	DWORD dwPlotID;

	int nNumRanges = rData.GetNumData(dwRules);	

	if (1 > nNumRanges)
		return CER_COL_NUM_TOO_FEW_EX;
		
	vector vData;
	vector<string> vstrData;
	int nSize = 0, nMinTmp = 0, nMaxTmp = 0, nColSize = 0;
	for (int ii = 0; ii < nNumRanges; ii++)
	{
		rData.GetData(dwRules, ii, &dwPlotID, NULL, &vData, NULL, NULL, NULL);
		nColSize = vData.GetSize();

		nSize += nColSize;
		
		nMinTmp = (ii == 0) ? nColSize : min(nMinTmp, nColSize);
		nMaxTmp = (ii == 0) ? nColSize : max(nMaxTmp, nColSize);
	}

	if (0 == nSize)
		return CER_NO_DATA;	

	if (nMinSize)	*nMinSize = nMinTmp;
	if (nMaxSize)	*nMaxSize = nMaxTmp;

	return CER_NO_ERROR;
}
///End SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP

///---Sim 10-09-2009 QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF
int _check_data(const Range& rData, int nMethod, int nPoints)
{
	///Kyle 10/19/2009 QA80-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
	/*
	int nErrCode;
	int nMinSize, nMaxSize;
	nErrCode = check_1_data(rData, true, true, &nMinSize, &nMaxSize);
	if (nErrCode == CER_NO_ERROR && (nPoints > nMinSize || nPoints < 1))
		return XF_REDUCE_NUM_DATA;
	
	bool bSupportText = ( method_first == nMethod || method_last == nMethod );
	if ( !bSupportText )
	{
		nErrCode = check_1_data(rData, true, false, &nMinSize, &nMaxSize);
		if ( nErrCode == CER_NO_ERROR && nMinSize <= 0 )
			return CER_NO_DATA;
	}
	*/
	int nMinSize;
	int nErrCode = _check_1_data(rData, &nMinSize);
	if ( nErrCode == CER_NO_ERROR && (nPoints > nMinSize || nPoints < 1) )
		return XF_REDUCE_NUM_DATA;
	///End SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
	
	return nErrCode;
}
int _check_data(const TreeNode& trRange, int nMethod, int nPoints)
{
	if ( !trRange )
		return CER_INVALID_TREENODE;
	
	Range rData;
	okxf_resolve_tree_construct_range(&trRange, &rData);
	if ( !rData )
		return CER_INVALID_TREENODE;
	
	return _check_data(rData, nMethod, nPoints);
}
///---END QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF


void reducerows(const Range& irng, const int& npts, const int& method, ReportData& rd)
{
	
	/// *****		Terminate if error setting		***** ///
	///---Sim 10-09-2009 QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF
	//int nRet = check_1_data(irng, true);
	int nRet = _check_data(irng, method, npts);
	///---END QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF
	if (CER_NO_ERROR != nRet)
	{
		if (nRet == CER_COL_NUM_TOO_FEW_EX)
			XF_THROW_EX(nRet, 1)
		else
			XF_THROW(nRet);
	}
	
	
	///*** Begin reduce computation
	DWORD dwRules = DRR_NO_WEIGHTS | DRR_NO_FACTORS | DRR_GET_MISSING;
	int nNumRanges = irng.GetNumData(dwRules);
			
	///---Sim 10-09-2009 QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF
	//vector vDataCol, vMerged;
	///---END QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF
	//for( int ii = 0; ii < nNumRanges; ii++ )
	//{
		//int nDataCol = irng.GetData(dwRules, ii, NULL, NULL, &vDataCol, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
		//if (!merge_fixed_datapoints(vDataCol, num, method, vMerged))
		//{
			//XF_THROW(XF_REDUCE_NUM_DATA);
		//}
		//
		//if(!orng.SetColumnData(vMerged, true, ii))
			//return;
	//}
	///Kyle 12/22/2008 OUTPUT_COLUMN_COMMENTS
	//_set_output_range_comments(orng, irng, num, method);
	///End OUTPUT_COLUMN_COMMENTS
	if(!rd)
		XF_THROW(XFERR_FAILED_GET_RANGE);
	ReportTable rt = rd.CreateTable("ReduceRows", "", REDUCE_ROWS_REPORT_TABLE);
	if(!rt)
		XF_THROW(XFERR_FAILED_GET_RANGE);
	
	string strMethod = _get_method_string(method), strComments;
	
	int nID = REDUCE_ROWS_COL_BEGIN;
	for( int ii = 0; ii < nNumRanges; ii++ )
	{
		///---Sim 10-09-2009 QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF
		/*
		int nDataCol = irng.GetData(dwRules, ii, NULL, NULL, &vDataCol, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
		if (!merge_fixed_datapoints(vDataCol, npts, method, vMerged))
		{
			XF_THROW(XF_REDUCE_NUM_DATA);
		}
		string strComments;
		strComments.Format(_L("reduce every %d points with %s of %s"), npts, _L(strMethod), range_get_col_name(irng, ii, true));
		
		int nDesignation = _get_column_designation(irng, ii);
	
		TreeNode tr = rt.AddColumn(vMerged, "", nID++, NULL, nDesignation);
		tr.SetAttribute(STR_COMMENT_ATTRIB, strComments);
		*/
		///Kyle 10/19/2009 QA80-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
		/*
		Column col;
		DataRange drSub;
		if ( irng.GetSubRange(drSub, dwRules, ii) )
		{
			Worksheet wks;
			int nC1, nC2;
			if ( drSub.GetRange(wks, nC1, nC2, 0) && wks )
				col = wks.Columns(nC1);
		}
		
		int nDesignation = _get_column_designation(irng, ii);
		int nFormat = col.GetFormat();
		
		bool bNonCalc = ( method_first == method || method_last == method );
		bool bTextCol = ( OKCOLTYPE_TEXT == nFormat );
		
		if ( !bNonCalc && bTextCol )
		{
			XF_THROW(CER_NO_DATA);
		}
		
		TreeNode trColumn;
		if ( bTextCol )
		{
			vector<string> vsDataCol, vsMerged;
			col.GetStringArray(vsDataCol);
			if (!merge_fixed_datapoints(vsDataCol, npts, method, vsMerged) )
			{
				XF_THROW(XF_REDUCE_NUM_DATA);
			}
			trColumn = rt.AddColumn(vsMerged, "", nID++, NULL, nDesignation);
		}
		else
		{
			vector vDataCol, vMerged;
			int nDataCol = irng.GetData(dwRules, ii, NULL, NULL, &vDataCol, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
			if (!merge_fixed_datapoints(vDataCol, npts, method, vMerged))
			{
				XF_THROW(XF_REDUCE_NUM_DATA);
			}
			trColumn = rt.AddColumn(vMerged, "", nID++, NULL, nDesignation);
		}
		*/
		int nDesignation = _get_column_designation(irng, ii);
		TreeNode trColumn;
		if(0 != dr_get_col_percent_text(irng, ii) && (method_first == method || method_last == method))
		{
			DWORD dwPlotID;
			vector<string> vsDataCol, vsMerged;
			irng.GetData(dwRules, ii, &dwPlotID, NULL, &vsDataCol);
	
			if (!merge_fixed_datapoints(vsDataCol, npts, method, vsMerged) )
			{
				XF_THROW(XF_REDUCE_NUM_DATA);
			}
			trColumn = rt.AddColumn(vsMerged, "", nID++, NULL, nDesignation);
		}
		else
		{
			vector vDataCol, vMerged;
			int nDataCol = irng.GetData(dwRules, ii, NULL, NULL, &vDataCol, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
			if (!merge_fixed_datapoints(vDataCol, npts, method, vMerged))
			{
				XF_THROW(XF_REDUCE_NUM_DATA);
			}
			trColumn = rt.AddColumn(vMerged, "", nID++, NULL, nDesignation);
		}
		///End SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
		
		if ( trColumn )
		{
			string strComments;
			strComments.Format(_L("reduce every %d points with %s of %s"), npts, _L(strMethod), range_get_col_name(irng, ii, true));
			trColumn.SetAttribute(STR_COMMENT_ATTRIB, strComments);
			
			///Kyle 10/19/2009 QA80-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
			Column col;
			range_get_col(irng, ii, col);
			///End SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF_TRY_TO_SPEED_UP
	
			///---Sim 10-09-2009 QA81-14428 FIX_COPY_COL_FORMAT_FOR_REDUCE_XF
			if ( col )
			///Kyle 10/10/2009 QA80-14187 REPORT_TREE_COPY_PROPERTY_FROM_SOURCE_COLUMN
				//trColumn.SetAttribute(STR_COL_FORMAT_SRC_COL_UID_ATTRIB, col.GetUID(true));
			{
				int nSrcColUID = col.GetUID(true);
				///Kyle 10/29/2009 QA80-14428-P2 COPY_ROW_HEADER_INFO
				//DWORD dwCntrl = SRC_COL_PROPERTY_FORMAT;
				DWORD dwCntrl = SRC_COL_PROPERTY_FORMAT | SRC_COL_PROPERTY_LABELS;
				///End COPY_ROW_HEADER_INFO
				okutil_source_column_property(&trColumn, &nSrcColUID, &dwCntrl, false);
			}
			///End REPORT_TREE_COPY_PROPERTY_FROM_SOURCE_COLUMN
				
			///---END QA81-14428 FIX_COPY_COL_FORMAT_FOR_REDUCE_XF
		}
		///---END QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF
	}
	
}

//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 reducerows_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return reducerows_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	
	///---Sim 10-09-2009 QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF
	//int nMinSize, nMaxSize;
	//int nErrCode = check_1_data(trGetN.irng, true, false, &nMinSize, &nMaxSize);
	//if (nErrCode == CER_NO_ERROR && (trGetN.npts.nVal > nMinSize || trGetN.npts.nVal < 1))
		//nErrCode = XF_REDUCE_NUM_DATA;
	int nErrCode = _check_data(trGetN.irng, trGetN.method.nVal, trGetN.npts.nVal);
	///---END QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF
	
	if (nErrCode != CER_NO_ERROR)
	{
		bOKEnable = false;
		strErrMsg = nErrCode;
		if (nErrCode == CER_COL_NUM_TOO_FEW_EX)
			strErrMsg += ":" + 1;
	}
	
	
	return true;
	

}

int reducerows_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 reducerows_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	///Kyle 12/22/2008 OPEN_DIALOG_WHEN_THEME_IS_USED_AND_ERROR_HAPPENS
	if(is_xf_startup(nGetNDialog, dwCntrl))
	{
		if ( (dwCntrl&LTXF_THEME_USED) && nGetNDialog <= 0 )
		{
			///---Sim 10-09-2009 QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF
			//int nMinSize, nMaxSize;
			//int nErrCode = check_1_data(trGetN.irng, true, false, &nMinSize, &nMaxSize);
			//if (nErrCode == CER_NO_ERROR && (trGetN.npts.nVal > nMinSize || trGetN.npts.nVal < 1) )
				//nErrCode = XF_REDUCE_NUM_DATA;
			int nErrCode = _check_data(trGetN.irng, trGetN.method.nVal, trGetN.npts.nVal);
			///---END QA81-14428 SUPPORT_COPY_NON_NUMERIC_DATA_FOR_REDUCE_XF
			if (nErrCode != CER_NO_ERROR)
				nRet = XFEVT_PROCEED_WITH_DLG;
		}
	}
	///End OPEN_DIALOG_WHEN_THEME_IS_USED_AND_ERROR_HAPPENS
}
//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 reducerows_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
