/*****************************************************************************
 * Copyright (c) 2014-15 CEA LIST, Montages AG 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:
 *   Michael Golubev (Montages) - Initial API and implementation
 *   
 *****************************************************************************/
package org.eclipse.gmf.tooling.runtime.linklf;

import java.util.Collections;
import java.util.List;

import org.eclipse.draw2d.AbsoluteBendpoint;
import org.eclipse.draw2d.Bendpoint;
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.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.RelativeBendpoints;
import org.eclipse.gmf.runtime.notation.datatype.RelativeBendpoint;

/**
 * This class defines when to enable the enhanced link anchors and bendpoints
 * behavior, which implementation is based on storing the fixed bendpoints
 * coordinates instead of their relative locations to anchors.
 * 
 * @since 3.3
 */
public abstract class AbsoluteBendpointsConvention {

	private static AbsoluteBendpointsConvention ourInstance;

	public static AbsoluteBendpointsConvention getInstance() {
		if (ourInstance == null) {
			// ourInstance = new OnlyForNewLinks();
			ourInstance = new ForAllLinks();
		}
		return ourInstance;
	}

	public abstract RelativeBendpoint createAbsoluteBendpointStoredAsRelative(
			Point point);

	public abstract boolean isAbsoluteStoredAsRelative(RelativeBendpoint modelBP);

	public abstract Bendpoint d2dBendpoint(RelativeBendpoint modelBP,
			Connection connection, float weight);

	public abstract boolean hasAbsoluteStoredAsRelativeBendpoints(Edge edge);

	public abstract PointList getPointList(Edge edge, Object linkConstraint);

	private abstract static class ConventionBase extends
			AbsoluteBendpointsConvention {

		private static final int MAGIC = -643984;

		@Override
		public RelativeBendpoint createAbsoluteBendpointStoredAsRelative(
				Point point) {
			return new RelativeBendpoint(point.x, point.y, MAGIC, MAGIC);
		}

		@Override
		public boolean isAbsoluteStoredAsRelative(RelativeBendpoint modelBP) {
			return modelBP.getTargetX() == MAGIC
					&& modelBP.getTargetY() == MAGIC;
		}

		@Override
		public Bendpoint d2dBendpoint(RelativeBendpoint modelBP,
				Connection connection, float weight) {
			if (isAbsoluteStoredAsRelative(modelBP)) {
				return new AbsoluteBendpoint(modelBP.getSourceX(),
						modelBP.getSourceY());
			}
			return null;
		}

		@Override
		public PointList getPointList(Edge edge, Object linkConstraint) {
			PointList result = new PointList();
			List<?> d2dBendpoints = linkConstraint instanceof List<?> ? (List<?>) linkConstraint
					: Collections.emptyList();
			RelativeBendpoints allModelBendpoints = (RelativeBendpoints) edge
					.getBendpoints();
			@SuppressWarnings("unchecked")
			List<RelativeBendpoint> modelBendpoints = allModelBendpoints
					.getPoints();
			for (int i = 0; i < modelBendpoints.size(); i++) {
				RelativeBendpoint nextModel = modelBendpoints.get(i);
				Object nextD2d = d2dBendpoints.size() > i ? d2dBendpoints
						.get(i) : null;

				Point nextPoint = getLocation(nextModel, nextD2d);
				if (nextPoint == null) {
					throw new IllegalStateException(
							"Can't extract location: modelBP: " + nextModel
									+ ", d2dBP: " + nextD2d);
				}
				result.addPoint(nextPoint);
			}
			return result;
		}

		protected static org.eclipse.draw2d.RelativeBendpoint newRelativeBendpointD2d(
				RelativeBendpoint modelBP, Connection connection, float weight) {
			org.eclipse.draw2d.RelativeBendpoint rbp = new org.eclipse.draw2d.RelativeBendpoint(
					connection);
			rbp.setRelativeDimensions(new Dimension(modelBP.getSourceX(),
					modelBP.getSourceY()), //
					new Dimension(modelBP.getTargetX(), modelBP.getTargetY()));
			rbp.setWeight(weight);
			return rbp;
		}

		protected abstract Point getLocation(RelativeBendpoint modelBendpoint,
				Object d2dbendpoint);

	}

	protected static class OnlyForNewLinks extends ConventionBase {

		@Override
		public Bendpoint d2dBendpoint(RelativeBendpoint modelBP,
				Connection connection, float weight) {
			Bendpoint result = super.d2dBendpoint(modelBP, connection, weight);
			if (result == null) {
				result = newRelativeBendpointD2d(modelBP, connection, weight);
			}
			return result;
		}

		@Override
		public boolean hasAbsoluteStoredAsRelativeBendpoints(Edge edge) {
			List<?> bendpoints = ((RelativeBendpoints) edge.getBendpoints())
					.getPoints();
			for (Object o : bendpoints) {
				if (o instanceof RelativeBendpoint
						&& isAbsoluteStoredAsRelative((RelativeBendpoint) o)) {
					return true;
				}
			}
			return false;
		}

		@Override
		protected Point getLocation(RelativeBendpoint modelBendpoint,
				Object d2dbendpoint) {
			if (isAbsoluteStoredAsRelative(modelBendpoint)) {
				return new Point(modelBendpoint.getSourceX(),
						modelBendpoint.getSourceY());
			}
			if (d2dbendpoint instanceof Bendpoint) {
				return ((Bendpoint) d2dbendpoint).getLocation();
			}
			return null;
		}

	}

	protected static class ForAllLinks extends ConventionBase {

		@Override
		public Bendpoint d2dBendpoint(RelativeBendpoint modelBP,
				Connection connection, float weight) {
			Bendpoint result = super.d2dBendpoint(modelBP, connection, weight);
			if (result == null) {
				org.eclipse.draw2d.RelativeBendpoint rbp = newRelativeBendpointD2d(
						modelBP, connection, weight);
				// if(connection.getSourceAnchor() != null &&
				// connection.getTargetAnchor() != null) {
				result = new RelativeBendpointWrapper(rbp, connection);
				// }
			}
			return result;
		}

		@Override
		public boolean hasAbsoluteStoredAsRelativeBendpoints(Edge edge) {
			List<?> bendpoints = ((RelativeBendpoints) edge.getBendpoints())
					.getPoints();
			return !bendpoints.isEmpty();
		}

		@Override
		protected Point getLocation(RelativeBendpoint modelBendpoint,
				Object d2dBendpoint) {
			if (isAbsoluteStoredAsRelative(modelBendpoint)) {
				return new Point(modelBendpoint.getSourceX(),
						modelBendpoint.getSourceY());
			}
			if (d2dBendpoint instanceof AbsoluteBendpoint) {
				AbsoluteBendpoint wrapper = (AbsoluteBendpoint) d2dBendpoint;
				return wrapper.getLocation();
			}
			throw new IllegalStateException(
					"I had to create AbsoluteBendpointWrapper for this: "
							+ modelBendpoint + ", " + d2dBendpoint);
		}

		/**
		 * Provides implicit migration of the diagrams created before the
		 * LinksLF.
		 * <p/>
		 * Idea is to create the same "absolute" bendpoints for the old relative
		 * bendpoints created with previous version, and only update the
		 * persistence on the first modification of the link.
		 * <p/>
		 * However, positions of the {@link RelativeBendpoint} depends on the
		 * anchors and, more generally on the bounds of link ends, so they can't
		 * be computed immediately at the time of creation. This class
		 * introduced the deferred replacement, that is, once the
		 * {@link RelativeBendpoint} can compute its positions, their
		 * coordinates are saved and don't depend on the source or target
		 * anchors anymore.
		 */
		@SuppressWarnings("serial")
		private static class RelativeBendpointWrapper extends AbsoluteBendpoint {

			private Point myLocation = null;

			private org.eclipse.draw2d.RelativeBendpoint myRelativeBendpoint;

			private Connection myConnection;

			/**
			 * Wraps the {@link RelativeBendpoint} and defers computation of its
			 * positions until it is ready.
			 * 
			 * @param relativeBendpoint
			 * @param conn
			 */
			public RelativeBendpointWrapper(
					org.eclipse.draw2d.RelativeBendpoint relativeBendpoint,
					Connection conn) {
				super(new Point());
				myRelativeBendpoint = relativeBendpoint;
				myConnection = conn;
			}

			@Override
			public Point getLocation() {
				if (myLocation == null && isReadyToComputeLocation()) {
					myLocation = new Point(myRelativeBendpoint.getLocation());
					myRelativeBendpoint = null;
					myConnection = null;
				}
				return myLocation != null ? myLocation : myRelativeBendpoint
						.getLocation();
			}

			private boolean isReadyToComputeLocation() {
				if (myConnection == null) {
					return false;
				}
				ConnectionAnchor source = myConnection.getSourceAnchor();
				ConnectionAnchor target = myConnection.getTargetAnchor();
				if (source == null || target == null) {
					return false;
				}
				return hasLocation(source.getReferencePoint())
						&& hasLocation(target.getReferencePoint());
			}

			private boolean hasLocation(Point point) {
				return point != null && (point.x() != 0 || point.y() != 0);
			}

			@Override
			public int x() {
				return getLocation().x();
			}

			@Override
			public int y() {
				return getLocation().y();
			}
		}
	}
}
