Index: trunk/src/org/openstreetmap/josm/Main.java
===================================================================
--- trunk/src/org/openstreetmap/josm/Main.java	(revision 2271)
+++ trunk/src/org/openstreetmap/josm/Main.java	(revision 2272)
@@ -52,4 +52,5 @@
 import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
 import org.openstreetmap.josm.gui.preferences.MapPaintPreference;
+import org.openstreetmap.josm.gui.preferences.ProjectionPreference;
 import org.openstreetmap.josm.gui.preferences.TaggingPresetPreference;
 import org.openstreetmap.josm.gui.preferences.ToolbarPreferences;
@@ -282,28 +283,4 @@
     };
 
-    static public void setProjection(String name)
-    {
-        Bounds b = (map != null && map.mapView != null) ? map.mapView.getRealBounds() : null;
-        Projection oldProj = Main.proj;
-        try {
-            Main.proj = (Projection)Class.forName(name).newInstance();
-        } catch (final Exception e) {
-            JOptionPane.showMessageDialog(
-                    Main.parent,
-                    tr("The projection {0} could not be activated. Using Mercator", name),
-                    tr("Error"),
-                    JOptionPane.ERROR_MESSAGE
-            );
-            Main.proj = new Mercator();
-        }
-        if(!Main.proj.equals(oldProj))
-        {
-            if(b != null) {
-                map.mapView.zoomTo(b);
-                /* TODO - remove layers with fixed projection */
-            }
-        }
-    }
-
     /**
      * Should be called before the main constructor to setup some parameter stuff
@@ -311,5 +288,5 @@
      */
     public static void preConstructorInit(Map<String, Collection<String>> args) {
-        setProjection(Main.pref.get("projection", Mercator.class.getName()));
+        ProjectionPreference.setProjection();
 
         try {
Index: trunk/src/org/openstreetmap/josm/data/projection/ProjectionSubPrefs.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/projection/ProjectionSubPrefs.java	(revision 2272)
+++ trunk/src/org/openstreetmap/josm/data/projection/ProjectionSubPrefs.java	(revision 2272)
@@ -0,0 +1,47 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.projection;
+
+import java.util.Collection;
+
+import javax.swing.JPanel;
+
+public interface ProjectionSubPrefs {
+    /**
+     * Generates the GUI for the given preference and packs them in a JPanel
+     * so they may be displayed if the projection is selected.
+     *
+     * Implementation hints:
+     * <ul>
+     *      <li>Do not return <code>null</code> as it is assumed that if this
+     *      interface is implemented the projection actually has prefs to
+     *      display/save.</li>
+     *      <li>Cache the JPanel in a local variable so that changes are
+     *      persistent even if the user chooses another projection in between.
+     *      Destroy the panel on destroyCachedPanel() so that the pre-selected
+     *      settings may update the preferences are updated from the outside</li>
+     *      </li>
+     * @return
+     */
+    public JPanel getPreferencePanel();
+
+    /**
+     * Will be called if the preference dialog is dismissed.
+     */
+    public Collection<String> getPreferences();
+
+    /**
+     * Return null when code is not part of this projection.
+     */
+    public Collection<String> getPreferencesFromCode(String code);
+
+    /**
+     * Will be called if the preference dialog is dismissed.
+     */
+    public void setPreferences(Collection<String> args);
+
+    /**
+     * Resets all variables related to the projection preferences so they may
+     * update the next time getPreferencePanel is called.
+     */
+    public void destroyCachedPanel();
+}
Index: trunk/src/org/openstreetmap/josm/data/projection/UTM.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/projection/UTM.java	(revision 2271)
+++ trunk/src/org/openstreetmap/josm/data/projection/UTM.java	(revision 2272)
@@ -4,7 +4,17 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.awt.GridBagLayout;
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.tools.GBC;
 
 /**
@@ -14,5 +24,7 @@
  * code based on JavaScript from Chuck Taylor
  */
-public class UTM implements Projection {
+public class UTM implements Projection, ProjectionSubPrefs {
+
+    private int zone = 33;
 
     final private double UTMScaleFactor = 0.9996;
@@ -336,19 +348,18 @@
 
     @Override public String toString() {
-        return tr("UTM Zone {0}", getzone());
-    }
-
-    /* TODO - support all UTM's not only zone 33 */
+        return tr("UTM");
+    }
+
     public int getzone()
     {
-        return 33;
+        return zone;
     }
 
     public String toCode() {
-        return "EPSG:325833";
+        return "EPSG:"+ (325800 + getzone());
     }
 
     public String getCacheDirectoryName() {
-        return "epsg325833";
+        return "epsg"+ (325800 + getzone());
     }
 
@@ -364,3 +375,47 @@
         return 10;
     }
+
+    private JPanel prefpanel = null;
+    private JComboBox prefcb = null;
+    public JPanel getPreferencePanel() {
+        if(prefpanel != null)
+            return prefpanel;
+
+        prefcb = new JComboBox();
+        for(int i = 1; i <= 60; i++) {
+            prefcb.addItem(i);
+        }
+
+        prefcb.setSelectedIndex(zone - 1);
+        prefpanel = new JPanel(new GridBagLayout());
+        prefpanel.add(new JLabel(tr("UTM Zone")), GBC.std().insets(5,5,0,5));
+        prefpanel.add(GBC.glue(1, 0), GBC.std().fill(GBC.HORIZONTAL));
+        prefpanel.add(prefcb, GBC.eop().fill(GBC.HORIZONTAL));
+        prefpanel.add(GBC.glue(1, 1), GBC.eol().fill(GBC.BOTH));
+        return prefpanel;
+    }
+
+    public Collection<String> getPreferences() {
+        if(prefcb == null)
+            return null;
+        int zone = prefcb.getSelectedIndex() + 1;
+        return Collections.singleton(Integer.toString(zone));
+    }
+
+    public void destroyCachedPanel() {
+        prefpanel = null;
+        prefcb = null;
+    }
+
+    public void setPreferences(Collection<String> args)
+    {
+        /* TODO: parse args instead of fixed value */
+        zone = 33;
+    }
+
+    public Collection<String> getPreferencesFromCode(String code)
+    {
+        /* TODO: implement */
+        return null;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/ProjectionPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/ProjectionPreference.java	(revision 2271)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/ProjectionPreference.java	(revision 2272)
@@ -5,16 +5,22 @@
 
 import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import java.util.Collection;
 
 import javax.swing.BorderFactory;
-import javax.swing.Box;
 import javax.swing.JComboBox;
 import javax.swing.JLabel;
+import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.CoordinateFormat;
 import org.openstreetmap.josm.data.projection.Mercator;
 import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.data.projection.ProjectionSubPrefs;
 import org.openstreetmap.josm.tools.GBC;
 
@@ -31,14 +37,35 @@
      */
     private JComboBox projectionCombo = new JComboBox(Projection.allProjections);
+
+    /**
+     * Combobox with all coordinate display possibilities
+     */
     private JComboBox coordinatesCombo = new JComboBox(CoordinateFormat.values());
 
+    /**
+     * This variable holds the JPanel with the projection's preferences. If the
+     * selected projection does not implement this, it will be set to an empty
+     * Panel.
+     */
+    private JPanel projSubPrefPanel;
+
+    private JLabel projectionCode = new JLabel();
+    private JLabel bounds = new JLabel();
+
+    /**
+     * This is the panel holding all projection preferences
+     */
+    private JPanel projPanel = new JPanel();
+
+    /**
+     * The GridBagConstraints for the Panel containing the ProjectionSubPrefs.
+     * This is required twice in the code, creating it here keeps both occurrences
+     * in sync
+     */
+    static private GBC projSubPrefPanelGBC = GBC.eol().fill(GBC.BOTH).insets(20,5,5,5);
+
     public void addGui(PreferenceDialog gui) {
-
-        for (int i = 0; i < projectionCombo.getItemCount(); ++i) {
-            if (projectionCombo.getItemAt(i).getClass().getName().equals(Main.pref.get("projection", Mercator.class.getName()))) {
-                projectionCombo.setSelectedIndex(i);
-                break;
-            }
-        }
+        clearSubProjPrefs();
+        setupProjectionCombo();
 
         for (int i = 0; i < coordinatesCombo.getItemCount(); ++i) {
@@ -49,5 +76,4 @@
         }
 
-        JPanel projPanel = new JPanel();
         projPanel.setBorder(BorderFactory.createEmptyBorder( 0, 0, 0, 0 ));
         projPanel.setLayout(new GridBagLayout());
@@ -58,19 +84,153 @@
         projPanel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
         projPanel.add(projectionCombo, GBC.eop().fill(GBC.HORIZONTAL).insets(0,5,5,5));
-        projPanel.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.BOTH));
+        projPanel.add(new JLabel(tr("Projection code")), GBC.std().insets(25,5,0,5));
+        projPanel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
+        projPanel.add(projectionCode, GBC.eop().fill(GBC.HORIZONTAL).insets(0,5,5,5));
+        projPanel.add(new JLabel(tr("Bounds")), GBC.std().insets(25,5,0,5));
+        projPanel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
+        projPanel.add(bounds, GBC.eop().fill(GBC.HORIZONTAL).insets(0,5,5,5));
+        projPanel.add(projSubPrefPanel, projSubPrefPanelGBC);
         JScrollPane scrollpane = new JScrollPane(projPanel);
         gui.mapcontent.addTab(tr("Map Projection"), scrollpane);
+
+        projectionCode.setText(Main.proj.toCode());
+        Bounds b = Main.proj.getWorldBoundsLatLon();
+        CoordinateFormat cf = CoordinateFormat.getDefaultFormat();
+        bounds.setText(b.min.latToString(cf)+"; "+b.min.lonToString(cf)+" : "+b.max.latToString(cf)+"; "+b.max.lonToString(cf));
+        /* TODO: Fix bugs, refresh code line and world bounds, fix design (e.g. add border around sub-prefs-stuff */
     }
 
     public boolean ok() {
-        String projname = projectionCombo.getSelectedItem().getClass().getName();
+        Projection proj = (Projection) projectionCombo.getSelectedItem();
+
+        String projname = proj.getClass().getName();
+        Collection<String> prefs = null;
+        if(projHasPrefs(proj))
+            prefs = ((ProjectionSubPrefs) proj).getPreferences();
+
         if(Main.pref.put("projection", projname)) {
-            Main.setProjection(projname);
-        }
+            setProjection(projname, prefs);
+        }
+
         if(Main.pref.put("coordinates",
                 ((CoordinateFormat)coordinatesCombo.getSelectedItem()).name())) {
             CoordinateFormat.setCoordinateFormat((CoordinateFormat)coordinatesCombo.getSelectedItem());
         }
+
+        // We get the change to remove these panels on closing the preferences
+        // dialog, so take it. TODO: Make this work always, even when canceling
+        // the dialog
+        clearSubProjPrefs();
+
         return false;
     }
+
+    /**
+     * Finds out if the given projection implements the ProjectionPreference
+     * interface
+     * @param proj
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    static private boolean projHasPrefs(Projection proj) {
+        Class[] ifaces = proj.getClass().getInterfaces();
+        for(int i = 0; i < ifaces.length; i++) {
+            if(ifaces[i].getSimpleName().equals("ProjectionSubPrefs"))
+                return true;
+        }
+        return false;
+    }
+
+    static public void setProjection()
+    {
+        setProjection(Main.pref.get("projection", Mercator.class.getName()),
+        Main.pref.getCollection("projection.sub", null));
+    }
+
+    static public void setProjection(String name, Collection<String> coll)
+    {
+        Bounds b = (Main.map != null && Main.map.mapView != null) ? Main.map.mapView.getRealBounds() : null;
+        Projection oldProj = Main.proj;
+
+        try {
+            Main.proj = (Projection)Class.forName(name).newInstance();
+        } catch (final Exception e) {
+            JOptionPane.showMessageDialog(
+                    Main.parent,
+                    tr("The projection {0} could not be activated. Using Mercator", name),
+                    tr("Error"),
+                    JOptionPane.ERROR_MESSAGE
+            );
+            coll = null;
+            Main.proj = new Mercator();
+        }
+        if(!Main.proj.equals(oldProj) && b != null)
+        {
+            Main.map.mapView.zoomTo(b);
+            /* TODO - remove layers with fixed projection */
+        }
+        Main.pref.putCollection("projection.sub", coll);
+        if(coll != null && projHasPrefs(Main.proj))
+            ((ProjectionSubPrefs) Main.proj).setPreferences(coll);
+    }
+
+    /**
+     * Handles all the work related to update the projection-specific
+     * preferences
+     * @param proj
+     */
+    private void selectedProjectionChanged(Projection proj) {
+        if(!projHasPrefs(proj)) {
+            projSubPrefPanel = new JPanel();
+        } else {
+            ProjectionSubPrefs projPref = (ProjectionSubPrefs) proj;
+            projSubPrefPanel = projPref.getPreferencePanel();
+        }
+
+        // Don't try to update if we're still starting up
+        int size = projPanel.getComponentCount();
+        if(size < 1)
+            return;
+
+        // Replace old panel with new one
+        projPanel.remove(size - 1);
+        projPanel.add(projSubPrefPanel, projSubPrefPanelGBC);
+        projPanel.revalidate();
+    }
+
+    /**
+     * Sets up projection combobox with default values and action listener
+     */
+    private void setupProjectionCombo() {
+        for (int i = 0; i < projectionCombo.getItemCount(); ++i) {
+            Projection proj = (Projection)projectionCombo.getItemAt(i);
+            if (proj.getClass().getName().equals(Main.pref.get("projection", Mercator.class.getName()))) {
+                projectionCombo.setSelectedIndex(i);
+                selectedProjectionChanged(proj);
+                break;
+            }
+        }
+
+        projectionCombo.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                JComboBox cb = (JComboBox)e.getSource();
+                Projection proj = (Projection)cb.getSelectedItem();
+                selectedProjectionChanged(proj);
+            }
+        });
+    }
+
+    /**
+     * Method to clean up the preference panels made by each projection. This
+     * requires them to be regenerated when the prefs dialog is opened again,
+     * but this also makes them react to changes to their preferences from the
+     * outside
+     */
+    static private void clearSubProjPrefs() {
+        for(Projection proj : Projection.allProjections) {
+            if(projHasPrefs(proj)) {
+                ((ProjectionSubPrefs) proj).destroyCachedPanel();
+            }
+        }
+    }
 }
