/******************************************************************************
 * Copyright (c) 2000, 2009  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.gmf.runtime.diagram.ui.internal.parts;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.Viewport;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.RootEditPart;
import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;

/**
 * @author melaasar
 * <p>
 * Code taken from Eclipse reference bugzilla #98820
 *
 */
public class DiagramGraphicalViewerKeyHandler
	extends GraphicalViewerKeyHandler {

	/**
	 * @param viewer
	 */
	public DiagramGraphicalViewerKeyHandler(GraphicalViewer viewer) {
		super(viewer);
	}

	/**
	 * @see org.eclipse.gef.KeyHandler#keyPressed(org.eclipse.swt.events.KeyEvent)
	 */
	public boolean keyPressed(KeyEvent event) {
		switch (event.keyCode) {
			case SWT.HOME :
				if ((event.stateMask & SWT.ALT) != 0) {
					if (navigateEndSibling(event, PositionConstants.WEST))
						return true;
				} else {
					if (navigateEndSibling(event, PositionConstants.NORTH))
						return true;
				}
                break;
			case SWT.END :
				if ((event.stateMask & SWT.ALT) != 0) {
					if (navigateEndSibling(event, PositionConstants.EAST))
						return true;
				} else {
					if (navigateEndSibling(event, PositionConstants.SOUTH))
						return true;
				}
                break;
			case SWT.PAGE_UP :
				if ((event.stateMask & SWT.ALT) != 0) {
					if (navigatePageSibling(event, PositionConstants.WEST))
						return true;
				} else {
					if (navigatePageSibling(event, PositionConstants.NORTH))
						return true;
				}
                break;
			case SWT.PAGE_DOWN :
				if ((event.stateMask & SWT.ALT) != 0) {
					if (navigatePageSibling(event, PositionConstants.EAST))
						return true;
				} else {
					if (navigatePageSibling(event, PositionConstants.SOUTH))
						return true;
				}
				break;
	        case SWT.TAB:
	            if ((event.stateMask & SWT.SHIFT) != 0) {
                    if (navigateNextHorizontalSibling(isViewerMirrored() ? PositionConstants.EAST
                        : PositionConstants.WEST)) {
                        return true;
                    }
                } else {
                    if (navigateNextHorizontalSibling(isViewerMirrored() ? PositionConstants.WEST
                        : PositionConstants.EAST)) {
                        return true;
                    }
                }
                break;
		}
		return super.keyPressed(event);
	}

	/**
	 * @return
	 */
	protected GraphicalEditPart getFocusPart() {
		return (GraphicalEditPart) getViewer().getFocusEditPart();
	}

	/**
	 * @param part
	 * @param event
	 */
	protected void navigateToPart(EditPart part, KeyEvent event) {
		if (part == null)
			return;
		if (!part.isSelectable()) {
			getViewer().deselectAll();
			getViewer().setFocus(part);
		} else 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);
	}

	/**
	 * @return
	 */
	protected List getPartNavigationSiblings() {
        EditPart epParent = findParent(getFocusPart());
        if (epParent != null)
            return epParent.getChildren();
        else
            return null;
	}

	/**
	 * @param figure
	 * @return
	 */
	protected Point getFigureInterestingPoint(IFigure figure) {
		return figure.getBounds().getCenter();
	}

	protected Viewport findViewport(GraphicalEditPart part) {
        if (part == null) 
            return null;
        
		IFigure figure = null;
		Viewport port = null;
		do {
			if (figure == null)
				figure = part.getContentPane();
			else
				figure = figure.getParent();
			if (figure instanceof Viewport) {
				port = (Viewport) figure;
				break;
			}
		} while (figure != null);
		return port;
	}

	/**
	 * @param event
	 * @param direction
	 * @param page
	 * @param list
	 * @return
	 */
	protected boolean navigatePageSibling(KeyEvent event, int direction) {
		GraphicalEditPart epStart = getFocusPart();
		IFigure figure = epStart.getFigure();
		Point pStart = getFigureInterestingPoint(figure);
		figure.translateToAbsolute(pStart);

		GraphicalEditPart epParent = (GraphicalEditPart) findParent(epStart);
		Viewport viewport = findViewport(epParent);
		Rectangle bounds =
			(viewport != null)
				? new Rectangle(viewport.getBounds())
				: epParent.getFigure().getClientArea();
		int pageDistance = 0;
		switch (direction) {
			case PositionConstants.NORTH :
			case PositionConstants.SOUTH :
				pageDistance = bounds.height;
				break;
			case PositionConstants.EAST :
			case PositionConstants.WEST :
				pageDistance = bounds.width;
				break;
		}
		
	    if (epStart instanceof DiagramEditPart) {
	        Point location = viewport.getViewLocation().getCopy();
	        switch (direction) {
	            case PositionConstants.NORTH :
	                location.translate(0, -pageDistance);
	                break;              
	            case PositionConstants.SOUTH :
	                location.translate(0, pageDistance);
	                break;
	            case PositionConstants.EAST :
	                location.translate(pageDistance, 0);
	                break;
	            case PositionConstants.WEST :
                    location.translate(-pageDistance, 0);
	                break;
	        }
	        viewport.setViewLocation(location);
        }

		List<GraphicalEditPart> editParts =
			findPageSibling(
				getPartNavigationSiblings(),
				pStart,
				pageDistance,
				direction,
				epStart);
		if (editParts.isEmpty())
			return false;
		if ((event.stateMask & SWT.SHIFT) != 0) {
			Iterator<GraphicalEditPart> parts = editParts.iterator();
			while (parts.hasNext())
				navigateToPart(parts.next(), event);
		} else {
			EditPart part = editParts.get(editParts.size() - 1);
			navigateToPart(part, event);
		}
		return true;
	}

	/**
	 * @param event
	 * @param direction
	 * @param list
	 * @return
	 */
	protected boolean navigateEndSibling(KeyEvent event, int direction) {
		GraphicalEditPart epStart = getFocusPart();
		
		// go to top-left or bottom-right corner if nothing is selected
		if (epStart instanceof DiagramEditPart) {
            Viewport viewport = findViewport(epStart);
            switch (direction) {
                case PositionConstants.NORTH:
                case PositionConstants.WEST:
                    viewport.setViewLocation(viewport.getHorizontalRangeModel()
                        .getMinimum(), viewport.getVerticalRangeModel()
                        .getMinimum());
                    break;
                case PositionConstants.SOUTH:
                case PositionConstants.EAST:
                    viewport.setViewLocation(viewport.getHorizontalRangeModel()
                        .getMaximum(), viewport.getVerticalRangeModel()
                        .getMaximum());
                    break;
            }
        }
		
		IFigure figure = epStart.getFigure();
		Point pStart = getFigureInterestingPoint(figure);
		figure.translateToAbsolute(pStart);
		List<GraphicalEditPart> editParts =
			findEndSibling(
				getPartNavigationSiblings(),
				pStart,
				direction,
				epStart);
		if (editParts.isEmpty())
			return false;
		if ((event.stateMask & SWT.SHIFT) != 0) {
			Iterator<GraphicalEditPart> parts = editParts.iterator();
			while (parts.hasNext())
				navigateToPart(parts.next(), event);
		} else {
			EditPart part = editParts.get(editParts.size() - 1);
			navigateToPart(part, event);
		}
		return true;
	}

	/**
	 * @param siblings
	 * @param pStart
	 * @param minDistance
	 * @param direction
	 * @param exclude
	 * @return
	 */
	private List<GraphicalEditPart> findPageSibling(
		List siblings,
		Point pStart,
		int pageDistance,
		int direction,
		EditPart exclude) {
	    
		GraphicalEditPart epCurrent;
		GraphicalEditPart epFinal = null;
		GraphicalEditPart epFurthest = null;  // in case there is not a full pageDistance left to scroll
		List<GraphicalEditPart> selection = new ArrayList<GraphicalEditPart>();
		IFigure figure;
		Point pCurrent;
		int distance = Integer.MAX_VALUE;
		int furthestDistance = 0;

		Iterator iter = siblings.iterator();
		while (iter.hasNext()) {
			epCurrent = (GraphicalEditPart) iter.next();
			if (epCurrent == exclude
				|| !epCurrent.getFigure().isVisible()
				|| epCurrent.getFigure().getBounds().isEmpty())
				continue;
			figure = epCurrent.getFigure();
			pCurrent = getFigureInterestingPoint(figure);
			figure.translateToAbsolute(pCurrent);
			if (!isInDirection(direction, pStart, pCurrent))
				continue;

			int d = pCurrent.getDistanceOrthogonal(pStart);
			if (d >= pageDistance) {
				selection.add(epCurrent);
				if (d < distance) {
					distance = d;
					epFinal = epCurrent;
				}
			}
			if (d > furthestDistance) {
			    epFurthest = epCurrent;
			}
			if (epFinal != null) {
				selection.remove(epFinal);
				selection.add(epFinal);
			}
		}
		if (selection.isEmpty() && epFurthest != null) {
		    return Collections.singletonList(epFurthest);
		}
		return selection;
	}

	/**
	 * @param siblings
	 * @param pStart
	 * @param direction
	 * @param exclude
	 * @return
	 */
	private List<GraphicalEditPart> findEndSibling(
		List siblings,
		Point pStart,
		int direction,
		EditPart exclude) {
		GraphicalEditPart epCurrent;
		GraphicalEditPart epFinal = null;
		List<GraphicalEditPart> selection = new ArrayList<GraphicalEditPart>();
		IFigure figure;
		Point pCurrent;
		int distance = 0;

		Iterator iter = siblings.iterator();
		while (iter.hasNext()) {
			epCurrent = (GraphicalEditPart) iter.next();
			if (epCurrent == exclude
				|| !epCurrent.getFigure().isVisible()
				|| epCurrent.getFigure().getBounds().isEmpty())
				continue;
			figure = epCurrent.getFigure();
			pCurrent = getFigureInterestingPoint(figure);
			figure.translateToAbsolute(pCurrent);
			if (!isInDirection(direction, pStart, pCurrent))
				continue;

			selection.add(epCurrent);
			int d = pCurrent.getDistanceOrthogonal(pStart);
			if (d > distance) {
				distance = d;
				epFinal = epCurrent;
			}
		}
		if (epFinal != null) {
			selection.remove(epFinal);
			selection.add(epFinal);
		}
		return selection;
	}
    
    
    /**
     * @param child
     * @return EditPart
     */
    private EditPart findParent(EditPart child) {
        //check to see if we are not looking for a parent on RootEditPart, 
        //as it does not have a parent.
        if (child instanceof RootEditPart)
            return child;
        else
            return child.getParent(); //any other EditPart    
    }

    /**
     * Traverses to the closest EditPart in the given list that is also in the
     * given direction (EAST or WEST). The x-location alone is used to determine
     * the closest sibling. If the direction is EAST and there are no EditParts
     * to the EAST then the farthest WEST EditPart is returned (and vice versa).
     * This allows the user to cycle through all the EditParts using the TAB
     * key.
     * 
     * @param direction
     *            the direction in which to navigate (either
     *            PositionConstants.WEST or PositionConstants.EAST)
     * @return true if a sibling was found to navigate to; false otherwise.
     */
    private boolean navigateNextHorizontalSibling(int direction) {
        GraphicalEditPart epStart = getFocusEditPart();
        EditPart next = null;
        if (epStart instanceof DiagramEditPart) {
            next = findClosestHorizontalSibling(epStart.getChildren(),
                new Point(0, 0), PositionConstants.EAST, null);
        } else {
            IFigure figure = epStart.getFigure();
            Point pStart = figure.getBounds().getCenter();
            figure.translateToAbsolute(pStart);
            next = findClosestHorizontalSibling(getNavigationSiblings(),
                pStart, direction, epStart);
        }
        if (next == null)
            return false;

        getViewer().select(next);
        getViewer().reveal(next);
        return true;
    }

	/**
	 * 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 (EAST or WEST). The x-location is used to determine the
	 * closest sibling. Also, if going EAST and there is vertically aligned
	 * figure underneath pStart, then that figure is the result. If going WEST
	 * and there is a figure above pStartm then that figure is the result.If the
	 * direction is EAST and there are no EditParts to the EAST and SOUTH then
	 * the farthest WEST EditPart is returned (and vice versa). This allows the
	 * user to cycle through all the EditParts using the TAB key.
	 * 
	 * @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.EAST or PositionConstants.WEST
	 * @param exclude
	 *            The EditPart to be excluded from the search
	 */
    private GraphicalEditPart findClosestHorizontalSibling(List siblings,
            Point pStart, int direction, EditPart exclude) {
        GraphicalEditPart epCurrent;
        GraphicalEditPart epFinal = null;
        GraphicalEditPart epCycle = null; // in case there are no more shapes in this direction
        GraphicalEditPart epCycleVertical = null; // in case there are no more shapes in EAST or WEST direction
        
        IFigure figure;
        Point pCurrent;
        int distanceX = Integer.MAX_VALUE;
        int distanceY = Integer.MAX_VALUE;
        int finalY = 0;
        boolean goVertical = false;
        int xCycle = direction == PositionConstants.EAST ? Integer.MAX_VALUE : 0;
        int yCycle = xCycle;
        int yCycleVertical = xCycle;

        Iterator iter = siblings.iterator();
        while (iter.hasNext()) {
            epCurrent = (GraphicalEditPart) iter.next();
            if (epCurrent == exclude || !epCurrent.isSelectable())
                continue;
            figure = epCurrent.getFigure();
            pCurrent = figure.getBounds().getCenter();
            figure.translateToAbsolute(pCurrent);

            int dx = pCurrent.x - pStart.x;

            if (!goVertical && 
            		((direction == PositionConstants.EAST && dx > 0)
            				|| (direction == PositionConstants.WEST && dx < 0))) {
                int abs_dx = Math.abs(dx);
                if (abs_dx < distanceX) {
                    distanceX = abs_dx;
                    finalY = pCurrent.y;
                    epFinal = epCurrent;
                } else if (abs_dx == distanceX) {
                	// There are vertically aligned figures that could be horizontally closest to the current figure.
                	// If we go east, choose the top one, if we go west, choose the bottom one.
                	// finalY is always assigned in this case
                	if ((direction == PositionConstants.EAST && pCurrent.y < finalY) || 
                			(direction == PositionConstants.WEST && pCurrent.y > finalY))	{
                        finalY = pCurrent.y;
                        epFinal = epCurrent;
                	}
                }
            }
            if (dx == 0) {
            	// Once we find a figure that is vertically aligned with the current, we have to go vertically
            	// (to this or closest figure vertically aligned) since there will be no other chance to traverse it.
            	// The exception: we reached the far east end while going east, or far west end while going west.            	
            	int dy = pCurrent.y - pStart.y;
                if ((direction == PositionConstants.EAST && dy > 0)
                        || (direction == PositionConstants.WEST && dy < 0)) {
                	goVertical = true;
                	int abs_dy = Math.abs(dy);                	
                    if (abs_dy < distanceY) {
                    	distanceY = abs_dy;
                    	epFinal = epCurrent;
                    }                    
            	}
            }
        	// Consider the case when we need to go east (south) or west (north) and the current figure is on the 
        	// far east (south) or west (north) end, respectively.
            if (epFinal == null) {
            	if (dx == 0) {
            		// Case when the figure is at the end and there is one or more vertically aligned figure.
            		// This will be the result only if there are no figures to the left or right.
                    if (direction == PositionConstants.EAST && pCurrent.y < yCycleVertical) {
                    	yCycleVertical = pCurrent.y;
                        epCycleVertical = epCurrent;
                    } else if (direction == PositionConstants.WEST && pCurrent.y > yCycleVertical) {
                    	yCycleVertical = pCurrent.y;
                        epCycleVertical = epCurrent;
                    }            		
            	} else {
            		boolean assign = false;
	                if (direction == PositionConstants.EAST) {
	                	if (pCurrent.x < xCycle) {
	                		assign = true;
	                	} else if (pCurrent.x == xCycle) {
	                		// Current figure is vertically aligned with the possible result figure.
	                		// Choose the top figure.
	                		if (pCurrent.y < yCycle) {
	                			assign = true;
	                		}
	                	}
	                } else if (direction == PositionConstants.WEST) {
	                	if (pCurrent.x > xCycle) {	                
	                		assign = true;
	                	} else if (pCurrent.x == xCycle) {
	                		// Current figure is vertically aligned with the possible result figure.
	                		// Choose the top figure.
	                		if (pCurrent.y > yCycle) {
	                			assign = true;
	                		}
	                	}
	                }
	                if (assign) {
                		xCycle = pCurrent.x;
                		yCycle = pCurrent.y;
                		epCycle = epCurrent;
	                }
            	}
            }
        }
        if (epFinal == null) {
        	if (epCycle == null) {
        		return epCycleVertical;
        	} else {
        		return epCycle;
        	}
        }
        return epFinal;
    }

    /**
     * Returns true if the point in question is in the given direction from the
     * starting point.
     * 
     * @param direction
     *            the direction
     * @param start
     *            the starting point
     * @param point
     *            the point in question
     * @return true if the point in question is in the given direction from the
     *         starting point; false otherwise
     */
    private boolean isInDirection(int direction, Point start, Point point) {
        switch (direction) {
            case PositionConstants.WEST:
                return start.x > point.x;
            case PositionConstants.EAST:
                return start.x < point.x;
            case PositionConstants.NORTH:
                return start.y > point.y;
            case PositionConstants.SOUTH:
                return start.y < point.y;
        }
        return false;
    }
    
}
