Index: trunk/src/org/expeditee/settings/Settings.java
===================================================================
--- trunk/src/org/expeditee/settings/Settings.java	(revision 641)
+++ trunk/src/org/expeditee/settings/Settings.java	(revision 655)
@@ -3,5 +3,4 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -13,7 +12,11 @@
 import org.expeditee.gui.FrameIO;
 import org.expeditee.gui.FrameUtils;
+import org.expeditee.items.Item;
 import org.expeditee.items.Text;
 import org.expeditee.items.widgets.Password;
 import org.expeditee.reflection.PackageLoader;
+import org.expeditee.setting.GenericSetting;
+import org.expeditee.setting.Setting;
+import org.expeditee.setting.VariableSetting;
 
 public abstract class Settings {
@@ -24,61 +27,27 @@
 	private static final class PageDescriptor {
 		
-		private static final class FieldSet {
-			
-			private final Field field;
-			private final Method method;
-			
-			private FieldSet(Field field, Method method) {
-				this.field = field;
-				this.method = method;
-			}
-		}
-		
-		private final HashMap<String, FieldSet> settings = new HashMap<String, FieldSet>();
-		private final List<Field> hasDefault = new LinkedList<Field>();
+		private final HashMap<String, Setting> settings = new HashMap<String, Setting>();
 		private final List<String> orderedEntries = new LinkedList<String>();
+		private final List<VariableSetting> hasDefault = new LinkedList<VariableSetting>();
 		private final Method onParsed;
 		
 		private PageDescriptor(Class<?> clazz) {
 			
-			// populate map of settings with methods
-			for(Method m : clazz.getMethods()) {
-				// method name must start with "set", and method must take 1 Text item as parameter
-				if(m.getName().toLowerCase().startsWith("set") && m.getParameterTypes().length == 1 && m.getParameterTypes()[0] == Text.class) {
-					// System.out.println(m.getName().toLowerCase());
-					settings.put(m.getName().substring(3).toLowerCase(), new FieldSet(null, m));
-					if(!orderedEntries.contains(m.getName().substring(3))) {
-						orderedEntries.add(m.getName().substring(3));
-					}
-				}
-			}
-			// populate map of settings with fields
+			// populate map of settings
 			for(Field f : clazz.getFields()) {
-				Class<?> type = f.getType();
 				// only allow valid types
-				if(type != String.class &&
-						type != Boolean.class && type != boolean.class &&
-						type != Integer.class && type != int.class &&
-						type != Double.class && type != double.class &&
-						type != Float.class && type != float.class) {
-					continue;
-				}
-				FieldSet fs = settings.get(f.getName().toLowerCase());
-				if(fs == null) {
-					settings.put(f.getName().toLowerCase(), new FieldSet(f, null));
-				} else {
-					settings.put(f.getName().toLowerCase(), new FieldSet(f, fs.method));
-				}
-				if(!orderedEntries.contains(f.getName())) {
-					orderedEntries.add(f.getName());
-				}
-			}
-			// check which fields have default values
-			for(Field f : clazz.getFields()) {
-				if(!Modifier.isFinal(f.getModifiers())) {
-					if(this.settings.get("default" + f.getName().toLowerCase()) != null) {
-						this.hasDefault.add(f);
-					}
-				}
+				if(! Setting.class.isAssignableFrom(f.getType())) {
+					continue;
+				}
+				try {
+					Setting s = (Setting) f.get(null);
+	                settings.put(f.getName().toLowerCase(), s);
+	                if(s instanceof VariableSetting && ((VariableSetting) s).hasDefault()) {
+	                	hasDefault.add((VariableSetting) s);
+	                }
+	                orderedEntries.add(f.getName());
+                } catch (Exception e) {
+	                e.printStackTrace();
+                }
 			}
 			Method m = null;
@@ -108,5 +77,5 @@
 			e.printStackTrace();
 		}
-		FrameUtils.ParseProfile(FrameIO.LoadProfile(UserSettings.ProfileName));
+		FrameUtils.ParseProfile(FrameIO.LoadProfile(UserSettings.ProfileName.get()));
 	}
 	
@@ -136,5 +105,5 @@
 				return;
 			}
-			List<Field> toDefault = new LinkedList<Field>(pd.hasDefault);
+			List<VariableSetting> toDefault = new LinkedList<VariableSetting>(pd.hasDefault);
 			// set the fields
 			for (Text t : text.getChild().getBodyTextItems(true)) {
@@ -142,40 +111,10 @@
 				try {
 					// System.out.println(avp.getAttributeOrValue().trim().toLowerCase().replaceAll("^@", ""));
-					PageDescriptor.FieldSet fs = pd.settings.get(avp.getAttributeOrValue().trim().toLowerCase().replaceAll("^@", ""));
-					if(fs == null) {
+					Setting s = pd.settings.get(avp.getAttributeOrValue().trim().toLowerCase().replaceAll("^@", ""));
+					if(s == null) {
 						continue;
 					}
-					Field f = fs.field;
-					Method m = fs.method;
-					if(m != null) {
-						m.invoke(null, t);
-						// System.out.println("Set " + avp.getAttributeOrValue() + " by method");
-						// we're setting this field, so remove it from the list of fields to default
-						toDefault.remove(f);
-					} else {
-						if (f != null) {
-							// if the value is empty, set it to the default
-							if(avp.getValue() == null || avp.getValue().trim().length() == 0) {
-								continue;
-							}
-							Class<?> type = f.getType();
-							if(type == String.class) {
-								f.set(null, avp.getValue());
-							} else if(type == Boolean.class || type == boolean.class) {
-								f.set(null, avp.getBooleanValue());
-							} else if(type == Integer.class || type == int.class) {
-								f.set(null, avp.getIntegerValue());
-							} else if(type == Double.class || type == double.class) {
-								f.set(null, avp.getDoubleValue());
-							} else if(type == Float.class || type == float.class) {
-								f.set(null, avp.getDoubleValue().floatValue());
-							} else {
-								System.err.println("Failed to set " + f.getName() + " of " + type);
-								continue;
-							}
-							// we're setting this field, so remove it from the list of fields to default
-							toDefault.remove(f);
-							// System.out.println("Set " + f.getName() + " to " + f.get(null));
-						}
+					if(s.setSetting(t)) {
+						toDefault.remove(s);
 					}
 				} catch (Exception e) {
@@ -184,7 +123,8 @@
 			}
 			// set any unset fields to their default
-			for(Field f : toDefault) {
+			for(VariableSetting s : toDefault) {
 				try {
-		            f.set(null, pd.settings.get("default" + f.getName().toLowerCase()).field.get(null));
+					// System.out.println("Resetting " + s.getTooltip());
+		            s.reset();
 		            // System.out.println("Set " + f.getName() + " to default value " + f.get(null));
 	            } catch (Exception e) {
@@ -210,4 +150,10 @@
 	}
 	
+	/**
+	 * 
+	 * Generates settings tree
+	 * TODO: merge with @see FrameCreator
+	 * 
+	 */
 	private static Text generateSettingsTree(String page, Text text) {
 		Frame frame = FrameIO.CreateNewFrame(text);
@@ -215,6 +161,6 @@
 		
 		int x = 50, y = 100;
-		int dY = UserSettings.ItemTemplate.getPolygon().getBounds().height + 1;
-		int maxY = UserSettings.InitialHeight - 150;
+		int dY = UserSettings.ItemTemplate.get().getPolygon().getBounds().height + 1;
+		int maxY = UserSettings.InitialHeight.get() - 150;
 		
 		// add subpages of the current page
@@ -243,34 +189,40 @@
 			for(String str : pd.orderedEntries) {
 				String key = str.toLowerCase();
-				if(key.startsWith("default")) {
-					continue;
-				}
-				PageDescriptor.FieldSet fs = pd.settings.get(key);
-				String name = null;
-				Object value = "";
-				name = str.substring(0, 1).toUpperCase() + str.substring(1);
-				if(fs.method == null && fs.field != null) {
-    				try {
-    					if(pd.hasDefault.contains(fs.field)) {
-    						value = ": " + pd.settings.get("default" + key).field.get(null);
-    					} else {
-    						value = ": " + fs.field.get(null);
-    					}
-    				} catch (Exception e) {
-                        e.printStackTrace();
-                    }
-				} else if(fs.method == null) {
-					continue;
+				Setting s = pd.settings.get(key);
+				if(s == null) {
+					continue;
+				}
+				String name = str.substring(0, 1).toUpperCase() + str.substring(1);
+				String value = "";
+				if(s instanceof GenericSetting && ((GenericSetting) s).isPrimitive()) {
+					System.out.println("VALUE: " + ((GenericSetting) s).get());
+					if(((GenericSetting) s).get() != null) {
+						value = ": " + ((GenericSetting) s).get();
+					} else {
+						value = ": ";
+					}
 				}
 				if(key.equals("pass")) {
-					Password pw = new Password(frame.createNewText("@iw: org.expeditee.items.widgets.Password"), null);
+					Text t = frame.addText(x, y, "iw: org.expeditee.items.widgets.Password", null);
+					Password pw = new Password(t, null);
 					pw.setPassword((String) value);
-					pw.setPosition(x, y);
+					frame.removeItem(t);
 					frame.addAllItems(pw.getItems());
 					y += pw.getHeight();
+				} else if(s instanceof GenericSetting && ((GenericSetting) s).getType().equals(Text.class)) {
+					Text t = ((GenericSetting<Text>) s).get();
+					if(t == null) continue;
+					t = t.copy();
+					int h = t.getPolygon().getBounds().height + 1;
+					t.setID(frame.getNextItemID());
+					t.setX(x);
+					t.setY(y + h / 2);
+					t.setText(name);
+					frame.addItem(t);
+					y += h;
 				} else {
-					frame.addText(x, y, name + value, null);
-				}
-				y += dY;
+					frame.addText(x, y + dY / 2, name + value, null);
+					y += dY;
+				}
 				if(y >= maxY) {
 					x += 300;
