package ash.util;
import java.io.PrintStream;
import java.util.Iterator;

/**
 * 木構造を表示する
 */
public class PrintTree<T extends PrintableTree<T>> {
	private static final char LNK_NULL = ' ';
	private static final char LNK_CONT = '|';
	private static final char LNK_TERM = '+';
	private static final char LNK_LEAF = '-';
	private int maxLevel;
	private PrintStream out;
	private char[] cm;			// continueMark
	public PrintTree(int maxLevel, PrintStream out) {
		this.maxLevel = maxLevel;
		this.out = out;
		cm = new char[maxLevel];
	}
	public void printTree(PrintableTree<T> root) {
		out.println(root.getContent(PrintableTree.ROOT));
		printSubTree(root, 1);
	}
	private void printSubTree(PrintableTree<T> node, int level) {
		if(level > maxLevel) {
			out.println("最大レベルを超えました。");
			return;
		}
		Iterator<T> it = node.iterator();
		while(it.hasNext()) {
			PrintableTree<T> n = (PrintableTree<T>)it.next();
			cm[level-1] = it.hasNext() ? LNK_CONT : LNK_TERM;
			printIndent(level);
			if(n.hasMember()) {
				out.println(n.getContent(PrintableTree.SUBROOT));
				if (cm[level-1] == LNK_TERM) cm[level-1] = LNK_NULL;
				printSubTree(n, level + 1);
			} else {
				out.println(n.getContent(PrintableTree.LEAF));
			}
		}
	}
	private void printIndent(int level) {
		for(int i = 0; i < level; i++) {
			char bar = (i < level - 1) ? LNK_NULL : LNK_LEAF;
			out.printf(" %c%c ", cm[i], bar);
		}
	}
}
