/*******************************************************************************
 * Copyright (c) 2005, 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 org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;

/**
 * Animates the routing of a connection. The animator will capture the effects
 * of the connection's router, and the play back the placement of the routing,
 * interpolating the intermediate routes.
 * <P>
 * To use a routing animator, hook it as a routing listener for the connection
 * whose points are to be animated, by calling
 * {@link PolylineConnection#addRoutingListener(RoutingListener)}. An animator
 * is active only when the Animation utility is activated.
 * 
 * @since 3.2
 */
public class RoutingAnimator extends Animator implements RoutingListener {

	static final RoutingAnimator INSTANCE = new RoutingAnimator();

	/**
	 * Constructs a routing animator for use with one or more connections. The
	 * default instance ({@link #getDefault()} can be used on any number of
	 * connections.
	 * 
	 * @since 3.2
	 */
	protected RoutingAnimator() {
	}

	/**
	 * Overridden to sync initial and final states.
	 * 
	 * @see Animator#playbackStarting(IFigure)
	 */
	public void playbackStarting(IFigure connection) {
		reconcileStates((Connection) connection);
	}

	/**
	 * Returns the current state of the connection. Currently, this is a copy of
	 * the list of points. However this Object could change in future releases
	 * and should not be considered API.
	 * 
	 * @see Animator#getCurrentState(IFigure)
	 */
	protected Object getCurrentState(IFigure connection) {
		return ((Connection) connection).getPoints().getCopy();
	}

	/**
	 * Returns the default instance.
	 * 
	 * @return the default instance
	 * @since 3.2
	 */
	public static RoutingAnimator getDefault() {
		return INSTANCE;
	}

	/**
	 * Hooks invalidate for animation purposes.
	 * 
	 * @see RoutingListener#invalidate(Connection)
	 */
	public final void invalidate(Connection conn) {
		if (Animation.isInitialRecording())
			Animation.hookAnimator(conn, this);
	}

	/**
	 * Plays back the interpolated state.
	 * 
	 * @see Animator#playback(IFigure)
	 */
	protected boolean playback(IFigure figure) {
		Connection conn = (Connection) figure;

		PointList list1 = (PointList) Animation.getInitialState(this, conn);
		PointList list2 = (PointList) Animation.getFinalState(this, conn);
		if (list1 == null) {
			conn.setVisible(false);
			return true;
		}

		float progress = Animation.getProgress();
		if (list1.size() == list2.size()) {
			Point pt1 = new Point(), pt2 = new Point();
			PointList points = conn.getPoints();
			points.removeAllPoints();
			for (int i = 0; i < list1.size(); i++) {
				list1.getPoint(pt2, i);
				list2.getPoint(pt1, i);
				pt1.x = Math.round(pt1.x * progress + (1 - progress) * pt2.x);
				pt1.y = Math.round(pt1.y * progress + (1 - progress) * pt2.y);
				points.addPoint(pt1);
			}
			conn.setPoints(points);
		}
		return true;
	}

	/**
	 * Hooks post routing for animation purposes.
	 * 
	 * @see RoutingListener#postRoute(Connection)
	 */
	public final void postRoute(Connection connection) {
		if (Animation.isFinalRecording())
			Animation.hookNeedsCapture(connection, this);
	}

	private void reconcileStates(Connection conn) {
		PointList points1 = (PointList) Animation.getInitialState(this, conn);
		PointList points2 = (PointList) Animation.getFinalState(this, conn);

		if (points1 != null && points1.size() != points2.size()) {
			Point p = new Point(), q = new Point();

			int size1 = points1.size() - 1;
			int size2 = points2.size() - 1;

			int i1 = size1;
			int i2 = size2;

			double current1 = 1.0;
			double current2 = 1.0;

			double prev1 = 1.0;
			double prev2 = 1.0;

			while (i1 > 0 || i2 > 0) {
				if (Math.abs(current1 - current2) < 0.1 && i1 > 0 && i2 > 0) {
					// Both points are the same, use them and go on;
					prev1 = current1;
					prev2 = current2;
					i1--;
					i2--;
					current1 = (double) i1 / size1;
					current2 = (double) i2 / size2;
				} else if (current1 < current2) {
					// 2 needs to catch up
					// current1 < current2 < prev1
					points1.getPoint(p, i1);
					points1.getPoint(q, i1 + 1);

					p.x = (int) (((q.x * (current2 - current1) + p.x
							* (prev1 - current2)) / (prev1 - current1)));
					p.y = (int) (((q.y * (current2 - current1) + p.y
							* (prev1 - current2)) / (prev1 - current1)));

					points1.insertPoint(p, i1 + 1);

					prev1 = prev2 = current2;
					i2--;
					current2 = (double) i2 / size2;

				} else {
					// 1 needs to catch up
					// current2< current1 < prev2

					points2.getPoint(p, i2);
					points2.getPoint(q, i2 + 1);

					p.x = (int) (((q.x * (current1 - current2) + p.x
							* (prev2 - current1)) / (prev2 - current2)));
					p.y = (int) (((q.y * (current1 - current2) + p.y
							* (prev2 - current1)) / (prev2 - current2)));

					points2.insertPoint(p, i2 + 1);

					prev2 = prev1 = current1;
					i1--;
					current1 = (double) i1 / size1;
				}
			}
		}
	}

	/**
	 * This callback is unused. Reserved for possible future use.
	 * 
	 * @see RoutingListener#remove(Connection)
	 */
	public final void remove(Connection connection) {
	}

	/**
	 * Hooks route to intercept routing during animation playback.
	 * 
	 * @see RoutingListener#route(Connection)
	 */
	public final boolean route(Connection conn) {
		return Animation.isAnimating() && Animation.hookPlayback(conn, this);
	}

	/**
	 * This callback is unused. Reserved for possible future use.
	 * 
	 * @see RoutingListener#setConstraint(Connection, Object)
	 */
	public final void setConstraint(Connection connection, Object constraint) {
	}

}
