package bramble.slavenode;

import java.io.IOException;
import java.io.Serializable;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.util.ArrayList;

import bramble.genericnode.GenericNode;
import bramble.masternode.MessageParser;
import bramble.networking.Handshake;
import bramble.networking.JobResponseData;
import bramble.networking.JobSetupData;
import bramble.networking.ListenerServer;

public abstract class SlaveNode extends GenericNode implements Runnable {
	
	private ListenerServer listenerServer;
	private int jobID;
	private ArrayList<Serializable> initializationData;
	
	public SlaveNode() {
		super();
		
		try {
			listenerServer = new ListenerServer();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.exit(1);
		}
	}

	public void listenForever() {
		
		while(true){
			listen();
		}
	}
	
	public void listen(){
		try {
			JobSetupData jobSetupData = (JobSetupData) listenerServer.listen();
			
			this.jobID = jobSetupData.getJobID();
			this.initializationData = jobSetupData.getInitializationData();
			
			// Parse in seperate thread to avoid missing packet(s).
			new Thread(this).start();
			
		} catch (ClassNotFoundException | IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Sends the data from a completed job back to the master node.
	 * 
	 * @param jobIdentifier - the unique job ID
	 * @param message - Status message.
	 * @param data - The data to send back to the master node in ArrayList form.
	 */
	public static void sendData(int jobIdentifier, String message, ArrayList<? extends Object> data){
		try{
			(new JobResponseData(jobIdentifier, message, data)).send();
		} catch (IOException e) {
			System.out.println("Couldn't connect to master node. Aborting.");
			e.printStackTrace();
			System.exit(1);
		}
	}
	
	public void run(){
		runJob(this.jobID, this.initializationData);
	}
	
	protected abstract void runJob(int jobID, ArrayList<Serializable> initializationData);

}

@@ -616,21 +616,24 @@
 ta;%0A%09%0A%09p
-ublic
+rotected
  SlaveNo
@@ -820,16 +820,112 @@
 %09%09%7D%0A%09%7D%0A%0A
+%09/**%0A%09 * Will call listen() forever, meaning %0A%09 * that more than one job can be scheduled.%0A%09 */%0A
 %09public 
@@ -947,19 +947,16 @@
 ver() %7B%0A
-%09%09%0A
 %09%09while(
@@ -976,32 +976,221 @@
 ten();%0A%09%09%7D%0A%09%7D%0A%09%0A
+%09/**%0A%09 * Sets up a listener server to listen for incoming jobs.%0A%09 * %0A%09 * When a job is received, it sets jobID and %0A%09 * initializationData fields in this class, then calls run().%0A%09 * %0A%09 */%0A
 %09public void lis
@@ -1395,67 +1395,8 @@
 %09%09%09%0A
-%09%09%09// Parse in seperate thread to avoid missing packet(s).%0A
 %09%09%09n
@@ -2073,78 +2073,718 @@
 %0A%09%0A%09
-public void run()%7B%0A%09%09runJob(this.jobID, this.initializationData);%0A%09%7D%0A%09
+/**%0A%09 * Called when a job starts. By default, will %0A%09 * call runJob with the jobID and initialization %0A%09 * data as parameters.%0A%09 * %0A%09 * Clients should override runJob() rather than run().%0A%09 */%0A%09public void run()%7B%0A%09%09runJob(this.jobID, this.initializationData);%0A%09%7D%0A%09%0A%09/**%0A%09 * Clients should override this method to call code relevant to their project.%0A%09 * %0A%09 * @param jobID - the job identifier. This %0A%09 * %09%09%09%09%09should be saved and sent back to the master %0A%09 * %09%09%09%09%09node along with any relevant computation %0A%09 * %09%09%09%09%09data once the job is finished.%0A%09 * %0A%09 * @param initializationData - An array of data which is used to %0A%09 * %09%09%09%09%09%09%09set the initial state, configuration, %0A%09 * %09%09%09%09%09%09%09or limits of a computation.%0A%09 */
 %0A%09pr

Add javadoc