#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
//put additional include files here
#include <event_utils.h>
//put your own support static functions here



void colstats(const Range& irng, vector<string>& col, vector& mean, vector& sd, vector& sem, vector& n, vector& min, vector& q1, vector& median, vector& q3, vector& max, vector& iqr, vector& sum, vector& variance, vector& skewness, vector& kurtosis, vector& cv, vector& missing)
{
	int nErrCode = check_1_data(irng, true);
	
	if ( nErrCode != CER_NO_ERROR )
		XF_THROW(nErrCode);
	
	bool	bBasicStats = mean != NULL || sd != NULL || sem != NULL || sum != NULL || variance != NULL ||
						skewness != NULL || kurtosis != NULL || cv != NULL || n != NULL || missing != NULL;
	bool	bQuantiles = min != NULL || q1 != NULL || median != NULL || q3 != NULL || max != NULL || iqr != NULL;
	
	SheetRangesList rngList(irng);
	int nNumSheet = rngList.GetNumSheets();
	
	for ( int ii=0; ii<nNumSheet; ++ii )
	{
		int nNumSubRange = rngList.GetNumSubRange(ii);
		Worksheet wks;
		vector<uint> vnRows, vnIndeces;
		for ( int jj=0; jj< nNumSubRange; ++jj )
		{
			ORANGE orng;
			if ( rngList.GetRange(ii, wks, jj, &orng) )
			{
				for ( ; orng.c1<=orng.c2; ++orng.c1 )
				{
					Column		cc(wks, orng.c1);
					vector		vd;
					///Kyle 08/14/2009 QA80-14136 COL_STATS_DO_STATISTICS_ON_SUB_COLUMNS
					//vd = (vector)cc.GetDataObject();
					vector		vdTmp;
					vdTmp = (vector)cc.GetDataObject();
					vdTmp.GetSubVector(vd, orng.r1, orng.r2);
					///End COL_STATS_DO_STATISTICS_ON_SUB_COLUMNS
					
					if ( col != NULL )
					{
						string strColName = cc.GetLongName();
						if ( strColName.IsEmpty() )
							strColName = cc.GetName();
						col.Add(strColName);
					}
					
					if ( bBasicStats )
					{
						int					nN, nMissing;
						double				dMean, dSD, dSE, dSum, dVariance, dSkewness, dKurtosis, dCV;
						int nRet = ocmath_basic_summary_stats(vd.GetSize(), vd, &nN, &dMean, &dSD, &dSE, &dVariance, &dSum, &dSkewness, &dKurtosis, NULL, NULL, &dCV, NULL, &nMissing);
						if ( nRet != OE_NOERROR )
							XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
						
						if ( mean != NULL )
							mean.Add(dMean);
						if ( sd != NULL)
							sd.Add(dSD);
						if ( sem != NULL )
							sem.Add(dSE);
						if ( sum != NULL )
							sum.Add(dSum);
						if ( variance != NULL )
							variance.Add(dVariance);
						if ( skewness != NULL )
							skewness.Add(dSkewness);
						if ( kurtosis != NULL )
							kurtosis.Add(dKurtosis);
						if ( cv != NULL )
							cv.Add(dCV);
						if ( n != NULL )
							n.Add(nN);
						if ( missing != NULL )
							missing.Add(nMissing);
					}
					
					if ( bQuantiles )
					{
						QuantileOptions		stQuantileOptions = {0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0};
						QuantileResults		stQuantileResults;
						int nRet = ocmath_quantiles(vd, vd.GetSize(), &stQuantileOptions, &stQuantileResults);
						if ( nRet != OE_NOERROR )
							XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
						
						if ( min != NULL )
							min.Add(stQuantileResults.Min);
						if ( q1 != NULL )
							q1.Add(stQuantileResults.Q1);
						if ( median != NULL )
							median.Add(stQuantileResults.Median);
						if ( q3 != NULL )
							q3.Add(stQuantileResults.Q3);
						if ( max != NULL )
							max.Add(stQuantileResults.Max);
						if ( iqr != NULL )
							iqr.Add(stQuantileResults.IQR);
					}
				}
			}
		}
	}
}

//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 colstats_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return colstats_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	return false;

}

int colstats_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 colstats_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{

}
//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 colstats_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
