package net.woodyfolsom.msproj;

public class GameResult {
	public static final GameResult BLACK_BY_RESIGNATION = new GameResult(
			RESULT_TYPE.BLACK_BY_RESIGNATION);
	public static final GameResult VOID = new GameResult(RESULT_TYPE.VOID);
	public static final GameResult WHITE_BY_RESIGNATION = new GameResult(
			RESULT_TYPE.WHITE_BY_RESIGNATION);

	private double komi;
	private int blackScore;
	private int whiteScore;
	private int normalizedZeroScore;

	public enum RESULT_TYPE {
		BLACK_BY_RESIGNATION, WHITE_BY_RESIGNATION, IN_PROGRESS, SCORED, VOID
	}

	private RESULT_TYPE resultType;

	public GameResult(int blackScore, int whiteScore, int size, double komi,
			boolean finished) {
		this.blackScore = blackScore;
		this.komi = komi;
		this.whiteScore = whiteScore;
		this.normalizedZeroScore = size * size + ((int) (komi * 2));
		if (finished) {
			resultType = RESULT_TYPE.SCORED;
		} else {
			resultType = RESULT_TYPE.IN_PROGRESS;
		}
	}

	private GameResult(RESULT_TYPE resultType) {
		komi = 0.0;
		blackScore = 0;
		whiteScore = 0;
		normalizedZeroScore = 0;

		this.resultType = resultType;
	}

	public double getBlackScore() {
		return blackScore;
	}

	public String getFullText() {
		double blackScore = getBlackScore();
		double whiteScore = getWhiteScore();

		switch (resultType) {
		case BLACK_BY_RESIGNATION:
			return "Black wins by resignation";
		case WHITE_BY_RESIGNATION:
			return "White wins by resignation";
		case IN_PROGRESS:
		case VOID:
			return "Game in progress";
		case SCORED:
			if (blackScore > whiteScore) {
				return "Black wins by " + (blackScore - whiteScore);
			} else {
				return "White wins by " + (whiteScore - blackScore);
			}
		default:
			return "Unknown game result";
		}
	}

	public int getNormalizedZeroScore() {
		return normalizedZeroScore;
	}

	/**
	 * Gets a representation for the game score as an integer. Lower numbers are
	 * better for white. The minimum value is 0 (Chinese scoring - white owns
	 * every intersection on 19x19 and has 9 stone komi). Likewise, the maximum
	 * value if 379x2 (black owns every intersection with zero komi).
	 * 
	 * @return
	 */
	public int getNormalizedScore() {
		return normalizedZeroScore + 2 * blackScore
				- ((int) (2 * (whiteScore + komi)));
	}

	public double getScore(Player color) {
		if (color == Player.BLACK) {
			return getBlackScore();
		} else if (color == Player.WHITE) {
			return getWhiteScore();
		} else {
			return 0.0;
		}
	}

	public double getWhiteScore() {
		return (double) whiteScore + komi;
	}

	public boolean isWinner(Player player) {
		if (Player.WHITE == player) {
			return whiteScore + komi > blackScore;
		} else {
			return blackScore > whiteScore + komi;
		}
	}

	public String toString() {
		switch (resultType) {
		case BLACK_BY_RESIGNATION:
			return "B+R";
		case SCORED:
			double blackScore = getBlackScore();
			double whiteScore = getWhiteScore();
			if (blackScore > whiteScore) {
				return "B+" + (blackScore - whiteScore);
			} else if (whiteScore > blackScore) {
				return "W+" + (whiteScore - blackScore);
			} else {
				return "DRAW";
			}
		case WHITE_BY_RESIGNATION:
			return "W+R";
		case IN_PROGRESS:
		case VOID: // intentional fall-through
			return "Void";
		default:
			return "?";
		}
	}
}