import java.util.Iterator;

public class Controle {

	private boolean demandeEM;
	private boolean jeton_pris;
	private int id_site;
	
	public Controle(int id){
		demandeEM = false;
		jeton_pris = false;
		id_site = id;
	}
	
	/* MESSAGES */
	
	public synchronized boolean bsc(int NumApp, FileAtt file){
		demandeEM = true;
		
		if(file.chemin_tete() == 0){ //Si c'est le pre
			Req requete = new Req(new ReqIndiv(NumApp,Null));
			
			/* ENVOI D'UNE REQUETE AU PERE */
		}
		else{
			empiler(NumApp,file);
			return false;
		}
			
		return true;
	}
	
	public synchronized void fsc(int NumApp, FileAtt file){
		demandeEM = false;
		depiler(file);
		
		int filsreq1 = file.chemin_tete();
		
		if(file.nombre_req() > 0){
			file = ajout_retrait_file(file);
			jeton_pris = false;
			/* ENVOI DU JETON A SON FILS */
		}
	}
	
	public int req(int NumApp, FileAtt file){
		if(file.chemin_tete() == 0){ //Si c'est le pre
			if(demandeEM)
				empiler(NumApp,file);
			else{
				jeton_pris = false;
				int fils = retirer_recepteur_req(file);
				/* ENVOI DU JETON AU FILS */
				return fils;
			}
		}
		else{
			file.head_req().ajout_chemin(id_site);
			/* ENVOI DE LA NOUVELLE REQUETE AU PERE */
		}
		return -1;
	}
	
	public Message jeton(FileAtt file){
		
		if(id_site == file.demandeur_tete()){
			jeton_pris = false;
			/* ENVOI DEMANDE SECTION CRITIQUE A L'APPLI */
			return new Dsc();
		}
		else{
			int pere = file.chemin_tete();
			file = ajout_retrait_file(file);
			/* ENVOI DU JETON A SON PERE */
			return new Jeton(file);
		}
	}
	
	/* FIN MESSAGES */
	
	/* Ajoute une requte en fin de file */
	private void empiler(int NumApp, FileAtt file){
		ReqIndiv requete = new ReqIndiv(NumApp,file.chemin_tete());
		file.ajouter(requete);
	}
	
	/* Supprime la requte en tte de file */
	private FileAtt depiler(FileAtt file){
		file.depiler();
		return file;
	}
	
	/* Retire le rŽcepteur de la requte en tte de file et renvoi le suivant */
	private int retirer_recepteur_req(FileAtt file){
		file.head_req().retirer_chemin();
		return file.head_req().getTeteChemin();
	}
	
	/* Retire son fils de tous les chemins o il est et ajoute son id dans tous les chemins o son fils n'est pas */
	private FileAtt ajout_retrait_file(FileAtt file){
		FileAtt newfile = new FileAtt();
		
		Iterator<ReqIndiv> filetmp;
		filetmp = file.all_requetes();
		
		ReqIndiv req = filetmp.next();
		int filsreq1 = req.getTeteChemin();
		
		while(filetmp.hasNext()){
			
			if(req.getTeteChemin() == filsreq1)
				req.retirer_chemin();
			else
				req.ajout_chemin(id_site);
			
			newfile.ajouter(req);
			req = filetmp.next();
		}
		
		return newfile;
	}
}
