import madkit.kernel.*;
import madkit.lib.messages.*;
import java.util.*;
import madkit.kernel.AgentAddress;
import java.io.Serializable;


/**
 * Une classe représentant le comportement de l'agent Matchmaker
 * 
 * @author Vincent Delord & Alexandre Lanoix
 * @version 1
 * @see madkit.kernel.Agent
 */


public class MatchMaker extends Agent {
  
  
    /*------------------------------------------------------------------------*/
    /*----------------------- Matchmaker -------------------------------------*/
    /*------------------------------------------------------------------------*/

    /**
     * Liste qui permet garde en mémoire les Inficard des différents agents Vendeur 
     */
    private Vector infoCards = new Vector();
    


    /**
     * Méthode qui gère l'activation de l'agent MatchMaker
     * Cette activation consiste à créer le groupe marché et à initialiser l'agent MatchMaler
     */
    public void activate () {
	println("Agent matchmaker activé");
	createGroup(true,"DESS IHM","market",null,null);
	println("J'ai cree le group market");
	requestRole("DESS IHM","market","matchmaker",null);
    }
    
    /**
     * Méthode qui gère la vie de l'agent MatchMaker
     * Durant sa vie, cet agent met en relation des agents Acheteur et Vendeur
     */
    public void live() {
	ActMessage m;
	String reponse;

	println("Je vais attendre les vendeurs et les acheteurs....");
	do {
	    exitImmediatlyOnKill(); //être sûr d'arrrêter le thread
	    pause(100);
	    while(!isMessageBoxEmpty()) {
		m = (ActMessage)nextMessage();
		AgentAddress agt = m.getSender();

		// Message : publier - vendeur
		if (m.getAction().equals("demander publier")) {

		    println(" Un vendeur me demande de publier les informations de son infoCard");
		    /* on récupère l'info card d'un vendeur donné */
		    InfoCard inf = (InfoCard)(m.getObject());
		    
		    /* on vérifie s'il n'existe déjà ce type de poisson */
		    if (isPoisson(inf.getMarchandise())==false) {		
			infoCards.add(inf);
			/* renvoyer au vendeur l'autorisation d'ouvrir un marché */
		        reponse = "oui";
			println("Le vendeur peut ouvrir son marché");
		    }
		    else {
			reponse = "non";
			println("Le vendeur ne peut pas ouvrir son marché, car un tel marché existe déjà");
		    }
		    sendMessage (agt,new ActMessage("répondre publier",reponse));
					
		}

		/* Message : existe salle de vente - acheteur */
		if (m.getAction().equals("demander existence salle")) {
		    /* on récupère le type de poisson que l'acheteur désire */
		    String acheteurTypePoisson = m.getContent();
		    println(acheteurTypePoisson);
		    println("J'ai recu une demande d'existence de salle pour le poisson "+acheteurTypePoisson);
		    if (isPoisson(acheteurTypePoisson)== true) {
			/* demande au vendeur si l'acheteur peut rentrer dans son groupe */
			
			/* 1. on recupere l'infoCard du vendeur du type de poisson */
			InfoCard info = seekInfoCard (acheteurTypePoisson);
			/* 2. on recupere son adresse */
			AgentAddress adresse = info.getAddressVendeur();
			/* 2. on envoie le message au bon vendeur */
			sendMessage (adresse,new ActMessage("demander entrer groupe",m.getSender()));
			println(" J'envoie un acheteur potentiel au vendeur de "+acheteurTypePoisson);
		    }
		}

		// Message : OK pour entrer salle de vente - vendeur
		if (m.getAction().equals("AR demander entrer groupe")) {
		    /*  on récupère l'addresse du demandeur en 1° argt ,
			on récupère l'infoCard correspondant a l'addresse
			du vendeur qui a fait l'AR (2° argt du message), 
			ensuite  il ne reste plus qu'à envoyer le message... au demandeur */
		    sendMessage ((AgentAddress)(m.getObject()),
				 new ActMessage("repondre existence salle",
						seekInfoCard((AgentAddress)(m.getSender()))));
		}

		// Mesage : suicide du vendeur - vendeur
		if (m.getAction().equals("informer suicide")) {
		    /* on récupère l infoCard du vendeur suicide 
		       et on met a jour notre tableau d infoCards*/
		    infoCards.remove(seekInfoCard((AgentAddress)(m.getSender())));
		}
	    }
	}	    
	
	while(true);
    }


    /**
     * Méthode qui gère la fin de l'agent MatchMaker
     */
    public void end(){
    }

    /*------------------------------------------------------------------------*/
    /*------------------------- Methodes Utiles-------------------------------*/
    /*------------------------------------------------------------------------*/

    /** 
     * Méthode testant si un poisson donné est déjà référencé par le matchmaker
     *
     * @param poisson le poisson sur lequel se porte le test
     * @return boolean
     *
     */
    public boolean isPoisson (String poisson ) {
	/* on vérifie qu'il n'existe pas déjà ce type de poisson */
	Iterator i = infoCards.iterator();
	boolean exist = false;
	while (i.hasNext() && (exist==false)) {
	    InfoCard c = (InfoCard)i.next();
	    if (c.getMarchandise() == poisson) {
		exist=true;
	    }
	}
	return exist;
    }

    /**
     * Méthode retournant un objet Infocard d'un agent Vendeur à partir d'un poisson donné
     *
     * @param poisson le poisson permettant de retrouver l'InfoCard
     * @return l'Infocard désirée
     *
     */
    public InfoCard seekInfoCard (String poisson) {
	/* on récupère tout d'abord tous les types de poisson */
	int taille = infoCards.size();
	String [] tableauPoisson = new String [taille];
	for ( int i =0; i< taille;i++) {
	    InfoCard tmp = (InfoCard)infoCards.elementAt(i);
	    String fish = tmp.getMarchandise();
	    tableauPoisson[i]= (fish);
	}
	int compteur=0;
	while (tableauPoisson[compteur]!=poisson) {
	    compteur++;
	}
	return (InfoCard)infoCards.get(compteur);
    }


    /**
     * Méthode retournant un objet Infocard d'un agent Vendeur à partir d'une adresse donnée
     *
     * @param address l'adresse de l'agent permettant de retrouver l'InfoCard
     * @return l'InfoCard désirée
     *
     */
    public InfoCard seekInfoCard (AgentAddress address) {
	/* on récupère tout d'abord tous les types de AgentAddress */
	int taille = infoCards.size();
	AgentAddress [] tableauAddress = new AgentAddress [taille];
	for ( int i =0; i< taille;i++) {
	    InfoCard tmp = (InfoCard)infoCards.elementAt(i);
	    AgentAddress add = tmp.getAddressVendeur();
	    tableauAddress[i]= (add);
	}
	int compteur=0;
	while (tableauAddress[compteur]!=address) {
	    compteur++;
	}
	return (InfoCard)infoCards.get(compteur);
    }



    /*-----------------------------------fin de la classe MatchMaker-----------------------------*/


}
		    
		  
