/* BEGIN_HEADER                                              Java TreeView
 *
 * $Author: avsegal
 * $RCSfile: TreeAnalysisNode.java
 * $Revision: 
 * $Date: Jun 25, 2004
 * $Name:  
 *
 * This file is part of Java TreeView
 * Copyright (C) 2001-2014 Alok Saldanha, All Rights Reserved. Modifications Copyright (C) Lawrence Berkeley Lab.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * END_HEADER
 */
 
package edu.stanford.genetics.treeview.plugin.dendroview;

/**
 * @author avsegal
 *
 * Generic class for analysis of ATR and GTR trees.
 */

import java.util.Vector;

public abstract class TreeAnalysisNode {
	
	/**
	 * Create a new node with given id.
	 * @param pID the id of the node
	 */
    TreeAnalysisNode(String pID)
	{
		id = pID;
		left = null;
		right = null;
		parent = null;
	}
	
    /**
     * Create a new node with a given id and parent.
     * @param pID the id of the node
     * @param pParent the parent of the node
     */
	TreeAnalysisNode(String pID, TreeAnalysisNode pParent)
	{
		id = pID;
		left = null;
		right = null;
		parent = pParent;
	}
	
	/**
	 * Gets the node's id.
	 * @return the id
	 */
	public String getID()
	{
		return id;
	}
	
	/**
	 * Gets the index of this node.
	 * @return the index
	 */
	public int getIndex()
	{
		return index;
	}

	/**
	 * Sets the index of this node.
	 * @param ind index to set
	 */
	public void setIndex(int ind)
	{
		index = ind;
	}
	
	/**
	 * Is this a root node?
	 * @return true if this node is a root, false otherwise
	 */
	public boolean isRoot()
	{
		return (parent == null);
	}
	
	/**
	 * Is this a leaf node?
	 * @return true if this node is a leaf, false otherwise
	 */
	public boolean isLeaf()
	{
		return (left == null && right == null);
	}
	
	/**
	 * Gets the leftmost leaf of the subtree rooted at this node.
	 * @return the leftmost leaf of subtree.
	 */
	public TreeAnalysisNode getLeftLeaf()
	{
		if(isLeaf())
		{
			return this;
		}
		
		if(left != null)
		{
			return left.getLeftLeaf();
		}
		
		return right.getLeftLeaf(); // right cannot be null, otherwise this is a leaf			
	}

	/**
	 * Gets the rightmost leaf of the subtree rooted at this node.
	 * @return the rightmost leaf of subtree.
	 */
	public TreeAnalysisNode getRightLeaf()
	{
		if(isLeaf())
		{
			return this;
		}
		
		if(right != null)
		{
			return right.getRightLeaf();
		}
		
		return left.getRightLeaf(); // left cannot be null, otherwise this is a leaf			
	}
	
	/**
	 * Switched the left and right child.
	 *
	 */
	public void flip()
	{
		TreeAnalysisNode temp;
		
		temp = left;
		left = right;
		right = temp;	
	}
	
	/**
	 * Gives a listing, in order, of all nodes in this tree.
	 * @param v vector to be filled with the listing
	 */
	public void enumerate(Vector v)
	{
		if(left != null)
		{
			left.enumerate(v);
		}
		
		v.add(this);
		
		if(right != null)
		{
			right.enumerate(v);
		}		
	}
	
	/**
	 * Computes the root of this node's tree.
	 * @return the root node
	 */
	public TreeAnalysisNode findRoot()
	{
		if(isRoot())
		{
			return this;
		}
		
		return parent.findRoot();
	}
	/**
	 * Find a node with given id in this subtree.
	 * @param id id to look for
	 * @return node found, or null if no such node exists
	 */
	public TreeAnalysisNode find(String id)
	{
		TreeAnalysisNode temp;
		
		if(getID().equals(id))
		{
			return this;
		}
		
		if(left != null)
		{
			temp = left.find(id);
			if(temp != null)
			{
				return temp;
			}
		}
		
		if(right != null)
		{
			temp = right.find(id);
			if(temp != null)
			{
				return temp;
			}
		}
		
		return null;		
	}
	
	/**
	 * Set the left child.
	 * @param node left child
	 */
	public void setLeft(TreeAnalysisNode node)
	{
		left = node;
	}
	
	/**
	 * Gets the left child.
	 * @return left child
	 */
	public TreeAnalysisNode getLeft()
	{
		return left;
	}
	
	/**
	 * Set the right child.
	 * @param node right child
	 */
	public void setRight(TreeAnalysisNode node)
	{
		right = node;
	}
	
	/**
	 * Gets the right child.
	 * @return right child
	 */
	public TreeAnalysisNode getRight()
	{
		return right;
	}
	
	/**
	 * Sets the parent.
	 * @param node parent
	 */
	public void setParent(TreeAnalysisNode node)
	{
		parent = node;
	}
	/**
	 * Gets the parent.
	 * @return parent
	 */
	public TreeAnalysisNode getParent()
	{
		return parent;
	}
	
	TreeAnalysisNode left;
	TreeAnalysisNode right;
	TreeAnalysisNode parent;
	String id;
	int index;
	
}