#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
//put additional include files here
#include <GetNBox.h>
#include <report_utils.h>
#include <event_utils.h>
#include <stats_utils.h>
#include <o8dlg.h>
///////////////////////////////////////////////////
// Modification log
///Jasmine 08/14/07 QA80-10207 REPORT_SHEET_CHECK_CONFLICT
/// Max 9/26/07 CORRECT_ONESAMPLE_VARIANCE_TEST_LABEL_BY_TAIL
/// Max 3/7/08 SHOULD_PASS_WHOLE_STRING_OF_LPCSZRDLABEL_FOR_LOCALIZATION
/// Folger 12/26/08 QA80-12642 v8.0991 CONSISTENT_SHOW_LN_ONLY_IF_EXIST_FOR_STATISTICAL_TOOLS
/// Kyle 06/01/2009 ADD_NEW_LINE_CHARACTER_WITHOUT_REFERENCE_TO_THE_SUB_STRING
/// Kyle 06/05/2009 QA70-13733 RADIX_POINT_SHOULD_BE_COMMA_IN_GOS
/// Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
/// Jacky 08/27/10 ORG-920-P3 ONE_SAMPLE_TTEST_BETTER_HANDLING_OF_OUTPUT_PLOT_AND_REPORT_DATA
///////////////////////////////////////////////////

//put your own support static functions here

static void _get_chisq_stats(tTestResults &stChiSqStats, vector &vChiSqStats)
{
	vChiSqStats.SetSize(3);
	vChiSqStats[0] = stChiSqStats.tValue;
	vChiSqStats[1] = stChiSqStats.DOF;
	vChiSqStats[2] = stChiSqStats.Prob;	
	
}

static void _set_desc_stats_opt(DescStatOptions& stDescOpt)
{
	stDescOpt.N = true;
	stDescOpt.Mean = true;
	stDescOpt.SD = true;
	stDescOpt.Variance = true;	
}

static int _chisq_test_check_input(TreeNode& trGetN, bool bChanged = true)
{
	int nErr;
	if (bChanged)
	{
		nErr = check_1_data(trGetN.irng, true);
		if (nErr)
			return nErr;
	}
	
	nErr = hyt_check_input(trGetN);
	if (nErr)
		return nErr;
	
	return CER_NO_ERROR;
}


void OneSampleTestVar(const Range& irng, const double& var, const string& null, const int& tail, const double& alpha, const int& conf, const string& level, const int& histogram, const int& box, ReportData& rd, 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);
	
	vector<string> vstrLab(nNumRanges);
	vector vLevInGroup, vDataAll;
	vLevInGroup.SetSize(nNumRanges);
	string strFootNote;
	LPCSTR lpsczLabel = _L("One Sample Test for Variance");
	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
		//vstrLab[ii] =  range_get_col_name(irng, ii);
		vstrLab[ii] =  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);
		
		//Deal with missing values first
		int nMissing = ocmath_count(NANUM, vData.GetSize(), vData);
		if (0 < nMissing && nMissing != vData.GetSize())
			vData.Trim();
		
		//if (vData.GetSize() == 0)
			//break;
		
		//int tail = trtTest.TailType.nVal;
		
		/// *** Descriptive Statistics
		DescStatOptions stStatsOpt;
		_set_desc_stats_opt(stStatsOpt);
		DescStatResults stStatsRes;
		
		nRet = stats_desc_stats(vData, stStatsOpt, stStatsRes);
		if (nRet != STATS_NO_ERROR)
		{
			XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
		}
			
		DescStatOptions stDescOpt;	
		rt_add_desc_stats(rt, &stStatsOpt, NULL, &stStatsRes, NULL, vstrLab[ii]);
			
		/// *****		One sample chi-sq test		***** ///
		HypotTestOptions opt;
		tTestResults stChiSqRes;
		opt.HypotValue = var;
		opt.TailType=tail;
		int nSize = vData.GetSize();
		nRet = ocmath_chi_square_test(nSize, vData, &opt, &stChiSqRes );
		if (nRet != STATS_NO_ERROR)
		{
			XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
		}
		
		vector vChiSqStats;
		_get_chisq_stats(stChiSqRes, vChiSqStats);
		
		vector<string> vChiSqStatsLabels;
		vChiSqStatsLabels.SetSize(3);
	    vChiSqStatsLabels[0] = _L("Chi-Square");
		vChiSqStatsLabels[1] = _L("DF");
		/// Max 9/26/07 CORRECT_ONESAMPLE_VARIANCE_TEST_LABEL_BY_TAIL
		//vChiSqStatsLabels[2] =  _L("Prob>Chi-Square");
		switch (tail)
		{
			case TAILED_TEST_TWO:
			case TAILED_TEST_UPPER:	
			default:
				vChiSqStatsLabels[2] =  _L("Prob>Chi-Square");
				break;
			case TAILED_TEST_LOWER:
				vChiSqStatsLabels[2] =  _L("Prob<Chi-Square");
				break;
		}
		/// END CORRECT_ONESAMPLE_VARIANCE_TEST_LABEL_BY_TAIL
	
		
		string strHYPT, strConclusion;
		int nHYPT, nConclusion, nConAccept, nConReject;
		switch (tail)
		{
			case TAILED_TEST_TWO:
			default:
				nHYPT = FOOTNOTE_VARTEST1_TWO_TAIL;
				nConAccept = FOOTNOTE_VARTEST1_CON_DIFF;
				nConReject = FOOTNOTE_VARTEST1_CON_SAME;
				break;
			case TAILED_TEST_UPPER:
				nHYPT = FOOTNOTE_VARTEST1_UPPER_TAIL;
				nConAccept = FOOTNOTE_VARTEST1_CON_GRT;
				nConReject = FOOTNOTE_VARTEST1_CON_NOT_GRT;
				break;
			case TAILED_TEST_LOWER:
				nHYPT = FOOTNOTE_VARTEST1_LOWER_TAIL;
				nConAccept = FOOTNOTE_VARTEST1_CON_LES;
				nConReject = FOOTNOTE_VARTEST1_CON_NOT_LES;
				break;
		}
		string strVar = ftoa(var);			///Kyle 06/05/2009 QA70-13733 RADIX_POINT_SHOULD_BE_COMMA_IN_GOS
		
		ocu_load_err_msg_str(nHYPT, &strHYPT);
		///Kyle 06/05/2009 QA70-13733 RADIX_POINT_SHOULD_BE_COMMA_IN_GOS
		//strHYPT.Format(strHYPT, var, var);
		strHYPT.Format(strHYPT, strVar, strVar);
		///End RADIX_POINT_SHOULD_BE_COMMA_IN_GOS
		//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
		//nConclusion = (stChiSqRes.Prob<0.05) ? nConAccept : nConReject;
		nConclusion = (stChiSqRes.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, vstrLab[ii], var);
		//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
		//strConclusion.Format(strConclusion, vstrLab[ii], strVar);
		strConclusion.Format(strConclusion, vstrLab[ii],alpha,strVar);
		//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
		///End RADIX_POINT_SHOULD_BE_COMMA_IN_GOS
		///Kyle 06/01/2009 ADD_NEW_LINE_CHARACTER_WITHOUT_REFERENCE_TO_THE_SUB_STRING
		//strFootNote += strConclusion;
		strConclusion.TrimRight("\r\n");
		if(!strFootNote.IsEmpty())
			strFootNote += "\r\n";
		strFootNote += strConclusion;
		///End ADD_NEW_LINE_CHARACTER_WITHOUT_REFERENCE_TO_THE_SUB_STRING
		
		rt_add_test_stats(rt, tail, vChiSqStats, strHYPT, strFootNote, vstrLab[ii], &vChiSqStatsLabels);
		
		if (conf)
		{
			vector vLevels, vPercents;
			int nLevels = level.GetTokens(vPercents);//put the confidence levels in vector
			vLevels = vPercents / 100.0;
			
			vector vLCLs, vUCLs;
			vLCLs.SetSize(nLevels);
			vUCLs.SetSize(nLevels);
	
			nRet = ocmath_confidence_levels_for_variance(vLevels.GetSize(), vLevels, stStatsRes.SD, stChiSqRes.DOF, vLCLs, vUCLs);	if (nRet != STATS_NO_ERROR)
			if (nRet != STATS_NO_ERROR)
			{
				XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
			}
				
			rt_add_conf_intvl(rt, vPercents, vLCLs, vUCLs, _L("Variance"), vstrLab[ii]);
		}
		
		vLevInGroup[ii] = vData.GetSize();
		vDataAll.Append(vData);
	
	}
	
	if (rd)
	{
		
		ttest_update_report_data(rd, vDataAll,vLevInGroup,vstrLab);
		
		int nPlotType; 
		if (histogram) nPlotType += HYPO_TEST_HISTOGRAM;
		if (box) nPlotType += HYPO_TEST_BOX;
		
		hypo_test_rd_plotting(rd, vstrLab, nPlotType, rt);
	}
	
}

//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 OneSampleTestVar_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return OneSampleTestVar_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	/// Max 3/7/08 SHOULD_PASS_WHOLE_STRING_OF_LPCSZRDLABEL_FOR_LOCALIZATION
	//rd_set_optional(nEventID, bOKEnable, lpcszNodeName, trGetN.rd, trGetN.box.nVal||trGetN.histogram.nVal, "PlotData1");
	
	/// Max 4/8/08 move to event_utils.h
	//string strRDvalue = "[<input>]<new>";
	//--- Jacky 08/27/10 ORG-920-P3 ONE_SAMPLE_TTEST_BETTER_HANDLING_OF_OUTPUT_PLOT_AND_REPORT_DATA
	//string strRDvalue = STR_DEFAULT_TEXT_FOR_REPORT_DATA_NODE;
	//--- end ONE_SAMPLE_TTEST_BETTER_HANDLING_OF_OUTPUT_PLOT_AND_REPORT_DATA
	//------
	//--- Jacky 08/27/10 ORG-920-P3 ONE_SAMPLE_TTEST_BETTER_HANDLING_OF_OUTPUT_PLOT_AND_REPORT_DATA
	//okutil_convert_localized_PDS(&strRDvalue);
	//tr_set_optional(nEventID, lpcszNodeName, trGetN.rd, trGetN.box.nVal||trGetN.histogram.nVal, strRDvalue);
	tr_set_optional_ex(nEventID, lpcszNodeName, trGetN.rd, xf_event_is_change_param(trGetN), trGetN.box.nVal || trGetN.histogram.nVal);
	//--- end ONE_SAMPLE_TTEST_BETTER_HANDLING_OF_OUTPUT_PLOT_AND_REPORT_DATA
	/// END SHOULD_PASS_WHOLE_STRING_OF_LPCSZRDLABEL_FOR_LOCALIZATION
	
	hyt_set_gui(trGetN, _L("Variance"));
	
	//bool bChanged = (!lstrcmp(lpcszNodeName, "irng") || nEventID == GETNE_ON_INIT);
	
	//int nErrCode = _chisq_test_check_input(trGetN, bChanged);
	int nErrCode = _chisq_test_check_input(trGetN);
	///Jasmine 08/14/07 QA80-10207 REPORT_SHEET_CHECK_CONFLICT
	if (nErrCode == CER_NO_ERROR && is_same_sheet(trGetN.rd, trGetN.rt))
		nErrCode = XFERR_REPORT_SHEET_CONFLICT;
	///End REPORT_SHEET_CHECK_CONFLICT
	if (nErrCode != CER_NO_ERROR)
	{
		bOKEnable = false;
		strErrMsg = nErrCode;
		if (nErrCode == CER_COL_NUM_TOO_FEW_EX)
			strErrMsg += ":" + 1;
	}
	
	return true;
	//return ttest_event(trGetN, bOKEnable, strErrMsg, _L("Variance"));	
		

}

int OneSampleTestVar_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 OneSampleTestVar_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_OneSampleTestVar);
	
	///Jasmine 08/14/07 QA80-10207 REPORT_SHEET_CHECK_CONFLICT
	//if ((dwCntrl&LTXF_THEME_USED) && nGetNDialog <= 0)
	if (nGetNDialog <= 0)
	{
		int nErr;
		bool bOKEnable; 
		string strErrMsg;
		ttest_event(trGetN, bOKEnable, strErrMsg, _L("Variance"));
		//if (CER_NO_ERROR != _chisq_test_check_input(trGetN) ||  strErrMsg != "")
		if(strErrMsg.IsEmpty() && CER_NO_ERROR == nErr)
		{
			nErr = _chisq_test_check_input(trGetN);
			if(CER_NO_ERROR == nErr && is_same_sheet(trGetN.rd, trGetN.rt))
				nErr = XFERR_REPORT_SHEET_CONFLICT;
		}
		if(!strErrMsg.IsEmpty() || CER_NO_ERROR != nErr)
		{
			if((dwCntrl&LTXF_THEME_USED))
				nRet = XFEVT_PROCEED_WITH_DLG;		
			else
			{
				if(strErrMsg.IsEmpty())
					warning_msg_box(nErr, false, 'E');
				else
					warning_msg_box(strErrMsg, false, 'E');
				nRet = XFEVT_ABORT;
			}
		}
	}
	///End REPORT_SHEET_CHECK_CONFLICT
}
//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 OneSampleTestVar_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
