/*******************************************************************************
 * 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.ui.parts;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.events.KeyEvent;

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

import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.KeyHandler;

/**
 * An extended KeyHandler which processes default keystrokes for common
 * navigation in a GraphicalViewer. This class can be used as a KeyHandler too;
 * Unrecognized keystrokes are sent to the super's implementation. This class
 * will process key events containing the following:
 * <UL>
 * <LI>Arrow Keys (UP, DOWN, LEFT, RIGHT) with optional SHIFT and CTRL modifiers
 * to navigate between siblings.
 * <LI>Arrow Keys (UP, DOWN) same as above, but with ALT modifier to navigate
 * into or out of a container.
 * <LI>'\'Backslash and '/' Slash keys with optional SHIFT and CTRL modifiers to
 * traverse connections.
 * </UL>
 * <P>
 * All processed key events will do nothing other than change the selection
 * and/or focus editpart for the viewer.
 * 
 * @author hudsonr
 */
public class GraphicalViewerKeyHandler extends KeyHandler {

	int counter;

	/**
	 * When navigating through connections, a "Node" EditPart is used as a
	 * reference.
	 */
	private WeakReference cachedNode;
	private GraphicalViewer viewer;

	/**
	 * Constructs a key handler for the given viewer.
	 * 
	 * @param viewer
	 *            the viewer
	 */
	public GraphicalViewerKeyHandler(GraphicalViewer viewer) {
		this.viewer = viewer;
	}

	/**
	 * @return <code>true</code> if key pressed indicates a connection
	 *         traversal/selection
	 */
	boolean acceptConnection(KeyEvent event) {
		return event.character == '/' || event.character == '?'
				|| event.character == '\\' || event.character == '\u001c'
				|| event.character == '|';
	}

	/**
	 * @return <code>true</code> if the keys pressed indicate to traverse inside
	 *         a container
	 */
	boolean acceptIntoContainer(KeyEvent event) {
		return ((event.stateMask & SWT.ALT) != 0)
				&& (event.keyCode == SWT.ARROW_DOWN);
	}

	/**
	 * @return <code>true</code> if the keys pressed indicate to stop
	 *         traversing/selecting connection
	 */
	boolean acceptLeaveConnection(KeyEvent event) {
		int key = event.keyCode;
		if (getFocusEditPart() instanceof ConnectionEditPart)
			if ((key == SWT.ARROW_UP) || (key == SWT.ARROW_RIGHT)
					|| (key == SWT.ARROW_DOWN) || (key == SWT.ARROW_LEFT))
				return true;
		return false;
	}

	/**
	 * @return <code>true</code> if the viewer's contents has focus and one of
	 *         the arrow keys is pressed
	 */
	boolean acceptLeaveContents(KeyEvent event) {
		int key = event.keyCode;
		return getFocusEditPart() == getViewer().getContents()
				&& ((key == SWT.ARROW_UP) || (key == SWT.ARROW_RIGHT)
						|| (key == SWT.ARROW_DOWN) || (key == SWT.ARROW_LEFT));
	}

	/**
	 * @return <code>true</code> if the keys pressed indicate to traverse to the
	 *         parent of the currently focused EditPart
	 */
	boolean acceptOutOf(KeyEvent event) {
		return ((event.stateMask & SWT.ALT) != 0)
				&& (event.keyCode == SWT.ARROW_UP);
	}

	boolean acceptScroll(KeyEvent event) {
		return ((event.stateMask & SWT.CTRL) != 0
				&& (event.stateMask & SWT.SHIFT) != 0 && (event.keyCode == SWT.ARROW_DOWN
				|| event.keyCode == SWT.ARROW_LEFT
				|| event.keyCode == SWT.ARROW_RIGHT || event.keyCode == SWT.ARROW_UP));
	}

	/**
	 * Given a connection on a node, this method finds the next (or the
	 * previous) connection of that node.
	 * 
	 * @param node
	 *            The EditPart whose connections are being traversed
	 * @param current
	 *            The connection relative to which the next connection has to be
	 *            found
	 * @param forward
	 *            <code>true</code> if the next connection has to be found;
	 *            false otherwise
	 */
	ConnectionEditPart findConnection(GraphicalEditPart node,
			ConnectionEditPart current, boolean forward) {
		List connections = new ArrayList(node.getSourceConnections());
		connections.addAll(node.getTargetConnections());
		connections = getValidNavigationTargets(connections);
		if (connections.isEmpty())
			return null;
		if (forward)
			counter++;
		else
			counter--;
		while (counter < 0)
			counter += connections.size();
		counter %= connections.size();
		return (ConnectionEditPart) connections.get(counter
				% connections.size());
	}

	private List getValidNavigationTargets(List candidateEditParts) {
		List validNavigationTargetEditParts = new ArrayList();
		for (int i = 0; i < candidateEditParts.size(); i++) {
			EditPart candidate = (EditPart) candidateEditParts.get(i);
			if (isValidNavigationTarget(candidate)) {
				validNavigationTargetEditParts.add(candidate);
			}
		}
		return validNavigationTargetEditParts;
	}

	/**
	 * Given an absolute point (pStart) and a list of EditParts, this method
	 * finds the closest EditPart (except for the one to be excluded) in the
	 * given direction.
	 * 
	 * @param siblings
	 *            List of sibling EditParts
	 * @param pStart
	 *            The starting point (must be in absolute coordinates) from
	 *            which the next sibling is to be found.
	 * @param direction
	 *            PositionConstants
	 * @param exclude
	 *            The EditPart to be excluded from the search
	 * 
	 */
	GraphicalEditPart findSibling(List siblings, Point pStart, int direction,
			EditPart exclude) {
		GraphicalEditPart epCurrent;
		GraphicalEditPart epFinal = null;
		IFigure figure;
		Point pCurrent;
		int distance = Integer.MAX_VALUE;

		Iterator iter = getValidNavigationTargets(siblings).iterator();
		while (iter.hasNext()) {
			epCurrent = (GraphicalEditPart) iter.next();
			if (epCurrent == exclude)
				continue;
			figure = epCurrent.getFigure();
			pCurrent = getNavigationPoint(figure);
			figure.translateToAbsolute(pCurrent);
			if (pStart.getPosition(pCurrent) != direction)
				continue;

			int d = pCurrent.getDistanceOrthogonal(pStart);
			if (d < distance) {
				distance = d;
				epFinal = epCurrent;
			}
		}
		return epFinal;
	}

	/**
	 * Figures' navigation points are used to determine their direction compared
	 * to one another, and the distance between them.
	 * 
	 * @return the center of the given figure
	 */
	Point getNavigationPoint(IFigure figure) {
		return figure.getBounds().getCenter();
	}

	/**
	 * Returns the cached node. It is possible that the node is not longer in
	 * the viewer but has not been garbage collected yet.
	 */
	private GraphicalEditPart getCachedNode() {
		if (cachedNode == null)
			return null;
		if (cachedNode.isEnqueued())
			return null;
		return (GraphicalEditPart) cachedNode.get();
	}

	/**
	 * @return the EditPart that has focus
	 */
	protected GraphicalEditPart getFocusEditPart() {
		return (GraphicalEditPart) getViewer().getFocusEditPart();
	}

	/**
	 * Returns the list of editparts which are conceptually at the same level of
	 * navigation as the currently focused editpart. By default, these are the
	 * siblings of the focused part.
	 * <p>
	 * This implementation returns a list that contains the EditPart that has
	 * focus.
	 * </p>
	 * 
	 * @return a list of navigation editparts
	 * @since 3.4
	 */
	protected List getNavigationSiblings() {
		EditPart focusPart = getFocusEditPart();
		if (focusPart.getParent() != null)
			return focusPart.getParent().getChildren();
		List list = new ArrayList();
		list.add(focusPart);
		return list;
	}

	/**
	 * Returns the viewer on which this key handler was created.
	 * 
	 * @return the viewer
	 */
	protected GraphicalViewer getViewer() {
		return viewer;
	}

	/**
	 * @return <code>true</code> if the viewer is mirrored
	 * @since 3.4
	 */
	protected boolean isViewerMirrored() {
		return (viewer.getControl().getStyle() & SWT.MIRRORED) != 0;
	}

	/**
	 * Extended to process key events described above.
	 * 
	 * @see org.eclipse.gef.KeyHandler#keyPressed(org.eclipse.swt.events.KeyEvent)
	 */
	public boolean keyPressed(KeyEvent event) {
		// if CTRL + SPACE is pressed, event.character == ' ' does not hold;
		// therefore using the keyCode to decide whether SPACE was pressed (with
		// or without modifiers).
		if (event.keyCode == 32) {
			processSelect(event);
			return true;
		} else if (acceptIntoContainer(event)) {
			navigateIntoContainer(event);
			return true;
		} else if (acceptOutOf(event)) {
			navigateOut(event);
			return true;
		} else if (acceptConnection(event)) {
			navigateConnections(event);
			return true;
		} else if (acceptScroll(event)) {
			scrollViewer(event);
			return true;
		} else if (acceptLeaveConnection(event)) {
			navigateOutOfConnection(event);
			return true;
		} else if (acceptLeaveContents(event)) {
			navigateIntoContainer(event);
			return true;
		}

		switch (event.keyCode) {
		case SWT.ARROW_LEFT:
			if (navigateNextSibling(event,
					isViewerMirrored() ? PositionConstants.EAST
							: PositionConstants.WEST))
				return true;
			break;
		case SWT.ARROW_RIGHT:
			if (navigateNextSibling(event,
					isViewerMirrored() ? PositionConstants.WEST
							: PositionConstants.EAST))
				return true;
			break;
		case SWT.ARROW_UP:
			if (navigateNextSibling(event, PositionConstants.NORTH))
				return true;
			break;
		case SWT.ARROW_DOWN:
			if (navigateNextSibling(event, PositionConstants.SOUTH))
				return true;
			break;

		case SWT.HOME:
			if (navigateJumpSibling(event, PositionConstants.WEST))
				return true;
			break;
		case SWT.END:
			if (navigateJumpSibling(event, PositionConstants.EAST))
				return true;
			break;
		case SWT.PAGE_DOWN:
			if (navigateJumpSibling(event, PositionConstants.SOUTH))
				return true;
			break;
		case SWT.PAGE_UP:
			if (navigateJumpSibling(event, PositionConstants.NORTH))
				return true;
		}
		return super.keyPressed(event);
	}

	/**
	 * This method navigates through connections based on the keys pressed.
	 */
	void navigateConnections(KeyEvent event) {
		GraphicalEditPart focus = getFocusEditPart();
		ConnectionEditPart current = null;
		GraphicalEditPart node = getCachedNode();
		if (focus instanceof ConnectionEditPart) {
			current = (ConnectionEditPart) focus;
			if (node == null
					|| (node != current.getSource() && node != current
							.getTarget())) {
				node = (GraphicalEditPart) current.getSource();
				counter = 0;
			}
		} else {
			node = focus;
		}

		setCachedNode(node);
		boolean forward = event.character == '/' || event.character == '?';
		ConnectionEditPart next = findConnection(node, current, forward);
		navigateTo(next, event);
	}

	private boolean isValidNavigationTarget(EditPart editPart) {
		return editPart.isSelectable();
	}

	/**
	 * This method traverses to the closest child of the currently focused
	 * EditPart, if it has one.
	 */
	void navigateIntoContainer(KeyEvent event) {
		GraphicalEditPart focus = getFocusEditPart();
		List childList = getValidNavigationTargets(focus.getChildren());
		Point tl = focus.getContentPane().getBounds().getTopLeft();

		int minimum = Integer.MAX_VALUE;
		int current;
		GraphicalEditPart closestPart = null;

		for (int i = 0; i < childList.size(); i++) {
			GraphicalEditPart child = (GraphicalEditPart) childList.get(i);

			Rectangle childBounds = child.getFigure().getBounds();
			current = (childBounds.x - tl.x) + (childBounds.y - tl.y);
			if (current < minimum) {
				minimum = current;
				closestPart = child;
			}
		}
		if (closestPart != null)
			navigateTo(closestPart, event);
	}

	/**
	 * Not yet implemented.
	 */
	boolean navigateJumpSibling(KeyEvent event, int direction) {
		// TODO: Implement navigateJumpSibling() (for PGUP, PGDN, HOME and END
		// key events)
		return false;
	}

	/**
	 * Traverses to the next sibling in the given direction.
	 * 
	 * @param event
	 *            the KeyEvent for the keys that were pressed to trigger this
	 *            traversal
	 * @param direction
	 *            PositionConstants.* indicating the direction in which to
	 *            traverse
	 */
	boolean navigateNextSibling(KeyEvent event, int direction) {
		return navigateNextSibling(event, direction, getNavigationSiblings());
	}

	/**
	 * Traverses to the closest EditPart in the given list that is also in the
	 * given direction.
	 * 
	 * @param event
	 *            the KeyEvent for the keys that were pressed to trigger this
	 *            traversal
	 * @param direction
	 *            PositionConstants.* indicating the direction in which to
	 *            traverse
	 */
	boolean navigateNextSibling(KeyEvent event, int direction, List list) {
		GraphicalEditPart epStart = getFocusEditPart();
		IFigure figure = epStart.getFigure();
		Point pStart = getNavigationPoint(figure);
		figure.translateToAbsolute(pStart);
		EditPart next = findSibling(list, pStart, direction, epStart);
		if (next == null)
			return false;
		navigateTo(next, event);
		return true;
	}

	/**
	 * Navigates to the parent of the currently focused EditPart.
	 */
	void navigateOut(KeyEvent event) {
		if (getFocusEditPart() == null
				|| getFocusEditPart() == getViewer().getContents())
			return;

		EditPart editPart = getFocusEditPart().getParent();
		while (editPart != null && editPart != getViewer().getContents()
				&& !isValidNavigationTarget(editPart)) {
			editPart = editPart.getParent();
		}

		if (editPart != null && isValidNavigationTarget(editPart)) {
			navigateTo(editPart, event);
		}
	}

	/**
	 * Navigates to the source or target of the currently focused
	 * ConnectionEditPart.
	 */
	void navigateOutOfConnection(KeyEvent event) {
		GraphicalEditPart cached = getCachedNode();
		ConnectionEditPart conn = (ConnectionEditPart) getFocusEditPart();
		if (cached != null
				&& (cached == conn.getSource() || cached == conn.getTarget()))
			navigateTo(cached, event);
		else
			navigateTo(conn.getSource(), event);
	}

	/**
	 * Navigates to the given EditPart
	 * 
	 * @param part
	 *            the EditPart to navigate to
	 * @param event
	 *            the KeyEvent that triggered this traversal
	 */
	protected void navigateTo(EditPart part, KeyEvent event) {
		if (part == null)
			return;
		if ((event.stateMask & SWT.SHIFT) != 0) {
			getViewer().appendSelection(part);
			getViewer().setFocus(part);
		} else if ((event.stateMask & SWT.CONTROL) != 0)
			getViewer().setFocus(part);
		else
			getViewer().select(part);
		getViewer().reveal(part);
	}

	/**
	 * This method is invoked when the user presses the space bar. It toggles
	 * the selection of the EditPart that currently has focus.
	 * 
	 * @param event
	 *            the key event received
	 */
	protected void processSelect(KeyEvent event) {
		EditPart part = getViewer().getFocusEditPart();
		if (part != getViewer().getContents()) {
			if ((event.stateMask & SWT.CTRL) != 0
					&& part.getSelected() != EditPart.SELECTED_NONE)
				getViewer().deselect(part);
			else
				getViewer().appendSelection(part);

			getViewer().setFocus(part);
		}
	}

	void scrollViewer(KeyEvent event) {
		if (!(getViewer().getControl() instanceof FigureCanvas))
			return;
		FigureCanvas figCanvas = (FigureCanvas) getViewer().getControl();
		Point loc = figCanvas.getViewport().getViewLocation();
		Rectangle area = figCanvas.getViewport()
				.getClientArea(Rectangle.SINGLETON).scale(.1);
		switch (event.keyCode) {
		case SWT.ARROW_DOWN:
			figCanvas.scrollToY(loc.y + area.height);
			break;
		case SWT.ARROW_UP:
			figCanvas.scrollToY(loc.y - area.height);
			break;
		case SWT.ARROW_LEFT:
			if (isViewerMirrored())
				figCanvas.scrollToX(loc.x + area.width);
			else
				figCanvas.scrollToX(loc.x - area.width);
			break;
		case SWT.ARROW_RIGHT:
			if (isViewerMirrored())
				figCanvas.scrollToX(loc.x - area.width);
			else
				figCanvas.scrollToX(loc.x + area.width);
		}
	}

	private void setCachedNode(GraphicalEditPart node) {
		if (node == null)
			cachedNode = null;
		else
			cachedNode = new WeakReference(node);
	}

}
