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

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

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

/**
 * An implementation of {@link Connection} based on Polyline. PolylineConnection
 * adds the following additional features:
 * <UL>
 * <LI>
 * A {@link ConnectionRouter} may be provided which will be used to determine
 * the connections points.
 * <LI>
 * Children may be added. The bounds calculation is extended such that the
 * bounds is the smallest Rectangle which is large enough to display the
 * Polyline and all of its children figures.
 * <LI>
 * A {@link DelegatingLayout} is set as the default layout. A delegating layout
 * allows children to position themselves via {@link Locator Locators}.
 * </UL>
 * <P>
 */
public class PolylineConnection extends Polyline implements Connection,
		AnchorListener {

	private ConnectionAnchor startAnchor, endAnchor;
	private ConnectionRouter connectionRouter = ConnectionRouter.NULL;
	private RotatableDecoration startArrow, endArrow;

	{
		setLayoutManager(new DelegatingLayout());
		addPoint(new Point(0, 0));
		addPoint(new Point(100, 100));
	}

	/**
	 * Hooks the source and target anchors.
	 * 
	 * @see Figure#addNotify()
	 */
	public void addNotify() {
		super.addNotify();
		hookSourceAnchor();
		hookTargetAnchor();
	}

	/**
	 * Appends the given routing listener to the list of listeners.
	 * 
	 * @param listener
	 *            the routing listener
	 * @since 3.2
	 */
	public void addRoutingListener(RoutingListener listener) {
		if (connectionRouter instanceof RoutingNotifier) {
			RoutingNotifier notifier = (RoutingNotifier) connectionRouter;
			notifier.listeners.add(listener);
		} else
			connectionRouter = new RoutingNotifier(connectionRouter, listener);
	}

	/**
	 * Called by the anchors of this connection when they have moved,
	 * revalidating this polyline connection.
	 * 
	 * @param anchor
	 *            the anchor that moved
	 */
	public void anchorMoved(ConnectionAnchor anchor) {
		revalidate();
	}

	/**
	 * Returns the bounds which holds all the points in this polyline
	 * connection. Returns any previously existing bounds, else calculates by
	 * unioning all the children's dimensions.
	 * 
	 * @return the bounds
	 */
	public Rectangle getBounds() {
		if (bounds == null) {
			super.getBounds();
			for (int i = 0; i < getChildren().size(); i++) {
				IFigure child = (IFigure) getChildren().get(i);
				bounds.union(child.getBounds());
			}
		}
		return bounds;
	}

	/**
	 * Returns the <code>ConnectionRouter</code> used to layout this connection.
	 * Will not return <code>null</code>.
	 * 
	 * @return this connection's router
	 */
	public ConnectionRouter getConnectionRouter() {
		if (connectionRouter instanceof RoutingNotifier)
			return ((RoutingNotifier) connectionRouter).realRouter;
		return connectionRouter;
	}

	/**
	 * Returns this connection's routing constraint from its connection router.
	 * May return <code>null</code>.
	 * 
	 * @return the connection's routing constraint
	 */
	public Object getRoutingConstraint() {
		if (getConnectionRouter() != null)
			return getConnectionRouter().getConstraint(this);
		else
			return null;
	}

	/**
	 * @return the anchor at the start of this polyline connection (may be null)
	 */
	public ConnectionAnchor getSourceAnchor() {
		return startAnchor;
	}

	/**
	 * @return the source decoration (may be null)
	 */
	protected RotatableDecoration getSourceDecoration() {
		return startArrow;
	}

	/**
	 * @return the anchor at the end of this polyline connection (may be null)
	 */
	public ConnectionAnchor getTargetAnchor() {
		return endAnchor;
	}

	/**
	 * @return the target decoration (may be null)
	 * 
	 * @since 2.0
	 */
	protected RotatableDecoration getTargetDecoration() {
		return endArrow;
	}

	private void hookSourceAnchor() {
		if (getSourceAnchor() != null)
			getSourceAnchor().addAnchorListener(this);
	}

	private void hookTargetAnchor() {
		if (getTargetAnchor() != null)
			getTargetAnchor().addAnchorListener(this);
	}

	/**
	 * Layouts this polyline. If the start and end anchors are present, the
	 * connection router is used to route this, after which it is laid out. It
	 * also fires a moved method.
	 */
	public void layout() {
		if (getSourceAnchor() != null && getTargetAnchor() != null)
			connectionRouter.route(this);

		Rectangle oldBounds = bounds;
		super.layout();
		bounds = null;

		if (!getBounds().contains(oldBounds)) {
			getParent().translateToParent(oldBounds);
			getUpdateManager().addDirtyRegion(getParent(), oldBounds);
		}

		repaint();
		fireFigureMoved();
	}

	/**
	 * Called just before the receiver is being removed from its parent. Results
	 * in removing itself from the connection router.
	 * 
	 * @since 2.0
	 */
	public void removeNotify() {
		unhookSourceAnchor();
		unhookTargetAnchor();
		connectionRouter.remove(this);
		super.removeNotify();
	}

	/**
	 * Removes the first occurence of the given listener.
	 * 
	 * @param listener
	 *            the listener being removed
	 * @since 3.2
	 */
	public void removeRoutingListener(RoutingListener listener) {
		if (connectionRouter instanceof RoutingNotifier) {
			RoutingNotifier notifier = (RoutingNotifier) connectionRouter;
			notifier.listeners.remove(listener);
			if (notifier.listeners.isEmpty())
				connectionRouter = notifier.realRouter;
		}
	}

	/**
	 * @see IFigure#revalidate()
	 */
	public void revalidate() {
		super.revalidate();
		connectionRouter.invalidate(this);
	}

	/**
	 * Sets the connection router which handles the layout of this polyline.
	 * Generally set by the parent handling the polyline connection.
	 * 
	 * @param cr
	 *            the connection router
	 */
	public void setConnectionRouter(ConnectionRouter cr) {
		if (cr == null)
			cr = ConnectionRouter.NULL;
		ConnectionRouter oldRouter = getConnectionRouter();
		if (oldRouter != cr) {
			connectionRouter.remove(this);
			if (connectionRouter instanceof RoutingNotifier)
				((RoutingNotifier) connectionRouter).realRouter = cr;
			else
				connectionRouter = cr;
			firePropertyChange(Connection.PROPERTY_CONNECTION_ROUTER,
					oldRouter, cr);
			revalidate();
		}
	}

	/**
	 * Sets the routing constraint for this connection.
	 * 
	 * @param cons
	 *            the constraint
	 */
	public void setRoutingConstraint(Object cons) {
		if (connectionRouter != null)
			connectionRouter.setConstraint(this, cons);
		revalidate();
	}

	/**
	 * Sets the anchor to be used at the start of this polyline connection.
	 * 
	 * @param anchor
	 *            the new source anchor
	 */
	public void setSourceAnchor(ConnectionAnchor anchor) {
		if (anchor == startAnchor)
			return;
		unhookSourceAnchor();
		// No longer needed, revalidate does this.
		// getConnectionRouter().invalidate(this);
		startAnchor = anchor;
		if (getParent() != null)
			hookSourceAnchor();
		revalidate();
	}

	/**
	 * Sets the decoration to be used at the start of the {@link Connection}.
	 * 
	 * @param dec
	 *            the new source decoration
	 * @since 2.0
	 */
	public void setSourceDecoration(RotatableDecoration dec) {
		if (startArrow == dec)
			return;
		if (startArrow != null)
			remove(startArrow);
		startArrow = dec;
		if (startArrow != null)
			add(startArrow, new ArrowLocator(this, ConnectionLocator.SOURCE));
	}

	/**
	 * Sets the anchor to be used at the end of the polyline connection. Removes
	 * this listener from the old anchor and adds it to the new anchor.
	 * 
	 * @param anchor
	 *            the new target anchor
	 */
	public void setTargetAnchor(ConnectionAnchor anchor) {
		if (anchor == endAnchor)
			return;
		unhookTargetAnchor();
		// No longer needed, revalidate does this.
		// getConnectionRouter().invalidate(this);
		endAnchor = anchor;
		if (getParent() != null)
			hookTargetAnchor();
		revalidate();
	}

	/**
	 * Sets the decoration to be used at the end of the {@link Connection}.
	 * 
	 * @param dec
	 *            the new target decoration
	 */
	public void setTargetDecoration(RotatableDecoration dec) {
		if (endArrow == dec)
			return;
		if (endArrow != null)
			remove(endArrow);
		endArrow = dec;
		if (endArrow != null)
			add(endArrow, new ArrowLocator(this, ConnectionLocator.TARGET));
	}

	private void unhookSourceAnchor() {
		if (getSourceAnchor() != null)
			getSourceAnchor().removeAnchorListener(this);
	}

	private void unhookTargetAnchor() {
		if (getTargetAnchor() != null)
			getTargetAnchor().removeAnchorListener(this);
	}

	final class RoutingNotifier implements ConnectionRouter {

		ConnectionRouter realRouter;
		List listeners = new ArrayList(1);

		RoutingNotifier(ConnectionRouter router, RoutingListener listener) {
			realRouter = router;
			listeners.add(listener);
		}

		public Object getConstraint(Connection connection) {
			return realRouter.getConstraint(connection);
		}

		public void invalidate(Connection connection) {
			for (int i = 0; i < listeners.size(); i++)
				((RoutingListener) listeners.get(i)).invalidate(connection);

			realRouter.invalidate(connection);
		}

		public void route(Connection connection) {
			boolean consumed = false;
			for (int i = 0; i < listeners.size(); i++)
				consumed |= ((RoutingListener) listeners.get(i))
						.route(connection);

			if (!consumed)
				realRouter.route(connection);

			for (int i = 0; i < listeners.size(); i++)
				((RoutingListener) listeners.get(i)).postRoute(connection);
		}

		public void remove(Connection connection) {
			for (int i = 0; i < listeners.size(); i++)
				((RoutingListener) listeners.get(i)).remove(connection);
			realRouter.remove(connection);
		}

		public void setConstraint(Connection connection, Object constraint) {
			for (int i = 0; i < listeners.size(); i++)
				((RoutingListener) listeners.get(i)).setConstraint(connection,
						constraint);
			realRouter.setConstraint(connection, constraint);
		}

	}

}
