package partyscenario;

import java.util.Random;
import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.CyclicBehaviour;
import jade.core.behaviours.TickerBehaviour;
import jade.core.behaviours.WakerBehaviour;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPANames;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.NotUnderstoodException;
import jade.domain.FIPAAgentManagement.SearchConstraints;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.proto.ProposeResponder;

public class GuestAgent extends Agent{
	private int capacidad_comida;
	private int capacidad_bebida;
	private Random r = new Random();
	private AID[] invitados;
	private String[] listaSaludo;
	private boolean hay = false;
	protected void setup() {
		capacidad_comida = r.nextInt(10)+1;
		capacidad_bebida = r.nextInt(10)+1;
		Object[] args = getArguments();
		String tiempo = (String) args[0]; 
		long t = Long.parseLong(tiempo);
		addBehaviour(new WakerBehaviour(this,t){
		    	protected void onWake(){
				 	int i = 0;
				 	Random ran = new Random();
				 	int aleatorio=0;
		    		DFAgentDescription template = new DFAgentDescription();
		            ServiceDescription sd1 = new ServiceDescription();
		            sd1.setType("attendant");
		            template.addServices(sd1);
		            SearchConstraints ALL = new SearchConstraints();
		            ALL.setMaxResults(new Long(-1));
		            try {
		            	DFAgentDescription[] result = DFService.search(myAgent, template, ALL);
		            	invitados = new AID[result.length];
		            	listaSaludo= new String[result.length]; 
		                for (int ik = 0; ik < result.length; ik++) {
		                  invitados[ik] = result[ik].getName();
		                }
		            	while(i< invitados.length){
		            	   aleatorio=ran.nextInt(invitados.length);
		            	   AID invitado = invitados[aleatorio];
		            	   for (int j=0; j<i; j++){
		            		   if (listaSaludo[j].compareTo(invitado.getLocalName())==0){
		            			  hay=true;
		            			  break;
		            		   }
		            	   }
		            	   if(hay == false){
		            		   listaSaludo[i] = invitado.getLocalName(); 
		            		   i++;
		            		   ACLMessage saludo = new ACLMessage(ACLMessage.INFORM);
				               saludo.setContent("hola, he llegado");
				               saludo.addReceiver(invitado);
				               System.out.println(myAgent.getLocalName()+": saludando a "+invitado.getLocalName());
				               myAgent.send(saludo);
				               myAgent.blockingReceive(MessageTemplate.MatchContent("Bienvenido"));
				               System.out.println(myAgent.getLocalName()+": se ha saludado a "+invitado.getLocalName()); 
		            	   }
		            	   hay=false;
		               }
		             }
		             catch (FIPAException fe) {
		               fe.printStackTrace();
		             }
		    		DFAgentDescription dfd = new DFAgentDescription();
				    dfd.setName(getAID());
				    ServiceDescription sd = new ServiceDescription();
				    sd.setType("attendant");
				    sd.setName("Guest");
				    dfd.addServices(sd);
				    try {
				      DFService.register(myAgent, dfd);
				    }
				    catch (FIPAException fe) {
				      fe.printStackTrace();
				    }
		    	}
		    });
			addBehaviour(new TickerBehaviour(this, t+5000){

				@Override
				protected void onTick() {
					if (capacidad_comida == 0){
						System.out.println(getLocalName()+ ": creo que he comido demasiado, hora de dejar la fiesta");
						doDelete();
					}
					else if (capacidad_bebida == 0){
						System.out.println(getLocalName()+ ": creo que he bebido demasiado, hora de dejar la fiesta");
						doDelete();
					}	
				}
				
			});
		    addBehaviour(new CyclicBehaviour(){ //escucha

				@Override
				 public void action() {
					  MessageTemplate mt = MessageTemplate.MatchContent("hola, he llegado");
					  ACLMessage msg = myAgent.receive(mt);
				    if (msg != null) {
				      System.out.println(getLocalName()+": devolviendo el saludo a " +msg.getSender().getLocalName());
				      ACLMessage reply = msg.createReply();
				      reply.setContent("Bienvenido");
				      myAgent.send(reply);
				    }
					  else {
					    block();
					  }
				  }
		    	
		    });
		    MessageTemplate plantilla = ProposeResponder.createMessageTemplate(FIPANames.InteractionProtocol.FIPA_PROPOSE);
	        this.addBehaviour(new Responderofrecimiento(this, plantilla));
	 }
	 protected void takeDown(){
		 System.out.println(getLocalName()+": despidiendome del anfitrión");
		 DFAgentDescription template = new DFAgentDescription();
		 ServiceDescription sd1 = new ServiceDescription();
         sd1.setName("Host");
         template.addServices(sd1);
         try{
        	 DFAgentDescription[] result = DFService.search(this, template);
        	 AID host = result[0].getName();
        	 ACLMessage despedida = new ACLMessage(ACLMessage.INFORM);
             despedida.setContent("gran fiesta, adios");
             despedida.addReceiver(host);
             send(despedida);
             blockingReceive(MessageTemplate.MatchContent("hasta la próxima"));
             DFService.deregister(this);
         }
         catch(FIPAException e){
        	 e.printStackTrace();
         }
		 System.out.println(getLocalName()+ ": Dejo la fiesta");
	 }
	    private class Responderofrecimiento extends ProposeResponder {
	   	 
	        public Responderofrecimiento(Agent agente, MessageTemplate plantilla) {
	            super(agente, plantilla);
	        }
	 
	        protected ACLMessage prepareResponse(ACLMessage propuesta)
	                throws NotUnderstoodException {
	        	
	            if (GuestAgent.this.Decision(propuesta.getContent())) {
	                System.out.println(this.myAgent.getLocalName()+ ": Si, tomare algo");
	                if(propuesta.getContent().compareTo("comida")==0)
	                	capacidad_comida--;
	                else
	                	capacidad_bebida--;
	                ACLMessage agree = propuesta.createReply();
	                agree.setPerformative(ACLMessage.ACCEPT_PROPOSAL);
	                return agree;
	            }
	            else {
	                System.out.println(this.myAgent.getLocalName()+ ": No gracias");
	                ACLMessage refuse = propuesta.createReply();
	                refuse.setPerformative(ACLMessage.REJECT_PROPOSAL);
	                return refuse;
	            }
	        }
	    }
		private boolean Decision(String content) {
			Random ran = new Random();
			int quiero = ran.nextInt(100);
			if (quiero >= 50)
				if((content.compareTo("bebida")==0 && capacidad_bebida > 0)||(content.compareTo("comida")==0 && capacidad_comida > 0)) 
					return true;
				else
					return false;
			else 
				return false;
		}
}

