/*******************************************************************************
 * Copyright (c) 2000, 2010 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.gef.tools;

import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.Cursor;

import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.rap.swt.SWT;

import org.eclipse.gef.SharedCursors;

/**
 * A subclass of the SelectionTool that allows panning by holding down the space
 * bar.
 */
public class PanningSelectionTool extends SelectionTool {

	private boolean isSpaceBarDown = false;
	private Point viewLocation;

	/**
	 * The state to indicate that the space bar has been pressed but no drag has
	 * been initiated.
	 */
	protected static final int PAN = SelectionTool.MAX_STATE << 1;

	/**
	 * The state to indicate that a pan is in progress.
	 */
	protected static final int PAN_IN_PROGRESS = PAN << 1;

	/** Max state */
	protected static final int MAX_STATE = PAN_IN_PROGRESS;

	/**
	 * Returns <code>true</code> if spacebar condition was accepted.
	 * 
	 * @param e
	 *            the key event
	 * @return true if the space bar was the key event.
	 */
	protected boolean acceptSpaceBar(KeyEvent e) {
		return (e.character == ' ' && (e.stateMask & SWT.MODIFIER_MASK) == 0);
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#getDebugName()
	 */
	protected String getDebugName() {
		return "Panning Tool";//$NON-NLS-1$
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#getDebugNameForState(int)
	 */
	protected String getDebugNameForState(int state) {
		if (state == PAN)
			return "Pan Initial"; //$NON-NLS-1$
		else if (state == PAN_IN_PROGRESS)
			return "Pan In Progress"; //$NON-NLS-1$
		return super.getDebugNameForState(state);
	}

	/**
	 * Returns the cursor used under normal conditions.
	 * 
	 * @see #setDefaultCursor(Cursor)
	 * @return the default cursor
	 */
	protected Cursor getDefaultCursor() {
		if (isInState(PAN | PAN_IN_PROGRESS))
			return SharedCursors.HAND;
		return super.getDefaultCursor();
	}

	/**
	 * @see org.eclipse.gef.tools.SelectionTool#handleButtonDown(int)
	 */
	protected boolean handleButtonDown(int which) {
		if (which == 1
				&& getCurrentViewer().getControl() instanceof FigureCanvas
				&& stateTransition(PAN, PAN_IN_PROGRESS)) {
			viewLocation = ((FigureCanvas) getCurrentViewer().getControl())
					.getViewport().getViewLocation();
			return true;
		}
		return super.handleButtonDown(which);
	}

	/**
	 * @see org.eclipse.gef.tools.SelectionTool#handleButtonUp(int)
	 */
	protected boolean handleButtonUp(int which) {
		if (which == 1 && isSpaceBarDown
				&& stateTransition(PAN_IN_PROGRESS, PAN))
			return true;
		else if (which == 1 && stateTransition(PAN_IN_PROGRESS, STATE_INITIAL)) {
			refreshCursor();
			return true;
		}

		return super.handleButtonUp(which);
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#handleDrag()
	 */
	protected boolean handleDrag() {
		if (isInState(PAN_IN_PROGRESS)
				&& getCurrentViewer().getControl() instanceof FigureCanvas) {
			FigureCanvas canvas = (FigureCanvas) getCurrentViewer()
					.getControl();
			canvas.scrollTo(viewLocation.x - getDragMoveDelta().width,
					viewLocation.y - getDragMoveDelta().height);
			return true;
		} else {
			return super.handleDrag();
		}
	}

	/**
	 * @see org.eclipse.gef.tools.SelectionTool#handleFocusLost()
	 */
	protected boolean handleFocusLost() {
		if (isInState(PAN | PAN_IN_PROGRESS)) {
			setState(STATE_INITIAL);
			refreshCursor();
			return true;
		}
		return super.handleFocusLost();
	}

	/**
	 * @see org.eclipse.gef.tools.SelectionTool#handleKeyDown(org.eclipse.swt.events.KeyEvent)
	 */
	protected boolean handleKeyDown(KeyEvent e) {
		if (acceptSpaceBar(e)) {
			isSpaceBarDown = true;
			if (stateTransition(STATE_INITIAL, PAN))
				refreshCursor();
			return true;
		} else {
			if (stateTransition(PAN, STATE_INITIAL)) {
				refreshCursor();
				isSpaceBarDown = false;
				return true;
			} else if (isInState(PAN_IN_PROGRESS))
				isSpaceBarDown = false;
		}

		return super.handleKeyDown(e);
	}

	/**
	 * @see org.eclipse.gef.tools.SelectionTool#handleKeyUp(org.eclipse.swt.events.KeyEvent)
	 */
	protected boolean handleKeyUp(KeyEvent e) {
		if (acceptSpaceBar(e)) {
			isSpaceBarDown = false;
			if (stateTransition(PAN, STATE_INITIAL))
				refreshCursor();
			return true;
		}

		return super.handleKeyUp(e);
	}

}