/** Class for storing a node in a binary tree
 * Each node stores data of type E
 */
public class BinaryTreeNode<E> {
	/** Data stored in the node*/
	private E data;
	/** Left child; null if left child does not exist */
	private BinaryTreeNode<E> left;
	/** Right child; null if right child does not exist */
	private BinaryTreeNode<E> right;
	/** Parent; null if root of the tree */
	private BinaryTreeNode<E> parent;

	/** Creates a node with the given data and no children or parent. 
	 * @param inData data to be stored in node
	 */
	public BinaryTreeNode(E inData) {
		data = inData;
		left = null;
		right = null;
		parent = null;
	}

	/** Creates a node with the given data, children, and parent. 
	 * @param inData data to be stored in node
	 * @param inLeft left child
	 * @param inRight right child
	 * @param inParent parent node
	 */
	public BinaryTreeNode(E inData, BinaryTreeNode<E> inLeft, BinaryTreeNode<E> inRight, BinaryTreeNode<E> inParent) {
		data = inData;
		left = inLeft;
		right = inRight;
		parent = inParent;
		if (inLeft != null) { 
			inLeft.parent = this;
		}
		if (inRight != null) {
			inRight.parent = this;
		}
	}

	/** Returns the data stored in this node. 
	 * @return data
	 */
	public E getData() {
		return data;
	}

	/** Returns the right child, or null if none. 
	 * @return right child 
	 */
	public BinaryTreeNode<E> getRight() {
		return right;
	}

	/** Returns the left child, or null if none. 
	 * @return left child
	 */
	public BinaryTreeNode<E> getLeft() {
		return left;
	}

	/** Returns the parent node, or null if this is the root. 
	 * @return parent node
	 */
	public BinaryTreeNode<E> getParent() {
		return parent;
	}

	/** Sets the right child and updates its parent pointer. 
	 * @param newRight new right child; may not be null
	 * @post newRight is the right child of this; this is the parent of newRight
	 */
	public void setRight(BinaryTreeNode<E> newRight) {
		right = newRight;
		newRight.parent = this;
	}

	/** Sets the left child and updates its parent pointer. 
	 * @param newLeft new left child; may not be null
	 * @post newLeft is the left child of this; this is the parent of newLeft
	 */
	public void setLeft(BinaryTreeNode<E> newLeft) {
		left = newLeft;
		newLeft.parent = this;
	}

}
