/*------------------------------------------------------------------------------*
 * File Name: Tree.h															*
 * Creation: TD 12-19-02														*
 * Purpose: Origin C support for a general Tree/TreeNode						*
 * Copyright (c) OriginLab Corp.2003											*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:07/25/03_PRITHVI_ADDED_DOCUMENTATION_FOR_METHODS_IN_		*
 *					TREENODE_CLASS												*
 *------------------------------------------------------------------------------*/

 
#ifndef _TREE_H
#define _TREE_H


#include <common.h>
#include <Collection.h>

/** >Composite Data Types
*/
class PropertyNode
{
public:
	PropertyNode();
	PropertyNode(PropertyNode &tn);
	
	int    				nVal;	
	double 				dVal;
	string				strVal;
	// vector data
	vector<double>		dVals;
	vector<float>		fVals;
	vector<int>			nVals;
	vector<short>		sVals;
	vector<char>		bVals;
	vector<string>      strVals;

	matrix<double>		dVals2;
	matrix<float>		fVals2;
	matrix<int>			nVals2;
	matrix<short>		sVals2;
	matrix<char>		bVals2;

};

/** >Composite Data Types
*/
class TreeNode :public PropertyNode
{
public:
	
	/** 
	
			Default contructor.
		Example:
			void test()
			{	Tree myTree;
				TreeNode tn1;
				tn1 = myTree.AddTextNode("abc", "node2", 2);
				out_tree(myTree);
			}
	*/		
	
	TreeNode(); //Default contructor

	/** 
	
			Contructor.
		Example:
			void test()
			{	Tree myTree1;
				TreeNode tn1;
				tn1 = myTree1.AddTextNode("abc", "node1", 1);
				
				Tree myTree2;
				TreeNode tn2(tn1);
				bool flag = myTree2.AddNode(tn2, FALSE);
				out_tree(myTree1);
				out_tree(myTree2);
			}
	*/		

	TreeNode(TreeNode &tn);//Contructor
	
	string 				Text;		
	int    				nVal;	
	double 				dVal;
	string				strVal;
	int					ID;
	int					Show;
	int					Enable; // -1 if attribute not in node
	
	string				tagName;		//read only

	// iterators -- syntax similar to C#
	TreeNode			FirstNode;		//read only
	TreeNode			NextNode;		//read only
	TreeNode			PrevNode;		//read only
	TreeNode			LastNode;		//read only

	/** 
	
			Gets a node from a tree when the name of the node is given.
		Parameters:
			Name = name of the node
		Returns:
			The node whose name matches the given name.
		Example:
			#include <Tree.h>
			void test()
			{	Tree myTree;
				TreeNode tn1, tn2, tn3;
				tn2 = myTree.AddTextNode("abc", "node2", 2);
				tn3 = tn2.AddTextNode("efg", "node3", 3);//tn2 is adding tn3 as its child
				tn1 = tn2.GetNode("node3");//now tn1 has tn3 as its child  
			}
	*/		
	TreeNode			GetNode(LPCSTR Name); // Find child by name
	
	/** 
	
			Gets the parent of a node in a tree.
		Returns: 
			 Parent node of the child node which calls this method.
		Example:
			void test()
			{
				Tree myTree;
				TreeNode tn1, tn2, tn3;
				tn2 = myTree.AddTextNode("abc", "node2", 2);
				tn3 = tn2.AddTextNode("efg", "node3", 3);//tn2 is adding tn3 as its child
				tn1 = tn3.Parent();//now tn1 has the parent of tn3  		
			}
	
	*/			
	TreeNode			Parent(); // Find parent -- Null if parent is not an element node
	
	
	/** 
	
			Creates a clone of a node i.e., creates an exact copy of a node and its contents. 
			If bDeep is true, copies the whole branch.
		Parameters:
			bDeep = TRUE or FALSE
		Returns: 
			 The cloned node
		Example:
			void test()
			{
				Tree myTree1, myTree2;
				TreeNode tn1, tn2, tn3;
				tn2 = myTree2.AddTextNode("abc", "node2", 2);
				tn3 = tn2.AddTextNode("efg", "node3", 3);//tn2 added tn3 as its child
				
				tn1 = tn2.Clone(TRUE);//TRUE, copies the tn2 as well as its sub-branch 	
				bool flag = myTree2.AddNode(tn1);
				out_tree(myTree1);
				out_tree(myTree2);
			}
	*/			
	TreeNode			Clone(BOOL bDeep = TRUE); // Clones a Node, if bDeep is true, copies the whole branch

	
	/** 
	
			Removes all the attributes and the children of a node or a tree.
		Example:
			void test()
			{
				Tree myTree;
				TreeNode tn1;
				tn1 = myTree.AddTextNode("abc", "node1", 1);
				out_tree(myTree);
				myTree.Reset();
				out_tree(myTree);
			}
	
	*/	
	void	Reset();	
	
	/** 
	
			Adds a reference to an existing node (in the same tree or another tree).
		Parameters:
			tn = the new node to be added to the tree
			bDeep = TRUE or FALSE; 
		Returns: 
			 TRUE if the node is successfully added; FALSE otherwise
		Example:
			void test()
			{	Tree myTree1;
				TreeNode tn1;
				tn1 = myTree1.AddTextNode("abc", "node1", 1);
				out_tree(myTree1);
				
				Tree myTree2;
				TreeNode tn2(tn1); // adds a node from myTree1	
				bool flag = myTree2.AddNode(tn2, FALSE);	
				out_tree(myTree2);
			}
	*/				
	BOOL				AddNode(TreeNode &tn, BOOL bDeep = TRUE);

	/** 
	
			Replaces a node in the tree.
		Parameters:
			tn = the new node to be added to the tree
			bDeep = TRUE or FALSE; 
		Returns: 
			 TRUE if the node is successfully replaced; FALSE otherwise
		Example:
			void test()
			{
				Tree myTree;
				TreeNode tn1, tn2, tn3;
				tn1 = myTree.AddNumericNode(123, "node1", 1);			
				tn2 = myTree.AddTextNode("abc", "node2", 2);
				tn3 = tn2.AddTextNode("abc", "node3", 2);
				out_tree(myTree);
				
				bool flag1 = tn3.Replace(tn1, TRUE);
				if(flag1) printf("node3 successfully replaced \n");
				out_tree(myTree);
				
			}
			
	*/			

	BOOL				Replace(TreeNode &tn, BOOL bDeep = TRUE);
	
	/** 
	
			Gives the number of nodes in the tree.
		Parameters:
		Returns: 
			 number of nodes in the tree
		Example:
			void test()
			{
				Tree myTree;
				TreeNode tn1, tn2, tn3;
				tn1 = myTree.AddNumericNode(123, "node1", 1);			
				tn2 = myTree.AddTextNode("abc", "node2", 2);
				tn3 = tn2.AddTextNode("abc", "node3", 2);
				printf("number of nodes in myTree = %d", myTree.GetNodeCount());
			}
	*/				
	int					GetNodeCount();
	
	/** 
			Creates a new node with the specified name & id and returns that node.
		Parameters:
			name  = the name of the new node to be added to the tree
			nChildID = the id of the new node to be added to the tree
		Returns: 
			 A new node bearing the name and the id.
		Example:
			void test()
			{
				Tree myTree;
				TreeNode tn1, tn2, tn3;
				tn1 = myTree.AddNode("node1", 1);
				tn2 = myTree.AddTextNode("abc", "node2", 2);
				tn3 = tn2.AddTextNode("efg", "node3", 3);
			}
	
	*/
	
	TreeNode			AddNode(LPCSTR Name = NULL, int nChildID = -1); //NodeID will not be created if < 0
	
	/** 
			Creates a new node with the specified name,id and the double value and returns that node. 
		Parameters:
			dVal  = double contents of the node
			name  = the name of the new node to be added to the tree
			nChildID = the id of the new node to be added to the tree; NodeID  will not be created if < 0
		Returns: 
			 A new node bearing the name and the id.
		Example:
			void test()
			{
				Tree myTree;
				TreeNode tn1;	
				tn1 = myTree.AddNumericNode(5.432, "node1", 1);
				out_tree(myTree);
			}
	*/	
	
	TreeNode			AddNumericNode(double  dVal, LPCSTR Name = NULL, int nChildID = -1);
	
	
	/** 
			Creates a new node with the specified name,id and the integer value and returns that node. 
		Parameters:
			nVal  = integer contents of the node
			name  = the name of the new node to be added to the tree
			nChildID = the id of the new node to be added to the tree; node will not be created if < 0
		Returns: 
			 A new node bearing the name and the id.
		Example:
			void test()
			{
				Tree myTree;
				TreeNode tn1;	
				tn1 = myTree.AddNumericNode(5, "node1", 1);
				out_tree(myTree);
			}
	*/		
	TreeNode			AddNumericNode(int nVal, LPCSTR Name = NULL, int nChildID = -1);
	
	
	/** 
			Creates a new node with the specified name,id and the string value and returns that node. 
		Parameters:
			strVal  = string contents of the node
			name  = the name of the new node to be added to the tree
			nChildID = the id of the new node to be added to the tree; node will not be created if < 0
		Returns: 
			 A new node bearing the name and the id.
		Example:
			void test()
			{
				Tree myTree;
				TreeNode tn1;	
				tn1 = myTree.AddTextNode("abcd", "node1", 1);
				out_tree(myTree);
			}
	*/			
	TreeNode			AddTextNode(LPCSTR strVal, LPCSTR Name = NULL, int nChildID = -1);
	
	/** 
			Gets the integer attribute of a node with the specified name. 
		Parameters:
			lpcszAttrName  = name of the node
			nVal  = contains the integer attribute of the node after the function call is finished
		Returns: 
			 True if the node is found; FALSE otherwise
		Example:
			void test()
			{
				Tree myTree;
				TreeNode tn1;
				tn1 = myTree.AddTextNode("abc", "node1", 2);
				int nVal;
	            bool flag1 = tn1.SetAttribute("node2", 5); //creates a new attribute named node2 and gives it an
	            										   //integer value 5 	
				bool flag2 = tn1.GetAttribute("node2", nVal);
				printf("the integer value of the attribute node2 is %d", nVal);
			}
	*/			

	BOOL				GetAttribute(LPCSTR lpcszAttrName, 	int &nVal);
	
	/** 
			Gets the double attribute of a node with the specified name. 
		Parameters:
			lpcszAttrName  = name of the node
			nVal  = After the method call, nVal contains the double attribute of the node.
		Returns: 
			 True if the node is found; FALSE otherwise
		Example:
			void test()
			{
				Tree myTree;
				TreeNode tn1;
				tn1 = myTree.AddTextNode("abc", "node1", 2);
				double dVal;
	            bool flag1 = tn1.SetAttribute("node2", 5.345);//creating a new attribute named node2 and giving it a
	            										   //double value 5.345 
				bool flag2 = tn1.GetAttribute("node2", dVal);
				printf("the double value of the attribute node2 is %d", dVal);
			}
	*/
			
	BOOL				GetAttribute(LPCSTR lpcszAttrName, 	double  &dVal);
	
	/** 
			Gets the string attribute of a node with the specified name. 
		Parameters:
			lpcszAttrName  = name of the node
			strVal  = After the method call, strVal contains the string attribute of the node.
		Returns: 
			 True if the node is found; FALSE otherwise
		Example:
			
			#include <Tree.h>
			void test()
			{
				Tree myTree;
				TreeNode tn1;
				tn1 = myTree.AddTextNode("abc", "node1", 2);
				string strVal;
	            bool flag1 = tn1.SetAttribute("node2", "xyz");//creating a new attribute named node2 and giving it a
	            										   	  //string value "xyz" 
				bool flag2 = tn1.GetAttribute("node2", strVal);
				printf("the string value of the attribute node2 is %d", strVal);
			}
	*/	
	
	
	BOOL				GetAttribute(LPCSTR lpcszAttrName, 	string &strVal);
	
	
	/** 
		Sets the integer value of a node. 
	Parameters:
		lpcszAttrName  = name of the node
		dVal  = contains the integer value to be set into the node.
	Returns: 
		 True if the node is found; FALSE otherwise
	Example:
		
		#include <Tree.h>
		void test()
		{
			Tree myTree;
			TreeNode tn1;
			tn1 = myTree.AddTextNode("abc", "node1", 2);
			int nVal;
            bool flag1 = tn1.SetAttribute("node2", 5); //creating a new attribute named node2 and giving it an
            										   //integer value 5 	
			bool flag2 = tn1.GetAttribute("node2", nVal);
			printf("the integer value of the attribute node2 is %d", nVal);
		}
	*/		
	

	BOOL				SetAttribute(LPCSTR lpcszAttrName, int nVal);
	
	/** 
			Sets the double value of a node. 
		Parameters:
			lpcszAttrName  = name of the node
			dVal  = contains the double value to be set into the node.
		Returns: 
			 True if the node is found; FALSE otherwise
		Example:
			
			#include <Tree.h>
			void test()
			{
				Tree myTree;
				TreeNode tn1;
				tn1 = myTree.AddTextNode("abc", "node2", 2);
				double dVal;
	            bool flag1 = tn1.SetAttribute("node2", 5.345);//creating a new attribute named node2 and giving it a
	            										   //double value 5.345 
				bool flag2 = tn1.GetAttribute("node2", dVal);
				printf("the double value of the attribute node2 is %d", dVal);
			}
	*/		
	
	BOOL				SetAttribute(LPCSTR lpcszAttrName, double  dVal);
	
	/** 
			Sets the string attribute of the node. 
		Parameters:
			lpcszAttrName  = name of the node
			strVal  = contains the string value to be set into the node.
		Returns: 
			 True if the node is found; FALSE otherwise
		Example:
			
			#include <Tree.h>
			void test()
			{
				Tree myTree;
				TreeNode tn1;
				tn1 = myTree.AddTextNode("abc", "node1", 2);
				string strVal;
	            bool flag1 = tn1.SetAttribute("node2", "xyz");//creating a new attribute named node2 and giving it a
	            										   	  //string value "xyz" 
				bool flag2 = tn1.GetAttribute("node2", strVal);
				printf("the string value of the attribute node2 is %d", strVal);
			}
	*/		
	BOOL				SetAttribute(LPCSTR lpcszAttrName, LPCSTR strVal);

	/**
			Removes the attribute of a node.
		Parameters:
			lpcszAttrName = name of attribute
		Returns:
			TRUE if attribute existed and was deleted successfully, FALSE if attribute does not exist.	
		Example:
			void test()
			{
				Tree myTree;
				TreeNode tn1;
				tn1 = myTree.AddTextNode("abc", "node1", 2);
				string strVal;
	            bool flag1 = tn1.SetAttribute("node2", "xyz");//creating a new attribute named node2 and giving it a
	            										   	  //string value "xyz" 
				bool flag2 = tn1.RemoveAttribute("node2");            										   	  
				bool flag3 = tn1.GetAttribute("node2", strVal);
			}
	*/
	BOOL				RemoveAttribute(LPCSTR lpcszAttrName);
	
	
	/**
			Removes the node with the specified id.
		Parameters:
			nChildID = id of the node to be removed
		Returns:
			TRUE if the node existed and was removed successfully; FALSE otherwise.	
		Example:		
			void test()
			{
				Tree myTree;
				TreeNode tn1;
				
				tn1 = myTree.AddNumericNode(5, "node1", 1);	
				printf("number of nodes = %d", myTree.GetNodeCount());		
				
				bool flag = myTree.RemoveChild(1);
				printf("number of nodes = %d", myTree.GetNodeCount());			
			}
	*/
	
	BOOL				RemoveChild(int nChildID);
	
	/**
			Removes the node with the specified name.
		Parameters:
			name = name of the node to be removed
		Returns:
			TRUE if the node existed and was removed successfully; FALSE otherwise.	
		Example:		
			void test()
			{
				Tree myTree;
				TreeNode tn1;
				
				tn1 = myTree.AddNumericNode(5, "node1", 1);	
				printf("number of nodes = %d", myTree.GetNodeCount());		
				
				bool flag = myTree.RemoveChild("node1");
				printf("number of nodes = %d", myTree.GetNodeCount());			
			}
	*/
		
	
	BOOL				RemoveChild(LPCSTR Name);
	
	/**
			Removes the node specified by the object.
		Parameters:
			tn = the node object that has to be removed
		Returns:
			TRUE if the node existed and was removed successfully; FALSE otherwise.	
		Example:		
			void test()
			{
				Tree myTree;
				TreeNode tn1;
				
				tn1 = myTree.AddNumericNode(5, "node1", 1);	
				printf("number of nodes = %d", myTree.GetNodeCount());		
				
				bool flag = myTree.RemoveChild(tn1);
				printf("number of nodes = %d", myTree.GetNodeCount());			
			}
	*/
	
	BOOL				RemoveChild(TreeNode &tn);
	
	/**
			Removes the node with the specified prefix.
		Parameters:
			lpcszPrefix = the prefix of name of the node(s).
		Returns:
			1 if the node existed and was removed successfully; 0 otherwise.	
		Example:		
			void test()
			{
				Tree myTree;
				TreeNode tn1, tn2;
				
				tn1 = myTree.AddNumericNode(5, "node1", 1);	
				tn2 = myTree.AddNumericNode(5, "node2", 1);	
				printf("number of nodes = %d \n", myTree.GetNodeCount());		
				
				int flag = myTree.RemoveChildrenWithPrefix("no");
				printf("number of nodes = %d \n", myTree.GetNodeCount());//should print 0			
			}
	*/	
	int					RemoveChildrenWithPrefix(LPCSTR lpcszPrefix);
	
	/**
			Removes the node that calls this method.
		Parameters:
		Returns:
			TRUE if the node was removed successfully; FALSE otherwise.	
		Example:		
			void test()
			{
				Tree myTree;
				TreeNode tn1;
				tn1 = myTree.AddTextNode("abc", "node1", 2);
				
				bool flag1 = tn1.Remove();
				printf("the number of nodes in myTree = %d", myTree.GetNodeCount());
			}
	*/		
	BOOL				Remove();
	
	/**
			Checks if a given node is a valid node or not
		Parameters:
		Returns:
			TRUE if the node is valid; FALSE otherwise.	
		Example:		
			void test()
			{
				Tree myTree;
				TreeNode tn1;
				tn1 = myTree.AddTextNode("abc", "node1", 2);
				bool flag2 = tn1.IsValid();
			}
	*/	
	
	BOOL				IsValid();
	Collection<TreeNode>	Children;
	
	/**
		Example:
			void run_XML()
			{
				Tree		tr;
				TreeNode  	trNode;
				trNode = tr.AddNode("Node1", 1);
				
				string strXML = tr.XML;
				out_str(strXML);
			}
	*/
	string				XML;	// init treenode from XML string or to get as XML string
};


/** >Composite Data Types
*/
class Tree : public TreeNode
{
	
public:
	
	/**
			Constructor which initializes a tree from an XML file.
		Parameters:
			File = file name
			nType = 0
		Returns:
		Example:		
			void test()
			{
				Tree myTree("xyz.xml", 0);			
			}
	*/		
	Tree(LPCSTR File, int nType = 0);
	
	/**
			Constructor.
		Parameters:
			nType = 0
		Returns:
		Example:		
			void test()
			{
				Tree myTree(0);		
			}
	*/		
	Tree(int nType = 0);
	
	/**
			Gets a tree from an XML file.
		Parameters:
			File = file name
			nType = 0
		Returns: TRUE if the tree can be created; FALSE otherwise
		Example:		
			void test()
			{
				Tree myTree;
				myTree.Load("xyz.xml", 0);			
			}
	*/			
	BOOL	Load(LPCSTR File, int nType = 0);
	
	
	/**
			Saves a tree to an XML file.
		Parameters:
			File = file name
			nType = 0
		Returns: TRUE if the tree can be created; FALSE otherwise
		Example:		
		void test()
			{
				Tree myTree(0);
				TreeNode tn1, tn2, tn3;
				tn1 = myTree.AddNode("node1", 1);
				tn2 = tn1.AddTextNode("abc", "node2", 2);
				tn3 = tn2.AddTextNode("efg", "node3", 3);
				
				myTree.Save("c:\\xyz.xml");
			}
	*/			
	BOOL	Save(LPCSTR lpcszFile);
};



/** >Composite Data Types
	Example:
	   Tree tree;
	   if(tree)
	   {
	       tree.AddNode();
	       tree.AddNumericNode(1);
	       tree.AddNumericNode(2);
	       tree.AddNumericNode(3, "I333");
	       tree.AddNumericNode(4);
	       
	       TreeNodeCollection tnc(tree, "int");
	       foreach(TreeNode tn in tnc)
	       {
	           string str = tn.tagName;
	           out_str(str);
	       }
	   }	
*/
class TreeNodeCollection : public Collection<TreeNode>
{
	public:

		/**
			To get a collection of tree nodes from parent tree node by name profix.
		Parameters:
			node = the parent tree node 
			lpcsz = the name prefix of the tree node
		Example:
		   Tree tree;
		   if(tree)
		   {
		       tree.AddNode();
		       tree.AddNumericNode(1);
		       tree.AddNumericNode(2);
		       tree.AddNumericNode(3, "I333");
		       tree.AddNumericNode(4);
		       
		       TreeNodeCollection tnc(tree, "int");
		       foreach(TreeNode tn in tnc)
		       {
		           string str = tn.tagName;
		           out_str(str);
		       }
		   }	
		*/
		TreeNodeCollection(TreeNode node, LPCSTR lpcsz);
};



#endif //_TREE_H