/*------------------------------------------------------------------------------*
 * File Name:Normality.cpp	 													*
 * Creation: 																	*
 * Purpose: OriginC Source C file to implementing Normality Test operation		*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 * Echo 8/24/05 ERROR_ALGORITHM_USED											*
 * Jim 11/17/05 P_VALUE_NAME_CONVENTION                                         * 
 * Jim 01/17/06 CREATE_PLOTS_BRANCH_IN_MAIN_NODES								*
 * Max 04/25/06 QA70-7031-P6&P7 REMOVE_GET_MISSING_DATA_OPTION					*
 * Alex 06/14/06 SET_NORMALITYTEST_BRANCH_ALL_OPEN                              *
 * Jasmine 09/07/06 ADD_FOOTNOTE												*
 * Jasmine 09/15/06 SETTING_CHANGE_AND_ADD_FOOTNOTE								*
 *	CPY 10/14/06 SEPARATE_OUT_OPERATION_BASE_INTO_SEPARATE_HEADER				*
 *	Echo 2/12/07 ADD_ERROR_REPORT												*
 *  Iris 04/12/2007 FIX_BOX_CHART_IS_EMPTY_IF_CHECKED_PLOT_ALL_PLOTS_IN_ONE_GRAPH
 *	Cheney 2007-6-7 SHOULD_CHECK_EVENT_ID_IN_EVENT_FUNC							*
 *	Max 6/8/07 CORRECT_RULE_FOR_CONCLUSION_IN_FOOTNOTE							*
 *	Echo 8/7/07 QA-7031-P4 V8.0676 VAR_NOT_LS_0									*
 *	Arvin 11/10/07 XOP_NEED_SUPPORT_CHANGE_FUNCTION								*
 *	Folger 12/10/07 CLEAN_NEGATIVE_ERROR_MESSAGES								*
 *	Sophy 12/17/2008 v8.0987d  QA80-12784 ADD_BINNING_CONTROL_FOR_HISTOGRAM_PLOT_IN_STATS_TOOLS
 *  Iris 4/09/2009 QA80-12784-P2 IMPROVE_HISTOGRAM_CONFIG_BRANCH				*
 *  Iris 5/18/2009 FIX_SHOW_NO_DATA_ERR_WHEN_CHOOSE_TWO_INCONTINUITY_COL		*
 *  Iris 8/05/2009 QA80-14808 HUGE_FOOTNOTE_IN_REPORT_SHEET_CAUSE_ORIGIN_NOT_ENERGETIC
 *  Iris 10/28/2009 QA81-14546 CHANGE_GUI_REPORT_TABLE_LABEL					*
 *  Iris 1/19/2010 QA81-14988-P2 FIX_EMPTY_NORMALITY_TABLE_WHEN_UNCHECK_ALL		*
 *  Iris 6/17/2010 ORG-289-P2 FIX_NORMALITY_TEST_GRAPH_ARRANGMENT_AUTO_CHECKBOX_NOT_WORK
 *	Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL						*
 *------------------------------------------------------------------------------*/
 
////////////////////////////////////////////////////////////////////////////////////
// Including the system header file Origin.h should be sufficient for most Origin
// applications and is recommended. Origin.h includes many of the most common system
// header files and is automatically pre-compiled when Origin runs the first time.
// Programs including Origin.h subsequently compile much more quickly as long as
// the size and number of other included header files is minimized. All NAG header
// files are now included in Origin.h and no longer need be separately included.
//
// Right-click on the line below and select 'Open "Origin.h"' to open the Origin.h
// system header file.
#include <Origin.h>
////////////////////////////////////////////////////////////////////////////////////

#include <event_utils.h>
#include <report_utils.h>
#include <o8dlg.h>

////////////////////////////////////////////////////////////////////////////////////
// Include your own header files here.
#ifdef _FOR_SMART_LOADING_ONLY
#include "wksOperation.h" //---- CPY 10/14/06 SEPARATE_OUT_OPERATION_BASE_INTO_SEPARATE_HEADER
#include <analysis_utils.h>
#include <stats_utils.h>
#include "stats_guis.h"
#include "stats_operations.h"
#include "nlsf_utils.h" /// Iris 7/08/2008 CLEAN_DUP_CALC_AVE_DATA_CODE_IN_NLSF_PREVIEW_AND_OP
#include "graph_utils.h" //---- Iris 11/19/2008 v8.0975 QA80-12591-P2 FIX_APPARENT_FIT_ON_GRAPH_CUSTOM_RANGE_GET_INCORRECT_X
#endif

#include <xfutils.h>
#include "StatsOpCommon.h"
#include "StatsOpBase.h"

#define FOOTNOTE_STOP_ATTRIB	"FootNoteStop" /// Iris 8/05/2009 QA80-14808 HUGE_FOOTNOTE_IN_REPORT_SHEET_CAUSE_ORIGIN_NOT_ENERGETIC
////////////////////////////////////////////////////////////////////////////////////
// Start your functions here.

///Echo 2/12/07 ADD_ERROR_REPORT
static int normalitytest_event1(TreeNode& tr, int nRow, int nEvent, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& getNCountainer, string& strAux, string& strErrMsg)
{
	DECLARE_BUTTON_ENABLES   //support more buttons enable/disable
		
	/// Iris 4/09/2009 QA80-12784-P2 IMPROVE_HISTOGRAM_CONFIG_BRANCH
	/*
	///Sophy 12/19/2008 v8.0987d  QA80-12784 ADD_BINNING_CONTROL_FOR_HISTOGRAM_PLOT_IN_STATS_TOOLS fix bin config not updated when change input data
	string strNodeName(lpcszNodeName);
	if ( strNodeName.CompareNoCase("X") == 0 )
	{
		TreeNode trHistogramConfig = tr.Output.GetNode(STR_HISTOGRAM_CONFIG_TAGNAME);
		_update_histogram_plot_bin_configuration_by_input(tr, trHistogramConfig);
	}
	///end ADD_BINNING_CONTROL_FOR_HISTOGRAM_PLOT_IN_STATS_TOOLS
	*/
	_update_histogram_bin_info_in_event1(tr, lpcszNodeName, nEvent);
	///end IMPROVE_HISTOGRAM_CONFIG_BRANCH	
	
	///Cheney 2007-6-7 SHOULD_CHECK_EVENT_ID_IN_EVENT_FUNC	
	///Cheney 2007-7-6 SHOULD_CHECK_ERR_WHEN_THEME_CHANGE_ALSO
	//if(GETNE_ON_VALUE_CHANGE == nEvent  || GETNE_ON_INIT == nEvent)
	if(GETNE_ON_VALUE_CHANGE == nEvent  || GETNE_ON_INIT == nEvent || GETNE_ON_THEME == nEvent)
	///end SHOULD_CHECK_ERR_WHEN_THEME_CHANGE_ALSO
	///end SHOULD_CHECK_EVENT_ID_IN_EVENT_FUNC
	{
		int nErr = check_1_data(tr.InputData.Range1.X, true);
		
		int nNumData = 0; /// Iris 6/17/2010 ORG-289-P2 FIX_NORMALITY_TEST_GRAPH_ARRANGMENT_AUTO_CHECKBOX_NOT_WORK
		
		/// Iris 5/18/2009 FIX_SHOW_NO_DATA_ERR_WHEN_CHOOSE_TWO_INCONTINUITY_COL
		// check_1_data cannot correctly check with unknown reason, so add this check.
		DataRange rData;
		rData.Create();
		rData.SetTree(tr.InputData.Range1, DRTREE_ONE_DATA);
		if( rData )
		{
			int nDataRules;
			if( tr.InputData.GetAttribute(STR_DATA_RULES_ATTRIB, nDataRules) )
			{
				/// Iris 6/17/2010 ORG-289-P2 FIX_NORMALITY_TEST_GRAPH_ARRANGMENT_AUTO_CHECKBOX_NOT_WORK
				//nErr = rData.GetNumData(nDataRules) > 0 ? CER_NO_ERROR : CER_COL_NUM_TOO_FEW_EX;
				nNumData = rData.GetNumData(nDataRules);
				nErr = nNumData > 0 ? CER_NO_ERROR : CER_COL_NUM_TOO_FEW_EX;
				///End FIX_NORMALITY_TEST_GRAPH_ARRANGMENT_AUTO_CHECKBOX_NOT_WORK
			}
		}
		///end FIX_SHOW_NO_DATA_ERR_WHEN_CHOOSE_TWO_INCONTINUITY_COL
		
		/// Iris 6/17/2010 ORG-289-P2 FIX_NORMALITY_TEST_GRAPH_ARRANGMENT_AUTO_CHECKBOX_NOT_WORK
		TreeNode trGraphNumCols = OP_GUI_GRAPH_ARRANGEMENT_NODE(tr).GraphNumCols;
		if( trGraphNumCols )
		{
			if( 1 == octree_get_auto_support( &trGraphNumCols ) )
			{
				TreeNode trPlotInOne = OP_GUI_GRAPH_ARRANGEMENT_NODE(tr).PlotInOneGraph;
				bool bPlotInOne = trPlotInOne && trPlotInOne.Show && trPlotInOne.nVal;
				trGraphNumCols.nVal = get_report_graph_num_cols( nNumData, 0, bPlotInOne );
			}
		}
		///End FIX_NORMALITY_TEST_GRAPH_ARRANGMENT_AUTO_CHECKBOX_NOT_WORK
		
		/// Iris 1/19/2010 QA81-14988-P2 FIX_EMPTY_NORMALITY_TABLE_WHEN_UNCHECK_ALL
		if( tree_is_true(tr.OptionBranch.GetNode("shap-wilk")) + 
			tree_is_true(tr.OptionBranch.kolm) + 
			tree_is_true(tr.OptionBranch.lilliefors) == 0 )		
		nErr = NORMALITY_TEST_NO_OUTPUT;
		///End FIX_EMPTY_NORMALITY_TABLE_WHEN_UNCHECK_ALL
		
		///Echo 8/7/07 QA-7031-P4 V8.0676 VAR_NOT_LS_0
		TreeNode trKolm = tr.OptionBranch.kolm;
		if (nErr == CER_NO_ERROR && trKolm.Paras.nVal == 1 && trKolm.Variance.dVal <= 0)
		{
			nErr = CER_VAR_LS_0;
		}
		///END VAR_NOT_LS_0
		///Sophy 4/11/2008 CHECK_REPORT_DATA_BOOK_NAME_DIFFERENT
		string strRet = "";
		if( CER_NO_ERROR == nErr )
		{
			nErr = check_report_book_curve_book( tr, strRet );
		}
		///end CHECK_REPORT_DATA_BOOK_NAME_DIFFERENT
		
		//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
		if(!check_sig_level(tr.OptionBranch.alpha.dVal))
		{
			nErr = CER_INVALID_SIG_LEV;
		}
		//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
		
		///Sophy 12/17/2008 v8.0987d  QA80-12784 ADD_BINNING_CONTROL_FOR_HISTOGRAM_PLOT_IN_STATS_TOOLS
		if ( CER_NO_ERROR == nErr )
		{
			//if ( !check_histogram_config_bin_min_max(tr) )
				//nErr = CER_MIN_MAX;
			nErr = _check_histogram_plot_bin_configuration(tr, strRet);
		}
		///end ADD_BINNING_CONTROL_FOR_HISTOGRAM_PLOT_IN_STATS_TOOLS
		
		if (nErr != CER_NO_ERROR)
		{
			bOKEnable = false;
			strErrMsg = nErr;
			if (nErr == CER_COL_NUM_TOO_FEW_EX)
				strErrMsg += ":" + 1;
			///Sophy 4/14/2008 ADD_OUTPUT_ERR_STRING
			else if( !strRet.IsEmpty() )
			{
				strErrMsg = nErr;
				strErrMsg += ":" + strRet;  
			}
			///end ADD_OUTPUT_ERR_STRING
		}
	}
	return true;

}
///end ADD_ERROR_REPORT

class OC_REGISTERED NormalityTest : public StatsOpBase
{
///Arvin 11/10/07 XOP_NEED_SUPPORT_CHANGE_FUNCTION	
public:
	//Need call this method from oc code, so move it to public session
	void    ClearOutputTables(TreeNode& trOperation)
	{
		StatsOpBase::ClearOutputTables(trOperation);
		
		TreeNode 	trNormality, trTable;
		trNormality = trOperation.Calculation.NormalityTest;
		if(trNormality)
		{
			trTable = trNormality.SW;
			if(trTable)
				trTable.Reset(true);
			
			trTable = trNormality.LF;
			if(trTable)
				trTable.Reset(true);
			
			trTable = trNormality.KS;
			if(trTable)
				trTable.Reset(true);
		}
	}
///end XOP_NEED_SUPPORT_CHANGE_FUNCTION

protected:
	BOOL Construct(TreeNode& trOperation, int nOption = 0)
	{
		if( WksReportOperation::Construct(trOperation, nOption) )
		{
		
			constructAddNormalityTestReport(trOperation);
			
			TreeNode	trGUI = ConstructAddGUI(trOperation);
			
			ConstructNormalityGUITree(trGUI, nOption);
			
			DWORD dwOptions = REPORT_ARRANGE_GRAPHS_TO_COLS | REPORT_PLOT_ALL_PLOTS_IN_ONE_GRAPH;
			ConstructAddReportCommon(trOperation, dwOptions, IDST_OUTPUT_RESULTS_OPTIONS, true);
			
			FilterStatsGUI(trOperation);    ///Jim 01/17/06 v8.0358 CREATE_PLOTS_BRANCH_IN_MAIN_NODES
			
			///Sophy 12/17/2008 v8.0987d  QA80-12784 ADD_BINNING_CONTROL_FOR_HISTOGRAM_PLOT_IN_STATS_TOOLS add for stats tool(stats column, normality test
			AddHistogramPlotConfigBranch(trOperation, trOperation.GUI.Output);
			///end ADD_BINNING_CONTROL_FOR_HISTOGRAM_PLOT_IN_STATS_TOOLS

			return TRUE;
		
		}
		return FALSE;
	}
	
	// virtual 
	// fisher 11/16/2007 ADD_MAP_ID_TO_CHM
	int GetHelpID()
	{
		return IDD_XF_NormalityTest;
	}
	
	//virtual 
	string 	GetResultBookName(TreeNode& trGUI) { return E_STR_NORMALITY_TEST_REPORT_TABLE_BOOK_SHORT_NAME; } /// Iris 3/21/2008 v8.0829 QA80-10934 ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME

	/// Iris 06/07/2007 v8.0635 FIX_APPEND_MORE_ONE_FOOTNOTE_AFTER_DO_CHANGE_PARAMETERS
	//virtual
	///Arvin 11/10/07 XOP_NEED_SUPPORT_CHANGE_FUNCTION	
	//Need call this method from oc code, so move it to public session
	//void    ClearOutputTables(TreeNode& trOperation)
	//{
		//StatsOpBase::ClearOutputTables(trOperation);
		//
		//TreeNode 	trNormality, trTable;
		//trNormality = trOperation.Calculation.NormalityTest;
		//if(trNormality)
		//{
			//trTable = trNormality.SW;
			//if(trTable)
				//trTable.Reset(true);
			//
			//trTable = trNormality.LF;
			//if(trTable)
				//trTable.Reset(true);
			//
			//trTable = trNormality.KS;
			//if(trTable)
				//trTable.Reset(true);
		//}
	//}
	///end XOP_NEED_SUPPORT_CHANGE_FUNCTION
	///end FIX_APPEND_MORE_ONE_FOOTNOTE_AFTER_DO_CHANGE_PARAMETERS
	
	//virtual 
	int ConstructGraphNumber()
	{
		return 2;
	}
	
	//virtual 
	string GetClassName() {return "NormalityTest";}
	
	///Cheney 2007-9-28 MODIFY_TITLE_AS_MAX_SAID
	//virtual
	string GetAnalysisName(int nOption)
	{
		return _L("Normality Test");
	}
	///end MODIFY_TITLE_AS_MAX_SAID
	//----- CPY 9/30/07 FIX_CHENEY_MODIFY_TITLE_AS_MAX_SAID
	//virtual 
	string GetDlgDescription(int nOption)
	{
		return _L("Perform Normality Test");
	}
	//-----
	
	/// Iris 10/28/2009 QA81-14546 CHANGE_GUI_REPORT_TABLE_LABEL
	/*
	/// Iris 4/17/2008 SPECIAL_REPORT_TABLE_NAME_FOR_DIFF_TOOLS
	//virtual	
	string	GetReportTableGUIName(TreeNode& trGUI)
	{
		return STR_OUTPUT_NORMALITY_TEST_REPORT_TABLE;
	}
	///end SPECIAL_REPORT_TABLE_NAME_FOR_DIFF_TOOLS
	*/
	///end CHANGE_GUI_REPORT_TABLE_LABEL

	//virtual 
	DWORD	GetDataRules(const TreeNode& trOp, bool bIgnoreCombineInfo = false )
	{
		/// Max 04/25/06 QA70-7031-P6&P7 REMOVE_GET_MISSING_DATA_OPTION		
		//DWORD dwRet =  DRR_GET_MISSING|DRR_NO_WEIGHTS;
		///Jasmine 09/15/06 SETTING_CHANGE_AND_ADD_FOOTNOTE
		//Max said Normality Test not support grouping now
		//DWORD dwRet = DRR_NO_WEIGHTS;	
		DWORD dwRet = DRR_NO_WEIGHTS | DRR_NO_FACTORS;	
		///End SETTING_CHANGE_AND_ADD_FOOTNOTE
		/// END QA70-7031-P6&P7 REMOVE_GET_MISSING_DATA_OPTION		
		
		return CheckDataRules(trOp, dwRet, bIgnoreCombineInfo);
	}
	
	//virtual 
	int	ReportGetPicureIndexFromDataIndex(int nGraphIndex, int nDataIndex)
	{
		switch( ReportGetPlotTypeFromGraphIndex(nGraphIndex) )
		{
		case IDM_PLOT_BOX:
			return nDataIndex;
			
		case IDM_PLOT_HISTOGRAM_TYPE:
			return nDataIndex; 
		}
		
		return -1;
	}
	
	//virtual 
	int	ReportGetPlotTypeFromGraphIndex(int nGraphIndex)
	{
		switch( nGraphIndex )
		{
		/// Iris 04/12/2007 FIX_BOX_CHART_IS_EMPTY_IF_CHECKED_PLOT_ALL_PLOTS_IN_ONE_GRAPH
		/*
		case 0:
			return IDM_PLOT_BOX;
			
		case 1:
			return IDM_PLOT_HISTOGRAM_TYPE;
		*/
		case GRAPH_STATS_HISTOGRAM:
			return IDM_PLOT_HISTOGRAM_TYPE;
			
		case GRAPH_STATS_BOX:
			return IDM_PLOT_BOX;
		///end FIX_BOX_CHART_IS_EMPTY_IF_CHECKED_PLOT_ALL_PLOTS_IN_ONE_GRAPH
		}
		
		return -1;
	}
	
	//virtual 
	BOOL	CalcOneData(TreeNode &trOp, int index, int nTotalNumData, const vector<int> &vFactorSizes,
						const vector<string> &vstrFactors, vector &vData, vector &vDummy, matrix &mDummy, vector &vWeights, DWORD dwPlotObjUID, int nRowColIndex, const vector<int>& vintRowsInSource = NULL)
	{
		NormTestResults SWRes,LFRes,KSRes;
		
		string			strDataLabel;
		GetOneDataLabel(trOp, index, nRowColIndex, strDataLabel);
		
		if(NULL != vstrFactors && vstrFactors.GetSize()>0 )
			strDataLabel = vstrFactors[0];
		
		if(!AddDescStatsTable(trOp, index, vData, strDataLabel, vWeights, vstrFactors))
			return false;		
			
		if(!updateOutputNormTest(trOp, index, vData, strDataLabel, SWRes, LFRes, KSRes))
			return false;
		
		AddBinDataTableAndGraphNodes(trOp, index, vData, vstrFactors, strDataLabel);
	
		return true;
	}	

	//virtual
	void 	UpdateReportingTables(TreeNode &trOperation, int nTotalNumData, int nExeMode)
	{
		WksReportOperation::UpdateReportingTables(trOperation, nTotalNumData, nExeMode);
		
		TreeNode trTable = trOperation.Calculation.GetNode(TABLE_DESC_STATS);
		if(trTable)
			trTable.SetAttribute(TREE_Table, GetTableStringSupport(false)); 
			
		trTable = trOperation.Calculation.NormalityTest;
		if(trTable)
		{
			//trTable.SetAttribute(TREE_Table, GetTableStringSupport(false));///Alex 06/14/06 SET_NORMALITYTEST_BRANCH_ALL_OPEN
			trTable.SetAttribute(TREE_Table, atof(GetTableStringMain(false)));
			trTable.SetAttribute(STR_LABEL_ATTRIB, _L("NormalityTest"));///Jasmine 09/15/06 SETTING_CHANGE_AND_ADD_FOOTNOTE
		}
	}

///Echo 2/12/07 ADD_ERROR_REPORT
	//virtual 
	PEVENT_GETN GetNewEventFunction()
	{
		return normalitytest_event1;
	}
///end ADD_ERROR_REPORT
	
private:
	void 	constructAddNormalityTestReport(TreeNode& trOperation)
	{	
		TreeNode 	trOut = trOperation.Calculation; 
		
		trOut.Statistics.ID = IDST_DESC_STATS_RESULTS;
		trOut.NormalityTest.ID = IDST_NORM_TEST_RESULTS;				
	}
	
	bool updateOutputNormTest(TreeNode& trOp, int index, const vector& vData, string& strDataLabel, 
	NormTestResults& SWRes,NormTestResults& LFRes, NormTestResults& KSRes)
	 {	 	
	 	int nSWRet, nLFRet, nKSRet = 1;//set nKSRet not 0
	 	
	 	TreeNode tnSW = trOp.GUI.OptionBranch.GetNode("shap-wilk");
	 	if(tnSW.nVal)
	 	{
	 		///Echo 8/24/05 ERROR_ALGORITHM_USED
	 		//nSWRet = stats_shapiro_wilk_test(vData, SWRes, 1);
	 		nSWRet = stats_shapiro_wilk_test(vData, SWRes, 0);
	 		///END ERROR_ALGORITHM_USED
	 		updateNormTest(trOp, index, strDataLabel, nSWRet, SWRes, _LE("SW"), IDST_NORM_TEST_SW_RESULT, _LE("Shapiro-Wilk"));
			//trOp.Calculation.NormalityTest.SW.SetAttribute(STR_LABEL_ATTRIB, "Shapiro-Wilk");
	 	}
	 	
	 	if(trOp.GUI.OptionBranch.lilliefors.nVal)
	 	{
	 		nLFRet = stats_lilliefors_test(vData, LFRes);
	 		updateNormTest(trOp, index, strDataLabel, nLFRet, LFRes, _LE("LF"), IDST_NORM_TEST_LF_RESULT, _LE("Lilliefors"));
	 		//trOp.Calculation.NormalityTest.LF.SetAttribute(STR_LABEL_ATTRIB, "Lilliefors");
	 	}
	 	
	 	vector vPara(2);
	 	int nParatype = trOp.GUI.OptionBranch.kolm.Paras.nVal;
	 	int nUse;
	 	if(trOp.GUI.OptionBranch.kolm.GetAttribute(STR_USE_ATTRIB, nUse))
	 		if(nUse)
	 		{
		 		if( nParatype == PARA_SUPPLIED)
		 		{
		 			vPara[0]= trOp.GUI.OptionBranch.Kolm.mean.dVal;
		 			vPara[1]= trOp.GUI.OptionBranch.Kolm.variance.dVal;	
		 		}
		 		nKSRet =stats_kolmogorov_smirnov_test(vData, nParatype, vPara, KSRes);
		 		updateNormTest(trOp, index, strDataLabel, nKSRet, KSRes, _LE("KS"), IDST_NORM_TEST_KS_RESULT, _LE("Kolmogorov_Smirnov"));
		 		//trOp.Calculation.NormalityTest.KS.SetAttribute(STR_LABEL_ATTRIB, "Kolmogorov_Smirnov");
	 		}	
	 	
	 	/// Iris 1/19/2010 QA81-14988-P2 FIX_EMPTY_NORMALITY_TABLE_WHEN_UNCHECK_ALL
	 	TreeNode trTable = trOp.Calculation.NormalityTest;
	 	tree_check_set_hidden(trTable, trTable.GetNodeCount()>0 ? false : true);
	 	///End FIX_EMPTY_NORMALITY_TABLE_WHEN_UNCHECK_ALL
	 	return true;
	 }
	
	///Arvin 09/19/07 UPDATE_ERROR_MASSAGE_FOR_FOOTNOTE as echo said
	string getErrMsgForTables(LPCSTR lpsczDataLabel, LPCSTR lpsczTableLabel, int nErr)
	{
		string strDataLabel(lpsczDataLabel), strTableLabel(lpsczTableLabel);
		strTableLabel.TrimLeft();
		strTableLabel.TrimRight();
		if(strTableLabel.IsEmpty())
			return "";
		
		string strError;
		strError.Empty();
		int nPoints = 0;
		int nErrMsg; ///Arvin 10/27/07 LOCALIZED_FOOTNOTES_STRINGS
		switch(nErr)
		{
		case STATS_ERROR_TOO_FEW_DATA_PTS:
			if(strTableLabel.Compare("Shapiro-Wilk") == 0 || strTableLabel.Compare("Kolmogorov_Smirnov") == 0)	
				nPoints = 3;
			else if(strTableLabel.Compare("Lilliefors") == 0)
				nPoints = 4;
			
			if(nPoints > 0)
				///Arvin 10/27/07 LOCALIZED_FOOTNOTES_STRINGS
				//strError.Format("%s: Too few data points, data points number should not less than %d for %s.", strDataLabel, nPoints, strTableLabel);
				nErrMsg = FOOTNOTE_SHAPIRO_WILLK_1;
				///end LOCALIZED_FOOTNOTES_STRINGS
			break;
		case STATS_ERROR_TOO_MANY_DATA_PTS:
			if(strTableLabel.Compare("Shapiro-Wilk") == 0)
				nPoints = 5000;
			
			if(nPoints > 0)
				///Arvin 10/27/07 LOCALIZED_FOOTNOTES_STRINGS
				//strError.Format("%s: Too many data points, data points number should not be greater than %d for %s.", strDataLabel, nPoints, strTableLabel);
				nErrMsg = FOOTNOTE_SHAPIRO_WILLK_2;
				///end LOCALIZED_FOOTNOTES_STRINGS
			break;
		default:
			break;
		}
		
		///Arvin 10/27/07 LOCALIZED_FOOTNOTES_STRINGS
		ocu_load_err_msg_str(nErrMsg, &strError);
		strError.Format(strError, _L(strDataLabel), nPoints, _L(strTableLabel));
		///end LOCALIZED_FOOTNOTES_STRINGS
		return strError;
	}
	///end UPDATE_ERROR_MASSAGE_FOR_FOOTNOTE
	
	void updateNormTest(TreeNode& trOp, int index, const string strDataLabel, int nCalcResult, const NormTestResults& NormTestRes, LPCSTR lpcsztagName, int nId, LPCSTR lpsczTableLabel)
	 {
	 	//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
	 	double dAlpha=trOp.GUI.OptionBranch.alpha.dVal;
	 	//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
		string 	strLabel(strDataLabel);
		///Arvin 02/15/08 QA70-11097 KEEP_ESCAPED_STRINGS	
		//ConvertEscapedString(strLabel);
		string strTempLabel = strLabel;
		ConvertEscapedString(strTempLabel);
		///end KEEP_ESCAPED_STRINGS
	 	TreeNode trTable;
	 	
	 	trTable = tree_check_get_node(trOp.Calculation.NormalityTest, lpcsztagName, nId, STR_LABEL_ATTRIB, _L(lpsczTableLabel));
		//trTable.SetAttribute(TREE_Table, GetTableStringSupport(false));///Alex 06/14/06 SET_NORMALITYTEST_BRANCH_ALL_OPEN
		trTable.SetAttribute(TREE_Table, GetTableStringSupport(false) | GETNBRANCH_OPEN);
		
		///Arvin 09/19/07 UPDATE_ERROR_MASSAGE_FOR_FOOTNOTE as echo said
		TreeNode trRow;
		trRow = check_add_enumerated_node(trTable, CALCULATION_REPORT_TABLE_ROW_PREFIX, index+1, IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, _L(strDataLabel));
		trRow += NormTestRes;
		trRow.DOF.SetAttribute(STR_LABEL_ATTRIB, _L("DF"));		
		trRow.TestStat.SetAttribute(STR_LABEL_ATTRIB, _L("Statistic"));
		///Jim 11/17/05 P_VALUE_NAME_CONVENTION  For the names' convention of p-value
		if( IDST_NORM_TEST_SW_RESULT == nId ) 
			trRow.Prob.SetAttribute(STR_LABEL_ATTRIB, _L("Prob<W"));
		else
			trRow.Prob.SetAttribute(STR_LABEL_ATTRIB, _L("Prob>D"));
		//END P_VALUE_NAME_CONVENTION
		trRow.ID = make_one_set_ID(nId, index+1);
		///end UPDATE_ERROR_MASSAGE_FOR_FOOTNOTE
		
		/// Iris 8/05/2009 QA80-14808 HUGE_FOOTNOTE_IN_REPORT_SHEET_CAUSE_ORIGIN_NOT_ENERGETIC
		{
			TreeNode 	trFooter = tree_check_get_node(trTable, "Footnote", IDE_FOOTNOTE_BEGIN, TREE_Footnote, "1");
			if( 0 == index )
				trFooter.SetAttribute(FOOTNOTE_STOP_ATTRIB, 0);		
			if( index >= 5 )
			{
				// stop to add foonote when dataset index >= 5
				int nStop = 0;
				if( trFooter.GetAttribute(FOOTNOTE_STOP_ATTRIB, nStop) && 1== nStop )
					return;				
				trFooter.SetAttribute(FOOTNOTE_STOP_ATTRIB, 1);
				
				if( STATS_NO_ERROR ==  nCalcResult )
				{
					string strProbValueInfo;
					ocu_load_err_msg_str(FOOTNOTE_PROB_VALUE_INFO, &strProbValueInfo);
					//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
					strProbValueInfo.Format(strProbValueInfo,dAlpha,dAlpha);
					//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
					if( !trFooter.IsEmpty() )
						strProbValueInfo = trFooter.strVal + "\n" + strProbValueInfo;
					trFooter.strVal = strProbValueInfo;
					return;
				}
			}
		}
		///end HUGE_FOOTNOTE_IN_REPORT_SHEET_CAUSE_ORIGIN_NOT_ENERGETIC
		
		if( STATS_NO_ERROR !=  nCalcResult)
		{
			//------ Iris 02/26/2007 NEW_DESIGN_ON_FOOTNOTE_TO_INCLUDE_ERRORINFO From Echo's suggestion, put error message into footnote
			/*
			TreeNode    trRow = tree_check_get_node(trTable, "Error", nId, STR_LABEL_ATTRIB, "Attention!");
			trRow.strVal = "error in NormalityTest";
			return;
			*/
			TreeNode 	trFooter = tree_check_get_node(trTable, "Footnote", IDE_FOOTNOTE_BEGIN, TREE_Footnote, "1"); 
			string		strError;
			///Arvin 09/19/07 UPDATE_ERROR_MASSAGE_FOR_FOOTNOTE as echo said
			//if( !trFooter.IsEmpty() )
			//	strError = trFooter.strVal + "\n";
			///end UPDATE_ERROR_MASSAGE_FOR_FOOTNOTE
			
			///Arvin 09/19/07 UPDATE_ERROR_MASSAGE_FOR_FOOTNOTE as echo said
			//switch(nCalcResult)
			//{
			//case STATS_ERROR_TOO_FEW_DATA_PTS:
			//	strError += strLabel + ": Too few data points, N must be > 2\n";
			//	break;
			//default:
			//	break;
			//}
			//strError.TrimRight("\n");
			///Arvin 02/15/08 QA70-11097 KEEP_ESCAPED_STRINGS
			//strError = getErrMsgForTables(strLabel, lpsczTableLabel, nCalcResult);
			strError = getErrMsgForTables(strTempLabel, lpsczTableLabel, nCalcResult);
			///end KEEP_ESCAPED_STRINGS
			if(!trFooter.IsEmpty())
				strError = trFooter.strVal + "\n" + strError;
			///end UPDATE_ERROR_MASSAGE_FOR_FOOTNOTE
			trFooter.strVal = strError;
			//------ NEW_DESIGN_ON_FOOTNOTE_TO_INCLUDE_ERRORINFO 
		}
		///Arvin 09/19/07 UPDATE_ERROR_MASSAGE_FOR_FOOTNOTE as echo said
		/*
		TreeNode trRow;
		trRow = check_add_enumerated_node(trTable, CALCULATION_REPORT_TABLE_ROW_PREFIX, index+1, IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, strDataLabel);
		trRow += NormTestRes;
		trRow.DOF.SetAttribute(STR_LABEL_ATTRIB, "DF");		
		trRow.TestStat.SetAttribute(STR_LABEL_ATTRIB, "Statistic");
		///Jim 11/17/05 P_VALUE_NAME_CONVENTION  For the names' convention of p-value
		if( IDST_NORM_TEST_SW_RESULT == nId ) 
			trRow.Prob.SetAttribute(STR_LABEL_ATTRIB, "Prob<W");
		else
			trRow.Prob.SetAttribute(STR_LABEL_ATTRIB, "Prob>D");
		//END P_VALUE_NAME_CONVENTION
		trRow.ID = make_one_set_ID(nId, index+1);
		*/
		///end UPDATE_ERROR_MASSAGE_FOR_FOOTNOTE
		//----- Iris 02/26/2007 v8.0570 according to Echo's requirement, cannot set DOF to Missing data since type of DOF varaible is INT in NormTestResults struct
		///Arvin 09/19/07 UPDATE_ERROR_MASSAGE_FOR_FOOTNOTE as echo said
		//if( STATS_NO_ERROR !=  nCalcResult)
		//	trRow.DOF.dVal = NANUM;
		///end UPDATE_ERROR_MASSAGE_FOR_FOOTNOTE
		//----- 
		
		/// Iris 02/26/2007 v8.0570 NEW_DESIGN_ON_FOOTNOTE_TO_INCLUDE_ERRORINFO
		///Jasmine 09/07/06 ADD_FOOTNOTE
		/*
		trTable = trOp.Calculation.NormalityTest.GetNode(lpcsztagName);
		if(trTable)
		{	
			TreeNode 	trFooter = tree_check_get_node(trTable, "Footnote", IDE_FOOTNOTE_BEGIN, TREE_Footnote, "1"); // just need the TREE_Footnote attribute, value does not matter, so 1 is good
			string strMessage, strPV = IDST_NORM_TEST_SW_RESULT == nId? "" : " not";
			
			strMessage.Format("At the 0.05 level, the data was%s significantly drawn from a normally distributed population", strPV);
			trFooter.strVal = strMessage;
			///Jasmine 09/15/06 SETTING_CHANGE_AND_ADD_FOOTNOTE
			//add a footnote when Kolmogorov-Smirnov test is selected and Parameters box is set as "Specified"
			string strTagName = "ks";
			TreeNode trKolm = trOp.GUI.OptionBranch.Kolm;
			if(!strTagName.CompareNoCase(lpcsztagName) &&  PARA_SUPPLIED == trKolm.Paras.nVal)
			{				
				strMessage.Format("\nParameters for Normal Distribution was specified. Mean = %f, Variance = %f.", trKolm.mean.dVal, trKolm.variance.dVal);
				trFooter.strVal += strMessage;
			}
			///End SETTING_CHANGE_AND_ADD_FOOTNOTE
		}
		*/
		///End ADD_FOOTNOTE
			
		TreeNode 	trFooter = tree_check_get_node(trTable, "Footnote", IDE_FOOTNOTE_BEGIN, TREE_Footnote, "1"); // just need the TREE_Footnote attribute, value does not matter, so 1 is good
		string 		strMessage;
		if(0 == index)
		{
			string 		strTagName = "ks";
			TreeNode 	trKolm = trOp.GUI.OptionBranch.Kolm;
			if(!strTagName.CompareNoCase(lpcsztagName) &&  PARA_SUPPLIED == trKolm.Paras.nVal)
			{				
				///Arvin 10/27/07 LOCALIZED_FOOTNOTES_STRINGS
				//strMessage.Format("Parameters for Normal Distribution was specified. Mean = %f, Variance = %f.", trKolm.mean.dVal, trKolm.variance.dVal);
				string strMean, strVariance;
				strMean = ftoa(trKolm.mean.dVal);
				strVariance = ftoa(trKolm.variance.dVal);
				ocu_load_msg_str(FOOTNOTE_NORM_KOLM, &strMessage, strMean, NULL, strVariance);
				///end LOCALIZED_FOOTNOTES_STRINGS
				trFooter.strVal += strMessage;
			}
		}
		
		if( STATS_NO_ERROR ==  nCalcResult )
		{
			/// Max 6/8/07 CORRECT_RULE_FOR_CONCLUSION_IN_FOOTNOTE
			// string		strPV = trRow.Prob.dVal > 0.05? " not" : "";
			//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
			//string		strPV = trRow.Prob.dVal > 0.05? "" : "" + _L("not");
			double dAlpha=trOp.GUI.OptionBranch.alpha.dVal;
			string		strPV = trRow.Prob.dVal > dAlpha? "" : "" + _L("not");
			//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
			/// END CORRECT_RULE_FOR_CONCLUSION_IN_FOOTNOTE
			///Arvin 10/27/07 LOCALIZED_FOOTNOTES_STRINGS
			//strMessage.Format("%s: At the 0.05 level, the data was%s significantly drawn from a normally distributed population", strLabel, strPV);
			//------ Folger 12/10/07 CLEAN_NEGATIVE_ERROR_MESSAGES
			//ocu_load_msg_str(FOOTNOTE_NORM_PROB, &strMessage, _L(strLabel), NULL, strPV);
			///Arvin 02/15/08 QA70-11097 KEEP_ESCAPED_STRINGS
			//ocu_load_msg_str(trRow.Prob.dVal > 0.05 ? FOOTNOTE_NORM_PROB : FOOTNOTE_NORM_PROB_NEGATIVE, &strMessage, _L(strLabel));
			//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
			//ocu_load_msg_str(trRow.Prob.dVal > 0.05 ? FOOTNOTE_NORM_PROB : FOOTNOTE_NORM_PROB_NEGATIVE, &strMessage, _L(strTempLabel));
			ocu_load_err_msg_str(trRow.Prob.dVal > dAlpha ? FOOTNOTE_NORM_PROB : FOOTNOTE_NORM_PROB_NEGATIVE, &strMessage);
			strMessage.Format(strMessage, _L(strTempLabel),dAlpha);
			//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
			///end KEEP_ESCAPED_STRINGS
			//------
			///end LOCALIZED_FOOTNOTES_STRINGS
			if(!trFooter.IsEmpty())
				strMessage = trFooter.strVal + "\n" + strMessage;
			
			trFooter.strVal = strMessage;
		}
		
		if(is_missing_value(trRow.Prob.dVal))
		{
			if(0 != lstrlen(trFooter.strVal))
				trFooter.strVal += "\n";
			///Arvin 10/27/07 LOCALIZED_FOOTNOTES_STRINGS
			//trFooter.strVal += strLabel + ": " + STATS_NO_CONCLUSION;
			string strConclusion;
			ocu_load_msg_str(FOOTNOTE_NO_CONCLUSION, &strConclusion);
			///Arvin 02/15/08 QA70-11097 KEEP_ESCAPED_STRINGS
			//trFooter.strVal += strLabel + ": " + strConclusion;
			trFooter.strVal += strTempLabel + ": " + strConclusion;
			///end KEEP_ESCAPED_STRINGS
			///end LOCALIZED_FOOTNOTES_STRINGS
		}
		///end NEW_DESIGN_ON_FOOTNOTE_TO_INCLUDE_ERRORINFO
	 }	
};
