#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>

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

//put your own support static functions here

/*------------------------------------------------------------------------------*
 * Modification Log:															*
 *	Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL						*
 *------------------------------------------------------------------------------*/
 
#define IDST_NPH_KWANOVA_TEST  0x00000001
#define IDST_NPH_MESTATS_TEST  0x00000010

static bool _check_no_input(TreeNode& tr)
{
	if ( !tr.kw.nVal && !tr.mt.nVal )
		return false;
	
	return true;		
}
//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
//static string _get_conclusion(const double dProb)
static string _get_conclusion(const double dProb,double dAlpha)
//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
{
	string strConclusion;
	int nConclusion;
	if (dProb == NANUM)
		nConclusion = FOOTNOTE_NO_CONCLUSION;
	else
	{
		//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
		//if (dProb >= 0.05)
		if (dProb >= dAlpha)
		//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
			nConclusion = FOOTNOTE_NPHK_CON_SAME;
		else
			nConclusion = FOOTNOTE_NPHK_CON_DIFF;
	}
	
	ocu_load_err_msg_str(nConclusion, &strConclusion);
	
	return strConclusion;
}

void NPHKSamples(const Range& irng, const int& kw, const int& mt, const double& alpha, ReportTree& rt)
{
		
	vector vData, vIndex;
	vector<string> vstrLab;
		
	int nRet = get_data_in_group(irng, vData, vIndex, vstrLab);
	if (CER_NO_ERROR != nRet)
	{
		XF_THROW(nRet);
	}
		
	vector<string> vstrColLabels;
	get_multi_data_col_label(irng, "X", vstrColLabels);
	
	int nDataCols = vstrColLabels.GetSize();
	double dBegin = 0.0, dEnd = 0.0;
	int iLevels = (int)vIndex.GetSize()/nDataCols;
	
	LPCSTR lpsczLabel = _L("Nonparametric Analysis (K Sample)");
	report_tree_create(rt, lpsczLabel, "irng");
	
	string strKWFootNote, strMDFootNote;
	for (int jj = 0; jj < nDataCols; jj++)
	{
		vector vSubData, vSubIndex;
		vector<string> vstrSubLab;
		vIndex.GetSubVector(vSubIndex, jj*iLevels, (jj+1)*iLevels-1);
		get_sub_string_vector(vstrLab, vstrSubLab, jj*iLevels, (jj+1)*iLevels-1);
		
		
		vSubIndex.Sum(dEnd);
		dEnd = dBegin + dEnd;
		vData.GetSubVector(vSubData, (int)dBegin, (int)dEnd-1);
		
		vector vGroup, vSubGroup;
		for (int ii = jj*iLevels; ii < (jj+1)*iLevels; ii++ )
		{
			vSubGroup.SetSize(vIndex[ii]);
			vSubGroup = ii;
			vGroup.Append(vSubGroup);		
		}
		
		dBegin = dEnd;
		
		DescStatResults pDescStats[NPHK_MAX_GROUP];
		QuantileResults pQuantiles[NPHK_MAX_GROUP];
		desc_stats_group(vSubData, vGroup, pDescStats, pQuantiles);
			
		NPHSummary KWSummary[NPHK_MAX_GROUP];
		NPHRanks KWRanks[NPHK_MAX_GROUP];
		NPHStats KWStats;
		nRet = ocmath_kruskal_wallis_anova(vSubData, vSubData.GetSize(), iLevels, (vector)vSubIndex, KWSummary, KWRanks, &KWStats);
		if (nRet != STATS_NO_ERROR)
		{
			XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
		}
			
		NPHFreqs MdFreqs[NPHK_MAX_GROUP];
		NPHStats MdStats;
		nRet = ocmath_median_test(vSubData, vSubData.GetSize(), iLevels, (vector)vSubIndex, MdFreqs, &MdStats);
		if (nRet != STATS_NO_ERROR)
		{
			XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
		}
		
		
		rt_add_nph_descriptive(rt, pDescStats, pQuantiles, vstrSubLab, vstrColLabels[jj]);
		
		string strHYPT;
		ocu_load_err_msg_str(FOOTNOTE_NPH_K_SAMPLE, &strHYPT);				
		
		vector<string> vstrStatsLabel;
		string strStatsLabel = NPH_K_SAMP_STATS;
		strStatsLabel.GetTokens(vstrStatsLabel, '|');
		
		vector vNPHStats;
		
		if(kw)
		{
			ReportTable rtKWAtest = rt.CreateTable("Kruskal", _L("Kruskal-Wallis ANOVA test"), IDST_NPH_KWANOVA_TEST);
			rt_add_nph_ranks(rtKWAtest, KWRanks, vstrSubLab, vstrColLabels[jj]);
			get_nph_stats(KWStats, vNPHStats);
			string strConclusion;
			//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
			//strConclusion.Format(_get_conclusion(KWStats.Prob), vstrColLabels[jj]);
			strConclusion.Format(_get_conclusion(KWStats.Prob,alpha), vstrColLabels[jj],alpha);
			//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
			strKWFootNote += strConclusion;
			rt_add_test_stats(rtKWAtest, 0, vNPHStats, strHYPT, strKWFootNote, vstrColLabels[jj], &vstrStatsLabel);
		}
		if(mt)
		{
			ReportTable rtMDtest = rt.CreateTable("Median", _L("Median test"), IDST_NPH_MESTATS_TEST);
			rt_add_nph_freq(rtMDtest,MdFreqs,vstrSubLab, vstrColLabels[jj]);
			vstrStatsLabel.InsertAt(0, _L("Median"));
			get_nph_stats(MdStats, vNPHStats);
			vNPHStats.InsertAt(0, y50(vSubData));
			string strConclusion;
			//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
			//strConclusion.Format(_get_conclusion(MdStats.Prob), vstrColLabels[jj]);
			strConclusion.Format(_get_conclusion(MdStats.Prob,alpha), vstrColLabels[jj],alpha);
			//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
			strMDFootNote += strConclusion;
			rt_add_test_stats(rtMDtest, 0, vNPHStats, strHYPT, strMDFootNote, vstrColLabels[jj], &vstrStatsLabel);
		}
			
	}
	
	rt.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);
	
	
		
	
	
}

//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 NPHKSamples_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return NPHKSamples_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	
	tree_stats_convert_input_data(trGetN.irng, SIDT_INGROUP);
	
	int nErr = check_data_in_group(trGetN.irng);
	
	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;
	}
	return true;	
	//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
	

}

int NPHKSamples_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 NPHKSamples_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	
	if(is_use_origin_chm())
		trGetN.SetAttribute(STR_HELPID_ATTRIB, IDD_XF_NPHKSamples);
	
	if ( (dwCntrl&LTXF_THEME_USED) && nGetNDialog <= 0 )
	{
		int nErr = check_data_in_group(trGetN.irng);
		
		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 NPHKSamples_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
