package game;

/**
 * @author Thibault Podevin avec l'aide de Martin Robinson et Alexis Caron
 *
 */
public class TicTacToeFrame {

	private final TabToInt tab;
	private int nbTours;

	/**
	 * @param newTab Contient le tableau de INT qui g�nere le TicTacToe
	 */
	private TicTacToeFrame(final TabToInt newTab, int tour){
		tab = newTab;
		nbTours = tour;
	}

	private static TicTacToeFrame _empty = new TicTacToeFrame(TabToInt.fromEmpty(),0);
	public static TicTacToeFrame fromEmpty(){
		return _empty;
	}

	/**
	 * @param x	Indice des X du tableau
	 * @param y Indice des Y du tableau
	 * @return	Une Nouvelle Instance tableau(cot�s des X) modifier
	 * @throws Exception Retourne une exeception au cas ou il existe deja un X ou un O a une case
	 */
	public TicTacToeFrame setX(int x, int y) throws Exception{
		if(getO(x,y)||getX(x,y))
			throw new Exception("Input invalide, contient deja une valeur");
		return new TicTacToeFrame(tab.set(x+y*3), nbTours++);
	}

	/**
	 * @param x Indice des X du tableau des X
	 * @param y Indice des Y du tableau des X
	 * @return Une Nouvelle Instance tableau(cot�s des O) modifier
	 * @throws Exception Retourne une exeception au cas ou il existe deja un X ou un O a une case
	 */
	public TicTacToeFrame setO(int x, int y) throws Exception{
		if(getO(x,y)||getX(x,y))
			throw new Exception("Input invalide, contient deja une valeur");
		return setX(x,y+3);
	}

	/**
	 * @param x Indice des X du tableau
	 * @param y Indice des Y du tableau
	 * @return La valeur bool�en (vide ou pas vide) de l'emplacement du tableau
	 */
	public boolean get(int x, int y){
		return tab.get(x+y*3);
	}

	/**
	 * @param x Indice des X du tableau des X
	 * @param y Indice des Y du tableau des X
	 * @return La valeur bool�en (vide ou pas vide) de l'emplacement du tableau du cot� X
	 */
	public boolean getX(int x, int y){
		return get(x,y);
	}

	/**
	 * @param x Indice des X du tableau des Y
	 * @param y Indice des Y du tableau des Y
	 * @return La valeur bool�en (vide ou pas vide) de l'emplacement du tableau du cot� O
	 */
	public boolean getO(int x, int y){
		return get(x,y+3);
	}


	/**
	 * @return Les contenu du Int du tableau
	 */
	public int getData(){
		return tab.getData();
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString(){
		String result = "Tab1 \n";
		for(int i=0; i<3; i++)
		{
			for(int j=0; j<3; j++)
				result += (getX(j,i) + " ");
			result += "\n";
		}
		result += "Tab2 \n";
		for(int i=0; i<3; i++)
		{
			for(int j=0; j<3; j++)
				result += (getO(j,i) + " ");
			result += "\n";
		}

		return result;
	}

	/**
	 * @param indice Indice ou commencer la recherche (0 pour les X, 3 pour les O)
	 * @return Si quelqun gagne ou perd
	 */
	private boolean getWinner(int indice){
		for(int i=0;i<3;i++){
				if(this.get(0, indice+i) == true && this.get(1, indice+i) == true && this.get(2, indice+i) == true)
					return true;
			}
		for(int i=0;i<3;i++){
			if(this.get(i, indice+0) == true && this.get(i, indice+1) == true && this.get(i, indice+2) == true)
				return true;
		}

		if(this.get(0, indice+0) == true && this.get(1, indice+1) == true && this.get(2, indice+2) == true)
			return true;

		if(this.get(0, indice+2) == true && this.get(1, indice+1) == true && this.get(2, indice+0) == true)
			return true;

		return false;
	}

	/**
	 * @return Vrai si X gagne
	 */
	public boolean getWinnerX(){
		return getWinner(0);
	}


	/**
	 * @return Vrai si O gagne
	 */
	public boolean getWinnerO(){
		return getWinner(3);
	}

	/**
	 * @param declancheur nb de tours avant la fin du jeu
	 * @return vrais si la game est fini
	 */
	public boolean endGame(){
		return nbTours == 9;
	}


	public static void main(String[] args) throws Exception {
		TabToInt boby = new TabToInt(0);

		TicTacToeFrame bob = new TicTacToeFrame(boby,0);

		System.out.println(bob.toString());

		try {
			bob=bob.setO(1, 0);
			bob=bob.setO(1, 1);
			bob=bob.setO(1, 2);

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		bob=bob.setX(1,1);
		System.out.println(bob.toString());

		System.out.println(bob.getWinnerO());

	}

}
