/*******************************************************************************
 * 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.ui.rulers;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;

import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ScrollBar;

import org.eclipse.core.runtime.Assert;

import org.eclipse.draw2d.AbstractBorder;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.DefaultRangeModel;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.RangeModel;
import org.eclipse.draw2d.Viewport;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.swt.SWT;

import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.Handle;
import org.eclipse.gef.RootEditPart;
import org.eclipse.gef.internal.ui.rulers.GuideEditPart;
import org.eclipse.gef.internal.ui.rulers.RulerContextMenuProvider;
import org.eclipse.gef.internal.ui.rulers.RulerEditPart;
import org.eclipse.gef.internal.ui.rulers.RulerEditPartFactory;
import org.eclipse.gef.internal.ui.rulers.RulerRootEditPart;
import org.eclipse.gef.rulers.RulerProvider;
import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler;
import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;

/**
 * A RulerComposite is used to show rulers to the north and west of the control
 * of a given {@link #setGraphicalViewer(ScrollingGraphicalViewer) graphical
 * viewer}. The rulers will be shown based on whether or not
 * {@link org.eclipse.gef.rulers.RulerProvider#PROPERTY_HORIZONTAL_RULER
 * horizontal ruler} and
 * {@link org.eclipse.gef.rulers.RulerProvider#PROPERTY_VERTICAL_RULER vertical
 * ruler} properties are set on the given viewer, and the value of the
 * {@link org.eclipse.gef.rulers.RulerProvider#PROPERTY_RULER_VISIBILITY
 * visibility} property.
 * 
 * @author Pratik Shah
 * @since 3.0
 */
public class RulerComposite extends Composite {

	private EditDomain rulerEditDomain;
	private GraphicalViewer left, top;
	private FigureCanvas editor;
	private GraphicalViewer diagramViewer;
	private Font font;
	private Listener layoutListener;
	private PropertyChangeListener propertyListener;
	private boolean layingOut = false;
	private boolean isRulerVisible = true;
	private boolean needToLayout = false;
	private Runnable runnable = new Runnable() {
		public void run() {
			layout(false);
		}
	};

	/**
	 * Constructor
	 * 
	 * @param parent
	 *            a widget which will be the parent of the new instance (cannot
	 *            be null)
	 * @param style
	 *            the style of widget to construct
	 * @see Composite#Composite(org.eclipse.swt.widgets.Composite, int)
	 */
	public RulerComposite(Composite parent, int style) {
		super(parent, style);
		addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				disposeResources();
			}
		});
	}

	/**
	 * Calculates the proper trim. Includes scrollbars' sizes only if they're
	 * visible.
	 * 
	 * @param canvas
	 *            The canvas.
	 * @since 3.6
	 */
	public static Rectangle calculateEditorTrim(Composite canvas) {
		/*
		 * Workaround for Bug# 87712 Calculating the trim using the clientArea.
		 */
		Rectangle bounds = canvas.getBounds();
		Rectangle clientArea = canvas.getClientArea();
		Rectangle result = new Rectangle(0, 0, bounds.width - clientArea.width,
				bounds.height - clientArea.height);
		if (result.width != 0 || result.height != 0) {
			Rectangle trim = canvas.computeTrim(0, 0, 0, 0);
			result.x = result.height == 0 ? 0 : trim.x;
			result.y = result.width == 0 ? 0 : trim.y;
		}
		return result;
	}

	/**
	 * Calculates the proper trim for the ruler.
	 * 
	 * @param canvas
	 *            The canvas.
	 * @since 3.6
	 */
	public static Rectangle calculateRulerTrim(Composite canvas) {
		// IMPORTANT: As stated in bug #314750, this is a Mac Carbon related
		// workaround that is not needed on Cocoa.
		if ("carbon".equals(SWT.getPlatform())) { //$NON-NLS-1$
			Rectangle trim = canvas.computeTrim(0, 0, 0, 0);
			trim.width = 0 - trim.x * 2;
			trim.height = 0 - trim.y * 2;
			return trim;
		}
		return new Rectangle(0, 0, 0, 0);
	}

	private GraphicalViewer createRulerContainer(int orientation) {
		ScrollingGraphicalViewer viewer = new RulerViewer();
		final boolean isHorizontal = orientation == PositionConstants.NORTH
				|| orientation == PositionConstants.SOUTH;

		// Finish initializing the viewer
		viewer.setRootEditPart(new RulerRootEditPart(isHorizontal));
		viewer.setEditPartFactory(new RulerEditPartFactory(diagramViewer));
		viewer.createControl(this);
		((GraphicalEditPart) viewer.getRootEditPart()).getFigure().setBorder(
				new RulerBorder(isHorizontal));
		viewer.setProperty(GraphicalViewer.class.toString(), diagramViewer);

		// Configure the viewer's control
		FigureCanvas canvas = (FigureCanvas) viewer.getControl();
		canvas.setScrollBarVisibility(FigureCanvas.NEVER);
		if (font == null) {
			FontData[] data = canvas.getFont().getFontData();
			for (int i = 0; i < data.length; i++) {
				data[i].setHeight(data[i].getHeight() - 1);
			}
			font = new Font(Display.getCurrent(), data);
		}
		canvas.setFont(font);
		if (isHorizontal) {
			canvas.getViewport().setHorizontalRangeModel(
					editor.getViewport().getHorizontalRangeModel());
		} else {
			canvas.getViewport().setVerticalRangeModel(
					editor.getViewport().getVerticalRangeModel());
		}

		// Add the viewer to the rulerEditDomain
		if (rulerEditDomain == null) {
			rulerEditDomain = new EditDomain();
			rulerEditDomain.setCommandStack(diagramViewer.getEditDomain()
					.getCommandStack());
		}
		rulerEditDomain.addViewer(viewer);

		return viewer;
	}

	private void disposeResources() {
		if (diagramViewer != null)
			diagramViewer.removePropertyChangeListener(propertyListener);
		if (font != null)
			font.dispose();
		// layoutListener is not being removed from the scroll bars because they
		// are already
		// disposed at this point.
	}

	private void disposeRulerViewer(GraphicalViewer viewer) {
		if (viewer == null)
			return;
		/*
		 * There's a tie from the editor's range model to the RulerViewport (via
		 * a listener) to the RulerRootEditPart to the RulerViewer. Break this
		 * tie so that the viewer doesn't leak and can be garbage collected.
		 */
		RangeModel rModel = new DefaultRangeModel();
		Viewport port = ((FigureCanvas) viewer.getControl()).getViewport();
		port.setHorizontalRangeModel(rModel);
		port.setVerticalRangeModel(rModel);
		rulerEditDomain.removeViewer(viewer);
		viewer.getControl().dispose();
	}

	/**
	 * Perform the ruler layout.
	 * 
	 * @since 3.6
	 */
	public void doLayout() {
		if (left == null && top == null) {
			Rectangle area = getClientArea();
			if (!editor.getBounds().equals(area))
				editor.setBounds(area);
			return;
		}

		int leftWidth = 0, topHeight = 0;
		Rectangle leftTrim = null, topTrim = null;
		if (left != null) {
			leftTrim = calculateRulerTrim((Canvas) left.getControl());
			// Adding the trim width here because FigureCanvas#computeSize()
			// does not
			leftWidth = left.getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT).x
					+ leftTrim.width;
		}
		if (top != null) {
			topTrim = calculateRulerTrim((Canvas) top.getControl());
			topHeight = top.getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT).y
					+ topTrim.height;
		}

		Rectangle editorSize = getClientArea();
		editorSize.x = leftWidth;
		editorSize.y = topHeight;
		editorSize.width -= leftWidth;
		editorSize.height -= topHeight;
		editor.setBounds(editorSize);

		/*
		 * Fix for Bug# 67554 Take trim into account. Some platforms (such as
		 * MacOS and Motif) leave some trimming around some canvasses.
		 */
		Rectangle trim = calculateEditorTrim(editor);
		if (left != null) {
			// The - 1 and + 1 are to compensate for the RulerBorder
			left.getControl().setBounds(0, topHeight - trim.x + leftTrim.x - 1,
					leftWidth,
					editorSize.height - trim.height + leftTrim.height + 1);
		}
		if (top != null) {
			top.getControl().setBounds(leftWidth - trim.y + topTrim.y - 1, 0,
					editorSize.width - trim.width + topTrim.width + 1,
					topHeight);
		}
	}

	private GraphicalViewer getRulerContainer(int orientation) {
		GraphicalViewer result = null;
		switch (orientation) {
		case PositionConstants.NORTH:
			result = top;
			break;
		case PositionConstants.WEST:
			result = left;
		}
		return result;
	}

	/**
	 * @see org.eclipse.swt.widgets.Composite#layout(boolean)
	 */
	public void layout(boolean change) {
		if (!layingOut && !isDisposed()) {
			checkWidget();
			if (change || needToLayout) {
				needToLayout = false;
				layingOut = true;
				doLayout();
				layingOut = false;
			}
		}
	}

	/**
	 * Creates rulers for the given graphical viewer.
	 * <p>
	 * The primaryViewer or its Control cannot be <code>null</code>. The
	 * primaryViewer's Control should be a FigureCanvas and a child of this
	 * Composite. This method should only be invoked once.
	 * <p>
	 * To create ruler(s), simply add the RulerProvider(s) (with the right key:
	 * RulerProvider.PROPERTY_HORIZONTAL_RULER or
	 * RulerProvider.PROPERTY_VERTICAL_RULER) as a property on the given viewer.
	 * It can be done after this method is invoked.
	 * RulerProvider.PROPERTY_RULER_VISIBILITY can be used to show/hide the
	 * rulers.
	 * 
	 * @param primaryViewer
	 *            The graphical viewer for which the rulers have to be created
	 */
	public void setGraphicalViewer(ScrollingGraphicalViewer primaryViewer) {
		// pre-conditions
		Assert.isNotNull(primaryViewer);
		Assert.isNotNull(primaryViewer.getControl());
		Assert.isTrue(diagramViewer == null);

		diagramViewer = primaryViewer;
		editor = (FigureCanvas) diagramViewer.getControl();

		// layout whenever the scrollbars are shown or hidden, and whenever the
		// RulerComposite
		// is resized
		layoutListener = new Listener() {
			public void handleEvent(Event event) {
				// @TODO:Pratik If you use Display.asyncExec(runnable) here,
				// some flashing
				// occurs. You can see it when the palette is in the editor, and
				// you hit
				// the button to show/hide it.
				layout(true);
			}
		};
		addListener(SWT.Resize, layoutListener);
		ScrollBar horizontalBar = editor.getHorizontalBar();
		if (horizontalBar != null) {
			horizontalBar.addListener(SWT.Show, layoutListener);
			horizontalBar.addListener(SWT.Hide, layoutListener);
		}
		ScrollBar verticalBar = editor.getVerticalBar();
		if (verticalBar != null) {
			verticalBar.addListener(SWT.Show, layoutListener);
			verticalBar.addListener(SWT.Hide, layoutListener);
		}

		propertyListener = new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent evt) {
				String property = evt.getPropertyName();
				if (RulerProvider.PROPERTY_HORIZONTAL_RULER.equals(property)) {
					setRuler(
							(RulerProvider) diagramViewer
									.getProperty(RulerProvider.PROPERTY_HORIZONTAL_RULER),
							PositionConstants.NORTH);
				} else if (RulerProvider.PROPERTY_VERTICAL_RULER
						.equals(property)) {
					setRuler(
							(RulerProvider) diagramViewer
									.getProperty(RulerProvider.PROPERTY_VERTICAL_RULER),
							PositionConstants.WEST);
				} else if (RulerProvider.PROPERTY_RULER_VISIBILITY
						.equals(property))
					setRulerVisibility(((Boolean) diagramViewer
							.getProperty(RulerProvider.PROPERTY_RULER_VISIBILITY))
							.booleanValue());
			}
		};
		diagramViewer.addPropertyChangeListener(propertyListener);
		Boolean rulerVisibility = (Boolean) diagramViewer
				.getProperty(RulerProvider.PROPERTY_RULER_VISIBILITY);
		if (rulerVisibility != null)
			setRulerVisibility(rulerVisibility.booleanValue());
		setRuler(
				(RulerProvider) diagramViewer
						.getProperty(RulerProvider.PROPERTY_HORIZONTAL_RULER),
				PositionConstants.NORTH);
		setRuler(
				(RulerProvider) diagramViewer
						.getProperty(RulerProvider.PROPERTY_VERTICAL_RULER),
				PositionConstants.WEST);
	}

	private void setRuler(RulerProvider provider, int orientation) {
		Object ruler = null;
		if (isRulerVisible && provider != null)
			// provider.getRuler() might return null (at least the API does not
			// prevent that)
			ruler = provider.getRuler();

		if (ruler == null) {
			// Ruler is not visible or is not present
			setRulerContainer(null, orientation);
			// Layout right-away to prevent an empty control from showing
			layout(true);
			return;
		}

		GraphicalViewer container = getRulerContainer(orientation);
		if (container == null) {
			container = createRulerContainer(orientation);
			setRulerContainer(container, orientation);
		}
		if (container.getContents() != ruler) {
			container.setContents(ruler);
			needToLayout = true;
			Display.getCurrent().asyncExec(runnable);
		}
	}

	private void setRulerContainer(GraphicalViewer container, int orientation) {
		if (orientation == PositionConstants.NORTH) {
			if (top == container)
				return;
			disposeRulerViewer(top);
			top = container;
		} else if (orientation == PositionConstants.WEST) {
			if (left == container)
				return;
			disposeRulerViewer(left);
			left = container;
		}
	}

	private void setRulerVisibility(boolean isVisible) {
		if (isRulerVisible != isVisible) {
			isRulerVisible = isVisible;
			if (diagramViewer != null) {
				setRuler(
						(RulerProvider) diagramViewer
								.getProperty(RulerProvider.PROPERTY_HORIZONTAL_RULER),
						PositionConstants.NORTH);
				setRuler(
						(RulerProvider) diagramViewer
								.getProperty(RulerProvider.PROPERTY_VERTICAL_RULER),
						PositionConstants.WEST);
			}
		}
	}

	private static class RulerBorder extends AbstractBorder {
		private static final Insets H_INSETS = new Insets(0, 1, 0, 0);
		private static final Insets V_INSETS = new Insets(1, 0, 0, 0);
		private boolean horizontal;

		/**
		 * Constructor
		 * 
		 * @param isHorizontal
		 *            whether or not the ruler being bordered is horizontal or
		 *            not
		 */
		public RulerBorder(boolean isHorizontal) {
			horizontal = isHorizontal;
		}

		/**
		 * @see org.eclipse.draw2d.Border#getInsets(org.eclipse.draw2d.IFigure)
		 */
		public Insets getInsets(IFigure figure) {
			return horizontal ? H_INSETS : V_INSETS;
		}

		/**
		 * @see org.eclipse.draw2d.Border#paint(org.eclipse.draw2d.IFigure,
		 *      org.eclipse.draw2d.Graphics, org.eclipse.draw2d.geometry.Insets)
		 */
		public void paint(IFigure figure, Graphics graphics, Insets insets) {
			graphics.setForegroundColor(ColorConstants.buttonDarker);
			if (horizontal) {
				graphics.drawLine(
						figure.getBounds().getTopLeft(),
						figure.getBounds()
								.getBottomLeft()
								.translate(
										new org.eclipse.draw2d.geometry.Point(
												0, -4)));
			} else {
				graphics.drawLine(
						figure.getBounds().getTopLeft(),
						figure.getBounds()
								.getTopRight()
								.translate(
										new org.eclipse.draw2d.geometry.Point(
												-4, 0)));
			}
		}
	}

	/**
	 * Custom graphical viewer intended to be used for rulers.
	 * 
	 * @author Pratik Shah
	 * @since 3.0
	 */
	private static class RulerViewer extends ScrollingGraphicalViewer {
		/**
		 * Constructor
		 */
		public RulerViewer() {
			super();
			init();
		}

		/**
		 * @see org.eclipse.gef.EditPartViewer#appendSelection(org.eclipse.gef.EditPart)
		 */
		public void appendSelection(EditPart editpart) {
			if (editpart instanceof RootEditPart)
				editpart = ((RootEditPart) editpart).getContents();
			setFocus(editpart);
			super.appendSelection(editpart);
		}

		/**
		 * @see org.eclipse.gef.GraphicalViewer#findHandleAt(org.eclipse.draw2d.geometry.Point)
		 */
		public Handle findHandleAt(org.eclipse.draw2d.geometry.Point p) {
			final GraphicalEditPart gep = (GraphicalEditPart) findObjectAtExcluding(
					p, new ArrayList());
			if (gep == null || !(gep instanceof GuideEditPart))
				return null;
			return new Handle() {
				public DragTracker getDragTracker() {
					return ((GuideEditPart) gep).getDragTracker(null);
				}

				public org.eclipse.draw2d.geometry.Point getAccessibleLocation() {
					return null;
				}
			};
		}

		/**
		 * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#init()
		 */
		protected void init() {
			setContextMenu(new RulerContextMenuProvider(this));
			setKeyHandler(new RulerKeyHandler(this));
		}

		/**
		 * Requests to reveal a ruler are ignored since that causes undesired
		 * scrolling to the origin of the ruler
		 * 
		 * @see org.eclipse.gef.EditPartViewer#reveal(org.eclipse.gef.EditPart)
		 */
		public void reveal(EditPart part) {
			if (part != getContents())
				super.reveal(part);
		}

		/**
		 * 
		 * @see org.eclipse.gef.ui.parts.GraphicalViewerImpl#handleFocusGained(org.eclipse.swt.events.FocusEvent)
		 */
		protected void handleFocusGained(FocusEvent fe) {
			if (focusPart == null) {
				setFocus(getContents());
			}
			super.handleFocusGained(fe);
		}

		/**
		 * 
		 * @see org.eclipse.gef.ui.parts.GraphicalViewerImpl#handleFocusLost(org.eclipse.swt.events.FocusEvent)
		 */
		protected void handleFocusLost(FocusEvent fe) {
			super.handleFocusLost(fe);
			if (focusPart == getContents()) {
				focusPart = null;
			}
		}

		/**
		 * Custom KeyHandler intended to be used with a RulerViewer
		 * 
		 * @author Pratik Shah
		 * @since 3.0
		 */
		protected static class RulerKeyHandler extends
				GraphicalViewerKeyHandler {
			/**
			 * Constructor
			 * 
			 * @param viewer
			 *            The viewer for which this handler processes keyboard
			 *            input
			 */
			public RulerKeyHandler(GraphicalViewer viewer) {
				super(viewer);
			}

			/**
			 * @see org.eclipse.gef.KeyHandler#keyPressed(org.eclipse.swt.events.KeyEvent)
			 */
			public boolean keyPressed(KeyEvent event) {
				if (event.keyCode == SWT.DEL) {
					// If a guide has focus, delete it
					if (getFocusEditPart() instanceof GuideEditPart) {
						RulerEditPart parent = (RulerEditPart) getFocusEditPart()
								.getParent();
						getViewer()
								.getEditDomain()
								.getCommandStack()
								.execute(
										parent.getRulerProvider()
												.getDeleteGuideCommand(
														getFocusEditPart()
																.getModel()));
						event.doit = false;
						return true;
					}
					return false;
				} else if (((event.stateMask & SWT.ALT) != 0)
						&& (event.keyCode == SWT.ARROW_UP)) {
					// ALT + UP_ARROW pressed
					// If a guide has focus, give focus to the ruler
					EditPart parent = getFocusEditPart().getParent();
					if (parent instanceof RulerEditPart)
						navigateTo(getFocusEditPart().getParent(), event);
					return true;
				}
				return super.keyPressed(event);
			}
		}
	}

	/**
	 * Retrieve the left ruler graphical viewer.
	 * 
	 * @return The left ruler graphical viewer.
	 * @since 3.6
	 */
	protected GraphicalViewer getLeft() {
		return left;
	}

	/**
	 * Retrieve the top ruler graphical viewer.
	 * 
	 * @return The top ruler graphical viewer.
	 * @since 3.6
	 */
	protected GraphicalViewer getTop() {
		return top;
	}

	/**
	 * Retrieve the editor figure canvas.
	 * 
	 * @return The editor figure canvas.
	 * @since 3.6
	 */
	protected FigureCanvas getEditor() {
		return editor;
	}
}
