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

import com.ibm.icu.text.DecimalFormat;
import com.ibm.icu.text.NumberFormat;

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

import org.eclipse.swt.widgets.Display;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.Platform;

import org.eclipse.draw2d.FreeformFigure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.ScalableFigure;
import org.eclipse.draw2d.ScalableFreeformLayeredPane;
import org.eclipse.draw2d.Viewport;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;

import org.eclipse.gef.SharedMessages;

/**
 * Manage the primary zoom function in a graphical viewer. This class is used by
 * the zoom contribution items, including:
 * <UL>
 * <LI>{@link org.eclipse.gef.ui.actions.ZoomInAction}
 * <LI>{@link org.eclipse.gef.ui.actions.ZoomOutAction}
 * <LI>and {@link org.eclipse.gef.ui.actions.ZoomComboContributionItem}
 * </UL>
 * <P>
 * A ZoomManager controls how zoom in and zoom out are performed. It also
 * determines the list of choices the user sees in the drop-down Combo on the
 * toolbar. The zoom manager controls a <code>ScalableFigure</code>, which
 * performs the actual zoom, and also a <code>Viewport</code>. The viewport is
 * needed so that the scrolled location is preserved as the zoom level changes.
 * <p>
 * <b>NOTE:</b> For the settings of {@link #FIT_ALL Page}, {@link #FIT_WIDTH
 * Width} and {@link #FIT_HEIGHT Height} to work properly, the given
 * <code>Viewport</code> should have its scrollbars always visible or never
 * visible. Otherwise, these settings may cause undesired effects.
 * 
 * @author Dan Lee
 * @author Eric Bordeau
 */
public class ZoomManager {

	/** Style bit meaning don't animate any zooms */
	public static final int ANIMATE_NEVER = 0;
	/** Style bit meaning animate during {@link #zoomIn()} and {@link #zoomOut()} */
	public static final int ANIMATE_ZOOM_IN_OUT = 1;

	private List listeners = new ArrayList();

	private double multiplier = 1.0;
	private ScalableFigure pane;
	private Viewport viewport;
	private double zoom = 1.0;
	// private int zoomAnimationStyle = ANIMATE_NEVER;
	private double[] zoomLevels = { .5, .75, 1.0, 1.5, 2.0, 2.5, 3, 4 };
	/**
	 * String constant for the "Height" zoom level. At this zoom level, the zoom
	 * manager will adopt a zoom setting such that the entire height of the
	 * diagram will be visible on the screen.
	 */
	public static final String FIT_HEIGHT = SharedMessages.FitHeightAction_Label;
	/**
	 * String constant for the "Width" zoom level. At this zoom level, the zoom
	 * manager will adopt a zoom setting such that the entire width of the
	 * diagram will be visible on the screen.
	 */
	public static final String FIT_WIDTH = SharedMessages.FitWidthAction_Label;
	/**
	 * String constant for the "Page" zoom level. At this zoom level, the zoom
	 * manager will adopt a zoom setting such that the entire diagram will be
	 * visible on the screen.
	 */
	public static final String FIT_ALL = SharedMessages.FitAllAction_Label;
	private List zoomLevelContributions = Collections.EMPTY_LIST;

	DecimalFormat format = new DecimalFormat("####%"); //$NON-NLS-1$

	/**
	 * Creates a new ZoomManager.
	 * 
	 * @param pane
	 *            The ScalableFigure associated with this ZoomManager
	 * @param viewport
	 *            The Viewport assoicated with this ZoomManager
	 */
	public ZoomManager(ScalableFigure pane, Viewport viewport) {
		this.pane = pane;
		this.viewport = viewport;
	}

	/**
	 * @deprecated Use {@link #ZoomManager(ScalableFigure, Viewport)} instead.
	 *             Creates a new ZoomManager
	 * @param pane
	 *            The ScalableFreeformLayeredPane associated with this
	 *            ZoomManager
	 * @param viewport
	 *            The Viewport assoicated with this viewport
	 */
	public ZoomManager(ScalableFreeformLayeredPane pane, Viewport viewport) {
		this.pane = pane;
		this.viewport = viewport;
	}

	/**
	 * Adds the given ZoomListener to this ZoomManager's list of listeners.
	 * 
	 * @param listener
	 *            the ZoomListener to be added
	 */
	public void addZoomListener(ZoomListener listener) {
		listeners.add(listener);
	}

	/**
	 * returns <code>true</code> if the zoommanager can perform
	 * <code>zoomIn()</code>.
	 * 
	 * @return boolean true if zoomIn can be called
	 */
	public boolean canZoomIn() {
		return getZoom() < getMaxZoom();
	}

	/**
	 * returns <code>true</code> if the zoommanager can perform
	 * <code>zoomOut()</code>.
	 * 
	 * @return boolean true if zoomOut can be called
	 */
	public boolean canZoomOut() {
		return getZoom() > getMinZoom();
	}

	/**
	 * Notifies listeners that the zoom level has changed.
	 */
	protected void fireZoomChanged() {
		Iterator iter = listeners.iterator();
		while (iter.hasNext())
			((ZoomListener) iter.next()).zoomChanged(zoom);
	}

	private double getFitXZoomLevel(int which) {
		IFigure fig = getScalableFigure();

		Dimension available = getViewport().getClientArea().getSize();
		Dimension desired;
		if (fig instanceof FreeformFigure)
			desired = ((FreeformFigure) fig).getFreeformExtent().getCopy()
					.union(0, 0).getSize();
		else
			desired = fig.getPreferredSize().getCopy();

		desired.width -= fig.getInsets().getWidth();
		desired.height -= fig.getInsets().getHeight();

		while (fig != getViewport()) {
			available.width -= fig.getInsets().getWidth();
			available.height -= fig.getInsets().getHeight();
			fig = fig.getParent();
		}

		double scaleX = Math.min(available.width * zoom / desired.width,
				getMaxZoom());
		double scaleY = Math.min(available.height * zoom / desired.height,
				getMaxZoom());
		if (which == 0)
			return scaleX;
		if (which == 1)
			return scaleY;
		return Math.min(scaleX, scaleY);
	}

	/**
	 * Calculates and returns the zoom percent required so that the entire
	 * height of the {@link #getScalableFigure() scalable figure} is visible on
	 * the screen. This is the zoom level associated with {@link #FIT_HEIGHT}.
	 * 
	 * @return zoom setting required to fit the scalable figure vertically on
	 *         the screen
	 */
	protected double getFitHeightZoomLevel() {
		return getFitXZoomLevel(1);
	}

	/**
	 * Calculates and returns the zoom percentage required to fit the entire
	 * {@link #getScalableFigure() scalable figure} on the screen. This is the
	 * zoom setting associated with {@link #FIT_ALL}. It is the minimum of
	 * {@link #getFitHeightZoomLevel()} and {@link #getFitWidthZoomLevel()}.
	 * 
	 * @return zoom setting required to fit the entire scalable figure on the
	 *         screen
	 */
	protected double getFitPageZoomLevel() {
		return getFitXZoomLevel(2);
	}

	/**
	 * Calculates and returns the zoom percentage required so that the entire
	 * width of the {@link #getScalableFigure() scalable figure} is visible on
	 * the screen. This is the zoom setting associated with {@link #FIT_WIDTH}.
	 * 
	 * @return zoom setting required to fit the scalable figure horizontally on
	 *         the screen
	 */
	protected double getFitWidthZoomLevel() {
		return getFitXZoomLevel(0);
	}

	/**
	 * Returns the maxZoom.
	 * 
	 * @return double
	 */
	public double getMaxZoom() {
		return getZoomLevels()[getZoomLevels().length - 1];
	}

	/**
	 * Returns the minZoom.
	 * 
	 * @return double
	 */
	public double getMinZoom() {
		return getZoomLevels()[0];
	}

	/**
	 * Returns the mutltiplier. This value is used to use zoom levels internally
	 * that are proportionally different than those displayed to the user. e.g.
	 * with a multiplier value of 2.0, the zoom level 1.0 will be displayed as
	 * "200%".
	 * 
	 * @return double The multiplier
	 */
	public double getUIMultiplier() {
		return multiplier;
	}

	/**
	 * Returns the zoom level that is one level higher than the current level.
	 * If zoom level is at maximum, returns the maximum.
	 * 
	 * @return double The next zoom level
	 */
	public double getNextZoomLevel() {
		for (int i = 0; i < zoomLevels.length; i++)
			if (zoomLevels[i] > zoom)
				return zoomLevels[i];
		return getMaxZoom();
	}

	/**
	 * @deprecated Use {@link #getScalableFigure()} instead. Returns the pane.
	 * @return the pane
	 */
	public ScalableFreeformLayeredPane getPane() {
		Assert.isTrue(pane instanceof ScalableFreeformLayeredPane);
		return (ScalableFreeformLayeredPane) pane;
	}

	/**
	 * Returns the zoom level that is one level higher than the current level.
	 * If zoom level is at maximum, returns the maximum.
	 * 
	 * @return double The previous zoom level
	 */
	public double getPreviousZoomLevel() {
		for (int i = 1; i < zoomLevels.length; i++)
			if (zoomLevels[i] >= zoom)
				return zoomLevels[i - 1];
		return getMinZoom();
	}

	/**
	 * Returns the figure which performs the actual zooming.
	 * 
	 * @return the scalable figure
	 */
	public ScalableFigure getScalableFigure() {
		return pane;
	}

	/**
	 * Returns the viewport.
	 * 
	 * @return Viewport
	 */
	public Viewport getViewport() {
		return viewport;
	}

	/**
	 * Returns the current zoom level.
	 * 
	 * @return double the zoom level
	 */
	public double getZoom() {
		return zoom;
	}

	/**
	 * Returns the current zoom level as a percentage formatted String
	 * 
	 * @return String The current zoom level as a String
	 */
	public String getZoomAsText() {
		String newItem = format.format(zoom * multiplier);
		return newItem;
	}

	/**
	 * Returns the list of strings that should be appended to the list of
	 * numerical zoom levels. These could be things such as Fit Width, Fit Page,
	 * etc. May return <code>null</code>.
	 * 
	 * @return the list of contributed zoom levels
	 */
	public List getZoomLevelContributions() {
		return zoomLevelContributions;
	}

	/**
	 * Returns the zoomLevels.
	 * 
	 * @return double[]
	 */
	public double[] getZoomLevels() {
		return zoomLevels;
	}

	/**
	 * Returns the list of zoom levels as Strings in percent notation, plus any
	 * additional zoom levels that were contributed using
	 * {@link #setZoomLevelContributions(List)}.
	 * 
	 * @return List The list of zoom levels
	 */
	public String[] getZoomLevelsAsText() {
		String[] zoomLevelStrings = new String[zoomLevels.length
				+ zoomLevelContributions.size()];
		for (int i = 0; i < zoomLevels.length; i++) {
			zoomLevelStrings[i] = format.format(zoomLevels[i] * multiplier);
		}
		if (zoomLevelContributions != null) {
			for (int i = 0; i < zoomLevelContributions.size(); i++) {
				zoomLevelStrings[i + zoomLevels.length] = (String) zoomLevelContributions
						.get(i);
			}
		}
		return zoomLevelStrings;
	}

	/**
	 * Sets the zoom level to the given value. Min-max range check is not done.
	 * 
	 * @param zoom
	 *            the new zoom level
	 */
	protected void primSetZoom(double zoom) {
		Point p1 = getViewport().getClientArea().getCenter();
		Point p2 = p1.getCopy();
		Point p = getViewport().getViewLocation();
		double prevZoom = this.zoom;
		this.zoom = zoom;
		pane.setScale(zoom);
		fireZoomChanged();
		getViewport().validate();

		p2.scale(zoom / prevZoom);
		Dimension dif = p2.getDifference(p1);
		p.x += dif.width;
		p.y += dif.height;
		setViewLocation(p);
	}

	/**
	 * Removes the given ZoomListener from this ZoomManager's list of listeners.
	 * 
	 * @param listener
	 *            the ZoomListener to be removed
	 */
	public void removeZoomListener(ZoomListener listener) {
		listeners.remove(listener);
	}

	/**
	 * Sets the UI multiplier. The UI multiplier is applied to all zoom settings
	 * when they are presented to the user ({@link #getZoomAsText()}).
	 * Similarly, the multiplier is inversely applied when the user specifies a
	 * zoom level ({@link #setZoomAsText(String)}).
	 * <P>
	 * When the UI multiplier is <code>1.0</code>, the User will see the exact
	 * zoom level that is being applied. If the value is <code>2.0</code>, then
	 * a scale of <code>0.5</code> will be labeled "100%" to the User.
	 * 
	 * @param multiplier
	 *            The mutltiplier to set
	 */
	public void setUIMultiplier(double multiplier) {
		this.multiplier = multiplier;
	}

	/**
	 * Sets the Viewport's view associated with this ZoomManager to the passed
	 * Point
	 * 
	 * @param p
	 *            The new location for the Viewport's view.
	 */
	public void setViewLocation(Point p) {
		viewport.setViewLocation(p.x, p.y);

	}

	/**
	 * Sets the zoom level to the given value. If the zoom is out of the min-max
	 * range, it will be ignored.
	 * 
	 * @param zoom
	 *            the new zoom level
	 */
	public void setZoom(double zoom) {
		zoom = Math.min(getMaxZoom(), zoom);
		zoom = Math.max(getMinZoom(), zoom);
		if (this.zoom != zoom)
			primSetZoom(zoom);
	}

	/**
	 * Sets which zoom methods get animated.
	 * 
	 * @param style
	 *            the style bits determining the zoom methods to be animated.
	 */
	public void setZoomAnimationStyle(int style) {
		// zoomAnimationStyle = style;
	}

	/**
	 * Sets zoom to the passed string. The string must be composed of numeric
	 * characters only with the exception of a decimal point and a '%' as the
	 * last character. If the zoom level contribution list has been set, this
	 * method should be overridden to provide the appropriate zoom
	 * implementation for the new zoom levels.
	 * 
	 * @param zoomString
	 *            The new zoom level
	 */
	public void setZoomAsText(String zoomString) {
		if (zoomString.equalsIgnoreCase(FIT_HEIGHT)) {
			primSetZoom(getFitHeightZoomLevel());
			viewport.getUpdateManager().performUpdate();
			viewport.setViewLocation(viewport.getHorizontalRangeModel()
					.getValue(), viewport.getVerticalRangeModel().getMinimum());
		} else if (zoomString.equalsIgnoreCase(FIT_ALL)) {
			primSetZoom(getFitPageZoomLevel());
			viewport.getUpdateManager().performUpdate();
			viewport.setViewLocation(viewport.getHorizontalRangeModel()
					.getMinimum(), viewport.getVerticalRangeModel()
					.getMinimum());
		} else if (zoomString.equalsIgnoreCase(FIT_WIDTH)) {
			primSetZoom(getFitWidthZoomLevel());
			viewport.getUpdateManager().performUpdate();
			viewport.setViewLocation(viewport.getHorizontalRangeModel()
					.getMinimum(), viewport.getVerticalRangeModel().getValue());
		} else {
			try {
				// Trim off the '%'
				if (zoomString.charAt(zoomString.length() - 1) == '%')
					zoomString = zoomString.substring(0,
							zoomString.length() - 1);
				double newZoom = NumberFormat.getInstance().parse(zoomString)
						.doubleValue() / 100;
				setZoom(newZoom / multiplier);
			} catch (Exception e) {
				// Workaround for MacOS X Cocoa Bugzilla 300837
				if (!("".equals(zoomString) && Platform.WS_COCOA //$NON-NLS-1$
						.equals(Platform.getWS()))) {
					Display.getCurrent().beep();
				}
			}
		}
	}

	/**
	 * Sets the list of zoom level contributions (as strings). If you contribute
	 * something <b>other than</b> {@link #FIT_HEIGHT}, {@link #FIT_WIDTH} and
	 * {@link #FIT_ALL} you must subclass this class and override this method to
	 * implement your contributed zoom function.
	 * 
	 * @param contributions
	 *            the list of contributed zoom levels
	 */
	public void setZoomLevelContributions(List contributions) {
		zoomLevelContributions = contributions;
	}

	/**
	 * Sets the zoomLevels.
	 * 
	 * @param zoomLevels
	 *            The zoomLevels to set
	 */
	public void setZoomLevels(double[] zoomLevels) {
		this.zoomLevels = zoomLevels;
	}

	/**
	 * Sets the zoom level to be one level higher
	 */
	public void zoomIn() {
		setZoom(getNextZoomLevel());
	}

	/**
	 * Currently does nothing.
	 * 
	 * @param rect
	 *            a rectangle
	 */
	public void zoomTo(Rectangle rect) {
	}

	// private void performAnimatedZoom(Rectangle rect, boolean zoomIn, int
	// iterationCount) {
	// double finalRatio;
	// double zoomIncrement;
	//
	// if (zoomIn) {
	// finalRatio = zoom / getNextZoomLevel();
	// zoomIncrement = (getNextZoomLevel() - zoom) / iterationCount;
	// } else {
	// finalRatio = zoom / getPreviousZoomLevel();
	// zoomIncrement = (getPreviousZoomLevel() - zoom) / iterationCount;
	// }
	//
	// getScalableFigure().translateToRelative(rect);
	// Point originalViewLocation = getViewport().getViewLocation();
	// Point finalViewLocation = calculateViewLocation(rect, finalRatio);
	//
	// double xIncrement =
	// (double) (finalViewLocation.x - originalViewLocation.x) / iterationCount;
	// double yIncrement =
	// (double) (finalViewLocation.y - originalViewLocation.y) / iterationCount;
	//
	// double originalZoom = zoom;
	// Point currentViewLocation = new Point();
	// for (int i = 1; i < iterationCount; i++) {
	// currentViewLocation.x = (int)(originalViewLocation.x + (xIncrement * i));
	// currentViewLocation.y = (int)(originalViewLocation.y + (yIncrement * i));
	// setZoom(originalZoom + zoomIncrement * i);
	// getViewport().validate();
	// setViewLocation(currentViewLocation);
	// getViewport().getUpdateManager().performUpdate();
	// }
	//
	// if (zoomIn)
	// setZoom(getNextZoomLevel());
	// else
	// setZoom(getPreviousZoomLevel());
	//
	// getViewport().validate();
	// setViewLocation(finalViewLocation);
	// }
	//
	// private Point calculateViewLocation(Rectangle zoomRect, double ratio) {
	// Point viewLocation = new Point();
	// viewLocation.x = (int)(zoomRect.x / ratio);
	// viewLocation.y = (int)(zoomRect.y / ratio);
	// return viewLocation;
	// }

	/**
	 * Sets the zoom level to be one level lower
	 */
	public void zoomOut() {
		setZoom(getPreviousZoomLevel());
	}

}
