/*******************************************************************************
 * Copyright (c) 2003, 2005 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.draw2d.graph;

import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;

/**
 * @author Randy Hudson
 */
class RouteEdges extends GraphVisitor {

/**
 * @see GraphVisitor#visit(DirectedGraph)
 */
public void revisit(DirectedGraph g) {
	for (int i = 0; i < g.edges.size(); i++) {
		Edge edge = (Edge)g.edges.get(i);
		edge.start = new Point(
			edge.getSourceOffset() + edge.source.x,
			edge.source.y + edge.source.height);
		if (edge.source instanceof SubgraphBoundary) {
			SubgraphBoundary boundary = (SubgraphBoundary)edge.source;
			if (boundary.getParent().head == boundary)
				edge.start.y = boundary.getParent().y + boundary.getParent().insets.top;
		}
		edge.end = new Point(
			edge.getTargetOffset() + edge.target.x,
			edge.target.y);
		
		if (edge.vNodes != null)
			routeLongEdge(edge, g);
		else {
			PointList list = new PointList();
			list.addPoint(edge.start);
			list.addPoint(edge.end);
			edge.setPoints(list);
		}
	}
}

static void routeLongEdge(Edge edge, DirectedGraph g) {
	ShortestPathRouter router = new ShortestPathRouter();
	Path path = new Path(edge.start, edge.end);
	router.addPath(path);
	Rectangle o;
	Insets padding;
	for (int i = 0; i < edge.vNodes.size(); i++) {
		VirtualNode node = (VirtualNode)edge.vNodes.get(i);
		Node neighbor;
		if (node.left != null) {
			neighbor = node.left;
			o = new Rectangle(neighbor.x, neighbor.y, neighbor.width, neighbor.height);
			padding = g.getPadding(neighbor);
			o.width += padding.right + padding.left;
			o.width += (edge.getPadding() * 2);
			o.x -= (padding.left + edge.getPadding());
			o.union(o.getLocation().translate(-100000, 2));
			router.addObstacle(o);
		}
		if (node.right != null) {
			neighbor = node.right;
			o = new Rectangle(neighbor.x, neighbor.y, neighbor.width, neighbor.height);
			padding = g.getPadding(neighbor);
			o.width += padding.right + padding.left;
			o.width += (edge.getPadding() * 2);
			o.x -= (padding.left + edge.getPadding());
			o.union(o.getLocation().translate(100000, 2));
			router.addObstacle(o);
		}
	}
	router.setSpacing(0);
	router.solve();
	edge.setPoints(path.getPoints());
}

}
