Index: /trunk/src/org/expeditee/gui/Help.java
===================================================================
--- /trunk/src/org/expeditee/gui/Help.java	(revision 682)
+++ /trunk/src/org/expeditee/gui/Help.java	(revision 683)
@@ -11,170 +11,151 @@
 	
 	// contexts
-	public static final int background = 0, item = 1;
+	private static final int background = 0, item = 1, line = 2, text = 3;
 	
 	// mouse buttons
-	public static final int left = 1, middle = 2, right = 4;
+	private static final int left = 1, middle = 2, right = 4;
 	private static final String[] buttons = { "", "L", "M", "LM", "R", "LR", "MR" };
 	
 	// modifiers
-	public static final int none = 0, control = 1, shift = 2, drag = 4;
-	private static final String[] modifiers = { "", "^", "+", "^+", "d", "d^", "d+", "d^+" };
+	private static final int control = 1, shift = 2;
+	private static final String[] modifiers = { "", "^", "+", "^+" };
 	
 	// other
-	public static final int panning = 1, action = 2, line = 4, cursor = 8;
+	private static final int panning = 1, action = 2, cursor = 4;
 	
 	// separator between command and description
-	private static final String separator = ": ";
-	
-	/**
-	 * Set each index of $array to reference $value
-	 */
-	private static final void fill(String[] array, String value) {
-		for(int i = 0; i < array.length; i++) {
-			array[i] = value;
-		}
-	}
-	
-	/**
-	 * Set each index of $array to reference an array filled with $value
-	 */
-	private static final void fill(String[][] array, String value) {
-		array[0] = new String[array[0].length];
-		fill(array[0], value);
-   		for(int i = 1; i < array.length; i++) {
-   			array[i] = array[0];
-   		}
-	}
-	
-	/**
-	 * Set the indices of $array that have $indexBit set (or not set if $invert) to reference $value
-	 */
-	private static final void fill(String[] array, int indexBit, String value, boolean invert, boolean lazy) {
-		for(int i = 0; i < array.length; i++) {
-			if((!lazy && ((i & indexBit) == indexBit && !invert) || ((i & indexBit) == 0 && invert)) ||
-				(lazy && ((i & indexBit) != 0 && !invert)        || ((i & indexBit) != indexBit && invert))){
-				array[i] = value;
-			}
-		}
-	}
-	
-	/**
-	 * Calls fill(array, indexBit, value, false, false)
-	 */
-	private static final void fill(String[] array, int indexBit, String value) {
-		fill(array, indexBit, value, false, false);
-	}
-	
-	/**
-	 * Set the indices of $array that have $indexBit set (or not set if $invert) to reference an array filled with $value
-	 */
-	private static final void fill(String[][] array, int indexBit, String value, boolean invert, boolean lazy) {
-		for(int i = 0; i < array.length; i++) {
-			if((!lazy && ((i & indexBit) == indexBit && !invert) || ((i & indexBit) == 0 && invert)) ||
-				(lazy && ((i & indexBit) != 0 && !invert)        || ((i & indexBit) != indexBit && invert))){
-				fill(array[i] = Arrays.copyOf(array[i], array[i].length), value);
-			}
-		}
-	}
-	
-	/**
-	 * Calls fill(array, indexBit, value, false, false)
-	 */
-	private static final void fill(String[][] array, int indexBit, String value) {
-		fill(array, indexBit, value, false, false);
-	}
-	
-	/**
-	 * For each array at the indices of $array that have $indexBit set (or not set if $invert),
-	 * set each index that has $indexBit2 set (or not set if $invert) to reference $value
-	 */
-	private static final void fill(String[][] array, int indexBit, int indexBit2, String value, boolean invert, boolean invert2, boolean lazy, boolean lazy2) {
-		for(int i = 0; i < array.length; i++) {
-			if((!lazy && ((i & indexBit) == indexBit && !invert) || ((i & indexBit) == 0 && invert)) ||
-				(lazy && ((i & indexBit) != 0 && !invert)        || ((i & indexBit) != indexBit && invert))) {
-				fill(array[i] = Arrays.copyOf(array[i], array[i].length), indexBit2, value, invert2, lazy2);
-			}
-		}
-	}
-	
-	/**
-	 * Calls fill(array, indexBit, indexBit2, value, false, false, false, false)
-	 */
-	private static final void fill(String[][] array, int indexBit, int indexBit2, String value) {
-		fill(array, indexBit, indexBit2, value, false, false, false, false);
-	}
-	
-	// help text
-	private static final String[/* contexts */][/* buttons */][/* modifiers */][/* other */] statusText = new String[2][8][8][16];
-	static {
-		fill(statusText[background][left], "Go back");
-		fill(statusText[background][left], control | shift, "Go forward", false, true);
-		fill(statusText[background][left], drag, null); // no action for dragging unless shift down
-		fill(statusText[background][left], shift | drag, panning, "Drag to pan");
-		fill(statusText[background][left], drag, cursor, null);
-		
-		fill(statusText[background][middle], "Create arrow");
-		fill(statusText[background][middle], 0, cursor, "Place item(s)", true, false, true, false);
-		fill(statusText[background][middle], drag, null); // no action for dragging
-		
-		fill(statusText[background][right], "Create rectangle");
-		fill(statusText[background][right], 0, cursor, "Stamp item(s)", true, false, true, false);
-		fill(statusText[background][right], drag, null); // no action for dragging
-		
-		fill(statusText[background][left | middle], null); // no action for left + middle
-		
-		fill(statusText[background][left | right], "Auto format");
-		
-		fill(statusText[background][middle | right], "Undo");
-		fill(statusText[background][middle | right], 0, cursor, "Delete", true, false, true, false);
-    	
-		
-    	fill(statusText[item][left], "Follow link");
-    	fill(statusText[item][left], control, action, "Run action", true, false, false, false);
-    	fill(statusText[item][left], drag, null); // no action for dragging
-    	
-    	fill(statusText[item][middle], "Pickup");
-    	fill(statusText[item][middle], shift, "Create arrow");
-    	fill(statusText[item][middle], 0, cursor, "Place item(s)", true, false, true, false);
-    	fill(statusText[item][middle], drag, null); // no action for dragging
-    	
-    	fill(statusText[item][right], "Copy");
-    	fill(statusText[item][right], shift, "Create rectangle");
-    	fill(statusText[item][right], 0, cursor, "Stamp item(s)", true, false, true, false);
-    	fill(statusText[item][right], drag, null); // no action for dragging unless currentItem is a line
-    	fill(statusText[item][right], drag, line, "Extrude shape");
-    	
-    	fill(statusText[item][left | middle], null); // no action for left + middle
-    	
-		fill(statusText[item][left | right], "Extract attributes");
-		fill(statusText[item][left | right], 0, cursor, null, true, false, true, false);
-		
-		fill(statusText[item][middle | right], "Delete");
-	}
+	private static final String separatorString = ": ";
+	// flag for dragging
+	private static final String dragString = "d";
 	
 	private static final String commandPadding = "     ";
 	private static final String padding = "                  ";
 	
+	private static final String command(int mod, int button, boolean drag) {
+		String cmd = (drag ? dragString : "") + modifiers[mod] + buttons[button];
+		return commandPadding.substring(cmd.length()) + cmd + separatorString;
+	}
+	
 	private static final String command(int mod, int button) {
-		String cmd = modifiers[mod] + buttons[button];
-		return commandPadding.substring(cmd.length()) + cmd + separator;
+		return command(mod, button, false);
 	}
+	
+	private static final String left(int context, int mod, int other) {
+		switch(context) {
+		case background:
+    		if((mod & (control | shift)) != 0) return "Go forward";
+    		return "Go back";
+		case line:
+		case item:
+			if((other & action) != 0 && (mod & control) == 0) return "Run action";
+			return "Follow link";
+		}
+		return null;
+	}
+	
+	private static final String middle(int context, int mod, int other) {
+		switch(context) {
+		case background:
+    		if((other & cursor) != 0) return "Place item(s)";
+    		return "Create arrow";
+		case line:
+			if((mod & shift) != 0) return "Extend shape";
+		case item:
+			if((other & cursor) != 0) return "Place item(s)";
+    		if((mod & shift) != 0) return "Create arrow";
+			return "Pickup";
+		}
+		return null;
+	}
+	
+	private static final String right(int context, int mod, int other) {
+		switch(context) {
+		case background:
+			if((other & cursor) != 0) return "Stamp item(s)";
+			return "Create rectangle";
+		case line:
+			if((mod & shift) != 0) return "Add line";
+		case item:
+			if((other & cursor) != 0) return "Stamp item(s)";
+			if((mod & shift) != 0) return "Create rectangle";
+			return "Copy";
+		}
+		return null;
+	}
+	
+	private static final String left_middle(int context, int mod, int other) {
+		return null;
+	}
+	
+	private static final String left_right(int context, int mod, int other) {
+		switch(context) {
+		case line:
+		case item:
+			if((other & cursor) == 0) return "Extract attributes";
+		case background:
+			return "Auto format";
+		}
+		return null;
+	}
+	
+	private static final String middle_right(int context, int mod, int other) {
+		switch(context) {
+		case background:
+			if((other & cursor) == 0) return "Undo";
+		case line:
+		case item:
+			return "Delete";
+		}
+		return null;
+	}
+	
+	private static final String drag_left(int context, int mod, int other) {
+		switch(context) {
+		case background:
+    		if((mod & shift) != 0 && (other & cursor) == 0) return "Drag to pan";
+		}
+		return null;
+	}
+	
+	private static final String drag_middle(int context, int mod, int other) {
+		return null;
+	}
+	
+	private static final String drag_right(int context, int mod, int other) {
+		switch(context) {
+		case line:
+			return "Extrude shape";
+		}
+		return null;
+	}
+	
 	
 	public static void updateStatus() {
 		Item current = FrameUtils.getCurrentItem();
-		int context = current != null || FrameUtils.getCurrentItems() != null ? item : background;
+		int context;
+		if(current != null) {
+			if(current instanceof Line) {
+				context = line;
+			} else {
+				context = item;
+			}
+		} else if(FrameUtils.getCurrentItems() != null) {
+			context = item;
+		} else {
+			context = background;
+		}
 		int mod = (FrameMouseActions.isControlDown() ? control : 0) | (FrameMouseActions.isShiftDown() ? shift : 0);
-		int other = (ExperimentalFeatures.MousePan.get() ? panning : 0) | (current != null && current.hasAction() ? action : 0) | (current instanceof Line ? line : 0) | (FreeItems.itemsAttachedToCursor() ? cursor : 0);
+		int other = (ExperimentalFeatures.MousePan.get() ? panning : 0) | (current != null && current.hasAction() ? action : 0) | (FreeItems.itemsAttachedToCursor() ? cursor : 0);
 		String status = "";
 		
-		String l = statusText[context][left][mod][other];
-		String m = statusText[context][middle][mod][other];
-		String r = statusText[context][right][mod][other];
-		String lr = statusText[context][left | right][mod][other];
-		String lm = statusText[context][left | middle][mod][other];
-		String mr = statusText[context][middle | right][mod][other];
-		String dl = statusText[context][left][mod | drag][other];
-		String dm = statusText[context][middle][mod | drag][other];
-		String dr = statusText[context][right][mod | drag][other];
+		String l =  left(context, mod, other);
+		String m =  middle(context, mod, other);
+		String r =  right(context, mod, other);
+		String lr = left_right(context, mod, other);
+		String lm = left_middle(context, mod, other);
+		String mr = middle_right(context, mod, other);
+		String dl = drag_left(context, mod, other);
+		String dm = drag_middle(context, mod, other);
+		String dr = drag_right(context, mod, other);
 		
 		if(l != null)  status += command(mod, left) + l + padding.substring(l.length());
@@ -185,7 +166,7 @@
 		if(mr != null) status += command(mod, middle | right) + mr + padding.substring(mr.length());
 		if(dl != null || dm != null || dr != null) status += "\n";
-		if(dl != null) status += command(mod | drag, left) + dl + padding.substring(dl.length());
-		if(dm != null) status += command(mod | drag, middle) + dm + padding.substring(dm.length());
-		if(dr != null) status += command(mod | drag, right) + dr + padding.substring(dr.length());
+		if(dl != null) status += command(mod, left, true) + dl + padding.substring(dl.length());
+		if(dm != null) status += command(mod, middle, true) + dm + padding.substring(dm.length());
+		if(dr != null) status += command(mod, right, true) + dr + padding.substring(dr.length());
 		
 		MessageBay.setStatus(status);
