package carte.belote;
/**
 * classes pour représenter un tour (pli) de belote et savoir quelle carte le remporte
 *
 * @author Matthias Colin
 * @version 1.0 (31/05/2011)
 */ 

import java.util.*;
import carte.*;

/**
 * Comparateur de 2 cartes d'un même pli connaissant
 * la famille de la 1ère carte posée et celle de l'atout
 */
class ComparateurBelote implements Comparator<Carte> {

	// famille de la 1ère carte d'un tour
	private Famille first;
	
	// famille de l'atout
	private Famille atout;
	
	// ordre des valeurs 7,8,9,10,V,D,R,A pour l'atout (à utiliser avec l'ordinal d'une valeur)
	private static int[] ordreAtout = {0,1,6,4,7,2,3,5};
	// ordre des valeurs 7,8,9,10,V,D,R,A pour les autres familles (à utiliser avec l'ordinal d'une valeur)
	private static int[] ordreAutres = {0,1,2,6,3,4,5,7};
	
	// ordre des familles (dépend du tour) : Coeur, Carreau, Pique, Trefle
	private Map<Famille, Integer> ordreFamille;
	
	/**
	 * constructeur du comparateur
	 * enregistre les familles de la 1ère carte posée et de l'atout
	 * et en déduit l'ordre des familles
	 * @param first - la famille de la 1ère carte posée
	 * @param atout - la famille de l'atout
	 */
	public ComparateurBelote(Famille first, Famille atout) {
		this.first = first;
		this.atout = atout;
		// ordre des familles : ?;?;first;atout ou ?;?;?;atout si first=atout
		ordreFamille = new EnumMap<Famille, Integer>(Famille.class);
		ordreFamille.put(first, 2);
		ordreFamille.put(atout, 3); // si l'atout est aussi la 1ère, 3 remplace 2
		// on récupère les 2 ou 3 autres familles pour leur donner un ordre qq
		int ordre=0;
		for (Famille f : Famille.values()) {
			if (f != first && f != atout) {
				ordreFamille.put(f, ordre++);
			}
		}
		// [Debug only] System.err.println(ordreFamille);
	}
	
	/**
	 * comparaison de 2 cartes d'un même tour (pli)
	 * suivant leur famille et les familles de la 1ère carte posée
	 * et celle de l'atout
	 * @param c1 1ère carte
	 * @param c2 2ème carte
	 * @return un nombre négatif, nul ou positif, respectivement
	 * pour la 1ère carte plus petite, égale ou plus grande
	 * que la 2ème carte
	 */
	@Override
	public int compare(Carte c1, Carte c2) {
		Integer o1, o2;
		if (c1.getFamille() == c2.getFamille()) {
			// même famille, on compare suivant l'ordre adéquat
			if (c1.getFamille() == atout) {
				o1 = ordreAtout[c1.getValeur().ordinal()];
				o2 = ordreAtout[c2.getValeur().ordinal()];
			} else {
				o1 = ordreAutres[c1.getValeur().ordinal()];
				o2 = ordreAutres[c2.getValeur().ordinal()];
			}
		} else {
			// famille différente : l'atout l'emporte sur
			// la famille posée en 1er (si différente)
			// qui l'emporte sur les autres familles
			o1 = ordreFamille.get(c1.getFamille());
			o2 = ordreFamille.get(c2.getFamille());
		}
		return o1.compareTo(o2);
	}
	
}

public class Tour implements Iterable<Carte> {

	private NavigableSet<Carte> cartes;
	
	public Tour(Carte carte, Famille atout) {
		cartes = new TreeSet<Carte>(new ComparateurBelote(carte.getFamille(),atout));
		cartes.add(carte);
	}

	public void jouer(Carte carte) {
		cartes.add(carte);
	}
	
	public Iterator<Carte> iterator() {
		return cartes.iterator();
	}
	
	public Carte carteGagnante() {
		return cartes.last();
	}

}