/******************************************************************************
 * Copyright (c) 2002, 2007 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.gef.ui.internal.editpolicies;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.Assert;
import org.eclipse.draw2d.AbsoluteBendpoint;
import org.eclipse.draw2d.AutomaticRouter;
import org.eclipse.draw2d.Bendpoint;
import org.eclipse.draw2d.BendpointLocator;
import org.eclipse.draw2d.Connection;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.PrecisionPoint;
import org.eclipse.draw2d.geometry.PrecisionRectangle;
import org.eclipse.gef.AccessibleHandleProvider;
import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.SelectionHandlesEditPolicy;
import org.eclipse.gef.handles.BendpointCreationHandle;
import org.eclipse.gef.handles.BendpointMoveHandle;
import org.eclipse.gef.requests.BendpointRequest;
import org.eclipse.gmf.runtime.draw2d.ui.figures.FigureUtilities;
import org.eclipse.gmf.runtime.draw2d.ui.geometry.LineSeg;
import org.eclipse.gmf.runtime.draw2d.ui.geometry.PointListUtilities;
import org.eclipse.gmf.runtime.draw2d.ui.internal.figures.FeedbackConnection;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
import org.eclipse.gmf.runtime.gef.ui.internal.handles.BendpointCreationInvisibleHandle;
import org.eclipse.gmf.runtime.gef.ui.internal.handles.BendpointMoveHandleEx;
import org.eclipse.gmf.runtime.gef.ui.internal.handles.LineSegMoveInvisibleHandle;

/**
 * This EditPolicy defines the behavior of Bendpoints on a Connection.
 */
abstract public class ConnectionBendpointEditPolicy
	extends SelectionHandlesEditPolicy
	implements PropertyChangeListener {

	private static List NULL_CONSTRAINT = new ArrayList();
	private static final int STICKY_TOLERANCE_DP = 6;

	private LineMode lineSegMode = LineMode.OBLIQUE;
	
	static private class FeedbackState {
		public List originalConstraint;
		public Point ref1 = new Point();
		public Point ref2 = new Point();
		public boolean isDeleting = false;
		public boolean isOutsideSource = false;
		public boolean isOutsideTarget = false;
		public boolean init = false;
	}
	
	private FeedbackState feedbackState = null;
	
	private FeedbackState getFeedbackState() {
		if (feedbackState == null) {
			feedbackState = new FeedbackState();
		}
		
		return feedbackState;
	}
	
	private boolean useRealtimeFeedback() {
		return false;
	}
	
	/**
	 * Constructor for EditPolicy
	 * @param lineSegMode
	 */
	public ConnectionBendpointEditPolicy(LineMode lineSegMode) {
		super();
		this.lineSegMode = lineSegMode;
	}

	/**
	 * @return Returns the lineSegMode.
	 */
	public LineMode getLineSegMode() {
		return lineSegMode;
	}

	/** 
	 * Adds a PropertyChangeListener to the Connection so we can react
	 * to point changes in the connection.  
	 *
	 * @see SelectionHandlesEditPolicy#activate()
	 */
	public void activate() {
		super.activate();
		getConnection().addPropertyChangeListener(
			Connection.PROPERTY_POINTS,
			this);
	}

	/**
	 * @return <code>Connection</code> representing drag source feedback
	 */
	protected Connection createDragSourceFeedbackConnection() {
		if (useRealtimeFeedback()) {
			// Use the actual figure for feedback
			return getConnection();
		} else {
			// Use a ghost rectangle for feedback
			FeedbackConnection r = new FeedbackConnection(getConnection());
			addFeedback(r);
			return r;
		}
	}

	/**
	 * Adds selection handles to the connection for the bendpoints.  In this class,
	 * this method just decides if it is appropriate to add the handles, and then
	 * calls on the superclass to do the dirty work.s
	 */
	protected void addSelectionHandles() {
		if (handles == null)
			super.addSelectionHandles();
		else {
			int count = handles.size();
			int points = getConnection().getPoints().size();
			if (count != points * 2 - 3)
				super.addSelectionHandles();
		}
	}

	/**
	 * @return list of manual handles
	 */
	protected List createManualHandles() {
		List list = new ArrayList();
		ConnectionEditPart connEP = (ConnectionEditPart) getHost();
		PointList points = getConnection().getPoints();
		for (int i = 1; i < points.size() - 1; i++) {
			addInvisibleCreationHandle(list, connEP, i - 1);
			list.add(
				new BendpointMoveHandleEx(
					connEP,
					i,
					new BendpointLocator(getConnection(), i)));
		}		
		addInvisibleCreationHandle(list, connEP, points.size() - 2);
		return list;
	}

	/**
	 * Method addInvisibleCreationHandle.
	 * This handle is necessary for the accessibility feature to allow keyboard navigation to
	 * the add bendpoint feature.
	 * @param list
	 * @param connEP
	 * @param i
	 */
	protected void addInvisibleCreationHandle(
		List list,
		ConnectionEditPart connEP,
		int i) {
		if (getLineSegMode() != LineMode.OBLIQUE) {
			list.add(new LineSegMoveInvisibleHandle(connEP, i));
		} else {
			list.add(new BendpointCreationInvisibleHandle(connEP, i));
		}
	}

	/**
	 * Creates selection handles for the bendpoints.  Explicit (user-defined)
	 * bendpoints will have {@link BendpointMoveHandle}s on them with a single 
	 * {@link BendpointCreationHandle} between 2 consecutive explicit bendpoints.
	 * If implicit bendpoints (such as those created by the {@link AutomaticRouter})
	 * are used, one {@link BendpointCreationHandle} is placed in the middle
	 * of the Connection.
	 */
	protected List createSelectionHandles() {
		return createManualHandles();
	}

	/**
	 * Removes this from the Connection's list of PropertyChangeListeners.
	 *
	 * @see SelectionHandlesEditPolicy#deactivate()
	 */
	public void deactivate() {
		getConnection().removePropertyChangeListener(
			Connection.PROPERTY_POINTS,
			this);

		super.deactivate();
	}

	/**
	 * Erases bendpoint feedback.  Since the original figure is used
	 * for feedback, we just restore the original constraint that
	 * was saved before feedback started to show.
	 */
	protected void eraseConnectionFeedback(
		BendpointRequest request,
		boolean removeFeedbackFigure) {
		restoreOriginalConstraint();
		getFeedbackState().originalConstraint = null;
		if (removeFeedbackFigure)
			feedbackState = null;
	}

	/**
	 * Erases feedback, when appropriate.
	 *
	 * @see #eraseConnectionFeedback(BendpointRequest, boolean)
	 */
	public void eraseSourceFeedback(Request request) {
		if (REQ_MOVE_BENDPOINT.equals(request.getType())
			|| REQ_CREATE_BENDPOINT.equals(request.getType()))
			eraseConnectionFeedback((BendpointRequest) request, true);
	}

	/**
	 * Returns the appropriate Command for the request type given.  Handles
	 * creating, moving and deleting bendpoints.  The actual creation of the
	 * command is taken care of by subclasses implementing the appropriate
	 * methods.
	 *
	 * @see #getCreateBendpointCommand(BendpointRequest)
	 * @see #getMoveBendpointCommand(BendpointRequest)
	 * @see #getDeleteBendpointCommand(BendpointRequest)
	 */
	public Command getCommand(Request request) {
		if (REQ_MOVE_BENDPOINT.equals(request.getType())) {
			if (getLineSegMode() != LineMode.OBLIQUE) {
				return getMoveLineSegCommand((BendpointRequest) request);
			} else {
				if (getFeedbackState().isDeleting)
					return getDeleteBendpointCommand(
						(BendpointRequest) request);
				return getMoveBendpointCommand((BendpointRequest) request);
			}
		}
		if (REQ_CREATE_BENDPOINT.equals(request.getType()))
			return getCreateBendpointCommand((BendpointRequest) request);

		return null;
	}

	/**
	 * Returns the Connection associated with this EditPolicy.
	 */
	protected Connection getConnection() {
		return (Connection) ((ConnectionEditPart) getHost()).getFigure();
	}

	/**
	 * @return Point cached value representing the first reference point.
	 */
	private Point getFirstReferencePoint() {
		return getFeedbackState().ref1;
	}

	/**
	 * @return Point cached value representing the second reference point.
	 */
	private Point getSecondReferencePoint() {
		return getFeedbackState().ref2;
	}

	/**
	 * Utility method to determine if point p passes through the line segment 
	 * defined by p1 and p2.
	 * 
	 * @param p1 Point that is the first point in the line segment to test against.
	 * @param p2 Point that is the second point in the line segment to test against.
	 * @param p Point that is tested to see if it falls in the line segment defined by p1 and p2.
	 * @return true if line segment contains Point p, false otherwise.
	 */
	private boolean lineContainsPoint(Point p1, Point p2, Point p) {
		LineSeg line = new LineSeg(p1, p2);
		return line.containsPoint(p, getStickyTolerance() / 3);
	}

	/**
	 * Adds selection handles to the Connection, if it is selected, when the points 
	 * property changes.  Since we only listen for changes in the points property, 
	 * this method is only called when the points of the Connection have changed.
	 */
	public void propertyChange(PropertyChangeEvent evt) {
		if (getHost().getSelected() != EditPart.SELECTED_NONE) {
//			int count = handles.size();
//			int points = getConnection().getPoints().size();
//			if (count != points * 2 - 3)
				addSelectionHandles();
		}
	}

	/**
	 * Restores the original constraint that was saved before feedback
	 * began to show.
	 */
	protected void restoreOriginalConstraint() {
		if (getFeedbackState().originalConstraint != null) {
			Assert.isTrue(getFeedbackState().originalConstraint.size() >= 2);
			getConnection().setRoutingConstraint(
				getFeedbackState().originalConstraint);
		}
	}

	/**
	 * Since the original figure is used for feedback, this method saves the 
	 * original constraint, so that is can be restored when the feedback is
	 * erased.
	 */
	protected void saveOriginalConstraint() {
		getFeedbackState().originalConstraint = (List)
			getConnection().getRoutingConstraint();
		if (getFeedbackState().originalConstraint == null)
			getFeedbackState().originalConstraint = NULL_CONSTRAINT;

		if (getLineSegMode() != LineMode.OBLIQUE && !getFeedbackState().init) {
			// Update the constraint based on the current figure
			List newConstraint = new ArrayList(getFeedbackState().originalConstraint.size());
			PointList pts =
				PointListUtilities.copyPoints(getConnection().getPoints());
			//OrthogonalRouterUtilities.resetEndPointsToCenter(getConnection(), pts);

			for (int i = 0; i < pts.size(); i++) {
				Bendpoint abp = new AbsoluteBendpoint(pts.getPoint(i));
				newConstraint.add(abp);
			}

			Assert.isTrue(getFeedbackState().originalConstraint.size() >= 2);
			getConnection().setRoutingConstraint(
				newConstraint);

			// reset booleans
			getFeedbackState().isOutsideSource = false;
			getFeedbackState().isOutsideTarget = false;
		} else {
			// if the constraint and the connection figure points list don't match then reset the constraint
			// based on the connection figure list.  This could happen in certain cases - sepcifically when
			// fan router detects a collision or when a self relation is routed.
			int nConstraintSize = getFeedbackState().originalConstraint.size();
			PointList pts = getConnection().getPoints();
			int nPointSize = pts.size();

			if (!getFeedbackState().init && nConstraintSize != nPointSize) {

				while (getFeedbackState().originalConstraint.size() > 0) {
					getFeedbackState().originalConstraint.remove(0);
				}

				for (int i = 0; i < pts.size(); i++) {
					Bendpoint bpNew = new AbsoluteBendpoint(pts.getPoint(i));
					getFeedbackState().originalConstraint.add(i, bpNew);
				}
			}

			Assert.isTrue(getFeedbackState().originalConstraint.size() >= 2);
			getConnection().setRoutingConstraint(
				new ArrayList(getFeedbackState().originalConstraint));
		}
		
		getFeedbackState().init = true;
	}

	/**
	 * Method setReferencePoints.
	 * This method will calculate the two end reference points for a point that is
	 * being moved or created.  The reference points are used to determine if the 
	 * request point can be deleted or not (for straight line tolerance).
	 * 
	 * @param request BendpointRequest object containing index information.
	 */
	private void setReferencePoints(BendpointRequest request) {
		if (getFeedbackState().originalConstraint == null) {
			saveOriginalConstraint();
		}

		List constraint = (List)
			getConnection().getRoutingConstraint();
		Bendpoint bp = (Bendpoint) constraint.get(Math.max(0, request.getIndex() - 1));
		getFeedbackState().ref1 = bp.getLocation();

		bp = (Bendpoint) constraint.get(Math.min(request.getIndex() + 1, constraint.size() -1));
		getFeedbackState().ref2 = bp.getLocation();
	}

	private void setNewFeedbackConstraint(List constraint) {
		Assert.isTrue(constraint.size() >= 2);
		getConnection().setRoutingConstraint(constraint);
	}

	/**
	 * Shows feedback when a bendpoint is being created.  The original figure
	 * is used for feedback and the original constraint is saved, so that it
	 * can be restored when feedback is erased.
	 */
	protected void showCreateBendpointFeedback(BendpointRequest request) {
		Point p = new Point(request.getLocation());
		List constraint;
		
		getConnection().translateToRelative(p);

		Bendpoint bp = new AbsoluteBendpoint(p);
		if (getFeedbackState().originalConstraint == null) {
			saveOriginalConstraint();
			constraint = (List)
				getConnection().getRoutingConstraint();
			constraint.add(request.getIndex() + 1, bp);
		} else {
			constraint = (List)
				getConnection().getRoutingConstraint();
		}

		stickyStraightLineFeedback(constraint, request.getIndex() + 1, bp);

		setNewFeedbackConstraint(constraint);
	}

	/**
	 * Shows feedback when a bendpoint is being deleted.  This method is
	 * only called once when the bendpoint is first deleted, not every
	 * mouse move.  The original figure is used for feedback and the original 
	 * constraint is saved, so that it can be restored when feedback is erased.
	 */
	protected void showDeleteBendpointFeedback(BendpointRequest request) {
		if (getFeedbackState().originalConstraint == null) {
			saveOriginalConstraint();
			List constraint = (List)
				getConnection().getRoutingConstraint();
			constraint.remove(request.getIndex());

			setNewFeedbackConstraint(constraint);
		}
	}

	/**
	 * Shows feedback when a bendpoint is being moved.  Also checks to see if the bendpoint 
	 * should be deleted and then calls {@link #showDeleteBendpointFeedback(BendpointRequest)}
	 * if needed.  The original figure is used for feedback and the original constraint is 
	 * saved, so that it can be restored when feedback is erased.
	 */
	protected void showMoveBendpointFeedback(BendpointRequest request) {		
		Point p = new Point(request.getLocation());
		if (!getFeedbackState().isDeleting) {
			setReferencePoints(request);
		}

		getConnection().translateToRelative(p);
		Bendpoint bp = new AbsoluteBendpoint(p);

		if (getFeedbackState().originalConstraint == null) {
			saveOriginalConstraint();
		}

		if (lineContainsPoint(getFirstReferencePoint(),
			getSecondReferencePoint(),
			p)) {
			if (!getFeedbackState().isDeleting) {
				getFeedbackState().isDeleting = true;
				eraseConnectionFeedback(request, false);
				showDeleteBendpointFeedback(request);
			}
			return;
		}
		if (getFeedbackState().isDeleting) {
			getFeedbackState().isDeleting = false;
			eraseConnectionFeedback(request, false);
		}

		List constraint = (List)
			getConnection().getRoutingConstraint();
		stickyStraightLineFeedback(constraint, request.getIndex(), bp);

		setNewFeedbackConstraint(constraint);
	}

	/**
	 * This method will set the constraint with the given bendpoint, with the additional behavior of
	 * "sticking" the point around a tolerance to a straight line.  If it's within a tolerance of the
	 * previous point, stick it to the horizontal or vertical coordinates that make it straight.
	 */
	protected void stickyStraightLineFeedback(
		List constraint,
		int nIndex,
		Bendpoint bp) {
		Point ptLoc = new Point(bp.getLocation());
		
		int sticky_tolerance = getStickyTolerance();
		
		if (nIndex > 0) {
			Point ptPrev;
			if ((nIndex - 1) == 0) {
				ptPrev =
					getConnection()
						.getSourceAnchor()
						.getReferencePoint();
				getConnection().translateToRelative(ptPrev);
			} else
				ptPrev = ((Bendpoint) constraint.get(nIndex - 1)).getLocation();

			if (Math.abs(ptPrev.x - ptLoc.x) < sticky_tolerance)
				ptLoc.x = ptPrev.x;
			if (Math.abs(ptPrev.y - ptLoc.y) < sticky_tolerance)
				ptLoc.y = ptPrev.y;
		}

		if (nIndex < constraint.size() - 1) {
			Point ptNext;
			if ((nIndex + 1) == (constraint.size() - 1)) {
				ptNext =
					getConnection()
						.getTargetAnchor()
						.getReferencePoint();
				getConnection().translateToRelative(ptNext);
			} else
				ptNext = ((Bendpoint) constraint.get(nIndex + 1)).getLocation();

			if (Math.abs(ptNext.x - ptLoc.x) < sticky_tolerance)
				ptLoc.x = ptNext.x;
			if (Math.abs(ptNext.y - ptLoc.y) < sticky_tolerance)
				ptLoc.y = ptNext.y;
		}

		if (!ptLoc.equals(bp.getLocation())) {
			Bendpoint bpNew = new AbsoluteBendpoint(ptLoc);
			constraint.set(nIndex, bpNew);
		} else {
			constraint.set(nIndex, bp);
		}
	}

	private int getStickyTolerance() {
		int sticky_tolerance = MapModeUtil.getMapMode(getConnection()).DPtoLP(STICKY_TOLERANCE_DP);
		return sticky_tolerance;
	}

	/**
	 * Shows feedback, when appropriate.  Calls a different method
	 * depending on the request type.
	 *
	 * @see #showCreateBendpointFeedback(BendpointRequest)
	 * @see #showMoveBendpointFeedback(BendpointRequest)
	 */
	public void showSourceFeedback(Request request) {
		if (getLineSegMode() != LineMode.OBLIQUE) {
			if (REQ_CREATE_BENDPOINT.equals(request.getType())) {
				showMoveLineSegFeedback((BendpointRequest) request);
			} else if (REQ_MOVE_BENDPOINT.equals(request.getType())) {
				showMoveOrthogonalBenspointFeedback((BendpointRequest) request);
			}
			
		} else {
			if (REQ_MOVE_BENDPOINT.equals(request.getType()))
				showMoveBendpointFeedback((BendpointRequest) request);
			else if (REQ_CREATE_BENDPOINT.equals(request.getType()))
				showCreateBendpointFeedback((BendpointRequest) request);
		}

		super.showSourceFeedback(request);
	}

	/**
	 * Method getBendpointsChangedCommand.
	 * This method will return a SetBendpointsCommand with the points retrieved from
	 * the user feedback in the figure.
	 * @param request BendpointRequest from the user gesture for moving / creating a bendpoint
	 * @return Command SetBendpointsCommand that contains the point changes for the connection.
	 */
	abstract protected Command getBendpointsChangedCommand(BendpointRequest request);

	protected Command getCreateBendpointCommand(BendpointRequest request) {
		return getBendpointsChangedCommand(request);
	}

	protected Command getMoveBendpointCommand(BendpointRequest request) {
		return getBendpointsChangedCommand(request);
	}

	protected Command getDeleteBendpointCommand(BendpointRequest request) {
		return getBendpointsChangedCommand(request);
	}

	protected final LineSeg getLineSeg(List bendPoints, int nIndex) {
		Point pt1 =
			new Point(((Bendpoint) bendPoints.get(nIndex - 1)).getLocation());
		Point pt2 =
			new Point(((Bendpoint) bendPoints.get(nIndex)).getLocation());

		return new LineSeg(pt1, pt2);
	}

	/**
	 * @param bendPoints
	 * @param nIndex
	 * @param newLine
	 */
	protected void setLineSeg(List bendPoints, int nIndex, LineSeg newLine) {
		Bendpoint bp1 = new AbsoluteBendpoint(newLine.getOrigin());
		Bendpoint bp2 = new AbsoluteBendpoint(newLine.getTerminus());
		
		bendPoints.set(nIndex - 1, bp1);
		bendPoints.set(nIndex, bp2);
	}

	/**
	 * @param request
	 * @return move line segment command
	 */
	protected Command getMoveLineSegCommand(BendpointRequest request) {
		return getBendpointsChangedCommand(request);
	}


	/**
	* Method lineOutsideSource.
	* Utility method to determine if the constraint needs to be adjusted becauase the line is
	* outside of the source bounds.
	* 
	* @param line LineSeg defining the new line moved by the user gesture
	* @return boolean true if origin of line lies outside the starting source element, false otherwise.
	*/
	protected boolean lineOutsideSource(LineSeg line) {

		// check if end points are outside of bounds and if so - add a new point
		PrecisionRectangle startRect =
			new PrecisionRectangle(FigureUtilities.getAnchorableFigureBounds(getConnection().getSourceAnchor().getOwner()));
		getConnection().getSourceAnchor().getOwner().translateToAbsolute(
			startRect);
		if (getLineSegMode().equals(LineMode.ORTHOGONAL_CONSTRAINED)) {
			if (line.isHorizontal()) {
				startRect.shrink(0, 2);
			} else {
				startRect.shrink(2, 0);
			}
		}
		
		getConnection().translateToRelative(startRect);
		/*
		 * Rectangle needs to be expanded by the "odd" number below because the number after
		 * translations could be N.999999999... 
		 */
		if (!startRect.expand(0.000001, 0.000001).contains(new PrecisionPoint(line.getOrigin()))) {
			return true;
		}

		return false;
	}

	/**
	* Method lineOutsideTarget.
	* Utility method to determine if the constraint needs to be adjusted because the line is
	* outside of the target bounds.
	* 
	* @param line LineSeg defining the new line moved by the user gesture.
	* @return boolean true if terminus of line lies outside the target element, false otherwise.
	*/
	protected boolean lineOutsideTarget(LineSeg line) {

		// check if end points are outside of bounds and if so - add a new point
		PrecisionRectangle endRect =
			new PrecisionRectangle(FigureUtilities.getAnchorableFigureBounds(getConnection().getTargetAnchor().getOwner()));
		getConnection().getTargetAnchor().getOwner().translateToAbsolute(
			endRect);
		if (getLineSegMode().equals(LineMode.ORTHOGONAL_CONSTRAINED)) {
			if (line.isHorizontal()) {
				endRect.shrink(0, 2);
			} else {
				endRect.shrink(2, 0);
			}
		}
		
		/*
		 * Rectangle needs to be expanded by the "odd" number below because the number after
		 * translations could be N.999999999... 
		 */
		getConnection().translateToRelative(endRect);
		if (!endRect.expand(0.00001, 0.00001).contains(new PrecisionPoint(line.getTerminus()))) {
			return true;
		}

		return false;
	}

	/**
	* Method removeOutsideSourceFeedback.
	* Removes a bendpoint from the beginning of the constraint.
	* 
	* @param constraint List of bendpoints that the source point will be added too.
	*/
	protected void removeOutsideSourceFeedback(List constraint) {
		constraint.remove(0);
	}

	/**
	* Method removeOutsideTargetFeedback.
	* Removes a bendpoint from the end of the constraint.
	* 
	* @param constraint List of bendpoints that the target point will be added too.
	*/
	protected void removeOutsideTargetFeedback(List constraint) {
		constraint.remove(constraint.size() - 1);
	}
	
	/**
	 * Draws feedback for moving a bend point of a rectilinear connection
	 * 
	 * @param request Benndpoint request
	 */
	private void showMoveOrthogonalBenspointFeedback(BendpointRequest request) {
		if (getFeedbackState().originalConstraint == null) {
			saveOriginalConstraint();
		}
		
		Point ptLoc = new Point(request.getLocation());
		List constraint = (List)
			getConnection().getRoutingConstraint();
		
		getConnection().translateToRelative(ptLoc);
		
		int index =
		getFeedbackState().isOutsideSource ? request.getIndex() + 1 : request.getIndex();
		
		Point previous = ((Bendpoint)constraint.get(index - 1)).getLocation();
		Point moving = ((Bendpoint)constraint.get(index)).getLocation();
		Point next = ((Bendpoint)constraint.get(index + 1)).getLocation();
		
		LineSeg originalFirst = new LineSeg(previous.getCopy(), moving.getCopy());
		LineSeg originalSecond = new LineSeg(moving.getCopy(), next.getCopy());
		
		Dimension diff = ptLoc.getDifference(moving);
		
		if (originalFirst.isHorizontal()) {
			previous.y += diff.height;
			next.x += diff.width;
		} else {
			previous.x += diff.width;
			next.y += diff.height;
		}
		
		LineSeg movedFirst = new LineSeg(previous, ptLoc.getCopy());
		LineSeg movedSecond = new LineSeg(ptLoc.getCopy(), next);
		
		index = adjustOutsideBoundsLineFeedback(movedFirst, index - 1, constraint, originalFirst);
		constraint.set(index, new AbsoluteBendpoint(movedFirst.getOrigin()));
		constraint.set(index + 1, new AbsoluteBendpoint(movedFirst.getTerminus()));
		
		index = adjustOutsideBoundsLineFeedback(movedSecond, index + 1, constraint, originalSecond);
		constraint.set(index + 1, new AbsoluteBendpoint(movedSecond.getTerminus()));
		
		getConnection().setRoutingConstraint(constraint);	}

	/**
	* Shows feedback when a line segment is being moved.  Also checks to see if the bendpoint 
	* should be deleted and then calls {@link #showDeleteBendpointFeedback(BendpointRequest)}
	* if needed.  The original figure is used for feedback and the original constraint is 
	* saved, so that it can be restored when feedback is erased.
	*/
	protected void showMoveLineSegFeedback(BendpointRequest request) {

		if (getFeedbackState().originalConstraint == null) {
			saveOriginalConstraint();
		}

		Point ptLoc = new Point(request.getLocation());
		List constraint = (List)
			getConnection().getRoutingConstraint();
		
		getConnection().translateToRelative(ptLoc);
		
		// adjust request index to account for source bendpoint if needed
		int index =
			getFeedbackState().isOutsideSource ? request.getIndex() + 1 : request.getIndex();

		LineSeg moveLine = getLineSeg(constraint, index + 1);
		LineSeg newLine = moveLine.getParallelLineSegThroughPoint(ptLoc);
				
		index = adjustOutsideBoundsLineFeedback(newLine, index, constraint, moveLine);
		
		setLineSeg(constraint, index + 1, newLine);
		
		getConnection().setRoutingConstraint(constraint);
	}
	
	/**
	 * adjustOutsideBoundsLineFeedback
	 * Method to handle feedback where the line is dragged outside of the source or target shapes bounding box.
	 * 
	 * @param newLine LineSeg representing the line currently being manipulated.
	 * @param index the index
	 * @param constraint List of Bendpoint objects that is the constraint to the gesture.
	 * @param moveLine original segment that is being manipulated
	 * @return int new index value after the constraint and feedback have been adjusted.
	 */
	private int adjustOutsideBoundsLineFeedback(LineSeg newLine, int index, List constraint, LineSeg moveLine) {
		if (getLineSegMode().equals(LineMode.ORTHOGONAL_CONSTRAINED)) {
			// merely enforce the fact that we can't adjust the line outside the bounds of the source and target.
			if ((index == 0 && lineOutsideSource(newLine)) ||
				((index + 1 == constraint.size() - 1)&& lineOutsideTarget(newLine))) {
				newLine.setOrigin(moveLine.getOrigin());
				newLine.setTerminus(moveLine.getTerminus());
			}

			return index;
		}
		
		boolean bRemoveSource = false;
		boolean bRemoveTarget = false;
		boolean bSetNewSource = false;
		boolean bSetNewTarget = false;

		// Check source to see if we need to add a bendpoint
		if (index == 0 && lineOutsideSource(newLine)) {
			if (!getFeedbackState().isOutsideSource) {
				getFeedbackState().isOutsideSource = true;
				bSetNewSource = true;
			}
		} else if (index == 1 && getFeedbackState().isOutsideSource && !lineOutsideSource(newLine)) {
			getFeedbackState().isOutsideSource = false;
			bRemoveSource = true;
		}
		
		// Check target to see if we need to add a bendpoint
		int checkTargetIndex = index + 1 + (getFeedbackState().isOutsideTarget ? 1 : 0);
		if ((checkTargetIndex == constraint.size() - 1)
			&& lineOutsideTarget(newLine)) {
			if (!getFeedbackState().isOutsideTarget) {
				getFeedbackState().isOutsideTarget = true;
				bSetNewTarget = true;
			}
		} else if (checkTargetIndex == constraint.size() - 2 && getFeedbackState().isOutsideTarget
				&& !lineOutsideTarget(newLine)) {
			getFeedbackState().isOutsideTarget = false;
			bRemoveTarget = true;
		}
		if (bRemoveSource) {
			removeOutsideSourceFeedback(constraint);
			index--;
		}
		
		if (bRemoveTarget) {
			removeOutsideTargetFeedback(constraint);
		}

		if (bSetNewSource) {
			showOutsideSourceFeedback(newLine, moveLine, constraint);
			index++;
		}

		if (bSetNewTarget) {
			showOutsideTargetFeedback(newLine, moveLine, constraint);
		}
		return index;
	}
	
	/**
	* Method showOutsideSourceFeedback.
	* Adds a bendpoint to the beginning of the constraint.
	* Also adjusts the new segment with respect to added constraint
	* 
	* @param constraint List of bendpoints that the source point will be added too.
	*/
	private void showOutsideSourceFeedback(LineSeg newLine, LineSeg moveLine, List constraint) {
		Connection conn = (Connection)getHostFigure();
		ConnectionAnchor anchor = conn.getSourceAnchor();
		PrecisionPoint startPoint = new PrecisionPoint(anchor.getOwner().getBounds().getCenter());
		anchor.getOwner().translateToAbsolute(startPoint);
		conn.translateToRelative(startPoint);
		PrecisionRectangle bounds = new PrecisionRectangle(anchor.getOwner().getBounds());
		anchor.getOwner().translateToAbsolute(bounds);
		conn.translateToRelative(bounds);
		Point origin = new Point(newLine.getOrigin());
		if (moveLine.isHorizontal()) {
			origin.x = startPoint.x;
		} else {
			origin.y = startPoint.y;
		}
		newLine.setOrigin(origin);
		constraint.add(0, new AbsoluteBendpoint(startPoint));
		
	}

	/**
	* Method showOutsideTargetFeedback.
	* Adds a bendpoint to the end of the constraint.
	* Also adjusts the new segment with respect to added constraint
	* 
	* @param constraint List of bendpoints that the target point will be added too.
	*/
	private void showOutsideTargetFeedback(LineSeg newLine, LineSeg moveLine, List constraint) {
		Connection conn = (Connection)getHostFigure();
		ConnectionAnchor anchor = conn.getTargetAnchor();
		PrecisionPoint endPoint = new PrecisionPoint(anchor.getOwner().getBounds().getCenter());
		anchor.getOwner().translateToAbsolute(endPoint);
		conn.translateToRelative(endPoint);
		PrecisionRectangle bounds = new PrecisionRectangle(anchor.getOwner().getBounds());
		anchor.getOwner().translateToAbsolute(bounds);
		conn.translateToRelative(bounds);
		Point terminus = new Point(newLine.getTerminus()); 
		if (moveLine.isHorizontal()) {
			terminus.x = endPoint.x;
		} else {
			terminus.y = endPoint.y;
		}
		newLine.setTerminus(terminus);
		constraint.add(new AbsoluteBendpoint(endPoint));
	}

	/**
	 * Override for AccessibleHandleProvider when deactivated
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=69316
	 * 
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class key) {
		if (key == AccessibleHandleProvider.class)
			//handles == null when deactivated
			if (handles == null) {
				return null;
			}
		return super.getAdapter(key);
	}	
}
