/******************************************************************************
 * Copyright (c) 2007, 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.gmf.runtime.draw2d.ui.internal.routers;

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

import org.eclipse.draw2d.AbsoluteBendpoint;
import org.eclipse.draw2d.AnchorListener;
import org.eclipse.draw2d.Bendpoint;
import org.eclipse.draw2d.Connection;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.LayoutManager;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Geometry;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.PrecisionRectangle;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.graph.Path;
import org.eclipse.draw2d.graph.ShortestPathRouter;
import org.eclipse.gmf.runtime.draw2d.ui.figures.IBorderItemLocator;
import org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;

/**
 * @author mmostafa
 *
 * RectilinearRouter which is aware of border items
 * This router, will make sure that it connects to teh correct side of teh border item
 * Also, it willmake sure that it never overlape the border item container
 * 
 */

public class BorderItemRectilinearRouter
    extends RectilinearRouter {

    private static int OFFSET = 15;

    /* (non-Javadoc)
     * @see org.eclipse.gmf.runtime.draw2d.ui.internal.routers.ObliqueRouter#calculateBendPoints(org.eclipse.draw2d.Connection)
     */
    protected PointList calculateBendPoints(Connection conn) {
        IFigure source = conn.getSourceAnchor().getOwner();
        IFigure target = conn.getTargetAnchor().getOwner();
        PointList bends = super.calculateBendPoints(conn);
        if (source == null || target == null || isAvoidingObstructions(conn) || isClosestDistance(conn)
        		|| bends.size() > 2) {
            // reorient
            return bends;
        }

        int sourcePosition = getBorderFigurePosition(source);
        int targetPosition = getBorderFigurePosition(target);
        
        if (sourcePosition == PositionConstants.NONE && targetPosition == PositionConstants.NONE) {
        	return bends;
        }
        
        PolylineConnectionEx fakeConnection = new PolylineConnectionEx() {

            public void validate() {
                // no need to validate
            }

            public void paintFigure(Graphics graphics) {
                // nothing to paint
            }
        };
        Rectangle sourceParentRect = getObstacle(source, conn, (sourcePosition != PositionConstants.NONE));
        Rectangle targetParentRect = getObstacle(target, conn, (targetPosition != PositionConstants.NONE));
        if (bends.size() == 2
        		&& (sourcePosition == PositionConstants.NONE || (sourcePosition != PositionConstants.NONE && !lineIntersectRectangle(bends.getFirstPoint(), bends.getLastPoint(), sourceParentRect)))
        		&& (targetPosition == PositionConstants.NONE || (targetPosition != PositionConstants.NONE && !lineIntersectRectangle(bends.getFirstPoint(), bends.getLastPoint(), targetParentRect)))) {
           	return bends;
        }
        if (sourceParentRect.contains(targetParentRect)) {
            sourcePosition = reversePosition(sourcePosition);
        } else if (targetParentRect.contains(sourceParentRect)) {
            targetPosition = reversePosition(targetPosition);
        }

        fakeConnection.setSourceAnchor(new BorderItemConnectionAnchor(conn
            .getSourceAnchor(), sourcePosition, OFFSET));
        fakeConnection.setTargetAnchor(new BorderItemConnectionAnchor(conn
            .getTargetAnchor(), targetPosition, OFFSET));

        fakeConnection.setConnectionRouter(conn.getConnectionRouter());
        List originalbendpoints = (ArrayList) conn.getConnectionRouter()
            .getConstraint(conn);
        // protection code to prevent NPE while creating the connection
        if (originalbendpoints == null || originalbendpoints.size() == 0) {
            // reorient
            return bends;
        }

        fakeConnection.setParent(conn.getParent());
        if (conn instanceof PolylineConnectionEx) {
            PolylineConnectionEx connection = (PolylineConnectionEx) conn;
            fakeConnection.setRoutingStyles(connection
                .isClosestDistanceRouting(), connection
                .isAvoidObstacleRouting());
        }
        List constraint = new ArrayList();
        for (Iterator itr = originalbendpoints.iterator(); itr.hasNext();) {
            Bendpoint bp = (Bendpoint) itr.next();
            constraint.add(new AbsoluteBendpoint(bp.getLocation()));
        }
        AbsoluteBendpoint startPoint = (AbsoluteBendpoint) constraint.get(0);
        if (sourcePosition != PositionConstants.NONE) {
            BorderItemConnectionAnchor anchor = (BorderItemConnectionAnchor) fakeConnection
                .getSourceAnchor();
            Point startBendpoint = anchor.getReferencePoint();
            conn.translateToRelative(startBendpoint);
            constraint.remove(0);
            startPoint = new AbsoluteBendpoint(startBendpoint);
            constraint.add(0, startPoint);
        }
        AbsoluteBendpoint endPoint = (AbsoluteBendpoint) constraint
            .get(constraint.size() - 1);
        if (targetPosition != PositionConstants.NONE) {
            BorderItemConnectionAnchor anchor = (BorderItemConnectionAnchor) fakeConnection
                .getTargetAnchor();
            Point endBendpoint = anchor.getReferencePoint();
            conn.translateToRelative(endBendpoint);
            constraint.remove(constraint.size() - 1);
            endPoint = new AbsoluteBendpoint(endBendpoint);
            constraint.add(endPoint);
        }
        avoidOverlappingWithParent(startPoint, endPoint, sourceParentRect,
            targetParentRect, constraint, conn);
        fakeConnection.setRoutingConstraint(constraint);
        PointList points = super.calculateBendPoints(fakeConnection);
        if (sourcePosition != PositionConstants.NONE) {
            BorderItemConnectionAnchor anchor = (BorderItemConnectionAnchor) fakeConnection
                .getSourceAnchor();
            Point startPoint1 = anchor.getAnchorPoint();
            conn.translateToRelative(startPoint1);
            points.insertPoint(startPoint1, 0);
        }

        if (targetPosition != PositionConstants.NONE) {
            BorderItemConnectionAnchor anchor = (BorderItemConnectionAnchor) fakeConnection
                .getTargetAnchor();
            Point endPoint1 = anchor.getAnchorPoint();
            conn.translateToRelative(endPoint1);
            points.addPoint(endPoint1);
        }
        fakeConnection.setParent(null);
        return points;
    }

    /**
     * utility method to revers the position
     * @param position the position to reverse
     * @return  teh reversed position
     */
    private int reversePosition(int position) {
        int newPosition = position;
        if (position == PositionConstants.SOUTH)
            newPosition = PositionConstants.NORTH;
        else if (position == PositionConstants.NORTH)
            newPosition = PositionConstants.SOUTH;
        else if (position == PositionConstants.WEST)
            newPosition = PositionConstants.EAST;
        else if (position == PositionConstants.EAST)
            newPosition = PositionConstants.WEST;
        return newPosition;
    }

    /**
     * @author MMostafa
     *  Border Item aware Anchor, this anchor will make sure that the anchor point
     *  and the reference point are on the correct side
     */
    private class BorderItemConnectionAnchor
        implements ConnectionAnchor {

        private ConnectionAnchor anchor;

        private int position;

        private int offset;

        public BorderItemConnectionAnchor(ConnectionAnchor anchor,
                int position, int offset) {
            this.anchor = anchor;
            this.position = position;
            this.offset = offset;
        }

        public Point getReferencePoint() {
            Point referencePoint = getAnchorPoint();
            if (position == PositionConstants.SOUTH)
                referencePoint.y += offset;
            else if (position == PositionConstants.NORTH)
                referencePoint.y -= offset;
            else if (position == PositionConstants.WEST)
                referencePoint.x -= offset;
            else if (position == PositionConstants.EAST)
                referencePoint.x += offset;
            return referencePoint;
        }

        public Point getAnchorPoint() {
            Rectangle ownerBounds = getOwner().getBounds().getCopy();
            getOwner().translateToAbsolute(ownerBounds);
            if (position == PositionConstants.SOUTH)
                return ownerBounds.getBottom();
            else if (position == PositionConstants.NORTH)
                return ownerBounds.getTop();
            else if (position == PositionConstants.WEST)
                return ownerBounds.getLeft();
            else if (position == PositionConstants.EAST)
                return ownerBounds.getRight();
            return ownerBounds.getCenter();
        }

        public void addAnchorListener(AnchorListener listener) {
            // nothing to do
        }

        public Point getLocation(Point reference) {
            return reference;
        }

        public IFigure getOwner() {
            return anchor.getOwner();
        }

        public void removeAnchorListener(AnchorListener listener) {
            // nothing to do
        }

    }

    /**
     * Returns the position of the border item with respect to its parent
     * Clients can override this method to change the way postions is
     * calculated for border items
     * @param borderFigure  Figure to use to get the position
     * @return  the border item position, see <code>PositionConstants</code>
     */
    protected int getBorderFigurePosition(IFigure borderFigure) {
        IFigure child = borderFigure;
        IFigure parent = borderFigure.getParent();
        if (parent != null && parent.getLayoutManager() != null) {
            LayoutManager layoutManager = parent.getLayoutManager();
            Object layoutConstraint = layoutManager.getConstraint(child);
            if (layoutConstraint instanceof IBorderItemLocator) {
                return ((IBorderItemLocator) layoutConstraint)
                    .getCurrentSideOfParent();
            }
        }
        return PositionConstants.NONE;
    }
    
    

    /**
     * Utility method that adjust the constrinat to avoid overlapping with 
     * Source or target parents, this method should be called only in case
     * of routing connections connecting to border items 
     * @param startPoint        start point or the route
     * @param endPoint          end point of the route
     * @param sourceParentRect  the rectangle of the source element parent
     * @param targetParentRect  the rectangle of the target element parent
     * @param constraint        the constraint to modify
     * @param conn              the connection to route
     */
    private void avoidOverlappingWithParent(AbsoluteBendpoint startPoint,
            AbsoluteBendpoint endPoint, Rectangle sourceParentRect,
            Rectangle targetParentRect, List constraint, Connection conn) {
        if (sourceParentRect.intersects(targetParentRect)) {
            return;
        }
        IMapMode mapMode = MapModeUtil.getMapMode(conn);
        int logicalOffset = mapMode.DPtoLP(OFFSET);
        // use GEF's shortest path router to get reference bend points
        ShortestPathRouter router = new ShortestPathRouter();
        Path path = new Path(startPoint, endPoint);
        router.addPath(path);
        router.addObstacle(sourceParentRect);
        router.addObstacle(targetParentRect);
        router.setSpacing(logicalOffset);
        router.solve();
        PointList points = path.getPoints();
        // remove the start and end points
        points.removePoint(0);
        points.removePoint(points.size() - 1);
        // deal with the remaining points
        if (points.size() > 0) {
            Point refrencePoint = points.getFirstPoint();
            AbsoluteBendpoint startPointGuidePoint = new AbsoluteBendpoint(startPoint);
            adjustPointUsingReferencePointAndObstacle(startPointGuidePoint,refrencePoint,sourceParentRect,  logicalOffset);
            constraint.add(1, startPointGuidePoint);
            points.removePoint(0);
            // this means we had only one reference point, we will use this point
            // to adjust poth source and target
            if (points.size() == 0) {
                AbsoluteBendpoint endPointGuidePoint = new AbsoluteBendpoint(endPoint);
                adjustPointUsingReferencePointAndObstacle(endPointGuidePoint,refrencePoint,targetParentRect,  logicalOffset);
                if (endPointGuidePoint.y == endPoint.y)
                    endPointGuidePoint.x = startPointGuidePoint.x;
                else
                    endPointGuidePoint.y = startPointGuidePoint.y;
                constraint.add(2, endPointGuidePoint);
            }
        }
        if (points.size() > 0) {
            Point referencePoint = points.getLastPoint();
            AbsoluteBendpoint endPointGuidePoint = new AbsoluteBendpoint(endPoint);
            adjustPointUsingReferencePointAndObstacle(endPointGuidePoint,referencePoint,targetParentRect , logicalOffset);
            constraint.add(constraint.size() - 1, endPointGuidePoint);
        }
    }

    /**
     * Modify a guide point based on a reference point to avoid collision with the
     * passed obstacle, the offset had to be in logical coordinates
     * @param guidePoint, the point to adjust
     * @param referencePoint, reference point to use during the adjust process
     * @param obstacle, obstable to consider
     * @param offSet, the offset had to be in logical coordinate
     */
    private void adjustPointUsingReferencePointAndObstacle(AbsoluteBendpoint guidePoint, Point referencePoint,
            Rectangle obstacle, int offSet ) {
        // check if the y of the starting point is in the rectangle range (point
        // will be west or east or the rectangle)
        boolean changeY = (guidePoint.y >= obstacle.y && guidePoint.y <= (obstacle.y + obstacle.height));

        if (changeY) {
            if (referencePoint.y < guidePoint.y)
                guidePoint.y = obstacle.y - offSet;
            else
                guidePoint.y = obstacle.y + obstacle.height
                    + offSet;
        } else {
            if (referencePoint.x < guidePoint.x)
                guidePoint.x = obstacle.x - offSet;
            else
                guidePoint.x = obstacle.x + obstacle.width
                    + offSet;
        }
    }

    /**
     * Returns the obstacle that the route should try to avoid, for example if the isBordereItem 
     * flag is ON, it will return the rectangle of the border item parent.
     * This method can be overriden by clients to provide a client specific way to find the obstacle
     * @param figure, figure to get the obstacle for
     * @param conn, the connection the router is routing
     * @param isBorderItem, indicates if the passed figure is a border item figrue or not
     * @return obstacle
     */
    protected Rectangle getObstacle(IFigure figure, Connection conn,
            boolean isBorderItem) {
        IFigure parent = null;
        if (isBorderItem)
            parent = getBorderItemParent(figure);
        else
            parent = figure;
        Rectangle rect = new PrecisionRectangle(parent.getBounds());
        parent.translateToAbsolute(rect);
        conn.translateToRelative(rect);
        return rect;
    }

    /**
     * return the parent of a border item figure
     * clients can override this method to find the 
     * @param figure, the border item figure
     * @return teh parent of the border item
     */
    protected IFigure getBorderItemParent(IFigure figure) {
        return figure.getParent().getParent();
    }
    
    private boolean lineIntersectRectangle(Point start, Point end, Rectangle rect) {
    	return Geometry.linesIntersect(start.x, start.y, end.x, end.y, rect.x, rect.y, rect.x + rect.width, rect.y)
    		|| Geometry.linesIntersect(start.x, start.y, end.x, end.y, rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + rect.height)
    		|| Geometry.linesIntersect(start.x, start.y, end.x, end.y, rect.x + rect.width, rect.y + rect.height, rect.x, rect.y + rect.height)
    		|| Geometry.linesIntersect(start.x, start.y, end.x, end.y, rect.x, rect.y + rect.height, rect.x, rect.y);
    }
}
