/**
 * @author Scott Douglas ( scott@scottdouglas.net )
 */

public class HuffmanTreeNode implements Comparable {
	private HuffmanTreeNode left;
	private HuffmanTreeNode right;
	private HuffmanCharacter character;
	private HuffmanBitList bits;
	
	public HuffmanTreeNode( HuffmanCharacter newCharacter ) {
		left = null;
		right = null; 
		character = newCharacter;	
		bits = new HuffmanBitList();
	}
	
	public HuffmanTreeNode() {
		left = null;
		right = null;
		character = null;
		bits = new HuffmanBitList();
	}
	
	public HuffmanCharacter getCharacter() {
		return character;
	}
	
	public HuffmanBitList getBits() {
		return bits;
	}
	
	public void setBits( HuffmanBitList newBits ) {
		bits = newBits;
	}
	
	public void assignBits() {
		if ( left != null ) {
			left.getBits().appendBitList( bits );
			left.getBits().appendBit( false );
			left.assignBits();
		}
		
		if ( right != null ) {
			right.getBits().appendBitList( bits );
			right.getBits().appendBit( true );
			right.assignBits();
		}
	}
	
	public void setNodeValue( HuffmanCharacter newCharacter ) {
		character = newCharacter;
	}
	
	public HuffmanTreeNode getRightNode() {
		return right;
	}
	
	public HuffmanTreeNode getLeftNode() {
		return left;
	}
	
	public void setRightNode( HuffmanTreeNode newNode ) {
		right = newNode;
	}
	
	public void setLeftNode( HuffmanTreeNode newNode ) {
		left = newNode;
	}
	
	public int getCharacterFrequency() {
		int frequency = 0;
		
		if ( character != null ) {
			frequency += character.getFrequency();
		}
		if ( left != null ) {
			frequency += left.getCharacterFrequency();
		}
		if ( right != null ) {
			frequency += right.getCharacterFrequency();
		}
		
		return frequency;
	}
	
	public int compareTo( Object object1 )  {
		HuffmanTreeNode aNode = ( HuffmanTreeNode ) object1;
		int compareValue = 0;

		if ( getCharacterFrequency() < aNode.getCharacterFrequency() ) {
			compareValue = -1;
		} else if ( getCharacterFrequency() > aNode.getCharacterFrequency() ) {
			compareValue = 1;
		} else {
			if ( character == null && aNode.getCharacter() != null ) {
				compareValue = -1;
			} else if ( character != null && aNode.getCharacter() == null ) {
				compareValue = 1;
			} else if ( character == null && aNode.getCharacter() == null ) {
				compareValue = -1;
			} else {
				if ( character.getCharacter() < aNode.getCharacter().getCharacter() ) {
					compareValue = -1;
				} else if ( character.getCharacter() > aNode.getCharacter().getCharacter() ) {
					compareValue = 1;
				} else {
					compareValue = 0;
					System.err.println( "This shouldn't happen" );				
				}
			}
		}
		return compareValue;
	}
	
	public boolean equals( Object object ) {
		boolean areEqual = false;
	
		if ( object instanceof HuffmanTreeNode ) {
			HuffmanTreeNode other = ( HuffmanTreeNode ) object;
			areEqual = getCharacterFrequency() == other.getCharacterFrequency();
		}
	
		return areEqual;
	}
	
	public String toString() {
		String representation;
		
		if ( character != null ) {
			representation = character.toString();
		} else {
			representation = "[ null, " + getCharacterFrequency() + ", " + bits + " ]";
		}
		
		return representation;
	}
}

