/**
*Programme cree par The Clusters
*Classe Joueur du jeu "Chkoba"
*@author The Clusters
*@version 1.0
**/

package chkoba;
import chkoba.*;
import java.util.*;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

/**
*	Classe Joueur
*/

public abstract class JoueurImpl extends UnicastRemoteObject implements IJoueur
{
	// Attributs en protected, sinon les classes filles ne les ont pas!
	
	/** Attribut main du joueur */
	protected IMain main;
	/** Attribut nom du joueur */
	protected String nom;
	/** Attribut pour savoir si la main est vide */
	protected boolean vide;
	/** Attribut qui contient les plis du joueur */
	protected ArrayList<ICarte> plis= new ArrayList<ICarte>();
	/** Attribut qui compte le nombre de points chkoba */
	protected int point_chkoba;
	/** Attribut qui compte son nombre de points */
	protected int points;
	/** Attribut pour savoir si il a pris recemment*/
	protected boolean pris=false;
	/** Attribut pour voir si il est "fait" <br/> Confere au reseau */
	protected boolean fait=false;
	
	/**
	* CONSTRUCTEUR
	**/
	
	/**
	*Constructeur par defaut
	*/
	public JoueurImpl() throws RemoteException
	{
		super();
		main= new MainImpl();
		this.setVide(false);
	}
	
	/**
	*Constructeur avec un parametre
	*@param n , nom du joueur
	*/
	public JoueurImpl(String n) throws RemoteException
	{
		super();
		nom=n;
		main= new MainImpl();
		this.setVide(false);
	}
	
	/**
	* METHODES 
	**/
	
	/**
	* Dans ce jeu, il n'y a qu'un seul paquet de carte donc si le joueur a les meme carte dans la main que j alors il sont identique
	* Renvoie 	0 si les deux joueurs sont identiques
	*		1 si il sont different
	*		-2 si l'objet en parametre n'est pas une instance de IJoueur
	*		-3 si une erreur s'est produite 
	*/
	public int compareTo(Object j) throws RemoteException
	{
		if(j instanceof IJoueur)
		{
			try
			{
				IJoueur joueur = (IJoueur)j;
				IMain mainJoueurJ = joueur.getMain();
				IMain mainJoueurThis = this.getMain();
				if ( mainJoueurJ.size() != mainJoueurThis.size())
					return 1;
				else
				{	
					for ( int i = 0 ; i != mainJoueurThis.size();i++)
					{
						int valeurCarteThis = mainJoueurThis.get(i).getValeur();
						Couleur CouleurCarteThis = mainJoueurThis.get(i).getCoul();
						int valeurCarteJ = mainJoueurJ.get(i).getValeur();
						Couleur CouleurCarteJ = mainJoueurJ.get(i).getCoul();
						if ( (valeurCarteThis != valeurCarteJ) || (""+CouleurCarteThis).compareTo(""+CouleurCarteJ)!=0)
							return 1;
					}
				}					
				//~ if (carteIdent == true)
				return 0;
			}
			catch(Exception e)
			{
				return -3;
			}
		}
		else
			return -2;
	}
	
	/**
	* Methode qui ajoute un les carte de l'arrayList en parametre au plis du joueur affin de compter le nombre de carte rammasees
	*/
	public void ajoutePlis(ArrayList<ICarte> array) throws RemoteException
	{
		plis.addAll(array);
	}
	
	/**
	*Compte le nombre de point du joueur
	*/
	public void comptePoint() throws RemoteException
	{
		int total=0,tmp;
		
		//verification nombre de carreau
		tmp=this.compteCarreaux();
		if(tmp>5)
			total++;
		
		//verification plus de 20 cartes de plis
		tmp=this.getPlis().size();
		if(tmp>20)
			total++;
		
		//verification sept de carreau
		if(this.septCarreau())
			total++;
		
		//on compte les sept ou les six si egalite
		tmp=this.compteSept();
		if(tmp>2)
			total++;
		else 
		{
			tmp=this.compteSix();
			if(tmp>2)			
				total++;
		}
		
		total+=point_chkoba;
		this.points=total;
	}
	
	/**
	*Methode abstraite definie dans les classe filles
	*/
	public abstract void jouer(IPlateau pl) throws RemoteException;
	
	/**
	*Faire un point Chkoba
	*/
	public void chkoba() throws RemoteException 
	{
		this.point_chkoba++;
	}
	
	/**
	*Compte le nombre de carreaux dans les plis du joueur
	*/
	public int compteCarreaux() throws RemoteException
	{
		int nb=0;
		if ( plis.size() != 0)
		{
			for (int i=0; i<plis.size();i++)
			{
				if(plis.get(i).getCoul()==Couleur.carreau)
					nb++;
			}
		}
		return nb;
	}
	
	/**
	*Compte le nombre de septs dans les plis
	*/
	public int compteSept() throws RemoteException
	{
		int nb=0;
		if ( plis.size() != 0)
		{
			for (int i=0; i<plis.size();i++)
			{
				if(plis.get(i).getValeur()==7)
					nb++;
			}
		}
		return nb;
	}
	
	/**
	*Compte le nombre de six dans les plis
	*/
	public int compteSix() throws RemoteException
	{
		int nb=0;
		if ( plis.size() != 0)
		{
			for (int i=0; i<plis.size();i++)
			{
				if(plis.get(i).getValeur()==6)
					nb++;
			}
		}
		return nb;
	}
	
	/**
	*retourne vraie si le joueur a le sept de carreau
	*/
	public boolean septCarreau() throws RemoteException
	{
		if ( plis.size() != 0)
		{
			for (int i=0; i<plis.size();i++)
			{
				if(plis.get(i).getValeur()==7 && plis.get(i).getCoul()==Couleur.carreau)
				{
					return true;
				}
			}
		}
		return false;
	}
	
	
	
	/**
	* ACCESSEURS
	**/
	
	/**
	*Switch automatiquement fait a false si fait est a vrai et inversement
	*/
	public void setFait() throws RemoteException
	{
		if ( fait == false )
			fait=true;
		else
			fait=false;
	}
	
	/**
	*Switch automatiquement pris a false si fait est a vrai et inversement
	*/
	public void setPris() throws RemoteException
	{
		if ( pris == false )
			pris=true;
		else
			pris=false;
	}
	
	/** Mettre le nom du joueur au parametre s */
	public void setNom(String s) throws RemoteException { nom=s; }
	/** Mettre le booleen vide au parametre b */
	public void setVide(boolean b) throws RemoteException { vide=b; }
	
	/** Retourne la variable "fait" */
	public boolean getFait() throws RemoteException { return fait; }
	/** Retourne la variable "pris" */
	public boolean getPris() throws RemoteException { return pris; }
	/** Retourne vrai si la main est vide */
	public boolean mainEstVide() throws RemoteException { return vide; }
	/** Retourne la main du joueur */
	public IMain getMain() throws RemoteException { return main; }
	/** Retourne les plis du joueur */
	public ArrayList<ICarte> getPlis() throws RemoteException { return plis; }
	/** Retourne les plis du joueur */
	public int getTaillePlis() throws RemoteException { return plis.size(); }
	/** Retourne le nom du joueur*/
	public String getNom() throws RemoteException { return nom; }
	/** Afficher le joueur */
	public abstract String affiche() throws RemoteException;
	/** Retourne la variable chkoba  */
	public int getChkoba() throws RemoteException { return point_chkoba; }
	/** Retourne le nombre de points du joueur */
	public int getPoint() throws RemoteException { return points; }
}
