/*------------------------------------------------------------------------------*
 * File Name:				 													*
 * Creation: CPY 8/10/2006														*
 * Purpose: OriginC Source C file												*
 * Copyright (c) Originlab Corp. 2006											*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 * Hong 03/23/07 v8.0588 MORE_OPTION_ALLOW_NOT_RESCALE_ON_INIT					*
 *	Hong 04/19/07 v8.0604 NEW_LINE_CONTROL_CLASS_FOR_PFM_XF_NEEDED_BY_SANDY		*
 *	Hong 05/05/07 QA80-9716 ADD_PLOT_CONTROL_XF_FOR_GRAPH_WINDOW				*
 *	Sim 07-17-2007 ADD_XY_SCALER_OBJECT											*
 *	Cloud 11/30/07 COORDINATE_SHOULD_BE_DOUBLE									*
 *	YuI 02/05/08 WORK_ON_SPFW													*
 *	Hong 02/26/08 v8.0812 USING_CLASS_CENTRALIZE_CODE_OF_PEAK_CONTROL			*
 * 	Hong 02/27/08 v8.0813 COMPILE_ERROR_WHEN_MULTIPLE_INCLUDE_IN_XF				*
 *	Jasmine 03/15/08 CP_ASK_MOVE_CPEAKSPREVIEWHELPER_FROM_SPFM_UTILS			*
 *	Hong 03/20/08 v8.0828 EMPTY_DESTRUCTOR_LEAD_XF_PKFIND_LINKING_ERROR_UNEXPECTED
 *	Hong 03/26/08 v8/0832b PA_PEAKS_DEL_REQUIRE_FOLLOWING_DATA_SUPPORT			*
 *	Folger 04/25/08 IMPROVE_MODIFY_AND_DELETE_PEAKS_IN_NANOSIZER				*
 *	YuI 09/16/08 QA70-12204 POSITION_CONTROL_FOR_CONNECT_TO						*
 *	YuI 09/24/08 QA70-12264 OPTION_TO_SELECT_GR_OBJECT_BEFORE_DATA				*
 *	CPY 9/26/08 QA70-12266 ADDTOOL_XF_NEEDS_PROJ_VAR_TO_INDICATE_THEY_ARE_STILL_ACTIVE
 *	Kenny 05/04/2009 ADD_FUNC_FOR_USE_OF_VERTICAL_CURSOR						*
 *	Fisher 7/20/09 QA80-13975 	HANDLE_RESCALE_EVENT_FOR_GRAPH_OBJ_TOOL			*
 *	Sophy 8/21/2009 QA80-14175 CREATE_ALL_NODES_IN_ONE_TREE_TO_GET_RID_OF_OPTIONS_BRANCH
 *	Sophy 8/26/2009 QA80-14169 MAKE_GRAPHOBJECT_FOR_PROGRAMMING_CONTROL_PRINTABLE
 *	Sophy 11/26/2009 EVT_HANDLER_IN_TREENODE_INVALID_WHEN_RESTART_ORIGIN		*
 *	Sophy 12/3/2009 QA80-14686 CENTRALIZE_CODE_FOR_UPDATE_RESULT_ON_RESCALE_GRAPH
 *	Sophy 12/4/2009 QA80-14799 EXPOSE_DATAMASK_EVENT_TO_OC_GRAPHOBJECT			*
 *	Sophy 12/14/2009 QA80-14686-P2 DATAPLOT_GET_DATAPOINTS_NEED_TO_SKIP_MASKED_DATA
 *	Sophy 1/4/2010 QA80-14904-S1 SUPPORT_FLEXIBLE_ATTACHED_GROBJ_FOR_ROI_TOOLS	*
 *  Iris 2/09/2010 FIX_COMPILE_ERR_WHEN_INCLUDE_GROBJUTILS_H_FILE				*
 *	Jasmine 03/18/10 QA81-14861 IMAGE_PROFILE_WANT_POLYLINE						*
 *------------------------------------------------------------------------------*/

/// Hong 02/27/08 v8.0813 COMPILE_ERROR_WHEN_MULTIPLE_INCLUDE_IN_XF
#ifndef _GROBJ_UTILS_H_
#define _GROBJ_UTILS_H_
/// end COMPILE_ERROR_WHEN_MULTIPLE_INCLUDE_IN_XF

 //////////////////////////////////////////////////////////////////////////////
///Sandy 2007-3-12 ///////move from ocimgROIPreview.h for ROI Object saving to XF theme///
//////////////////////////////////////////////////////////////////////////////
///sandy 2008-3-17 need to remove dataid later since it isn't a good solution
#define IDE_ANCHOR_NUMBER			    10000
#define IDE_ANCHOR_MAX_NUM				40000
#define IDE_ANCHOR_ID     				20000
#define IDE_ANCHOR_SETTING_ID           30000

//use in simple anchor, the limit of anchors number is 99, by now
#define IDE_ATTR_BIT_ANCHOR_NAME   		100
#define IDE_ATTR_BIT_ANCHOR_TYPE  		200
#define IDE_ATTR_BIT_ANCHOR_X			300
#define IDE_ATTR_BIT_ANCHOR_Y	  		400

#define IDE_ATTR_BIT_ANCHOR_LEFT		700
#define IDE_ATTR_BIT_ANCHOR_RIGHT		800
#define IDE_ATTR_BIT_ANCHOR_TOP		    500
#define IDE_ATTR_BIT_ANCHOR_BOTTOM		600
#define IDE_ATTR_BIT_ANCHOR_W   		550
#define IDE_ATTR_BIT_ANCHOR_H   		650

#define IDE_ATTR_BIT_ANCHOR_LINE_X		900
#define IDE_ATTR_BIT_ANCHOR_I   		1000

//use in controlshape class
#define IDE_ATTR_BIT_ANCHOR_SPAN   		1100
#define IDE_ATTR_BIT_ANCHOR_DIR  		1200
#define IDE_ATTR_BIT_ANCHOR_TITLE		1300
#define IDE_ATTR_BIT_ANCHOR_COLOR	  	1400
#define IDE_ATTR_BIT_ANCHOR_LTSCRIPT   	1500
#define IDE_ATTR_BIT_ANCHOR_EVENTID   	1600

#define IDE_ATTR_BIT_ANCHOR_HAS_LINE	  	1700
#define IDE_ATTR_BIT_ANCHOR_HAS_TITLE   	1800
#define IDE_ATTR_BIT_ANCHOR_HAS_LABEL   	1900
#define IDE_ATTR_BIT_ANCHOR_HAS_HLINE   	2000

#define IDE_ATTR_BIT_ANCHOR_BEHINDDATA      2100


///////////////////////end of ROI object saving///////////////////////////////

enum {
	ATTACH_TO_LAYER,
	ATTACH_TO_PAGE,
	ATTACH_TO_SCALE,
};

/**
	Parameters:
		nAttach = [input] 0 = layer, 1 = page, 2 = scale
*/
/// Iris 12/06/2006 v8.0519 CORRECT_XY_RANGE_LINE_IN_XYZGRIDDING
//bool add_line(Layer& lay, GraphObject& go, double x0=0, double y0 = 0, int nAttach=2, int nDirection = LN_VERTICAL, bool bSpan=true, bool bPercent = true, double x1=50, double y1 = 50, int nColor = 1);
bool add_line(Layer& lay, GraphObject& go, double x0=0, double y0 = 0, int nAttach= ATTACH_TO_SCALE, int nDirection = LN_VERTICAL, bool bSpan=true, bool bPercent = true, double x1=50, double y1 = 50, int nColor = 1, LPCSTR lpcszName = NULL);
///end CORRECT_XY_RANGE_LINE_IN_XYZGRIDDING

///Jasmine 03/18/10 QA81-14861 IMAGE_PROFILE_WANT_POLYLINE
bool add_polyline(Layer& lay, GraphObject& goPolyLine, const vector& vx, const vector& vy, int nAttach = ATTACH_TO_SCALE, bool bPercent = true, int nColor = SYSCOLOR_RED, LPCSTR lpcszName = NULL);
///End IMAGE_PROFILE_WANT_POLYLINE

bool add_polygon(Layer& lay, GraphObject& go, const vector& vxPos, const vector& vyPos, int nAttach = 2, bool bPercent = false);
bool add_text(Layer& lay, GraphObject& go, double x, double y, LPCSTR lpcszText, int nFontSize = 0, bool bPercent = true, int nAttach=0);

///Sandy 2007-1-18 add position info for initialize.
//bool make_slider(GraphObject& go, LPCSTR lpcszCallbackFuncName, int index, LPCSTR lpcszName);
bool make_slider(GraphObject& go, LPCSTR lpcszCallbackFuncName, int index, LPCSTR lpcszName, double dPosPercent);
///Sandy 2007-2-12 add modify slider function to speed up preview
bool modify_slider(GraphObject& go,   double dPosPercent);
//end
//----- CPY 9/23/08 QA70-12263 RECT_WITH_BUTTON_NOT_DELETABLE 
//bool set_LT_script(GraphObject& go, LPCSTR lpcszScript, int nExecMode = GRCT_MOUSEUP);
bool set_LT_script(GraphObject& go, LPCSTR lpcszScript, int nExecMode = GRCT_MOUSEUP, int nSetDeletable = -1);
//-----
bool add_polygon_cntrl(const GraphLayer& gl, LPCSTR lpcszName, const vector& vx, const vector& vy, LPCSTR lpcszSecName, bool bKeepInside);

///---Sim 10-17-2006 MODIFIED_FUNC_INTERFACE
//bool add_rect(const Layer& lay, int x0, int y0, int x1, int y1, int nFillColor,  int nAttach = 2, int nDirection = LN_VERTICAL, bool bSpan=true, bool bPercent = true);
///Sandy 2007-3-23 CHANGE_RECT_POSITION_VALUE_AS_DOUBLE
//bool add_rect(const Layer& lay, GraphObject& go, int x0, int y0, int x1, int y1, int nFillColor, int nAttach = 2, int nDirection = LN_VERTICAL, bool bSpan=true, bool bPercent = true);
bool add_rect(const Layer& lay, GraphObject& go, double x0, double y0, double x1, double y1, int nFillColor, int nAttach = 2, int nDirection = LN_VERTICAL, bool bSpan=true, bool bPercent = true);

bool disable_go_move(GraphObject& go, bool bHorz = true, bool bVert = true, bool bKeepInside = true, bool bEnable = false);
bool get_go_color(const GraphObject& go, int& nColor);
bool set_go_color(GraphObject& go, int nColor);//Sandy 2008-12-3 add
bool set_go_border_color(GraphObject& go, int nColor);
bool set_go_behind_data(GraphObject& go, bool bBehindData = true);

/// YuI 09/24/08 QA70-12264 OPTION_TO_SELECT_GR_OBJECT_BEFORE_DATA
bool set_go_hittest_before_data(GraphObject& go, bool bHittestBeforeData = true);
/// end OPTION_TO_SELECT_GR_OBJECT_BEFORE_DATA
///---END MODIFIED_FUNC_INTERFACE

#ifdef NEW_FEATURE_VERTICAL_CURSOR
///Kenny 05/04/2009 ADD_FUNC_FOR_USE_OF_VERTICAL_CURSOR
bool update_go_states(GraphObject& go, DWORD dwStateAdd, DWORD dwStateRemove = 0);
///End ADD_FUNC_FOR_USE_OF_VERTICAL_CURSOR
#endif // NEW_FEATURE_VERTICAL_CURSOR

bool disable_go_rotate_skew(GraphObject& go, bool bNoRotate = true, bool bNoSkew = true,  bool bEnable = false);

//----- CPY 10/19/06 PCLAMP_TAGS
enum {
	GTB_NONE,
	GTB_LINE,
	GTB_SHADOW,
};
bool set_text_border(GraphObject& go, int nType = GTB_LINE, int nFillColor = SYSCOLOR_WHITE);
bool set_text_link_LT_var(GraphObject& go, bool bLink, int nFontSize = 0);
bool find_connected_object(const GraphObject& go, GraphObject& grText, int nConnector = 0);

/// YuI 11/27/06 QA70-9156 MORE_OPTIONS_TO_CONNECTING_OBJECTS
//	bool add_x_tag(Layer& lay, GraphObject& goLine, GraphObject& goText, double x, LPCSTR lpcszText);
bool add_x_tag(Layer& lay, GraphObject& go, GraphObject& goText, double xx, LPCSTR lpcszText, double dWidth = 0);
/// end MORE_OPTIONS_TO_CONNECTING_OBJECTS
bool set_auto_hide(GraphObject& go, bool bSet = true);
//-----
///Sophy 12/30/2009 QA80-14904-S1 SUPPORT_FLEXIBLE_ATTACHED_GROBJ_FOR_ROI_TOOLS
//enum {
	//CJ_VIEW_X_GAP_MASK	= 0x00FF,
	//CJ_VIEW_X_GAP_N		= 0x0001,
	//CJ_VIEW_X_GAP_L		= 0x0002,
	//CJ_VIEW_X_GAP_XL	= 0x0003,
	//CJ_VIEW_X_GAP_XXL	= 0x0004,
	//CJ_VIEW_X_GAP_XXXL	= 0x0005,
	//
	//CJ_VIEW_Y_GAP_MASK	= 0xFF00,
	//CJ_VIEW_Y_GAP_N		= 0x0100,
	//CJ_VIEW_Y_GAP_L		= 0x0200,
	//CJ_VIEW_Y_GAP_XL	= 0x0300,
	//CJ_VIEW_Y_GAP_XXL	= 0x0400,
	//CJ_VIEW_Y_GAP_XXXL	= 0x0500,
//};
typedef	struct OGRGAP {
	double xGap, yGap; //percent of width and height
}OGRGAP, *POGRGAP;

///end SUPPORT_FLEXIBLE_ATTACHED_GROBJ_FOR_ROI_TOOLS
/// YuI 09/16/08 QA70-12204 POSITION_CONTROL_FOR_CONNECT_TO
/**
		Moves object and connects it to target object according to nTargetTetheringPoint
	Parameters:
		grTarget = [input] target graph object to which object will get connected
		gr = [input] object that gets connected to target
		nTargetTetheringPoint = [input] point on the target object to which connection will be made (see CONNECTORTETHERINGPOINT enumeration)
*/
///Sophy 12/30/2009 QA80-14904-S1 SUPPORT_FLEXIBLE_ATTACHED_GROBJ_FOR_ROI_TOOLS
//bool	connect_justify(GraphObject& grTarget, GraphObject& gr, int nTargetTetheringPoint);
bool	connect_justify(GraphObject& grTarget, GraphObject& gr, int nTargetTetheringPoint, POGRGAP pGapCtrl = NULL);
///end SUPPORT_FLEXIBLE_ATTACHED_GROBJ_FOR_ROI_TOOLS
/// end POSITION_CONTROL_FOR_CONNECT_TO

bool set_go_width(GraphObject& go, int nWidth);

///---Sim 12-07-2006 WORK_FOR_GRAPH_OBJECT_ATTRIBUTE
//int get_rect_width(GraphObject& go);//return the min side length
//int get_rect_dir(GraphObject& go);
//bool set_rect_border_width(GraphObject& go, int nWidth);
//int get_thick_line_width(GraphObject& go);
double get_thick_line_width(GraphObject& go, double* pd1=NULL, double* pd2=NULL);///Sandy 2006-12-12 modify for more infomation of graphObject's position
int get_thick_line_dir(GraphObject& go);
///---END WORK_FOR_GRAPH_OBJECT_ATTRIBUTE

//--------- CPY 10/27/06 COLOR_SPECTRUM_PLOT
// nX = {1,2,3,...256}
// nY = {1,1,1,1...1}
// nC = {RGB, RGB...}
bool plot_color_spectrum(DataPlot& dp, GraphLayer& gl, const Worksheet& wks, int nX = 0, int nY = 1, int nC = 2);
//---------

bool move_vline(GraphObject& go, double dTop, double dBottom, double x = 50.);//CPY 11/7/06

/// AW 11/09/06 ADD_SCALER_OBJECT
// CPY 11/16/06, when bRoundScale, dScaleSize will be rounded to 1 significant digits actual value is updated to dScaleSize
// CPY 7/13/2007 when bEnumNextName = true, will create new
bool add_y_scaler(GraphLayer &gl, GraphObject& go, double& dScaleSize, LPCSTR lpcszUnits, double dLeft = 90, double dTop = 50, bool bRoundScale = true, bool bEnumNextName=false);
// %Layer, 1/5 of layer height, when %layey get value inside function  
/// END ADD_SCALER_OBJECT

///---Sim 07-17-2007 ADD_XY_SCALER_OBJECT
bool add_xy_scaler(GraphLayer &gl, GraphObject& go, double& dXScaleSize, double& dYScaleSize, LPCSTR lpcszXUnits, LPCSTR lpcszYUnits, double dLeft = 90, double dTop = 50, bool bRoundScale = true, bool bEnumNextName=false);
///---END ADD_XY_SCALER_OBJECT


///Sandy 2006-12-6 add
/// Cloud 11/30/07 COORDINATE_SHOULD_BE_DOUBLE
//bool add_ellipse(const Layer& lay, GraphObject& go, int x0, int y0, int x1, int y1, int nFillColor, int nAttach, bool bPercent = true);
bool add_ellipse(const Layer& lay, GraphObject& go, double x0, double y0, double x1, double y1, int nFillColor, int nAttach, bool bPercent = true);
/// End COORDINATE_SHOULD_BE_DOUBLE
///end

///Sophy 3/4/2010 EXTEND_ROI_SHAPE_FOR_CLUSTER_TOOL
bool add_circle(const Layer& layer, GraphObject& go, double xc, double yc, double rx, double ry, int nFillColor, int nBorderColor, int nAttach, bool bPercent = true);
///end EXTEND_ROI_SHAPE_FOR_CLUSTER_TOOL

/// Iris 12/06/2006 v8.0519 UPDATE_MAT_XY_RANGE_BY_DRAG_RECT
bool set_unit(GraphObject& go, int nUnit);
///---Sim 12-12-2006 IMPROVE_MOVE_FUNCTION
//bool rect_move(GraphObject& go, double dLeft, double dTop, int nUnit = UNITS_SCALE);
bool rect_move(GraphObject& go, double dLeft, double dTop, int nUnit = UNITS_SCALE, double dRight = __NANUM, double dBottom = __NANUM);
///---END IMPROVE_MOVE_FUNCTION

///Sandy 2007-3-28 add default value -1(or any value less than 0) to means no change
//bool rect_resize(GraphObject& go, double dWidth, double dHeight, int nUnit = UNITS_SCALE);
bool rect_resize(GraphObject& go, double dWidth = -1, double dHeight =-1, int nUnit = UNITS_SCALE);
//end

bool rect_get_size(GraphObject& go, double& dWidth, double& dHeight, int nUnit = UNITS_SCALE);	

bool rect_get_position(GraphObject& go, double& dLeft, double& dTop, double& dRight, double& dBottom, int nUnit = UNITS_SCALE);
//end UPDATE_MAT_XY_RANGE_BY_DRAG_RECT

/// Iris 12/18/2006 v8.0527 XYZ2MAT_DISABLE_RECT_MOVEMENT_EXCEPT_TPS_METHOD
bool go_is_moveable(GraphObject& go, bool bCheckVertical);
bool go_is_resized(GraphObject& go);
///end XYZ2MAT_DISABLE_RECT_MOVEMENT_EXCEPT_TPS_METHOD

///Sandy add 2006-12-13
bool remove_GraphObjects_with_prefix(Layer& lay, LPCSTR lpcstrPrefix);
//end

///Sandy 2006-12-26 add
bool get_go_size(GraphObject& go, double* pw, double* ph);
//end

//----- CPY 1/5/07 OGS_BASED_AXIS_SCROLLER_RECT
bool get_go_rect(GraphObject& go, FRECT& fr);
// this assume proper LT codes in graph_controls.ogs
// scrollbar rect will be called xScrollbar if bHorizontal, or yScrollbar if bHorizontal=false
// and it has a rect inside called xScrollThumb or yScrollThumb
// position given are in page ratio
/// Hong 03/23/07 v8.0588 MORE_OPTION_ALLOW_NOT_RESCALE_ON_INIT
//bool add_axis_scrollbar(GraphLayer& gl, double x1, double x2, double left = 0.1, double top = 0.1, double length = 0.8, double width = 0.05, bool bHorizontal = true);
bool add_axis_scrollbar(GraphLayer& gl, double x1, double x2, double left = 0.1, double top = 0.1, double length = 0.8, double width = 0.05, bool bHorizontal = true, bool bResetScale = true);
/// end MORE_OPTION_ALLOW_NOT_RESCALE_ON_INIT
//-----


///Sandy 2007-3-8 
bool move_span_vline(GraphObject& go, double dX, int nAttach = 2, int nUnit = UNITS_SCALE);
bool move_span_vrect(GraphObject& go, double dLeft, double dRight, int nAttach = 2, int nUnit = UNITS_SCALE);
//end

///Sandy 2007-3-12 add
bool fill_rect_with_color(GraphObject& go,  int nFillColor); 
bool span_rect(GraphObject& go,int nDirection, bool bSpan); 

///sandy 2007-3-28 add
bool add_label(Layer& ll, GraphObject& grText, double x, double y, LPCSTR lpcszText);

///sandy 2007-3-29 add
bool go_is_span_in_dir(GraphObject& go, bool& bSpan, int& nDir=NULL);
bool get_go_pattern_color(GraphObject& go, int& nPatternColor);
bool get_go_LTScript_event(GraphObject& go, string& strLTScript, int& nEvent = NULL);

///sandy 2007-4-2 add
bool set_go_selectable(GraphObject& go, bool bEnable);

/// Hong 04/23/07 v8.0606 ALLOW_USER_DELETE_LINE_CONTROL
bool set_go_user_deleteable(GraphObject& go, bool bEnable);
/// end ALLOW_USER_DELETE_LINE_CONTROL

///add by sandy 2007-4-18
bool move_hline(GraphObject& go, double dLeft, double dRight, double y,  int nUnit = UNITS_SCALE);
///add by sandy 2007-4-18
bool move_line(GraphObject& goLine, double x1, double x2, double y1, double y2, int nUnit  = UNITS_SCALE);

///Sandy 2007-3-12 ///////move from ocimgROIPreview.h for ROI Object saving
bool make_anchors_tree_without_info(TreeNode& tr, int nAnchorsNum = 1);
bool get_anchor_xy_from_tree(TreeNode& trAnchors, int nIndex,  double& x0, double& y0, double& w, double& h);
bool update_tree_anchors_object_type(int nObjectType, TreeNode& trAnchors);
bool save_anchors_to_tree(Layer& lay, TreeNode& tr, LPCSTR lpcstrPrefix);
bool read_and_create_anchors_from_tree(Layer& lay, TreeNode& tr, LPCSTR lpcstrPrefix, GraphObject& go = NULL);
///Sandy add end

///Sophy 8/26/2009 QA80-14169 MAKE_GRAPHOBJECT_FOR_PROGRAMMING_CONTROL_PRINTABLE
bool set_go_printable(GraphObject& go);
///end MAKE_GRAPHOBJECT_FOR_PROGRAMMING_CONTROL_PRINTABLE

///Sandy 2008-9-9 QA80-12141 XYRANGE_PLOT_LABELS_WITHOUT_L_COL 
//enum{
	//SYMBOL_TYPE_Y = 1,
	//SYMBOL_TYPE_X = 2,
//};
//bool set_plot_XY_values_as_labels(DataPlot& dp, int nSymbolType);

///Sandy 2009-2-25 move from xf
double  get_radius(GraphObject& go, int nRadiusUnit = UNITS_PIXEL, double& vertical_r2 = NULL);
bool ellipse_move(GraphObject& go, double xc, double yc,  int nUnit );

///Sophy 12/30/2009 QA80-14904-S1 SUPPORT_FLEXIBLE_ATTACHED_GROBJ_FOR_ROI_TOOLS
bool get_attachment(GraphObject& grTarget, GraphObject& gr, int nPosition, int nObjType, DWORD dwCtrl = 0);
bool check_create_attachment(GraphObject& grTarget, GraphObject& gr, LPCSTR lpcszLabel, int nObjType, int nPosition, DWORD dwCtrl = 0);

class GraphObjTool; //forward declare
void graphobjtool_events(GraphObjTool& iTool, int nEvent, int nMsg = 0);
///end SUPPORT_FLEXIBLE_ATTACHED_GROBJ_FOR_ROI_TOOLS

///Sophy 2/4/2010 PROPERLY_UPDATE_GROBJ_POSITION_ACCORDING_TO_LAYER_SCALE
double	update_position_by_scale(GraphLayer& glSrc, double dVal, bool bX = true);
///end PROPERLY_UPDATE_GROBJ_POSITION_ACCORDING_TO_LAYER_SCALE
//----- CP Sandy 3/25/07 RECT_OBJ_WITH_ASSOCIATED_OBJS
// This class implement a group of gr objects with a main obj being a Rect or an Ellipse
// associted objects include a title (text obj) and a line (default vertical) and a label (text obj)
// all associated objects are optional
class ShapeControl
{
public:
	ShapeControl(GraphObject & goOriginal);
	ShapeControl(Layer& lay, LPCSTR lpcszName);
	bool IsValid()
	{
		return m_goMain.IsValid();
	}
	// additional objects are created only if set to true
	/// Fisher 9/16/2008 GRAPH_OBJ_CURVE_TOOL
	//bool Create(Layer& lay, LPCSTR lpcszNameBase, int nIndex, TreeNode& trSettings, int nMainObj = GROT_RECT, 
	//				BOOL bLine = false, BOOL bTitle = false, BOOL bLabel=false);//, BOOL bHorizLine = false);
	bool Create(Layer& lay, LPCSTR lpcszNameBase, int nIndex, TreeNode& trSettings, int nMainObj = GROT_RECT, 
					BOOL bLine = false, BOOL bTitle = false, BOOL bLabel=false, int nAttach=ATTACH_TO_SCALE);//, BOOL bHorizLine = false);
	/// end GRAPH_OBJ_CURVE_TOOL
	void Remove();
	
	//get Properties
	int GetIndex()	{ return m_nIndex;}
	//double GetX(int nUnitType = UNITS_SCALE);
	//double GetWidth(int nUnitType = UNITS_SCALE);
	//double GetLeft();
	//double GetRight();
	//bool GetPosition(double& dX, double& dY, double& dWidth, double& dHeight, double& dLeft = NULL, double& dRight = NULL);
	bool GetPosition(double& dX, double& dY,  double& dLeft, double& dRight, double& dTop , double& dBottom );
	
	void GetOptionalSettings(TreeNode& trOptionalSettings);
	bool GetLinePos(double& dX);
	
	bool MoveTo(double dLeft, double dRight, double dTop , double dBottom,  int nUnit = UNITS_SCALE);
	//bool SetX(double x, int nUnitType = UNITS_SCALE);
	//bool SetWidth(double dw, int nUnitType = UNITS_SCALE);
	bool SetLeftRight(double dxLeft, double dxRight, int nUnitType = UNITS_SCALE);
	bool SetLinePos(double dX, int nUnitType = UNITS_SCALE);
	
	//bool SetHorizLinePos(double dY, double dLeft, double dRight, int nUnitType = UNITS_SCALE);
	void SetIndex(int nIndex);
	string GetMainObjName()
	{
		return m_goMain.GetName();
	}
	int GetMainObjType() 
	{
		int nType;
		m_goMain.GetObjectType(&nType);
		return nType;
	}
	
	GraphObject GetMainObj(){return m_goMain}
	
	//void HasObjs(bool& bLine, bool& bTitle, bool& bLabel, bool& bHorizLine)
	void HasObjs(bool& bLine, bool& bTitle, bool& bLabel)
	{
		 bLine = (m_goLine.IsValid()? true : false);
		 bTitle = (m_goTitle.IsValid()? true : false);
		 bLabel = (m_goLabel.IsValid()? true : false);
		 //bHorizLine = (m_goHLine.IsValid()? true:false);
	}
	
	bool SetTitle(LPCSTR lpcsz)
	{
		if(!m_goTitle) return false;
		m_goTitle.Text = lpcsz;
		return true;
	}
	bool SetLabel(LPCSTR lpcsz)
	{
		if(!m_goLabel) return false;
		m_goLabel.Text = lpcsz;
		return true;
	}
		
	bool ShowTitle(bool bShow = true)
	{
		if(!m_goTitle) return false;
		return m_goTitle.Show(bShow);
	}
	bool ShowLabel(bool bShow = true)
	{
		if(!m_goLabel) return false;
		return m_goLabel.Show(bShow);
	}
	bool ShowLine(bool bShow = true)
	{
		if(!m_goLine) return false;
		return m_goLine.Show(bShow);
	}
	bool Show(bool bShow = true)
	{
		if(!m_goMain) return false;
		return m_goMain.Show(bShow);		
	}	
	

private:
	bool createFromMainObj(GraphObject & goOriginal);
	bool updateLable();
	bool updateObjsName();
	
private:
	Layer m_layParent;
	string m_strBaseName;// base object name
	int    m_nIndex;
	GraphObject	m_goMain;
	
	GraphObject m_goTitle;
	GraphObject m_goLine; //Line Locking to Postition
	GraphObject m_goLabel;
	//GraphObject m_goVCLine; //vertical center line
	//GraphObject m_goHLine;
};


class ShapeControlList
{
public:	

	//create list by searching same prefix name from a layer
	ShapeControlList(Layer& lay, LPCSTR lpcszNameBase, int nMaxNum);
	bool IsValid();
	
	//create list by a same setting tree
    bool CreateList(Layer& lay, LPCSTR lpcszNameBase, int nMaxNum, int nNum, TreeNode& trSettings, 
    		int nMainObj = GROT_RECT, BOOL bLine = false, BOOL bTitle = false, BOOL bLabel=false);//, BOOL bHorizLine = false);
    bool GetMember(ShapeControl& sc, int nIndex = 0);
    
	bool Sort();
	bool RemoveAll();
	
	bool RemoveAt(int nIndex);
	bool Remove(GraphObject& goMain);
	
	bool Add(TreeNode& trSettings);
	int  GetCount()
	{
		return m_nCount;
	}
	
	//modify Properties
	bool SetXPosition(vector& vxNew, vector& vxLeft, vector& vxRight, int nUnitType = UNITS_SCALE, vector<uint>&vnIndex = NULL);
	bool SetXPosition(TreeNode& tr);
	//bool GetXPosition(vector& vxNew, vector& vwNew,  vector<uint>&vnIndex = NULL);
	bool GetXBoundarys(vector& vxLeft, vector& vxRight,  vector<uint>&vnIndex = NULL);
	
	bool SetPosition(vector& vxLeft, vector& vxRight, vector& vyTop, vector& vyBottom, int nUnitType = UNITS_SCALE, vector<uint>&vnIndex = NULL);
	bool GetPosition(vector& vxCenter, vector& vyCenter, vector& vxLeft, vector& vxRight, vector& vyTop, vector& vyBottom,  vector<uint>&vnIndex = NULL);
	
	//can save to GetN tree and support theme saving
	bool SaveToTree(TreeNode& tr);
	
	/// YuI 02/05/08 WORK_ON_SPFW
	bool	FixPositions(bool bFix);
	/// end WORK_ON_SPFW
private:
	int updateMembersProperty();//return the number of Members
	
//private:
protected: /// Hong 02/26/08 v8.0812 USING_CLASS_CENTRALIZE_CODE_OF_PEAK_CONTROL
	//main member, unchangeable in a instance
	Layer m_layParent;
	string m_strNameBase;
	int    m_nMaxNum;

	//manage ShapeControls Properties
	vector<uint> m_vnMembers;
	vector m_vecX;
	vector m_vecY;
	//vector m_vecW;
	//vector m_vecH;
	vector m_vecLeft;
	vector m_vecRight;
	vector m_vecTop;
	vector m_vecBottom;
	vector m_vecLineX;
	
	//counter of valid ShapeControl in the list
	int    m_nCount;
	
};

//bool init_setting_tree_for_ShapeControl(TreeNode& tr, int nMaxNum);
///-----

/// Hong 04/19/07 v8.0604 NEW_LINE_CONTROL_CLASS_FOR_PFM_XF_NEEDED_BY_SANDY
//---create a new line list class for pfm xfs needed by Sandy
class LineControl
{
public:
	LineControl()
	{
		m_bValid = false;
	}
	
	LineControl(const GraphObject & goOriginal);
	
	LineControl(const GraphLayer& gl, LPCSTR lpcszName);
	
	~LineControl(){}
	
public:
	bool Create(const GraphLayer& gl, LPCSTR lpcszName, double dX, LPCSTR lpcszLabel = NULL, LPCSTR lpcszLTScript = NULL);
	
	bool UpdateLabel(LPCSTR lpcszLabel);
		
	bool IsValid()
	{
		return m_bValid;
	}
	
	double GetLinePos()
	{
		return m_goLine.X;
	}
	
	bool Show(bool bShow = true); // add by sandy 2008-1-7
	
private:
	bool Init(const GraphObject & goOriginal);

private:
	bool		m_bValid;
	GraphObject		m_goLine;
	GraphObject		m_goLabel;
};

// this class manage a list of LineControl and it's attached DataPlot and Worksheet data
class LineControlList
{
public:
	LineControlList()
	{
		Reset();
	}
	
	LineControlList(const GraphLayer& gl, LPCSTR lpcszNameBase);
	
	~LineControlList(){}
	
public:	
	int CreateList(const GraphLayer& gl, LPCSTR lpcszNameBase, const vector& vdX, LPCSTR lpcszLTScript = NULL);
	
	LineControl GetAt(int nIndex);

	int RemoveAt(int nIndex,  bool bUpdateLabels = true); 
		
	int RemoveAll();
	
	int Remove(LPCSTR lpcszName);
	
	int ShowAll(bool bShow = true); // add by sandy 2008-1-7
	
	int Add(double dX, LPCSTR lpcszLTScript = NULL, bool bReplace = true);

	int GetCount()
	{
		return m_vstrObjName.GetSize();
	}
	
	int GetLinePositions(vector& vdX);
	
	bool IsValid()
	{
		if ( !m_glTarget || 0 == m_vstrObjName.GetSize() )
			return false;
			
		return true;
	}
	
private:
	void Reset()
	{
		m_vstrObjName.SetSize(0);
	}
	
	int UpdateLabels(int nOffset);
	
private:
	vector<string>	m_vstrObjName; 
	GraphLayer	m_glTarget;	
};
/// end NEW_LINE_CONTROL_CLASS_FOR_PFM_XF_NEEDED_BY_SANDY


///Sandy add 2008-2-21
//bool select_data_points_from_active_graph(vector& vx, vector& vy, vector<int>& vSelIndex, LPCSTR lpcszMsg1, LPCSTR lpcszMsg2, double dErrX , double dErrY);
///Sandy 2008-3-17 use absolute error since there maybe only one component in vx and vy
/// Hong 03/26/08 v8/0832b PA_PEAKS_DEL_REQUIRE_FOLLOWING_DATA_SUPPORT
/**$
	Parameters:
		pnPlotIndex = [input] Sets/Unsets the cursor to move along a DataPlot specified by the plot index. Default NULL is unset.
*/
//bool select_data_points_from_active_graph(vector& vx, vector& vy, vector<int>& vSelIndex, LPCSTR lpcszMsg1, LPCSTR lpcszMsg2, double dAbsErrX , double dAbsErrY);
//bool delete_data_points_from_graph(vector& vx, vector& vy, vector<int>& vDelIndex, LPCSTR lpcszMsg1=NULL, LPCSTR lpcszMsg2=NULL, double dAbsErrX = 0.05 , double dAbsErrY = 0.05);
bool select_data_points_from_active_graph(vector& vx, vector& vy, vector<int>& vSelIndex, LPCSTR lpcszMsg1, LPCSTR lpcszMsg2, double dAbsErrX , double dAbsErrY, int* pnPlotIndex = NULL);
bool delete_data_points_from_graph(vector& vx, vector& vy, vector<int>& vDelIndex, LPCSTR lpcszMsg1=NULL, LPCSTR lpcszMsg2=NULL, double dAbsErrX = 0.05 , double dAbsErrY = 0.05, int* pnPlotIndex = NULL);
/// end PA_PEAKS_DEL_REQUIRE_FOLLOWING_DATA_SUPPORT
bool delete_data_points_of_dataplot_from_graph(DataPlot& dp, vector<int>& vDelIndex, LPCSTR lpcszMsg1=NULL, LPCSTR lpcszMsg2=NULL, double dAbsErrX = 0.05, double dAbsErrY = 0.05);


///Jasmine 03/15/08 CP_ASK_MOVE_CPEAKSPREVIEWHELPER_FROM_SPFM_UTILS
#define _NANO_PEAKS_REG_NAME 	"_NanoPeaks"

string get_shape_control_indexed_name(LPCSTR lpcszName, int nIndex);

void				GetROIGraphicObjectSettings(TreeNode& trSettings);
void				GetROIPeakGraphicObjectOptionalSettings(TreeNode& trSettings);
void				GetPeakGraphicObjectSettings(TreeNode& trSettings, double dX, double dY, double dXWidth, double dYWidth, BOOL bOptional = FALSE);

/////////////////////////////////////////////////////////
// class	CPeaksPreviewHelper
/////////////////////////////////////////////////////////
class	CPeaksPreviewHelper
{
public:
	CPeaksPreviewHelper(GraphLayer gl);
	/// Hong 03/20/08 v8.0828 EMPTY_DESTRUCTOR_LEAD_XF_PKFIND_LINKING_ERROR_UNEXPECTED
	//~CPeaksPreviewHelper();
	/// end EMPTY_DESTRUCTOR_LEAD_XF_PKFIND_LINKING_ERROR_UNEXPECTED
	
public:	
	void		Reset();
	BOOL		Fix(BOOL bFix);
	BOOL		Add(double dX, double dY, double dXWidth, double dYWidth);
	BOOL		RemoveSelected();
	int			GetCount();
	
	int			Get(vector& vXCenter, vector& vYCenter, vector& vXWidth = NULL, vector& vYWidth = NULL);
	BOOL		Set(vector& vXCenter, vector& vYCenter, vector& vXWidth, vector& vYWidth);
	
	//------ Folger 04/25/08 IMPROVE_MODIFY_AND_DELETE_PEAKS_IN_NANOSIZER
	int			SetSelectable(bool bEnable);
	bool		GetPeakNames(vector<string> &vsNames);
	//------
protected:
	GraphLayer	GetLayer();
	
private:
	GraphLayer 	m_gl;
};

///End CP_ASK_MOVE_CPEAKSPREVIEWHELPER_FROM_SPFM_UTILS


////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
/// Sophy 9/13/2008 GRAPH_OBJ_TOOL

//#define	_ROI_TOOL_NEW_MENU_ //use to switch GUI.
/////Sophy 1/5/2010 QA80-14904-S1 CLEAN_CODE_FOR_ROI_TOOLS
//enum {
	//GOT_BTN_OUTPUT	= 0x0001,
	//GOT_BTN_EDIT	= 0x0002,
	//GOT_BTN_CLOSE	= 0x0004,
	//GOT_BTN_CONTEXT	= 0x0008,
	//GOT_BTN_EXPAND	= 0x0010,
	//GOT_BTN_NLFIT	= 0x0020,
	//GOT_BTN_FINDXY	= 0x0040,
	//GOT_BTN_FIXED_MASK	= 0xFFFF0000,
	//GOT_BTN_FLEX_MASK	= 0x0000FFFF,
	//GOT_BTN_PLOTS		= 0x00010000,
	//GOT_BTN_FUNCTION	= 0x00020000,
//};
//
//#define	STR_SHOW_PLOTS	_L("Change Data")
//#define	STR_DO_OUTPUT	_L("Output Result")
//#define	STR_DO_EDIT		_L("Preferences...")
//#define	STR_DO_FUNCITON	_L("Change Function")
//#define	STR_EXPAND_AREA	_L("Expand to Full Plot Range")
//#define	STR_DO_NLFIT	_L("Switch to NLFit...")
//#define	STR_DO_FINDXY	_L("Find X/Y...")
/////end CLEAN_CODE_FOR_ROI_TOOLS
/*
//----- CPY 9/17/08 CLEANUP_CODE_RELATED_TO_USING_BASE_CLASS_SET_TREE, I added code related to lpcszMainObjName to allow in constructor and optional for OnMove
class	GraphObjTool
{
public:
	GraphObjTool(LPCSTR lpcszMainObjName = NULL);
	BOOL	IsValidLayer() {if(m_gl) return true; else return false;}
	BOOL	IsValidGrObj() {if(m_go) return true; else return false;}
	BOOL	SetTree( const TreeNode& tr ); //Sophy, currently, we just need to save information of m_go( main graph object )
	BOOL	GetTree( TreeNode& tr );
	//virtual BOOL OnDestroy(){return true;}
	//---- CPY 9/27/08 CENTRALIZE_ADD_RECT_FOR_ALL_TOOLS
	void	OnEvent(int nEvent, int nMsg = 0);
	//----
	//----- CPY 9/17/08 CLEANUP_CODE_RELATED_TO_USING_BASE_CLASS_SET_TREE
	virtual BOOL Init();
	
	///Sophy 1/4/2010 QA80-14904-S1 SUPPORT_FLEXIBLE_ATTACHED_GROBJ_FOR_ROI_TOOLS
	void	DestroyInternal();
	virtual	bool	DoShowPlots(){ return false; }
	virtual	bool	DoOutput(){return false;}
	virtual	bool	DoEdit(){return false;}
	virtual	bool	DoFunction(){ return false; }
	virtual	bool	CheckAttachObjs(){ return false; }
	virtual	bool	DoContext(){ return false; }
	virtual	bool	DoExpand(){ return false; }
	///end SUPPORT_FLEXIBLE_ATTACHED_GROBJ_FOR_ROI_TOOLS
private:
	bool	connectToObj(LPCSTR lpcszName);
	void	saveClassInfo();
	bool	readClassInfo();
	//-----
	
protected:
	//derived class should implement these methods
	virtual BOOL InvalidateResults(){ ASSERT(FALSE); return OnMove(); }

protected:
	//---- CPY 9/27/08 CENTRALIZE_ADD_RECT_FOR_ALL_TOOLS
	virtual void OnMoving();
	virtual BOOL OnMove() {return true;}
	//----
	virtual BOOL OnPreMove();
	
	/// Fisher 7/20/09 QA80-13975 	HANDLE_RESCALE_EVENT_FOR_GRAPH_OBJ_TOOL
	///Sophy 12/3/2009 QA80-14686 CENTRALIZE_CODE_FOR_UPDATE_RESULT_ON_RESCALE_GRAPH
	//virtual BOOL OnRescale() {return true;}
	virtual BOOL OnRescale() { return InvalidateResults();}
	///end CENTRALIZE_CODE_FOR_UPDATE_RESULT_ON_RESCALE_GRAPH
	/// End HANDLE_RESCALE_EVENT_FOR_GRAPH_OBJ_TOOL
	///Sophy 12/4/2009 QA80-14799 EXPOSE_DATAMASK_EVENT_TO_OC_GRAPHOBJECT
	virtual	BOOL OnMasked(){ return InvalidateResults();}
	///end EXPOSE_DATAMASK_EVENT_TO_OC_GRAPHOBJECT
	
	//---- CPY 9/26/08 QA70-12266 ADDTOOL_XF_NEEDS_PROJ_VAR_TO_INDICATE_THEY_ARE_STILL_ACTIVE
	virtual string GetSignature() {
		ASSERT(false);
		return "xf_addtool_unknown";
	}
	int 	GetTotalNumTools();
	virtual BOOL OnDestroy();
	bool	Attach(LPCSTR lpcszMainObjName);//---- CPY 9/27/08 CENTRALIZE_ADD_RECT_FOR_ALL_TOOLS
	///Jasmine 02/27/09 GraphVerticalCursor_WANT_IT_PROTECTED
	int 	referenceCount(bool bInc); // true to increment, false to decrement
	///End GraphVerticalCursor_WANT_IT_PROTECTED
private:

	///Sandy 2008-12-23 add
	virtual void 		getBoundingBoxInfo(string& str);
	//end 
	
protected:
	//-----
	// returns <0 for err, 1 if already existed and type correct then just get out, 0 if normal creation on empty slot
	// nParam if > 0 might be used for additional setting, like font size if text
	int		CreateAttachment(int nObjType, int nPos, GraphObject* pgo=NULL, LPCSTR lpcszInitText = NULL, int nParam = -1);
	int		GetAttachment(int nPos, GraphObject& go, int nObjType = -1);
	
	///-------Sandy 2008-12-9 add color option
	///----- Sandy 2008-12-2 add ployline as one kind of free line
	//int		CreateAttachedFreeLine(GraphObject* pgo=NULL, int nFreePos = 0);
	//int		CreateAttachedFreeLine(GraphObject* pgo=NULL, int nFreePos = 0,  int nLineType = GROBJ_TN_LINE2);
	int		CreateAttachedFreeLine(GraphObject* pgo=NULL, int nFreePos = 0,  int nLineType = GROBJ_TN_LINE2, int nColor = SYSCOLOR_BLACK);
	
	//----- CPY 9/17/08 CLEANUP_CODE_RELATED_TO_USING_BASE_CLASS_SET_TREE
	//int		GetAttachmentCount();
	// this is just a utility function but I see no better place to put this so leave here for now.
	void AddNewLine(string& str, string strNew);
	//-----
	
	///Sophy 1/5/2010 QA80-14904-S1 CLEAN_CODE_FOR_ROI_TOOLS
	virtual	int		CreateAdvancedButtons(LPCSTR lpcszXFName, DWORD dwCtrl = GOT_BTN_CONTEXT | GOT_BTN_PLOTS | GOT_BTN_OUTPUT | GOT_BTN_EDIT | GOT_BTN_CLOSE);
	virtual	bool	UpdateContextMenu(Menu& pm, uint& nPosition){ return false; }
	///end CLEAN_CODE_FOR_ROI_TOOLS
protected:
	GraphPage 	m_gp;
	GraphLayer 	m_gl;
	GraphObject m_go;
	///Sophy 1/5/2010 QA80-14904-S1 CLEAN_CODE_FOR_ROI_TOOLS
	GraphObject m_goPlots;
	GraphObject	m_goOutput;
	GraphObject	m_goEdit;
	GraphObject m_goClose;
	GraphObject	m_goContext;
	///end CLEAN_CODE_FOR_ROI_TOOLS
	string		m_strGrName;
	
private:
	vector<string>	m_attObjNames;
};
///end GRAPH_OBJ_TOOL

GraphObject& get_master_gr(GraphObject &go);/// Fisher 2008-9-19

//---- CPY 9/27/08 CENTRALIZE_ADD_RECT_FOR_ALL_TOOLS
enum {
	GCTC_FREE_FORM_RECT = 0x0001,
};
//---- end

///Sophy 12/17/2009 QA80-14598-P4 RISE_TIME_TOOL_NEED_CREATE_LONGNAME_IN_RESULT_COLUMN
//!!!! new enum item should all use high 32bits of the DWORD, as these value will be combined with TREE2STR_CHECK_USER_LABEL, etc. !!!!//
enum {
	OUTTREE_USE_TAGNAME_IN_SCRIPT_WIN = 0x00010000,
};
///end RISE_TIME_TOOL_NEED_CREATE_LONGNAME_IN_RESULT_COLUMN
/// Fisher 2008-9-13	GRAPH_OBJ_CURVE_TOOL
class GraphObjCurveTool : public GraphObjTool
{
public:
	GraphObjCurveTool(LPCSTR lpcszMainObjName = NULL);
	///Sophy 8/21/2009 QA80-14175 CREATE_ALL_NODES_IN_ONE_TREE_TO_GET_RID_OF_OPTIONS_BRANCH
	//int 	Create(LPCSTR lpcszOCFuncName, int color, DWORD dwCntrl = 0, const TreeNode& trGUI = NULL); //---- CPY 9/27/08 CENTRALIZE_ADD_RECT_FOR_ALL_TOOLS	
	int 	Create(LPCSTR lpcszOCFuncName, DWORD dwCntrl = 0, const TreeNode& trGUI = NULL); //---- CPY 9/27/08 CENTRALIZE_ADD_RECT_FOR_ALL_TOOLS	
	///end CREATE_ALL_NODES_IN_ONE_TREE_TO_GET_RID_OF_OPTIONS_BRANCH
	
	//virtual
	bool	DoShowPlots();	///Sophy 1/5/2010 QA80-14904-S1 CLEAN_CODE_FOR_ROI_TOOLS
	//virtual
	bool	CheckAttachObjs();
	//virtual
	bool	DoContext();
	
	//virtual
	bool	DoExpand();



protected:
	
	int		AddPlots(Menu& pm, uint& nPosition);
	bool	SetPlot(int nIndex);	
	virtual	bool	SetFunction(int nIndex){ return false; }
	virtual	bool	DoNLFit(){ return false; }
	virtual	bool	DoFindXY(){ return false; }
	///Sophy 8/26/2009 QA80-14169 MAKE_GRAPHOBJECT_FOR_PROGRAMMING_CONTROL_PRINTABLE
	virtual	bool	MakePrintable(GraphObject& go) { return false; }
	///end MAKE_GRAPHOBJECT_FOR_PROGRAMMING_CONTROL_PRINTABLE
	///Sophy 8/21/2009 QA80-14175 CREATE_ALL_NODES_IN_ONE_TREE_TO_GET_RID_OF_OPTIONS_BRANCH
	int		UpdateMainRect(const TreeNode& trGUI);
	///end CREATE_ALL_NODES_IN_ONE_TREE_TO_GET_RID_OF_OPTIONS_BRANCH
	// return < 0 if no preview graph, 1 = initial show, 0 = already shown 
	// this function will always check and create wks if has been deleted by user
	int		CheckShowPreview();
	// return < 0 if no temp wks, 1 = initial wks, 0 = already have temp wks 	
	// this function used when there is wks but no separate preview graph 
	int		CheckPreviewDataWks(bool bCreate = true);//---- CPY 7/20/09 QA70-13575 HANDLE_RESCALE_EVENT_FOR_GRAPH_OBJ_TOOL added bCreate
	string	GetPreviewGraphName() {return m_strPreviewGraphName;}
	//---- CPY 9/27/08 CENTRALIZE_ADD_RECT_FOR_ALL_TOOLS
	bool	SetGUITree(const TreeNode& trGUI);
	bool	GetGUITree(Tree& trGUI);
	bool	SetResultsTree(const TreeNode& trResults);
	virtual bool GetResultsTree(TreeNode& trResults);
	bool    GetResultsTree(TreeNode& trResults, LPCSTR lpcszTagName);///Sandy add 2009-2-24 get result tree by clone sub-tree of gui
	void	ConnectToTempPreviewDataAndGraph(); 
	//virtual
	BOOL	OnDestroy();
	//
	//virtual 
	BOOL OnMove();
	//---- end CENTRALIZE_ADD_RECT_FOR_ALL_TOOLS
	
	void 	OutputResultTree(bool bToScript, bool bToResLog, bool bAppendWks, string strWksPageName, DWORD dwCtrl);///Sandy 2009-2-25 add CENTRALIZE_TO_BASE_CLASS_GROBJ_UTILS
	void 	GetRectCoordinate(double& dLeft, double& dRight, double& dTop = NULL, double& dBottom = NULL);
	
	///Sophy 11/26/2009 EVT_HANDLER_IN_TREENODE_INVALID_WHEN_RESTART_ORIGIN
	void	UpdateGUITree(TreeNode& trGUI);
	virtual	string	GetXFName(){ return ""; }
	virtual	int*	GetXFEventHandlersState() { return NULL; }
	///EVT_HANDLER_IN_TREENODE_INVALID_WHEN_RESTART_ORIGIN
	
protected:	
	string		m_strGraphTemplate;
	string		m_strPreviewGraphName;
	string		m_strPreviewGraphLongName;
	string		m_strPreviewDataWksName;
	string		m_strPreviewDataWksLongName;
	//WorksheetPage m_wp; CPY 9/13/08, no need for this as we assume only one sheet
	//GraphPage 	m_gpPreview;
	Worksheet	m_wks;
	GraphLayer	m_glPreview;
	//---- CPY 10/1/08 MOVE_DATA_DISPLAY_CODE_TO_BASE_CLASS
	//virtual BOOL GetData(DataPlot& dp, int& i1, int& i2);
	virtual 	BOOL GetData();
	DataPlot	m_dp;
	int			m_i1, m_i2;
	double		m_x1, m_x2;
	//----
	/// YuI 10/09/08 QA70-12265-P3 CURVE_STATS_QUICK_TOOL_MUST_BE_SMARTER
	///Sophy 12/14/2009 QA80-14686-P2 DATAPLOT_GET_DATAPOINTS_NEED_TO_SKIP_MASKED_DATA
	//virtual 	BOOL GetData(vector& vX, vector& vY	);
	virtual 	BOOL GetData(vector& vX, vector& vY, DWORD dwCtrl = 0);
	///end DATAPLOT_GET_DATAPOINTS_NEED_TO_SKIP_MASKED_DATA
	/// end CURVE_STATS_QUICK_TOOL_MUST_BE_SMARTER

	///Sandy 2008-12-23 add
	void 		getBoundingBoxInfo(string& str);
	//end 
};
/// end	GRAPH_OBJ_CURVE_TOOL
*/
class ShapeControlListEx
{
public:	

	ShapeControlListEx(){}

	/// Iris 2/09/2010 FIX_COMPILE_ERR_WHEN_INCLUDE_GROBJUTILS_H_FILE
	/*
	bool Init(GraphLayer &gl, LPCSTR lpcszNameBase, double dxCenter, double dyCenter)
	{
		if(!gl)
			return false;

		RemoveAll();
		m_layParent = gl;
		m_nCount = 0;
		m_lpcszNameBase = lpcszNameBase;
		m_dxCenter = dxCenter;
		m_dyCenter = dyCenter;
		return true;
	}
	*/
	bool Init(GraphLayer &gl, LPCSTR lpcszNameBase, double dxCenter, double dyCenter);
	///End FIX_COMPILE_ERR_WHEN_INCLUDE_GROBJUTILS_H_FILE	

	bool IsValid(){return m_layParent? true: false;}
    bool GetMember(ShapeControl& sc, int nIndex = 0);
    
	bool RemoveAll();
	
	bool RemoveAt(int nIndex);
	bool Remove(GraphObject& go);
	bool Remove(string& strName);

	bool Add(int nObjType, TreeNode& trSettings);
	bool Add(GraphObject& go);

	int  GetCount()
	{
		return m_nCount;
	}
	
	bool OnMove(double dx, double dy, int nUnitType);
	bool SetPosition(vector& vxLeft, vector& vxRight, vector& vyTop, vector& vyBottom, int nUnitType = UNITS_SCALE, vector<uint>&vnIndex = NULL);
	bool GetPosition(vector& vxCenter, vector& vyCenter, vector& vxLeft, vector& vxRight, vector& vyTop, vector& vyBottom,  vector<uint>&vnIndex = NULL);

	bool SaveToTree(TreeNode& tr);
private:


protected:
	Layer	m_layParent;
	int		m_nCount;
	LPCSTR	m_lpcszNameBase;
	double	m_dxCenter, m_dyCenter;

	vector<int>		m_ObjTypes;
	vector<string>	m_ObjNames;
	/*
	vector m_vecX;
	vector m_vecY;
	vector m_vecLeft;
	vector m_vecRight;
	vector m_vecTop;
	vector m_vecBottom;
	*/
};


/// Hong 02/27/08 v8.0813 COMPILE_ERROR_WHEN_MULTIPLE_INCLUDE_IN_XF
#endif // _GROBJ_UTILS_H_
/// end COMPILE_ERROR_WHEN_MULTIPLE_INCLUDE_IN_XF
