/*******************************************************************************
 * 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
 * Austin Riddle (Texas Center for Applied Technology) - initial RAP port
 *******************************************************************************/
package org.eclipse.draw2d;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Slider;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.SWT;

/**
 * A scrolling Canvas that contains {@link Figure Figures} viewed through a
 * {@link Viewport}. Call {@link #setContents(IFigure)} to specify the root of
 * the tree of <tt>Figures</tt> to be viewed through the <tt>Viewport</tt>.
 * <p>
 * Normal procedure for using a FigureCanvas:
 * <ol>
 * <li>Create a FigureCanvas.
 * <li>Create a Draw2d Figure and call {@link #setContents(IFigure)}. This
 * Figure will be the top-level Figure of the Draw2d application.
 * </ol>
 * <dl>
 * <dt><b>Required Styles (when using certain constructors):</b></dt>
 * <dd>V_SCROLL, H_SCROLL, NO_REDRAW_RESIZE</dd>
 * <dt><b>Optional Styles:</b></dt>
 * <dd>DOUBLE_BUFFERED, RIGHT_TO_LEFT, LEFT_TO_RIGHT, NO_BACKGROUND, BORDER</dd>
 * </dl>
 * <p>
 * Note: Only one of the styles RIGHT_TO_LEFT, LEFT_TO_RIGHT may be specified.
 * </p>
 */
public class FigureCanvas extends Composite {

	private static final int ACCEPTED_STYLES = org.eclipse.draw2d.rap.swt.SWT.RIGHT_TO_LEFT
			| SWT.LEFT_TO_RIGHT | SWT.V_SCROLL | SWT.H_SCROLL
			| SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.DOUBLE_BUFFERED
			| SWT.BORDER;

	/**
	 * The default styles are mixed in when certain constructors are used. This
	 * constant is a bitwise OR of the following SWT style constants:
	 * <UL>
	 * <LI>{@link SWT#NO_REDRAW_RESIZE}</LI>
	 * <LI>{@link SWT#NO_BACKGROUND}</LI>
	 * <LI>{@link SWT#V_SCROLL}</LI>
	 * <LI>{@link SWT#H_SCROLL}</LI>
	 * </UL>
	 */
	static final int DEFAULT_STYLES = SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND
			| SWT.V_SCROLL | SWT.H_SCROLL;

	private static final int REQUIRED_STYLES = SWT.NO_REDRAW_RESIZE
			| SWT.V_SCROLL | SWT.H_SCROLL;

	/** Never show scrollbar */
	public static int NEVER = 0;
	/** Automatically show scrollbar when needed */
	public static int AUTOMATIC = 1;
	/** Always show scrollbar */
	public static int ALWAYS = 2;

	protected Slider horizontalBar, verticalBar;
	protected Canvas innerCanvas;

	private int vBarVisibility = AUTOMATIC;
	private int hBarVisibility = AUTOMATIC;
	private Viewport viewport;
	private Font font;
	private int hBarOffset;
	private int vBarOffset;

	private PropertyChangeListener horizontalChangeListener = new PropertyChangeListener() {
		public void propertyChange(PropertyChangeEvent event) {
			RangeModel model = getViewport().getHorizontalRangeModel();
			hBarOffset = Math.max(0, -model.getMinimum());
			Slider horizontalBar = getHorizontalSlider();
			if (horizontalBar != null) {
				horizontalBar.setValues(model.getValue() + hBarOffset,
						model.getMinimum() + hBarOffset, model.getMaximum()
								+ hBarOffset, model.getExtent(),
						Math.max(1, model.getExtent() / 20),
						Math.max(1, model.getExtent() * 3 / 4));
			}
		}
	};

	private PropertyChangeListener verticalChangeListener = new PropertyChangeListener() {
		public void propertyChange(PropertyChangeEvent event) {
			RangeModel model = getViewport().getVerticalRangeModel();
			vBarOffset = Math.max(0, -model.getMinimum());
			Slider verticalBar = getVerticalSlider();
			if (verticalBar != null) {
				verticalBar.setValues(model.getValue() + vBarOffset,
						model.getMinimum() + vBarOffset, model.getMaximum()
								+ vBarOffset, model.getExtent(),
						Math.max(1, model.getExtent() / 20),
						Math.max(1, model.getExtent() * 3 / 4));
			}
		}
	};

	private final LightweightSystem lws;

	/**
	 * Creates a new FigureCanvas with the given parent and the
	 * {@link #DEFAULT_STYLES}.
	 * 
	 * @param parent
	 *            the parent
	 */
	public FigureCanvas(Composite parent) {
		this(parent, SWT.DOUBLE_BUFFERED, new LightweightSystem());
	}

	/**
	 * Constructor which applies the default styles plus any optional styles
	 * indicated.
	 * 
	 * @param parent
	 *            the parent composite
	 * @param style
	 *            see the class javadoc for optional styles
	 * @since 3.1
	 */
	public FigureCanvas(Composite parent, int style) {
		this(parent, style, new LightweightSystem());
	}

	/**
	 * Constructor which uses the given styles verbatim. Certain styles must be
	 * used with this class. Refer to the class javadoc for more details.
	 * 
	 * @param style
	 *            see the class javadoc for <b>required</b> and optional styles
	 * @param parent
	 *            the parent composite
	 * @since 3.4
	 */
	public FigureCanvas(int style, Composite parent) {
		this(style, parent, new LightweightSystem());
	}

	/**
	 * Constructs a new FigureCanvas with the given parent and
	 * LightweightSystem, using the {@link #DEFAULT_STYLES}.
	 * 
	 * @param parent
	 *            the parent
	 * @param lws
	 *            the LightweightSystem
	 */
	public FigureCanvas(Composite parent, LightweightSystem lws) {
		this(parent, SWT.DOUBLE_BUFFERED, lws);
	}

	/**
	 * Constructor taking a lightweight system and SWT style, which is used
	 * verbatim. Certain styles must be used with this class. Refer to the class
	 * javadoc for more details.
	 * 
	 * @param style
	 *            see the class javadoc for <b>required</b> and optional styles
	 * @param parent
	 *            the parent composite
	 * @param lws
	 *            the LightweightSystem
	 * @since 3.4
	 */
	public FigureCanvas(int style, Composite parent, LightweightSystem lws) {
		super(parent, checkStyle(style));
		setLayout(new Layout() {
			protected org.eclipse.swt.graphics.Point computeSize(
					Composite composite, int wHint, int hHint,
					boolean flushCache) {
				return innerCanvas.computeSize(wHint, hHint, flushCache);
			}

			protected void layout(Composite composite, boolean flushCache) {
				org.eclipse.swt.graphics.Point size = composite.getSize();
				int vScrollBarWidth = getVScrollBarWidth();
				int hScrollBarHeight = getHScrollBarHeight();
				if (!getHorizontalSlider().isVisible()) {
					hScrollBarHeight = 0;
				}
				if (!getVerticalSlider().isVisible()) {
					vScrollBarWidth = 0;
				}
				getHorizontalSlider().setBounds(0, size.y - hScrollBarHeight,
						size.x - vScrollBarWidth, hScrollBarHeight);
				getVerticalSlider().setBounds(size.x - vScrollBarWidth, 0,
						vScrollBarWidth, size.y - hScrollBarHeight);
				innerCanvas.setLocation(0, 0);
				innerCanvas.setSize(size.x - vScrollBarWidth, size.y
						- hScrollBarHeight);
			}
		});
		Slider horizontalBar = getHorizontalSlider();
		if (horizontalBar != null) {
			horizontalBar.setVisible(false);
		}
		Slider verticalBar = getVerticalSlider();
		if (verticalBar != null) {
			verticalBar.setVisible(false);
		}
		this.lws = lws;
		lws.setControl(getInnerCanvas());
		hook();
	}

	public org.eclipse.swt.graphics.Rectangle getClientArea() {
		return innerCanvas.getClientArea();
	}

	private Canvas getInnerCanvas() {
		if (innerCanvas == null) {
			innerCanvas = new Canvas(this, getStyle());
			this.setData(Canvas.class.getName(), innerCanvas);
		}
		return innerCanvas;
	}

	/**
	 * Constructor
	 * 
	 * @param parent
	 *            the parent composite
	 * @param style
	 *            look at class javadoc for valid styles
	 * @param lws
	 *            the lightweight system
	 * @since 3.1
	 */
	public FigureCanvas(Composite parent, int style, LightweightSystem lws) {
		this(style | DEFAULT_STYLES, parent, lws);
	}

	private static int checkStyle(int style) {
		if ((style & REQUIRED_STYLES) != REQUIRED_STYLES)
			throw new IllegalArgumentException(
					"Required style missing on FigureCanvas"); //$NON-NLS-1$
		if ((style & ~ACCEPTED_STYLES) != 0)
			throw new IllegalArgumentException(
					"Invalid style being set on FigureCanvas"); //$NON-NLS-1$
		return style;
	}

	/**
	 * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)
	 */
	public org.eclipse.swt.graphics.Point computeSize(int wHint, int hHint,
			boolean changed) {
		// TODO Still doesn't handle scrollbar cases, such as when a constrained
		// width
		// would require a horizontal scrollbar, and therefore additional
		// height.
		int borderSize = computeTrim(0, 0, 0, 0).x * -2;
		if (wHint >= 0)
			wHint = Math.max(0, wHint - borderSize);
		if (hHint >= 0)
			hHint = Math.max(0, hHint - borderSize);
		Dimension size = getLightweightSystem().getRootFigure()
				.getPreferredSize(wHint, hHint)
				.getExpanded(borderSize, borderSize);
		size.union(new Dimension(wHint, hHint));
		return new org.eclipse.swt.graphics.Point(size.width, size.height);
	}

	/**
	 * @return the contents of the {@link Viewport}.
	 */
	public IFigure getContents() {
		return getViewport().getContents();
	}

	/**
	 * @see org.eclipse.swt.widgets.Control#getFont()
	 */
	public Font getFont() {
		if (font == null)
			font = super.getFont();
		return font;
	}

	/**
	 * @return the horizontal scrollbar visibility.
	 */
	public int getHorizontalScrollBarVisibility() {
		return hBarVisibility;
	}

	int getVScrollBarWidth() {
		return 16;
	}

	int getHScrollBarHeight() {
		return 16;
	}

	/**
	 * @return the LightweightSystem
	 */
	public LightweightSystem getLightweightSystem() {
		return lws;
	}

	/**
	 * @return the vertical scrollbar visibility.
	 */
	public int getVerticalScrollBarVisibility() {
		return vBarVisibility;
	}

	/**
	 * Returns the Viewport. If it's <code>null</code>, a new one is created.
	 * 
	 * @return the viewport
	 */
	public Viewport getViewport() {
		if (viewport == null)
			setViewport(new Viewport(true));
		return viewport;
	}

	/**
	 * Adds listeners for scrolling.
	 */
	private void hook() {
		getLightweightSystem().getUpdateManager().addUpdateListener(
				new UpdateListener() {
					public void notifyPainting(Rectangle damage,
							java.util.Map dirtyRegions) {
					}

					public void notifyValidating() {
						if (!isDisposed())
							layoutViewport();
					}
				});

		final Slider horizontalBar = getHorizontalSlider();
		if (horizontalBar != null) {
			horizontalBar.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent event) {
					scrollToX(horizontalBar.getSelection() - hBarOffset);
				}
			});
		}

		final Slider verticalBar = getVerticalSlider();
		if (verticalBar != null) {
			verticalBar.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent event) {
					scrollToY(verticalBar.getSelection() - vBarOffset);
				}
			});
		}
	}

	private void hookViewport() {
		getViewport().getHorizontalRangeModel().addPropertyChangeListener(
				horizontalChangeListener);
		getViewport().getVerticalRangeModel().addPropertyChangeListener(
				verticalChangeListener);
	}

	private void unhookViewport() {
		getViewport().getHorizontalRangeModel().removePropertyChangeListener(
				horizontalChangeListener);
		getViewport().getVerticalRangeModel().removePropertyChangeListener(
				verticalChangeListener);
	}

	private void layoutViewport() {
		ScrollPaneSolver.Result result;
		result = ScrollPaneSolver.solve(
				new Rectangle(innerCanvas.getBounds()).setLocation(0, 0),
				getViewport(), getHorizontalScrollBarVisibility(),
				getVerticalScrollBarVisibility(),
				innerCanvas.computeTrim(0, 0, 0, 0).width,
				innerCanvas.computeTrim(0, 0, 0, 0).height);
		getLightweightSystem().setIgnoreResize(true);
		try {
			Slider horizontalBar = getHorizontalSlider();
			if (horizontalBar != null
					&& horizontalBar.getVisible() != result.showH) {
				horizontalBar.setVisible(result.showH);
				layout(new Control[] { horizontalBar });
			}
			Slider verticalBar = getVerticalSlider();
			if (verticalBar != null && verticalBar.getVisible() != result.showV) {
				verticalBar.setVisible(result.showV);
				layout(new Control[] { verticalBar });
			}
			Rectangle r = new Rectangle(getClientArea());
			r.setLocation(0, 0);
			getLightweightSystem().getRootFigure().setBounds(r);
		} finally {
			getLightweightSystem().setIgnoreResize(false);
		}
	}

	/**
	 * Scrolls in an animated way to the new x and y location.
	 * 
	 * @param x
	 *            the x coordinate to scroll to
	 * @param y
	 *            the y coordinate to scroll to
	 */
	public void scrollSmoothTo(int x, int y) {
		// Ensure newHOffset and newVOffset are within the appropriate ranges
		x = verifyScrollBarOffset(getViewport().getHorizontalRangeModel(), x);
		y = verifyScrollBarOffset(getViewport().getVerticalRangeModel(), y);

		int oldX = getViewport().getViewLocation().x;
		int oldY = getViewport().getViewLocation().y;
		int dx = x - oldX;
		int dy = y - oldY;

		if (dx == 0 && dy == 0)
			return; // Nothing to do.

		Dimension viewingArea = getViewport().getClientArea().getSize();

		int minFrames = 3;
		int maxFrames = 6;
		if (dx == 0 || dy == 0) {
			minFrames = 6;
			maxFrames = 13;
		}
		int frames = (Math.abs(dx) + Math.abs(dy)) / 15;
		frames = Math.max(frames, minFrames);
		frames = Math.min(frames, maxFrames);

		int stepX = Math.min((dx / frames), (viewingArea.width / 3));
		int stepY = Math.min((dy / frames), (viewingArea.height / 3));

		for (int i = 1; i < frames; i++) {
			scrollTo(oldX + i * stepX, oldY + i * stepY);
			getViewport().getUpdateManager().performUpdate();
		}
		scrollTo(x, y);
	}

	/**
	 * Scrolls the contents to the new x and y location. If this scroll
	 * operation only consists of a vertical or horizontal scroll, a call will
	 * be made to {@link #scrollToY(int)} or {@link #scrollToX(int)},
	 * respectively, to increase performance.
	 * 
	 * @param x
	 *            the x coordinate to scroll to
	 * @param y
	 *            the y coordinate to scroll to
	 */
	public void scrollTo(int x, int y) {
		x = verifyScrollBarOffset(getViewport().getHorizontalRangeModel(), x);
		y = verifyScrollBarOffset(getViewport().getVerticalRangeModel(), y);
		if (x == getViewport().getViewLocation().x)
			scrollToY(y);
		else if (y == getViewport().getViewLocation().y)
			scrollToX(x);
		else
			getViewport().setViewLocation(x, y);
	}

	/**
	 * Scrolls the contents horizontally so that they are offset by
	 * <code>hOffset</code>.
	 * 
	 * @param hOffset
	 *            the new horizontal offset
	 */
	public void scrollToX(int hOffset) {
		hOffset = verifyScrollBarOffset(
				getViewport().getHorizontalRangeModel(), hOffset);
		int hOffsetOld = getViewport().getViewLocation().x;
		if (hOffset == hOffsetOld)
			return;
		int dx = -hOffset + hOffsetOld;

		Rectangle clientArea = getViewport().getBounds().getCropped(
				getViewport().getInsets());
		Rectangle blit = clientArea.getResized(-Math.abs(dx), 0);
		Rectangle expose = clientArea.getCopy();
		Point dest = clientArea.getTopLeft();
		expose.width = Math.abs(dx);
		if (dx < 0) { // Moving left?
			blit.translate(-dx, 0); // Move blit area to the right
			expose.x = dest.x + blit.width;
		} else
			// Moving right
			dest.x += dx; // Move expose area to the right

		// fix for bug 41111
		Control[] children = getInnerCanvas().getChildren();
		boolean[] manualMove = new boolean[children.length];
		for (int i = 0; i < children.length; i++) {
			org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds();
			manualMove[i] = blit.width <= 0 || bounds.x > blit.x + blit.width
					|| bounds.y > blit.y + blit.height
					|| bounds.x + bounds.width < blit.x
					|| bounds.y + bounds.height < blit.y;
		}
		scroll(dest.x, dest.y, blit.x, blit.y, blit.width, blit.height, true);
		for (int i = 0; i < children.length; i++) {
			if (children[i].isDisposed())
				continue;
			org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds();
			if (manualMove[i])
				children[i].setBounds(bounds.x + dx, bounds.y, bounds.width,
						bounds.height);
		}

		getViewport().setIgnoreScroll(true);
		getViewport().setHorizontalLocation(hOffset);
		getViewport().setIgnoreScroll(false);
		getInnerCanvas().redraw(expose.x, expose.y, expose.width,
				expose.height, true);
	}

	/**
	 * Scrolls the contents vertically so that they are offset by
	 * <code>vOffset</code>.
	 * 
	 * @param vOffset
	 *            the new vertical offset
	 */
	public void scrollToY(int vOffset) {
		vOffset = verifyScrollBarOffset(getViewport().getVerticalRangeModel(),
				vOffset);
		int vOffsetOld = getViewport().getViewLocation().y;
		if (vOffset == vOffsetOld)
			return;
		int dy = -vOffset + vOffsetOld;

		Rectangle clientArea = getViewport().getBounds().getCropped(
				getViewport().getInsets());
		Rectangle blit = clientArea.getResized(0, -Math.abs(dy));
		Rectangle expose = clientArea.getCopy();
		Point dest = clientArea.getTopLeft();
		expose.height = Math.abs(dy);
		if (dy < 0) { // Moving up?
			blit.translate(0, -dy); // Move blit area down
			expose.y = dest.y + blit.height; // Move expose area down
		} else
			// Moving down
			dest.y += dy;

		// fix for bug 41111
		Control[] children = getInnerCanvas().getChildren();
		boolean[] manualMove = new boolean[children.length];
		for (int i = 0; i < children.length; i++) {
			org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds();
			manualMove[i] = blit.height <= 0 || bounds.x > blit.x + blit.width
					|| bounds.y > blit.y + blit.height
					|| bounds.x + bounds.width < blit.x
					|| bounds.y + bounds.height < blit.y;
		}
		scroll(dest.x, dest.y, blit.x, blit.y, blit.width, blit.height, true);
		for (int i = 0; i < children.length; i++) {
			if (children[i].isDisposed())
				continue;
			org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds();
			if (manualMove[i])
				children[i].setBounds(bounds.x, bounds.y + dy, bounds.width,
						bounds.height);
		}

		getViewport().setIgnoreScroll(true);
		getViewport().setVerticalLocation(vOffset);
		getViewport().setIgnoreScroll(false);
		getInnerCanvas().redraw(expose.x, expose.y, expose.width,
				expose.height, true);
	}

	public void scroll(int destX, int destY, int x, int y, int width,
			int height, boolean all) {
		checkWidget();
		int deltaX = destX - x, deltaY = destY - y;
		if (all) {
			Control[] children = getInnerCanvas().getChildren();
			for (int i = 0; i < children.length; i++) {
				Control child = children[i];
				org.eclipse.swt.graphics.Rectangle rect = child.getBounds();
				if (Math.min(x + width, rect.x + rect.width) >= Math.max(x,
						rect.x)
						&& Math.min(y + height, rect.y + rect.height) >= Math
								.max(y, rect.y)) {
					child.setLocation(rect.x + deltaX, rect.y + deltaY);
				}
			}
		}
	}

	/**
	 * Sets the given border on the LightweightSystem's root figure.
	 * 
	 * @param border
	 *            The new border
	 */
	public void setBorder(Border border) {
		getLightweightSystem().getRootFigure().setBorder(border);
	}

	/**
	 * Sets the contents of the {@link Viewport}.
	 * 
	 * @param figure
	 *            the new contents
	 */
	public void setContents(IFigure figure) {
		getViewport().setContents(figure);
	}

	/**
	 * @see org.eclipse.swt.widgets.Control#setFont(org.eclipse.swt.graphics.Font)
	 */
	public void setFont(Font font) {
		this.font = font;
		super.setFont(font);
	}

	/**
	 * Sets the horizontal scrollbar visibility. Possible values are
	 * {@link #AUTOMATIC}, {@link #ALWAYS}, and {@link #NEVER}.
	 * 
	 * @param v
	 *            the new visibility
	 */
	public void setHorizontalScrollBarVisibility(int v) {
		hBarVisibility = v;
	}

	/**
	 * Sets both the horizontal and vertical scrollbar visibility to the given
	 * value. Possible values are {@link #AUTOMATIC}, {@link #ALWAYS}, and
	 * {@link #NEVER}.
	 * 
	 * @param both
	 *            the new visibility
	 */
	public void setScrollBarVisibility(int both) {
		setHorizontalScrollBarVisibility(both);
		setVerticalScrollBarVisibility(both);
	}

	/**
	 * Sets the vertical scrollbar visibility. Possible values are
	 * {@link #AUTOMATIC}, {@link #ALWAYS}, and {@link #NEVER}.
	 * 
	 * @param v
	 *            the new visibility
	 */
	public void setVerticalScrollBarVisibility(int v) {
		vBarVisibility = v;
	}

	/**
	 * Sets the Viewport. The given Viewport must use "fake" scrolling. That is,
	 * it must be constructed using <code>new Viewport(true)</code>.
	 * 
	 * @param vp
	 *            the new viewport
	 */
	public void setViewport(Viewport vp) {
		if (viewport != null)
			unhookViewport();
		viewport = vp;
		lws.setContents(viewport);
		hookViewport();
	}

	private int verifyScrollBarOffset(RangeModel model, int value) {
		value = Math.max(model.getMinimum(), value);
		return Math.min(model.getMaximum() - model.getExtent(), value);
	}

	public Slider getHorizontalSlider() {
		checkWidget();
		if (horizontalBar == null) {
			horizontalBar = new Slider(this, SWT.HORIZONTAL);
			horizontalBar.setMaximum(100);
			horizontalBar.setThumb(10);
		}
		return horizontalBar;
	}

	public Slider getVerticalSlider() {
		checkWidget();
		if (verticalBar == null) {
			verticalBar = new Slider(this, SWT.VERTICAL);
			verticalBar.setMaximum(100);
			verticalBar.setThumb(10);
		}
		return verticalBar;
	}

}
