#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	tail_two,
	tail_upper,
	tail_lower,
};

#include <o8dlg.h>
#include <stats_utils.h>
//#include <RangeEx.h>
#include <ReportTree.h>
#include <report_utils.h>
#include <GetNBox.h>
#include <event_utils.h>

//put additional include files here

/*------------------------------------------------------------------------------*
 * Modification Log:															*
 *	Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL						*
 *------------------------------------------------------------------------------*/

//put your own support static functions here
//const string  NPH2_FOOTER1 = "At the 0.05 level, the two distributions are significantly different. \n";
//const string  NPH2_FOOTER2 = "At the 0.05 level, the two distributions are not significantly different. \n";

#define IDST_NPH_MW_TEST      0x00000001
#define IDST_NPH_KSSTATS_TEST 0x00000010

//enum
//{
	//ERR_TOO_FEW_DATA = XF_LOCAL_ERR_BEGIN,
	//ERROR_DATA_DIFF_SIZE,
	//ERR_TAIL,
//};

enum
{
	RES_MW,
	RES_KS,
	RES_BOTH,
};


static bool _check_no_input(TreeNode& tr)
{
	if ( !tr.mw.nVal && !tr.ks.nVal )
		return false;
	
	return true;		
}



void NPHTwoSample(const string& hint_indexed, const string& hint_raw, const int& type, const Range& irng, const string& null, const int& tail, const double& alpha, const int& mw, const int& exact, const int& ks, ReportTree& rt)
{
	
	vector vData1, vData2;
	vector<string> vstrLab;
	int nMissing, nRet;
	nRet = (0 == type) ? get_2_data_in_group(irng, vData1, vData2, vstrLab, nMissing) : get_2_data_in_var(irng, vData1, vData2, vstrLab, nMissing); 
	if (nRet != STATS_NO_ERROR)			
		XF_THROW(nRet);
	
	/// *****		Terminate if error setting		***** ///	
	int nSize1 = vData1.GetSize();
	int nSize2 = vData2.GetSize();
		
	/// *****		Begin Two Sample Non-parametric analysis Computation		***** ///
	DescStatResults pDescStats[2];
	QuantileOptions stQuanOpt;
	QuantileResults pQuantiles[2];
	nRet = stats_descriptive(vData1, pDescStats[0]);
	nRet += stats_descriptive(vData2, pDescStats[1]);
	if (nRet != STATS_NO_ERROR)
		XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
	
	InitQuantiles(stQuanOpt);
	nRet = stats_quantiles(vData1, stQuanOpt, pQuantiles[0]);
	nRet += stats_quantiles(vData2, stQuanOpt, pQuantiles[1]);
	if (nRet != STATS_NO_ERROR)
		XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
	
	
	LPCSTR lpsczLabel = _L("Nonparametric Analysis (Two Sample)");
	report_tree_create(rt, lpsczLabel, "irng");
	rt_add_nph_descriptive(rt, pDescStats, pQuantiles, vstrLab);
	
	//Begin Mann-Whitney test
	NPHSummary pMannSummary[2];
	NPHRanks pMannRanks[2];
	NPHStats stMannStats, stKSStats;
	
	string strErr;
	
	
	if (mw)
	{
		//nRet = ocmath_mann_whitney(vData1, nSize1, vData2, nSize2, tail, pMannSummary, pMannRanks, &stMannStats, false);///Echo 3/17/08 QA70-11268 V8.0825 MW_ADD_EXACT_P
		nRet = ocmath_mann_whitney(vData1, nSize1, vData2, nSize2, tail, pMannSummary, pMannRanks, &stMannStats, exact);
		if (nRet != STATS_NO_ERROR)
		{
			XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
		}
		ReportTable rtMannWhitney = rt.CreateTable("MWtest", _L("Mann-Whitney test"), IDST_NPH_MW_TEST);
		//rt_add_mann_whitney(rtMannWhitney, pMannRanks, stMannStats, vstrLab, tail);///Echo 3/17/08 QA70-11268 V8.0825 MW_ADD_EXACT_P
		//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
		//rt_add_mann_whitney(rtMannWhitney, pMannRanks, stMannStats, vstrLab, tail,exact);
		rt_add_mann_whitney(rtMannWhitney, pMannRanks, stMannStats, vstrLab, tail,alpha,exact);
		//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
	}
	
	if (ks)
	{
		//Begin Kolmogorov-Smirnov test
		nRet = ocmath_2_sample_ks_test(vData1, nSize1, vData2, nSize2, tail, &stKSStats);
		if (nRet != STATS_NO_ERROR)
		{
			XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
		}
		vector vFreqs(2);
		vFreqs[0] = nSize1;
		vFreqs[1] = nSize2;
		ReportTable rtKS = rt.CreateTable("KSTest", _L("Kolmogorov-Smirnov test"), IDST_NPH_KSSTATS_TEST);
		//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
		//rt_add_ks_2_sample(rtKS, vFreqs, stKSStats, vstrLab, tail);
		rt_add_ks_2_sample(rtKS, vFreqs, stKSStats, vstrLab, tail,alpha);
		//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
	}
	
	//Compute descriptive statistics
	//nph2_update_report_tree(rt, pMannRanks, stMannStats, stKSStats, vstrLab, type, tail, mw, ks);
	
}

//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 NPHTwoSample_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return NPHTwoSample_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	///Kyle 09/24/08 SET_NO_NEED_TO_LOCALIZE
	if ( GETNE_ON_INIT == nEventID )
	{
		trGetN.tail.SetAttribute(STR_OCNTRL_OPTNS, OCNTRLPARAM1_NOT_LOCALIZED);
	}
	///End SET_NO_NEED_TO_LOCALIZE
	
	switch( trGetN.type.nVal )
	{
	case 0:
		tree_stats_convert_input_data(trGetN.irng, SIDT_INGROUP);
		break;
	
	case 1:
		tree_stats_convert_input_data(trGetN.irng, SIDT_INVAR);
		break;
	}
	
	///Sophy 10/27/2008 v8.961 QA80-12452 SUPPORT_INPUT_DATA_FROM_OPTION_ADD_ALTERNATIVE_COMBOLIST_FOR_NPH_TESTS
	/* code centralized in nph_add_null_event in event_utils.h, will be executed at the end of this function
	trGetN.null.Enable = false;
	//Null hypothetival type of mean changes according to the alternate hypothetical types
	if (trGetN.tail.nVal == 0)	
		trGetN.null.strVal = _L("F(x) = G(x)");
	else if (trGetN.tail.nVal == 1)	
		trGetN.null.strVal = _L("F(x) <= G(x)");
	else if (trGetN.tail.nVal == 2)
		trGetN.null.strVal = _L("F(x) >= G(x)");
	*/
	///end SUPPORT_INPUT_DATA_FROM_OPTION_ADD_ALTERNATIVE_COMBOLIST_FOR_NPH_TESTS
	///Echo 3/17/08 QA70-11268 V8.0825 MW_ADD_EXACT_P
	trGetN.exact.Enable = trGetN.mw.nVal; 
	if (trGetN.mw.nVal == 0)
		trGetN.exact.nVal = 0;
	///end MW_ADD_EXACT_P
	
	int nErr = ( 0 == trGetN.type.nVal ) ? check_2_data_in_group(trGetN.irng, false) : check_2_data_in_var(trGetN.irng, false);
	
	if (!_check_no_input(trGetN) && CER_NO_ERROR == nErr)
	{
		nErr = CER_SUPPRESS_ALL_OUTPUT; 		
	}
	if (CER_NO_ERROR != nErr)
	{
		bOKEnable = false;
		strErrMsg = nErr;
	}
	
	//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
	int nErr2 = hyt_check_input(trGetN);
	if (nErr2 != CER_NO_ERROR)
	{
		bOKEnable = false;
		strErrMsg = nErr2;
	}
	//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
	
	///Sophy 10/27/2008 v8.961 QA80-12452 SUPPORT_INPUT_DATA_FROM_OPTION_ADD_ALTERNATIVE_COMBOLIST_FOR_NPH_TESTS
	//return true;
	return nph_add_null_event(trGetN);
	///end SUPPORT_INPUT_DATA_FROM_OPTION_ADD_ALTERNATIVE_COMBOLIST_FOR_NPH_TESTS
	
	

}

int NPHTwoSample_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 NPHTwoSample_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	
	if(is_use_origin_chm())
		trGetN.SetAttribute(STR_HELPID_ATTRIB, IDD_XF_NPHTwoSamples);
	
	if ( (dwCntrl&LTXF_THEME_USED) && nGetNDialog <= 0 )
	{
		int nErr = ( 0 == trGetN.type.nVal ) ? check_2_data_in_group(trGetN.irng, false) : check_2_data_in_var(trGetN.irng, false);		
		if (!_check_no_input(trGetN) && CER_NO_ERROR == nErr)
		{
			nErr = CER_SUPPRESS_ALL_OUTPUT; 		
		}
		if ( CER_NO_ERROR != nErr )
			nRet = XFEVT_PROCEED_WITH_DLG;
	}
	
}
//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 NPHTwoSample_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
