/*
 * This file is part of Geomajas, a component framework for building
 * rich Internet applications (RIA) with sophisticated capabilities for the
 * display, analysis and management of geographic information.
 * It is a building block that allows developers to add maps
 * and other geographic data capabilities to their web applications.
 *
 * Copyright 2008-2010 Geosparc, http://www.geosparc.com, Belgium
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.geomajas.gwt.client.controller;

import org.geomajas.geometry.Coordinate;
import org.geomajas.gwt.client.widget.MapWidget;

import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseEvent;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.smartgwt.client.types.Cursor;

/**
 * Handle panning by dragging the map. Also allows zoom to rectangle when using shift or ctrl when you start to drag.
 * 
 * @author Joachim Van der Auwera
 */
public class PanController extends AbstractGraphicsController {

	private boolean zooming;

	private boolean dragging;

	private Coordinate begin;

	private ZoomToRectangleController zoomToRectangleController;

	// Constructors:

	public PanController(MapWidget mapWidget) {
		super(mapWidget);
		zoomToRectangleController = new ZoomToRectangleController(mapWidget);
	}

	@Override
	public void onMouseDown(MouseDownEvent event) {
		if (event.isControlKeyDown() || event.isShiftKeyDown()) {
			zooming = true;
			zoomToRectangleController.onMouseDown(event);
		} else if (event.getNativeButton() != NativeEvent.BUTTON_RIGHT) {
			dragging = true;
			mapWidget.getMapModel().getMapView().setPanDragging(true);
			begin = getScreenPosition(event);
			mapWidget.setCursor(Cursor.MOVE);
		}
	}

	@Override
	public void onMouseUp(MouseUpEvent event) {
		if (zooming) {
			zoomToRectangleController.onMouseUp(event);
			zooming = false;
		} else if (dragging) {
			stopPanning(event);
		}
	}

	@Override
	public void onMouseMove(MouseMoveEvent event) {
		if (zooming) {
			zoomToRectangleController.onMouseMove(event);
		} else if (dragging) {
			updateView(event);
		}
	}

	@Override
	public void onMouseOut(MouseOutEvent event) {
		if (zooming) {
			zoomToRectangleController.onMouseOut(event);
		} else {
			stopPanning(null);
		}
	}

	// Private methods:

	private void stopPanning(MouseUpEvent event) {
		mapWidget.getMapModel().getMapView().setPanDragging(false);
		dragging = false;
		mapWidget.setCursor(Cursor.DEFAULT);
		if (null != event) {
			updateView(event);
		}
	}

	private void updateView(MouseEvent<?> event) {
		Coordinate end = getScreenPosition(event);
		Coordinate beginWorld = getTransformer().viewToWorld(begin);
		Coordinate endWorld = getTransformer().viewToWorld(end);
		mapWidget.getMapModel().getMapView().translate(beginWorld.getX() - endWorld.getX(),
				beginWorld.getY() - endWorld.getY());
		begin = end;
	}
}

@@ -1163,16 +1163,116 @@
 dinate;%0A
+import org.geomajas.gwt.client.map.MapView.ZoomOption;%0Aimport org.geomajas.gwt.client.spatial.Bbox;%0A
 import o
@@ -1351,32 +1351,89 @@
 nt.NativeEvent;%0A
+import com.google.gwt.event.dom.client.DoubleClickEvent;%0A
 import com.googl
@@ -1848,16 +1848,87 @@
 o drag.%0A
+ * Double clicking allows the user to zoom in on the clicked location.%0A
  * %0A * @
@@ -1957,16 +1957,43 @@
  Auwera%0A
+ * @author Pieter De Graef%0A
  */%0Apubl
@@ -2199,16 +2199,56 @@
 oller;%0A%0A
+%09private Coordinate lastClickPosition;%0A%0A
 %09// Cons
@@ -2811,24 +2811,71 @@
 .MOVE);%0A%09%09%7D%0A
+%09%09lastClickPosition = getWorldPosition(event);%0A
 %09%7D%0A%0A%09@Overri
@@ -3407,16 +3407,530 @@
 %09%09%7D%0A%09%7D%0A%0A
+%09/**%0A%09 * Zoom in to the double-clicked position.%0A%09 */%0A%09public void onDoubleClick(DoubleClickEvent event) %7B%0A%09%09// Zoom in on the event location.%0A%09%09Bbox bounds = mapWidget.getMapModel().getMapView().getBounds();%0A%09%09double x = lastClickPosition.getX() - (bounds.getWidth() / 4);%0A%09%09double y = lastClickPosition.getY() - (bounds.getHeight() / 4);%0A%09%09Bbox newBounds = new Bbox(x, y, bounds.getWidth() / 2, bounds.getHeight() / 2);%0A%09%09mapWidget.getMapModel().getMapView().applyBounds(newBounds, ZoomOption.LEVEL_CHANGE);%0A%09%7D%0A%0A
 %09// Priv
@@ -4418,16 +4418,21 @@
 apView()
+%0A%09%09%09%09
 .transla
@@ -4470,21 +4470,17 @@
 .getX(),
-%0A%09%09%09%09
+ 
 beginWor

Add double click possibility to the pan controller, so that it is able to zoom in by double clicking.