/*******************************************************************************
 * 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 java.lang.ref.WeakReference;
import java.util.List;

import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;

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

import org.eclipse.gef.AccessibleHandleProvider;
import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.Handle;
import org.eclipse.gef.KeyHandler;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.requests.LocationRequest;
import org.eclipse.gef.requests.SelectionRequest;

/**
 * Tool to select and manipulate figures. A selection tool is in one of three
 * states, e.g., background selection, figure selection, handle manipulation.
 * The different states are handled by different child tools.
 */
public class SelectionTool extends TargetingTool {

	private static final int FLAG_HOVER_FEEDBACK = TargetingTool.MAX_FLAG << 1;
	/** Max flag */
	protected static final int MAX_FLAG = FLAG_HOVER_FEEDBACK;

	/** Traverse handle state */
	protected static final int STATE_TRAVERSE_HANDLE = TargetingTool.MAX_STATE << 1;
	/** Max state */
	protected static final int MAX_STATE = STATE_TRAVERSE_HANDLE;

	private int handleIndex;
	private DragTracker dragTracker;
	private LocationRequest hoverRequest;

	private WeakReference cachedHandlePart;

	/**
	 * Default constructor.
	 */
	public SelectionTool() {
	}

	private boolean acceptTraverseHandle(KeyEvent e) {
		return (e.character == '.' || e.character == '>')
				&& isInState(STATE_INITIAL | STATE_ACCESSIBLE_DRAG
						| STATE_ACCESSIBLE_DRAG_IN_PROGRESS)
				&& ((e.stateMask & (SWT.ALT | SWT.CONTROL)) == 0);
	}

	/**
	 * Creates the hover request (a {@link LocationRequest}) and sets its type
	 * to {@link RequestConstants#REQ_SELECTION_HOVER}.
	 */
	protected void createHoverRequest() {
		hoverRequest = new LocationRequest();
		hoverRequest.setType(RequestConstants.REQ_SELECTION_HOVER);
	}

	/**
	 * Creates a {@link SelectionRequest} for the target request.
	 * 
	 * @see TargetingTool#createTargetRequest()
	 */
	protected Request createTargetRequest() {
		SelectionRequest request = new SelectionRequest();
		request.setType(getCommandName());
		return request;
	}

	/**
	 * Deactivates the tool. This method is called whenever the user switches to
	 * another tool. Use this method to do some clean-up when the tool is
	 * switched. Sets the drag tracker to <code>null</code>.
	 */
	public void deactivate() {
		setDragTracker(null); // deactivates the current drag tracker
		super.deactivate();
	}

	/**
	 * Erases the hover feedback by calling
	 * {@link EditPart#eraseTargetFeedback(Request)}.
	 */
	protected void eraseHoverFeedback() {
		if (getTargetEditPart() == null)
			return;
		if (getTargetHoverRequest() == null)
			return;
		getTargetEditPart().eraseTargetFeedback(getTargetHoverRequest());
	}

	/**
	 * @see AbstractTool#getCommandName()
	 */
	protected String getCommandName() {
		return REQ_SELECTION;
	}

	/**
	 * @see AbstractTool#getDebugName()
	 */
	protected String getDebugName() {
		return "Selection Tool";//$NON-NLS-1$
	}

	/**
	 * Returns the current drag tracker.
	 * 
	 * @return the drag tracker
	 */
	protected DragTracker getDragTracker() {
		return dragTracker;
	}

	private EditPart getLastHandleProvider() {
		if (cachedHandlePart == null)
			return null;
		EditPart part = (EditPart) cachedHandlePart.get();
		if (cachedHandlePart.isEnqueued())
			return null;
		return part;
	}

	/**
	 * Returns a new Conditional that evaluates to <code>true</code> if the
	 * queried edit part's {@link EditPart#isSelectable()} method returns
	 * <code>true</code>.
	 * 
	 * @see TargetingTool#getTargetingConditional()
	 */
	protected EditPartViewer.Conditional getTargetingConditional() {
		return new EditPartViewer.Conditional() {
			public boolean evaluate(EditPart editpart) {
				EditPart targetEditPart = editpart
						.getTargetEditPart(getTargetRequest());
				return targetEditPart != null && targetEditPart.isSelectable();
			}
		};
	}

	/**
	 * Returns the target hover request. If <code>null</code>, it will be
	 * created via {@link #createHoverRequest()}.
	 * 
	 * @return the hover request
	 */
	protected Request getTargetHoverRequest() {
		if (hoverRequest == null)
			createHoverRequest();
		return hoverRequest;
	}

	/**
	 * If there is a {@link Handle} under the mouse, this method sets the drag
	 * tracker returned from the handle. If there's an {@link EditPart} under
	 * the mouse, this method sets the drag tracker returned from the edit part.
	 * 
	 * @see AbstractTool#handleButtonDown(int)
	 */
	protected boolean handleButtonDown(int button) {
		if (!stateTransition(STATE_INITIAL, STATE_DRAG)) {
			resetHover();
			return true;
		}
		resetHover();
		EditPartViewer viewer = getCurrentViewer();
		Point p = getLocation();

		if (getDragTracker() != null)
			getDragTracker().deactivate();

		if (viewer instanceof GraphicalViewer) {
			Handle handle = ((GraphicalViewer) viewer).findHandleAt(p);
			if (handle != null) {
				setDragTracker(handle.getDragTracker());
				return true;
			}
		}
		updateTargetRequest();
		((SelectionRequest) getTargetRequest()).setLastButtonPressed(button);
		updateTargetUnderMouse();
		EditPart editpart = getTargetEditPart();
		if (editpart != null) {
			setDragTracker(editpart.getDragTracker(getTargetRequest()));
			lockTargetEditPart(editpart);
			return true;
		}
		return false;
	}

	/**
	 * Resets this tool when the last button is released.
	 * 
	 * @see AbstractTool#handleButtonUp(int)
	 */
	protected boolean handleButtonUp(int button) {
		if (getCurrentInput().isAnyButtonDown())
			return false;
		((SelectionRequest) getTargetRequest()).setLastButtonPressed(0);
		setDragTracker(null);
		setState(STATE_INITIAL);
		unlockTargetEditPart();
		return true;
	}

	/**
	 * @see AbstractTool#handleCommandStackChanged()
	 */
	protected boolean handleCommandStackChanged() {
		if (getDragTracker() == null)
			return super.handleCommandStackChanged();
		return false;
	}

	/**
	 * Sets the drag tracker to <code>null</code> and goes into the initial
	 * state when focus is lost.
	 * 
	 * @see AbstractTool#handleFocusLost()
	 */
	protected boolean handleFocusLost() {
		if (isInState(STATE_ACCESSIBLE_DRAG | STATE_ACCESSIBLE_DRAG_IN_PROGRESS
				| STATE_DRAG | STATE_DRAG_IN_PROGRESS)) {
			if (getDragTracker() != null)
				setDragTracker(null);
			setState(STATE_INITIAL);
			return true;
		}
		return false;
	}

	/**
	 * Called when the mouse hovers. Calls {@link #showHoverFeedback()}.
	 * 
	 * @see AbstractTool#handleHover()
	 */
	protected boolean handleHover() {
		setHoverActive(true);
		showHoverFeedback();
		return true;
	}

	/**
	 * Called when the mouse hover stops (i.e. the mouse moves or a button is
	 * clicked). Calls {@link #eraseHoverFeedback()}.
	 * 
	 * @see TargetingTool#handleHoverStop()
	 */
	protected boolean handleHoverStop() {
		eraseHoverFeedback();
		return true;
	}

	/**
	 * Processes key down events. Specifically, arrow keys for moving edit
	 * parts, the ESC key for aborting a drag, the period '.' key for traversing
	 * handles, and the ENTER key for committing a drag. If none of these keys
	 * were pressed and the current viewer has a {@link KeyHandler}, it calls
	 * {@link KeyHandler#keyPressed(KeyEvent)}.
	 * 
	 * @see AbstractTool#handleKeyDown(KeyEvent)
	 */
	protected boolean handleKeyDown(KeyEvent e) {
		resetHover();

		if (acceptArrowKey(e))
			if (stateTransition(STATE_ACCESSIBLE_DRAG,
					STATE_ACCESSIBLE_DRAG_IN_PROGRESS))
				return true;

		if (acceptAbort(e)) {
			if (getDragTracker() != null)
				setDragTracker(null);
			if (isInState(STATE_TRAVERSE_HANDLE | STATE_ACCESSIBLE_DRAG
					| STATE_ACCESSIBLE_DRAG_IN_PROGRESS))
				placeMouseInViewer(getStartLocation().getTranslated(6, 6));
			setState(STATE_INITIAL);
			setLastHandleProvider(null);
			return true;
		}

		if (acceptTraverseHandle(e)) {
			if (isInState(STATE_ACCESSIBLE_DRAG_IN_PROGRESS))
				if (getDragTracker() != null)
					getDragTracker().commitDrag();
			if (isInState(STATE_ACCESSIBLE_DRAG
					| STATE_ACCESSIBLE_DRAG_IN_PROGRESS)) {
				setDragTracker(null);
				getCurrentViewer().flush();
			}
			if (!handleTraverseHandle(e))
				setState(STATE_INITIAL);
			return true;
		}

		if (acceptDragCommit(e)) {
			if (getDragTracker() != null)
				getDragTracker().commitDrag();
			setDragTracker(null);
			setState(STATE_INITIAL);
			handleIndex--;
			placeMouseInViewer(getLocation().getTranslated(6, 6));
			return true;
		}

		if (isInState(STATE_INITIAL)) {
			if (getCurrentViewer().getKeyHandler() != null)
				return getCurrentViewer().getKeyHandler().keyPressed(e);
		}

		return false;
	}

	/**
	 * If in the initial state and the viewer has a {@link KeyHandler}, calls
	 * {@link KeyHandler#keyReleased(KeyEvent)} sending it the given key event.
	 * 
	 * @see AbstractTool#handleKeyUp(KeyEvent)
	 */
	protected boolean handleKeyUp(KeyEvent e) {
		if (isInState(STATE_INITIAL)
				&& getCurrentViewer().getKeyHandler() != null
				&& getCurrentViewer().getKeyHandler().keyReleased(e))
			return true;

		return false;
	}

	/**
	 * If in the initial state, updates the request and the mouse target and
	 * asks to show target feedback. If in the traverse handle state, finds the
	 * next handle, moves the mouse cursor to that handle, and gets a drag
	 * tracker from the handle.
	 * 
	 * @see AbstractTool#handleMove()
	 */
	protected boolean handleMove() {
		if (stateTransition(STATE_ACCESSIBLE_DRAG, STATE_INITIAL))
			setDragTracker(null);
		if (isInState(STATE_INITIAL)) {
			updateTargetRequest();
			updateTargetUnderMouse();
			showTargetFeedback();
			return true;
		} else if (isInState(STATE_TRAVERSE_HANDLE)) {
			EditPartViewer viewer = getCurrentViewer();
			if (viewer instanceof GraphicalViewer) {
				Handle handle = ((GraphicalViewer) viewer)
						.findHandleAt(getLocation());
				if (handle != null) {
					setState(STATE_ACCESSIBLE_DRAG);
					setStartLocation(getLocation());
					setDragTracker(handle.getDragTracker());
					return true;
				} else {
					setState(STATE_INITIAL);
				}
			}
		}
		return false;
	}

	/**
	 * If there's a drag tracker, calls handleNativeDragFinished() on the drag
	 * tracker and then sets the drag tracker to <code>null</code>.
	 * 
	 * @see AbstractTool#handleNativeDragFinished(DragSourceEvent)
	 */
	public boolean handleNativeDragFinished(DragSourceEvent event) {
		if (getDragTracker() != null)
			getDragTracker().nativeDragFinished(event, getCurrentViewer());
		setDragTracker(null);
		unlockTargetEditPart();
		return true;
	}

	/**
	 * If there's a drag tracker, calls nativeDragStarted() on the drag tracker.
	 * 
	 * @see AbstractTool#handleNativeDragStarted(DragSourceEvent)
	 */
	public boolean handleNativeDragStarted(DragSourceEvent event) {
		if (getDragTracker() != null)
			getDragTracker().nativeDragStarted(event, getCurrentViewer());
		setState(STATE_INITIAL);
		return true;
	}

	private boolean handleTraverseHandle(KeyEvent e) {
		EditPart focus = getCurrentViewer().getFocusEditPart();
		if (focus.getSelected() == EditPart.SELECTED_NONE)
			return false;
		getCurrentViewer().reveal(focus);

		AccessibleHandleProvider provider;
		provider = (AccessibleHandleProvider) focus
				.getAdapter(AccessibleHandleProvider.class);
		if (provider == null
				|| provider.getAccessibleHandleLocations().isEmpty())
			return false;

		/*
		 * At this point, a handle provider with 1 or more handles has been
		 * obtained
		 */
		setState(STATE_TRAVERSE_HANDLE);
		List locations = provider.getAccessibleHandleLocations();
		// Goto next index, wrapping if necessary
		if (e.character == '.')
			handleIndex = (++handleIndex) % locations.size();
		else
			handleIndex = (--handleIndex + locations.size()) % locations.size();
		if (getLastHandleProvider() != focus) {
			handleIndex = 0;
			setLastHandleProvider(focus);
		}

		Point loc = (Point) locations.get(handleIndex);
		Point current = new Point(getCurrentViewer().getControl().toControl(
				Display.getCurrent().getCursorLocation()));

		if (current.equals(loc)) {
			// The cursor is already at the location that it is to be moved to.
			// So, we
			// move to the next handle instead. If there are no more handles,
			// then we
			// cancel the drag.
			if (locations.size() > 1)
				if (e.character == '.')
					handleIndex = (++handleIndex) % locations.size();
				else
					handleIndex = (--handleIndex + locations.size())
							% locations.size();
			else {
				placeMouseInViewer(loc.getTranslated(6, 6));
				return false;
			}
		}
		placeMouseInViewer((Point) locations.get(handleIndex));
		return true;
	}

	/**
	 * If there's a drag tracker, sets it to <code>null</code> and then sets
	 * this tool's state to the initial state.
	 * 
	 * @see AbstractTool#handleViewerExited()
	 */
	protected boolean handleViewerExited() {
		if (isInState(STATE_ACCESSIBLE_DRAG | STATE_ACCESSIBLE_DRAG_IN_PROGRESS
				| STATE_TRAVERSE_HANDLE | STATE_DRAG | STATE_DRAG_IN_PROGRESS)) {
			if (getDragTracker() != null)
				setDragTracker(null);
			setState(STATE_INITIAL);
		}
		return super.handleViewerExited();
	}

	/**
	 * Forwards the key down event to the drag tracker, if one exists.
	 * 
	 * @see org.eclipse.gef.Tool#keyDown(KeyEvent,
	 *      org.eclipse.gef.EditPartViewer)
	 */
	public void keyDown(KeyEvent evt, EditPartViewer viewer) {
		if (getDragTracker() != null)
			getDragTracker().keyDown(evt, viewer);
		super.keyDown(evt, viewer);
	}

	/**
	 * Forwards the key up event to the drag tracker, if one exists.
	 * 
	 * @see org.eclipse.gef.Tool#keyUp(KeyEvent, org.eclipse.gef.EditPartViewer)
	 */
	public void keyUp(KeyEvent evt, EditPartViewer viewer) {
		if (getDragTracker() != null)
			getDragTracker().keyUp(evt, viewer);
		super.keyUp(evt, viewer);
	}

	/**
	 * Forwards the mouse down event to the drag tracker, if one exists.
	 * 
	 * @see org.eclipse.gef.Tool#mouseDown(MouseEvent,
	 *      org.eclipse.gef.EditPartViewer)
	 */
	public void mouseDown(MouseEvent e, EditPartViewer viewer) {
		super.mouseDown(e, viewer);
		if (getDragTracker() != null)
			getDragTracker().mouseDown(e, viewer);
	}

	/**
	 * Forwards the mouse double clicked event to the drag tracker, if one
	 * exists.
	 * 
	 * @see org.eclipse.gef.Tool#mouseDoubleClick(MouseEvent,
	 *      org.eclipse.gef.EditPartViewer)
	 */
	public void mouseDoubleClick(MouseEvent e, EditPartViewer viewer) {
		super.mouseDoubleClick(e, viewer);
		if (getDragTracker() != null)
			getDragTracker().mouseDoubleClick(e, viewer);
	}

	/**
	 * Forwards the mouse drag event to the drag tracker, if one exists.
	 * 
	 * @see org.eclipse.gef.Tool#mouseDrag(MouseEvent,
	 *      org.eclipse.gef.EditPartViewer)
	 */
	public void mouseDrag(MouseEvent e, EditPartViewer viewer) {
		if (getDragTracker() != null)
			getDragTracker().mouseDrag(e, viewer);
		super.mouseDrag(e, viewer);
	}

	/**
	 * Forwards the mouse hover event to the drag tracker, if one exists.
	 * 
	 * @see org.eclipse.gef.Tool#mouseHover(MouseEvent,
	 *      org.eclipse.gef.EditPartViewer)
	 */
	public void mouseHover(MouseEvent me, EditPartViewer viewer) {
		if (getDragTracker() != null)
			getDragTracker().mouseHover(me, viewer);
		super.mouseHover(me, viewer);
	}

	/**
	 * Forwards the mouse move event to the drag tracker, if one exists.
	 * 
	 * @see org.eclipse.gef.Tool#mouseMove(MouseEvent,
	 *      org.eclipse.gef.EditPartViewer)
	 */
	public void mouseMove(MouseEvent me, EditPartViewer viewer) {
		if (getDragTracker() != null)
			getDragTracker().mouseMove(me, viewer);
		super.mouseMove(me, viewer);
	}

	/**
	 * Forwards the mouse up event to the drag tracker, if one exists.
	 * 
	 * @see org.eclipse.gef.Tool#mouseUp(MouseEvent,
	 *      org.eclipse.gef.EditPartViewer)
	 */
	public void mouseUp(MouseEvent e, EditPartViewer viewer) {
		if (getDragTracker() != null)
			getDragTracker().mouseUp(e, viewer);
		super.mouseUp(e, viewer);
	}

	/**
	 * Delegates the scrolling to the DragTracker (if there is one). If not,
	 * invokes the super method.
	 * 
	 * @see org.eclipse.gef.Tool#mouseWheelScrolled(org.eclipse.swt.widgets.Event,
	 *      org.eclipse.gef.EditPartViewer)
	 */
	public void mouseWheelScrolled(Event event, EditPartViewer viewer) {
		if (getDragTracker() != null) {
			getDragTracker().mouseWheelScrolled(event, viewer);
			event.doit = false;
		} else
			super.mouseWheelScrolled(event, viewer);
	}

	/**
	 * If there is a drag tracker, this method does nothing so that the drag
	 * tracker can take care of the cursor. Otherwise, calls <code>super</code>.
	 * 
	 * @see AbstractTool#refreshCursor()
	 */
	protected void refreshCursor() {
		// If we have a DragTracker, let it control the Cursor
		if (getDragTracker() == null)
			super.refreshCursor();
	}

	/**
	 * Sets the drag tracker for this SelectionTool. If the current drag tracker
	 * is not <code>null</code>, this method deactivates it. If the new drag
	 * tracker is not <code>null</code>, this method will activate it and set
	 * the {@link EditDomain} and {@link EditPartViewer}.
	 * 
	 * @param newDragTracker
	 *            the new drag tracker
	 */
	public void setDragTracker(DragTracker newDragTracker) {
		if (newDragTracker == dragTracker)
			return;
		if (dragTracker != null)
			dragTracker.deactivate();
		dragTracker = newDragTracker;

		// if (!getCurrentInput().isMouseButtonDown(3))
		// setMouseCapture(dragTracker != null);
		if (newDragTracker != null) {
			newDragTracker.setEditDomain(getDomain());
			newDragTracker.activate();
			newDragTracker.setViewer(getCurrentViewer());
		}

		refreshCursor();
	}

	private void setLastHandleProvider(EditPart part) {
		if (part == null)
			cachedHandlePart = null;
		else
			cachedHandlePart = new WeakReference(part);
	}

	/**
	 * Asks the target edit part (if there is one) to show hover feedback via
	 * {@link EditPart#showTargetFeedback(Request)} with a hover request.
	 */
	protected void showHoverFeedback() {
		if (getTargetEditPart() == null)
			return;
		if (getTargetHoverRequest() == null)
			return;
		getTargetEditPart().showTargetFeedback(getTargetHoverRequest());
	}

	/**
	 * Updates the location of the hover request.
	 */
	protected void updateHoverRequest() {
		LocationRequest request = (LocationRequest) getTargetHoverRequest();
		request.setLocation(getLocation());
	}

	/**
	 * Sets the modifiers , type and location of the target request (which is a
	 * {@link SelectionRequest}) and then calls {@link #updateHoverRequest()}.
	 * 
	 * @see TargetingTool#updateTargetRequest()
	 */
	protected void updateTargetRequest() {
		SelectionRequest request = (SelectionRequest) getTargetRequest();
		request.setModifiers(getCurrentInput().getModifiers());
		request.setType(getCommandName());
		request.setLocation(getLocation());
		updateHoverRequest();
	}

	/**
	 * @see AbstractTool#getDebugNameForState(int)
	 */
	protected String getDebugNameForState(int state) {
		if (state == STATE_TRAVERSE_HANDLE)
			return "Traverse Handle"; //$NON-NLS-1$
		return super.getDebugNameForState(state);
	}

}
