/*******************************************************************************
 * 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.util.ArrayList;
import java.util.Collection;
import java.util.List;

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

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

import org.eclipse.gef.AccessibleAnchorProvider;
import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.SharedCursors;
import org.eclipse.gef.Tool;
import org.eclipse.gef.requests.ReconnectRequest;

/**
 * A DragTracker that moves the endpoint of a connection to another location.
 */
public class ConnectionEndpointTracker extends TargetingTool implements
		DragTracker {

	private static final int FLAG_SOURCE_FEEBBACK = TargetingTool.MAX_FLAG << 1;
	/** The max flag */
	protected static final int MAX_FLAG = FLAG_SOURCE_FEEBBACK;

	private String commandName;
	private List exclusionSet;

	private ConnectionEditPart connectionEditPart;

	/**
	 * Constructs a new ConnectionEndpointTracker for the given
	 * ConnectionEditPart.
	 * 
	 * @param cep
	 *            the ConnectionEditPart
	 */
	public ConnectionEndpointTracker(ConnectionEditPart cep) {
		setConnectionEditPart(cep);
		setDisabledCursor(SharedCursors.NO);
	}

	/**
	 * Returns a custom "plug" cursor if this tool is in the initial, drag or
	 * accessible drag state. Otherwise defers to <code>super</code>.
	 * 
	 * @return the cursor
	 */
	protected Cursor calculateCursor() {
		if (isInState(STATE_INITIAL | STATE_DRAG | STATE_ACCESSIBLE_DRAG))
			return getDefaultCursor();
		return super.calculateCursor();
	}

	/**
	 * Erases source and target feedback and executes the current command.
	 * 
	 * @see DragTracker#commitDrag()
	 */
	public void commitDrag() {
		eraseSourceFeedback();
		eraseTargetFeedback();
		executeCurrentCommand();
	}

	/**
	 * Creates the target request, a {@link ReconnectRequest}.
	 * 
	 * @return the target request
	 */
	protected Request createTargetRequest() {
		ReconnectRequest request = new ReconnectRequest(getCommandName());
		request.setConnectionEditPart(getConnectionEditPart());
		return request;
	}

	/**
	 * Erases feedback and sets the viewer's focus to <code>null</code>. This
	 * will remove any focus rectangles that were painted to show the new target
	 * or source edit part.
	 * 
	 * @see Tool#deactivate()
	 */
	public void deactivate() {
		eraseSourceFeedback();
		getCurrentViewer().setFocus(null);
		super.deactivate();
	}

	/**
	 * Erases the source feedback.
	 */
	protected void eraseSourceFeedback() {
		if (!getFlag(FLAG_SOURCE_FEEBBACK))
			return;
		setFlag(FLAG_SOURCE_FEEBBACK, false);
		getConnectionEditPart().eraseSourceFeedback(getTargetRequest());
	}

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

	/**
	 * Returns the ConnectionEditPart's figure.
	 * 
	 * @return the connection
	 */
	protected Connection getConnection() {
		return (Connection) getConnectionEditPart().getFigure();
	}

	/**
	 * Returns the ConnectionEditPart.
	 * 
	 * @return the ConnectionEditPart
	 */
	protected ConnectionEditPart getConnectionEditPart() {
		return connectionEditPart;
	}

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

	/**
	 * @see org.eclipse.gef.tools.TargetingTool#getExclusionSet()
	 */
	protected Collection getExclusionSet() {
		if (exclusionSet == null) {
			exclusionSet = new ArrayList();
			exclusionSet.add(getConnection());
		}
		return exclusionSet;
	}

	/**
	 * If currently in the drag-in-progress state, it goes into the terminal
	 * state erases feedback and executes the current command.
	 * 
	 * @see org.eclipse.gef.tools.AbstractTool#handleButtonUp(int)
	 */
	protected boolean handleButtonUp(int button) {
		if (stateTransition(STATE_DRAG_IN_PROGRESS, STATE_TERMINAL)) {
			eraseSourceFeedback();
			eraseTargetFeedback();
			executeCurrentCommand();
		}
		return true;
	}

	/**
	 * Updates the request and the mouse target, asks to show feedback, and gets
	 * the current command.
	 * 
	 * @return <code>true</code>
	 */
	protected boolean handleDragInProgress() {
		updateTargetRequest();
		updateTargetUnderMouse();
		showSourceFeedback();
		showTargetFeedback();
		setCurrentCommand(getCommand());
		return true;
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#handleDragStarted()
	 */
	protected boolean handleDragStarted() {
		stateTransition(STATE_INITIAL, STATE_DRAG_IN_PROGRESS);
		return false;
	}

	/**
	 * @see org.eclipse.gef.tools.TargetingTool#handleHover()
	 */
	protected boolean handleHover() {
		if (isInDragInProgress())
			updateAutoexposeHelper();
		return true;
	}

	/**
	 * Processes the arrow keys (to choose a different source or target edit
	 * part) and forwardslash and backslash keys (to try to connect to another
	 * connection).
	 * 
	 * @see org.eclipse.gef.tools.AbstractTool#handleKeyDown(org.eclipse.swt.events.KeyEvent)
	 */
	protected boolean handleKeyDown(KeyEvent e) {
		if (acceptArrowKey(e)) {
			if (stateTransition(STATE_INITIAL,
					STATE_ACCESSIBLE_DRAG_IN_PROGRESS)) {
				// When the drag first starts, set the focus Part to be one end
				// of the connection
				if (isTarget()) {
					getCurrentViewer().setFocus(
							getConnectionEditPart().getTarget());
					getCurrentViewer().reveal(
							getConnectionEditPart().getTarget());
				} else {
					getCurrentViewer().setFocus(
							getConnectionEditPart().getSource());
					getCurrentViewer().reveal(
							getConnectionEditPart().getSource());
				}
			}
			int direction = 0;
			switch (e.keyCode) {
			case SWT.ARROW_DOWN:
				direction = PositionConstants.SOUTH;
				break;
			case SWT.ARROW_UP:
				direction = PositionConstants.NORTH;
				break;
			case SWT.ARROW_RIGHT:
				direction = isCurrentViewerMirrored() ? PositionConstants.WEST
						: PositionConstants.EAST;
				break;
			case SWT.ARROW_LEFT:
				direction = isCurrentViewerMirrored() ? PositionConstants.EAST
						: PositionConstants.WEST;
				break;
			}

			boolean consumed = false;
			if (direction != 0 && e.stateMask == 0)
				consumed = navigateNextAnchor(direction);
			if (!consumed) {
				e.stateMask |= SWT.CONTROL;
				e.stateMask &= ~SWT.SHIFT;
				if (getCurrentViewer().getKeyHandler().keyPressed(e)) {
					navigateNextAnchor(0);
					return true;
				}
			}
		}
		if (e.character == '/' || e.character == '\\') {
			e.stateMask |= SWT.CONTROL;
			if (getCurrentViewer().getKeyHandler().keyPressed(e)) {
				// Do not try to connect to the same connection being dragged.
				if (getCurrentViewer().getFocusEditPart() != getConnectionEditPart())
					navigateNextAnchor(0);
				return true;
			}
		}

		return false;
	}

	private boolean isTarget() {
		return getCommandName() == RequestConstants.REQ_RECONNECT_TARGET;
	}

	boolean navigateNextAnchor(int direction) {
		EditPart focus = getCurrentViewer().getFocusEditPart();
		AccessibleAnchorProvider provider;
		provider = (AccessibleAnchorProvider) focus
				.getAdapter(AccessibleAnchorProvider.class);
		if (provider == null)
			return false;

		List list;
		if (isTarget())
			list = provider.getTargetAnchorLocations();
		else
			list = provider.getSourceAnchorLocations();

		Point start = getLocation();
		int distance = Integer.MAX_VALUE;
		Point next = null;
		for (int i = 0; i < list.size(); i++) {
			Point p = (Point) list.get(i);
			if (p.equals(start)
					|| (direction != 0 && (start.getPosition(p) != direction)))
				continue;
			int d = p.getDistanceOrthogonal(start);
			if (d < distance) {
				distance = d;
				next = p;
			}
		}

		if (next != null) {
			placeMouseInViewer(next);
			return true;
		}
		return false;
	}

	/**
	 * Sets the command name.
	 * 
	 * @param newCommandName
	 *            the new command name
	 */
	public void setCommandName(String newCommandName) {
		commandName = newCommandName;
	}

	/**
	 * Sets the connection edit part that is being reconnected.
	 * 
	 * @param cep
	 *            the connection edit part
	 */
	public void setConnectionEditPart(ConnectionEditPart cep) {
		this.connectionEditPart = cep;
	}

	/**
	 * Asks the ConnectionEditPart to show source feedback.
	 */
	protected void showSourceFeedback() {
		getConnectionEditPart().showSourceFeedback(getTargetRequest());
		setFlag(FLAG_SOURCE_FEEBBACK, true);
	}

	/**
	 * Updates the request location.
	 * 
	 * @see org.eclipse.gef.tools.TargetingTool#updateTargetRequest()
	 */
	protected void updateTargetRequest() {
		ReconnectRequest request = (ReconnectRequest) getTargetRequest();
		Point p = getLocation();
		request.setLocation(p);
	}

}