From 98e02b48ea5b83fa6c3247869b841b0afd260a89 Mon Sep 17 00:00:00 2001
From: Eduardo Pedroni <e.pedroni91@gmail.com>
Date: Sun, 23 Nov 2014 16:06:59 +0000
Subject: Commented some new files, optimised some methods, moved as much
 setting up as possible into the GUIGene constructors - ChromosomePane is
 slightly tidier now.

---
 src/jcgp/backend/population/Gene.java       | 15 ++++-
 src/jcgp/gui/constants/Constants.java       | 52 +++++++++------
 src/jcgp/gui/constants/Position.java        | 79 ++++++++++++++++++++---
 src/jcgp/gui/population/ChromosomePane.java | 90 +++++---------------------
 src/jcgp/gui/population/GUIConnection.java  | 15 +++++
 src/jcgp/gui/population/GUIGene.java        | 63 ++++++++++++++++---
 src/jcgp/gui/population/GUIInput.java       | 45 ++++++++++---
 src/jcgp/gui/population/GUIMutable.java     | 10 +++
 src/jcgp/gui/population/GUINode.java        | 98 ++++++++++++++++++-----------
 src/jcgp/gui/population/GUIOutput.java      | 55 ++++++++++++----
 10 files changed, 352 insertions(+), 170 deletions(-)

diff --git a/src/jcgp/backend/population/Gene.java b/src/jcgp/backend/population/Gene.java
index 47c8dfd..a22abc6 100644
--- a/src/jcgp/backend/population/Gene.java
+++ b/src/jcgp/backend/population/Gene.java
@@ -1,7 +1,12 @@
 package jcgp.backend.population;
 
 /**
- * TODO comment
+ * This abstract class defines a generic CGP gene.
+ * Three types of gene exist, primarily: {@code Input}, {@code Node} and {@code Output}.
+ * <br><br>
+ * In practice, this class facilitates support for a graphical user interface. An arbitrary
+ * object can be associate with each gene using {@code setGUIObject(...)} and retrieved using
+ * {@code getGUIObject()}. 
  * 
  * @author Eduardo Pedroni
  *
@@ -10,10 +15,18 @@ public abstract class Gene {
 
 	private Object guiObject;
 	
+	/**
+	 * Sets a new GUI object.
+	 * 
+	 * @param guiObject the object to set.
+	 */
 	public void setGUIObject(Object guiObject) {
 		this.guiObject = guiObject;
 	}
 	
+	/**
+	 * @return the current GUI object associated with this instance.
+	 */
 	public Object getGUIObject() {
 		return guiObject;
 	}
diff --git a/src/jcgp/gui/constants/Constants.java b/src/jcgp/gui/constants/Constants.java
index 350f8b1..d53b1ca 100644
--- a/src/jcgp/gui/constants/Constants.java
+++ b/src/jcgp/gui/constants/Constants.java
@@ -1,52 +1,62 @@
 package jcgp.gui.constants;
 
+import javafx.scene.paint.Paint;
+
 /**
  * Holds the constants used in the GUI.
  * 
  * @author Eduardo Pedroni
  *
  */
-public abstract class Constants {
+public final class Constants {
 
+	/**
+	 * Private constructor to prevent instantiation.
+	 */
+	private Constants(){}
+	
 	/* Colours */
 	/**
-	 * A string containing the hexadecimal colour used for representing neutrality.
+	 * A {@code Paint} containing the colour used for representing neutrality.
 	 */
-	public static final String NEUTRAL_COLOUR = "#FFFFFF";
+	public static final Paint NEUTRAL_COLOUR = Paint.valueOf("#FFFFFF");
 	/**
-	 * A string containing the hexadecimal colour used for representing a hard highlight.
+	 * A {@code Paint} containing the colour used for representing a hard highlight.
 	 * A "hard" select, for instance, happens when an output path is locked on the chromosome
 	 * pane.
 	 */
-	public static final String HARD_HIGHLIGHT_COLOUR = "#5496FF";
+	public static final Paint HARD_HIGHLIGHT_COLOUR = Paint.valueOf("#5496FF");
 	/**
-	 * A string containing the hexadecimal colour used for a medium highlight.
+	 * A {@code Paint} containing the colour used for a medium highlight.
 	 * One example of such a selection is the colour applied to a node
 	 * when it is hovered over.
 	 */
-	public static final String MEDIUM_HIGHLIGHT_COLOUR = "#75BAFF";
+	public static final Paint MEDIUM_HIGHLIGHT_COLOUR = Paint.valueOf("#75BAFF");
 	/**
-	 * A string containing the hexadecimal colour used for a soft highlight.
+	 * A {@code Paint} containing the colour used for a soft highlight.
 	 * When hovering over a node, its connections are soft-selected.
 	 */
-	public static final String SOFT_HIGHLIGHT_COLOUR = "#C7DFFF";
+	public static final Paint SOFT_HIGHLIGHT_COLOUR = Paint.valueOf("#C7DFFF");
 	/**
-	 * A string containing the hexadecimal colour used for representing a good selection.
+	 * A {@code Paint} containing the colour used for representing a good selection.
 	 * Ideally a shade of green, used for instance when a manual connection is valid.
 	 */
-	public static final String GOOD_SELECTION_COLOUR = "#38C25B";
+	public static final Paint GOOD_SELECTION_COLOUR = Paint.valueOf("#38C25B");
 	/**
-	 * A string containing the hexadecimal colour used for representing a neutral selection.
+	 * A {@code Paint} containing the colour used for representing a neutral selection.
 	 * Ideally a shade of yellow, used for instance when a manual connection is already the
 	 * current connection.
 	 */
-	public static final String NEUTRAL_SELECTION_COLOUR = "#FFEF73";
+	public static final Paint NEUTRAL_SELECTION_COLOUR = Paint.valueOf("#FFEF73");
 	/**
-	 * A string containing the hexadecimal colour used for representing a bad selection.
+	 * A {@code Paint} containing the colour used for representing a bad selection.
 	 * Ideally a shade of red, use for instance when a manual connection is not valid.
 	 */
-	public static final String BAD_SELECTION_COLOUR = "#FF5C5C";
-	
+	public static final Paint BAD_SELECTION_COLOUR = Paint.valueOf("#FF5C5C");
+	/**
+	 * A {@code Paint} containing the colour used for the gene sockets.
+	 */
+	public static final Paint SOCKET_COLOUR = Paint.valueOf("#FFFFFF");
 	
 	
 	/* Sizes and distances */
@@ -74,13 +84,15 @@ public abstract class Constants {
 	 */
 	public static final double SPACING = 15;
 	/**
-	 * The angle across which the node's sockets are evently distributed.
+	 * The margin between the genes and the edge of the chromosome pane.
+	 */
+	public static final double CHROMOSOME_PANE_MARGIN = 10;
+	/**
+	 * The angle across which the node's sockets are evenly distributed.
 	 */
 	public static final double THETA = Math.PI / 1.4;
 	/**
-	 * The radius of the connection sockets, calculated as a function of
-	 * NODE_RADIUS.
-	 * 
+	 * The radius of the connection sockets, calculated as a function of NODE_RADIUS.
 	 */
 	public static final double SOCKET_RADIUS = Math.sqrt(NODE_RADIUS) / 1.8;
 	/**
diff --git a/src/jcgp/gui/constants/Position.java b/src/jcgp/gui/constants/Position.java
index a13d21e..144ba6d 100644
--- a/src/jcgp/gui/constants/Position.java
+++ b/src/jcgp/gui/constants/Position.java
@@ -1,5 +1,6 @@
 package jcgp.gui.constants;
 
+import javafx.scene.shape.Circle;
 import javafx.scene.shape.Line;
 import jcgp.gui.GUI;
 import jcgp.gui.population.GUIGene;
@@ -7,34 +8,98 @@ import jcgp.gui.population.GUIInput;
 import jcgp.gui.population.GUINode;
 import jcgp.gui.population.GUIOutput;
 
+/**
+ * Abstracts the task of positioning GUI components.
+ * <br>
+ * Do not instantiate this class; instead, use the {@code public static} methods provided.
+ * 
+ * @author Eduardo Pedroni
+ *
+ */
 public final class Position {
 	
+	/**
+	 * Private constructor to prevent instantiation.
+	 */
+	private Position() {}
+	
+	/**
+	 * Sets the X and Y layouts of the specified input to the appropriate values, according to its index.
+	 * 
+	 * @param input the {@code GUIInput} instance to relocate.
+	 */
 	public static void place(GUIInput input) {
-		input.relocate(0,
-				input.getInput().getIndex() * (2 * Constants.NODE_RADIUS + Constants.SPACING));
+		// inputs are the first column, so we only worry about the margin and their index
+		input.relocate(Constants.CHROMOSOME_PANE_MARGIN,
+				input.getInput().getIndex() * (2 * Constants.NODE_RADIUS + Constants.SPACING) + Constants.CHROMOSOME_PANE_MARGIN);
 	}
 	
+	/**
+	 * Sets the X and Y layouts of the specified node to the appropriate values, according to its row and column values.
+	 * This also connects the start of every line with its respective socket. Therefore, this method should be called at least
+	 * once when the {@code GUINode} is instantiated.
+	 * 
+	 * @param node the {@code GUINode} instance to relocate.
+	 */
 	public static void place(GUINode node) {
-		// TODO cut down method calls
-		double xOffset = ((node.getNode().getColumn() + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING));
-		double yOffset = node.getNode().getRow() * (2 * Constants.NODE_RADIUS + Constants.SPACING);
+		// calculate x and y offsets, in relation to the layout origin
+		double xOffset = (node.getNode().getColumn() + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING) + Constants.CHROMOSOME_PANE_MARGIN;
+		double yOffset = node.getNode().getRow() * (2 * Constants.NODE_RADIUS + Constants.SPACING) + Constants.CHROMOSOME_PANE_MARGIN;
+		
+		// move node
 		node.relocate(xOffset, yOffset);
 		
+		// use the offset and the socket positions to connect the lines
 		for (int i = 0; i < GUI.resources.arity(); i++) {
 			node.getLine(i).setStartX(node.getSocket(i).getCenterX() + xOffset + Constants.NODE_RADIUS + Constants.SOCKET_RADIUS);
 			node.getLine(i).setStartY(node.getSocket(i).getCenterY() + yOffset + Constants.NODE_RADIUS);
 		}
 	}
 	
+	/**
+	 * Sets the X and Y layouts of the specified output to the appropriate values, according to its index.
+	 * This also connects the start of the output's single line to its single input socket.Therefore,
+	 * this method should be called at least once when the {@code GUIOutput} is instantiated.
+	 * 
+	 * @param output the {@code GUIOutput} instance to relocate.
+	 */
 	public static void place(GUIOutput output) {
-		output.relocate(((GUI.resources.columns() + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING)),
-				output.getOutput().getIndex() * (2 * Constants.NODE_RADIUS + Constants.SPACING));
+		// the output's position is a function of the number of columns and its own index
+		output.relocate(((GUI.resources.columns() + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.CHROMOSOME_PANE_MARGIN,
+				output.getOutput().getIndex() * (2 * Constants.NODE_RADIUS + Constants.SPACING) + Constants.CHROMOSOME_PANE_MARGIN);
 		output.getLine().setStartX(output.getLayoutX() - Constants.NODE_RADIUS);
 		output.getLine().setStartY(output.getLayoutY());
 	}
 	
+	
+	
+	/**
+	 * Connects the end of a specified line to the specified gene.
+	 * 
+	 * @param line the line to connect.
+	 * @param target the target gene to connect to.
+	 */
 	public static void connect(Line line, GUIGene target) {
+		// set line ends based on the layout position of the target
 		line.setEndX(target.getLayoutX() + Constants.NODE_RADIUS);
 		line.setEndY(target.getLayoutY());
 	}
+
+	/**
+	 * Relocates the given socket to the appropriate position given the 
+	 * socket's index.
+	 * 
+	 * @param index the socket index.
+	 * @param socket the {@code Circle} instance to relocate.
+	 */
+	public static void placeSocket(int index, Circle socket) {
+		// calculate the angle with respect to the x-axis
+		double angle = (((index + 1) / ((double) (GUI.resources.arity() + 1))) * Constants.THETA) - (Constants.THETA / 2);
+		// convert to cartesian form
+		double xPos = -Math.cos(angle) * Constants.NODE_RADIUS;
+		double yPos = Math.sin(angle) * Constants.NODE_RADIUS;
+		// set centre
+		socket.setCenterX(xPos);
+		socket.setCenterY(yPos);
+	}
 }
diff --git a/src/jcgp/gui/population/ChromosomePane.java b/src/jcgp/gui/population/ChromosomePane.java
index bf9db72..7826dcc 100644
--- a/src/jcgp/gui/population/ChromosomePane.java
+++ b/src/jcgp/gui/population/ChromosomePane.java
@@ -6,20 +6,13 @@ import javafx.scene.control.ScrollPane;
 import javafx.scene.layout.Pane;
 import javafx.scene.shape.Line;
 import jcgp.backend.population.Chromosome;
-import jcgp.backend.population.Gene;
-import jcgp.backend.population.Input;
 import jcgp.backend.population.Node;
-import jcgp.backend.population.Output;
 import jcgp.gui.GUI;
-import jcgp.gui.constants.Position;
-import jcgp.gui.handlers.InputHandlers;
-import jcgp.gui.handlers.NodeHandlers;
-import jcgp.gui.handlers.OutputHandlers;
 
 /**
  * This extension of {@code ScrollPane} contains a series of
  * nodes, inputs and outputs spread across a grid. It also contains
- * all of the connection lines overlaid over the nodes, inputs and outputs.
+ * all of the connection lines laid over the nodes, inputs and outputs.
  * 
  * 
  * @author Eduardo Pedroni
@@ -33,8 +26,6 @@ public class ChromosomePane extends ScrollPane {
 
 	private Pane content;
 
-	private int rows, columns;
-
 	private boolean target = false;
 
 	public ChromosomePane(Chromosome chromosome) {
@@ -42,58 +33,39 @@ public class ChromosomePane extends ScrollPane {
 
 		ArrayList<Line> connectionLines = new ArrayList<Line>();
 
-		rows = GUI.resources.rows();
-		columns = GUI.resources.columns();
+		int rows = GUI.resources.rows();
+		int columns = GUI.resources.columns();
 
 		content = new Pane();
 		content.setId("content pane for genes");
 
-		// generate the GUIGenes
 		/* 
 		 * inputs
 		 */
 		guiInputs = new GUIInput[GUI.resources.inputs()];
 		for (int i = 0; i < guiInputs.length; i++) {
-			// get the backend input
-			Input input = chromosome.getInput(i);
-			// make the GUI elements
-			guiInputs[i] = new GUIInput(input);
-			// assign the GUI object to the associated backend element
-			input.setGUIObject(guiInputs[i]);
-			// position, handlers
-			Position.place(guiInputs[i]);
-			InputHandlers.addHandlers(guiInputs[i]);
+			guiInputs[i] = new GUIInput(chromosome.getInput(i));
 		}
+		// add inputs to content pane
 		content.getChildren().addAll(guiInputs);
 
 		/*
 		 * nodes
 		 */
 		guiNodes = new GUINode[rows][columns];
-		//double angle, xPos, yPos;
-
 		for (int c = 0; c < columns; c++) {
 			for (int r = 0; r < rows; r++) {
-				// get the backend node
-				Node node = chromosome.getNode(r, c);
 				// make the connection lines
 				Line lines[] = new Line[GUI.resources.arity()];
 				for (int l = 0; l < lines.length; l++) {
 					lines[l] = new Line();
-
-					Position.connect(lines[l], (GUIGene) ((Gene) node.getConnection(l)).getGUIObject());
-
 					lines[l].setMouseTransparent(true);
 					lines[l].setVisible(false);
 					connectionLines.add(lines[l]);
 				}
-				// make the GUI elements
-				guiNodes[r][c] = new GUINode(node, lines);
-				// assign the GUI object to the associated backend element
-				node.setGUIObject(guiNodes[r][c]);
-				// position, handlers
-				Position.place(guiNodes[r][c]);
-				NodeHandlers.addHandlers(guiNodes[r][c]);
+				// make the GUI element
+				guiNodes[r][c] = new GUINode(chromosome.getNode(r, c), lines);
+				// add node to content pane
 				content.getChildren().add(guiNodes[r][c]);
 			}
 		}
@@ -103,45 +75,24 @@ public class ChromosomePane extends ScrollPane {
 		 */
 		guiOutputs = new GUIOutput[GUI.resources.outputs()];
 		for (int i = 0; i < guiOutputs.length; i++) {
-			// get the backend output
-			Output output = chromosome.getOutput(i);
-			// make the GUI elements
+			// make the connection line
 			Line line = new Line();
-			Position.connect(line, (GUIGene) ((Gene) output.getSource()).getGUIObject());
 			line.setVisible(false);
 			line.setMouseTransparent(true);
-			guiOutputs[i] = new GUIOutput(output, line);
-			// assign the GUI object to the associated backend element
-			output.setGUIObject(guiOutputs[i]);
-			// position, handlers
-			Position.place(guiOutputs[i]);
-			OutputHandlers.addHandlers(guiOutputs[i]);
 			connectionLines.add(line);
+			// make the GUI element
+			guiOutputs[i] = new GUIOutput(chromosome.getOutput(i), line);
 		}
+		// add outputs to content pane
 		content.getChildren().addAll(guiOutputs);
 
 		// add lines to the pane on top of genes
 		content.getChildren().addAll(connectionLines);
 
-		setPrefWidth(620);	
+		setPrefWidth(620);
 		setContent(content);
 	}
 
-
-	/*
-	 * does this work lol
-	 */
-	//	protected GUIGene getGuiGene(Connection gene) {
-	//		if (gene instanceof Input) {
-	//			return guiInputs[((Input) gene).getIndex()];
-	//		} else if (gene instanceof Node) {
-	//			return guiNodes[((Node) gene).getRow()][((Node) gene).getColumn()];
-	//		} else {
-	//			// something bad happened!
-	//			throw new ClassCastException();
-	//		}	
-	//	}
-
 	protected boolean isTarget() {
 		return target;
 	}
@@ -151,8 +102,8 @@ public class ChromosomePane extends ScrollPane {
 	}
 
 	public void updateGenes(Chromosome chr) {
-		for (int r = 0; r < rows; r++) {
-			for (int c = 0; c < columns; c++) {
+		for (int r = 0; r < GUI.resources.rows(); r++) {
+			for (int c = 0; c < GUI.resources.columns(); c++) {
 				guiNodes[r][c].setNode(chr.getNode(r, c));
 			}
 		}
@@ -186,15 +137,4 @@ public class ChromosomePane extends ScrollPane {
 		// if the source was neither node nor output, something bad is happening
 		throw new ClassCastException("Source was neither GUINode nor GUIOutput.");
 	}
-
-	//	private GUIConnection getGUIConnection(Connection connection) {
-	//		if (connection instanceof Input) {
-	//			return guiInputs[((Input) connection).getIndex()];
-	//		} else if (connection instanceof Node) {
-	//			return guiNodes[((Node) connection).getRow()][((Node) connection).getColumn()];
-	//		} else {
-	//			// something bad happened!
-	//			throw new ClassCastException();
-	//		}
-	//	}
 }
diff --git a/src/jcgp/gui/population/GUIConnection.java b/src/jcgp/gui/population/GUIConnection.java
index 5fc857b..c17033a 100644
--- a/src/jcgp/gui/population/GUIConnection.java
+++ b/src/jcgp/gui/population/GUIConnection.java
@@ -2,8 +2,23 @@ package jcgp.gui.population;
 
 import jcgp.gui.population.GUIGene.GUIGeneState;
 
+/**
+ * A loose equivalent to {@link jcgp.backend.population.Connection}.
+ * <br>
+ * This defines behaviour that all GUI representations of connections
+ * should be capable of.
+ * 
+ * @author Eduardo Pedroni
+ *
+ */
 public interface GUIConnection {
 
+	/**
+	 * Set the connection's state, but also recursively propagate that state
+	 * all the way back to the inputs.
+	 * 
+	 * @param state the state to set.
+	 */
 	public void setStateRecursively(GUIGeneState state);
 	
 }
diff --git a/src/jcgp/gui/population/GUIGene.java b/src/jcgp/gui/population/GUIGene.java
index 032d217..d6f9638 100644
--- a/src/jcgp/gui/population/GUIGene.java
+++ b/src/jcgp/gui/population/GUIGene.java
@@ -21,33 +21,55 @@ import jcgp.gui.constants.Constants;
  */
 public abstract class GUIGene extends Group {
 
+	/**
+	 * This {@code enum} type defines a finite list of all states
+	 * a gene can take. Each state represents a particular steady
+	 * situation, and has its own GUI appearance associated with it:
+	 * a combination of connection line visibility, gene background colour
+	 * and other visual characteristics.
+	 * 
+	 * @author Eduardo Pedroni
+	 *
+	 */
 	public enum GUIGeneState {
+		/**
+		 * No user interaction at all.
+		 */
 		NEUTRAL,
+		/**
+		 * User is simply hovering over the node.
+		 */
 		HOVER,
+		/**
+		 * User is hovering over a node connected to this one.
+		 */
 		EXTENDED_HOVER,
+		/**
+		 * User is hovering over an output connected to this gene.
+		 */
 		ACTIVE_HOVER
 	}
 
 	private GUIGeneState currentState = GUIGeneState.NEUTRAL;
 
-	private Text text = new Text();
-	private Circle mainCircle = new Circle(Constants.NODE_RADIUS, Paint.valueOf(Constants.NEUTRAL_COLOUR));
+	private Text text;
+	private Circle mainCircle;
 
 	/**
 	 * Initialises the {@code Text} and {@code Circle} objects so that all genes are standardised.
 	 */
 	protected GUIGene() {
+		text = new Text();
 		text.setFont(Font.font("Arial", 12));
 		text.setTextOrigin(VPos.CENTER);
 		text.setTextAlignment(TextAlignment.CENTER);
 		text.setWrappingWidth(Constants.NODE_RADIUS * 2);
 		text.setX(-Constants.NODE_RADIUS);
-		text.setVisible(true);
 
+		mainCircle = new Circle(Constants.NODE_RADIUS, Constants.NEUTRAL_COLOUR);
 		mainCircle.setStroke(Paint.valueOf("black"));
 		
 		getChildren().addAll(mainCircle, text);
-		
 	}
 
 	/**
@@ -59,26 +81,43 @@ public abstract class GUIGene extends Group {
 		text.setText(newText);
 	}
 
+	/**
+	 * @return the gene's current state.
+	 */
 	public GUIGeneState getState() {
 		return currentState;
 	}
 
-	public void setState(GUIGeneState newState) {
+	/**
+	 * Gene states are standardised: all gene subclasses behave the same way in each state.
+	 * <br>
+	 * This design choice was made for the sake of consistency. Rather than controlling the 
+	 * appearance of the genes with logic in the state transition method AND the mouse handlers, 
+	 * the states are now consistent across all types of gene. The mouse handlers implement
+	 * whatever logic is necessary to determine the gene's new state given a certain user input,
+	 * but the states themselves are the same for all genes.
+	 * <br>
+	 * The transition logic for each type of gene is defined in its respective handler class:
+	 * {@code InputHandlers}, {@code NodeHandlers} and {@code OutputHandlers}.   
+	 * 
+	 * @param newState the gene's new state.
+	 */
+	public final void setState(GUIGeneState newState) {
 		switch (newState) {
 		case NEUTRAL:
-			mainCircle.setFill(Paint.valueOf(Constants.NEUTRAL_COLOUR));
+			mainCircle.setFill(Constants.NEUTRAL_COLOUR);
 			setLinesVisible(false);
 			break;
 		case HOVER:
-			mainCircle.setFill(Paint.valueOf(Constants.MEDIUM_HIGHLIGHT_COLOUR));
+			mainCircle.setFill(Constants.MEDIUM_HIGHLIGHT_COLOUR);
 			setLinesVisible(true);
 			break;
 		case EXTENDED_HOVER:
-			mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR));
+			mainCircle.setFill(Constants.SOFT_HIGHLIGHT_COLOUR);
 			setLinesVisible(false);
 			break;
 		case ACTIVE_HOVER:
-			mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR));
+			mainCircle.setFill(Constants.SOFT_HIGHLIGHT_COLOUR);
 			setLinesVisible(true);
 			break;
 			
@@ -88,5 +127,11 @@ public abstract class GUIGene extends Group {
 		currentState = newState;
 	}
 	
+	/**
+	 * For the sake of practicality, all {@code GUIGene} instances must implement this
+	 * method. It sets the visibility of all of the gene's lines, if it has any.
+	 * 
+	 * @param value the visibility value.
+	 */
 	protected abstract void setLinesVisible(boolean value);
 }
diff --git a/src/jcgp/gui/population/GUIInput.java b/src/jcgp/gui/population/GUIInput.java
index 68952f6..9b5f567 100644
--- a/src/jcgp/gui/population/GUIInput.java
+++ b/src/jcgp/gui/population/GUIInput.java
@@ -4,43 +4,68 @@ import javafx.scene.paint.Paint;
 import javafx.scene.shape.Circle;
 import jcgp.backend.population.Input;
 import jcgp.gui.constants.Constants;
+import jcgp.gui.constants.Position;
+import jcgp.gui.handlers.InputHandlers;
 
 /**
- * 
+ * The GUI counterpart of {@link jcgp.backend.population.Input}. This is a 
+ * subclass of {@code GUIGene} which represents a chromosome input.
  * 
  * @author Eduardo Pedroni
- *
  */
 public class GUIInput extends GUIGene implements GUIConnection {
 
 	private Input input;
 	
 	/**
-	 * @param input
+	 * Instantiate {@code GUIInput} given an {@code Input}.
+	 * 
+	 * @param input the associated backend input.
 	 */
 	public GUIInput(final Input input) {
 		super();
-		
+		// store the input, associate itself with it
 		this.input = input;
+		input.setGUIObject(this);
 		
+		// inputs only have a single output socket
 		Circle outputSocket = new Circle(Constants.NODE_RADIUS, 0, Constants.SOCKET_RADIUS, Paint.valueOf("white"));
-		outputSocket.setId(String.valueOf(0));
 		outputSocket.setStroke(Paint.valueOf("black"));
-
-		getChildren().addAll(outputSocket);
+		outputSocket.setId(String.valueOf(0));
+		getChildren().add(outputSocket);
+		
+		// relocate to the right position, add mouse handlers
+		Position.place(this);
+		InputHandlers.addHandlers(this);
 	}
 
+	/**
+	 * @return the {@code Input} instance associated with this object.
+	 */
 	public Input getInput() {
 		return input;
 	}
+	
+	/**
+	 * Associates this instance with a new input.
+	 * 
+	 * @param input the new input.
+	 */
+	void setInput(Input input) {
+		this.input = input;
+	}
 
+	/* (non-Javadoc)
+	 * @see jcgp.gui.population.GUIConnection#setStateRecursively(jcgp.gui.population.GUIGene.GUIGeneState)
+	 */
 	@Override
 	public void setStateRecursively(GUIGeneState state) {
 		setState(state);
 	}
 
+	/* (non-Javadoc)
+	 * @see jcgp.gui.population.GUIGene#setLinesVisible(boolean)
+	 */
 	@Override
-	protected void setLinesVisible(boolean value) {
-		// blank
-	}	
+	protected void setLinesVisible(boolean value) {}
 }
diff --git a/src/jcgp/gui/population/GUIMutable.java b/src/jcgp/gui/population/GUIMutable.java
index e51b54e..61a8f48 100644
--- a/src/jcgp/gui/population/GUIMutable.java
+++ b/src/jcgp/gui/population/GUIMutable.java
@@ -1,6 +1,16 @@
 package jcgp.gui.population;
 
+/**
+ * A loose equivalent to {@link jcgp.backend.population.Mutable}.
+ * <br>
+ * This defines behaviour that all GUI representations of mutables
+ * should be capable of.
+ * 
+ * @author Eduardo Pedroni
+ *
+ */
 public interface GUIMutable {
 
 	
+	
 }
diff --git a/src/jcgp/gui/population/GUINode.java b/src/jcgp/gui/population/GUINode.java
index f8f2e20..230d167 100644
--- a/src/jcgp/gui/population/GUINode.java
+++ b/src/jcgp/gui/population/GUINode.java
@@ -1,6 +1,5 @@
 package jcgp.gui.population;
 
-import javafx.scene.control.Label;
 import javafx.scene.paint.Paint;
 import javafx.scene.shape.Circle;
 import javafx.scene.shape.Line;
@@ -8,63 +7,109 @@ import jcgp.backend.population.Gene;
 import jcgp.backend.population.Node;
 import jcgp.gui.GUI;
 import jcgp.gui.constants.Constants;
+import jcgp.gui.constants.Position;
+import jcgp.gui.handlers.NodeHandlers;
 
+/**
+ * The GUI counterpart of {@link jcgp.backend.population.Node}. This is a 
+ * subclass of {@code GUIGene} which represents a chromosome node.
+ * 
+ * @author Eduardo Pedroni
+ */
 public class GUINode extends GUIGene implements GUIMutable, GUIConnection {
 
 	private Node node;
 	private Line[] lines;
 	private Circle[] sockets;
 	
+	/**
+	 * Instantiate {@code GUINode} given a {@code Node} and the lines needed
+	 * to show its connections.
+	 * 
+	 * @param node the associated backend node.
+	 * @param lines the lines used to display connections.
+	 */
 	public GUINode(Node node, Line[] lines) {
 		super();
-		// store references
+		// store references, associate with node
 		this.node = node;
 		this.lines = lines;
-		
-		Label connectionNumber = new Label();
-		connectionNumber.setStyle("-fx-background-color:rgb(255, 255, 255); -fx-border-color:rgba(0, 0, 0, 0.5);");
-		connectionNumber.setVisible(false);
+		node.setGUIObject(this);
 
-		Circle output = new Circle(Constants.NODE_RADIUS, 0, Constants.SOCKET_RADIUS, Paint.valueOf("white"));
+		// create the output socket
+		Circle output = new Circle(Constants.NODE_RADIUS, 0, Constants.SOCKET_RADIUS, Constants.SOCKET_COLOUR);
 		output.setStroke(Paint.valueOf("black"));
 		
+		// create input sockets
 		sockets = new Circle[GUI.resources.arity()];
-		double angle, xPos, yPos;
 		for (int l = 0; l < sockets.length; l++) {
-			angle = (((l + 1) / ((double) (GUI.resources.arity() + 1))) * Constants.THETA) - (Constants.THETA / 2);
-			xPos = -Math.cos(angle) * Constants.NODE_RADIUS;
-			yPos = Math.sin(angle) * Constants.NODE_RADIUS;
-
-			sockets[l] = new Circle(xPos, yPos, Constants.SOCKET_RADIUS, Paint.valueOf("white"));
-			sockets[l].setId(String.valueOf(l));
+			sockets[l] = new Circle(Constants.SOCKET_RADIUS, Constants.SOCKET_COLOUR);
 			sockets[l].setStroke(Paint.valueOf("black"));
+			sockets[l].setId(String.valueOf(l));
+			// relocate them
+			Position.placeSocket(l, sockets[l]);
+			Position.connect(lines[l], (GUIGene) ((Gene) node.getConnection(l)).getGUIObject());
 		}
 		
+		// add elements
 		getChildren().addAll(sockets);
-		getChildren().addAll(output, connectionNumber);
+		getChildren().add(output);
+		
+		// relocate node, add handlers
+		Position.place(this);
+		NodeHandlers.addHandlers(this);
 	}
 	
+	/**
+	 * @return the {@code Node} instance associated with this object.
+	 */
 	public Node getNode() {
 		return node;
 	}
 
-	void setNode(Node node2) {
-		// TODO Auto-generated method stub
-		
+	/**
+	 * Associates this instance with a new node.
+	 * 
+	 * @param node the new node.
+	 */
+	void setNode(Node node) {
+		this.node = node;
 	}
 	
+	/**
+	 * Returns one of this object's connection lines. Lines are 
+	 * indexed in the same order as sockets and the connections
+	 * they represent.
+	 * 
+	 * @param index the line to return.
+	 * @return the indexed line object.
+	 */
 	public Line getLine(int index) {
 		return lines[index];
 	}
 	
+	/**
+	 * @return the entire {@code Line} array.
+	 */
 	public Line[] getLines() {
 		return lines;
 	}
 	
+	/**
+	 * Returns one of this object's connection sockets. They are 
+	 * indexed in the same order as lines and the connections
+	 * they represent.
+	 * 
+	 * @param index the socket to return.
+	 * @return the indexed socket object.
+	 */
 	public Circle getSocket(int index) {
 		return sockets[index];
 	}
 	
+	/**
+	 * @return the entire {@code Socket} array.
+	 */
 	public Circle[] getSockets() {
 		return sockets;
 	}
@@ -83,21 +128,4 @@ public class GUINode extends GUIGene implements GUIMutable, GUIConnection {
 			lines[i].setVisible(value);
 		}
 	}
-	
-//	@Override
-//	public void updateLines() {
-//		for (int l = 0; l < connectionLines.length; l++) {
-//			if (node.getConnection(l) instanceof Node) {
-//				int row = ((Node) node.getConnection(l)).getRow(), 
-//					column = ((Node) node.getConnection(l)).getColumn();
-//				connectionLines[l].setEndX((((column + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + 2 * Constants.NODE_RADIUS) + Constants.SOCKET_RADIUS);
-//				connectionLines[l].setEndY((row * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS);		
-//			} else if (node.getConnection(l) instanceof Input) {
-//				int inputIndex = ((Input) node.getConnection(l)).getIndex();
-//				connectionLines[l].setEndX(2 * Constants.NODE_RADIUS);
-//				connectionLines[l].setEndY(inputIndex * (2 * Constants.NODE_RADIUS + Constants.SPACING) + Constants.NODE_RADIUS);
-//			}
-//		}
-//	}
-	
 }
diff --git a/src/jcgp/gui/population/GUIOutput.java b/src/jcgp/gui/population/GUIOutput.java
index a07fd90..b281833 100644
--- a/src/jcgp/gui/population/GUIOutput.java
+++ b/src/jcgp/gui/population/GUIOutput.java
@@ -1,42 +1,71 @@
 package jcgp.gui.population;
 
-import javafx.scene.control.Label;
 import javafx.scene.paint.Paint;
 import javafx.scene.shape.Circle;
 import javafx.scene.shape.Line;
+import jcgp.backend.population.Gene;
 import jcgp.backend.population.Output;
 import jcgp.gui.constants.Constants;
+import jcgp.gui.constants.Position;
+import jcgp.gui.handlers.OutputHandlers;
 
+/**
+ * The GUI counterpart of {@link jcgp.backend.population.Output}. This is a 
+ * subclass of {@code GUIGene} which represents a chromosome output.
+ * 
+ * @author Eduardo Pedroni
+ */
 public class GUIOutput extends GUIGene implements GUIMutable {
 
 	private Output output;
 	private Line line;
 
+	/**
+	 * Instantiate {@code GUIOutput} given an {@code Output} and the line needed
+	 * to show its connection.
+	 * 
+	 * @param output the associated backend output.
+	 * @param line the line used to display connection.
+	 */
 	public GUIOutput(final Output output, Line line) {
 		super();
+		// store references, associate with backend object
 		this.output = output;
 		this.line = line;
-		
-		Circle socket = new Circle(-Constants.NODE_RADIUS, 0, Constants.SOCKET_RADIUS, Paint.valueOf("white"));
-		socket.setId(String.valueOf(0));
+		output.setGUIObject(this);
+
+		// create input socket
+		Circle socket = new Circle(-Constants.NODE_RADIUS, 0, Constants.SOCKET_RADIUS, Constants.SOCKET_COLOUR);
 		socket.setStroke(Paint.valueOf("black"));
+		socket.setId(String.valueOf(0));
+		Position.connect(line, (GUIGene) ((Gene) output.getSource()).getGUIObject());
+		getChildren().add(socket);
 
-		Label connectionLabel = new Label("S");
-		connectionLabel.setStyle("-fx-background-color:rgb(255, 255, 255); -fx-border-color:rgba(0, 0, 0, 0.5);");
-		connectionLabel.relocate(socket.getCenterX() + 5, socket.getCenterY() - 10);
-		connectionLabel.setVisible(false);
-		
-		getChildren().addAll(socket, connectionLabel);
+		// relocate output, add handlers
+		Position.place(this);
+		OutputHandlers.addHandlers(this);
 	}
 
-	void setOutput(Output output2) {
-		
+	/**
+	 * Associates this instance with a new output.
+	 * 
+	 * @param output the new output.
+	 */
+	void setOutput(Output output) {
+		this.output = output;
 	}
-	
+
+	/**
+	 * @return the {@code Output} instance associated with this object.
+	 */
 	public Output getOutput() {
 		return output;
 	}
+
 	
+	/**
+	 * @return this output's single connection line.
+	 */
 	public Line getLine() {
 		return line;
 	}
-- 
cgit v1.2.3