/*------------------------------------------------------------------------------*
 *	File Name: 	OCTreeUtils.h							 						*
 *	Purpose:																   	*
 *  Creation:	07/07/2004, Shulin												*
 *				SY 07/07/2004 QA70-6641 MOVE_OC_TREE_UTILITY_TO_VC_LEVEL		*
 *  	Copyright Originlab Corp. 2003, 2004,									*
 *	Modification log	                                                        *
 *  SY 09/03/2004 v8.0119 OCTREE_ATTRIBUTE_VALUES_ASSERT_FALSE					*
 *	YuI 10/18/04 QA70-70-60 v7.5151 NON_HIERARCHY_GRID_SHOULD_NOT_ADD_UNWANTED_COLUMNS*
 *  Danice 12/1/04 QA70-6891 v8.0168 GET_TREENODE_STOP_ATTRIBUTE_OPTION			*
 *  DG 3/17/05 v8.0206 CLEAN_DOUBLE_STORAGE										*
 *  SY 03/25/2005 QA70-7543 v8.0212 OCTREE_FIND_NODE_BY_ATTRIBUTE				*
 *  Forest 3/30/05 QA70-7456 COPY_TREE_BY_FILTER								*
 *  Forest 4/2/05 TREE_FILTER_BY_ATTRIB_MATCH									*
 *  DG 4/18/05 v8.0223 REWRITE_TREE_GET_NODE									*
 *	ML 4/18/2005 XFUNCTION_TREE_MANIPULATION_IN_VC								*
 *	DSC 8/26/05 OCTREE_FIND_NODE_BY_ID_AND_REPEAT_ID							*
 *	DSC 9/26/05 QA70-8113 TEST_DATAID_EXITS_AND_VALID							*
 *	ML 1/13/2006 XVARIABLEBASE_TO_VC											*
 *------------------------------------------------------------------------------*/      

#ifndef _OCTREEUTILS2_H
#define _OCTREEUTILS2_H

#ifdef __AFX_H__
	#ifdef OCTREE_UTILS_DLL
		#define OCTRUT_API __declspec(dllexport)
	#else
		#define OCTRUT_API __declspec(dllimport)
	#endif
	#define string 			CString  //DSC 9/26/05 QA70-8113 TEST_DATAID_EXITS_AND_VALID
	#define TreeNode		OCXmlWrapperBase
	#define StringArray		CScriptMocaObject
	#define	IntArray		CScriptMocaObject
	#define	UIntArray		CScriptMocaObject

	extern "C" {
#else
	#define OCTRUT_API
	#pragma dll(OCTree_Utils)	// Associate all functions below to OCTree_Utils.dll which must be in the Origin EXE folder
	#define	IntArray	vector<int>
	#define	UIntArray	vector<uint>

#endif	//__AFX_H__


#ifdef _NOT_READY

//OCTRUT_API BOOL	octree_filter_by_attrib_match(TreeNode* ptr, int iUnitNodeID, LPCSTR lpcstrAttrib, LPCSTR lpcstrPattern, BOOL bCaseSensitive = FALSE);

/**#
	for debug only
*/
void out_tree_dataID(int nDataID, TreeNode* tr, int nLevel = 0);

// Comments last updated by Frank on 03/17/2005
/** >Basic I/O
		Dump a tree to a specified output, also show standard attributes if any
	Parameters:
		tr= [Input] TreeNode to dump to output
		lpcsz= [Input] optional string to diplay before the dump
		nOutput= [Input] one of the constants defined in oc_const.h,
		enum {WRITE_SCRIPT_WINDOW, WRITE_STATUS_BAR, WRITE_OUTPUT_LOG, WRITE_MESSAGE_BOX, WRITE_COMPILER_OUTPUT};
	Example1:
		void tree_dump_ex1()
		{
			Tree tr;
			tr.Grade.Math.dVal = 90.5;
			tr.Grade.English.dVal = 95.5;
			tree_dump(tr, "*****************", WRITE_COMPILER_OUTPUT);
		}
	Return:
		TRUE if given tree is a valid TreeNode
	SeeAlso:
		out_tree	
*/
bool tree_dump(const TreeNode* tr, LPCSTR lpcsz = NULL, int nOutput = WRITE_SCRIPT_WINDOW); //Dump a tree to a specified output


///-----Frank 11/05/05 GET_NODE_BY_ATTRIBUTE_OF_ROW
/** >Tree
		Get TreeNode by provided Row and search attribute matching. Find TreeNode from 0 level.
	Parameters:
		nStopLevel=[Input]specify the stop level in TreeNode to search
		lpcszSkipSubTreeAttrib = [input] if no NULL, skip the arrribute of sub tree, If NULl, do nothing
		nCurrentLevel = [input] middle variable, unmeaning for user
	Parameters:
		tr=[input]TreeNode to walk
		nRow=[Input]to find the nRow TreeNode from up to down, 0 based offset
		lpcszAttrName=[input]treenode attribute name to find, if exist and value equal to lpcszAttrValue, then is the node find.
		lpcszAttrValue=[input]value of the treenode attribute.
		lpInc = [input]	middle variable, unmeaning for user
	Return:
		Returns the TreeNode be found, invalid tree node if not found.
*/
TreeNode tree_get_node_by_attribute(TreeNode &tr, int nRow, LPCSTR lpcszAttrName , LPCSTR lpcszAttrValue = NULL,int* lpInc = NULL);
///-----End GET_NODE_BY_ATTRIBUTE_OF_ROW

// Comments last updated by Iris on 02/25/2005
///	Frank 06/16/04	v8.0890	TREE_SET_VALUE_FROM_VECTOR
/** >Tree
		Set string value to the TreeNode, setting order as the vector index
	Parameters:
		tr = [modify]TreeNode to set value
		vs = [input]vector of the value want to input to treenode, if it is branch node, the cell will empty.
		lpnSections = [modify]index of the start cell of the vector
	Return:
		false if tr is invalid
*/
bool tree_set_values( TreeNode &tr, vector<string>& vs, int* lpnSections = NULL);//=0);
//End TREE_SET_VALUE_FROM_VECTOR
// Comments last updated by Iris on 01/05/2005
/** >Tree
		Get both the numeric value of a tree node as well as its associated label
	Parameters:
		tr=[Input]TreeNode to get
		strLabel=[Input]the text label if present, otherwise the tagName
		dDefault=[Input]default value in case node is not a valid node
	Example1:
		void tree_node_get_double_ex1()
		{
			Tree tr;
			TreeNode trFirst = tr.AddNumericNode(1.0, "First", 1);
			string strLabel = "Label";
			trFirst.SetAttribute(STR_LABEL_ATTRIB, strLabel);
			
			double dVal = tree_node_get_double(trFirst, strLabel, 0);
			out_double("", dVal);
			dVal = tree_node_get_double(tr.Second, strLabel, 0); //tr.Second is an invalid node
			out_double("", dVal);	
		}		
	Return:
		Returns the numeric value
*/
double tree_node_get_double(TreeNode& tr, string& strLabel, double dDefault = _ONAN);

/**# >Operation
*/
BOOL	load_default_settings(Tree& tr, LPCSTR lpcszClassName, int nCategory = SETTINGS_MAIN);
// Comments last updated by Iris on 02/25/2005
/** >Tree
		Duplicate tree node and update tag name
	Parameters:
		trN = [modify]the source tree node
		lpcstrSor = [input]the name of source tree node
		lpcstrDes = [intput]the name of destination tree node
	Return:
		Returns duplicate tree node.			
*/

TreeNode duplicate_treenode_with_new_name(TreeNode &trN, LPCSTR lpcstrSor, LPCSTR lpcstrDes);
///Frank 12/14/04 AUTO_SET_MULTILINE_EDIT_SHOW_RANGE
// Comments last updated by Iris on 02/25/2005
/**# >Tree
*/
void check_set_multiline_edit_range_display(TreeNode trGetN, int nMinRow, int nMaxRow = -1);
///End AUTO_SET_MULTILINE_EDIT_SHOW_RANGE
///Frank 1/24/05 v8.0185 CENTRALIZE_CODE_OF_FILE_NAME_ATTRIB
// Comments last updated by Iris on 02/25/2005
/** >Tree
		Set filename to tree attribute.
	Parameters:
		tr = [Input]TreeNode wand set file name.
		lpcszFileName = [Input] File name info.
	Example1: 
		void tree_set_file_name_ex1()
		{
			Tree tr;
			string strFileName = "TreeFile";
			ASSERT(tree_set_file_name(tr, strFileName));
		}
	Return:
		TRUE if success, else false
	SeeAlso:
		tree_get_file_name	
*/
bool tree_set_file_name(TreeNode &tr, LPCSTR lpcszFileName);

// Comments last updated by Iris on 02/25/2005
/** >Tree
		Get file name to tree attribute .
	Parameters:
		tr = [Input]TreeNode wand set file name.
		strFileName = [Output] File name info.
	Example1: 
		void tree_get_file_name_ex1()
		{
			Tree tr;
			string strFileName = "TreeFile";
			ASSERT(tree_set_file_name(tr, strFileName));
			string strFileNewname;
			ASSERT(tree_get_file_name(tr, strFileNewname));
			out_str( strFileNewname);
		}
	Return:
		TRUE if success, else false
	SeeAlso:
		tree_get_file_name	
*/
bool tree_get_file_name(TreeNode &tr, string &strFileName);
///End5 CENTRALIZE_CODE_OF_FILE_NAME_ATTRIB

/** >Tree
	copy source tree to destination, remove children of TreeNode with given DataID
Parameters:
	trDest = [modify] destination tree node
	trSrc = [input] source tree node
	nUnitNodeID = [input] Data ID	
Return:
	true on success, false on failure	
Example1:	
	int tree_copy_remove_children_ex1()
	{
		Tree tr;
		TreeNode trPh = tr.AddNode("physics");
		trPh.ExamMonth.strVal = "May";
		
		TreeNode trMath = tr.AddNode("Math");
		TreeNode trTeacher = trMath.AddTextNode("Danice", "Teather");
		trTeacher.DataID = 1;
		trTeacher.Other.strVal = "Male";
		
		TreeNode trCount = trMath.AddNumericNode(100, "Count");
		trCount.DataID = 2;
		trCount.Other.strVal = "First";
		
		//Copy the children of trMath to trPh, the Other node of trCount is copied but the Other node
		//of trTeacher is not copied
		tree_copy_remove_children(trPh, trMath, trCount.DataID);
		return 1;
	}
*/
bool tree_copy_remove_children(TreeNode& trDest, const TreeNode& trSrc, int nUnitNodeID);
// Comments last updated by Frank on 03/17/2005
///Forest 03/17/05 GO_THROUGH_TREE_USING_LOOP_INSTEAD_OF_RECURSION
/** >Tree
	get next tree node using preorder traversal
Parameters:
	trCur = [input]current tree node
	trNext = [output]next tree node
	lpcstrStopAttrib =[input] stop attribute, children of tree node with such attribute will be omitted
	lpcstrStopValue = [input] stop attribute value, if not null, only when stop attribute of tree node is this value, it no longer travels its children
Return:
	Returns true if current tree node has next node
Example:
	//this is an example showing how to go through all the tree nodes using loop instead of recursion
	bool	tree_get_next_node_ex1()
	{
		Tree	tr("c:\\sample.xml");
		if(!tr)
			return	false;
		TreeNode 	trCurrent = tr;
		while(1)
		{
			out_str(trCurrent.tagName);
			TreeNode trNext;
			if(!tree_get_next_node(trCurrent, trNext))
				break;
			trCurrent = trNext;
		}
		return	true;
	}	
*/
bool tree_get_next_node(const TreeNode& trCur, TreeNode& trNext, LPCSTR	lpcstrStopAttrib = NULL, LPCSTR lpcstrStopValue = NULL);
///End GO_THROUGH_TREE_USING_LOOP_INSTEAD_OF_RECURSION
///Kevin 11/24/05	ADD_TREE_FIND_MAX_DATA_ID_FUNCTION
int tree_find_max_data_id(TreeNode& tr, bool bDeep=false, TreeNode* pFound = NULL);
///End ADD_TREE_FIND_MAX_DATA_ID_FUNCTION
/// YuI 11/09/05 QA70-8279 REPORT_TREE_AND_REPORT_DATA_XVARIABLES
void tree_filter_for_report_generation(TreeNode& tr);
/// end REPORT_TREE_AND_REPORT_DATA_XVARIABLES
///Hong 08/04/06 THEME_TREE_GET_NODE_BY_ID
TreeNode theme_tree_get_node_by_id(TreeNode* tr, int nID, bool bRecursive = false);
///End 08/04/06 THEME_TREE_GET_NODE_BY_ID

///Hong 08/04/06 THEME_TREE_GET_NODE_BY_INDEX
TreeNode theme_tree_get_node_by_id(TreeNode* tr, int nID, int nIndex = -1, bool bRecursive = false);
///End 08/04/06 THEME_TREE_GET_NODE_BY_INDEX
#endif //#ifdef _NOT_READY


///READY

// Comments last updated by Iris on 02/25/2005
//----- CPY 6/16/04 QA70-6294 OC_INPUT_DATA_NODE_CLEANUP
/** >Tree
	set the attributes to all nodes in the given tree
	Parameters:
		tr = [modify]root tree node to set attributes
		lpcszAttrib = [input]name of attribute to set
		lpcszAttribVal = [input]value of attribute to set
		b1stLevelChildrenOnly = [input]true will set only the immediate children, false will set current node as well as all child nodes recursively
		bBranchOnly = [input] true will set only branch tree node, false will set all tree node
*/
//OCTRUT_API void octree_set_attribute_to_all_nodes(TreeNode* tr, LPCSTR lpcszAttrib, LPCSTR lpcszAttribVal, bool b1stLevelChildrenOnly = false, bool bBranchOnly = false);


///Danice 11/15/04 QA70-7169 TREE_ROW_SHOW_ALTERNATE_COLORS
// Comments last updated by Iris on 02/25/2005
/** Tree
		Get TreeNode level
	Example1:
		void tree_get_level_ex1()
		{
			Tree tr;
			TreeNode tn=tr.AddNode("L1");
			for(int ii=2; ii<4; ii++)
				tn=tn.AddNode("L"+ii);
			int nLevel=tree_get_level(tn);
			out_int("Tree Node level is ", nLevel);
		}
	Parameters:
		trNode = [input]the tree node to walk		
	Return:
		the level of TreeNode
*/
//OCTRUT_API int octree_get_level(TreeNode* trNode);

// Comments last updated by Iris on 02/25/2005
/** >Tree
		Set tree node value by node id
	Parameters:
		trSetting = [modify]the tree node that need setting values
		vnNodeIDs = [input] the vector of node is
		vsValues = [input] the vector of value
	Return:
		number of the setted value tree node
*/
//OCTRUT_API int octree_set_values_by_nodeids(TreeNode* trSetting, IntArray* vnNodeIDs, StringArray* vsValues);


// return total number of nodes set to be hidden
// Comments last updated by Iris on 02/25/2005
/**
		Walk all tree nides and set all empty ones to be hidden 
	Parameters:
		tr = [input]the tree node to walk
		bRecursive = [input]true will walk the entire tree, false will only the current tree node
	Return:
		number of the empty tree nodes
*/
//OCTRUT_API int octree_hide_empty_nodes(TreeNode* tr, bool bRecursive = true);

// Comments last updated by Iris on 02/25/2005
/**
		Scan all child nodes and see if any not empty, then set the specified bit in the given attribute
	Parameters:
		tr = [modify]tree node to set the attribute
		lpcszAttribute = [input]attribute to set
		dwBit = [input]the specify bit(s) to turn on if any child node not empty
		bRecursive = [input]true will walk the entire tree, false will only the current tree node
	Return:
		true if attribute modified by this function
*/  
//OCTRUT_API BOOL octree_set_attribute_bit_if_not_empty(TreeNode* tr, LPCSTR lpcszAttribute, DWORD dwBit, bool bRecursive = true);	//---- CPY 12/17/04 SHOW_MISSING_MASED_TABLES_IF_NOT_EMPTY


// Comments last updated by Iris on 01/05/2005
/** >Tree
		Copy attribute from TreeNode trSrc to trDest
	Parameters:
		trSrc=[Input]source TreeNode
		trDest=[Modify]destination TreeNode
		lpcszAttribute=[Input]specify attribute name to copy
	Example1:
		void tree_node_copy_attribute_ex1()
		{
			Tree tr;
			TreeNode trFirst = tr.AddNode("First");
			TreeNode trSecond = tr.AddNode("Second");
			trFirst.SetAttribute(STR_LABEL_ATTRIB, "All Nodes Label");
			
			bool bRet = tree_node_copy_attribute(trFirst, trSecond, STR_LABEL_ATTRIB);
			string strLabel;
			trSecond.GetAttribute(STR_LABEL_ATTRIB, strLabel);
			out_str(strLabel);
		}		
	Return:
		true if trSrc has given attribute and is copied to trDest
*/
//OCTRUT_API BOOL octree_node_copy_attribute(TreeNode* trSrc, TreeNode* trDest, LPCSTR lpcszAttribute);

//OCTRUT_API string octree_get_node_label(TreeNode *tr, bool bGetLabelFirst = true);

//OCTRUT_API int octree_remove_attribute(TreeNode *tr, LPCSTR lpcszAttribute);

//OCTRUT_API BOOL octree_get_node_names(TreeNode *tr, StringArray *vs, bool bSubNodeOnly = false);

//OCTRUT_API void octree_clear_all_value(TreeNode *tr);

//OCTRUT_API BOOL octree_check_attribute_value_exist(TreeNode *tr, LPCSTR lpcszVal, LPCSTR lpcszAttrib, bool bCaseSensitive = false, bool bRecursive = false);

//OCTRUT_API BOOL octree_get_node_by_id(TreeNode *tr, TreeNode *trOut, int nID, bool bRecursive = false);

//OCTRUT_API BOOL octree_branch_to_key_value_pairs_str(TreeNode *tr, string& strMultiline, string strKVSep = '=', string strLineSep = '\n');
//OCTRUT_API BOOL octree_branch_to_key_value_pairs_str(TreeNode *tr, string* pstrMultiline, char cKVSep = '=', char cLineSep = '\n'); //CPY 7/19/06 FIX_BAD_DEFAULT_STR

//OCTRUT_API BOOL octree_set_or_remove_attribute(TreeNode *tr, LPCSTR lpcszAttribute = NULL,  bool bAdd = false, LPCSTR lpcszAttribValue = NULL);

//OCTRUT_API BOOL	octree_is_in_ids_range(TreeNode *trNode, int nBeginID, int nEndID, int nOffset = 0);

//OCTRUT_API BOOL	octree_get_root_node(TreeNode *tr, TreeNode *trRoot);

//OCTRUT_API BOOL octree_changed_data(TreeNode *tn, int nValue = -1);

//OCTRUT_API BOOL octree_key_value_pairs_str_to_branch(TreeNode *tr, LPCSTR lpcszMultiline, char cKVSep = '=', char cLineSep = '\n');

//OCTRUT_API bool octree_tree_read_values_with_ids(LPCSTR lpcszFullFilename, IntArray* pocvnIDs, StringArray* pocvsValues, string* lpcszTreeNodeComment = NULL );

//OCTRUT_API int octree_GETN_reset_hidden_values(TreeNode *tr, IntArray *pvnDataIDsToReset, bool bRecursive = true );

//OCTRUT_API void octree_get_enum_node_name(TreeNode *trNode, string *strOut, LPCSTR strPrefix);

//OCTRUT_API void octree_get_enum_attribute_value(TreeNode *trNode, string *strOut, LPCSTR strAttribute, LPCSTR strPrefix);

//OCTRUT_API bool octree_set_advanced_settings_file(TreeNode *trGUI, LPCSTR strFileName = "");

//OCTRUT_API void octree_get_advanced_settings_file(TreeNode *trGUI, string *strOut);

//OCTRUT_API int octree_append_children(TreeNode *tr1, TreeNode *tr2, LPCSTR lpcszPrefix);

//OCTRUT_API int octree_get_next_enum_tag_name(TreeNode *tr, string *strTag = NULL);	

//OCTRUT_API int octree_move_node(TreeNode *tr, int nRow, int nPosition = -1, DWORD dwCntrl = 0, LPCSTR lpcszAttribute = NULL);

//OCTRUT_API string octree_get_GetN_background_colors(UINT *nLeafFirstColor, UINT *nLeafSecondColor, UIntArray *vnBranchColors);
//OCTRUT_API int octree_tree_to_str(TreeNode *tr, string& str, IntArray *vnDisplayFormat = NULL, bool bSkipHidden = true, bool bSimpleTypesOnly = true, bool bCheckUseLabel = true, bool bIncludeParentNamePrefix  = false, LPCSTR lpcszDoubleValueFormat = NULL,  bool bIncludeAuxDisplayInfo = false);



/// TD 4-12-06 VC_FUNCTIONS_TO_LAUNCH_XFN_GETN
//OCTRUT_API int octree_tree_get_theme_type(TreeNode* tr);
//OCTRUT_API bool octree_tree_get_theme_file_name(TreeNode *tr, string *pstrThemeFileName);
//OCTRUT_API bool octree_tree_set_theme_file_name(TreeNode *tr, LPCSTR lpcszThemeFileName);
//OCTRUT_API bool octree_tree_save_values_with_ids(LPCSTR lpcszFullFilename, IntArray* pocvnIDs, StringArray* pocvsValues, LPCSTR lpcszTreeNodeComment );
/// end VC_FUNCTIONS_TO_LAUNCH_XFN_GETN


#ifdef __AFX_H__
	}
#endif	//__AFX_H__

#endif //_OCTREEUTILS2_H

