package jadelab1;

import jade.core.*;
import jade.core.behaviours.*;
import jade.lang.acl.*;
import jade.domain.*;
import jade.domain.FIPAAgentManagement.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class MyAgent extends Agent
{

	protected void setup()
	{
		displayResponse("Hello, I am " + getAID().getLocalName());
		addBehaviour(new MyCyclicBehaviour(this));
		//doDelete();
	}

	protected void takeDown()
	{
		displayResponse("See you");
	}
	public void displayResponse(String message)
	{
		JOptionPane.showMessageDialog(null,message,"Message",JOptionPane.PLAIN_MESSAGE);
	}

	public void displayHtmlResponse(String html)
	{
		JTextPane tp = new JTextPane();
		JScrollPane js = new JScrollPane();
		js.getViewport().add(tp);
		JFrame jf = new JFrame();
		jf.getContentPane().add(js);
		jf.pack();
		jf.setSize(400,500);
		jf.setVisible(true);
		tp.setContentType("text/html");
		tp.setEditable(false);
		tp.setText(html);
	}
}

class MyCyclicBehaviour extends CyclicBehaviour
{
	MyAgent myAgent;

	Map<String, String> messagesDB = new HashMap<>();


	public MyCyclicBehaviour(MyAgent myAgent)
	{
		this.myAgent = myAgent;
	}


	public void action()
	{
		ACLMessage message = myAgent.receive();
		if (message == null)
		{
			block();
		}
		else
		{
			String ontology = message.getOntology();
			String content = message.getContent();
			int performative = message.getPerformative();

			if (performative == ACLMessage.REQUEST)
			{
				//I cannot answer but I will search for someone who can
				DFAgentDescription dfad = new DFAgentDescription();
				ServiceDescription sd = new ServiceDescription();
				sd.setName(ontology);
				dfad.addServices(sd);
				try
				{
					// Searching for ontology specific service
					DFAgentDescription[] result = DFService.search(myAgent, dfad);
					if (result.length == 0)
					{
						myAgent.displayResponse("No ontology specific service has been found ...");

						// Search for universal service
						dfad.clearAllServices();
						sd.setName("all");
						dfad.addServices(sd);
						result = DFService.search(myAgent, dfad);
						
						if (result.length == 0) myAgent.displayResponse("No universal service has been found ...");
						else
						{
							String foundAgent = result[0].getName().getLocalName();
							myAgent.displayResponse("Agent " + foundAgent + " is universal service provider. Sending message to " + foundAgent);

							// Put into hashmap
							String messageID = UUID.randomUUID().toString();
							messagesDB.put(messageID, message.getContent());

							ACLMessage forward = new ACLMessage(ACLMessage.REQUEST);
							forward.addReceiver(new AID(foundAgent, AID.ISLOCALNAME));
							forward.setContent(content);
							forward.setOntology(ontology);
							forward.setReplyWith(messageID);

							myAgent.send(forward);
						}
					}
					else
					{
						String foundAgent = result[0].getName().getLocalName();
						myAgent.displayResponse("Agent " + foundAgent + " is a service provider. Sending message to " + foundAgent);
						ACLMessage forward = new ACLMessage(ACLMessage.REQUEST);
						forward.addReceiver(new AID(foundAgent, AID.ISLOCALNAME));
						forward.setContent(content);
						forward.setOntology(ontology);
						myAgent.send(forward);
					}
				}
				catch (FIPAException ex)
				{
					ex.printStackTrace();
					myAgent.displayResponse("Problem occured while searching for a service ...");
				}
			}
			else
			{
				//when it is an answer
				if(message.getInReplyTo() != null && message.getInReplyTo() != "")
				{
					String orginalWord = messagesDB.get(message.getInReplyTo());

					myAgent.displayHtmlResponse("Message ID: " + message.getInReplyTo() + "<br>Orginal word: " + orginalWord + "<br>Reply content: " + content);
				}
			}
		}
	}
}
