/**
*Programme cree par The Clusters
*Classe d'initialisation des objets serveurs 
*Ainsi que "mise en reseau" des objets
*@see Client.java
*@see differentes classes RMI en java
*@see RemoteException ( erreurs de reseau )
*@author The Clusters
*@version 1.0
**/

package chkoba;

import java.net.MalformedURLException;
import java.rmi.*;
import java.rmi.server.*;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Properties;
import java.io.IOException;
import java.io.FileReader;
import chkoba.*;

/**
*	Classe Serveur
*/


//Le serveur doit heriter de IServeur meme si celui-ci ne contient quasiment rien
//L'utilisation correcte de rmi nous force ( probleme de type )
public class Serveur extends UnicastRemoteObject implements IServeur
{	
	/** Les proprietes de la machine */
	private static Properties pro;
	/** Le nom d'hote de la machine */
	private static String hostName;
	/** Le nom du joueur 1<br> Celui qui a lance le serveur */
	private String joueur1;
	/** Une reference vers la pioche */
	private static IPioche pioche;
	/** Une reference vers le tapis */
	private static ITapis tapis;
	/** Une reference vers la main du joueur 1 */
	private static IMain main1;
	/** Une reference vers la main du joueur 2 */
	private static IMain main2;
	/** Une reference vers la main du joueur 3 */
	private static IMain main3;
	/** Une reference vers la main du joueur 4 */
	private static IMain main4;
	
	/**
	* Constructeur creant un objet Serveur.
	* L'objet en lui meme ne sert pas forcement, il est juste utile en ce qui concerne la creation et la mise en reseau des objets
	* qui viendrait encombrer les autres classes etant donne sa longueur
	*/
	public Serveur(int total, int nbManuels, ArrayList<Integer> tm1) throws RemoteException
	{
		try
		{
			System.out.println("Creation du fichier de configuration");
			pro = System.getProperties();
			//~ osname=pro.getProperty("os.name");
			hostName=InetAddress.getLocalHost().getHostName();
			pro.setProperty("rmi.host",hostName);
			PropertiesPerso propers=new PropertiesPerso();
			propers.saveProperties(pro);
			
			try
			{
				java.rmi.registry.LocateRegistry.createRegistry(1099);
			}
			catch ( Exception e)
			{
				e.printStackTrace();
			}
			
			System.out.println("Initialisation des objets distants");
			
			System.out.println("Creation du Plateau");
			PlateauImpl plateau = new PlateauImpl();
			
			try
			{
				FileReader fr = new FileReader ("config.txt");
				Scanner scan = new Scanner(fr);
				scan.useDelimiter("\t");
				joueur1 = scan.next();
				scan.close();
			}
			catch ( Exception e)
			{
				e.printStackTrace();
				System.out.println("Erreur fichier config serveur");
			}
			
			plateau.ajouteJoueur(joueur1);
			plateau.getJoueurs().get(0).setFait();
			plateau.setNbJoueursMan(nbManuels);
			
			System.out.println("Mise a jour du fichier de configuration");
			pro.setProperty("total",Integer.toString(total));
			propers.saveProperties(pro);
			
			System.out.println("Bind du plateau");
			Naming.rebind("plateau", plateau);			
			
			System.out.println("Bind de la pioche");
			pioche=plateau.getPioche();
			// On bind la pioche aussi.
			Naming.rebind("pioche",pioche);
			
			//Même traitement avec le tapis
			System.out.println("Bind du tapis");
			tapis=plateau.getTapis();
			Naming.rebind("tapis",tapis);
			
			System.out.println("Attente des joueurs");
			System.out.println(""+total);
			Serveur.traitementJoueurs( total, plateau );
			
			if ( total == 4)
				plateau.setEquipes(tm1);
			//~ plateau.affiche();
			
			//Bind!!
			System.out.println("Bind des cartes");
			Serveur.cartes(plateau, pioche,total, tapis);
			
			System.out.println("Objets cree et binde, attente des connexions de client");
			System.out.println("fin Serveur");
		}
		catch (Exception e)
		{
			e.printStackTrace();
			System.out.println("Erreur dans le serveur");
		}
	}
	
	/**
	*On attend tous les joueurs
	*pour ensuite binder les joueurs
	*/
	public static void traitementJoueurs( int total, IPlateau pl ) throws Exception
	{
		try
		{
			int tmp;
			boolean b=true;
			
			while (b)
			{
				tmp=pl.getJoueurs().size();
				
				if ( tmp == total )
					b=false;
				
				Thread.sleep(30);
			}
		}
		catch ( Exception e )
		{
			e.printStackTrace();
		}
	}
	
	
	/**
	* Methode qui bind toutes les cartes
	* se trouvant dans la pioche
	*/
	public static void cartes(IPlateau plateau, IPioche pioche,int total,ITapis tapis) throws Exception
	{
		try
		{
			
			// On lie les mains de deux joueurs ( minimum )
			// On les bind
			System.out.println("Bind des mains");
			main1= plateau.getJoueurs().get(0).getMain();
			Naming.rebind("main1",main1);
			main2= plateau.getJoueurs().get(1).getMain();
			Naming.rebind("main2",main2);
			
			
			// Traitement des cartes de la pioche			
			Naming.rebind("c1",pioche.get(0));
			Naming.rebind("c2",pioche.get(1));
			Naming.rebind("c3",pioche.get(2));
			Naming.rebind("c4",pioche.get(3));
			Naming.rebind("c5",pioche.get(4));
			Naming.rebind("c6",pioche.get(5));
			Naming.rebind("c7",pioche.get(6));
			Naming.rebind("c8",pioche.get(7));
			Naming.rebind("c9",pioche.get(8));
			Naming.rebind("c10",pioche.get(9));
			Naming.rebind("c11",pioche.get(10));
			Naming.rebind("c12",pioche.get(11));
			Naming.rebind("c13",pioche.get(12));
			Naming.rebind("c14",pioche.get(13));
			Naming.rebind("c15",pioche.get(14));
			Naming.rebind("c16",pioche.get(15));
			Naming.rebind("c17",pioche.get(16));
			Naming.rebind("c18",pioche.get(17));
			Naming.rebind("c19",pioche.get(18));
			Naming.rebind("c20",pioche.get(19));
			Naming.rebind("c21",pioche.get(20));
			Naming.rebind("c22",pioche.get(21));
			Naming.rebind("c23",pioche.get(22));
			Naming.rebind("c24",pioche.get(23));
			
			switch( total )
			{
				case 2 ://"+hostName+"/
					//Bind des cartes de la pioche				
					Naming.rebind("c25",pioche.get(24));
					Naming.rebind("c26",pioche.get(25));
					Naming.rebind("c27",pioche.get(26));
					Naming.rebind("c28",pioche.get(27));
					Naming.rebind("c29",pioche.get(28));
					Naming.rebind("c30",pioche.get(29));
					
					//Bind des cartes des mains des joueurs
					// Main 1
					Naming.rebind("c31",main1.get(0));
					Naming.rebind("c32",main1.get(1));
					Naming.rebind("c33",main1.get(2));
					
					// Main 2
					Naming.rebind("c31",main2.get(0));
					Naming.rebind("c32",main2.get(1));
					Naming.rebind("c33",main2.get(2));
					
					break;
				case 4 ://"+hostName+"/
					// Main 1
					Naming.rebind("c25",main1.get(0));
					Naming.rebind("c26",main1.get(0));
					Naming.rebind("c27",main1.get(0));
					
					// Main 2
					Naming.rebind("c28",main2.get(0));
					Naming.rebind("c29",main2.get(0));
					Naming.rebind("c30",main2.get(0));
					
					// Main 3
					main3= plateau.getJoueurs().get(2).getMain();
					Naming.rebind("main3",main3);
					
					Naming.rebind("c31",main3.get(0));
					Naming.rebind("c32",main3.get(0));
					Naming.rebind("c33",main3.get(0));
					
					// Main 4
					main4= plateau.getJoueurs().get(3).getMain();
					Naming.rebind("main4",main4);
					
					Naming.rebind("c34",main4.get(0));
					Naming.rebind("c35",main4.get(0));
					Naming.rebind("c36",main4.get(0));
					
					break;
			}
			
			//Traitement des cartes du tapis			
			Naming.rebind("c37",tapis.get(0));
			Naming.rebind("c38",tapis.get(1));
			Naming.rebind("c39",tapis.get(2));
			Naming.rebind("c40",tapis.get(3));
			
		}
		catch ( Exception e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	* MAIN 
	* ==> Execution de toutes les methodes
	* Precedemment definies
	*/
	//~ public static void main ( String args[] ) throws Exception
	//~ {
		//~ try
		//~ {
			//~ new Serveur();
		//~ }
		//~ catch ( Exception e )
		//~ { e.printStackTrace(); }
	//~ }
}