#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
//put additional include files here
#include <..\originlab\grobj_utils.h>
#include <..\Originlab\GraphObjTools.h>
#include <o8dlg.h>
/*------------------------------------------------------------------------------*
 * Modification Log:															*
 *	Folger 09/24/08 SHOULD_NOT_OUTPUT_UNNECESSARY_RESULTS						*
 *	YuI 10/09/08 QA70-12265-P3 CURVE_STATS_QUICK_TOOL_MUST_BE_SMARTER			*
 *	CPY 11/02/08 QA70-12504 BETTER_DATAPLOT_NAME_DISPLAY						*
 *	Sophy 8/21/2009 QA80-14175 CREATE_ALL_NODES_IN_ONE_TREE_TO_GET_RID_OF_OPTIONS_BRANCH
 *	Sophy 1/23/2010 MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL					*
 *	Sophy 2/8/2010 ROI_STATS_CURVE_NEED_TO_DELAY_HANDLE_SCALE_CHANGE			*
 *	Sophy 2/11/2010 CURVE_STATS_SHOULD_GET_DATA_BY_INDEX_AS_OTHER_ROI_TOOLS		*
 *	Sophy 4/9/2010 QA81-15290 QUICK_STATS_SHOW_PREVIEW_LINE_LABELS				*
 *	Sophy 4/14/2010 BACKWORD_COMPATIBILITY_SUPPORT_FOR_GADGET_ATTACHMENTS		*
 *------------------------------------------------------------------------------*/
//put your own support static functions here

#define XF_NAME		"addtool_curve_stats"
#define	TOOLNAME	_L("Gadget Curve Stats")
#define	TOOL_PREFERENCES_TITLE	_L("Statistics")

///Sophy 1/13/2010 CLEAN_ROI_TOOLS
enum {
	CST_OBJ_FIRST = GOT_OBJ_TOTAL,
	CST_OBJ_RESULT,
	///Sophy 1/26/2010 MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	CST_OBJ_MEAN_LINE,
	CST_OBJ_SD_LINE1,
	CST_OBJ_SD_LINE2,
	///end MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	///Sophy 4/9/2010 QA81-15290 QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
	CST_OBJ_MEAN_LABEL,
	CST_OBJ_SD_LABEL1,
	CST_OBJ_SD_LABEL2,
	///end QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
};
///end CLEAN_ROI_TOOLS

///Sophy 1/19/2010 SHOW_TOOLNAME_FOR_ROI_TOOLS
#define	NEW_ID_BEGIN	(GET_USER_DATAID(0) + 100)
enum STATS_NEW_NODE_ID{
	STATS_TOOLNAME_ID	= NEW_ID_BEGIN,
	STATS_CLONE_OBJS_ID,
};
///end SHOW_TOOLNAME_FOR_ROI_TOOLS

///Sophy 1/23/2010 MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
static	int*	_get_xf_treenode_evt_handle_state()
{
	static int nUpdated = 0;
	return &nUpdated;
}

static	bool	_check_appwks_event(TreeNode& tr, int nRow, int nType, Dialog& Dlg)
{
	TreeNode trGUI = tr.trGUI;
	if ( !trGUI )
		trGUI = tr;
	
	trGUI.output.wksName.Show = trGUI.output.appendwks.nVal == 1;
	return true;
}
///end MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL

///Sophy 2/12/2010 MORE_CLEAN_CODE_TO_RESET_LABEL_POSITION
//static bool g_sbFirstTime = true; //this variable is true only when the ROI is created.
///end MORE_CLEAN_CODE_TO_RESET_LABEL_POSITION

class StatsCurveTool : public GraphObjCurveTool
{
public:
	StatsCurveTool(LPCSTR lpcszMainObjName = NULL):GraphObjCurveTool(lpcszMainObjName)
	{
		m_vnObjIDs.Add(CST_OBJ_RESULT);
		m_vsObjNames.Add("Result");
		
		///Sophy 1/26/2010 MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
		m_vnObjIDs.Add(CST_OBJ_MEAN_LINE);
		m_vsObjNames.Add("MeanLine");
		
		m_vnObjIDs.Add(CST_OBJ_SD_LINE1);
		m_vsObjNames.Add("nSDLineUpper");
		m_vnObjIDs.Add(CST_OBJ_SD_LINE2);
		m_vsObjNames.Add("nSDLineLower");
		///end MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
		///Sophy 4/9/2010 QA81-15290 QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
		m_vnObjIDs.Add(CST_OBJ_MEAN_LABEL);
		m_vsObjNames.Add("MeanLabel");
		
		m_vnObjIDs.Add(CST_OBJ_SD_LABEL1);
		m_vsObjNames.Add("nSDLabelUpper");
		
		m_vnObjIDs.Add(CST_OBJ_SD_LABEL2);
		m_vsObjNames.Add("nSDLabelLower");
		///end QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
	}
	
	//virtaul
	string GetSignature()
	{
		return "xf_addtool_curve_stats";
	}
	
	///Sophy 1/13/2010 CLEAN_ROI_TOOLS
	////virtual
	//BOOL Init()
	//{
		//if(!GraphObjCurveTool::Init())
			//return false;
		//
		//if ( CreateAttachment(GROBJ_TN_TEXT, CTP_RIGHT_BOTTOM, &m_goResult) < 0 )
			//return false;
		//return true;
	//}
	///end CLEAN_ROI_TOOLS	
protected:
	
	//virtual
	double	GetVersion()
	{
		return 8.103;
	}
	
	///Sophy 1/25/2010 SHOW_WARNING_ON_NOT_GETTTING_ENOUGH_DATA_POINTS
	//virtual
	int		GetPointsLimit(){ return 1; }
	///end SHOW_WARNING_ON_NOT_GETTTING_ENOUGH_DATA_POINTS

	///Sophy 1/26/2010 ADD_GO_TO_REPORT_TABLE_MENU_IN_CONTEXT
	//virtual
	BOOL	GetReportWorksheet(Worksheet& wksReport)
	{
		Tree trGUI;
		if ( !GetGUITree(trGUI) || trGUI.output.appendwks.nVal != 1 )
			return FALSE;
		string strWorksheet = trGUI.output.wksName.strVal;
		wksReport.Attach(strWorksheet);
		return wksReport.IsValid();
	}
	///end ADD_GO_TO_REPORT_TABLE_MENU_IN_CONTEXT
	
	///Sophy 1/26/2010 QA80-14832 SHOW_TOOLNAME_FOR_ROI_TOOLS
	//virtual
	TreeNode	GetFillColorNode(const TreeNode& trGUI)
	{
		TreeNode trColor;
		if ( trGUI )
			trColor = trGUI.ROI.rectcolor;
		ASSERT(trColor);
		return trColor;
	}
	
	//virtual
	TreeNode	GetToolNameNode(const TreeNode& trGUI)
	{
		TreeNode trToolName;
		if ( trGUI )
			trToolName = trGUI.ROI.toolname;
		ASSERT(trToolName);
		return trToolName;
	}
	///end SHOW_TOOLNAME_FOR_ROI_TOOLS
	
	///Sophy 1/23/2010 MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	//virtual
	/// Iris 2/20/2010 MOVE_REPLACE_LAST_OUTPUT_TO_CONTEXT_MENU
	//bool	DoOutput()
	bool	DoOutput(bool bUpdateLastOutput)
	///End MOVE_REPLACE_LAST_OUTPUT_TO_CONTEXT_MENU
	{
		Tree trGUI;
		if( !GetGUITree(trGUI) )
			return false;
		///Sophy 2/1/2010 UPDATE_LEGEND_STRING_IN_CASE_MODIFIED_OUTSIDE_ROI_TOOL
		Tree trResults;
		if ( GetResultsTree(trResults) )
		{
			if ( !m_dp )
				GetData(); //attach
			if ( !m_dp )
				return false; //maybe not selected.
			string strLegend;
			m_dp.GetLegend(strLegend);
			trResults.name.strVal = strLegend;
			trResults.name.TypeID = TNVAL_TYPE_CSTRING;
			SetResultsTree(trResults);
		}
		///end UPDATE_LEGEND_STRING_IN_CASE_MODIFIED_OUTSIDE_ROI_TOOL
		bool bOutToScriptWindow = trGUI.output.script.nVal == 1;
		bool bOutToResultLog = trGUI.output.reslog.nVal == 1;
		bool bOutToWks = trGUI.output.appendwks.nVal == 1;
		string	strWksName = trGUI.output.wksName.strVal;
		
		DWORD dwCtrl = TREE2STR_CHECK_USER_LABEL;
		OutputResultTree(bOutToScriptWindow, bOutToResultLog, bOutToWks, strWksName, dwCtrl);
		return true;
	}
	///end MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL

	//virtual
	int		CreateAttachments()
	{
		int nRet = GraphObjCurveTool::CreateAttachments();
		if ( 0 != nRet )
			return nRet;
		
		///Sophy 1/26/2010 MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
		nRet = CreateAttachment(m_goMeanLine, CST_OBJ_MEAN_LINE, CTP_FREE_1, GROT_LINE);
		if ( 0 != nRet )
			return nRet;
		set_go_selectable(m_goMeanLine, false);
		
		nRet = CreateAttachment(m_goSDUpper, CST_OBJ_SD_LINE1, CTP_FREE_2, GROT_LINE);
		if ( 0 != nRet )
			return nRet;
		set_go_selectable(m_goSDUpper, false);
		
		nRet = CreateAttachment(m_goSDLower, CST_OBJ_SD_LINE2, CTP_FREE_3, GROT_LINE);
		if ( 0 != nRet )
			return nRet;
		set_go_selectable(m_goSDLower, false);
		
		updateLinesFormat();
		///end MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
		///Sophy 4/9/2010 QA81-15290 QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
		nRet = CreateAttachment(m_goMeanLabel, CST_OBJ_MEAN_LABEL, CTP_FREE_4, GROT_TEXT);
		if ( 0 != nRet )
			return nRet;
		set_go_selectable(m_goMeanLabel, false);
		SetLabelTransparent(m_goMeanLabel);	///Sophy 4/12/2010 QA81-15290 LABELS_INSIDE_ROI_SHOULD_NOT_BE_WHITEOUT
		
		nRet = CreateAttachment(m_goSDUpperLabel, CST_OBJ_SD_LABEL1, CTP_FREE_5, GROT_TEXT);
		if ( 0 != nRet )
			return nRet;
		set_go_selectable(m_goSDUpperLabel, false);
		SetLabelTransparent(m_goSDUpperLabel);	///Sophy 4/12/2010 QA81-15290 LABELS_INSIDE_ROI_SHOULD_NOT_BE_WHITEOUT
		
		nRet = CreateAttachment(m_goSDLowerLabel, CST_OBJ_SD_LABEL2, CTP_FREE_5, GROT_TEXT);
		if ( 0 != nRet )
			return nRet;
		set_go_selectable(m_goSDLowerLabel, false);
		SetLabelTransparent(m_goSDLowerLabel);	///Sophy 4/12/2010 QA81-15290 LABELS_INSIDE_ROI_SHOULD_NOT_BE_WHITEOUT
		///end QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
		return nRet;
	}

	///Sophy 1/26/2010 MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	//virtual
	int		GetAttachments()
	{
		int nRet = GraphObjCurveTool::GetAttachments();
		if ( 0 != nRet )
			return nRet;
		
		nRet = GetAttachment(m_goMeanLine, CST_OBJ_MEAN_LINE);
		if ( 0 != nRet )
			return nRet;
		
		nRet = GetAttachment(m_goSDUpper, CST_OBJ_SD_LINE1);
		if ( 0 != nRet )
			return nRet;
		
		nRet = GetAttachment(m_goSDLower, CST_OBJ_SD_LINE2);
		if ( 0 != nRet )
			return nRet;
		
		///Sophy 4/9/2010 QA81-15290 QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
		nRet = GetAttachment(m_goMeanLabel, CST_OBJ_MEAN_LABEL);
		if ( 0 != nRet )
			return nRet;
		
		nRet = GetAttachment(m_goSDUpperLabel, CST_OBJ_SD_LABEL1);
		if ( 0 != nRet )
			return nRet;

		nRet = GetAttachment(m_goSDLowerLabel, CST_OBJ_SD_LABEL2);
		if ( 0 != nRet )
			return nRet;
		///end QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
		return nRet;
	}
	///end MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	
	
	///Sophy 4/14/2010 BACKWORD_COMPATIBILITY_SUPPORT_FOR_GADGET_ATTACHMENTS
	//virtual
	int		CheckCreateAttachments()
	{
		int nRet = GraphObjCurveTool::CheckCreateAttachments();
		if ( 0 != nRet )
			return nRet;
		
		nRet = GetAttachment(m_goMeanLabel, CST_OBJ_MEAN_LABEL);
		if ( 0 != nRet ) //if not exist, create it
		{
			nRet = CreateAttachment(m_goMeanLabel, CST_OBJ_MEAN_LABEL, CTP_FREE_4, GROT_TEXT);
			if ( 0 != nRet )
				return nRet;
			set_go_selectable(m_goMeanLabel, false);
			SetLabelTransparent(m_goMeanLabel);	///Sophy 4/12/2010 QA81-15290 LABELS_INSIDE_ROI_SHOULD_NOT_BE_WHITEOUT
		}
		
		nRet = GetAttachment(m_goSDUpperLabel, CST_OBJ_SD_LABEL1);
		if ( 0 != nRet ) //if not exist, create it
		{
			nRet = CreateAttachment(m_goSDUpperLabel, CST_OBJ_SD_LABEL1, CTP_FREE_5, GROT_TEXT);
			if ( 0 != nRet )
				return nRet;
			set_go_selectable(m_goSDUpperLabel, false);
			SetLabelTransparent(m_goSDUpperLabel);	///Sophy 4/12/2010 QA81-15290 LABELS_INSIDE_ROI_SHOULD_NOT_BE_WHITEOUT
		}

		nRet = GetAttachment(m_goSDLowerLabel, CST_OBJ_SD_LABEL2);
		if ( 0 != nRet ) //if not exist, create it
		{
			nRet = CreateAttachment(m_goSDLowerLabel, CST_OBJ_SD_LABEL2, CTP_FREE_5, GROT_TEXT);
			if ( 0 != nRet )
				return nRet;
			set_go_selectable(m_goSDLowerLabel, false);
			SetLabelTransparent(m_goSDLowerLabel);	///Sophy 4/12/2010 QA81-15290 LABELS_INSIDE_ROI_SHOULD_NOT_BE_WHITEOUT
		}
		return nRet;
	}
	///end BACKWORD_COMPATIBILITY_SUPPORT_FOR_GADGET_ATTACHMENTS
	
	//virtual 
	BOOL OnMove()
	{
		if(!OnPreMove()) 
			return false;
		
		Tree trGUI;
		if ( !GetGUITree(trGUI) )
		{
			error_report("Invalid GUI Tree! OnMove()");
			return FALSE;
		}
		
		Tree tr;
		vector vX;
		vector vY;
		///Sophy 2/11/2010 CURVE_STATS_SHOULD_GET_DATA_BY_INDEX_AS_OTHER_ROI_TOOLS
		//if ( GetData(vX, vY) )
		if ( GetData() )
		///end CURVE_STATS_SHOULD_GET_DATA_BY_INDEX_AS_OTHER_ROI_TOOLS
		{
			updateLinesFormat(); //show lines when change from No Data Selected state to having data state
			///Sophy 2/11/2010 CURVE_STATS_SHOULD_GET_DATA_BY_INDEX_AS_OTHER_ROI_TOOLS
			///Sophy 5/4/2010 QA82-15364-P2 ROI_TOOLS_OPTION_FOR_SKIP_ALL_MASKED_DATAPOINTS
			//m_dp.GetDataPoints(m_i1, m_i2, vX, vY);
			///end ROI_TOOLS_OPTION_FOR_SKIP_ALL_MASKED_DATAPOINTS
			///end CURVE_STATS_SHOULD_GET_DATA_BY_INDEX_AS_OTHER_ROI_TOOLS
			curve_stats(m_vX, m_vY, tr);
			
			Tree trResults;
			if ( !GetResultsTree(trResults, "quantities") )
			{
				error_report("Invalid Results Tree! OnMove()");
				return FALSE;
			}
			
			string str;
			m_dp.GetLegend(str);
			trResults.name.strVal = str;
			trResults.name.TypeID = TNVAL_TYPE_CSTRING;
			str.Format("[%d:%d]", m_i1 + 1, m_i2 + 1);
			trResults.range.strVal = str;
			trResults.range.TypeID = TNVAL_TYPE_CSTRING;
#define	COPY(_VAL)				trResults._VAL = tr._VAL
#define	TYPE(_SubNode, _Type)	trResults._SubNode.SetAttribute(STR_COL_DESIGNATION_ATTRIB, _Type)
			COPY(N.nVal);		TYPE(N, OKDATAOBJ_DESIGNATION_Y);
			COPY(sum.dVal);		TYPE(sum, OKDATAOBJ_DESIGNATION_Y);
			COPY(mean.dVal);	TYPE(mean, OKDATAOBJ_DESIGNATION_Y);
			COPY(median.dVal);	TYPE(median, OKDATAOBJ_DESIGNATION_Y);
			COPY(sd.dVal);		TYPE(sd, OKDATAOBJ_DESIGNATION_ERROR);
			COPY(min.dVal);		TYPE(min, OKDATAOBJ_DESIGNATION_Y);
			COPY(max.dVal);		TYPE(max, OKDATAOBJ_DESIGNATION_Y);

			///Sophy 4/12/2010 QA81-15289 OUTPUT_NSD_VALUES_WHEN_LINES_VISIBLE
			if ( m_goSDUpper.Show && m_goSDLower.Show )
			{
				double dnSD = trGUI.roi.sdline.nSD.dVal;
				double dOffset = dnSD * trResults.sd.dVal;
				
				trResults.nSDUpper.dVal = trResults.mean.dVal + dOffset;	
				str.Format("+%s SD", ftoa(dnSD));
				trResults.nSDUpper.SetAttribute(STR_LABEL_ATTRIB, str);
				TYPE(nSDUpper, OKDATAOBJ_DESIGNATION_ERROR);

				trResults.nSDLower.dVal = trResults.mean.dVal - dOffset;
				str.Format("-%s SD", ftoa(dnSD));
				trResults.nSDLower.SetAttribute(STR_LABEL_ATTRIB, str);
				TYPE(nSDLower, OKDATAOBJ_DESIGNATION_ERROR);
			}
			///end OUTPUT_NSD_VALUES_WHEN_LINES_VISIBLE
			tree_copy_values_to_attributes(trGUI.quantities, trResults, STR_LABEL_ATTRIB);
			if ( !SetResultsTree(trResults) )
			{
				error_report("Fail to set Results Tree! OnMove()");
				return FALSE;
			}
			updateResultText();
			updateLinesPosition();	///Sophy 1/26/2010 MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
		}
		else
			updateLinesFormat(false); //hide lines when no valid data available.
		return GraphObjCurveTool::OnMove();
	}

	//virtual
	string	GetXFName(){ return XF_NAME; }
	///Sophy 1/22/2010 CENTRALIZE_OPEN_PREFERENCE_DIALOG_TO_BASE_CLASS
	//virtual
	string	GetToolName(){ return TOOLNAME; }
	//virtual
	string	GetPreferenceTitle(){ return TOOL_PREFERENCES_TITLE; }
	///end CENTRALIZE_OPEN_PREFERENCE_DIALOG_TO_BASE_CLASS
	///Sophy 1/23/2010 MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	//virtual
	int*	GetXFEventHandlersState() { return _get_xf_treenode_evt_handle_state(); }
	///end MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	///Sophy 4/9/2010 QA81-15290 QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
	virtual	bool	IsCloneMainObj()
	{
		return false; ///Sophy 4/12/2010 temporary turn off this functionality to ER's suggestion on #15290
		Tree trGUI;
		if ( GetGUITree(trGUI) )
		{
			int nClone = trGUI.roi.cloneObjs.nVal;
			return (1 == nClone);
		}
		return false;
	}
	
	//virtual
	bool	CloneAttachments(GraphObject& goCloneMain)
	{
		//do NOT clone top label delibrately
		//if ( GraphObjCurveTool::CloneAttachments(goCloneMain) )
		//{
			GraphObject gc;
			if ( m_goMeanLine.Show )
			{
				CloneAndConnect(goCloneMain, m_goMeanLine);
				
				CloneAndConnect(goCloneMain, m_goMeanLabel);
			}
			if ( m_goSDUpper.Show )
			{
				CloneAndConnect(goCloneMain, m_goSDUpper);
				
				CloneAndConnect(goCloneMain, m_goSDUpperLabel);

			}
			if ( m_goSDLower.Show )
			{
				CloneAndConnect(goCloneMain, m_goSDLower);

				CloneAndConnect(goCloneMain, m_goSDLowerLabel);
			}
			return true;
		//}
		//return false;
	}
	///end QUICK_STATS_SHOW_PREVIEW_LINE_LABELS

private:
	
	///Sophy 1/23/2010 MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	bool	updateResultText()
	{
		Tree trGUI, trResults;
		if ( !GetGUITree(trGUI) || !GetResultsTree(trResults, "quantities") )
			return false;
		
		string strText;
		if ( trGUI.showtop.n.nVal )
			strText += "N = " + trResults.n.nVal;
		if ( trGUI.showtop.mean.nVal )
			strText += " Mean = " + ftoa(trResults.mean.dVal, "*") + "\n";
		if ( trGUI.showtop.sd.nVal )
			strText += "SD = " + ftoa(trResults.sd.dVal, "*") + "\n";
		if ( trGUI.showtop.min.nVal )
			strText += "Min = " + ftoa(trResults.min.dVal, "*");
		if ( trGUI.showtop.max.nVal )
			strText += " Max = " + ftoa(trResults.max.dVal, "*");
		
		strText.TrimRight('\n');
		///Sophy 2/12/2010 MORE_CLEAN_CODE_TO_RESET_LABEL_POSITION
		//if ( g_sbFirstTime )
			//roi_tool_option_access(ROI_OPTION_RESET_LABEL_POS, ROI_OP_SET);
		///end MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
		
		UpdateTopLabel(strText);
		//g_sbFirstTime = false;///Sophy 2/12/2010 MORE_CLEAN_CODE_TO_RESET_LABEL_POSITION
		return true;
	}
	///end MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	
	///Sophy 1/26/2010 MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	/*
	void curveStatsReport(const DataPlot& dp, const TreeNode &tr)
	{
		string strName;
		if(dp)
			dp.GetLegend(strName);//---- CPY 11/02/08 QA70-12504 BETTER_DATAPLOT_NAME_DISPLAY
		// If it found intersecting data, then dump basic stats to script window 
		string str, strOutput;
		if(!strName.IsEmpty())
		{
			str.Format("%s:", strName);
			strOutput += str;
		}

		Tree trGUI;
		if(!GetGUITree(trGUI))
		{
			ASSERT(false);
			return;
		}		
		if ( trGUI.output.Use != 0 )		//------ Folger 09/24/08 SHOULD_NOT_OUTPUT_UNNECESSARY_RESULTS
		{		
			LT_execute("ty -a"); //CPY 9/23/08 SCRIPT_WIN_MIGHT_BE_CLOSED
			if(tr)
			{
				if(trGUI.output.n.nVal)AddNewLine(strOutput, "  N = " + tr.N.nVal);
				if(trGUI.output.mean.nVal)AddNewLine(strOutput, "  mean = " + ftoa(tr.mean.dVal));
				if(trGUI.output.median.nVal)AddNewLine(strOutput, "  median = " + ftoa(tr.median.dVal));
				if(trGUI.output.sd.nVal)AddNewLine(strOutput, "  sd = " + ftoa(tr.sd.dVal));
				if(trGUI.output.min.nVal)AddNewLine(strOutput, "  min = " + ftoa(tr.min.dVal));
				if(trGUI.output.max.nVal)AddNewLine(strOutput, "  max = " + ftoa(tr.max.dVal));
			}
			printf("%s\r\n", strOutput);
			//printf("  x = %s - %s\n", ftoa(tr.x1.dVal), ftoa(tr.x2.dVal));//---- CPY 11/02/08 QA70-12504 BETTER_DATAPLOT_NAME_DISPLAY
			//printf("  i = %d - %d\n", m_i1+1, m_i2+1);
		}
		
		if(m_goLabel)
		{
			//str.Format("(%s->%s)", ftoa(tr.x1.dVal), ftoa(tr.x2.dVal));
			str.Empty();
			if ( trGUI.rightbottom.Use != 0 && tr)		//------ Folger 09/24/08 SHOULD_NOT_OUTPUT_UNNECESSARY_RESULTS
			{
				if(trGUI.rightbottom.n.nVal) AddNewLine(str, "N= " + tr.N.nVal);
				if(trGUI.rightbottom.mean.nVal) AddNewLine(str, "mean= " + ftoa(tr.mean.dVal, "*5"));
				if(trGUI.rightbottom.min.nVal) AddNewLine(str,  "min = " + ftoa(tr.min.dVal, "*5"));
				if(trGUI.rightbottom.max.nVal) AddNewLine(str,  "max = " + ftoa(tr.max.dVal, "*5"));
			}
		
			m_goLabel.Text = str;
		}
	}
	*/
	void updateLinesFormat(bool bShow = true)
	{
		Tree trGUI;
		if ( !GetGUITree(trGUI) )
			return;
		
		int nUse = 0;
		set_go_color(m_goMeanLine, trGUI.ROI.showmeanline.nVal);
		trGUI.ROI.showmeanline.GetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, nUse);
		m_goMeanLine.Show(nUse && bShow);
		m_goMeanLabel.Show(nUse && bShow);	///Sophy 4/9/2010 QA81-15290 QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
		set_go_color(m_goSDUpper, trGUI.ROI.sdline.sdcolor.nVal);
		set_go_color(m_goSDLower, trGUI.ROI.sdline.sdcolor.nVal);
		
		nUse = trGUI.ROI.sdline.Use;
		m_goSDUpper.Show(nUse && bShow);
		m_goSDLower.Show(nUse && bShow);
		///Sophy 4/9/2010 QA81-15290 QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
		m_goSDUpperLabel.Show(nUse && bShow);
		m_goSDLowerLabel.Show(nUse && bShow);
		///end QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
	}
	void updateLinesPosition()
	{
		Tree trResults;
		if ( !GetResultsTree(trResults, "quantities") )
			return;
		
		double dLeft, dRight;
		GetRectCoordinate(dLeft, dRight);
				
		string	strLabel;
		double dMean = trResults.mean.dVal;
		if( m_goMeanLine.Show )
		{
			move_hline(m_goMeanLine, dLeft, dRight, dMean);
			///Sophy 4/9/2010 QA81-15290 QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
			if ( m_goMeanLabel.IsValid() )
			{
				strLabel.Format("Mean\r\n%s", ftoa(dMean, "*"));
				m_goMeanLabel.Text = strLabel;
				updateLabelPosition(m_goMeanLabel, dMean);
			}
			///end QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
		}
		
		if ( m_goSDUpper.Show )
		{
			Tree trGUI;
			GetGUITree(trGUI);
			double dnSD = trGUI.roi.sdline.nSd.dVal;
			double dOffset = trResults.sd.dVal * dnSD;
			///Sophy 2/8/2010 ROI_STATS_CURVE_NEED_TO_DELAY_HANDLE_SCALE_CHANGE
			if ( is_missing_value(dOffset) )
				dOffset = 0;
			///end ROI_STATS_CURVE_NEED_TO_DELAY_HANDLE_SCALE_CHANGE
			move_hline(m_goSDUpper, dLeft, dRight, dMean + dOffset);
			move_hline(m_goSDLower, dLeft, dRight, dMean - dOffset);
			///Sophy 4/9/2010 QA81-15290 QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
			if ( m_goSDUpperLabel.IsValid() && m_goSDLowerLabel.IsValid() )
			{
				strLabel.Format("+%s SD\r\n%s", ftoa(dnSD), ftoa(dMean + dOffset, "*"));
				m_goSDUpperLabel.Text = strLabel;
				updateLabelPosition(m_goSDUpperLabel, dMean + dOffset);
				
				strLabel.Format("-%s SD\r\n%s", ftoa(dnSD), ftoa(dMean - dOffset, "*"));
				m_goSDLowerLabel.Text = strLabel;
				updateLabelPosition(m_goSDLowerLabel, dMean - dOffset);
			}
			///end QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
		}
	}
	///end MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	///Sophy 4/9/2010 QA81-15290 QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
	void updateLabelPosition(GraphObject& goLabel, double dY)
	{
		if ( goLabel )
		{
			goLabel.Y = dY;
			goLabel.X = m_go.X + (m_go.DX - goLabel.DX) / 2; //align right, inner of main object
		}
	}
	///end QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
private:

	///Sophy 1/26/2010 MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	GraphObject		m_goMeanLine;
	GraphObject		m_goSDUpper;
	GraphObject		m_goSDLower;
	///end MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	///Sophy 4/9/2010 QA81-15290 QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
	GraphObject		m_goMeanLabel;
	GraphObject		m_goSDUpperLabel;
	GraphObject		m_goSDLowerLabel;
	///end QUICK_STATS_SHOW_PREVIEW_LINE_LABELS
};

////XF_NAME_events
void addtool_curve_stats_events(string strGrName, int nEvent, int nMsg = 0)
{
	StatsCurveTool sTool;
	//sTool.OnEvent(nEvent);
	graphobjtool_events(sTool, strGrName, nEvent, nMsg);
}




void addtool_curve_stats(const TreeNode& trGUI)
{
	
	//g_sbFirstTime = true;///Sophy 2/12/2010 MORE_CLEAN_CODE_TO_RESET_LABEL_POSITION
	StatsCurveTool sTool();
	///Sophy 8/21/2009 QA80-14175 CREATE_ALL_NODES_IN_ONE_TREE_TO_GET_RID_OF_OPTIONS_BRANCH
	//int nErr = sTool.Create(XF_NAME, color, GCTC_FREE_FORM_RECT, tr);
	///Sophy 1/23/2010 MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	//int nErr = sTool.Create(XF_NAME, GCTC_FREE_FORM_RECT, trGUI);
	int nErr = sTool.Create(XF_NAME, 0, trGUI);
	///end MAKE_QUICK_CURVE_STATS_AS_STANDARD_ROI_TOOL
	///end CREATE_ALL_NODES_IN_ONE_TREE_TO_GET_RID_OF_OPTIONS_BRANCH
	if(nErr < 0)
	{
		XF_THROW(XFERR_INVALID_GRAPH_LAYER);
		return;
	}
	if(nErr != 0)
		error_report("addtool_curve_stats failed");
	
}

//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 addtool_curve_stats_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return addtool_curve_stats_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	///Sophy 1/29/2010 QA80-14995-P2 CHECK_UPDATE_REPORT_WORKSHEET_NAME_FOR_ROI_TOOLS
	if ( GETNE_ON_INIT == nEventID || GETNE_ON_THEME == nEventID || 0 == lstrcmpi(lpcszNodeName, "wksName") )
	{
		string strBookSheetName = trGetN.trGUI.output.wksName.strVal;
		if ( !check_update_worksheet_name(strBookSheetName) )
		{
			trGetN.trGUI.output.wksName.strVal = strBookSheetName; //update report book sheet name
			strErrMsg = CER_SHEET_NAME_ILLEGAL_CHAR;
		}
	}
	///end CHECK_UPDATE_REPORT_WORKSHEET_NAME_FOR_ROI_TOOLS
	return false;

}

int addtool_curve_stats_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	
	if ( tr.IsValid() )
	{
		int nBranchID = 1;
		int nUserID = GET_USER_DATAID(0);
		string strVarName(lpcszVarName);
		if ( strVarName == "trGUI" )
		{
			GETN_USE(tr)
			GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
			GETN_BEGIN_BRANCH(roi, STR_ROI_LABEL)	GETN_ID(nBranchID++)
				GETN_STR(toolname, STR_TOOLNAME, TOOLNAME)	GETN_ID(STATS_TOOLNAME_ID)	GETN_CONTROL_OPTION_BOX(0)
				//GETN_CHECK(cloneObjs, _L("Show Lines on Report"), false)	GETN_ID(STATS_CLONE_OBJS_ID) ///Sophy 4/12/2010 temporary turn off, No GUI change in SR3
				GETN_COLOR(rectcolor, STR_FILL_COLOR, SYSCOLOR_LTYELLOW)	GETN_COLOR_CHOICE_OPTIONS(COLORLIST_CUSTOM | COLORLIST_SINGLE)	GETN_ID(nUserID++)
				GETN_COLOR(showmeanline, _L("Show Mean Line"), SYSCOLOR_BLUE)		GETN_CONTROL_OPTION_BOX(1)	GETN_COLOR_CHOICE_OPTIONS(COLORLIST_CUSTOM | COLORLIST_SINGLE)	GETN_ID(nUserID++)
				
				
				GETN_BEGIN_BRANCH(sdline, _L("Show Standard Deviation Lines"))	GETN_OPTION_BRANCH(GETNBRANCH_OPEN)	GETN_CHECKBOX_BRANCH(0) GETN_ID(nBranchID++)
					GETN_COMBO(nSD, _L("Multiple of SD"), 1, "|0.5|1|1.5|2|3|4|5")	GETN_ID(nUserID++)
					GETN_COLOR(sdcolor, _L("SD Lines Color"), SYSCOLOR_RED)	GETN_COLOR_CHOICE_OPTIONS(COLORLIST_CUSTOM | COLORLIST_SINGLE)	GETN_ID(nUserID++)	
				GETN_END_BRANCH(sdline)
			GETN_END_BRANCH(roi)
			GETN_BEGIN_BRANCH(showtop, _L("Show on Center-Top of ROI Box"))	GETN_ID(nBranchID++)
				GETN_CHECK(n, _L("N"), true)		GETN_ID(nUserID++)
				GETN_CHECK(mean, _L("Mean"), true)	GETN_ID(nUserID++)
				GETN_CHECK(sd, _L("SD"), true)		GETN_ID(nUserID++)
				GETN_CHECK(min, _L("Minimum"), false)	GETN_ID(nUserID++)
				GETN_CHECK(max, _L("Maximum"), false)	GETN_ID(nUserID++)
			GETN_END_BRANCH(showtop)
			
			GETN_BEGIN_BRANCH(output, _L("Output To"))	GETN_ID(nBranchID++)
				GETN_CHECK(script, _L("Script Window"), 1)	GETN_ID(nUserID++)
				GETN_CHECK(reslog, _L("Result Log"), 1)		GETN_ID(nUserID++)
				GETN_CHECK(appendwks, _L("Append to Worksheet"), 0)	GETN_ID(nUserID++)	GETN_OPTION_EVENT(_check_appwks_event)
				GETN_STR(wksName, _L("Result Workbook Name"), "[QkStats]Result")	GETN_ID(nUserID++)
			GETN_END_BRANCH(output)
			
			GETN_BEGIN_BRANCH(quantities, _L("Quantities"))	GETN_OPTION_BRANCH(GETNBRANCH_OPEN)	GETN_ID(nBranchID++)
				GETN_CHECK(name, _L("Input Legend"), true)			GETN_ID(nUserID++)
				GETN_CHECK(range, _L("Input Range Index"), true)	GETN_ID(nUserID++)
				GETN_CHECK(n, _L("N"), true)		GETN_ID(nUserID++)
				GETN_CHECK(sum, _L("Sum"), true)	GETN_ID(nUserID++)
				GETN_CHECK(mean, _L("Mean"), true)	GETN_ID(nUserID++)
				GETN_CHECK(median, _L("Median"), true)	GETN_ID(nUserID++)
				GETN_CHECK(sd, _L("SD"), true)			GETN_ID(nUserID++)
				GETN_CHECK(min, _L("Minimum"), true)	GETN_ID(nUserID++)
				GETN_CHECK(max, _L("Maximum"), true)	GETN_ID(nUserID++)
			GETN_END_BRANCH(quantities)
		}
	}
	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 addtool_curve_stats_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	if ( is_xf_startup(nGetNDialog, dwCntrl) )
	{
		if(is_use_origin_chm())
			trGetN.SetAttribute(STR_HELPID_ATTRIB, IDD_XF_addtool_curve_stats);
	}
	
	///Sophy 1/29/2010 QA80-14995-P2 CHECK_UPDATE_REPORT_WORKSHEET_NAME_FOR_ROI_TOOLS
	if ( 0 == nGetNDialog || -1 == nGetNDialog )
	{
		if ( !O_QUERY_BOOL(dwCntrl, LTXF_SHOW_DIALOG) )
		{
			string strBookSheetName = trGetN.trGUI.output.wksName.strVal;
			if ( !check_update_worksheet_name(strBookSheetName) )
			{
				trGetN.trGUI.output.wksName.strVal = strBookSheetName; //update report book sheet name
				dwCntrl |= LTXF_SHOW_DIALOG;
			}			
		}
	}
	///end CHECK_UPDATE_REPORT_WORKSHEET_NAME_FOR_ROI_TOOLS
	
}
//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 addtool_curve_stats_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	
	return false;
	
}
