distributed_automated/multi_agent_system/src/com/mas/main/ConveyorAgent.java
package com.mas.main;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.mas.main.ENUMS.STATES;

import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.CyclicBehaviour;
import jade.core.behaviours.TickerBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;

public class ConveyorAgent extends Agent{
	/**
	 * 
	 */

	private String name;
	private ENUMS.STATES state;
	private List<String> palletDests = new ArrayList<String>();
	private Graph conveyor = new Graph();
	private Long transferTime = 1000L;
	public ConveyorAgent() {

	}

	protected void setup() {
		conveyor = ControllerAgent.getGraph();
		name = (String) this.getArguments()[0];
		this.state = (ENUMS.STATES) this.getArguments()[1];
		addBehaviour(new ConveyorBehaviour());
		addBehaviour(new ConveyorTransferBehaviour(this, transferTime));
		addBehaviour(new ConveyorRemovePalletBehaviour(this, 500L));

	}

	private class ConveyorTransferBehaviour extends TickerBehaviour  {
		public ConveyorTransferBehaviour(Agent a, long period) {
			super(a, period);
		}

		@Override
		protected void onTick() {
			Iterator<String> iterator = palletDests.iterator();
			while (iterator.hasNext()) {
				String pallet = iterator.next();
				if(!pallet.contentEquals(name)) {
					List<Vertex> list = conveyor.shortestPath(name, pallet);
					ACLMessage msg = new ACLMessage(ACLMessage.REQUEST);
					msg.setContent("ADD_PALLET_FROM:"+pallet+":"+name);
					msg.addReceiver(new AID("ConveyorAgent"+list.get(1).name, AID.ISLOCALNAME));
					System.out.println("move:"+name+", pallet:"+pallet+", list(1):"+list.get(1).name);

					send(msg);
					ACLMessage response = blockingReceive(); // Wait for a response

					if (response != null) {
						// Process the response
						String content = response.getContent();

						if(!(content.contentEquals("IDLE")||content.contentEquals("DOWN")||content.contentEquals("BUSY"))) {
							return;
						}
						System.out.println("Received response: " + content);
						if(ENUMS.STATES.IDLE == ENUMS.STATES.valueOf(content)) {
							iterator.remove();
						}
					} else {
						System.out.println("Did not receive a response.");
					}
				}
			}


		}
	}

	private class ConveyorRemovePalletBehaviour extends TickerBehaviour  {
		public ConveyorRemovePalletBehaviour(Agent a, long period) {
			super(a, period);
		}

		@Override
		protected void onTick() {
			conveyor.vertices.get(name).state= state.toString(); 
			Iterator<String> iterator = palletDests.iterator();
			while (iterator.hasNext()) {
				String pallet = iterator.next();
				if (pallet.contentEquals(name)) {
					iterator.remove();
				}
			}

		}
	}



	private class ConveyorBehaviour extends CyclicBehaviour {

		public void action() {
			MessageTemplate mt = MessageTemplate.MatchPerformative(ACLMessage.REQUEST);

			ACLMessage msg = receive(mt);
			if (msg != null) {
				String content = msg.getContent();
				System.out.println("msg: "+content);
				if(content!=null&&msg.getContent().contains("CHANGE_STATE")) {
					String newState = content.split(":")[1];
					if(!(newState.contentEquals("IDLE")||newState.contentEquals("DOWN")||newState.contentEquals("BUSY"))) {
						System.out.println("Wrong State");
						return;
					}
					state = ENUMS.STATES.valueOf(newState);
					ACLMessage notifyMsg = new ACLMessage(ACLMessage.INFORM);
					notifyMsg.addReceiver(new jade.core.AID("ControllerAgent", jade.core.AID.ISLOCALNAME));
					System.out.println("State Updated:"+newState+" for conveyor:"+name);
					notifyMsg.setContent("State Updated:"+newState+" for conveyor:"+name);
					send(notifyMsg);
					return;

				}else if(content!=null&&msg.getContent().contains("ADD_PALLET_FROM")) {
					String newPalletDest = content.split(":")[1];
					String newPalletsrc = content.split(":")[2];

					System.out.println("NewPallet with Dest:"+newPalletDest+" has arrived for conveyor:"+name+", from conveyor:"+newPalletsrc);
					if(state==STATES.BUSY||state==STATES.DOWN) {
						ACLMessage notifyMsg = new ACLMessage(ACLMessage.INFORM);
						notifyMsg.addReceiver(new jade.core.AID("ConveyorAgent"+newPalletsrc, jade.core.AID.ISLOCALNAME));
						notifyMsg.setContent("BUSY");
						send(notifyMsg);
					}else {
						palletDests.add(newPalletDest);
						ACLMessage notifyMsg = new ACLMessage(ACLMessage.INFORM);
						notifyMsg.addReceiver(new jade.core.AID("ConveyorAgent"+newPalletsrc, jade.core.AID.ISLOCALNAME));
						notifyMsg.setContent("IDLE");
						send(notifyMsg);

					}
				}else if(content!=null&&msg.getContent().contains("ADD_PALLET")) {
					String newPalletDest = content.split(":")[1];
					if(state==STATES.BUSY||state==STATES.DOWN) {
						System.out.println("NewPallet with Dest:"+newPalletDest+" has arrived for conveyor:"+name+", (BUSY OR DOWN)");
						ACLMessage notifyMsg = new ACLMessage(ACLMessage.INFORM);
						notifyMsg.addReceiver(new jade.core.AID("PalletAgent", jade.core.AID.ISLOCALNAME));
						notifyMsg.setContent("DOWN");
						send(notifyMsg);
					}else {
						System.out.println("NewPallet with Dest:"+newPalletDest+" has arrived for conveyor:"+name+", (IDLE)");
						palletDests.add(newPalletDest);
						ACLMessage notifyMsg = new ACLMessage(ACLMessage.INFORM);
						notifyMsg.addReceiver(new jade.core.AID("PalletAgent", jade.core.AID.ISLOCALNAME));
						notifyMsg.setContent("IDLE");
						send(notifyMsg);
					}
				}

			} else {
				// Block until a message is received
				block();
			}

		}
	}
}
