package coding;


/**
 * Container for the encoding and processing of a character
 * 
 * @author Benjamin Gojman
 */
public class CodeWord implements Comparable<CodeWord> {

	int frequency;
	int character;
	String code;
	CodeWord leftChild;
	CodeWord rightChild;
	int depth;

	public CodeWord() {
		leftChild = null;
		rightChild = null;
		this.frequency = -1;
		this.character = -1;
		depth = 0;
	}
	
	public CodeWord(int frequency, int character) {
		leftChild = null;
		rightChild = null;
		this.frequency = frequency;
		this.character = character;
		depth = 0; //helps keep the codes from exploding if frequency == 0
	}

	public CodeWord(CodeWord leftChild, CodeWord rightChild) {
		this(leftChild.frequency + rightChild.frequency, Math.min(
				leftChild.character, rightChild.character));
		this.leftChild = leftChild;
		this.rightChild = rightChild;
		this.depth = Math.max(leftChild.depth, rightChild.depth) + 1;
		
	}

	public void PopulateCodeTree(int character, String code) {
		if (code.length() > 0) {
			String car = code.substring(0, 1);
			String cdr = code.substring(1);
			if (car.equals("1")) {
				if (rightChild == null)
					rightChild = new CodeWord();
				rightChild.PopulateCodeTree(character, cdr);
			} else { //== 0
				if (leftChild == null)
					leftChild = new CodeWord();
				leftChild.PopulateCodeTree(character, cdr);
			}
		} else {
			this.character = character;
		}
			
	}
	
	public CodeWord getCharacter (String nextBit) {
		if(nextBit.equals("1"))
			return rightChild;
		return leftChild;
	}
	
	public void createCodes(String code, CodeWord[] finalCode) {
		finalCode[character] = this;
		this.code = code;
		if (leftChild != null && rightChild != null) {
			leftChild.createCodes(code + "0", finalCode);
			rightChild.createCodes(code + "1", finalCode);
		}
		
		
	}

	public int compareTo(CodeWord o) {
		int order = new Integer(frequency).compareTo(new Integer(o.frequency));
		if (order == 0)
			order = new Integer(depth).compareTo(new Integer(o.depth));
		if (order == 0)
			return new Integer(character).compareTo(new Integer(o.character));
		return order;
	}

	public String toString() {
		return code + " " + character + " " + frequency;
//		return ((char) character ) + " " + character + " " + frequency + " " + code;
	}
}

