/*------------------------------------------------------------------------------*
 * File Name:ANOVAOneWay.cpp													*
 * Creation:  																	*
 * Purpose: OriginC Source C file implementing One Way ANOVA operation 			*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *  Iris 12/15/04 NEED_REMOVE_MISS_VALUE										*
 *	CPY 12/21/04 CLEANUP_ANOVA1_AND_USE_BASE_CLASS_FIX							*
 *  Iris 12/30/04 CLEANP_UP_GRAPH_CODES											*
 *  Iris 02/16/05 BASE_CALSS_FUNCTION_INSTEAD_ADD_DESCSTAT_TABLE				*
 *  Iris 3/22/05 ADD_MORE_MEAN_COMPARISON_CASE									*
 *  Iris 3/22/05 FIX_GROUP_DATA_ONLY_ONE_BOX_CHART								*
 *	ML 10/20/2005 ANOVA_INPUT_DATA_TO_DATARANGE									*
 *	ML 10/24/2006 RUN_TIME_ERROR												*
 *	ML 10/24/2005 ANOVAS_INDEXED_RAW											*
 *	ML 10/25/2005 MUST_CLEAN_UP_CACHED_STUFF									*
 *  Jim 3/8/06 ADD_TABLE_FOOTNOTE                                               *
 *  Jim 3/10/06 EQUALVARI_SUBBRANCH_NOT_CHECK_RUNTIME_ERROR						*
 *  Thomas 03/21/2006 IGNORE_DESCSTATS_OPTION_TEMPORARILY						*
 *  Thomas 03/21/2006 REMOVE_DESCSTATS_NODE_IF_NO_DESCSTATS_OPTION				*
 *	CPY 10/14/06 SEPARATE_OUT_OPERATION_BASE_INTO_SEPARATE_HEADER				*
 *  Iris 11/01/06 v8.0502d NO_COL_LABEL_IN_POWER_TABLE							*
 *  Iris 01/03/2007 FAIL_TO_PLOT_MEAN_SD_SE_IF_NOT_PLOT_MEAN_COMP				*
 *	Echo 1/31/07 ADD_ERROR_REPORT												*
 *	Cheney 2007-6-7 SHOULD_CHECK_EVENT_ID_IN_EVENT_FUNC							*
 *	Arvin 08/09/07 QA70-7100 ADD_ERROR_MESSAGE									*
 *	Arvin 09/30/07 SHOULD_GET_LABEL_WITH_INDEXCOMP_FOR_BONHOLM_AND_SIDAKHOLM as max said
 *	Arvin 09/30/07 HIDE_DOF_COL_FOR_MEAN_COMP_TABLE as max said					*
 *	Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE										*
 *	Hong 10/24/07 v8.0732 LOCALISED_REPORTTREE_ISSUE							*
 *	Arvin 10/27/07 LOCALIZED_FOOTNOTES_STRINGS									*
 *	Folger 12/10/07 CLEAN_NEGATIVE_ERROR_MESSAGES								*
 *	Arvin 02/14/08 QA70-11094 SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
 *	Sophy 4/3/2009 QA80-13352 SUPPORT_SPECIFY_COLUMN_DESIGNATIONS_IN_REPORT_TABLES
 *	Hong 09/04/09 QA80-14258 HISTOGRAM_NEED_SPECIAL_HINT_FOR_DOING_NLFITTING	*
 *	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>

#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"
#include "ANOVAOneWay.h"
////////////////////////////////////////////////////////////////////////////////////
/// Iris 05/21/2007 v8.0622 NEED_REPORT_PLOTS_IN_RM_ONE_WAY
/*
enum{
	GRAPH_STATS_BAR,	
	GRAPH_STATS_BOX_PLOT,
	GRAPH_STATS_MEANS_SD_PLOT, 
	GRAPH_STATS_MEANS_SE_PLOT, 
	GRAPH_STATS_MEANS_COMP_PLOT
};

enum {
	ID_PLOT_STATS_MEANS_PLOT = 1234, 
	ID_PLOT_STATS_BARS_PLOT,
	ID_PLOT_STATS_LAST_ENTRY
};

#define STAT_MEANS_SD_PLOT_REPORT_LABEL "Means Plot (SD as Error)"
#define STAT_MEANS_SE_PLOT_REPORT_LABEL "Means Plot (SE as Error)"
#define STAT_BAR_REPORT_LABEL 			"Bar Chart"
#define STAR_MEAN_DIFF_LABEL			"Means Comparison Plot"
*/
////end NEED_REPORT_PLOTS_IN_RM_ONE_WAY

///Echo 1/31/07 ADD_ERROR_REPORT
static int anovaoneway_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
	
	///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
	{
		DataRange drData;
		drData.Create();
		bool bRaw = tr.InputData.Use;
		int nOption = bRaw ? DRTREE_ANOVA_ONE_WAY_RAW : DRTREE_ANOVA_ONE_WAY_INDEXED;
		drData.SetTree(tr.InputData, nOption);
		int nLevels;
		if (tr.InputData.Factor0.Levels) nLevels = tr.InputData.Factor0.Levels.GetNodeCount();
		int nErr = bRaw ? check_data_in_var(drData, nLevels, false) : check_data_in_group(drData);
		
		int nRaw = tr.InputData.Use;
		/// Iris 05/10/2007 v8.0615 REMOVE_BRANCH_CHECK_BOX
		//if ( tr.MeansComp.Use && !check_sig_level( tr.MeansComp.SigLevel.dVal) )
		//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL 
		if( CER_NO_ERROR == nErr && !check_sig_level(tr.alpha.dVal))
		{
			nErr = CER_INVALID_SIG_LEV;
		}
		if( CER_NO_ERROR == nErr && !check_sig_level(tr.EqualVar.sigVariance.dVal))
		{
			nErr = CER_INVALID_SIG_LEV;
		}
		//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
		int nCount = 0;
		foreach(TreeNode trN in tr.MeansComp.Children)
		{
			if(trN.ID == TRGP_CHECK && 0 != trN.nVal)
			{
				nCount++;
			}
		}
		if(0 != nCount && !check_sig_level( tr.MeansComp.SigLevel.dVal) )
		///end REMOVE_BRANCH_CHECK_BOX
		{
			nErr = CER_INVALID_SIG_LEV;
		}
		
		if (tr.PowerBranch.Use)
		{
			TreeNode trPower = tr.PowerBranch;
			if (  CER_NO_ERROR == nErr && !check_sig_level( trPower.SigLevel.dVal) )
			{
				nErr = CER_INVALID_SIG_LEV;
			}
			if ( trPower.HypotSizes.Enable && !check_sample_size(trPower.HypotSizes.strVal) && nErr == CER_NO_ERROR)
			{
				nErr = CER_SAMP_SIZES;
			}
			if (  CER_NO_ERROR == nErr && !check_sig_level( tr.PowerBranch.SigLevel.dVal) )
			{
				nErr = CER_INVALID_SIG_LEV;
			}
		}
		///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
		
		if (nErr != CER_NO_ERROR)
		{
			bOKEnable = false;
			strErrMsg = nErr;
			///Sophy 4/14/2008 ADD_OUTPUT_ERR_STRING
			if( !strRet.IsEmpty() )
			{
				strErrMsg += ":" + strRet; 
			}
			///end ///Sophy 4/14/2008 ADD_OUTPUT_ERR_STRING
		}
		
		/// Iris 5/27/2008 UPDATE_REPORT_BOOK_SHEET_COMBO_ON_SOURCE_CHANGE, if source book/sheet changed, source book/sheet name should update relative
		#ifdef _MOVE_FIT_OUTPUT_TO_OC_CLASS 
		OutputGUIManagerBase* 	pOutputManager = get_output_GUI_manager_pointer(tr);
		if(pOutputManager)
			pOutputManager->UpdateOutputOnDataChange(tr);
		#endif //_MOVE_FIT_OUTPUT_TO_OC_CLASS
		///end UPDATE_REPORT_BOOK_SHEET_COMBO_ON_SOURCE_CHANGE

	}
	return true;
	

}
///end ADD_ERROR_REPORT

///////////////////////////////////////////////
// Class ANOVAOneWay
///////////////////////////////////////////////
/// Iris 12/27/05 CONSTRUCT_RM_BASE_CLASS  move to base class
//BOOL ANOVAOneWay::Construct(TreeNode& trOperation, int nOption)
//{
	//if( WksReportOperation::Construct(trOperation, nOption) )
	//{			
		//ConstructOutputTable(trOperation);
		//
		//TreeNode	trGUI = ConstructAddGUI(trOperation);			
//
		///// YuI 09/26/05 ANOVA_DATA_SELECTION_GUI
		////	ConstructOneWayANOVAGUITree(trGUI, nOption);
		//ConstructOneWayANOVAGUITree(trGUI, nOption, IsRM());
		///// end ANOVA_DATA_SELECTION_GUI
		//
		/////Iris 4/06/05 INIT_GRAPH_NUMBER
		////ConstructAddReportCommon(trOperation, 0, IDST_OUTPUT_RESULTS_OPTIONS, true, 5);
		////ConstructAddReportCommon(trOperation, 0, IDST_OUTPUT_RESULTS_OPTIONS, true, 2);
		//ConstructAddReportCommon(trOperation, 0, IDST_OUTPUT_RESULTS_OPTIONS, true);
		/////---
		//
		//Operation::ConstructAddCommonBottom(trGUI);			
//
		//return TRUE;
	//}
//}	
///End CONSTRUCT_RM_BASE_CLASS

/////Jim 3/8/06 v8.0372 ADD_TABLE_FOOTNOTE
//ANOVAOneWay::ANOVAOneWay()
//{
	//ide_footnote = IDE_FOOTNOTE_BEGIN;
//}
/////END ADD_TABLE_FOOTNOTE

///Iris 4/06/05 INIT_GRAPH_NUMBER
//virtual
///Arvin 02/14/08 QA70-11094 SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
//DWORD ANOVAOneWay::GetOutputOptions()
DWORD ANOVAOneWay::GetOutputOptions(const TreeNode& trOp)
///end SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
{
	DWORD 	dwOptions = REPORT_ARRANGE_GRAPHS_TO_COLS | REPORT_PLOT_ALL_PLOTS_IN_ONE_GRAPH;
	return dwOptions;
}

int ANOVAOneWay::ConstructGraphNumber()
{
	return 5;
}

//virtual 
int	ANOVAOneWay::GetNumberLayersInOneGraph(TreeNode& trOp, int nGraphIndex)
{
	return 1;
}

///Echo 1/31/07 ADD_ERROR_REPORT

//virtual 
PEVENT_GETN ANOVAOneWay::GetNewEventFunction()
{
	return anovaoneway_event1;
}
///end ADD_ERROR_REPORT

/// Iris 3/21/2008 v8.0829 QA80-10934 ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME, want GUI tree as input in DescStats::GetResultSheetName
//string 	ANOVAOneWay::GetResultSheetName() 
string 		ANOVAOneWay::GetResultSheetName(TreeNode& trGUI)
///end ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME
{
	///Cheney 2007-10-27 CLEAN_UP_LOCALIZATION_THINGS
	//return "ANOVA1Way";
	return STR_ANOVA_1_WAY_REPORT_TABLE_SHEET_NAME;
	///end CLEAN_UP_LOCALIZATION_THINGS
}
//virtual 
string 	ANOVAOneWay::GetResultBookName(TreeNode& trGUI)
{
	return E_STR_ANOVA_1_WAY_REPORT_TABLE_BOOK_SHORT_NAME;
}

string ANOVAOneWay::GetClassName()
{
	return "ANOVAOneWay";
}

/// Iris 12/27/05 CONSTRUCT_RM_BASE_CLASS, move to base class
///// ML 10/20/2005 ANOVA_INPUT_DATA_TO_DATARANGE
//// virtual
//int		ANOVAOneWay::GetDRTreeOption(TreeNode &trOperation)
//{
	///// ML 10/26/2005 QA70-8225 ESCAPED_OPER_STRINGS_ANOVAS
	///*
	//TreeNode	trInputData = trOperation.GUI.InputData;
	//int			nDRTreeOption = DRTREE_DEFAULT;
	//switch( trInputData.Use )
	//{
	//case ANOVA_RAW_DATA:
		//nDRTreeOption = DRTREE_ANOVA_ONE_WAY_RAW;
		//break;
		//
	//case ANOVA_INDEXED_DATA:
		//nDRTreeOption = DRTREE_ANOVA_ONE_WAY_INDEXED;
		//break;
	//default:
		//ASSERT(FALSE);
	//}
	//
	//return nDRTreeOption;
	//*/
	//int			nDRTreeOption = IsIndexedData(trOperation) ? DRTREE_ANOVA_ONE_WAY_INDEXED : DRTREE_ANOVA_ONE_WAY_RAW;
	//return nDRTreeOption;
	///// end ESCAPED_OPER_STRINGS_ANOVAS
//}
///// end ANOVA_INPUT_DATA_TO_DATARANGE
///End CONSTRUCT_RM_BASE_CLASS

//virtual
int ANOVAOneWay::GetResultCurvesID() { return IDST_REPORT_CURVE_OPTIONS;}

/// Iris 05/21/2007 v8.0622 NEED_REPORT_PLOTS_IN_RM_ONE_WAY
/*
string 	ANOVAOneWay::GetGraphTemplate(int nGraphIndex)
{
	if(nGraphIndex == GRAPH_STATS_MEANS_COMP_PLOT)
		return "ReportMeanComp";
	/// Iris 05/08/2007 v8.0613 SUGGESTION_ON_BAR_CHART
	if(nGraphIndex == GRAPH_STATS_BAR)
		return "ReportBar";
	///end SUGGESTION_ON_BAR_CHART
	
	return WksReportOperation::GetGraphTemplate(nGraphIndex);
}

int	ANOVAOneWay::ReportGetPicureIndexFromDataIndex(int nGraphIndex, int nDataIndex)
{
	switch( nGraphIndex )
	{
	case GRAPH_STATS_BOX_PLOT:
	case GRAPH_STATS_MEANS_COMP_PLOT:
		return nDataIndex; 
	default:
		return 0; //Iris 12/22/05 bar chart of mean, line of mean sd, line of mean se, all just include one picture.
	}
	
	return -1;
}

int	ANOVAOneWay::ReportGetPlotTypeFromGraphIndex(int nGraphIndex)
{
	switch( nGraphIndex )
	{
	case GRAPH_STATS_BOX_PLOT:
		return IDM_PLOT_BOX;
		
	case GRAPH_STATS_MEANS_SD_PLOT:
	case GRAPH_STATS_MEANS_SE_PLOT:
		return IDM_PLOT_LINESYMB;
	case GRAPH_STATS_MEANS_COMP_PLOT:
		return IDM_PLOT_SCATTER;
	case GRAPH_STATS_BAR:
		/// Iris 05/08/2007 v8.0613 SUGGESTION_ON_BAR_CHART
		//return IDM_PLOT_BAR;
		return IDM_PLOT_COLUMN; 
		///end SUGGESTION_ON_BAR_CHART
	}
	
	return -1;
}

string ANOVAOneWay::GetResultCurveBookName(TreeNode& trOperation, int nDataIndex, int nOption, bool bSeparateSheetForDataset)
{
	return "Means Plot";
}


bool ANOVAOneWay::GetCustomGraphTypeName(string& strName, int nIndex)
{
	switch( nIndex )
	{
	case GRAPH_STATS_BOX_PLOT:
		strName = _L(STAT_BOXCHART_REPORT_LABEL);
		break;
	case GRAPH_STATS_MEANS_SD_PLOT:
		strName = _L(STAT_MEANS_SD_PLOT_REPORT_LABEL);
		break;
	case GRAPH_STATS_MEANS_SE_PLOT:
		strName = _L(STAT_MEANS_SE_PLOT_REPORT_LABEL);
		break;
	case GRAPH_STATS_BAR:
		strName = _L(STAT_BAR_REPORT_LABEL);
		break;
	case GRAPH_STATS_MEANS_COMP_PLOT:
		strName = _L(STAR_MEAN_DIFF_LABEL);
		break;
	}
		
	return true;
}

uint ANOVAOneWay::GetResultCurveTableID(TreeNode& trOp, int nDataIndex, int nTotalNumData, int nGraphIndex)
{
	switch( nGraphIndex )
	{
	case GRAPH_STATS_MEANS_SD_PLOT:
		return IDST_ANOVA_MEAN_SD_WKS_TABLE;
	case GRAPH_STATS_MEANS_SE_PLOT:
		return IDST_ANOVA_MEAN_SE_WKS_TABLE;
	case GRAPH_STATS_BAR:
		return IDST_ANOVA_BAR_CHART_WKS_TABLE;
	case GRAPH_STATS_MEANS_COMP_PLOT:
		return IDST_ANOVA_MEAN_COMP_WKS_TABLE + nDataIndex;		
	}
	
	return 0;
}
bool ANOVAOneWay::IsGraphTableInsertBackToSourceType(int nGraphIndex)
{		
	return false;
}

//--- Iris 11/02/06 v8.0502e SHOW_HIDDEN_REPORT_DATA_SHEET_EVEN_NO_NEED_OUTPUT_GRAPH
//give a better name
//virtual
string	ANOVAOneWay::GetResultCurveSheetName(TreeNode& trOperation, int nIndex, int nOption)
{
	//---- Iris 01/03/2007 discussed with Max, give a better name for curve sheet.
	//return "Means";
	return "Plots";
	//----
}

bool ANOVAOneWay::IsOutputSeparateResultCurveSheet(const TreeNode& trOp) 
{
	if( StatsOpBase::IsOutputSeparateResultCurveSheet(trOp) )
	{
		foreach(TreeNode trPlot in trOp.GUI.Plots.Children)
			if(trPlot.nVal)
				return true;
	}
	return false;
}
//--- 

int ANOVAOneWay::GetTotalNumPictureForOneGraphType(TreeNode& trOp, int nGraphIndex)
{
	int nNum = 0;
	if(-1 == nGraphIndex)
	{
		//--- Iris 11/02/06 v8.0502e SHOW_HIDDEN_REPORT_DATA_SHEET_EVEN_NO_NEED_OUTPUT_GRAPH
		//getMeanDiffTableNumber(trOp);
		//if( NULL != nTotalNumData && nTotalNumData>nNum )
			//nNum = nTotalNumData;
		/// Iris 01/03/2007 FAIL_TO_PLOT_MEAN_SD_SE_IF_NOT_PLOT_MEAN_COMP		
		//nNum = 1;
		//if(trOp.GUI.Plots.Graph5.nVal)//Graph5, mean comparison plot
		//{
			//nNum = getMeanDiffTableNumber(trOp);
		//}
		//else if(trOp.GUI.Plots.Graph2.nVal)//Graph2, Box chart, plot from source data
		//{
			//nNum = 0;
		//}		
		TreeNode	trPlots = trOp.GUI.Plots;
		if(trPlots.Graph1.nVal || trPlots.Graph3.nVal || trPlots.Graph4.nVal) //Graph1: Bar Chart; Graph3: Mean SD; Graph4: Mean SE
		{
			nNum = 1;
		}
		if(trPlots.Graph5.nVal)//Graph5, mean comparison plot
		{
			nNum = getMeanDiffTableNumber(trOp);//if check mean comparison plot, nNum >= 1
		}
		///end FAIL_TO_PLOT_MEAN_SD_SE_IF_NOT_PLOT_MEAN_COMP
		//--- 
	}
	else
	{	
		switch( nGraphIndex )
		{
		case GRAPH_STATS_BAR:
		case GRAPH_STATS_MEANS_SD_PLOT:
		case GRAPH_STATS_MEANS_SE_PLOT:
			nNum = 1;
			break;
			
		case GRAPH_STATS_MEANS_COMP_PLOT:
			nNum = getMeanDiffTableNumber(trOp);
			break;
			
		case GRAPH_STATS_BOX_PLOT:
			nNum = GetTotalNumData(trOp);
			break;
		}
	}	
	return nNum;
}
*/
///end NEED_REPORT_PLOTS_IN_RM_ONE_WAY

void 	ANOVAOneWay::UpdateReportingTables(TreeNode &trOperation, int nTotalNumData, int nExeMode)
{
	WksReportOperation::UpdateReportingTables(trOperation, nTotalNumData, nExeMode);		
	
	//DescStat
	if(!UpdateTableString(trOperation.Calculation.Statistics, false, false, atof(GetTableStringMain(false)) ))
		error_report("ANOVA One Way found invalid Calculation.Statistics node");
	
	//ANOVAs
	if(!UpdateTableString(trOperation.Calculation.ANOVAs, true, true, GetTableStringSupport(false), atof(GetTableStringMain(false))))
		error_report("ANOVA One Way found invalid Calculation.ANOVAs node");
	else
	{			
		UpdateTableString(trOperation.Calculation.ANOVAs.OvarallANOVA, false, false, atof(GetTableStringMain(false)) );
		
		/// Iris 01/15/2007 v8.0541 HIDE_FIT_STATS_TABLE_EMPTY_ROW_LABEL
		///Arvin 11/01/07 FIT_STATS_TABLE_CAN_NOT_COPY_TO_TXT
		UpdateTableString(trOperation.Calculation.ANOVAs.FitStats, false, false, atof(GetTableStringMain(false)) );
		//string 	str = GetTableStringMain(false);
		//int nn = atoi(str);
		//nn |= GETNBRANCH_HIDE_ROW_LABELS;	
		//double dd = nn;
		//UpdateTableString(trOperation.Calculation.ANOVAs.FitStats, false, false, dd );
		///END FIT_STATS_TABLE_CAN_NOT_COPY_TO_TXT
		///end HIDE_FIT_STATS_TABLE_EMPTY_ROW_LABEL
	}
	
	// other sub nodes inside ANOVA that has another level
	UpdateTableString(trOperation.Calculation.ANOVAs.MeanComp, true);		
	UpdateTableString(trOperation.Calculation.ANOVAs.EqualVari, true);
	
	///Jim 3/10/06 v8.0373 ADD_TABLE_FOOTNOTE 
	trOperation.Calculation.ANOVAs.MeanComp.Footnote.RemoveAttribute(TREE_Table);
	///END ADD_TABLE_FOOTNOTE
	
	///Iris 12/30/04 CLEANP_UP_GRAPH_CODES
	//Wks data for MeanSD, MeanSE, MeanComp plot
	TreeNode trTable;
	trTable = trOperation.Calculation.BarChart;
	if(trTable)
		trTable.SetAttribute(TREE_Table, GetTableStringDatasets());
	
	trTable = trOperation.Calculation.MeanSDPlot;
	if(trTable)
		trTable.SetAttribute(TREE_Table, GetTableStringDatasets());
	
	trTable = trOperation.Calculation.MeanSEPlot;
	if(trTable)
		trTable.SetAttribute(TREE_Table, GetTableStringDatasets());
	
	trTable = trOperation.Calculation.MeanCompPlot;
	if(trTable)
		trTable.SetAttribute(TREE_Table, GetTableStringDatasets());
	///end CLEANP_UP_GRAPH_CODES
		
}		
//---------- end CLEANUP_ANOVA1_AND_USE_BASE_CLASS_FIX

//virtual
BOOL		ANOVAOneWay::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)   
{	
	
	GetDependentData(vData);
	GetFactors(trOp, index, vstrFactors);
	GetWeights(vWeights);
	m_nFactors++;
	
	string strDataLabel, strFactorLabel;
	GetOneDataLabel(trOp, index, nRowColIndex, strDataLabel);
	GetOneDataLabel(trOp, index, nRowColIndex, strFactorLabel, vstrFactors);
	
	/// Thomas 03/21/2006 IGNORE_DESCSTATS_OPTION_TEMPORARILY
	/* 
	   the data in the descriptive statistics table is needed to plot the graphs
	   even though the "Descriptive Statistics" option is not checked
	 */
	/*
	if(trOp.GUI.DescStats.nVal && !AddDescStatsTable(trOp, index, vData, strFactorLabel, vWeights, vstrFactors, false, false))
		return false;
	*/
	if( !AddDescStatsTable(trOp, index, vData, strFactorLabel, vWeights, vstrFactors, false, false) )
		error_report("fail to AddDescStatsTable");
	/// End IGNORE_DESCSTATS_OPTION_TEMPORARILY

	/// ML 10/24/2006 RUN_TIME_ERROR
	// This causes run-time error:
	//AddBinDataTableAndGraphNodes(trOp, index, vData, vstrFactors);
	/// end RUN_TIME_ERROR
	/// Iris 12/22/05 TO_GET_PLOTINFO_FOR_SPECIAL_PIC_IN_ONE_GRAPH
	//AddBinDataTableAndGraphNodes(trOp, index, vData, vstrFactors, strLabel);	
	///Arvin 06/19/07 WRONG_HISTOGRAM_AND_BOXCHART_PLOTS_WHILE_DATA_HAVE_FACTORS
	//AddBinDataTableAndGraphNodes(trOp, index, vData, vstrFactors, strFactorLabel, false);
	
	/// Iris 3/23/2009 QA80-13285-P7 CLEAN_ANOVE_REPORT_DATA_COMMENTS_LABEL	
	/*
	ConvertEscapedString(strDataLabel);
	TreeNode trInput = trOp.GUI.InputData;
	//If is raw mode, data lablels are wrong
	if(trInput && trInput.Use)
		///Arvin 11/22/07 BETTER_LABEL_FOR_PLOTS as max's suggetion
		//strDataLabel = _L("All Levels");
		strDataLabel = _L("ANOVA Plots");
		///end BETTER_LABEL_FOR_PLOTS
	*/
	strDataLabel = STR_REPORT_ANOVE_PLOTS_DATA_LABEL;
	///end CLEAN_ANOVE_REPORT_DATA_COMMENTS_LABEL
	AddBinDataTableAndGraphNodes(trOp, index, vData, vstrFactors, strDataLabel, false);
	///end WRONG_HISTOGRAM_AND_BOXCHART_PLOTS_WHILE_DATA_HAVE_FACTORS
	//End TO_GET_PLOTINFO_FOR_SPECIAL_PIC_IN_ONE_GRAPH
	
	if(index < nTotalNumData-1)
		return TRUE;
	
	//if(!addResultsToReportTree(trOp, nTotalNumData, m_vWeights))
	if(!addReportTables(trOp, nTotalNumData, m_vWeights))
		return error_report("ANOVA One Way failed addReportTables");

	/// Iris 05/21/2007 v8.0622 NEED_REPORT_PLOTS_IN_RM_ONE_WAY
	//addReportDataTablesAndGraphNodes(trOp, nTotalNumData, strDataLabel);
	///Arvin 06/15/07 WRONG_HISTOGRAM_AND_BOXCHART_PLOTS_WHILE_DATA_HAVE_FACTORS
	//AddReportCurveTables(trOp, nTotalNumData, strDataLabel);
	AddReportCurveTables(trOp, nTotalNumData, strDataLabel, index);
	///end WRONG_HISTOGRAM_AND_BOXCHART_PLOTS_WHILE_DATA_HAVE_FACTORS
	///end NEED_REPORT_PLOTS_IN_RM_ONE_WAY
	
	/// Thomas 03/21/2006 REMOVE_DESCSTATS_NODE_IF_NO_DESCSTATS_OPTION
	if(!trOp.GUI.DescStats.nVal)
		trOp.Calculation.RemoveChild("Statistics");
	/// End REMOVE_DESCSTATS_NODE_IF_NO_DESCSTATS_OPTION
	
	return TRUE;
}

///Arvin 06/15/07 WRONG_HISTOGRAM_AND_BOXCHART_PLOTS_WHILE_DATA_HAVE_FACTORS
uint ANOVAOneWay::GetResultCurveTableID(TreeNode& trOp, int nDataIndex, int nTotalNumData, int nGraphIndex)
{
	//Now, we add mean SD,SE and comp tables and bar table to the node corresponding to last dataset while data has factor,
	//So, we need get total number data to make right IDs for graphs
	int index = nDataIndex;
	int nNumData = GetTotalNumData(trOp);
	if(nNumData > 0)
		index = nNumData - 1;
	
	switch( nGraphIndex )
	{
	case GRAPH_STATS_MEANS_SD_PLOT:
		return make_one_set_ID(IDST_ANOVA_MEAN_SD_WKS_TABLE, index+1);
	case GRAPH_STATS_MEANS_SE_PLOT:
		return make_one_set_ID(IDST_ANOVA_MEAN_SE_WKS_TABLE, index+1);
	case GRAPH_STATS_BAR:
		return make_one_set_ID(IDST_ANOVA_BAR_CHART_WKS_TABLE, index+1);
	case GRAPH_STATS_MEANS_COMP_PLOT:
		//return make_one_set_ID(IDST_ANOVA_MEAN_COMP_WKS_TABLE + index, index+1); ///Arvin 11/16/07 QA70-10676 UPDATE_MEANS_COMPARISION_PLOT_LEGENT_WITH_SIG_INFO
	case GRAPH_STATS_BOX_PLOT:
		return ANOVAReportOperation::GetResultCurveTableID(trOp, nDataIndex, nTotalNumData, nGraphIndex);
	}
	
	return 0;
}
///end 	WRONG_HISTOGRAM_AND_BOXCHART_PLOTS_WHILE_DATA_HAVE_FACTORS

/// YuI 09/26/05 ANOVA_DATA_SELECTION_GUI
// ok for now
/// Hong 09/04/09 QA80-14258 HISTOGRAM_NEED_SPECIAL_HINT_FOR_DOING_NLFITTING
//bool	ANOVAOneWay::InitFromSelection(TreeNode &trOperation)
int		ANOVAOneWay::InitFromSelection(TreeNode &trOperation)
/// end HISTOGRAM_NEED_SPECIAL_HINT_FOR_DOING_NLFITTING
{
	// init from selection is irrelevant for the case of ANOVA
	// this will get reset in anova_switch_to_indexed_data
	// so I will introduce selection resolution code there instead
	return true;
}
/// end ANOVA_DATA_SELECTION_GUI

/// ML 10/25/2005 MUST_CLEAN_UP_CACHED_STUFF
// virtual
void	ANOVAOneWay::OnAfterCalculations(TreeNode& trOp)
{
	ANOVAReportOperation::OnAfterCalculations(trOp);
	
	m_vData.SetSize(0);
	m_vnIndex.SetSize(0);
	m_vsFactors.SetSize(0);
	m_vWeights.SetSize(0);
	m_nFactors=0;
}
/// end MUST_CLEAN_UP_CACHED_STUFF

int		ANOVAOneWay::GetGroupSize(TreeNode& trOp)
{
	TreeNode trInputData = trOp.GUI.InputData;
	if(!trInputData)
		return -1;
	
	int nType = ANOVA_INDEXED_DATA == trInputData.Use? DRTREE_ANOVA_ONE_WAY_INDEXED : DRTREE_ANOVA_ONE_WAY_RAW;
	
	DataRange dr;
	dr.Create();
	dr.SetTree(trInputData, nType);	
	return dr.GetNumData(DRR_NO_WEIGHTS);	
}



BOOL	ANOVAOneWay::addANOVAs(TreeNode &trOp, const int iLevels, const vector<int>& vIndex, 
				ANOVADescStats* pstDescStats, uint nSizeDescStat,
				ANOVAStats& TotalStats, RegANOVA& ANOVATable)
{	
	///Iris 01/03/05 MOVE_CALCULATION_DESC_STATS_FUNC
	/*
	int nRet = stats_anova_one_way(vData, iLevels, vIndex, pstDescStats, nSizeDescStat, TotalStats, &ANOVATable);
	if( 0 != nRet )
	{
		addErrInfoANOVADescStats(trOp, nRet);
		return FALSE;	
	}	
	*/
	///end MOVE_CALCULATION_DESC_STATS_FUNC
	
	addOverallANOVA(trOp, ANOVATable);
	
	addFitStats(trOp, TotalStats);
	
	addMeanComparisonResults(trOp, pstDescStats, ANOVATable, iLevels);
	
	addEqualVariTestResult(trOp, iLevels, vIndex);
	
	addPowersResult(trOp, pstDescStats, nSizeDescStat, ANOVATable);
	
	return TRUE;
	
}	


BOOL	ANOVAOneWay::getInputDataTotalSize(const ANOVADescStats* pstDescStats, int nSizeDescStat, int& nTotalSize)
{
	nTotalSize = 0;
	for(int nCol=0; nCol<nSizeDescStat; nCol++)
	{
		nTotalSize += pstDescStats[nCol].N;
	}
	return TRUE;
}

///Iris 02/16/05 BASE_CALSS_FUNCTION_INSTEAD_ADD_DESCSTAT_TABLE
/*
BOOL	addANOVADescStats(TreeNode &trOp, const ANOVADescStats* pstDescStats, int nSizeDescStat)
{	
	
	TreeNode		trTable = tree_check_get_node(trOp.Calculation, "DescStat", IDST_ANOVA_DESC_STATS, STR_LABEL_ATTRIB, "Descriptive Statistics");
	for(int nRow=0; nRow<nSizeDescStat; nRow++)
	{
		TreeNode		trRow = check_add_enumerated_node(trTable, CALCULATION_PARAMETER_PREFIX, nRow+1, IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, m_vsFactors[nRow]);
				
		trRow += pstDescStats[nRow];
		
		trRow.ID = make_one_set_ID(IDST_ANOVA_DESC_STATS, nSizeDescStat + nRow + 1);
	}
	
	return TRUE;		
}
*/
///End BASE_CALSS_FUNCTION_INSTEAD_ADD_DESCSTAT_TABLE

///Iris 2/16/05 BASE_CALSS_FUNCTION_INSTEAD_ADD_DESCSTAT_TABLE
/*
void    addANOVATableHeaderLabel(TreeNode& trANOVA, LPCSTR lpcszName)
{
	vector<string> vsLabels = {"DF", "Sum of Squares", "Mean Square", "F Value", "P Value"};
	TreeNode trTable = trANOVA.GetNode(lpcszName);
	if(!trTable)
		return;
	
	int 	index = 0;
	foreach(TreeNode tr in trTable.Children)
	{
		tr.SetAttribute(STR_LABEL_ATTRIB, vsLabels[index++]);
	}
	
}
*/
///End BASE_CALSS_FUNCTION_INSTEAD_ADD_DESCSTAT_TABLE
void	ANOVAOneWay::addOneANOVASet(TreeNode &trOneSet, LPCSTR lpcszName, LPCSTR lpcszLabel, int nID, const RegANOVA& ANOVATable, int nANOVARow)
{
	stats_tree_set_one_ANOVA_set(trOneSet, lpcszName, NULL, 0, nID, ANOVATable, nANOVARow, lpcszLabel);
	///Iris 2/16/05 BASE_CALSS_FUNCTION_INSTEAD_ADD_DESCSTAT_TABLE
	//addANOVATableHeaderLabel(trOneSet, lpcszName);
	TreeNode trRow = trOneSet.GetNode(lpcszName);
	if(trRow)
		UpdateOverallANOVAColumnLabel(trRow);
	///End BASE_CALSS_FUNCTION_INSTEAD_ADD_DESCSTAT_TABLE
}

///Jim 3/8/06 v8.0372 ADD_TABLE_FOOTNOTE
void	ANOVAOneWay::addANOVAFootnote(TreeNode &trOneSet)
{
	TreeNode trFooter = tree_check_get_node(trOneSet, "Footnote", IDE_FOOTNOTE_BEGIN, TREE_Footnote, "1"); // just need the TREE_Footnote attribute, value does not matter, so 1 is good
	///Arvin 10/27/07 LOCALIZED_FOOTNOTES_STRINGS
	//trFooter.strVal = _L("Null Hypothesis: The means of all levels are equal\n");
	//trFooter.strVal += _L("Alternative Hypothesis: The means of one or more levels are different\n");
	///end LOCALIZED_FOOTNOTES_STRINGS
	string strSign;
	double dPValue;
	//dPValue = trOneSet.Model.PValue.dVal;
	dPValue = trOneSet.FirstNode.PValue.dVal;	
	//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL 
	//if(dPValue < 0.05)
	double dAlpha = GetAlphaValue();
	if(dPValue < dAlpha )
	//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
	{	
		strSign = _L("significantly");
	}
	else
	{
		strSign = _L("not significantly");
	}
	///Arvin 10/27/07 LOCALIZED_FOOTNOTES_STRINGS
	//trFooter.strVal += _L("At the 0.05 level, the population means are ") + strSign + _L(" different.");
	string strFooter = "Err: Hypothesis msg string not in oErrMsg";
	//------ Folger 12/10/07 CLEAN_NEGATIVE_ERROR_MESSAGES
	//ocu_load_msg_str(FOOTNOTE_ANOVA_HYPOTHESIS, &strFooter, strSign);

	//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL 
	//ocu_load_msg_str(dPValue < 0.05 ? FOOTNOTE_ANOVA_HYPOTHESIS : FOOTNOTE_ANOVA_HYPOTHESIS_NEGATIVE, &strFooter);
	ocu_load_err_msg_str(dPValue < dAlpha? FOOTNOTE_ANOVA_HYPOTHESIS : FOOTNOTE_ANOVA_HYPOTHESIS_NEGATIVE, &strFooter);
	//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
	//------
	//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
	strFooter.Format(strFooter,dAlpha);
	//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
	trFooter.strVal = strFooter;
	///end LOCALIZED_FOOTNOTES_STRINGS
	if(is_missing_value(dPValue))
	{
		///Arvin 10/27/07 LOCALIZED_FOOTNOTES_STRINGS
		//trFooter.strVal += "\n" + _L(STATS_NO_CONCLUSION);
		string strConclusion = "Err: Conclusion string not in oErrMsg";
		ocu_load_msg_str(FOOTNOTE_NO_CONCLUSION, &strConclusion);
		trFooter.strVal += "\n" + strConclusion;
		///end LOCALIZED_FOOTNOTES_STRINGS	
	}
}
///END ADD_TABLE_FOOTNOTE

BOOL	ANOVAOneWay::addOverallANOVA(TreeNode &trOp, RegANOVA&	ANOVATable)
{
	TreeNode	trTable = tree_check_get_node(trOp.Calculation, "ANOVAs", IDST_ANOVAS, STR_LABEL_ATTRIB, _L("One Way ANOVA"));
	
	TreeNode 	trOneSet = tree_check_get_node(trTable, "OvarallANOVA", IDST_ANOVAS_OVERALL, STR_LABEL_ATTRIB, _L("Overall ANOVA"));
	
	addOneANOVASet(trOneSet, "Model", _L("Model"), IDST_ANOVA_Model, ANOVATable, ANOVA_MODEL);
	addOneANOVASet(trOneSet, "Error", _L("Error"), IDST_ANOVA_Error, ANOVATable, ANOVA_ERR);
	addOneANOVASet(trOneSet, "Total", _L("Total"), IDST_ANOVA_Total, ANOVATable, ANOVA_TOTAL);
	addANOVAFootnote(trOneSet);	///Jim 3/8/06 v8.0372 ADD_TABLE_FOOTNOTE
	return TRUE;		
}

void    ANOVAOneWay::addFitStatsTableHeaderLabel(TreeNode &trRow)
{
	/// Hong 10/24/07 v8.0732 LOCALISED_REPORTTREE_ISSUE
	//vector<string> vsLabels = {"R-Square", "Coeff Var", "Root MSE", "Data Mean"};
	vector<string> vsLabels;
	vsLabels.Add(_L("R-Square"));
	vsLabels.Add(_L("Coeff Var"));
	vsLabels.Add(_L("Root MSE"));
	vsLabels.Add(_L("Data Mean"));
	/// end LOCALISED_REPORTTREE_ISSUE
	int index = 0;
	foreach(TreeNode tr in trRow.Children)
		tr.SetAttribute(STR_LABEL_ATTRIB, vsLabels[index++]);
}

BOOL	ANOVAOneWay::addFitStats(TreeNode &trOp, ANOVAStats& TotalStats)
{
	TreeNode	trTable = tree_check_get_node(trOp.Calculation, "ANOVAs", IDST_ANOVAS);
	
	TreeNode 	trOneSet = tree_check_get_node(trTable, "FitStats", IDST_ANOVAS_FIT_STATS, STR_LABEL_ATTRIB, _L("Fit Statistics"));
	
	TreeNode 	trRow = tree_check_get_node(trOneSet, CALCULATION_REPORT_TABLE_ROW_PREFIX, IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, " ");
	
	trRow += TotalStats;
	
	trRow.ID = IDST_ANOVAS_FIT_STATS+1;
	
	tree_set_attribute_to_all_nodes(trRow, STR_COL_DESIGNATION_ATTRIB, (string)OKDATAOBJ_DESIGNATION_Y); ///Sophy 3/30/2009 QA80-13352 SUPPORT_SPECIFY_COLUMN_DESIGNATIONS_IN_REPORT_TABLES
	///Sophy 4/3/2009 QA80-13352 SUPPORT_SPECIFY_COLUMN_DESIGNATIONS_IN_REPORT_TABLES
	if ( trRow.MSESQ )
		trRow.MSESQ.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_ERROR);
	///end SUPPORT_SPECIFY_COLUMN_DESIGNATIONS_IN_REPORT_TABLES
	addFitStatsTableHeaderLabel(trRow);
	return TRUE;		
}


BOOL    ANOVAOneWay::addOneMeanComparisonResult(TreeNode &trOp, int nIntervalType, ANOVADescStats* pstDescStats, RegANOVA& ANOVATable,
					const int iLevels)
{
	
	TreeNode	trGUI = trOp.GUI;
	///Iris 12/28/04 REMOVE_HOW_TO_COMPUTER_BRANCH
	//double		dAlpha = trGUI.CompControl.SigLevel.dVal;
	double		dAlpha = trGUI.MeansComp.SigLevel.dVal;
	
	///Iris 3/22/05 ADD_MORE_MEAN_COMPARISON_CASE
	//int 			nSizeMeanComp = iLevels*(iLevels-1);		
	int 			nSizeMeanComp = (iLevels*(iLevels-1))/2;		
	MeanCompStats*	pstMeanCompstats;		
	pstMeanCompstats = (MeanCompStats*)calloc(nSizeMeanComp, sizeof(MeanCompStats));
	
	string 			strNode;
	string			strLabel;
	int				nIntervalTypeID;
	///Iris 3/22/05 ADD_MORE_MEAN_COMPARISON_CASE
	/*
	switch(nIntervalType)
	{
	case ANOVA_BONFERRON:
		strNode = "Bonferr";
		strLabel = "Bonferroni Test";
		nIntervalTypeID = IDST_ANOVAS_MEAN_COMP_BONFERON;
		break;
	case ANOVA_SCHEFFE:
		strNode = "Scheffe";
		strLabel = "Scheffe Test";
		nIntervalTypeID = IDST_ANOVAS_MEAN_COMP_SCHEFFE;
		break;
	case ANOVA_TUKEY:
		strNode = "Tukey";
		strLabel = "Tukey Test";
		nIntervalTypeID = IDST_ANOVAS_MEAN_COMP_TUKEY;
		break;			
	default:
		return FALSE;
	}	
	*/
	GetMeanCompNodeInfo(strNode, strLabel, nIntervalTypeID, nIntervalType);		
	///end ADD_MORE_MEAN_COMPARISON_CASE
	
	TreeNode	trRoot = tree_check_get_node(trOp.Calculation, "ANOVAs", IDST_ANOVAS);
	
	TreeNode 	trMeanComp = tree_check_get_node(trRoot, "MeanComp", IDST_ANOVAS_MEAN_COMP, STR_LABEL_ATTRIB, _L("Means Comparisons"));
	
	TreeNode 	trTable = tree_check_get_node(trMeanComp, strNode, nIntervalTypeID, STR_LABEL_ATTRIB, strLabel);

	int nRet;
	nRet = stats_anova_mean_comparison(nIntervalType, pstDescStats, &ANOVATable, dAlpha, iLevels, pstMeanCompstats, nSizeMeanComp);
	if(0 != nRet)
	{
		///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
		//addErrInfoMeanComparison(trTable, nIntervalTypeID, nRet);
		AddErrInfoToTable(trTable, nIntervalTypeID, nRet);
		///end CLEAN_ANOVA_TOOLS_CODE
		free(pstMeanCompstats);
		return FALSE;
	}
	
	///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
	/*
	vector<string>	vsCompLabels;
	///Iris 02/16/05 BASE_CALSS_FUNCTION_INSTEAD_ADD_DESCSTAT_TABLE
	//getMeanCompColLabels(m_vsFactors, vsCompLabels);
	GetMeanCompColumnLabels(m_vsFactors, vsCompLabels);
	///End BASE_CALSS_FUNCTION_INSTEAD_ADD_DESCSTAT_TABLE
	
	for(int nRow=0; nRow < nSizeMeanComp; nRow++)
	{
		///Arvin 09/30/07 SHOULD_GET_LABEL_WITH_INDEXCOMP_FOR_BONHOLM_AND_SIDAKHOLM as max said
		//TreeNode trRow = tree_check_get_node(trTable, CALCULATION_REPORT_TABLE_ROW_PREFIX + nRow, IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, vsCompLabels[nRow]);  //Use Row as temp label 
		int nLabelRow = nRow;
		if(nIntervalType == ANOVA_BONHOLM || nIntervalType == ANOVA_SIDAKHOLM)
		{
			nLabelRow = pstMeanCompstats[nRow].IndexComp;	
			if(nLabelRow >= vsCompLabels.GetSize())
				return false;
		}	
		TreeNode trRow = tree_check_get_node(trTable, CALCULATION_REPORT_TABLE_ROW_PREFIX + nRow, IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, vsCompLabels[nLabelRow]);  
		///end SHOULD_GET_LABEL_WITH_INDEXCOMP_FOR_BONHOLM_AND_SIDAKHOLM
		trRow += pstMeanCompstats[nRow];
		//trRow.ID = nIntervalTypeID + nRow + 1;
		trRow.ID = make_one_set_ID(nIntervalTypeID, nRow + 1);
		//--- Iris 11/2/0/06 the node only used to debug, so commented out it
		if(trRow.IndexComp)
			trRow.IndexComp.Show = 0;
		//---
		///Arvin 09/30/07 HIDE_DOF_COL_FOR_MEAN_COMP_TABLE as max said
		if(trRow.DOF)
			trRow.DOF.Show = false;
		///end HIDE_DOF_COL_FOR_MEAN_COMP_TABLE
	}
	
	///Iris 3/22/05 ADD_MORE_MEAN_COMPARISON_CASE
	SetupMeanCompasionTableRows(trTable, nIntervalType);
	UpdateMeanCompasionStatRowName(trTable, nIntervalType);

	free(pstMeanCompstats);
	
		return TRUE;
	*/
	return AddMeanComparisonRows(trOp, trTable, m_vsFactors, pstMeanCompstats, nSizeMeanComp, nIntervalTypeID, nIntervalType);
	///end CLEAN_ANOVA_TOOLS_CODE	
}	

///Jim 3/8/06 v8.0372 ADD_TABLE_FOOTNOTE
///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
/*
bool ANOVAOneWay::addMeanComparisonFootnote(TreeNode &trOp)
{
	TreeNode	trRoot = tree_check_get_node(trOp.Calculation, "ANOVAs", IDST_ANOVAS);
	TreeNode 	trMeanComp = tree_check_get_node(trRoot, "MeanComp", IDST_ANOVAS_MEAN_COMP, STR_LABEL_ATTRIB, "Means Comparisons");
	TreeNode 	trFooter = tree_check_get_node(trMeanComp, "Footnote", IDE_FOOTNOTE_BEGIN, TREE_Footnote, "1"); // just need the TREE_Footnote attribute, value does not matter, so 1 is good
	string strSigLevel;
	///Arvin 07/17/07 v8.0661 WRONG_DOUBLE_PRESION_NUMBER
	//strSigLevel.Format("%f",trOp.GUI.MeansComp.SigLevel.dVal);
	double dSigLevel = trOp.GUI.MeansComp.SigLevel.dVal;
	strSigLevel = ftoa(dSigLevel);
	///end WRONG_DOUBLE_PRESION_NUMBER
	trFooter.strVal = "Sig equals 1 indicates that the means difference is significant at the " + strSigLevel + " level.\n";
	trFooter.strVal += "Sig equals 0 indicates that the means difference is not significant at the " + strSigLevel + " level.";
	return true;
}
*/
///end CLEAN_ANOVA_TOOLS_CODE
///END ADD_TABLE_FOOTNOTE

///Iris 02/16/05 BASE_CALSS_FUNCTION_INSTEAD_ADD_DESCSTAT_TABLE
/*
void		getMeanCompColLabels(const vector<string>& vsFactors, vector<string>& vsCompLabels)
{	
	int iLevels = vsFactors.GetSize();
	for(int ii=0; ii<iLevels; ii++)
		for(int jj=0; jj<iLevels; jj++)
		{
			if(ii == jj) continue;
			string strTemp;
			//strTemp.Format("%d  %d", ii, jj);
			strTemp.Format("%s  %s", vsFactors[ii], vsFactors[jj]);
			vsCompLabels.Add(strTemp);
		}
}	
*/
///End BASE_CALSS_FUNCTION_INSTEAD_ADD_DESCSTAT_TABLE

void	ANOVAOneWay::addMeanComparisonResults(TreeNode &trOp, ANOVADescStats* pstDescStats, RegANOVA& ANOVATable,
					const int iLevels)
{		
	/// Iris 05/10/2007 v8.0615 REMOVE_BRANCH_CHECK_BOX
	//if( !trOp.GUI.MeansComp.Use )
	//{
		//tree_check_set_hidden(trOp.Calculation.ANOVAs.MeanComp, true);
		//return;		
	//}
	///end REMOVE_BRANCH_CHECK_BOX
	
	if(trOp.GUI.MeansComp.Bonferroni.nVal)
		addOneMeanComparisonResult(trOp, ANOVA_BONFERRON, pstDescStats, ANOVATable, iLevels);
	
	if(trOp.GUI.MeansComp.Scheffe.nVal)
		addOneMeanComparisonResult(trOp, ANOVA_SCHEFFE, pstDescStats, ANOVATable, iLevels);
	
	if(trOp.GUI.MeansComp.Tukey.nVal)
		addOneMeanComparisonResult(trOp, ANOVA_TUKEY, pstDescStats, ANOVATable, iLevels);
	
	///Iris 3/22/05 ADD_MORE_MEAN_COMPARISON_CASE
	if(trOp.GUI.MeansComp.DunnSidak.nVal)
		addOneMeanComparisonResult(trOp, ANOVA_SIDAK, pstDescStats, ANOVATable, iLevels);
	
	if(trOp.GUI.MeansComp.FisherLSD.nVal)
		addOneMeanComparisonResult(trOp, ANOVA_FISHER, pstDescStats, ANOVATable, iLevels);
	
	if(trOp.GUI.MeansComp.HolmBonf.nVal)
		addOneMeanComparisonResult(trOp, ANOVA_BONHOLM, pstDescStats, ANOVATable, iLevels);
	
	if(trOp.GUI.MeansComp.HolmSidak.nVal)
		addOneMeanComparisonResult(trOp, ANOVA_SIDAKHOLM, pstDescStats, ANOVATable, iLevels);
	
	if(trOp.GUI.MeansComp.Dunnett && trOp.GUI.MeansComp.Dunnett.Use)
		addOneMeanComparisonResult(trOp, ANOVA_DUNNETT, pstDescStats, ANOVATable, iLevels);
	///end ADD_MORE_MEAN_COMPARISON_CASE

	TreeNode trMeansComp = trOp.Calculation.ANOVAs.MeanComp;
	if( trMeansComp && 0 == trMeansComp.GetNodeCount())
	{
		tree_check_set_hidden(trMeansComp, true);
		
	}
	///Jim 3/10/06 v8.0373 ADD_TABLE_FOOTNOTE
	if(trMeansComp)
		///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
		//addMeanComparisonFootnote(trOp);
		AddMeanComparisonFootnote(trOp);
		///end CLEAN_ANOVA_TOOLS_CODE
	///END ADD_TABLE_FOOTNOTE
}

void	ANOVAOneWay::addOneEqualVariTest(TreeNode &trOp, int nIntervalType, const vector& vData, 
				const int iLevels, const vector<int>& vIndex)
{
	//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL
	double		dAlpha = trOp.GUI.EqualVar.sigVariance.dVal;
	//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
	int					nSizeDescStat = iLevels;
	RegANOVA			ANOVATable;
	ANOVADescStats* 	pstDescStats;
	pstDescStats = (ANOVADescStats*)calloc(nSizeDescStat, sizeof(ANOVADescStats));
	
	int nRet;
	nRet = stats_anova_equal_variance_test(vData, iLevels, vIndex, pstDescStats, nSizeDescStat, &ANOVATable, nIntervalType);
	
	string 			strNode;
	string			strLabel;
	int				nStatsID;
	switch(nIntervalType)
	{
	case ANOVA_LEVENESQ:
		strNode = "LeveneSQ";
		strLabel = _L("Levene's Test(Squared Deviations)");
		nStatsID = IDST_ANOVAS_TEST_EQUAL_VAR_LEVENESQ;
		break;
	case ANOVA_LEVENE:
		strNode = "Levene";
		strLabel = _L("Levene's Test(Absolute Deviations)");
		nStatsID = IDST_ANOVAS_TEST_EQUAL_VAR_LEVENE;
		break;
	case ANOVA_BROWN:
		strNode = "Brown-Forsythe";
		strLabel = _L("Brown-Forsythe Test");
		nStatsID = IDST_ANOVAS_TEST_EQUAL_VAR_BROWN;
		break;
	default:
		return;
	}			
	
	TreeNode	trRoot = tree_check_get_node(trOp.Calculation, "ANOVAs", IDST_ANOVAS);
	
	TreeNode 	trEqualVari = tree_check_get_node(trRoot, "EqualVari", IDST_ANOVAS_TEST_EQUAL_VAR, STR_LABEL_ATTRIB, _L("Homogeneity of Variance Test"));
	
	TreeNode 	trTable = tree_check_get_node(trEqualVari, strNode, nStatsID, STR_LABEL_ATTRIB, strLabel);
	
	if(0 != nRet)
	{
		///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
		//addErrInfoEqualVariTest(trTable, nStatsID, nRet);
		AddErrInfoToTable(trTable, nStatsID, nRet);
		///end CLEAN_ANOVA_TOOLS_CODE
	}
	else			
	{
		addOneANOVASet(trTable, "Model", _L("Model"), IDST_ANOVA_Model, ANOVATable, ANOVA_MODEL);
		addOneANOVASet(trTable, "Error", _L("Error"), IDST_ANOVA_Error, ANOVATable, ANOVA_ERR);
	}
	
	///Jim 3/8/06 v8.0372 ADD_TABLE_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 strSign;
	double dPValue;
	//---- Iris 01/26/2007
	//dPValue = trTable.Model.PValue.dVal;
	TreeNode	trModel = trTable.FirstNode;	
	if(trModel)
	{
		dPValue = trModel.PValue.dVal;
	}
	else
		error_report("Fail to find Model node in addOneEqualVariTest");
	//----
	//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL 
	//if(dPValue < 0.05)]
	if(dPValue < dAlpha )
	//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
	{	
		strSign = _L("significantly");
	}
	else
	{
		strSign = _L("not significantly");
	}
	///Arvin 10/27/07 LOCALIZED_FOOTNOTES_STRINGS
	//trFooter.strVal = _L("At the 0.05 level, the population variations are ") + strSign + _L(" different.");
	string strFooter = "Err: Population variation string not in oErrMsg";
	//ocu_load_msg_str(FOOTNOTE_ANOVA_POPULATION_VARIATIONS, &strFooter, strSign);
	//------ Folger 12/10/07 CLEAN_NEGATIVE_ERROR_MESSAGES
	//ocu_load_msg_str(FOOTNOTE_ANOVA_POPULATION_VARIANCES, &strFooter, strSign);
	//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL 
	//ocu_load_msg_str(dPValue < 0.05 ? FOOTNOTE_ANOVA_POPULATION_VARIANCES : FOOTNOTE_ANOVA_POPULATION_VARIANCES_NEGATIVE, &strFooter);
	ocu_load_err_msg_str(dPValue < dAlpha ? FOOTNOTE_ANOVA_POPULATION_VARIANCES : FOOTNOTE_ANOVA_POPULATION_VARIANCES_NEGATIVE, &strFooter);
	strFooter.Format(strFooter,dAlpha);
	//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
	//------
	trFooter.strVal = strFooter; 
	///END ADD_TABLE_FOOTNOTE
	
	if(is_missing_value(dPValue))
	{
		///Arvin 10/27/07 LOCALIZED_FOOTNOTES_STRINGS
		//trFooter.strVal += "\n" + _L(STATS_NO_CONCLUSION);
		string strConclusion = "Err: Conclusion string not in oErrMsg";
		ocu_load_msg_str(FOOTNOTE_NO_CONCLUSION, &strConclusion);
		trFooter.strVal += "\n" + strConclusion;
		///end LOCALIZED_FOOTNOTES_STRINGS
	}
	
	free(pstDescStats);
}

void 	ANOVAOneWay::addEqualVariTestResult(TreeNode &trOp, const int iLevels, const vector<int>& vIndex)
{
	/// Iris 05/10/2007 v8.0615 REMOVE_BRANCH_CHECK_BOX
	/*
	if( !trOp.GUI.EqualVar.Use )
	{
		tree_check_set_hidden(trOp.Calculation.ANOVAs.EqualVari, true);
		return;
	}
	*/
	///end REMOVE_BRANCH_CHECK_BOX
	
	if(0 != trOp.GUI.EqualVar.Levene.nVal)
		addOneEqualVariTest(trOp, ANOVA_LEVENE, m_vData, iLevels, vIndex);
	
	if(0 != trOp.GUI.EqualVar.Levene2.nVal)
		addOneEqualVariTest(trOp, ANOVA_LEVENESQ, m_vData, iLevels, vIndex);
	
	if(0 != trOp.GUI.EqualVar.BrownForsythe.nVal)
		addOneEqualVariTest(trOp, ANOVA_BROWN, m_vData, iLevels, vIndex);
		
	///Jim 3/10/06 v8.0373 EQUALVARI_SUBBRANCH_NOT_CHECK_RUNTIME_ERROR
	//if(0 == trOp.Calculation.ANOVAs.EqualVari.GetNodeCount())  //==> This cause runtime error
		//tree_check_set_hidden(trOp.Calculation.ANOVAs.EqualVari, true);
	TreeNode trEqualVari = trOp.Calculation.ANOVAs.EqualVari;
	if( trEqualVari && 0 == trEqualVari.GetNodeCount())
		tree_check_set_hidden(trEqualVari, true);
	///END 	EQUALVARI_SUBBRANCH_NOT_CHECK_RUNTIME_ERROR
}
void    ANOVAOneWay::addPowersResult(TreeNode& trOp, ANOVADescStats* pstDescStats, int nSizeDescStat, RegANOVA ANOVATable)
{
	/// Iris 05/10/2007 v8.0615 REMOVE_BRANCH_CHECK_BOX
	/*
	if( !trOp.GUI.PowerBranch.Use )
	{
		tree_check_set_hidden(trOp.Calculation.ANOVAs.Powers, true);
		return;
	}
	*/
	///end REMOVE_BRANCH_CHECK_BOX
	
	///Iris 12/28/04 REMOVE_HOW_TO_COMPUTER_BRANCH
	//if(0 != trOp.GUI.QuanComp.PowerBranch.ActPower.nVal)
	//{
	///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
	/*
	if( trOp.GUI.PowerBranch.ActualPower.nVal ) /// Iris 05/10/2007 v8.0615 REMOVE_BRANCH_CHECK_BOX
	{
		if( !addPowers(trOp, true, pstDescStats, nSizeDescStat, ANOVATable))
			return;
	}
	//}
	
	///Iris 12/28/04 REMOVE_HOW_TO_COMPUTER_BRANCH
	//if(0 != trOp.GUI.QuanComp.PowerBranch.CalcHypotPower.nVal)
	if( trOp.GUI.PowerBranch.HypotPower.nVal )
	{
		if( !addPowers(trOp, false, pstDescStats, nSizeDescStat, ANOVATable))
			return;
	}
	*/
	int iPower = GetPowerInfo(trOp);
	if(iPower <= 0)
		return;
	
	if( !updateOnePowerTable(trOp, iPower, pstDescStats, nSizeDescStat, ANOVATable))
			return;
	///end CLEAN_ANOVA_TOOLS_CODE
	
}
///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
//bool	ANOVAOneWay::addPowers(TreeNode& trOp, bool bIsAtucalPower, ANOVADescStats* pstDescStats, 
//			int nSizeDescStat, RegANOVA ANOVATable)
bool	ANOVAOneWay::updateOnePowerTable(TreeNode& trOp, int iPower, ANOVADescStats* pstDescStats, 
			int nSizeDescStat, RegANOVA ANOVATable)
///end CLEAN_ANOVA_TOOLS_CODE
{
	vector	vSampleSizes;
	vector  vPowers;
	///Iris 12/28/04 REMOVE_HOW_TO_COMPUTER_BRANCH
	//double  dSigLevel = trOp.GUI.CompControl.SigLevel.dVal;
	double  dSigLevel = trOp.GUI.PowerBranch.SigLevel.dVal;
	int		nTotalSize;
	getInputDataTotalSize(pstDescStats, nSizeDescStat,nTotalSize );
	
	string strNodeName = "Powers";
	string strTableLabel = _L("Powers");
	int		nID = IDST_ANOVAS_POWER_TABLE;
	///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
	/*
	if(bIsAtucalPower)
	{
		vSampleSizes.SetSize(1);
		vSampleSizes = nTotalSize;
		nID = IDST_ANOVAS_ACT_POWER;
	}
	else
	{
		///Iris 12/28/04 REMOVE_HOW_TO_COMPUTER_BRANCH
		//string 	strSamples = trOp.GUI.CompControl.HypotSizes.strVal;
		string 	strSamples = trOp.GUI.PowerBranch.HypotSizes.strVal;
		strSamples.GetTokens(vSampleSizes, ' ');			
		nID = IDST_ANOVAS_HYPOTPOWER;
	}
	vPowers.SetSize(vSampleSizes.GetSize());
	*/
	GetSampleSizeByPowerType(trOp, iPower, nTotalSize, vSampleSizes);
	///end CLEAN_ANOVA_TOOLS_CODE
	int 	nRet = stats_anova_powers(dSigLevel, vSampleSizes, &ANOVATable, vPowers);
	///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
	if(0 != nRet)
	{
		//As Echo said, set powers as missing values
    	vPowers.SetSize(vSampleSizes.GetSize());
    	vPowers = NANUM;
	}
	///end CLEAN_ANOVA_TOOLS_CODE
	///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
	//PowerResults*	pstPowers;
	//pstPowers = (PowerResults*)calloc(vPowers.GetSize(), sizeof(PowerResults));	
	//stats_power_output(vPowers, vSampleSizes, dSigLevel, pstPowers, vPowers.GetSize());
	///end CLEAN_ANOVA_TOOLS_CODE
	
	TreeNode		trTable = tree_check_get_node(trOp.Calculation.ANOVAs, strNodeName, nID, STR_LABEL_ATTRIB, strTableLabel);
	///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
	//if(0 != nRet)
	//{
	//	///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
	//	//addErrInfoPowers(trTable, nID, nRet);
	//	AddErrInfoToTable(trTable, nID, nRet);
	//	///end CLEAN_ANOVA_TOOLS_CODE
	//	free(pstPowers);
	//	return false;
	//}
	///end CLEAN_ANOVA_TOOLS_CODE
	///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
	/*
	int 	nRow;
	string 	strLabel;
	if(bIsAtucalPower)
	{
		nRow = 0;
		strLabel = "Actual Power";
	}
	else
	{
		nRow = 1;
		strLabel = "Hypot Powers";
	}
	for(int ii=0; ii<vPowers.GetSize(); ii++, nRow++)
	{
		TreeNode	trRow = tree_check_get_node(trTable, CALCULATION_REPORT_TABLE_ROW_PREFIX + nRow, IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, strLabel);
		trRow += pstPowers[ii];
		trRow.ID = make_one_set_ID( nID, nRow+1);
		//----Iris 11/01/06 v8.0502d NO_COL_LABEL_IN_POWER_TABLE
		trRow.Alpha.SetAttribute(STR_LABEL_ATTRIB, "Alpha");
		trRow.SampleSize.SetAttribute(STR_LABEL_ATTRIB, "Sample Size");
		trRow.Power.SetAttribute(STR_LABEL_ATTRIB, "Power");
		//----
	}
	free(pstPowers);
	*/
	AddPowerTableRows(trTable, vPowers, vSampleSizes, dSigLevel, iPower, nID, nRet);
	///end CLEAN_ANOVA_TOOLS_CODE
	return true;
}

/*
bool 	addMeansPlot(TreeNode& trOp, int index, const vector& vData, const vector<string> &vstrFactors, int nGraphIndex)
{
	ReportCreateGraphHelper crtGraph(CREATE_GRAPH_PREPARE_TREE, trOp, index, nGraphIndex, m_vsFactors[0], &vstrFactors); 
	bool bCreateGraph = crtGraph.IsCreate();
	
	if(bCreateGraph)
	{
		if(!crtGraph.AddGraphToTreeNode())
			return false;
	}	
	return true;
}	
*/

/// Iris 05/21/2007 v8.0622 NEED_REPORT_PLOTS_IN_RM_ONE_WAY
/*
bool 	ANOVAOneWay::getDescStatsValues(TreeNode& trOp, vector& vMeans, vector& vSD, vector& vSE)
{
	TreeNode 	trDescStats = trOp.Calculation.GetNode(TABLE_DESC_STATS);
	if(!trDescStats)
	{
		return error_report("fail to get Statistics node in getDescStatsValues");
	}
	
	foreach(TreeNode trN in trDescStats.Children)
	{
		TreeNode 	tr;
		tr = tree_get_node_by_id(trN, IDE_MEAN, true);
		if( tr && vMeans)
			vMeans.Add(tr.dVal);
		
		tr = tree_get_node_by_id(trN, IDE_SD, true);
		if( tr && vSD)
			vSD.Add(tr.dVal);
		
		tr = tree_get_node_by_id(trN, IDE_SEM, true);
		if( tr && vSE)
			vSE.Add(tr.dVal);		
	}	
		
	return true;
}


void 	ANOVAOneWay::addMeansWksTable(TreeNode& trOp, int nGraphIndex, string strTable, int nID, const vector<string>& vsNames, const vector<string>& vsLabels, bool bIsSD)
{
	string strName = "Mean" + nGraphIndex;
	TreeNode	trTable = CheckCreateOneResultCurvesTable(trOp, 0, -1, nGraphIndex, strName, nID, strTable);
	
	bool  bCreateGraph = IsCreateReportGraph(trOp, nGraphIndex);
	tree_check_set_hidden(trTable, bCreateGraph? false:true);
	
	addNodeToMeanWksTable(trTable, vsNames, vsLabels, nID);	
	
	//vector<int> vnIndex;
	vector		vMeans;
	vector		vSD, vSE;
	if( !GetDescStatsValues(trOp, vMeans, vSD, vSE) )
	{
		error_report("GetDescStatsValues returns false in addMeansWksTable");
		return;
	}
	//vnIndex.Data(1, vMeans.GetSize(), 1);
	
	TreeNode trIndex = trTable.GetNode(vsNames[0]);
	if(trIndex) 	
	{
		//trIndex.nVals = vnIndex;
		trIndex.strVals = m_vsFactors;
		trIndex.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_X);
		trIndex.SetAttribute(STR_COL_FORAMT_ATTRIB, OKCOLTYPE_TEXT);
	}
		
	TreeNode trMean = trTable.GetNode(vsNames[1]);
	if(trMean)	
	{
		trMean.dVals = vMeans;
		trMean.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);
	}
	TreeNode trSTD = trTable.GetNode(vsNames[2]);
	if(trSTD)
	{
		trSTD.dVals = bIsSD? vSD : vSE;		
		trSTD.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_ERROR);
	}	
	
}


	

void 	ANOVAOneWay::addMeansSDWksTable(TreeNode& trOp)
{			
	vector<string> vsNames = {"Index", "Mean", "SD"};	
	addMeansWksTable(trOp, GRAPH_STATS_MEANS_SD_PLOT, "Mean SD Plot", IDST_ANOVA_MEAN_SD_WKS_TABLE, vsNames, vsNames);	
}

void	ANOVAOneWay::addMeansSEWksTable(TreeNode& trOp)
{	
	vector<string> vsNames = {"Index", "Mean", "SEM"};		
	addMeansWksTable(trOp, GRAPH_STATS_MEANS_SE_PLOT, "Mean SEM Plot", IDST_ANOVA_MEAN_SE_WKS_TABLE, vsNames, vsNames, false);		
}

void	ANOVAOneWay::addMeansDiffWksTable(TreeNode& trOp)
{
	int index=0;
	for(int iType = ANOVA_TUKEY; iType<ANOVA_LAST_ITEM; iType++)
	{
		if(addOneMeansDiffWksTable(trOp, iType, index))
			index++;
	}	
}
	
int		ANOVAOneWay::getMeanDiffTableNumber(TreeNode& trOp)
{
	int nNum = 0;
	TreeNode trMeanDiff = trOp.GUI.MeansComp;
	foreach(TreeNode trN in trMeanDiff.Children)
	{
		if(trN.ID == TRGP_CHECK || trN.ID == TRGP_BRANCH) //node is check box or branch
		{
			string str;
			if(trN.GetAttribute(STR_USE_ATTRIB, str))
				nNum += trN.Use;
			else
				nNum += trN.nVal;
		}
	}
	
	return nNum;
	
}
	
bool	ANOVAOneWay::addOneMeansDiffWksTable(TreeNode& trOp, int iType, int index)
{
	//get the values from the result table of mean comparison
	int 	nID;
	string 	strName, strLabel;
	GetMeanCompNodeInfo(strName, strLabel, nID, iType);	
	
	TreeNode 	trResult = tree_get_node_by_id(trOp.Calculation.ANOVAs.MeanComp, nID, true);	
	if(!trResult)
		return false;
	
	//vector<int> vnIndex;
	vector 		vMeanDiff, vSEM, vSig;
	foreach(TreeNode trN in trResult.Children)
	{
		TreeNode 	tr;
		tr = trN.MeanDiff;
		if(tr)
			vMeanDiff.Add(tr.dVal);
		
		tr = trN.SEM;
		if(tr)
			vSEM.Add(tr.dVal);	
			
		tr = trN.Sig;
		if(tr)
			vSig.Add(tr.dVal);
	}
	if(0 == vMeanDiff.GetSize() || 0 == vSEM.GetSize() || 0 == vSig.GetSize())
		return false;
	//vnIndex.Data(1, vMeanDiff.GetSize(), 1);
	
	
	// construct report data table of mean compasion 
	int nGraphIndex = GRAPH_STATS_MEANS_COMP_PLOT;
	int nTableID = IDST_ANOVA_MEAN_COMP_WKS_TABLE + index;
	string 		strTableLabel = "Mean Diff for " + strLabel;
	TreeNode	trTable = CheckCreateOneResultCurvesTable(trOp, index, -1, nGraphIndex, strName, nTableID, strTableLabel);	
	if(!trTable)
	{
		trTable = CheckCreateOneResultCurvesTable(trOp, index, -1, nGraphIndex, strName, nTableID, strTableLabel, "temp");
	}
	if(!trTable)
		return false;
	
	vector<string> vsNames = {"Index", "MeanDiff", "SEM", "Sig"};
	addNodeToMeanWksTable(trTable, vsNames, vsNames, nTableID);	

	
	//set value for each node in the report data table of mean compasion
	TreeNode 		trNode;
	vector<string> 	vsIndex;
	GetMeanCompColumnLabels(m_vsFactors, vsIndex);
	trNode = trTable.GetNode(vsNames[0]);
	if(trNode) 	
	{
		//trNode.nVals = vnIndex;
		//trNode.strVals = m_vsFactors;
		trNode.strVals = vsIndex;
		trNode.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_X);
		trNode.SetAttribute(STR_COL_FORAMT_ATTRIB, OKCOLTYPE_TEXT);
	}
		
	trNode = trTable.GetNode(vsNames[1]);
	if(trNode)	
	{
		trNode.dVals = vMeanDiff;
		trNode.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);
	}	
	
	trNode = trTable.GetNode(vsNames[2]);
	if(trNode)	
	{
		trNode.dVals = vSEM;
		trNode.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_ERROR);
	}
	
	trNode = trTable.GetNode(vsNames[3]);
	if(trNode)	
	{
		trNode.dVals = vSig;
		trNode.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_NONE);
	}	return true;
}

	

void 	ANOVAOneWay::addNodeToMeanWksTable(TreeNode& trTable, vector<string> vsNames, vector<string> vsLabels, int nBaseID)
{		
	for(int index=0; index<vsNames.GetSize(); index++)
	{
		tree_check_get_node(trTable, vsNames[index], make_one_set_ID(nBaseID, index+1), STR_LABEL_ATTRIB, vsLabels[index]);
	}
}
*/
///end NEED_REPORT_PLOTS_IN_RM_ONE_WAY
///end CLEANP_UP_GRAPH_CODES

///Arvin 08/09/07 QA70-7100 ADD_ERROR_MESSAGE
///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
/*
static string _get_error_msg(int nErr)
{
	string strErr;
	strErr = "Error(" + ftoa(nErr)+ "): One-Way ANOVA computational error.";
	return strErr;
}
///end ADD_ERROR_MESSAGE

void 	ANOVAOneWay::addErrorRowToTable(TreeNode& trTable, string strError, int nID)
{
	TreeNode    trRow = tree_check_get_node(trTable, "Error", nID, STR_LABEL_ATTRIB, "Attention!");
	trRow.strVal = strError;
}	

void 	ANOVAOneWay::addErrInfoANOVA(TreeNode& trOp, int nErr)
{
	TreeNode	trTable = tree_check_get_node(trOp.Calculation, "DescStat", IDST_ANOVA_DESC_STATS, STR_LABEL_ATTRIB, "Descriptive Statistics");
	string 		strError; //need wait Echo add related error info
	///Arvin 08/09/07 QA70-7100 ADD_ERROR_MESSAGE
	strError = _get_error_msg(nErr);
	///end ADD_ERROR_MESSAGE
	addErrorRowToTable(trTable, strError, IDST_ANOVA_DESC_STATS);
}

void 	ANOVAOneWay::addErrInfoMeanComparison(TreeNode& trTable, int nID, int nErr)
{
	string 		strError; //need wait Echo add related error info
	///Arvin 08/09/07 QA70-7100 ADD_ERROR_MESSAGE
	strError = _get_error_msg(nErr);
	///end ADD_ERROR_MESSAGE
	addErrorRowToTable(trTable, strError, nID);
}		

void 	ANOVAOneWay::addErrInfoEqualVariTest(TreeNode& trTable, int nID, int nErr)
{
	string 		strError; //need wait Echo add related error info
	///Arvin 08/09/07 QA70-7100 ADD_ERROR_MESSAGE
	strError = _get_error_msg(nErr);
	///end ADD_ERROR_MESSAGE
	addErrorRowToTable(trTable, strError, nID);
}

void   	ANOVAOneWay::addErrInfoPowers(TreeNode& trTable, int nID, int nErr)
{
	string 		strError; //need wait Echo add related error info
	///Arvin 08/09/07 QA70-7100 ADD_ERROR_MESSAGE
	strError = _get_error_msg(nErr);
	///end ADD_ERROR_MESSAGE
	addErrorRowToTable(trTable, strError, nID);
}
*/
///end CLEAN_ANOVA_TOOLS_CODE
bool	ANOVAOneWay::addReportTables(TreeNode &trOp, int nTotalNumData, vector &vWeights)
{	
	// define and initialize variables
	ANOVADescStats*		pstDescStats;
	ANOVAStats 			TotalStats;
	RegANOVA			ANOVATable;
	
	int	nSizeDescStat = nTotalNumData;
	pstDescStats = (ANOVADescStats*)calloc(nSizeDescStat, sizeof(ANOVADescStats));
	int nRet = stats_anova_one_way(m_vData, nTotalNumData, m_vnIndex, pstDescStats, nSizeDescStat, TotalStats, &ANOVATable);
	if( 0 != nRet )
	{
		///Arvin 10/17/07 CLEAN_ANOVA_TOOLS_CODE
		//addErrInfoANOVA(trOp, nRet);
		TreeNode	trTable = tree_check_get_node(trOp.Calculation, "DescStat", IDST_ANOVA_DESC_STATS, STR_LABEL_ATTRIB, _L("Descriptive Statistics"));
		AddErrInfoToTable(trTable, IDST_ANOVA_DESC_STATS, nRet);
		///end CLEAN_ANOVA_TOOLS_CODE
		free(pstDescStats);
		return false;	
	}	
	
	// add ANOVA table
	addANOVAs(trOp, nTotalNumData, m_vnIndex, pstDescStats, nSizeDescStat, TotalStats, ANOVATable);	

	free(pstDescStats);
	return true;
}

///Cheney 2007-10-25 ANOVA_TOOLS_HANDLE_AUTO_WRONG
//virtual
bool		ANOVAOneWay::GetAnovaToolsOption(bool bRow, int& nOption)
{
	nOption = bRow? DRTREE_ANOVA_ONE_WAY_RAW : DRTREE_ANOVA_ONE_WAY_INDEXED;
	return true;
}
///end ANOVA_TOOLS_HANDLE_AUTO_WRONG
//--- Jacky 07/22/10 ORG-102 USER_CAN_SET_SIGNIFICANCE_LEVEL 	
double		ANOVAOneWay::GetAlphaValue()
{
	Tree trOperation;
	GetTree(trOperation);
	double dAlpha = trOperation.GUI.alpha ? trOperation.GUI.alpha.dVal : 0.05;
	return dAlpha;
}
//--- end USER_CAN_SET_SIGNIFICANCE_LEVEL
///Cheney 2007-9-28 MODIFY_TITLE_AS_MAX_SAID
string		ANOVAOneWay::GetDlgDescription(int nOption)
{
	return _L("Perform One-Way ANOVA");
}
///end MODIFY_TITLE_AS_MAX_SAID

/// Iris 05/21/2007 v8.0622 NEED_REPORT_PLOTS_IN_RM_ONE_WAY
/*
void	ANOVAOneWay::addReportDataTablesAndGraphNodes(TreeNode &trOp, int nTotalNumData, string strLabel)
{	
	//add curve data tables
	addBarDataTable(trOp);
	addMeansSDWksTable(trOp);
	addMeansSEWksTable(trOp);
	addMeansDiffWksTable(trOp);
	
	for( int nGraphIndex=0; nGraphIndex<GetNumGraphs(); nGraphIndex++)
	{
		/// Iris 01/08/2007 v8.0538 REPORT_GRAPHS_ARRANGEMENT		
		//int ii;
		//switch(nGraphIndex)
		//{
		//case GRAPH_STATS_BOX_PLOT:
			//for(ii=0; ii<nTotalNumData; ii++)
				//PrepareGraphNodes(trOp, nGraphs, ii, m_vsFactors[ii], nGraphIndex);
			//break;
			//
		//case GRAPH_STATS_MEANS_COMP_PLOT:
			//for(ii=0; ii<getMeanDiffTableNumber(trOp); ii++)
				//PrepareGraphNodes(trOp, nGraphs, ii, strLabel, nGraphIndex);
			//break;
			//
		//default:	
			//PrepareGraphNodes(trOp, nGraphs, 0, strLabel, nGraphIndex);
			//break;
		//}		
		///end REPORT_GRAPHS_ARRANGEMENT
	}
}

/// Iris 01/08/2007 v8.0538 REPORT_GRAPHS_ARRANGEMENT
//virtual 
string ANOVAOneWay::GetReportGraphLabel(TreeNode& trOp, int nGraphIndex, int nPicRow, int nPicCol)
{
	string 	strLabel;
	int		nPicIndex = nPicRow * GetReportGraphTableColNum(trOp) + nPicCol;
	if(GRAPH_STATS_BOX_PLOT == nGraphIndex)
	{
		DataRange dr;
		GetInput(dr);
		if(dr)
		{
			vector<string> vstrFactors;
			if( 0 <= dr.GetData(GetDataRules(trOp), nPicIndex, NULL, NULL, NULL, NULL, NULL, &vstrFactors) )
				strLabel = vstrFactors[0];
		}			
	}
	
	if(GRAPH_STATS_MEANS_COMP_PLOT == nGraphIndex)
	{
		int ii = 0;
		foreach(TreeNode trN in trOp.GUI.MeansComp.Children)
		{
			if( TRGP_BRANCH == trN.ID || TRGP_CHECK == trN.ID)
			{				
				int 	nCheck;
				if( !trN.GetAttribute(STR_USE_ATTRIB, nCheck) )
					nCheck = trN.nVal;
				if(nCheck)
				{
					if(ii == nPicIndex)
					{
						trN.GetAttribute(STR_LABEL_ATTRIB, strLabel);
						break;
					}
					ii++;
				}
			}			
		}
		
	}	
	return strLabel;
}
///end REPORT_GRAPHS_ARRANGEMENT


void 	ANOVAOneWay::addBarDataTable(TreeNode& trOp)
{	
	int nGraphIndex = GRAPH_STATS_BAR;
	TreeNode trTable = CheckCreateOneResultCurvesTable(trOp, 0, -1, nGraphIndex, "BarChart", IDST_ANOVA_BAR_CHART_WKS_TABLE, STAT_BAR_REPORT_LABEL);
	
	vector vIndex;
	vector vMeans;
	if( !getDescStatsValues(trOp, vMeans) )
		return;	
	vIndex.Data(1, vMeans.GetSize(), 1);
	
	//add index column
	TreeNode trIndex = tree_check_get_node(trTable, "X", make_one_set_ID(IDST_ANOVA_BAR_CHART_WKS_TABLE, 1), STR_LABEL_ATTRIB, "Index"); 
	trIndex.dVals = vIndex;
	trIndex.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_X);
	
	//add mean data
	TreeNode trMeans = tree_check_get_node(trTable, "Y", make_one_set_ID(IDST_ANOVA_BAR_CHART_WKS_TABLE, 2), STR_LABEL_ATTRIB, "Mean"); 
	trMeans.dVals = vMeans;
	trMeans.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);

}
*/
///end NEED_REPORT_PLOTS_IN_RM_ONE_WAY
