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


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


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


public class Acheteur extends Agent {

    public class AcheteurGUI extends JPanel implements ItemListener, KeyListener, ActionListener{
	String poissonRecorded="saumon";
	
	JButton ok;
	JLabel monNom;
	JTextField nom;
	
	JLabel monPrix;
	JTextField prix;
	JLabel euros;
	
	JLabel monPoisson;
	JComboBox poisson;
	
	
	public AcheteurGUI () {
	    setSize(150,150);
	    //setBounds(300,450,200,200);
	    setVisible(true);
	    GridLayout agencement = new GridLayout(2,1);
	    
	    
	    // partie supérieure de l'interface : identité du vendeur
	    JPanel panel = new JPanel();
	    GridLayout grid = new GridLayout(4,1);
	    panel.setLayout(grid);

	    JPanel panel0 = new JPanel();
	    FlowLayout layout = new FlowLayout(FlowLayout.LEFT);
	    monNom = new JLabel ("Nom :",JLabel.RIGHT);
	    nom= new JTextField(12);
	    nom .addKeyListener(this);
	    panel0.setLayout(layout);
	    panel0.add(monNom);
	    panel0.add(nom);
	    panel.add(panel0);
	    this.add(panel);

	    
	    // partie mediane de l'interface : prix initial du poisson
	    JPanel panel1 = new JPanel();
	    FlowLayout layout1 = new FlowLayout(FlowLayout.LEFT);
	    monPrix = new JLabel (" Prix maximum: ",JLabel.RIGHT);
	    prix= new JTextField(5);
	    prix.addKeyListener(this);
	    euros = new JLabel("euros", JLabel.LEFT);
	    panel1.add(monPrix);
	    panel1.add(prix);
	    panel1.add(euros);
	    panel1.setLayout(layout1);
	    panel.add(panel1);
	    this.add(panel);
	    
	    //partie inférieure de l'interface : poisson vendu 
	    JPanel panel2 = new JPanel();
	    FlowLayout layout2 = new FlowLayout(FlowLayout.LEFT);
	    monPoisson = new JLabel ("J'achète du",JLabel.RIGHT);
	    
	    poisson = new JComboBox();
	    poisson.addItem("saumon");
	    poisson.addItem("truite");
	    poisson.addItem("thon");
	    poisson.addItem("requin");
	    poisson.addItem("sole");
	    poisson.addItemListener(this);
	    
	    panel2.add(monPoisson);
	    panel2.add(poisson);
	    panel2.setLayout(layout2);
	    panel.add(panel2);
	    this.add(panel);
	    
	    // partie inférieure de l'interface
	    JPanel panel3 = new JPanel();
	    ok = new JButton("S'inscrire");
	    FlowLayout layout3 = new FlowLayout(FlowLayout.CENTER);
	    ok.setEnabled(false);
	    ok.addActionListener(this);
	    panel3.add(ok);
	    panel3.setLayout(layout3);
	    panel.add(panel3);
	    this.add(panel);
	    
	    JPanel panel4 = new JPanel();
	    j = new JTextArea(6,25);
	    j.setLineWrap(true);
	    j.setWrapStyleWord(true);
	    JScrollPane textPane = new JScrollPane(j,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
	    panel4.add(textPane);
	    this.add(panel4);
	    
	    this.setLayout(agencement);
	
	}
 

	/* -------------------- Méthodes qui traite les évènements utilisateurs-------------------*/
       
	/* Méthode qui permet de réagir aux cases à cocher et aux listes d'options */
	public void itemStateChanged(ItemEvent e) {
	    Object type = e.getItem();
	    poissonRecorded  = type.toString();
	}
	
	/* Méthodes qui permettent de réagir aux événements claviers */
	public void keyPressed(KeyEvent e) {
	}
	
	public void keyReleased (KeyEvent e) {
	}
	
	public void keyTyped (KeyEvent e) {
	    if ((prix.getText()== "" )){
		ok.setEnabled(false);
	    }
	    else  {
		ok.setEnabled(true);
	    }
	}
	
	/* Méthode qui permet de réagir aux clics */
	public void actionPerformed(ActionEvent e) {
	    Object source = e.getSource();
	    if (source==ok) {
		initAcheteur(nom.getText(),poissonRecorded,prix.getText());
		estInscrit = true;
	    }
	}
    }


    /*------------------------------ Corps de l'acheteur ---------------------------------*/

    /**
     * nom de l'agent Acheteur
     */
    String nom="";
    /**
     * type de poisson que souhaite acheter l'agent Acheteur
     * par défaut, le poisson acheté est du saumon
     */
    String marchandise ="saumon";
    /**
     * carte d'accès que doit récupérer l'agent Acheteur afin de pouvoir entrer dans le groupe
     */
    String accessCard;
    //String espaceDeVenete;
    /**
     * adresse de l'agent Vendeur que doit récupérer l'agent Acheteur
     */
    AgentAddress vendeur = null;
    /**
     * prix maximum qu'est prêt à payer l'agent Acheteur pour acheter le poisson
     */
    int prixMax=0;
    /**
     * booleen qui teste si un agent Vendeur a rempli tous ses champs (nom, poisson, prix)
     */
    boolean estInscrit = false;
    /**
     * InfoCard que l'agent Acheteur récupère pour pouvoir récupérer des informations relatives à l'agent Vendeur
     */
    InfoCard infocard;

    JTextArea j;


    /**
     * Constructeur qui permet de créer l'interface associée
     * L'utilisateur pourra alors entrer les informations suivantes :
     *     - le nom de l'agent Acheteur
     *     - le type de poisson qu'il vend
     *     - le prix de vente maximal qu'il est prêt à payer
     */
    public Acheteur() {
    }
    
    public void initGUI() {
	AcheteurGUI a = new AcheteurGUI();
	this.setGUIObject(a);
    }

    /**
     * Méthode qui active l'agent Acheteur
     * Pendant cette activation, l'agent Acheteur initialise :
     *     - son nom
     *     - le poisson qu'il désire acheter
     *     - le prix max
     */
    public void activate(){
	   
	System.out.println("Activation de l'acheteur "+nom);
	do {
	    pause(2000);
	}
	while (!estInscrit);
	println("Bonjour, je m'appelle "+nom+" et je suis acheteur de "+marchandise+ " au prix de "+prixMax);

	// Attente creation groupe market

	requestRole("market","member",null);

    }


    /**
     * Méthode qui gère la vie de l'agent Acheteur
     * Durant sa vie, l'agent devra :
     *     - vérifier l'existence d'une salle de vente pour le poisson qu'il désire acheter
     *     - attendre que le matchmaker lui fournisse les informations relatives à l'agent Vendeur
     *     - participer aux enchères en compétittion avec au moins un autre acheteur
     */
    public void live(){
	    
        boolean adjugevendu = false;
	boolean isSalleDispo = false;

	println("L'acheteur vit");
	do {
	    // Vérifier existence d'une salle
	    ActMessage msgexistencesalle = new ActMessage("demander existence salle", marchandise);
	    sendMessage(getAgentWithRole("DESS IHM","market","matchmaker"),msgexistencesalle);

	    println("j'envoie une demande d'existence de salle pour la marchandise "+marchandise+" au prix de "+prixMax);
	    System.out.println("L'acheteur "+nom+" envoie une demande d'existence de salle pour la marchandise "+marchandise+" au prix de "+prixMax);
	    
	    System.out.println("L'acheteur "+nom+" attend 3 sec la réponse du matchmaker");
	    /* on attend la réponse du matchmaker pendant 3 sec */
	    pause(3000);

	    /* On attend la réponse du matchmaker */
	    while (!isMessageBoxEmpty()) {                                     
		ActMessage msg = (ActMessage)nextMessage();
		
		// Entrer dans le groupe
		if (msg.getAction() == "repondre existence salle"){
		    infocard = (InfoCard)msg.getObject();
		    vendeur = infocard.getAddressVendeur();
		    isSalleDispo = true;
		    println("entrée dans le groupe en tant qu'acheteur");
		    requestRole(infocard.getGroup(),"acheteur",infocard.getAccessCard()); 
		}
		else
		    isSalleDispo = false;
	    }
	}while (!isSalleDispo);
	
	/* Protocole FishMarket */
	println(" Je suis prêt pour l'enchère");
	System.out.println("L'acheteur "+nom+" est prêt pour l'enchère avec le vendeur "+infocard.getNomVendeur());
	while (adjugevendu == false){
	    pause(2000);
	    while (isMessageBoxEmpty() == true) {
		pause(3000);
		println("J'attend une proposition de la part du vendeur"+infocard.getNomVendeur());
		System.out.println("L' acheteur "+nom+" attend une proposition de la part du vendeur "+infocard.getNomVendeur());

	    }
	    ActMessage msg1 = (ActMessage)nextMessage();
	    if (msg1.getAction() == "proposer"){
		String temp = msg1.getContent();
		int prixpropose = Integer.parseInt(temp);
		if (prixpropose <= prixMax){
		    ActMessage msgok = new ActMessage("accepter proposition",null);
		    System.out.println("L'acheteur "+nom+"  accepte la proposition du vendeur "+infocard.getNomVendeur());
		    sendMessage(vendeur ,msgok);
		    println("J' accepte la proposition");
				    
		}
		else {
		    ActMessage msgok = new ActMessage("refuser proposition",null);
		    System.out.println("L'acheteur "+nom+"  refuse la proposition du vendeur "+infocard.getNomVendeur());
		    println("Je refuse la proposition");
		    sendMessage(vendeur ,msgok);
		}
	    }
	    else if (msg1.getAction() == "informer gagnant"){
		adjugevendu = true;
		println("fin des enchères! "+nom+" a  gagné");
		System.out.println(nom+ " a  gagné !");
		pause(2000);
	    }
	    else if (msg1.getAction() == "informer fin"){
		adjugevendu = true;
		println("fin des enchères! "+nom+" a perdu");
		System.out.println(nom+ " a perdu !");
		pause(2000);
	    }	
	}
    }


    /**
     * Méthode qui gère la fin de vie de l'agent Acheteur
     * Dans tous les cas, que l'agent Acheteur ait gagné ou non l'enchère, il meurt après la fin de celle-ci
     */
    public void end(){
	println("L'acheteur "+nom+" s'en va");
	System.out.println("L'acheteur "+nom+" s'en va");
	pause(2000);
    }


    /*---------------------------------Méthodes utiles--------------------------------------------*/

    /**
     * Méthode qui initialise les caractéristiques de l'agent Vendeur à savoir :
     *      - son nom
     *      - le type de poisson qu'il achète
     *      - le prix d'achat maximal
     * @param nom le nom de l'acheteur
     * @param poisson le type de poisson acheté par l'agent Acheteur
     * @param prix le prix d'achat maximal du poisson
     *
     */
     public void initAcheteur(String nom, String poisson, String prix) {
	this.nom = nom;
	this.marchandise = poisson;
	this.prixMax = Integer.parseInt(prix);
    }


    public void println(String s) {
	j.append(s +"\n");
    }

    /*---------------------------------fin de la classe Acheteur-----------------------------------*/
}
	    
		





