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

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

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.PrecisionRectangle;
import org.eclipse.draw2d.geometry.Rectangle;

import org.eclipse.gef.handles.HandleBounds;
import org.eclipse.gef.requests.GroupRequest;

/**
 * A temporary helper used to perform snapping to existing elements. This helper
 * can be used in conjunction with the
 * {@link org.eclipse.gef.tools.DragEditPartsTracker DragEditPartsTracker} when
 * dragging editparts within a graphical viewer. Snapping is based on the
 * existing children of a <I>container</I>. When snapping a rectangle, the edges
 * of the rectangle will snap to edges of other rectangles generated from the
 * children of the given container. Similarly, the centers and middles of
 * rectangles will snap to each other.
 * <P>
 * If the snap request is being made during a Move, Reparent or Resize, then the
 * figures of the participants of that request will not be used for snapping. If
 * the request is a Clone, then the figures for the parts being cloned will be
 * used as possible snap locations.
 * <P>
 * This helper does not keep up with changes made to the container editpart.
 * Clients should instantiate a new helper each time one is requested and not
 * hold on to instances of the helper.
 * 
 * @since 3.0
 * @author Randy Hudson
 * @author Pratik Shah
 */
public class SnapToGeometry extends SnapToHelper {

	/**
	 * A property indicating whether this helper should be used. The value
	 * should be an instance of Boolean. Currently, this class does not check to
	 * see if the viewer property is set to <code>true</code>.
	 * 
	 * @see EditPartViewer#setProperty(String, Object)
	 */
	public static final String PROPERTY_SNAP_ENABLED = "SnapToGeometry.isEnabled"; //$NON-NLS-1$

	/**
	 * The key used to identify the North anchor point in the extended data of a
	 * request. The north anchor may be set to an {@link Integer} value
	 * indicating where the snapping is occurring. This is used for feedback
	 * purposes.
	 */
	public static final String KEY_NORTH_ANCHOR = "SnapToGeometry.NorthAnchor"; //$NON-NLS-1$

	/**
	 * The key used to identify the South anchor point in the extended data of a
	 * request. The south anchor may be set to an {@link Integer} value
	 * indicating where the snapping is occurring. This is used for feedback
	 * purposes.
	 */
	public static final String KEY_SOUTH_ANCHOR = "SnapToGeometry.SouthAnchor"; //$NON-NLS-1$

	/**
	 * The key used to identify the West anchor point in the extended data of a
	 * request. The west anchor may be set to an {@link Integer} value
	 * indicating where the snapping is occurring. This is used for feedback
	 * purposes.
	 */
	public static final String KEY_WEST_ANCHOR = "SnapToGeometry.WestAnchor"; //$NON-NLS-1$

	/**
	 * The key used to identify the East anchor point in the extended data of a
	 * request. The east anchor may be set to an {@link Integer} value
	 * indicating where the snapping is occurring. This is used for feedback
	 * purposes.
	 */
	public static final String KEY_EAST_ANCHOR = "SnapToGeometry.EastAnchor"; //$NON-NLS-1$

	/**
	 * A vertical or horizontal snapping point. since 3.0
	 */
	protected static class Entry {
		final int type;
		final int location;

		/**
		 * Constructs a new entry of the given type and location.
		 * 
		 * @param type
		 *            an integer between -1 and 1 inclusively
		 * @param location
		 *            the location
		 */
		protected Entry(int type, int location) {
			if (type < -1 || type > 1)
				throw new IllegalArgumentException("Unrecognized snap type"); //$NON-NLS-1$
			this.type = type;
			this.location = location;
		}

		/**
		 * Returns the location of the snap entry.
		 * 
		 * @return the location
		 * @since 3.2
		 */
		public int getLocation() {
			return location;
		}

		/**
		 * Returns the snap type. The following values may be returned.
		 * <UL>
		 * <LI>-1 indicates left/top
		 * <LI>0 indicates middle/center
		 * <LI>1 indicates right/bottom
		 * </UL>
		 * 
		 * @return the snap type
		 * @since 3.2
		 */
		public int getType() {
			return type;
		}
	}

	/**
	 * The sensitivity of the snapping. Corrections greater than this value will
	 * not occur.
	 */
	protected static final double THRESHOLD = 5.0001;

	private double threshold = THRESHOLD;

	boolean cachedCloneBool;

	/**
	 * The horizontal rows being snapped to.
	 */
	protected Entry rows[];

	/**
	 * The vertical columnd being snapped to.
	 */
	protected Entry cols[];

	/**
	 * The container editpart providing the coordinates and the children to
	 * which snapping occurs.
	 */
	protected GraphicalEditPart container;

	/**
	 * Constructs a helper that will use the given part as its basis for
	 * snapping. The part's contents pane will provide the coordinate system and
	 * its children determine the existing elements.
	 * 
	 * @since 3.0
	 * @param container
	 *            the container editpart
	 */
	public SnapToGeometry(GraphicalEditPart container) {
		this.container = container;
	}

	/**
	 * Get the sensitivity of the snapping. Corrections greater than this value
	 * will not occur.
	 * 
	 * @return the snapping threshold
	 * @since 3.4
	 */
	protected double getThreshold() {
		return this.threshold;
	}

	/**
	 * Set the sensitivity of the snapping.
	 * 
	 * @see #getThreshold()
	 * @param newThreshold
	 *            the new snapping threshold
	 * @since 3.4
	 */
	protected void setThreshold(double newThreshold) {
		this.threshold = newThreshold;
	}

	/**
	 * Generates a list of parts which should be snapped to. The list is the
	 * original children, minus the given exclusions, minus and children whose
	 * figures are not visible.
	 * 
	 * @since 3.0
	 * @param exclusions
	 *            the children to exclude
	 * @return a list of parts which should be snapped to
	 */
	protected List generateSnapPartsList(List exclusions) {
		// Don't snap to any figure that is being dragged
		List children = new ArrayList(container.getChildren());
		children.removeAll(exclusions);

		// Don't snap to hidden figures
		List hiddenChildren = new ArrayList();
		for (Iterator iter = children.iterator(); iter.hasNext();) {
			GraphicalEditPart child = (GraphicalEditPart) iter.next();
			if (!child.getFigure().isVisible())
				hiddenChildren.add(child);
		}
		children.removeAll(hiddenChildren);

		return children;
	}

	/**
	 * Returns the correction value for the given entries and sides. During a
	 * move, the left, right, or center is free to snap to a location.
	 * 
	 * @param entries
	 *            the entries
	 * @param extendedData
	 *            the requests extended data
	 * @param vert
	 *            <code>true</code> if the correction is vertical
	 * @param near
	 *            the left/top side of the rectangle
	 * @param far
	 *            the right/bottom side of the rectangle
	 * @return the correction amount or #getThreshold () if no correction was
	 *         made
	 */
	protected double getCorrectionFor(Entry entries[], Map extendedData,
			boolean vert, double near, double far) {
		far -= 1.0;
		double total = near + far;
		// If the width is even (i.e., odd right now because we have reduced one
		// pixel from
		// far) there is no middle pixel so favor the left-most/top-most pixel
		// (which is what
		// populateRowsAndCols() does by using int precision).
		if ((int) (near - far) % 2 != 0)
			total -= 1.0;
		double result = getCorrectionFor(entries, extendedData, vert,
				total / 2, 0);
		if (result == getThreshold())
			result = getCorrectionFor(entries, extendedData, vert, near, -1);
		if (result == getThreshold())
			result = getCorrectionFor(entries, extendedData, vert, far, 1);
		return result;
	}

	/**
	 * Returns the correction value between +/- {@link #getThreshold()}, or the
	 * #getThreshold () if no corrections were found.
	 * 
	 * @param entries
	 *            the entries
	 * @param extendedData
	 *            the map for setting values
	 * @param vert
	 *            <code>true</code> if vertical
	 * @param value
	 *            the value being corrected
	 * @param side
	 *            which sides should be considered
	 * @return the correction or #getThreshold () if no correction was made
	 */
	protected double getCorrectionFor(Entry entries[], Map extendedData,
			boolean vert, double value, int side) {
		double resultMag = getThreshold();
		double result = getThreshold();

		String property;
		if (side == -1)
			property = vert ? KEY_WEST_ANCHOR : KEY_NORTH_ANCHOR;
		else
			property = vert ? KEY_EAST_ANCHOR : KEY_SOUTH_ANCHOR;

		for (int i = 0; i < entries.length; i++) {
			Entry entry = entries[i];
			double magnitude;

			if (entry.type == -1 && side != 0) {
				magnitude = Math.abs(value - entry.location);
				if (magnitude < resultMag) {
					resultMag = magnitude;
					result = entry.location - value;
					extendedData.put(property, new Integer(entry.location));
				}
			} else if (entry.type == 0 && side == 0) {
				magnitude = Math.abs(value - entry.location);
				if (magnitude < resultMag) {
					resultMag = magnitude;
					result = entry.location - value;
					extendedData.put(property, new Integer(entry.location));
				}
			} else if (entry.type == 1 && side != 0) {
				magnitude = Math.abs(value - entry.location);
				if (magnitude < resultMag) {
					resultMag = magnitude;
					result = entry.location - value;
					extendedData.put(property, new Integer(entry.location));
				}
			}
		}
		return result;
	}

	/**
	 * Returns the rectangular contribution for the given editpart. This is the
	 * rectangle with which snapping is performed.
	 * 
	 * @since 3.0
	 * @param part
	 *            the child
	 * @return the rectangular guide for that part
	 */
	protected Rectangle getFigureBounds(GraphicalEditPart part) {
		IFigure fig = part.getFigure();
		if (fig instanceof HandleBounds)
			return ((HandleBounds) fig).getHandleBounds();
		return fig.getBounds();
	}

	/**
	 * Updates the cached row and column Entries using the provided parts.
	 * 
	 * @since 3.0
	 * @param parts
	 *            a List of EditParts
	 */
	protected void populateRowsAndCols(List parts) {
		rows = new Entry[parts.size() * 3];
		cols = new Entry[parts.size() * 3];
		for (int i = 0; i < parts.size(); i++) {
			GraphicalEditPart child = (GraphicalEditPart) parts.get(i);
			Rectangle bounds = getFigureBounds(child);
			cols[i * 3] = new Entry(-1, bounds.x);
			rows[i * 3] = new Entry(-1, bounds.y);
			cols[i * 3 + 1] = new Entry(0, bounds.x + (bounds.width - 1) / 2);
			rows[i * 3 + 1] = new Entry(0, bounds.y + (bounds.height - 1) / 2);
			cols[i * 3 + 2] = new Entry(1, bounds.right() - 1);
			rows[i * 3 + 2] = new Entry(1, bounds.bottom() - 1);
		}
	}

	/**
	 * @see SnapToHelper#snapRectangle(Request, int, PrecisionRectangle,
	 *      PrecisionRectangle)
	 */
	public int snapRectangle(Request request, int snapOrientation,
			PrecisionRectangle baseRect, PrecisionRectangle result) {

		baseRect = baseRect.getPreciseCopy();
		makeRelative(container.getContentPane(), baseRect);
		PrecisionRectangle correction = new PrecisionRectangle();
		makeRelative(container.getContentPane(), correction);

		// Recalculate snapping locations if needed
		boolean isClone = request.getType().equals(RequestConstants.REQ_CLONE);
		if (rows == null || cols == null || isClone != cachedCloneBool) {
			cachedCloneBool = isClone;
			List exclusionSet = Collections.EMPTY_LIST;
			if (!isClone && request instanceof GroupRequest)
				exclusionSet = ((GroupRequest) request).getEditParts();
			populateRowsAndCols(generateSnapPartsList(exclusionSet));
		}

		if ((snapOrientation & HORIZONTAL) != 0) {
			double xcorrect = getThreshold();
			xcorrect = getCorrectionFor(cols, request.getExtendedData(), true,
					baseRect.preciseX(), baseRect.preciseRight());
			if (xcorrect != getThreshold()) {
				snapOrientation &= ~HORIZONTAL;
				correction.setPreciseX(correction.preciseX() + xcorrect);
			}
		}

		if ((snapOrientation & VERTICAL) != 0) {
			double ycorrect = getThreshold();
			ycorrect = getCorrectionFor(rows, request.getExtendedData(), false,
					baseRect.preciseY(), baseRect.preciseBottom());
			if (ycorrect != getThreshold()) {
				snapOrientation &= ~VERTICAL;
				correction.setPreciseY(correction.preciseY() + ycorrect);
			}
		}

		if ((snapOrientation & EAST) != 0) {
			double rightCorrection = getCorrectionFor(cols,
					request.getExtendedData(), true,
					baseRect.preciseRight() - 1, 1);
			if (rightCorrection != getThreshold()) {
				snapOrientation &= ~EAST;
				correction.setPreciseWidth(correction.preciseWidth()
						+ rightCorrection);
			}
		}

		if ((snapOrientation & WEST) != 0) {
			double leftCorrection = getCorrectionFor(cols,
					request.getExtendedData(), true, baseRect.preciseX(), -1);
			if (leftCorrection != getThreshold()) {
				snapOrientation &= ~WEST;
				correction.setPreciseWidth(correction.preciseWidth()
						- leftCorrection);
				correction.setPreciseX(correction.preciseX() + leftCorrection);
			}
		}

		if ((snapOrientation & SOUTH) != 0) {
			double bottom = getCorrectionFor(rows, request.getExtendedData(),
					false, baseRect.preciseBottom() - 1, 1);
			if (bottom != getThreshold()) {
				snapOrientation &= ~SOUTH;
				correction
						.setPreciseHeight(correction.preciseHeight() + bottom);
			}
		}

		if ((snapOrientation & NORTH) != 0) {
			double topCorrection = getCorrectionFor(rows,
					request.getExtendedData(), false, baseRect.preciseY(), -1);
			if (topCorrection != getThreshold()) {
				snapOrientation &= ~NORTH;
				correction.setPreciseHeight(correction.preciseHeight()
						- topCorrection);
				correction.setPreciseY(correction.preciseY() + topCorrection);
			}
		}

		makeAbsolute(container.getContentPane(), correction);
		result.setPreciseX(result.preciseX() + correction.preciseX());
		result.setPreciseY(result.preciseY() + correction.preciseY());
		result.setPreciseWidth(result.preciseWidth()
				+ correction.preciseWidth());
		result.setPreciseHeight(result.preciseHeight()
				+ correction.preciseHeight());
		return snapOrientation;
	}

}
