package net.woodyfolsom.msproj.ann;

import net.woodyfolsom.msproj.GameResult;
import net.woodyfolsom.msproj.GameState;
import net.woodyfolsom.msproj.Player;

import org.encog.ml.data.MLData;
import org.encog.ml.data.MLDataPair;
import org.encog.ml.data.basic.BasicMLData;
import org.encog.ml.data.basic.BasicMLDataPair;
import org.encog.util.kmeans.Centroid;

public class GameStateMLDataPair implements MLDataPair {
	private BasicMLDataPair mlDataPairDelegate;
	private GameState gameState;

	public GameStateMLDataPair(GameState gameState) {
		this.gameState = gameState;
		mlDataPairDelegate = new BasicMLDataPair(new BasicMLData(createInput()), new BasicMLData(createIdeal()));
	}

	public GameStateMLDataPair(GameStateMLDataPair that) {
		this.gameState = new GameState(that.gameState);
		mlDataPairDelegate = new BasicMLDataPair(
				that.mlDataPairDelegate.getInput(),
				that.mlDataPairDelegate.getIdeal());
	}

	@Override
	public MLDataPair clone() {
		return new GameStateMLDataPair(this);
	}

	@Override
	public Centroid<MLDataPair> createCentroid() {
		return mlDataPairDelegate.createCentroid();
	}

	/**
	 * Creates a vector of normalized scores from GameState.
	 * 
	 * @return
	 */
	private double[] createInput() {

		GameResult result = gameState.getResult();

		double maxScore = gameState.getGameConfig().getSize()
				* gameState.getGameConfig().getSize();

		double whiteScore = Math.min(1.0, result.getWhiteScore() / maxScore);
		double blackScore = Math.min(1.0, result.getBlackScore() / maxScore);

		return new double[] { blackScore, whiteScore };
	}

	/**
	 * Creates a vector of values indicating strength of black/white win output
	 * from network.
	 * 
	 * @return
	 */
	private double[] createIdeal() {
		GameResult result = gameState.getResult();

		double blackWinner = result.isWinner(Player.BLACK) ? 1.0 : 0.0;
		double whiteWinner = result.isWinner(Player.WHITE) ? 1.0 : 0.0;

		return new double[] { blackWinner, whiteWinner };
	}

	@Override
	public MLData getIdeal() {
		return mlDataPairDelegate.getIdeal();
	}

	@Override
	public double[] getIdealArray() {
		return mlDataPairDelegate.getIdealArray();
	}

	@Override
	public MLData getInput() {
		return mlDataPairDelegate.getInput();
	}

	@Override
	public double[] getInputArray() {
		return mlDataPairDelegate.getInputArray();
	}

	@Override
	public double getSignificance() {
		return mlDataPairDelegate.getSignificance();
	}

	@Override
	public boolean isSupervised() {
		return mlDataPairDelegate.isSupervised();
	}

	@Override
	public void setIdealArray(double[] arg0) {
		mlDataPairDelegate.setIdealArray(arg0);
	}

	@Override
	public void setInputArray(double[] arg0) {
		mlDataPairDelegate.setInputArray(arg0);
	}

	@Override
	public void setSignificance(double arg0) {
		mlDataPairDelegate.setSignificance(arg0);
	}

}