Index: trunk/code/projects/colonet/ColonetGUI/Colonet.java
===================================================================
--- trunk/code/projects/colonet/ColonetGUI/Colonet.java	(revision 426)
+++ trunk/code/projects/colonet/ColonetGUI/Colonet.java	(revision 427)
@@ -10,7 +10,7 @@
 import java.awt.event.*;
 import java.net.*;
 import java.io.*;
-import java.util.Random;
+import java.util.*;
 
 
 /**
@@ -22,7 +22,7 @@
 */
 public class Colonet extends JApplet implements ActionListener, MouseInputListener, KeyListener, Runnable {
 
-	// Used for the robot graph
+	// Used for images
 	final int CANVAS_SIZE = 500;  //the applet may be slow if the canvas gets too large
 	final int BUFFER = 50;
 	final int RADIUS = 30;
@@ -42,6 +42,9 @@
 	JTextArea txtInfo; 
 	JPanel panelConnect;
 	JPanel panelServerInterface;
+	Socket socket;					
+	OutputStreamWriter out;
+	DataUpdater dataUpdater;  
 	
 	// South
 	JPanel panelSouth;
@@ -62,6 +65,7 @@
 	JPanel panelBattery;
 	VectorController vectorController;
 	BufferedImage imageVectorControl;
+	JButton btnAssignID;
 	JButton btnCommand_StopTask;
 	JButton btnCommand_ResumeTask;
 	JButton btnCommand_ChargeNow;
@@ -81,7 +85,7 @@
 	JButton btnUpdateTasks;
 	TaskAddWindow taskAddWindow;
 	
-	//Webcam and Graph
+	//Webcam
 	WebcamPanel panelWebcam;
 	GraphicsPanel panelGraph;
 	GraphicsConfiguration gc;
@@ -90,16 +94,10 @@
 	int cx, cy;
 	JTabbedPane tabPaneMain;
 	
-	
-	Socket socket;					
-	OutputStreamWriter out;
-	DataUpdater dataUpdater;  
-	
 	Font botFont;
-	volatile int tokenLoc;  //the token is currently here
 	volatile int numBots;
-	volatile int selectedBot;  //the user has selected this bot
-	volatile Rectangle[] botRect;  //contains boundary shapes around bots for click detection
+	volatile int selectedBot;  //the user has selected this bot graphically
+	volatile java.util.List <RobotIcon> robotIcons;  //contains boundary shapes around bots for click detection
 	volatile int[] xbeeID;
 	
 	Thread drawThread;
@@ -109,7 +107,7 @@
 
 	
 	public void init () {
-		// set the default look and feel - choose one
+		// Set the default look and feel - choose one
         //String laf = UIManager.getSystemLookAndFeelClassName();
 		String laf = UIManager.getCrossPlatformLookAndFeelClassName();
 		//String laf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
@@ -160,10 +158,11 @@
 		cx = image.getWidth() / 2;
 		cy = image.getHeight() / 2;
 		
+		// Set up robots
 		botFont = new Font("Arial", Font.PLAIN, 14);
-		tokenLoc = 0;
 		numBots = 0;
 		selectedBot = 0;
+		robotIcons = new ArrayList <RobotIcon> ();
 		
 		// Connection area
 		txtMatrix = new JTextArea();
@@ -217,10 +216,9 @@
 		panelRobotCommands.setLayout(new GridLayout(5,2));
 		cmbRobotNum = new JComboBox();
 		// Battery subset
-		lblBattery = new JLabel();
 		batteryIcon = new BatteryIcon(25);
-		//batteryIcon = new BatteryIcon(50, lblBattery.getMaximumSize().height, lblBattery.getMaximumSize().height);
 		lblBattery = new JLabel(batteryIcon);
+		btnAssignID = new JButton("Assign ID");
 		btnCommand_StopTask = new JButton("Stop Current Task");
 		btnCommand_ResumeTask = new JButton("Resume Current Task");
 		btnCommand_ChargeNow = new JButton("Recharge Now");
@@ -229,10 +227,12 @@
 		panelRobotCommands.add(cmbRobotNum);
 		panelRobotCommands.add(new JLabel("Battery Level: "));
 		panelRobotCommands.add(lblBattery);
-		panelRobotCommands.add(btnCommand_StopTask);
-		panelRobotCommands.add(btnCommand_ResumeTask);
-		panelRobotCommands.add(btnCommand_ChargeNow);
-		panelRobotCommands.add(btnCommand_StopCharging);
+		panelRobotCommands.add(btnAssignID);
+		panelRobotCommands.add(new JLabel(""));  //make the items line up properly
+		//panelRobotCommands.add(btnCommand_StopTask);
+		//panelRobotCommands.add(btnCommand_ResumeTask);
+		//panelRobotCommands.add(btnCommand_ChargeNow);
+		//panelRobotCommands.add(btnCommand_StopCharging);
 		panelRobotControl = new JPanel();
 		panelRobotControl.setLayout(new GridLayout(2,1));
 		panelRobotControl.add(panelRobotDirection);
@@ -317,8 +317,6 @@
 		btnActivate.addActionListener(this);
 		btnActivate.addKeyListener(this);
 		cmbRobotNum.addKeyListener(this);
-		vectorController.addMouseMotionListener(this);
-		vectorController.addMouseListener(this);
 		btnCommand_StopTask.addActionListener(this);
 		btnCommand_ResumeTask.addActionListener(this);
 		btnCommand_ChargeNow.addActionListener(this);
@@ -326,8 +324,8 @@
 		// Other
 		btnConnect.addActionListener(this);
 		btnGetXBeeIDs.addActionListener(this);
-		panelGraph.addMouseListener(this);
-		this.addMouseMotionListener(this);	
+		btnAssignID.addActionListener(this);
+		panelWebcam.addMouseListener(this);	
 				
 		// Set up animation threads
 		indicator = new SelectionIndicator(canvas);
@@ -340,7 +338,6 @@
 			This paint method overrides the built-in paint of the 
 			JApplet, and we don't want to deal with redrawing the
 			components manually. Fuck that shit. */
-		step();
 		super.paint(g);
 	}
 	
@@ -348,65 +345,6 @@
 		paint(g);
 	}
 	
-	public void drawRobot (int id, int x, int y) {
-		//save the bot in memory, so we can tell if we click on it later
-		botRect[id] = new Rectangle(x-RADIUS, y-RADIUS, 2*RADIUS, 2*RADIUS);
-	
-		//draw the bot on the canvas
-		canvas.setColor(Color.BLACK);
-		canvas.drawOval(x-RADIUS, y-RADIUS, RADIUS*2, RADIUS*2);
-		
-		//draw the label
-		canvas.setFont(botFont);
-		try {
-			canvas.drawString("" + xbeeID[id], x-20, y+2);
-		} catch (Exception e) {
-			canvas.drawString("???", x-22, y+2);
-		}
-	}
-	
-	public void drawConnection (int start, int end, int radius, Color color) {
-		final int ARROW_LENGTH = 18;
-	
-		double angle = 2.0 * Math.PI / numBots;
-		int startx, starty, endx, endy;
-		startx = cx - (int)(radius * Math.cos(start * angle));
-		starty = cy - (int)(radius * Math.sin(start * angle));
-		endx = cx - (int)(radius * Math.cos(end * angle));
-		endy = cy - (int)(radius * Math.sin(end * angle));
-		canvas.setColor(color);
-		canvas.drawLine(startx, starty, endx, endy);
-		
-		//create arrow
-		if (color.equals(Color.BLACK)) return;
-		int big_dy = starty - endy;
-		int big_dx = endx - startx;
-		double theta = 0;
-		if (big_dx == 0 && starty > endy) //pointing up
-			theta = Math.PI/2;
-		else if (big_dx == 0 && starty < endy) //pointing down 
-			theta = 3*Math.PI/2;
-		else if (big_dy == 0 && startx > endx) //pointing left
-			theta = Math.PI;
-		else if (big_dy == 0 && startx < endx) //pointing right
-			theta = 0;
-		else
-			theta = Math.atan(1.0 * big_dy / big_dx);
-		
-		//create ploygon
-		Polygon poly = new Polygon();
-		int dx_arrow = Math.abs((int)(ARROW_LENGTH * Math.cos(theta)));
-		int dy_arrow = Math.abs((int)(ARROW_LENGTH * Math.sin(theta)));
-		int dy_half = (int)(ARROW_LENGTH/2 * Math.cos(theta));
-		int dx_half = (int)(ARROW_LENGTH/2 * Math.sin(theta));
-		int rx = (big_dx > 0) ? endx - dx_arrow : endx + dx_arrow;
-		int ry = (big_dy > 0) ? endy + dy_arrow : endy - dy_arrow;
-		poly.addPoint(endx, endy);
-		poly.addPoint(rx - dx_half, ry - dy_half);
-		poly.addPoint(rx + dx_half, ry + dy_half);
-		canvas.fillPolygon(poly);
-	}
-	
 	public void run () {
 		while (true) {
 			repaint();
@@ -417,74 +355,7 @@
 			}
 		}
 	}
-	
-	private void step () {
-		final int DIAMETER = image.getWidth() - 2*BUFFER;
-		final int BIGRADIUS = DIAMETER / 2;
-		final int TOKENRADIUS = 40;
-		boolean valid;
-	
-		// clear image
-		canvas.setColor(Color.WHITE);
-		canvas.fillRect(0, 0, image.getWidth(), image.getHeight());
 		
-		// parse the matrix, to see what robots exist
-		String [] rows = txtMatrix.getText().split("\n");
-		numBots = rows.length;
-		String [][] entries = new String[numBots][numBots];
-		valid = true;
-		for (int i = 0; i < numBots; i++) {
-			entries[i] = rows[i].split(" ");
-			if (entries[i].length != rows.length) valid = false;
-		}
-		
-		if (valid) {
-			this.showStatus("Running");
-			
-			// draw robots and find which one is seleced
-			double angle = 2.0 * Math.PI / numBots;
-			canvas.setColor(Color.BLACK);
-			botRect = new Rectangle[numBots];
-			int x, y;
-			if (selectedBot >= numBots) selectedBot = 0;
-			for (int i = 0; i < numBots; i++) {
-				x = cx - (int)(BIGRADIUS * Math.cos(i * angle));
-				y = cy - (int)(BIGRADIUS * Math.sin(i * angle));
-				drawRobot(i, x, y);
-				if (i == selectedBot) indicator.setCenter(x, y);
-			}
-			
-			// draw token marker
-			int tokenx, tokeny;
-			int tokenNum = tokenLoc;
-			tokenx = cx - (int)(BIGRADIUS * Math.cos(tokenNum * angle));
-			tokeny = cy - (int)(BIGRADIUS * Math.sin(tokenNum * angle));
-			canvas.setColor(Color.RED);
-			canvas.drawOval(tokenx-TOKENRADIUS, tokeny-TOKENRADIUS, 2*TOKENRADIUS, 2*TOKENRADIUS);
-			
-			// create an inner circle along which the connections are made.
-			// let the diameter of this circle be 2*RADIUS less than the outerDiameter.
-			// see what connections exist
-			for (int row = 0; row < numBots; row++) {
-				for(int col = 0; col < numBots; col++) {
-					if (!entries[row][col].equals("-") && entries[col][row].equals("-") && row != col) {
-						//TODO: Make a standard gray
-						drawConnection(row, col, BIGRADIUS-RADIUS, new Color(200,200,200));
-					} else if (!entries[row][col].equals("-") && ! entries[col][row].equals("-") && row != col) {
-						drawConnection(row, col, BIGRADIUS-RADIUS, Color.BLACK);
-					}
-				}
-			}
-			
-			// draw the selection indicator
-			indicator.draw();
-			
-		} else {  // if matrix is not valid
-			this.showStatus("Error: Invalid matrix");
-		}
-	
-	}
-	
 	/** 
 	* Gets the JTextArea used for storing the activity log. This method returns a reference to the 
 	* JTextArea that stores the log. The log can contain any activity that is revelant to the use
@@ -647,24 +518,13 @@
 	public void mouseEntered(MouseEvent e) {
 	}
 	public void mouseReleased(MouseEvent e) {
-		vectorController.notifyMouseEvent(e, true);
 	}
 	public void mouseClicked(MouseEvent e) {
-		vectorController.notifyMouseEvent(e, false);
 	}
 	public void mousePressed(MouseEvent e) {
-		try {
-			for (int i = 0; i < numBots; i++) {
-				if (botRect[i].contains(e.getPoint())) {
-					selectedBot = i;
-					cmbRobotNum.setSelectedIndex(i+1);
-				}
-			}
-		} catch (Exception ex) {
-		}
+		System.out.println(e);
 	}
 	public void mouseDragged(MouseEvent e) {
-		vectorController.notifyMouseEvent(e, false);
 	}
 	public void mouseMoved(MouseEvent e) {
 	}
@@ -703,11 +563,14 @@
 	public void actionPerformed (ActionEvent e) {
 		Object source = e.getSource();
 		
-		//Connection
+		// General Actions
 		if (source == btnConnect) {
 			connect();
 		} else if (source == btnGetXBeeIDs) {
 			csi.sendXBeeIDRequest();
+		} else if (source == btnAssignID) {
+		    String message;
+			
 		}
 		
 		// Robot Movement Controls
@@ -983,7 +846,6 @@
 		int BORDER = 16;  // this is arbitrary. it makes the image look nice inside a border.
 		int BOT_RADIUS = 40;
 		volatile BufferedImage img;
-		volatile Point [] points;
 	
 		public WebcamPanel () {
 			super();
@@ -995,12 +857,37 @@
 				img = null;
 				img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
 			}
-			System.gc();
 			img = newimg;
 		}
 		
 		public synchronized void setPoints (Point [] newpoints) {
-			this.points = newpoints;
+			// test code -- need to remove later
+			if (newpoints == null) {
+				Point [] p = new Point [3];
+				p[0] = new Point(100,150);
+				p[1] = new Point(200,200);
+				p[2] = new Point(400,300);
+				setPoints(p);
+				return;
+			}
+			
+			for (int i = 0; i < newpoints.length; i++) {
+				Point p = newpoints[i];
+				boolean found = false;
+				for (int j = 0; j < robotIcons.size(); j++) {
+					RobotIcon r = robotIcons.get(i);
+					if (r.isClose(p.x, p.y)) {
+						r.move(p.x, p.y);
+						found = true;
+					}
+				}
+				if (!found) {
+					RobotIcon r = new RobotIcon(p.x, p.y);
+					robotIcons.add(r);
+					System.out.println("Added " + r);
+				}
+			}
+			
 		}
 		
 		public synchronized void paint (Graphics g) {
@@ -1021,12 +908,14 @@
 						);
 						
 			// Draw Identifiers
-			if (points == null)
+			if (robotIcons == null)
 				return;
-			g.setColor(Color.RED);
 			((Graphics2D)g).setStroke(new BasicStroke(2));
-			for (int i = 0; i < points.length; i++) {
-				g.drawOval(points[i].x - BOT_RADIUS, points[i].y - BOT_RADIUS, 2*BOT_RADIUS, 2*BOT_RADIUS);
+			for (int i = 0; i < robotIcons.size(); i++) {
+				RobotIcon r = robotIcons.get(i);
+				g.setColor(r.color);
+				g.drawOval(r.x, r.y, 2*r.RADIUS, 2*r.RADIUS);
+				System.out.println("Painted: " + r);
 			}
 			
 		}
@@ -1074,7 +963,6 @@
 					Thread.sleep(WEBCAMLOADER_DELAY);
 					if (image != null) 
 						image.flush();
-					System.gc();
 					image = ImageIO.read(imagePath);
 					// The MediaTracker waitForID pauses the thread until the image is loaded.
 					// We don't want to display a half-downloaded image.
@@ -1083,7 +971,8 @@
 					mt.removeImage(image);
 					// Save
 					panelWebcam.setImage(image);
-					parseLocations(locationsPath.toURL());
+					//parseLocations(locationsPath.toURL());
+					panelWebcam.setPoints(null);  //temporary simulation code
 				} catch (InterruptedException e) {
 					return;
 				} catch (java.security.AccessControlException e) {
@@ -1132,6 +1021,42 @@
 			
 		}
 	}
+	
+	/*
+	*  RobotIcon class
+	*  Provides a means for graphically representing and keeping track of webcam bots.
+	*/
+	class RobotIcon {
+		public final int RADIUS = 30;
+		public final int CLOSE = 40;
+		
+		public int x, y;
+		public int id;
+		public Color color;
+		
+		public RobotIcon (int x, int y) {
+			this.id = -1;
+			this.color = Color.RED;
+			this.x = x;
+			this.y = y;
+		}
+		
+		public void move (int newX, int newY) {
+			this.x = newX;
+			this.y = newY;
+		}
+		
+		public boolean isClose (int nx, int ny) {
+			int dist = (int) Point.distance(this.x, this.y, nx, ny);
+			return (dist < CLOSE);
+		}
+		
+		public String toString () {
+			String s = "RobotIcon at (" + x + "," + y + "), id " + id;
+			return s;
+		}
+		
+	}
 
 	
 	/*
@@ -1138,7 +1063,7 @@
 	*	VectorController class
 	*	Manages robot motion control graphically
 	*/
-	class VectorController extends GraphicsPanel {
+	class VectorController extends GraphicsPanel implements MouseListener, MouseMotionListener {
 		int x, y, cx, cy;
 		int width, height;
 		int side;
@@ -1155,6 +1080,8 @@
 				side = width;
 			else
 				side = height;
+			this.addMouseListener(this);
+			this.addMouseMotionListener(this);
 		}
 		
 		public void setPoint (int x, int y) {
@@ -1180,6 +1107,24 @@
 				vectorController.sendToServer();
 		}
 		
+		public void mouseExited(MouseEvent e) {
+		}
+		public void mouseEntered(MouseEvent e) {
+		}
+		public void mouseReleased(MouseEvent e) {
+			this.notifyMouseEvent(e, true);
+		}
+		public void mouseClicked(MouseEvent e) {
+			this.notifyMouseEvent(e, false);
+		}
+		public void mousePressed(MouseEvent e) {
+		}
+		public void mouseDragged(MouseEvent e) {
+			vectorController.notifyMouseEvent(e, false);
+		}
+		public void mouseMoved(MouseEvent e) {
+		}
+		
 		public int getSpeed () {
 			int dx = x - cx;
 			int dy = y - cy;
@@ -1293,7 +1238,6 @@
 		JScrollPane spAvailableTasks;
 		JTextArea txtDescription;
 		JTextField txtParameters;
-		MouseListener mouseListener;
 		
 		public TaskAddWindow () {
 			super("Add a Task");
@@ -1393,6 +1337,10 @@
 	
 	}
 	
+	/*
+	*  BatteryIcon class
+	*  Graphical representation of battery level
+	*/
 	class BatteryIcon implements Icon {
 		private int width;
 	    private int height;
@@ -1483,4 +1431,5 @@
 	}
 
 
+
 }
