/*******************************************************************************
 * Copyright (c) 2006, 2008 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.jface.fieldassist;

import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.util.Util;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MenuDetectEvent;
import org.eclipse.swt.events.MenuDetectListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;

/**
 * ControlDecoration renders an image decoration near a control. It allows
 * clients to specify an image and a position for the image relative to the
 * control. A ControlDecoration may be assigned description text, which can
 * optionally be shown when the user hovers over the image. Clients can decorate
 * any kind of control.
 * <p>
 * Decoration images always appear on the left or right side of the field, never
 * above or below it. Decorations can be positioned at the top, center, or
 * bottom of either side of the control. Future implementations may provide
 * additional positioning options for decorations.
 * <p>
 * ControlDecoration renders the image adjacent to the specified (already
 * created) control, with no guarantee that it won't be clipped or otherwise
 * obscured or overlapped by adjacent controls, including another
 * ControlDecoration placed in the same location. Clients should ensure that
 * there is adequate space adjacent to the control to show the decoration
 * properly.
 * <p>
 * Clients using ControlDecoration should typically ensure that enough margin
 * space is reserved for a decoration by altering the layout data margins,
 * although this is not assumed or required by the ControlDecoration
 * implementation.
 * <p>
 * This class is intended to be instantiated and used by clients. It is not
 * intended to be subclassed by clients.
 * 
 * @since 3.3
 * 
 * @see FieldDecoration
 * @see FieldDecorationRegistry
 */
public class ControlDecoration {
	/**
	 * Debug flag for tracing
	 */
	private static boolean DEBUG = false;

	/**
	 * Cached platform flags for dealing with platform-specific issues.
	 */
	private static boolean CARBON = Util.isCarbon();

	/**
	 * The associated control
	 */
	private Control control;

	/**
	 * The composite on which to render the decoration and hook mouse events, or
	 * null if we are hooking all parent composites.
	 */
	private Composite composite;

	/**
	 * The associated image.
	 */
	private Image image;

	/**
	 * The associated description text.
	 */
	private String descriptionText;
	/**
	 * The position of the decoration.
	 */
	private int position;

	/**
	 * The decoration's visibility flag
	 */
	private boolean visible = true;

	/**
	 * Boolean indicating whether the decoration should only be shown when the
	 * control has focus
	 */
	private boolean showOnlyOnFocus = false;

	/**
	 * Boolean indicating whether the decoration should show its description
	 * text in a hover when the user hovers over the decoration.
	 */
	private boolean showHover = true;

	/**
	 * Margin width used between the decorator and the control.
	 */
	private int marginWidth = 0;

	/**
	 * Registered selection listeners.
	 */
	private ListenerList selectionListeners = new ListenerList();

	/**
	 * Registered menu detect listeners.
	 */
	private ListenerList menuDetectListeners = new ListenerList();

	/**
	 * The focus listener
	 */
	private FocusListener focusListener;

	/**
	 * The dispose listener
	 */
	private DisposeListener disposeListener;

	/**
	 * The paint listener installed for drawing the decoration
	 */
	private PaintListener paintListener;

	/**
	 * The mouse listener installed for tracking the hover
	 */
	private MouseTrackListener mouseTrackListener;

	/**
	 * The mouse move listener installed for tracking the hover
	 */
	private MouseMoveListener mouseMoveListener;

	/**
	 * The untyped listener installed for notifying external listeners
	 */
	private Listener compositeListener;

	/**
	 * Control that we last installed a move listener on. We only want one at a
	 * time.
	 */
	private Control moveListeningTarget = null;

	/**
	 * Debug counter used to match add and remove listeners
	 */
	private int listenerInstalls = 0;

	/**
	 * The current rectangle used for tracking mouse moves
	 */
	private Rectangle decorationRectangle;
	
	/**
	 * The rectangle of the previously used image.  Used
	 * for redrawing in the case where a smaller image replaces
	 * a larger one.
	 * 
	 * @since 3.5
	 */
	private Rectangle previousDecorationRectangle;

	/**
	 * An internal flag tracking whether we have focus. We use this rather than
	 * isFocusControl() so that we can set the flag as soon as we get the focus
	 * callback, rather than having to do an asyncExec in the middle of a focus
	 * callback to ensure that isFocusControl() represents the outcome of the
	 * event.
	 */
	private boolean hasFocus = false;

	/**
	 * The hover used for showing description text
	 */
	private Hover hover;

	/**
	 * The hover used to show a decoration image's description.
	 */
	class Hover {
		private static final String EMPTY = ""; //$NON-NLS-1$

		/**
		 * Offset of info hover arrow from the left or right side.
		 */
		private int hao = 10;

		/**
		 * Width of info hover arrow.
		 */
		private int haw = 8;

		/**
		 * Height of info hover arrow.
		 */
		private int hah = 10;

		/**
		 * Margin around info hover text.
		 */
		private int hm = 2;

		/**
		 * This info hover's shell.
		 */
		Shell hoverShell;

		/**
		 * The info hover text.
		 */
		String text = EMPTY;

		/**
		 * The region used to manage the shell shape
		 */
		Region region;

		/**
		 * Boolean indicating whether the last computed polygon location had an
		 * arrow on left. (true if left, false if right).
		 */
		boolean arrowOnLeft = true;

		/*
		 * Create a hover parented by the specified shell.
		 */
		Hover(Shell parent) {
			final Display display = parent.getDisplay();
			hoverShell = new Shell(parent, SWT.NO_TRIM | SWT.ON_TOP
					| SWT.NO_FOCUS | SWT.TOOL);
			hoverShell.setBackground(display
					.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
			hoverShell.setForeground(display
					.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
			hoverShell.addPaintListener(new PaintListener() {
				public void paintControl(PaintEvent pe) {
					pe.gc.drawText(text, hm, hm);
					if (!CARBON) {
						pe.gc.drawPolygon(getPolygon(true));
					}
				}
			});
			hoverShell.addMouseListener(new MouseAdapter() {
				public void mouseDown(MouseEvent e) {
					hideHover();
				}
			});
		}

		/*
		 * Compute a polygon that represents a hover with an arrow pointer. If
		 * border is true, compute the polygon inset by 1-pixel border. Consult
		 * the arrowOnLeft flag to determine which side the arrow is on.
		 */
		int[] getPolygon(boolean border) {
			Point e = getExtent();
			int b = border ? 1 : 0;
			if (arrowOnLeft) {
				return new int[] { 0, 0, e.x - b, 0, e.x - b, e.y - b,
						hao + haw, e.y - b, hao + haw / 2, e.y + hah - b, hao,
						e.y - b, 0, e.y - b, 0, 0 };
			}
			return new int[] { 0, 0, e.x - b, 0, e.x - b, e.y - b,
					e.x - hao - b, e.y - b, e.x - hao - haw / 2, e.y + hah - b,
					e.x - hao - haw, e.y - b, 0, e.y - b, 0, 0 };
		}

		/*
		 * Dispose the hover, it is no longer needed. Dispose any resources
		 * allocated by the hover.
		 */
		void dispose() {
			if (!hoverShell.isDisposed()) {
				hoverShell.dispose();
			}
			if (region != null) {
				region.dispose();
			}
		}

		/*
		 * Set the visibility of the hover.
		 */
		void setVisible(boolean visible) {
			if (visible) {
				if (!hoverShell.isVisible()) {
					hoverShell.setVisible(true);
				}
			} else {
				if (hoverShell.isVisible()) {
					hoverShell.setVisible(false);
				}
			}
		}

		/*
		 * Set the text of the hover to the specified text. Recompute the size
		 * and location of the hover to hover near the decoration rectangle,
		 * pointing the arrow toward the target control.
		 */
		void setText(String t, Rectangle decorationRectangle,
				Control targetControl) {
			if (t == null) {
				t = EMPTY;
			}
			if (!t.equals(text)) {
				Point oldSize = getExtent();
				text = t;
				hoverShell.redraw();
				Point newSize = getExtent();
				if (!oldSize.equals(newSize)) {
					// set a flag that indicates the direction of arrow
					arrowOnLeft = decorationRectangle.x <= targetControl
							.getLocation().x;
					setNewShape();
				}
			}

			Point extent = getExtent();
			int y = -extent.y - hah + 1;
			int x = arrowOnLeft ? -hao + haw / 2 : -extent.x + hao + haw / 2;

			hoverShell.setLocation(control.getParent().toDisplay(
					decorationRectangle.x + x, decorationRectangle.y + y));
		}

		/*
		 * Return whether or not the hover (shell) is visible.
		 */
		boolean isVisible() {
			return hoverShell.isVisible();
		}

		/*
		 * Compute the extent of the hover for the current text.
		 */
		Point getExtent() {
			GC gc = new GC(hoverShell);
			Point e = gc.textExtent(text);
			gc.dispose();
			e.x += hm * 2;
			e.y += hm * 2;
			return e;
		}

		/*
		 * Compute a new shape for the hover shell.
		 */
		void setNewShape() {
			Region oldRegion = region;
			region = new Region();
			region.add(getPolygon(false));
			hoverShell.setRegion(region);
			if (oldRegion != null) {
				oldRegion.dispose();
			}

		}
	}

	/**
	 * Construct a ControlDecoration for decorating the specified control at the
	 * specified position relative to the control. Render the decoration on top
	 * of any Control that happens to appear at the specified location.
	 * <p>
	 * SWT constants are used to specify the position of the decoration relative
	 * to the control. The position should include style bits describing both
	 * the vertical and horizontal orientation. <code>SWT.LEFT</code> and
	 * <code>SWT.RIGHT</code> describe the horizontal placement of the
	 * decoration relative to the control, and the constants
	 * <code>SWT.TOP</code>, <code>SWT.CENTER</code>, and
	 * <code>SWT.BOTTOM</code> describe the vertical alignment of the
	 * decoration relative to the control. Decorations always appear on either
	 * the left or right side of the control, never above or below it. For
	 * example, a decoration appearing on the left side of the field, at the
	 * top, is specified as SWT.LEFT | SWT.TOP. If no position style bits are
	 * specified, the control decoration will be positioned to the left and
	 * center of the control (<code>SWT.LEFT | SWT.CENTER</code>).
	 * </p>
	 * 
	 * @param control
	 *            the control to be decorated
	 * @param position
	 *            bit-wise or of position constants (<code>SWT.TOP</code>,
	 *            <code>SWT.BOTTOM</code>, <code>SWT.LEFT</code>,
	 *            <code>SWT.RIGHT</code>, and <code>SWT.CENTER</code>).
	 */
	public ControlDecoration(Control control, int position) {
		this(control, position, null);

	}

	/**
	 * Construct a ControlDecoration for decorating the specified control at the
	 * specified position relative to the control. Render the decoration only on
	 * the specified Composite or its children. The decoration will be clipped
	 * if it does not appear within the visible bounds of the composite or its
	 * child composites.
	 * <p>
	 * SWT constants are used to specify the position of the decoration relative
	 * to the control. The position should include style bits describing both
	 * the vertical and horizontal orientation. <code>SWT.LEFT</code> and
	 * <code>SWT.RIGHT</code> describe the horizontal placement of the
	 * decoration relative to the control, and the constants
	 * <code>SWT.TOP</code>, <code>SWT.CENTER</code>, and
	 * <code>SWT.BOTTOM</code> describe the vertical alignment of the
	 * decoration relative to the control. Decorations always appear on either
	 * the left or right side of the control, never above or below it. For
	 * example, a decoration appearing on the left side of the field, at the
	 * top, is specified as SWT.LEFT | SWT.TOP. If no position style bits are
	 * specified, the control decoration will be positioned to the left and
	 * center of the control (<code>SWT.LEFT | SWT.CENTER</code>).
	 * </p>
	 * 
	 * @param control
	 *            the control to be decorated
	 * @param position
	 *            bit-wise or of position constants (<code>SWT.TOP</code>,
	 *            <code>SWT.BOTTOM</code>, <code>SWT.LEFT</code>,
	 *            <code>SWT.RIGHT</code>, and <code>SWT.CENTER</code>).
	 * @param composite
	 *            The SWT composite within which the decoration should be
	 *            rendered. The decoration will be clipped to this composite,
	 *            but it may be rendered on a child of the composite. The
	 *            decoration will not be visible if the specified composite or
	 *            its child composites are not visible in the space relative to
	 *            the control, where the decoration is to be rendered. If this
	 *            value is <code>null</code>, then the decoration will be
	 *            rendered on whichever composite (or composites) are located in
	 *            the specified position.
	 */
	public ControlDecoration(Control control, int position, Composite composite) {
		this.position = position;
		this.control = control;
		this.composite = composite;

		addControlListeners();

	}

	/**
	 * Adds the listener to the collection of listeners who will be notified
	 * when the platform-specific context menu trigger has occurred, by sending
	 * it one of the messages defined in the <code>MenuDetectListener</code>
	 * interface.
	 * <p>
	 * The <code>widget</code> field in the SelectionEvent will contain the
	 * Composite on which the decoration is rendered that received the click.
	 * The <code>x</code> and <code>y</code> fields will be in coordinates
	 * relative to the display. The <code>data</code> field will contain the
	 * decoration that received the event.
	 * </p>
	 * 
	 * @param listener
	 *            the listener which should be notified
	 * 
	 * @see org.eclipse.swt.events.MenuDetectListener
	 * @see org.eclipse.swt.events.MenuDetectEvent
	 * @see #removeMenuDetectListener
	 */
	public void addMenuDetectListener(MenuDetectListener listener) {
		menuDetectListeners.add(listener);
	}

	/**
	 * Removes the listener from the collection of listeners who will be
	 * notified when the platform-specific context menu trigger has occurred.
	 * 
	 * @param listener
	 *            the listener which should no longer be notified. This message
	 *            has no effect if the listener was not previously added to the
	 *            receiver.
	 * 
	 * @see org.eclipse.swt.events.MenuDetectListener
	 * @see #addMenuDetectListener
	 */
	public void removeMenuDetectListener(MenuDetectListener listener) {
		menuDetectListeners.remove(listener);
	}

	/**
	 * Adds the listener to the collection of listeners who will be notified
	 * when the decoration is selected, by sending it one of the messages
	 * defined in the <code>SelectionListener</code> interface.
	 * <p>
	 * <code>widgetSelected</code> is called when the decoration is selected
	 * (by mouse click). <code>widgetDefaultSelected</code> is called when the
	 * decoration is double-clicked.
	 * </p>
	 * <p>
	 * The <code>widget</code> field in the SelectionEvent will contain the
	 * Composite on which the decoration is rendered that received the click.
	 * The <code>x</code> and <code>y</code> fields will be in coordinates
	 * relative to that widget. The <code>data</code> field will contain the
	 * decoration that received the event.
	 * </p>
	 * 
	 * @param listener
	 *            the listener which should be notified
	 * 
	 * @see org.eclipse.swt.events.SelectionListener
	 * @see org.eclipse.swt.events.SelectionEvent
	 * @see #removeSelectionListener
	 */
	public void addSelectionListener(SelectionListener listener) {
		selectionListeners.add(listener);
	}

	/**
	 * Removes the listener from the collection of listeners who will be
	 * notified when the decoration is selected.
	 * 
	 * @param listener
	 *            the listener which should no longer be notified. This message
	 *            has no effect if the listener was not previously added to the
	 *            receiver.
	 * 
	 * @see org.eclipse.swt.events.SelectionListener
	 * @see #addSelectionListener
	 */
	public void removeSelectionListener(SelectionListener listener) {
		selectionListeners.remove(listener);
	}

	/**
	 * Dispose this ControlDecoration. Unhook any listeners that have been
	 * installed on the target control. This method has no effect if the
	 * receiver is already disposed.
	 */
	public void dispose() {
		if (control == null) {
			return;
		}
		if (hover != null) {
			hover.dispose();
			hover = null;
		}
		removeControlListeners();
		control = null;
	}

	/**
	 * Get the control that is decorated by the receiver.
	 * 
	 * @return the Control decorated by the receiver. May be <code>null</code>
	 *         if the control has been uninstalled.
	 */
	public Control getControl() {
		return control;
	}

	/**
	 * Add any listeners needed on the target control and on the composite where
	 * the decoration is to be rendered.
	 */
	private void addControlListeners() {
		disposeListener = new DisposeListener() {
			public void widgetDisposed(DisposeEvent event) {
				dispose();
			}
		};
		printAddListener(control, "DISPOSE"); //$NON-NLS-1$
		control.addDisposeListener(disposeListener);

		focusListener = new FocusListener() {
			public void focusGained(FocusEvent event) {
				hasFocus = true;
				if (showOnlyOnFocus) {
					update();
				}
			}

			public void focusLost(FocusEvent event) {
				hasFocus = false;
				if (showOnlyOnFocus) {
					update();
				}
			}
		};
		printAddListener(control, "FOCUS"); //$NON-NLS-1$
		control.addFocusListener(focusListener);

		// Listener for painting the decoration
		paintListener = new PaintListener() {
			public void paintControl(PaintEvent event) {
				Control control = (Control) event.widget;
				Rectangle rect = getDecorationRectangle(control);
				if (shouldShowDecoration()) {
					event.gc.drawImage(getImage(), rect.x, rect.y);
				}
			}
		};

		// Listener for tracking the end of a hover. Only installed
		// after a hover begins.
		mouseMoveListener = new MouseMoveListener() {
			public void mouseMove(MouseEvent event) {
				if (showHover) {
					if (!decorationRectangle.contains(event.x, event.y)) {
						hideHover();
						// No need to listen any longer
						printRemoveListener(event.widget, "MOUSEMOVE"); //$NON-NLS-1$
						((Control) event.widget)
								.removeMouseMoveListener(mouseMoveListener);
						moveListeningTarget = null;
					}
				}
			}
		};

		// Listener for tracking the beginning of a hover. Always installed.
		mouseTrackListener = new MouseTrackListener() {
			public void mouseExit(MouseEvent event) {
				// Just in case we didn't catch it before.
				Control target = (Control) event.widget;
				if (target == moveListeningTarget) {
					printRemoveListener(target, "MOUSEMOVE"); //$NON-NLS-1$
					target.removeMouseMoveListener(mouseMoveListener);
					moveListeningTarget = null;
				}
				hideHover();
			}

			public void mouseHover(MouseEvent event) {
				if (showHover) {
					decorationRectangle = getDecorationRectangle((Control) event.widget);
					if (decorationRectangle.contains(event.x, event.y)) {
						showHoverText(getDescriptionText());
						Control target = (Control) event.widget;
						if (moveListeningTarget == null) {
							printAddListener(target, "MOUSEMOVE"); //$NON-NLS-1$
							target.addMouseMoveListener(mouseMoveListener);
							moveListeningTarget = target;
						} else if (target != moveListeningTarget) {
							printRemoveListener(moveListeningTarget,
									"MOUSEMOVE"); //$NON-NLS-1$
							moveListeningTarget
									.removeMouseMoveListener(mouseMoveListener);
							printAddListener(target, "MOUSEMOVE"); //$NON-NLS-1$
							target.addMouseMoveListener(mouseMoveListener);
							moveListeningTarget = target;
						} else {
							// It is already installed on this control.
						}
					}
				}
			}

			public void mouseEnter(MouseEvent event) {
				// Nothing to do until a hover occurs.
			}
		};

		compositeListener = new Listener() {
			public void handleEvent(Event event) {
				// Don't forward events if decoration is not showing
				if (!visible) {
					return;
				}
				// Notify listeners if any are registered.
				switch (event.type) {
				case SWT.MouseDown:
					if (!selectionListeners.isEmpty())
						notifySelectionListeners(event);
					break;
				case SWT.MouseDoubleClick:
					if (!selectionListeners.isEmpty())
						notifySelectionListeners(event);
					break;
				case SWT.MenuDetect:
					if (!menuDetectListeners.isEmpty())
						notifyMenuDetectListeners(event);
					break;
				}
			}
		};

		// We do not know which parent in the control hierarchy
		// is providing the decoration space, so hook all the way up, until
		// the shell or the specified parent composite is reached.
		Composite c = control.getParent();
		while (c != null) {
			installCompositeListeners(c);
			if (composite != null && composite == c) {
				// We just installed on the specified composite, so stop.
				c = null;
			} else if (c instanceof Shell) {
				// We just installed on a shell, so don't go further
				c = null;
			} else {
				c = c.getParent();
			}
		}
		// force a redraw of the decoration area so our paint listener
		// is notified.
		update();
	}

	/*
	 * Install the listeners used to paint and track mouse events on the
	 * composite.
	 */
	private void installCompositeListeners(Composite c) {
		if (!c.isDisposed()) {
			printAddListener(c, "PAINT"); //$NON-NLS-1$
			c.addPaintListener(paintListener);
			printAddListener(c, "MOUSETRACK"); //$NON-NLS-1$
			c.addMouseTrackListener(mouseTrackListener);
			printAddListener(c, "SWT.MenuDetect"); //$NON-NLS-1$
			c.addListener(SWT.MenuDetect, compositeListener);
			printAddListener(c, "SWT.MouseDown"); //$NON-NLS-1$
			c.addListener(SWT.MouseDown, compositeListener);
			printAddListener(c, "SWT.MouseDoubleClick"); //$NON-NLS-1$
			c.addListener(SWT.MouseDoubleClick, compositeListener);
		}
	}

	/*
	 * Remove the listeners used to paint and track mouse events on the
	 * composite.
	 */
	private void removeCompositeListeners(Composite c) {
		if (!c.isDisposed()) {
			printRemoveListener(c, "PAINT"); //$NON-NLS-1$
			c.removePaintListener(paintListener);
			printRemoveListener(c, "MOUSETRACK"); //$NON-NLS-1$
			c.removeMouseTrackListener(mouseTrackListener);
			printRemoveListener(c, "SWT.MenuDetect"); //$NON-NLS-1$
			c.removeListener(SWT.MenuDetect, compositeListener);
			printRemoveListener(c, "SWT.MouseDown"); //$NON-NLS-1$
			c.removeListener(SWT.MouseDown, compositeListener);
			printRemoveListener(c, "SWT.MouseDoubleClick"); //$NON-NLS-1$
			c.removeListener(SWT.MouseDoubleClick, compositeListener);
		}
	}

	private void notifySelectionListeners(Event event) {
		if (!(event.widget instanceof Control)) {
			return;
		}
		if (getDecorationRectangle((Control) event.widget).contains(event.x,
				event.y)) {
			SelectionEvent clientEvent = new SelectionEvent(event);
			clientEvent.data = this;
			if (getImage() != null) {
				clientEvent.height = getImage().getBounds().height;
				clientEvent.width = getImage().getBounds().width;
			}
			Object[] listeners;
			switch (event.type) {
			case SWT.MouseDoubleClick:
				if (event.button == 1) {
					listeners = selectionListeners.getListeners();
					for (int i = 0; i < listeners.length; i++) {
						((SelectionListener) listeners[i])
								.widgetDefaultSelected(clientEvent);
					}
				}
				break;
			case SWT.MouseDown:
				if (event.button == 1) {
					listeners = selectionListeners.getListeners();
					for (int i = 0; i < listeners.length; i++) {
						((SelectionListener) listeners[i])
								.widgetSelected(clientEvent);
					}
				}
				break;
			}
		}
	}

	private void notifyMenuDetectListeners(Event event) {
		if (getDecorationRectangle(null).contains(event.x, event.y)) {
			MenuDetectEvent clientEvent = new MenuDetectEvent(event);
			clientEvent.data = this;
			Object[] listeners = menuDetectListeners.getListeners();
			for (int i = 0; i < listeners.length; i++) {
				((MenuDetectListener) listeners[i]).menuDetected(clientEvent);

			}
		}
	}

	/**
	 * Show the specified text using the same hover dialog as is used to show
	 * decorator descriptions. When {@link #setShowHover(boolean)} has been set
	 * to <code>true</code>, a decoration's description text will be shown in
	 * an info hover over the field's control whenever the mouse hovers over the
	 * decoration. This method can be used to show a decoration's description
	 * text at other times (such as when the control receives focus), or to show
	 * other text associated with the field. The hover will not be shown if the
	 * decoration is hidden.
	 * 
	 * @param text
	 *            the text to be shown in the info hover, or <code>null</code>
	 *            if no text should be shown.
	 */
	public void showHoverText(String text) {
		if (control == null) {
			return;
		}
		showHoverText(text, control);
	}

	/**
	 * Hide any hover popups that are currently showing on the control. When
	 * {@link #setShowHover(boolean)} has been set to <code>true</code>, a
	 * decoration's description text will be shown in an info hover over the
	 * field's control as long as the mouse hovers over the decoration, and will
	 * be hidden when the mouse exits the decoration. This method can be used to
	 * hide a hover, whether it was shown explicitly using
	 * {@link #showHoverText(String)}, or was showing because the user was
	 * hovering in the decoration.
	 * <p>
	 * This message has no effect if there is no current hover.
	 * 
	 */
	public void hideHover() {
		if (hover != null) {
			hover.setVisible(false);
		}
	}

	/**
	 * Show the control decoration. This message has no effect if the decoration
	 * is already showing. If {@link #setShowOnlyOnFocus(boolean)} is set to
	 * <code>true</code>, the decoration will only be shown if the control
	 * has focus.
	 */
	public void show() {
		if (!visible) {
			visible = true;
			update();
		}
	}

	/**
	 * Hide the control decoration and any associated hovers. This message has
	 * no effect if the decoration is already hidden.
	 */
	public void hide() {
		if (visible) {
			visible = false;
			hideHover();
			update();
		}
	}

	/**
	 * Get the description text that may be shown in a hover for this
	 * decoration.
	 * 
	 * @return the text to be shown as a description for the decoration, or
	 *         <code>null</code> if none has been set.
	 */
	public String getDescriptionText() {
		return descriptionText;
	}

	/**
	 * Set the image shown in this control decoration. Update the rendered
	 * decoration.
	 * 
	 * @param text
	 *            the text to be shown as a description for the decoration, or
	 *            <code>null</code> if none has been set.
	 */
	public void setDescriptionText(String text) {
		this.descriptionText = text;
		update();
	}

	/**
	 * Get the image shown in this control decoration.
	 * 
	 * @return the image to be shown adjacent to the control, or
	 *         <code>null</code> if one has not been set.
	 */
	public Image getImage() {
		return image;
	}

	/**
	 * Set the image shown in this control decoration. Update the rendered
	 * decoration.
	 * 
	 * @param image
	 *            the image to be shown adjacent to the control. Should never be
	 *            <code>null</code>.
	 */
	public void setImage(Image image) {
		previousDecorationRectangle = getDecorationRectangle(control.getShell());
		this.image = image;
		update();
	}

	/**
	 * Get the boolean that controls whether the decoration is shown only when
	 * the control has focus. The default value of this setting is
	 * <code>false</code>.
	 * 
	 * @return <code>true</code> if the decoration should only be shown when
	 *         the control has focus, and <code>false</code> if it should
	 *         always be shown. Note that if the control is not capable of
	 *         receiving focus (<code>SWT.NO_FOCUS</code>), then the
	 *         decoration will never show when this value is <code>true</code>.
	 */
	public boolean getShowOnlyOnFocus() {
		return showOnlyOnFocus;
	}

	/**
	 * Set the boolean that controls whether the decoration is shown only when
	 * the control has focus. The default value of this setting is
	 * <code>false</code>.
	 * 
	 * @param showOnlyOnFocus
	 *            <code>true</code> if the decoration should only be shown
	 *            when the control has focus, and <code>false</code> if it
	 *            should always be shown. Note that if the control is not
	 *            capable of receiving focus (<code>SWT.NO_FOCUS</code>),
	 *            then the decoration will never show when this value is
	 *            <code>true</code>.
	 */
	public void setShowOnlyOnFocus(boolean showOnlyOnFocus) {
		this.showOnlyOnFocus = showOnlyOnFocus;
		update();
	}

	/**
	 * Get the boolean that controls whether the decoration's description text
	 * should be shown in a hover when the user hovers over the decoration. The
	 * default value of this setting is <code>true</code>.
	 * 
	 * @return <code>true</code> if a hover popup containing the decoration's
	 *         description text should be shown when the user hovers over the
	 *         decoration, and <code>false</code> if a hover should not be
	 *         shown.
	 */
	public boolean getShowHover() {
		return showHover;
	}

	/**
	 * Set the boolean that controls whether the decoration's description text
	 * should be shown in a hover when the user hovers over the decoration. The
	 * default value of this setting is <code>true</code>.
	 * 
	 * @param showHover
	 *            <code>true</code> if a hover popup containing the
	 *            decoration's description text should be shown when the user
	 *            hovers over the decoration, and <code>false</code> if a
	 *            hover should not be shown.
	 */
	public void setShowHover(boolean showHover) {
		this.showHover = showHover;
		update();
	}

	/**
	 * Get the margin width in pixels that should be used between the decorator
	 * and the horizontal edge of the control. The default value of this setting
	 * is <code>0</code>.
	 * 
	 * @return the number of pixels that should be reserved between the
	 *         horizontal edge of the control and the adjacent edge of the
	 *         decoration.
	 */
	public int getMarginWidth() {
		return marginWidth;
	}

	/**
	 * Set the margin width in pixels that should be used between the decorator
	 * and the horizontal edge of the control. The default value of this setting
	 * is <code>0</code>.
	 * 
	 * @param marginWidth
	 *            the number of pixels that should be reserved between the
	 *            horizontal edge of the control and the adjacent edge of the
	 *            decoration.
	 */
	public void setMarginWidth(int marginWidth) {
		previousDecorationRectangle = getDecorationRectangle(control.getShell());
		this.marginWidth = marginWidth;
		update();
	}

	/**
	 * Something has changed, requiring redraw. Redraw the decoration and update
	 * the hover text if appropriate.
	 */
	protected void update() {
		if (control == null || control.isDisposed()) {
			return;
		}
		Rectangle rect = getDecorationRectangle(control.getShell());
		// If this update is happening due to an image reset, we need to make
		// sure we clear the area from the old image.
		// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=212501
		if (previousDecorationRectangle != null) {
			rect = rect.union(previousDecorationRectangle);
		}
		// Redraw this rectangle in all children
		control.getShell()
				.redraw(rect.x, rect.y, rect.width, rect.height, true);
		control.getShell().update();
		if (hover != null && getDescriptionText() != null) {
			hover.setText(getDescriptionText(), getDecorationRectangle(control
					.getParent()), control);
		}
		previousDecorationRectangle = null;
	}

	/*
	 * Show the specified text in the hover, positioning the hover near the
	 * specified control.
	 */
	private void showHoverText(String text, Control hoverNear) {
		// If we aren't to show a hover, don't do anything.
		if (!showHover) {
			return;
		}

		// If we are not visible, don't show the hover.
		if (!visible) {
			return;
		}
		// If there is no text, don't do anything.
		if (text == null) {
			hideHover();
			return;
		}

		// If there is no control, nothing to do
		if (control == null) {
			return;
		}
		// Create the hover if it's not showing
		if (hover == null) {
			hover = new Hover(hoverNear.getShell());
		}
		hover.setText(text, getDecorationRectangle(control.getParent()),
				control);
		hover.setVisible(true);
	}

	/*
	 * Remove any listeners installed on the controls.
	 */
	private void removeControlListeners() {
		if (control == null) {
			return;
		}
		printRemoveListener(control, "FOCUS"); //$NON-NLS-1$
		control.removeFocusListener(focusListener);
		focusListener = null;

		printRemoveListener(control, "DISPOSE"); //$NON-NLS-1$
		control.removeDisposeListener(disposeListener);
		disposeListener = null;

		Composite c = control.getParent();
		while (c != null) {
			removeCompositeListeners(c);
			if (composite != null && composite == c) {
				// We previously installed listeners only to the specified
				// composite, so stop.
				c = null;
			} else if (c instanceof Shell) {
				// We previously installed listeners only up to the first Shell
				// encountered, so stop.
				c = null;
			} else {
				c = c.getParent();
			}
		}
		paintListener = null;
		mouseTrackListener = null;
		compositeListener = null;

		// We may have a remaining mouse move listener installed
		if (moveListeningTarget != null) {
			printRemoveListener(moveListeningTarget, "MOUSEMOVE"); //$NON-NLS-1$
			moveListeningTarget.removeMouseMoveListener(mouseMoveListener);
			moveListeningTarget = null;
			mouseMoveListener = null;
		}
		if (DEBUG) {
			if (listenerInstalls > 0) {
				System.out.println("LISTENER LEAK>>>CHECK TRACE ABOVE"); //$NON-NLS-1$
			} else if (listenerInstalls < 0) {
				System.out
						.println("REMOVED UNREGISTERED LISTENERS>>>CHECK TRACE ABOVE"); //$NON-NLS-1$
			} else {
				System.out.println("ALL INSTALLED LISTENERS WERE REMOVED."); //$NON-NLS-1$
			}
		}
	}

	/**
	 * Return the rectangle in which the decoration should be rendered, in
	 * coordinates relative to the specified control. If the specified control
	 * is null, return the rectangle in display coordinates.
	 * 
	 * @param targetControl
	 *            the control whose coordinates should be used
	 * @return the rectangle in which the decoration should be rendered
	 */
	protected Rectangle getDecorationRectangle(Control targetControl) {
		if (getImage() == null || control == null) {
			return new Rectangle(0, 0, 0, 0);
		}
		// Compute the bounds first relative to the control's parent.
		Rectangle imageBounds = getImage().getBounds();
		Rectangle controlBounds = control.getBounds();
		int x, y;
		// Compute x
		if ((position & SWT.RIGHT) == SWT.RIGHT) {
			x = controlBounds.x + controlBounds.width + marginWidth;
		} else {
			// default is left
			x = controlBounds.x - imageBounds.width - marginWidth;
		}
		// Compute y
		if ((position & SWT.TOP) == SWT.TOP) {
			y = controlBounds.y;
		} else if ((position & SWT.BOTTOM) == SWT.BOTTOM) {
			y = controlBounds.y + control.getBounds().height
					- imageBounds.height;
		} else {
			// default is center
			y = controlBounds.y
					+ (control.getBounds().height - imageBounds.height) / 2;
		}

		// Now convert to coordinates relative to the target control.
		Point globalPoint = control.getParent().toDisplay(x, y);
		Point targetPoint;
		if (targetControl == null) {
			targetPoint = globalPoint;
		} else {
			targetPoint = targetControl.toControl(globalPoint);
		}
		return new Rectangle(targetPoint.x, targetPoint.y, imageBounds.width,
				imageBounds.height);
	}

	/*
	 * Return true if the decoration should be shown, false if it should not.
	 */
	private boolean shouldShowDecoration() {
		if (!visible) {
			return false;
		}
		if (control == null || control.isDisposed() || getImage() == null) {
			return false;
		}

		if (!control.isVisible()) {
			return false;
		}
		if (showOnlyOnFocus) {
			return hasFocus;
		}
		return true;
	}

	/*
	 * If in debug mode, print info about adding the specified listener.
	 */
	private void printAddListener(Widget widget, String listenerType) {
		listenerInstalls++;
		if (DEBUG) {
			System.out
					.println("Added listener>>>" + listenerType + " to>>>" + widget); //$NON-NLS-1$//$NON-NLS-2$
		}
	}

	/*
	 * If in debug mode, print info about adding the specified listener.
	 */
	private void printRemoveListener(Widget widget, String listenerType) {
		listenerInstalls--;
		if (DEBUG) {
			System.out
					.println("Removed listener>>>" + listenerType + " from>>>" + widget); //$NON-NLS-1$//$NON-NLS-2$
		}
	}
}
