package projects.BenOr.nodes.nodeImplementations;

import java.awt.Color;
import java.awt.Graphics;
import java.util.LinkedList;

import projects.BenOr.nodes.messages.P;
import projects.BenOr.nodes.messages.R;
import projects.defaultProject.nodes.messages.Msg;
import projects.defaultProject.nodes.nodeImplementations.CNode;
import sinalgo.gui.transformation.PositionTransformation;

class triplet
{
	public String type;
	public int k,x;

	
	public triplet(String type,int k,int x){
		this.type=type;
		this.k=k;
		this.x=x;
	}
	
	public  triplet clone() {
		return new triplet(type,k,x);
	}
	
}

public class BONode extends CNode {
 
	int n;
	int v,k,t;
	public int d=-1;
	private LinkedList<triplet> recu;
	String tour; // utilisez cette variable pour savoir quel type de message attendre : "R" ou "P"
  
	public void initialization() {
	// à compléter
	}
	
	// pour supprimer les messages inutiles
	public void clear(String type, int x) {
		LinkedList<triplet> tmp=new LinkedList<triplet>();
		for(triplet t : recu) {
			if(!t.type.equals(type) || t.x!=x) tmp.add(t);
		}
		recu=tmp;
	}

	// diffusion élargie : on "inclut" le processus émetteur
	public void diffusion(Msg m) {
		this.broadcast(m);
		if(m instanceof R) {
			R message=(R) m;
			recu.add(new triplet("R",message.k,message.x));
		}
		else {
			P message=(P) m;
			recu.add(new triplet("P",message.k,message.x));
		}
	}
	
	public void spontaneously() {
		// à compléter
	}

	
	// fonctions utiles ...
	boolean AuMoins_n_moins_t_R_k_messages() {
		int cpt=0;
		for(triplet y : recu) {
			if(y.type.equals("R") && y.k==this.k) {
				cpt++;
			}
		}
		return cpt >= n-t; 
	}
	
	
	boolean AuMoins_n_moins_t_P_k_messages() {
		int cpt=0;
		for(triplet y : recu) {
			if(y.type.equals("P") && y.k==this.k) {
				cpt++;
			}
		}
		return cpt >= n-t; 
	}
	
	int PlusDe_n_sur_2_R_k_meme_valeur() {
		int Zero=0,Un=0;
		for(triplet y : recu) {
			if(y.type.equals("R") && y.k==this.k) {
				if(y.x==0) Zero++;
				else if(y.x==1) Un++;
			}
		}
		if(Zero >  n/2) return 0;
		if(Un > n/2) return 1;
		return -1;
	}
	
	
	
	int AuMoins_t_plus_1_P_k_x() {
		int Zero=0,Un=0;
		for(triplet y : recu) {
			if(y.type.equals("P") && y.k==this.k) {
				if(y.x==0) Zero++;
				else if(y.x==1) Un++;
			}
		}
		if(Zero >= t+1) return 0;
		if(Un >= t+1) return 1;
		return -1;
	}
	
	int AuMoins_1_P_k_x() {
		for(triplet y : recu) {
			if(y.type.equals("P") && y.k==this.k) {
				if(y.x==0) return 0;
				if(y.x==1) return 1;
			}
		}
		return -1;
	}
	
	public void receipt(LinkedList<Msg> inbox) {
			for(Msg m: inbox) {
				if(m instanceof R) {
					R message=(R) m;
					recu.add(new triplet("R",message.k,message.x));
				}
				else {
					P message=(P) m;
					recu.add(new triplet("P",message.k,message.x));
				}
			}

		// à compléter
		}
	
 
	
	Color couleur() {
		if(this.Crashed()) return Color.black;
		if(d==-1) {
			if(this.v==0) return Color.cyan;
			return Color.pink;
		}
		if(d==0) return Color.blue;
		return Color.red;
	}
	

  
    public void draw(Graphics g, PositionTransformation pt, boolean highlight){	 
    	String text="";
    	if(this.Id()>0)	text= ""+this.Id()+"";
    	this.setColor(couleur());
    	super.drawNodeAsDiskWithText(g, pt, false, text, 30, Color.black);
	 
    }	
    
}
