/*
 * Created on Mar 20, 2005
 */
/**
 * @author Nicole Sullivan
 *
 */
public class Belote extends Thread {
	//===========================================================
	//  Variables
	//===========================================================
    static PaquetDeCartes leJeu;
    static PaquetDeCartes p = new PaquetDeCartes();
    static PaquetDeCartes tapis = new PaquetDeCartes();
    static JoueurProgramme [] joueurs = new JoueurProgramme[3];
    static Couleur trumpCouleur;
    
    static int winnerRound;
    static int team0 = 0;
    static int team1 = 0;
    

    static Graphique fenetre;
    //===========================================================
    // functions
    //===========================================================
    
    //===========================================================
    //  DEAL
    //  deals a specified number of cards to each of the players in turn
    //  NumberCards: no. of cards to deal
    //  premierPerson: first person who starts in this round
	static void deal(int NumberCards, int premierPerson){
		for (int i=0; i<4; i++){
			int playerNumber = (premierPerson+i)%4;
			Terminal.ecrireStringln("player # " + playerNumber);
			if (playerNumber ==3) {
				// deal to human player  
				for (int j=0; j<NumberCards; j++){
					p.ajoute (leJeu.prendIeme (0));
					Terminal.ecrireStringln("Card " + (j+1) + " dealt for human player ");				
				}
			}else {
				// deal to computer player
				for (int j=0; j<NumberCards; j++){
					joueurs[playerNumber].recoitCarte(leJeu.prendIeme(0));
					Terminal.ecrireStringln("Card " + (j+1) + " dealt for computer player " + playerNumber);				
				}	
			}
		}	
	}
	//  deal a certain number of cards to one player
	//  NumberCards: no of cards to deal
	//  playerNumber: player to deal to
	static void dealOnePlayer(int NumberCards, int playerNumber){
		Terminal.ecrireStringln("player # " + playerNumber);
		if (playerNumber ==3) {
			// deal to human player  
			for (int j=0; j<NumberCards; j++){
				p.ajoute (leJeu.prendIeme (0));
				Terminal.ecrireStringln("Card " + (j+1) + " dealt for human player ");				
			}
		}else {
			// deal to computer player
			for (int j=0; j<NumberCards; j++){
				joueurs[playerNumber].recoitCarte(leJeu.prendIeme(0));
				Terminal.ecrireStringln("Card " + (j+1) + " dealt for computer player " + playerNumber);				
			}	
		}		
	}
	//	===========================================================
	//  PLAY
	//  goes through each of the players in turn starting with the premierPerson
	//  premierPerson: first person to play
	static void playRound(int premierPerson) {
		for (int i=0; i<4; i++){
			play((premierPerson+i)%4, i);
		}
		if (winnerRound == 2 || winnerRound == 0){//team 0 wins
			team0 = + Arbitre.comptePointsPaquet(tapis, trumpCouleur);
			Terminal.ecrireStringln("Winner of this round is player #" + winnerRound);
		}else {//team 1 wins (players 1 and 3)
			team1 = + Arbitre.comptePointsPaquet(tapis, trumpCouleur);
			Terminal.ecrireStringln("Winner of this round is player #" + winnerRound);
		}
		
	}
	//  plays a card
	//  playerNumber: the player who plays the card
	//  turn: tests if its the first person to play and uses a diff method for computer player
	static void play(int playerNumber, int turn){
		if (playerNumber == 3){
			//  human play
			int v=0;
			boolean badValue;
			do {
				try {
					badValue = false;
					Terminal.ecrireString("What number card would you like to play? ");
					v = Terminal.lireInt();
					if (v>p.longueur){
						badValue = true;
						Terminal.ecrireStringln("We're sorry, we can't find that card please enter a value between 1 and " + (p.longueur));
					}
				}catch (TerminalException e){
					Terminal.ecrireStringln("We're sorry, we can't find that card please enter a value between 1 and " + (p.longueur));
					badValue = true;
				}	
			}while(badValue);
			
			Carte carteJouee = p.prendIeme(v-1);
			if (turn != 0){
				if (Arbitre.estPlusForte(tapis.lesCartes[tapis.longueur-1], carteJouee, trumpCouleur)){
					winnerRound = playerNumber;
				}
			}
			tapis.ajoute (carteJouee);
			fenetre.joueurHumainJoue(p,carteJouee);
			Terminal.ecrireStringln("Human player plays " + carteJouee.couleur.nom + " " + carteJouee.figure.nom);//is giving address in memory, not value, how to fix?
		}else {
			//  computer play
			Carte carteJouee;
			if (turn == 0){ 
				carteJouee = joueurs[playerNumber].carteJoueEnPremier();
				Terminal.ecrireStringln("First Player, Computer Player plays card " + carteJouee.couleur.nom + " " + carteJouee.figure.nom);
			} else {
				Terminal.ecrireString("Computer Player " + playerNumber);
				joueurs[playerNumber].informePlisJouee(tapis);
				carteJouee = joueurs[playerNumber].carteJouee(tapis);
				Terminal.ecrireStringln(" plays card " + carteJouee.couleur.nom + " " + carteJouee.figure.nom);
				if (Arbitre.estPlusForte(tapis.lesCartes[winnerRound], carteJouee, trumpCouleur)){
					winnerRound = playerNumber;
				}
			}
			tapis.ajoute(carteJouee);
			fenetre.ordinateurJoue(carteJouee, playerNumber);
			// leave cards on the table for user to see. -- for a random amount of time to make it feel like the computer is "deciding"
			try {
				sleep((long)Math.random()*5000);
			}catch (InterruptedException e){}
		}
	}
	//	===========================================================
	//  TRUMP
	//  asks them if they want the trump
	//  player: player you are asking
	//  carteRetournee: the potential trump that the players are deciding about
	static boolean playerWantTrump(int player, Carte carteRetournee){
		if (player == 3){
			//  human ask
			String wantTrump;
			Terminal.ecrireString("Do you want the trump card (y/n)?");
			wantTrump = Terminal.lireString().toLowerCase();
			if (wantTrump.charAt(0) == 'y'){
				trumpCouleur = carteRetournee.couleur;
				Terminal.ecrireStringln("The trump is " + carteRetournee.couleur.nom);
				joueurs[1].campPrend = true;
				p.ajoute (carteRetournee);
				joueurs[1].informeAtout(trumpCouleur, true);
				Terminal.ecrireStringln("Human player takes center card");
				return true;
			} else { 
				Terminal.ecrireStringln("Human player doesn't want the trump");
				return false;
			}	//  add error message for incorrect input or make a box to click in
		}else{
			//  computer ask
			if (joueurs[player].prend1erTour(carteRetournee)){
				Terminal.ecrireStringln("Trump taken in the first round by player " + player);
				trumpCouleur = carteRetournee.couleur;
				joueurs[player].recoitCarte(carteRetournee);
				// lets players know if their partner took the trump
				joueurs[player].jePrend = true;
				if (player == 2){
					joueurs[0].campPrend = true;
				}else if (player == 0){
					joueurs[2].campPrend = true;
				}
				joueurs[player].informeAtout(trumpCouleur, joueurs[player].campPrend);
				//	Add informeAtout
				//trumpCouleur = carteRetournee.couleur;
				//joueurs[player].jePrend = true;
				//Terminal.ecrireStringln("Trump color is : " + trumpCouleur);
				return true;
			}else {
				Terminal.ecrireStringln("Computer player #" + player + " doesn't want the trump");
				return false;
			}
		}
	}
	//  Second Round - Player Want Trump
	//  Asks the player if they would like the center card 
	//  and then asks what color they would like the trump
	//  to be
	//  playerNumber: current player
	//  carteRetournee: the center card which is up for grabs
	//  choix: the color the player wants the trump to be
	static boolean playerWantTrump(int playerNumber, Carte carteRetournee, Couleur choix){
		if (playerNumber == 3){
			//  human ask
			String wantTrump;
			Terminal.ecrireString("Do you want the center card (y/n)?");
			wantTrump = Terminal.lireString().toLowerCase();
			if (wantTrump.charAt(0) == 'y'){
				p.ajoute (carteRetournee);
				joueurs[1].campPrend = true;
				Terminal.ecrireStringln("Human player takes center card");
				Terminal.ecrireString("What couleur would you like the trump card to be (Coeur/Pique/Carreau/Trefle)? ");
				choix.nom = Terminal.lireString();
				Terminal.ecrireStringln("The trump is " + choix.nom);
				trumpCouleur = choix;
				joueurs[1].informeAtout(trumpCouleur, true);
				return true;
			} else { 
				Terminal.ecrireStringln("Human player doesn't want the trump");
				return false;
			}	//  add error message for incorrect input or make a box to click in
		}else{
			//  computer ask
			if (joueurs[playerNumber].prend2ndTour(carteRetournee, choix)){
					trumpCouleur = choix;
					Terminal.ecrireStringln("Trump taken in the second round by player " + playerNumber);
					joueurs[playerNumber].recoitCarte(carteRetournee);
					//	lets players know if their partner took the trump
					joueurs[playerNumber].jePrend = true;
					if (playerNumber == 2){
						joueurs[0].campPrend = true;
					}else if (playerNumber == 0){
						joueurs[2].campPrend = true;
					}
					joueurs[playerNumber].informeAtout(trumpCouleur, joueurs[playerNumber].campPrend);
					Terminal.ecrireStringln("Trump color is : " + trumpCouleur);
					return true;
			}else {
				Terminal.ecrireStringln("Computer player #" + playerNumber + " doesn't want the trump");
				return false;
			}
		}
	}
	//  goes through each of the players and asks them if they want the trump and if one of them wants it it deals the card
	//  accordingly, if not it starts a second round, then if no one still wants the trump it returns "nobody wants trump"
	//  premierPerson: first person to play
	//  carteRetournee: the center card up for grabs
	static boolean takeTrump(int premierPerson, Carte carteRetournee){
		boolean taken = false;
		int whoTook = -1;
		for (int i=0; i<4; i++){
			int playerNumber = (premierPerson + i)%4;
			taken = playerWantTrump(playerNumber, carteRetournee);
			if (taken){
				whoTook = playerNumber;
				break;
			}
		}	
		if (taken){
			Terminal.ecrireStringln("Player number " + whoTook + "took the trump");
			dealOnePlayer(2, whoTook);
			for (int i=0; i<4; i++){
				if (i != whoTook){
					dealOnePlayer(3, i);
				}
			}
			//give carteRetournee to whoTook!!!
			return true;
		}else {
			//second round
			for (int i=0; i<4; i++){
				int playerNumber = (premierPerson + i)%4;
				Couleur choix = new Couleur("");
				taken = playerWantTrump(playerNumber, carteRetournee, choix);
				if (taken){
					whoTook = playerNumber;
					trumpCouleur = choix;
					break;
				}
			}
			if (taken){
				dealOnePlayer(2, whoTook);
				for (int i=0; i<4; i++){
					if (i != whoTook){
						dealOnePlayer(3, i);
					}
				}
				//give carte Retournee to whoTook  (same as above -- write function use for both)!!!
				return true;
			}else {
				Terminal.ecrireStringln("No one wants the trump");
				return false; //means the game cannot be played
			}
		}	
	}
	//  =============================================================
	//  Verify that the cards played are legal 
	//  =============================================================
	//  Does not work, for now letting human play any card
	/*static void verifyCard(Carte cardPlayed, Carte firstCardPlayed){
		for (int c=0; c<4; c++){
			if (tapis[c].couleur.nom == trumpCouleur.couleur.nom){
				
			}
		}
		if (cardPlayed.couleur.nom == firstCardPlayed.couleur.nom){
			
		}
			
	}
	static int haveInHand(Carte cardPlayed, Carte firstCardPlayed, PaquetDeCartes hand){
		for (int card = 0; card < p.length; card++){
			if (p[i].couleur.nom == firstCardPlayed.couleur.nom){
				return 0;
			}else if (p[i].couleur.nom == trumpCouleur.couleur.nom){
				return 1;
			}else {
				return 2;
				//doesn't have a card of the same suit or a trump
			}
		}
	}*/
    // ===============================================================
	//  MAIN
	// ===============================================================
	public static void main(String[] args) {
		
		//  on cree une fenetre
		Terminal.ecrireStringln("Window Created");
		fenetre = new Graphique();
		//  on cree the players
		for (int i=0; i<3; i++){
			joueurs[i] = new JoueurProgramme();
		}
		//Set the first player to generate randomly -- this will need to be at the 
		//beginning of each game and not each round!!! Maybe with a constructor to 
		// set it to a random number only when it is first built.
		int premierPerson = (int) Math.round( Math.random()*3);//this is wrong causing crash
		Terminal.ecrireStringln("premierPerson = " + premierPerson);
		Carte carteRetournee;
		do {		
			// on recupere un jeu de 32 cartes battu (shuffled)
			leJeu = Arbitre.donneJeuBeloteBattu();
			Terminal.ecrireStringln("Cards Shuffled");
		  	
			// deal the first three cards to each player
			deal(3, premierPerson);
			Terminal.ecrireStringln("First - Three Cards Dealt");
			
			//  deal the second two cards
			deal(2, premierPerson);
			Terminal.ecrireStringln("Second - Two Cards Dealt");
			
			//  Turn over center card and place it on the board.
			carteRetournee = leJeu.prendIeme(0);
			Terminal.ecrireStringln("Center card = " + carteRetournee.couleur.nom);
			
			//  Show the player his/her cards and the center card
			fenetre.affiche1(p, carteRetournee);  
			Terminal.ecrireStringln("Players cards on screen");
			
			//	give the player time to see the trump in the case that the computer takes it. . . Could be better done!!!
			Terminal.ecrireString("Press return when you have seen the Trump.");
			Terminal.lireString();
			
			//	Ask each player whether or not they would like to take the trump (atout)
		}while(!(takeTrump(premierPerson, carteRetournee)));
		//  Show cards
		fenetre.affiche2(p); 
		//  Play eight rounds
		for (int r=0; r<8; r++){  
			if (r > 0){
				premierPerson = winnerRound; 
			}
			playRound(premierPerson);
			fenetre.affiche2(p);
			//	Pause - to see the results of the round
			try {
				sleep(750);
			}catch (InterruptedException e){
				Terminal.ecrireStringln("Next Round");
			}
			//  Clear the board for next round
			fenetre.effaceTapis();
		}
		//  on affiche un message de victoire (100 est plus grand que 62)
		fenetre.perduGagne(team1, team0);
	}
}
