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


#include <stats_utils.h>
#include <ReportTree.h>
#include <report_utils.h>
#include <GetNBox.h>
#include <event_utils.h>
#include <o8dlg.h>
//put additional include files here

//put your own support static functions here

/*------------------------------------------------------------------------------*
 * Modification Log:															*
 *	Folger 12/26/08 QA80-12642 v8.0991 CONSISTENT_SHOW_LN_ONLY_IF_EXIST_FOR_STATISTICAL_TOOLS
 *	Kyle 06/05/2009 QA70-13733 RADIX_POINT_SHOULD_BE_COMMA_IN_GOS				*
 *	Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL						*
 *------------------------------------------------------------------------------*/

static void _signrank1_get_stats(NPHStats &stStats, vector &vNPHStats)
{
	vNPHStats.SetSize(3);
	vNPHStats[0] = stStats.Stat;
	vNPHStats[1] = stStats.Z;
	vNPHStats[2] = stStats.Prob;	
}

static void _signrank1_set_label(vector<string>& vstrStats, const int nTail)
{
	vstrStats.SetSize(3);
	vstrStats[0] = _L("W");
	vstrStats[1] = _L("Z");
	switch (nTail)
	{
	case 0:
	default:
		vstrStats[2] = _L("Prob>|W|");
		break;
	case 1:
		vstrStats[2] = _L("Prob<W");
		break;
	case 2:
		vstrStats[2] = _L("Prob>W");
		break;
		
	}		
}


void signrank1(const Range& irng, const double& median, const string& null, const int& tail, const double& alpha, ReportTree& rt)
{
	
	waitCursor junk;
	
	vector vData;
	DWORD dwRules = DRR_NO_WEIGHTS;
	DWORD dwPlotID;
	
	int nRet = check_1_data(irng, true);
	if (CER_NO_ERROR != nRet)
	{
		if (nRet == CER_COL_NUM_TOO_FEW_EX)
			XF_THROW_EX(nRet, 1)
		else
			XF_THROW(nRet);
	}
	
	int nNumRanges = irng.GetNumData(dwRules);
	
	string strMedian = ftoa(median);		///Kyle 06/05/2009 QA70-13733 RADIX_POINT_SHOULD_BE_COMMA_IN_GOS
	
	string strFootNote;
	
	LPCSTR lpsczLabel = _L("One Sample Wilcolxon Signed Rank Test");
	report_tree_create(rt, lpsczLabel, "irng");
	for (int ii = 0; ii < nNumRanges; ii++)
	{
		///------ Folger 12/26/08 QA80-12642 v8.0991 CONSISTENT_SHOW_LN_ONLY_IF_EXIST_FOR_STATISTICAL_TOOLS
		//string strColLabel =  range_get_col_name(irng, ii);
		string strColLabel =  range_get_col_name(irng, ii, TRUE);
		///------ End CONSISTENT_SHOW_LN_ONLY_IF_EXIST_FOR_STATISTICAL_TOOLS
		irng.GetData(dwRules, ii, &dwPlotID, NULL, &vData, NULL, NULL, NULL);
		
		/// Trim out missing values before calculation
		int nMissing = ocmath_count(NANUM, vData.GetSize(), vData);
		if (0 < nMissing)
			vData.Trim();
		
		///Echo 5/27/08 v8.0870 CORR_ENABLE_EMPTY_COL
		//if (vData.GetSize() == 0)
			//break;
		
		/// *****		Begin 1 Sample Wilcoxon Computation		***** ///
		DescStatOptions stDescOpt;
		QuantileOptions stQuanOpt;
		set_nph_desc_stats_opt(stDescOpt, stQuanOpt);
		DescStatResults stDescStats;
		QuantileResults stQuantiles;
		stDescStats.N = vData.GetSize();
		nRet = stats_quantiles(vData, stQuanOpt, stQuantiles);
		if (nRet != STATS_NO_ERROR)
		{
			XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
		}
		
		vector<string> vstrLab(1);
		///------ Folger 12/26/08 QA80-12642 v8.0991 CONSISTENT_SHOW_LN_ONLY_IF_EXIST_FOR_STATISTICAL_TOOLS
		//vstrLab[0] = range_get_col_name(irng);
		vstrLab[0] = range_get_col_name(irng, 0, TRUE);
		///------ End CONSISTENT_SHOW_LN_ONLY_IF_EXIST_FOR_STATISTICAL_TOOLS
		rt_add_desc_stats(rt, &stDescOpt, &stQuanOpt, &stDescStats, &stQuantiles, strColLabel);
		NPHSummary stWilco1Summary;
		NPHStats stWilco1Stats;
		
		nRet = ocmath_one_sample_wilcoxon(vData, vData.GetSize(), median, tail, &stWilco1Summary, &stWilco1Stats);
		if (nRet != STATS_NO_ERROR)
		{
			XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
		}
		
		string strHYPT, strConclusion;
		int nHYPT, nConclusion, nConAccept, nConReject;
		switch (tail)
		{
			case TAILED_TEST_TWO:
			default:
				nHYPT = FOOTNOTE_NPH1_TWO_TAIL;
				nConAccept = FOOTNOTE_NPH1_CON_DIFF; 
				nConReject = FOOTNOTE_NPH1_CON_SAME;
				break;
			case TAILED_TEST_UPPER:
				nHYPT = FOOTNOTE_NPH1_UPPER_TAIL;
				nConAccept = FOOTNOTE_NPH1_CON_GRT; 
				nConReject = FOOTNOTE_NPH1_CON_NOT_GRT;
				break;
			case TAILED_TEST_LOWER:
				nHYPT = FOOTNOTE_NPH1_LOWER_TAIL;
				nConAccept = FOOTNOTE_NPH1_CON_LES; 
				nConReject = FOOTNOTE_NPH1_CON_NOT_LES;
				break;
		}
		ocu_load_err_msg_str(nHYPT, &strHYPT);
		///Kyle 06/05/2009 QA70-13733 RADIX_POINT_SHOULD_BE_COMMA_IN_GOS
		//strHYPT.Format(strHYPT, median, median);
		strHYPT.Format(strHYPT, strMedian, strMedian);
		///End RADIX_POINT_SHOULD_BE_COMMA_IN_GOS
		//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
		//nConclusion = (stWilco1Stats.Prob< 0.05) ? nConAccept : nConReject;
		nConclusion = (stWilco1Stats.Prob< alpha) ? nConAccept : nConReject;
		//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
		ocu_load_err_msg_str(nConclusion, &strConclusion);
		///Kyle 06/05/2009 QA70-13733 RADIX_POINT_SHOULD_BE_COMMA_IN_GOS
		//strConclusion.Format(strConclusion, strColLabel, median);
		//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
		//strConclusion.Format(strConclusion, strColLabel, strMedian);
		strConclusion.Format(strConclusion, strColLabel, alpha,strMedian);
		//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
		///End RADIX_POINT_SHOULD_BE_COMMA_IN_GOS
		strFootNote += strConclusion;
				
		vector vNPHStats;
		_signrank1_get_stats(stWilco1Stats, vNPHStats);
		
		vector<string> vstrStatsLabel;
		_signrank1_set_label(vstrStatsLabel, tail);
		rt_add_test_stats(rt, tail, vNPHStats, strHYPT, strFootNote, strColLabel, &vstrStatsLabel);
	}
	
}

//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 signrank1_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return signrank1_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	
	double dMedian = trGetN.median.dVal;
	string strHypoValue = ftoa(dMedian);
	string strAltHypType;
	//strAltHypType.Format("Median <> %g|Median > %g|Median < %g"), dMedian, dMedian,dMedian);
	///Kyle 06/05/2009 QA70-13733 RADIX_POINT_SHOULD_BE_COMMA_IN_GOS
	//strAltHypType.Format("%s <> %g|%s > %g|%s < %g", _L("Median"), dMedian, _L("Median"), dMedian, _L("Median"), dMedian);
	strAltHypType.Format("%s <> %s|%s > %s|%s < %s", _L("Median"), strHypoValue, _L("Median"), strHypoValue, _L("Median"), strHypoValue);
	///End RADIX_POINT_SHOULD_BE_COMMA_IN_GOS
	trGetN.tail.SetAttribute(STR_COMBO_ATTRIB, strAltHypType);
	trGetN.null.Enable = false;
	
	//Null hypothetival type of Median changes according to the alternate hypothetical types
	if (trGetN.tail.nVal == 0)	
		//trGetN.null.strVal = "Median = " + strHypoValue;
		trGetN.null.strVal = _L("Median") + " = " + strHypoValue;
	else if (trGetN.tail.nVal == 1)	
		//trGetN.null.strVal = "Median <= " + strHypoValue;
		trGetN.null.strVal = _L("Median") + " <= " + strHypoValue;
	else if (trGetN.tail.nVal == 2)
		//trGetN.null.strVal = "Median >= " + strHypoValue;
		trGetN.null.strVal = _L("Median") + " >= " + strHypoValue;
	
	int nErrCode = check_1_data(trGetN.irng, true);
	if (nErrCode != CER_NO_ERROR)
	{
		bOKEnable = false;
		strErrMsg = nErrCode;
		if (nErrCode == CER_COL_NUM_TOO_FEW_EX)
			strErrMsg += ":" + 1;
	}
	//--- 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;
	}
	return true;
	//bool bRet = ttest_event(trGetN, bOKEnable, strErrMsg, _L("Median"));
	//return bRet;
	//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL

}

int signrank1_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 signrank1_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_signrank1);	
	
	if ( (dwCntrl&LTXF_THEME_USED) && nGetNDialog <= 0 )
	{
		if ( CER_NO_ERROR != check_1_data(trGetN.irng, true) )
			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 signrank1_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
