Index: /trunk/src/org/openstreetmap/josm/gui/download/DownloadDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/download/DownloadDialog.java	(revision 1389)
+++ /trunk/src/org/openstreetmap/josm/gui/download/DownloadDialog.java	(revision 1390)
@@ -101,4 +101,5 @@
 
         // predefined download selections
+        downloadSelections.add(new SlippyMapChooser());
         downloadSelections.add(new BoundingBoxSelection());
         downloadSelections.add(new TileSelection());
Index: /trunk/src/org/openstreetmap/josm/gui/download/OsmMapControl.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/download/OsmMapControl.java	(revision 1390)
+++ /trunk/src/org/openstreetmap/josm/gui/download/OsmMapControl.java	(revision 1390)
@@ -0,0 +1,121 @@
+// This code has been adapted and copied from code that has been written by Immanuel Scholz and others for JOSM.
+// License: GPL. Copyright 2007 by Tim Haussmann
+package org.openstreetmap.josm.gui.download;
+
+import java.awt.Point;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.KeyStroke;
+
+/**
+ * This class controls the user input by listening to mouse and key events.
+ * Currently implemented is: - zooming in and out with scrollwheel - zooming in
+ * and centering by double clicking - selecting an area by clicking and dragging
+ * the mouse
+ * 
+ * @author Tim Haussmann
+ */
+public class OsmMapControl extends MouseAdapter implements MouseMotionListener, MouseListener {
+
+    // start and end point of selection rectangle
+    private Point iStartSelectionPoint;
+    private Point iEndSelectionPoint;
+
+    // the SlippyMapChooserComponent
+    private final SlippyMapChooser iSlippyMapChooser;
+
+    private SizeButton iSizeButton = null;
+    private SourceButton iSourceButton = null;
+
+    /**
+     * Create a new OsmMapControl
+     */
+    public OsmMapControl(SlippyMapChooser navComp, JPanel contentPane, SizeButton sizeButton, SourceButton sourceButton) {
+        this.iSlippyMapChooser = navComp;
+        iSlippyMapChooser.addMouseListener(this);
+        iSlippyMapChooser.addMouseMotionListener(this);
+
+        String[] n = { ",", ".", "up", "right", "down", "left" };
+        int[] k =
+                { KeyEvent.VK_COMMA, KeyEvent.VK_PERIOD, KeyEvent.VK_UP, KeyEvent.VK_RIGHT,
+                        KeyEvent.VK_DOWN, KeyEvent.VK_LEFT };
+
+        if (contentPane != null) {
+            for (int i = 0; i < n.length; ++i) {
+                contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
+                        KeyStroke.getKeyStroke(k[i], KeyEvent.CTRL_DOWN_MASK),
+                        "MapMover.Zoomer." + n[i]);
+            }
+        }
+        iSizeButton = sizeButton;
+        iSourceButton = sourceButton;
+    }
+
+    /**
+     * Start drawing the selection rectangle if it was the 1st button (left
+     * button)
+     */
+    @Override
+    public void mousePressed(MouseEvent e) {
+        if (e.getButton() == MouseEvent.BUTTON1) {
+            if (!iSizeButton.hit(e.getPoint())) {
+                iStartSelectionPoint = e.getPoint();
+                iEndSelectionPoint = e.getPoint();
+            }
+        }
+        
+    }
+
+    public void mouseDragged(MouseEvent e) {        
+        if((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == MouseEvent.BUTTON1_DOWN_MASK){
+            if (iStartSelectionPoint != null) {             
+                iEndSelectionPoint = e.getPoint();
+                iSlippyMapChooser.setSelection(iStartSelectionPoint, iEndSelectionPoint);
+            }
+        }
+    }
+
+    /**
+     * When dragging the map change the cursor back to it's pre-move cursor. If
+     * a double-click occurs center and zoom the map on the clicked location.
+     */
+    @Override
+    public void mouseReleased(MouseEvent e) {
+        if (e.getButton() == MouseEvent.BUTTON1) {
+            
+            int sourceButton = iSourceButton.hit(e.getPoint());
+            
+            if (iSizeButton.hit(e.getPoint())) {
+                iSizeButton.toggle();
+                iSlippyMapChooser.resizeSlippyMap();
+            }
+            else if(sourceButton == SourceButton.HIDE_OR_SHOW) {
+                iSourceButton.toggle();
+                iSlippyMapChooser.repaint();
+                
+            }else if(sourceButton == SourceButton.MAPNIK || sourceButton == SourceButton.OSMARENDER || sourceButton == SourceButton.CYCLEMAP) {
+                iSlippyMapChooser.toggleMapSource(sourceButton);
+            }
+            else {
+                if (e.getClickCount() == 1) {
+                    iSlippyMapChooser.setSelection(iStartSelectionPoint, e.getPoint());
+
+                    // reset the selections start and end
+                    iEndSelectionPoint = null;
+                    iStartSelectionPoint = null;
+                }
+            }
+            
+        }
+    }
+
+    public void mouseMoved(MouseEvent e) {
+    }
+
+}
Index: /trunk/src/org/openstreetmap/josm/gui/download/SizeButton.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/download/SizeButton.java	(revision 1390)
+++ /trunk/src/org/openstreetmap/josm/gui/download/SizeButton.java	(revision 1390)
@@ -0,0 +1,54 @@
+// License: GPL. Copyright 2007 by Tim Haussmann
+package org.openstreetmap.josm.gui.download;
+
+
+import java.awt.Graphics;
+import java.awt.Point;
+
+import javax.swing.ImageIcon;
+
+import org.openstreetmap.josm.tools.ImageProvider;
+
+
+/**
+ * @author Tim Haussmann
+ */
+public class SizeButton{
+
+    private int x = 0;
+    private int y = 0;
+
+    private ImageIcon enlargeImage;
+    private ImageIcon shrinkImage;
+    private boolean isEnlarged = false;
+
+
+    public SizeButton(){
+        enlargeImage = ImageProvider.get("view-fullscreen.png");
+        shrinkImage = ImageProvider.get("view-fullscreen-revert.png");
+    }
+
+    public void paint(Graphics g){
+        if(isEnlarged){
+            if(shrinkImage != null)
+                g.drawImage(shrinkImage.getImage(),x,y, null);
+        }else{
+            if(enlargeImage != null)
+                g.drawImage(enlargeImage.getImage(),x,y, null);
+        }
+    }
+
+    public void toggle(){
+        isEnlarged = !isEnlarged;
+    }
+
+    public boolean hit(Point point){
+        if(x < point.x && point.x < x + enlargeImage.getIconWidth()){
+            if(y < point.y && point.y < y + enlargeImage.getIconHeight() ){
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
Index: /trunk/src/org/openstreetmap/josm/gui/download/SlippyMapChooser.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/download/SlippyMapChooser.java	(revision 1390)
+++ /trunk/src/org/openstreetmap/josm/gui/download/SlippyMapChooser.java	(revision 1390)
@@ -0,0 +1,295 @@
+// This code has been adapted and copied from code that has been written by Immanuel Scholz and others for JOSM.
+// License: GPL. Copyright 2007 by Tim Haussmann
+package org.openstreetmap.josm.gui.download;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Toolkit;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.geom.Point2D;
+import java.util.Vector;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import org.openstreetmap.gui.jmapviewer.JMapViewer;
+import org.openstreetmap.gui.jmapviewer.MapMarkerDot;
+import org.openstreetmap.gui.jmapviewer.MemoryTileCache;
+import org.openstreetmap.gui.jmapviewer.OsmFileCacheTileLoader;
+import org.openstreetmap.gui.jmapviewer.OsmMercator;
+import org.openstreetmap.gui.jmapviewer.OsmTileLoader;
+import org.openstreetmap.gui.jmapviewer.OsmTileSource;
+import org.openstreetmap.gui.jmapviewer.OsmTileSource.CycleMap;
+import org.openstreetmap.gui.jmapviewer.interfaces.MapMarker;
+import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
+import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.download.DownloadDialog;
+import org.openstreetmap.josm.gui.download.DownloadSelection;
+
+/**
+ * JComponent that displays the slippy map tiles
+ * 
+ * @author Tim Haussmann
+ * 
+ */
+public class SlippyMapChooser extends JMapViewer implements DownloadSelection, ComponentListener {
+
+    private DownloadDialog iGui;
+
+    // upper left and lower right corners of the selection rectangle (x/y on
+    // ZOOM_MAX)
+    Point iSelectionRectStart;
+    Point iSelectionRectEnd;
+
+    private SizeButton iSizeButton = new SizeButton();
+    private SourceButton iSourceButton = new SourceButton();
+
+    // standard dimension
+    private Dimension iDownloadDialogDimension;
+    // screen size
+    private Dimension iScreenSize;
+
+    private TileSource[] sources = { new OsmTileSource.Mapnik(), new OsmTileSource.TilesAtHome(),new OsmTileSource.CycleMap()};
+    TileLoader cachedLoader;
+    TileLoader uncachedLoader;
+    JPanel slipyyMapTabPanel;
+    boolean firstShown = true;
+
+    /**
+     * Create the chooser component.
+     */
+    public SlippyMapChooser() {
+        super();
+        cachedLoader = new OsmFileCacheTileLoader(this);
+        uncachedLoader = new OsmTileLoader(this);
+        setZoomContolsVisible(false);
+        setMapMarkerVisible(false);
+        setMinimumSize(new Dimension(350, 350 / 2));
+        setFileCacheEnabled(Main.pref.getBoolean("slippy_map_chooser.file_cache", true));
+        setMaxTilesInmemory(Main.pref.getInteger("slippy_map_chooser.max_tiles", 1000));
+        addComponentListener(this);
+
+        String mapStyle = Main.pref.get("slippy_map_chooser.mapstyle", "mapnik");
+        if(mapStyle.equals("osmarender")) {
+            iSourceButton.setMapStyle(SourceButton.OSMARENDER);
+            this.setTileSource(sources[1]);
+        }else if(mapStyle.equals("cyclemap")){
+        	 iSourceButton.setMapStyle(SourceButton.CYCLEMAP);
+             this.setTileSource(sources[2]);
+        }
+        else {
+            if(!mapStyle.equals("mapnik"))
+                Main.pref.put("slippy_map_chooser.mapstyle", "mapnik");
+        }
+    }
+
+    public void setMaxTilesInmemory(int tiles) {
+        ((MemoryTileCache) getTileCache()).setCacheSize(tiles);
+    }
+
+    public void setFileCacheEnabled(boolean enabled) {
+        if (enabled)
+            setTileLoader(cachedLoader);
+        else
+            setTileLoader(uncachedLoader);
+    }
+
+    public void addGui(final DownloadDialog gui) {
+        iGui = gui;
+        slipyyMapTabPanel = new JPanel();
+        slipyyMapTabPanel.setLayout(new BorderLayout());
+        slipyyMapTabPanel.add(this, BorderLayout.CENTER);
+        slipyyMapTabPanel.add(new JLabel((tr("Zoom: Mousewheel or double click.   "
+                + "Move map: Hold right mousebutton and move mouse.   Select: Click."))),
+                BorderLayout.SOUTH);
+        iGui.tabpane.add(slipyyMapTabPanel, tr("Slippy map"));
+        iGui.tabpane.addComponentListener(this);
+        new OsmMapControl(this, slipyyMapTabPanel, iSizeButton, iSourceButton);
+    }
+
+    protected Point getTopLeftCoordinates() {
+        return new Point(center.x - (getWidth() / 2), center.y - (getHeight() / 2));
+    }
+
+    /**
+     * Draw the map.
+     */
+    @Override
+    public void paint(Graphics g) {
+        try {
+            super.paint(g);
+
+            // draw selection rectangle
+            if (iSelectionRectStart != null && iSelectionRectEnd != null) {
+
+                int zoomDiff = MAX_ZOOM - zoom;
+                Point tlc = getTopLeftCoordinates();
+                int x_min = (iSelectionRectStart.x >> zoomDiff) - tlc.x;
+                int y_min = (iSelectionRectStart.y >> zoomDiff) - tlc.y;
+                int x_max = (iSelectionRectEnd.x >> zoomDiff) - tlc.x;
+                int y_max = (iSelectionRectEnd.y >> zoomDiff) - tlc.y;
+
+                int w = x_max - x_min;
+                int h = y_max - y_min;
+                g.setColor(new Color(0.9f, 0.7f, 0.7f, 0.6f));
+                g.fillRect(x_min, y_min, w, h);
+
+                g.setColor(Color.BLACK);
+                g.drawRect(x_min, y_min, w, h);
+
+            }
+
+            iSizeButton.paint(g);
+            iSourceButton.paint(g);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void boundingBoxChanged(DownloadDialog gui) {
+
+        // test if a bounding box has been set set
+        if (gui.minlat == 0.0 && gui.minlon == 0.0 && gui.maxlat == 0.0 && gui.maxlon == 0.0)
+            return;
+
+        int y1 = OsmMercator.LatToY(gui.minlat, MAX_ZOOM);
+        int y2 = OsmMercator.LatToY(gui.maxlat, MAX_ZOOM);
+        int x1 = OsmMercator.LonToX(gui.minlon, MAX_ZOOM);
+        int x2 = OsmMercator.LonToX(gui.maxlon, MAX_ZOOM);
+
+        iSelectionRectStart = new Point(Math.min(x1, x2), Math.min(y1, y2));
+        iSelectionRectEnd = new Point(Math.max(x1, x2), Math.max(y1, y2));
+
+        // calc the screen coordinates for the new selection rectangle
+        MapMarkerDot xmin_ymin = new MapMarkerDot(gui.minlat, gui.minlon);
+        MapMarkerDot xmax_ymax = new MapMarkerDot(gui.maxlat, gui.maxlon);
+
+        Vector<MapMarker> marker = new Vector<MapMarker>(2);
+        marker.add(xmin_ymin);
+        marker.add(xmax_ymax);
+        setMapMarkerList(marker);
+        setDisplayToFitMapMarkers();
+        zoomOut();
+    }
+
+    /**
+     * Callback for the OsmMapControl. (Re-)Sets the start and end point of the
+     * selection rectangle.
+     * 
+     * @param aStart
+     * @param aEnd
+     */
+    public void setSelection(Point aStart, Point aEnd) {
+        if (aStart == null || aEnd == null)
+            return;
+        Point p_max = new Point(Math.max(aEnd.x, aStart.x), Math.max(aEnd.y, aStart.y));
+        Point p_min = new Point(Math.min(aEnd.x, aStart.x), Math.min(aEnd.y, aStart.y));
+
+        Point tlc = getTopLeftCoordinates();
+        int zoomDiff = MAX_ZOOM - zoom;
+        Point pEnd = new Point(p_max.x + tlc.x, p_max.y + tlc.y);
+        Point pStart = new Point(p_min.x + tlc.x, p_min.y + tlc.y);
+
+        pEnd.x <<= zoomDiff;
+        pEnd.y <<= zoomDiff;
+        pStart.x <<= zoomDiff;
+        pStart.y <<= zoomDiff;
+
+        iSelectionRectStart = pStart;
+        iSelectionRectEnd = pEnd;
+
+        Point2D.Double l1 = getPosition(p_max);
+        Point2D.Double l2 = getPosition(p_min);
+        iGui.minlat = Math.min(l2.x, l1.x);
+        iGui.minlon = Math.min(l1.y, l2.y);
+        iGui.maxlat = Math.max(l2.x, l1.x);
+        iGui.maxlon = Math.max(l1.y, l2.y);
+
+        iGui.boundingBoxChanged(this);
+        repaint();
+    }
+
+    /**
+     * Performs resizing of the DownloadDialog in order to enlarge or shrink the
+     * map.
+     */
+    public void resizeSlippyMap() {
+        if (iScreenSize == null) {
+            Component c =
+                    iGui.getParent().getParent().getParent().getParent().getParent().getParent()
+                            .getParent().getParent().getParent();
+            // remember the initial set screen dimensions
+            iDownloadDialogDimension = c.getSize();
+            // retrive the size of the display
+            iScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
+        }
+
+        // resize
+        Component co =
+                iGui.getParent().getParent().getParent().getParent().getParent().getParent()
+                        .getParent().getParent().getParent();
+        Dimension currentDimension = co.getSize();
+
+        // enlarge
+        if (currentDimension.equals(iDownloadDialogDimension)) {
+            // make the each dimension 90% of the absolute display size and
+            // center the DownloadDialog
+            int w = iScreenSize.width * 90 / 100;
+            int h = iScreenSize.height * 90 / 100;
+            co.setBounds((iScreenSize.width - w) / 2, (iScreenSize.height - h) / 2, w, h);
+
+        }
+        // shrink
+        else {
+            // set the size back to the initial dimensions and center the
+            // DownloadDialog
+            int w = iDownloadDialogDimension.width;
+            int h = iDownloadDialogDimension.height;
+            co.setBounds((iScreenSize.width - w) / 2, (iScreenSize.height - h) / 2, w, h);
+
+        }
+
+        repaint();
+    }
+
+    public void toggleMapSource(int mapSource) {
+        this.tileCache = new MemoryTileCache();
+        if (mapSource == SourceButton.MAPNIK) {
+            this.setTileSource(sources[0]);
+            Main.pref.put("slippy_map_chooser.mapstyle", "mapnik");
+        }else if (mapSource == SourceButton.CYCLEMAP) {
+            this.setTileSource(sources[2]);
+            Main.pref.put("slippy_map_chooser.mapstyle", "cyclemap");
+        }else {
+            this.setTileSource(sources[1]);
+            Main.pref.put("slippy_map_chooser.mapstyle", "osmarender");
+        }
+    }
+
+    public void componentHidden(ComponentEvent e) {
+    }
+
+    public void componentMoved(ComponentEvent e) {
+    }
+
+    public void componentShown(ComponentEvent e) {
+    }
+
+    public void componentResized(ComponentEvent e) {
+        if (!this.equals(e.getSource()) || getHeight() == 0 || getWidth() == 0)
+            return;
+        firstShown = false;
+        // The bounding box has to be set after SlippyMapChooser's size has been
+        // finally set - otherwise the zoom level will be totally wrong (too wide)
+        boundingBoxChanged(iGui);
+    }
+
+}
Index: /trunk/src/org/openstreetmap/josm/gui/download/SourceButton.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/download/SourceButton.java	(revision 1390)
+++ /trunk/src/org/openstreetmap/josm/gui/download/SourceButton.java	(revision 1390)
@@ -0,0 +1,108 @@
+package org.openstreetmap.josm.gui.download;
+
+import java.awt.Graphics;
+import java.awt.Point;
+
+import javax.swing.ImageIcon;
+
+import org.openstreetmap.josm.tools.ImageProvider;
+
+public class SourceButton {
+
+    private int x = 0;
+    private int y = 30;
+
+    private ImageIcon enlargeImage;
+    private ImageIcon shrinkImage;
+    private ImageIcon imageMapnik;
+    private ImageIcon imageOsmarender;
+    private ImageIcon imageCycleMap;
+
+    private boolean isEnlarged = false;
+
+    private int currentMap = MAPNIK;
+
+    public static final int HIDE_OR_SHOW = 1;
+    public static final int MAPNIK = 2;
+    public static final int OSMARENDER = 3;
+    public static final int CYCLEMAP = 4;
+
+    public SourceButton() {
+        enlargeImage = ImageProvider.get("layer-switcher-maximize.png");
+        shrinkImage = ImageProvider.get("layer-switcher-minimize.png");
+        imageMapnik = ImageProvider.get("blue_Mapnik.png");
+        imageOsmarender = ImageProvider.get("blue_Osmarender.png");
+        imageCycleMap = ImageProvider.get("blue_CycleMap.png");
+    }
+
+    public void paint(Graphics g) {
+
+        if (isEnlarged) {
+            if (currentMap == MAPNIK) {
+                g.drawImage(imageMapnik.getImage(), g.getClipBounds().width
+                        - imageMapnik.getIconWidth(), y, null);
+            }else if(currentMap == CYCLEMAP){
+            	 g.drawImage(imageCycleMap.getImage(), g.getClipBounds().width
+                         - imageCycleMap.getIconWidth(), y, null);
+            }
+            else {
+                g.drawImage(imageOsmarender.getImage(), g.getClipBounds().width
+                        - imageMapnik.getIconWidth(), y, null);
+            }
+
+            if (shrinkImage != null) {
+                this.x = g.getClipBounds().width - shrinkImage.getIconWidth();
+                g.drawImage(shrinkImage.getImage(), x, y, null);
+            }
+
+        } else {
+            if (enlargeImage != null) {
+                this.x = g.getClipBounds().width - enlargeImage.getIconWidth();
+                g.drawImage(enlargeImage.getImage(), x, y, null);
+            }
+        }
+    }
+
+    public void toggle() {
+        this.isEnlarged = !this.isEnlarged;
+
+    }
+
+    public int hit(Point point) {
+        if (isEnlarged) {
+            if (x < point.x && point.x < x + shrinkImage.getIconWidth()) {
+                if (y < point.y && point.y < y + shrinkImage.getIconHeight()) {
+                    return HIDE_OR_SHOW;
+                }
+            } else if (x - imageMapnik.getIconWidth() < point.x && point.x < x) {
+                if (y < point.y && point.y < y + imageMapnik.getIconHeight() / 3) {
+                    currentMap = OSMARENDER;
+                    return OSMARENDER;
+                } else if (y + imageMapnik.getIconHeight() / 3 < point.y
+                        && point.y < y + imageMapnik.getIconHeight() *2/3) {
+                    currentMap = MAPNIK;
+                    return MAPNIK;
+                } else if (y + imageMapnik.getIconHeight()* 2/3 < point.y
+                        && point.y < y + imageMapnik.getIconHeight()) {
+                    currentMap = CYCLEMAP;
+                    return CYCLEMAP;
+                }
+            }
+        } else {
+            if (x < point.x && point.x < x + enlargeImage.getIconWidth()) {
+                if (y < point.y && point.y < y + enlargeImage.getIconHeight()) {
+                    return HIDE_OR_SHOW;
+                }
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * One of the constants OSMARENDER,MAPNIK or CYCLEMAP
+     */
+    public void setMapStyle (int style) {
+       currentMap = (style < 2 || style > 4) ? MAPNIK : style;
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java	(revision 1389)
+++ /trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java	(revision 1390)
@@ -58,5 +58,5 @@
         "lang-de", "lang-en_GB", "lang-fr", "lang-it", "lang-pl", "lang-ro",
         "lang-ru", "ewmsplugin", "ywms", "tways-0.2", "geotagged", "landsat",
-        "namefinder", "waypoints"};
+        "namefinder", "waypoints", "slippy_map_chooser"};
         for (String p : oldplugins) {
             if (plugins.contains(p)) {
