package net.woodyfolsom.msproj.sgf;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import net.woodyfolsom.msproj.Action;

public class SGFGameTree {
	private List<SGFNode> nodeSequence = new ArrayList<SGFNode>();
	private List<SGFGameTree> subTrees = new ArrayList<SGFGameTree>();

	public int getNodeCount() {
		return nodeSequence.size();
	}

	public List<SGFNode> getNodeSequence() {
		return Collections.unmodifiableList(nodeSequence);
	}

	public void setNodeSequence(List<SGFNode> nodeSequence) {
		this.nodeSequence.clear();

		for (SGFNode node : nodeSequence) {
			this.nodeSequence.add(node);
		}
	}

	public void addSubTree(SGFGameTree subTree) {
		subTrees.add(subTree);
	}

	public List<Action> getMoves(int boardSize) {
		List<Action> moves = new ArrayList<Action>();
		
		for (SGFNode node : nodeSequence) {
			SGFValue<?> sgfValue;
			switch (node.getType()) {
			case MOVE_BLACK :
				sgfValue = node.getFirstValue(SGFIdentifier.MOVE_BLACK);
				break;
			case MOVE_WHITE :
				sgfValue = node.getFirstValue(SGFIdentifier.MOVE_WHITE);
				break;
			default :
				continue;
			}
			
			moves.add(Action.parseSGF(sgfValue.getText(), boardSize));
		}
		
		return moves;
	}
	
	public int getSubTreeCount() {
		return subTrees.size();
	}

	public int getBoardSize() {
		for (SGFNode node : nodeSequence) {
			SGFNode.TYPE nodeType = node.getType();
			switch (nodeType) {
			case ROOT:
				return Integer.valueOf(node.getFirstValue(SGFIdentifier.SIZE).getText());
			default:
				// ignore
			}
		}
		throw new RuntimeException("Cannot get board size: SGFNode with identifier SZ was not found in any nodeSequence of type ROOT.");
	}
	
	public double getKomi() {
		for (SGFNode node : nodeSequence) {
			SGFNode.TYPE nodeType = node.getType();
			switch (nodeType) {
			case ROOT:
				return Double.parseDouble(node.getFirstValue(SGFIdentifier.KOMI).getText());
			default:
				// ignore
			}
		}
		throw new RuntimeException("Cannot get board size: SGFNode with identifier KM was not found in any nodeSequence of type ROOT.");
	}
	
	public String toSGF() {
		StringBuilder sgfFormatString = new StringBuilder("(");
		for (SGFNode node : nodeSequence) {
			sgfFormatString.append(node.toSGF());
		}
		sgfFormatString.append(")");
		return sgfFormatString.toString();
	}
	
	@Override
	public String toString() {
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append("(");
		for (SGFNode node : nodeSequence) {
			stringBuilder.append(node.toString());
		}
		stringBuilder.append(")");
		return stringBuilder.toString();
	}
}
