/*******************************************************************************
 * Copyright (c) 2000, 2009 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.text;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
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.ScrollBar;
import org.eclipse.swt.widgets.Scrollable;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;

import org.eclipse.jface.internal.text.DelayedInputChangeListener;
import org.eclipse.jface.internal.text.InformationControlReplacer;
import org.eclipse.jface.internal.text.InternalAccessor;
import org.eclipse.jface.util.Geometry;

import org.eclipse.jface.text.ITextViewerExtension8.EnrichMode;
import org.eclipse.jface.text.source.AnnotationBarHoverManager;


/**
 * An information control manager that shows information in response to mouse
 * hover events. The mouse hover events are caught by registering a
 * {@link org.eclipse.swt.events.MouseTrackListener} on the manager's subject
 * control. The manager has by default an information control closer that closes
 * the information control as soon as the mouse pointer leaves the subject area,
 * the user presses a key, or the subject control is resized, moved, or
 * deactivated.
 * <p>
 * When being activated by a mouse hover event, the manager disables itself,
 * until the mouse leaves the subject area. Thus, the manager is usually still
 * disabled, when the information control has already been closed by the closer.
 *
 * @see org.eclipse.swt.events.MouseTrackListener
 * @since 2.0
 */
abstract public class AbstractHoverInformationControlManager extends AbstractInformationControlManager {

	/**
	 * The  information control closer for the hover information. Closes the information control as
	 * soon as the mouse pointer leaves the subject area (unless "move into hover" is enabled),
	 * a mouse button is pressed, the user presses a key, or the subject control is resized, moved, or loses focus.
	 */
	class Closer implements IInformationControlCloser, MouseListener, MouseMoveListener, ControlListener, KeyListener, SelectionListener, Listener {

		/** The closer's subject control */
		private Control fSubjectControl;
		/** The subject area */
		private Rectangle fSubjectArea;
		/** Indicates whether this closer is active */
		private boolean fIsActive= false;
		/**
		 * The cached display.
		 * @since 3.1
		 */
		private Display fDisplay;


		/**
		 * Creates a new information control closer.
		 */
		public Closer() {
		}

		@Override
		public void setSubjectControl(Control control) {
			fSubjectControl= control;
		}

		/*
		 * @see IInformationControlCloser#setHoverControl(IHoverControl)
		 */
		@Override
		public void setInformationControl(IInformationControl control) {
			// NOTE: we use getCurrentInformationControl() from the outer class
		}

		@Override
		public void start(Rectangle subjectArea) {

			if (fIsActive)
				return;
			fIsActive= true;
			fWaitForMouseUp= false;

			fSubjectArea= subjectArea;

			if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
				fSubjectControl.addMouseListener(this);
				fSubjectControl.addMouseMoveListener(this);
				fSubjectControl.addControlListener(this);
				fSubjectControl.addKeyListener(this);
				if (fSubjectControl instanceof Scrollable) {
					Scrollable scrollable= (Scrollable) fSubjectControl;
					ScrollBar vBar= scrollable.getVerticalBar();
					if (vBar != null)
						vBar.addSelectionListener(this);
					ScrollBar hBar= scrollable.getHorizontalBar();
					if (hBar != null)
						hBar.addSelectionListener(this);
				}

				fDisplay= fSubjectControl.getDisplay();
				if (!fDisplay.isDisposed()) {
					fDisplay.addFilter(SWT.Activate, this);
					fDisplay.addFilter(SWT.MouseVerticalWheel, this);

					fDisplay.addFilter(SWT.FocusOut, this);

					fDisplay.addFilter(SWT.MouseDown, this);
					fDisplay.addFilter(SWT.MouseUp, this);

					fDisplay.addFilter(SWT.MouseMove, this);
					fDisplay.addFilter(SWT.MouseEnter, this);
					fDisplay.addFilter(SWT.MouseExit, this);
				}
			}
		}

		@Override
		public void stop() {
			if (!fIsActive)
				return;

			fIsActive= false;

			if (DEBUG)
				System.out.println("AbstractHoverInformationControlManager.Closer stopped"); //$NON-NLS-1$

			if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
				fSubjectControl.removeMouseListener(this);
				fSubjectControl.removeMouseMoveListener(this);
				fSubjectControl.removeControlListener(this);
				fSubjectControl.removeKeyListener(this);
				if (fSubjectControl instanceof Scrollable) {
					Scrollable scrollable= (Scrollable) fSubjectControl;
					ScrollBar vBar= scrollable.getVerticalBar();
					if (vBar != null)
						vBar.removeSelectionListener(this);
					ScrollBar hBar= scrollable.getHorizontalBar();
					if (hBar != null)
						hBar.removeSelectionListener(this);
				}
			}

			if (fDisplay != null && !fDisplay.isDisposed()) {
				fDisplay.removeFilter(SWT.Activate, this);
				fDisplay.removeFilter(SWT.MouseVerticalWheel, this);

				fDisplay.removeFilter(SWT.FocusOut, this);

				fDisplay.removeFilter(SWT.MouseDown, this);
				fDisplay.removeFilter(SWT.MouseUp, this);

				fDisplay.removeFilter(SWT.MouseMove, this);
				fDisplay.removeFilter(SWT.MouseEnter, this);
				fDisplay.removeFilter(SWT.MouseExit, this);
			}
			fDisplay= null;
		}

		@Override
		public void mouseMove(MouseEvent event) {
			if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(getCurrentInformationControl())) {
				if (!fSubjectArea.contains(event.x, event.y)) {
					hideInformationControl();
				}

			} else if (getCurrentInformationControl() != null && !getCurrentInformationControl().isFocusControl()) {
				if (!inKeepUpZone(event.x, event.y, fSubjectControl, fSubjectArea, true)) {
					hideInformationControl();
				}
			}
		}

		@Override
		public void mouseUp(MouseEvent event) {
		}

		@Override
		public void mouseDown(MouseEvent event) {
			hideInformationControl();
		}

		@Override
		public void mouseDoubleClick(MouseEvent event) {
			hideInformationControl();
		}

		@Override
		public void controlResized(ControlEvent event) {
			hideInformationControl();
		}

		@Override
		public void controlMoved(ControlEvent event) {
			hideInformationControl();
		}

		@Override
		public void keyReleased(KeyEvent event) {
		}

		@Override
		public void keyPressed(KeyEvent event) {
			hideInformationControl();
		}

		@Override
		public void widgetSelected(SelectionEvent e) {
			hideInformationControl();
		}

		@Override
		public void widgetDefaultSelected(SelectionEvent e) {
		}

		@Override
		public void handleEvent(Event event) {
			switch (event.type) {
				case SWT.Activate:
				case SWT.MouseVerticalWheel:
					if (!hasInformationControlReplacer())
						hideInformationControl();
					else if (!isReplaceInProgress()) {
						IInformationControl infoControl= getCurrentInformationControl();
						// During isReplaceInProgress(), events can come from the replacing information control
						if (event.widget instanceof Control && infoControl instanceof IInformationControlExtension5) {
							Control control= (Control) event.widget;
							IInformationControlExtension5 iControl5= (IInformationControlExtension5) infoControl;
							if (!(iControl5.containsControl(control)))
								hideInformationControl();
							else if (event.type == SWT.MouseVerticalWheel && cancelReplacingDelay())
								replaceInformationControl(false);
						} else if (infoControl != null && infoControl.isFocusControl() && cancelReplacingDelay()) {
							replaceInformationControl(true);
						}
					}
					break;

				case SWT.MouseUp:
				case SWT.MouseDown:
					if (!hasInformationControlReplacer())
						hideInformationControl();
					else if (!isReplaceInProgress()) {
						IInformationControl infoControl= getCurrentInformationControl();
						if (event.widget instanceof Control && infoControl instanceof IInformationControlExtension5) {
							Control control= (Control) event.widget;
							final IInformationControlExtension5 iControl5= (IInformationControlExtension5) infoControl;
							if (!(iControl5.containsControl(control))) {
								hideInformationControl();
							} else if (cancelReplacingDelay()) {
								if (event.type == SWT.MouseUp) {
									stop(); // avoid that someone else replaces the info control before the async is exec'd
									if (infoControl instanceof IDelayedInputChangeProvider) {
										final IDelayedInputChangeProvider delayedICP= (IDelayedInputChangeProvider) infoControl;
										final IInputChangedListener inputChangeListener= new DelayedInputChangeListener(delayedICP, getInformationControlReplacer());
										delayedICP.setDelayedInputChangeListener(inputChangeListener);
										// cancel automatic input updating after a small timeout:
										control.getShell().getDisplay().timerExec(1000, new Runnable() {
											@Override
											public void run() {
												delayedICP.setDelayedInputChangeListener(null);
											}
										});
									}

									// XXX: workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=212392 :
									control.getShell().getDisplay().asyncExec(new Runnable() {
										@Override
										public void run() {
											replaceInformationControl(true);
										}
									});
								} else {
									fWaitForMouseUp= true;
								}
							}
						} else {
							handleMouseMove(event);
						}
					}
					break;

				case SWT.FocusOut:
					IInformationControl iControl= getCurrentInformationControl();
					if (iControl != null && ! iControl.isFocusControl())
						hideInformationControl();
					break;

				case SWT.MouseMove:
				case SWT.MouseEnter:
				case SWT.MouseExit:
					handleMouseMove(event);
					break;
			}
		}

		/**
		 * Handle mouse movement events.
		 *
		 * @param event the event
		 * @since 3.4
		 */
		private void handleMouseMove(Event event) {
//			if (DEBUG)
//				System.out.println("AbstractHoverInformationControl.Closer.handleMouseMove():" + event); //$NON-NLS-1$

			if (!(event.widget instanceof Control))
				return;
			Control eventControl= (Control) event.widget;

			//transform coordinates to subject control:
			Point mouseLoc= event.display.map(eventControl, fSubjectControl, event.x, event.y);

			if (fSubjectArea.contains(mouseLoc))
				return;

			IInformationControl iControl= getCurrentInformationControl();
			if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(iControl)) {
				if (AbstractHoverInformationControlManager.this instanceof AnnotationBarHoverManager) {
					if (getInternalAccessor().getAllowMouseExit())
						return;
				}
				hideInformationControl();
				return;
			}

			IInformationControlExtension3 iControl3= (IInformationControlExtension3) iControl;
			Rectangle controlBounds= iControl3.getBounds();
			if (controlBounds != null) {
				Rectangle tooltipBounds= event.display.map(null, eventControl, controlBounds);
				if (tooltipBounds.contains(event.x, event.y)) {
					if (!isReplaceInProgress() && event.type != SWT.MouseExit)
						startReplaceInformationControl(event.display);
					return;
				}
				cancelReplacingDelay();
			}

			if (!fSubjectControl.getBounds().contains(mouseLoc)) {
				/*
				 *  Use inKeepUpZone() to make sure it also works when the hover is
				 *  completely outside of the subject control.
				 */
				if (!inKeepUpZone(mouseLoc.x, mouseLoc.y, fSubjectControl, fSubjectArea, true)) {
					hideInformationControl();
					return;
				}
			}
		}
	}

	/**
	 * To be installed on the manager's subject control.  Serves two different purposes:
	 * <ul>
	 * <li> start function: initiates the computation of the information to be presented. This happens on
	 * 		receipt of a mouse hover event and disables the information control manager,
	 * <li> restart function: tracks mouse move and shell activation event to determine when the information
	 * 		control manager needs to be reactivated.
	 * </ul>
	 */
	class MouseTracker extends ShellAdapter implements MouseTrackListener, MouseMoveListener {

		/** Margin around the original hover event location for computing the hover area. */
		private final static int EPSILON= 3;

		/** The area in which the original hover event occurred. */
		private Rectangle fHoverArea;
		/** The area for which is computed information is valid. */
		private Rectangle fSubjectArea;
		/** The tracker's subject control. */
		private Control fSubjectControl;

		/** Indicates whether the tracker is in restart mode ignoring hover events. */
		private boolean fIsInRestartMode= false;
		/** Indicates whether the tracker is computing the information to be presented. */
		private boolean fIsComputing= false;
		/** Indicates whether the mouse has been lost. */
		private boolean fMouseLostWhileComputing= false;
		/** Indicates whether the subject control's shell has been deactivated. */
		private boolean fShellDeactivatedWhileComputing= false;

		/**
		 * Creates a new mouse tracker.
		 */
		public MouseTracker() {
		}

		/**
		 * Sets this mouse tracker's subject area, the area to be tracked in order
		 * to re-enable the information control manager.
		 *
		 * @param subjectArea the subject area
		 */
		public void setSubjectArea(Rectangle subjectArea) {
			Assert.isNotNull(subjectArea);
			fSubjectArea= subjectArea;
		}

		/**
		 * Starts this mouse tracker. The given control becomes this tracker's subject control.
		 * Installs itself as mouse track listener on the subject control.
		 *
		 * @param subjectControl the subject control
		 */
		public void start(Control subjectControl) {
			start(subjectControl, subjectControl);
		}

		/**
		 * Starts this mouse tracker. The given control becomes this tracker's subject control.
		 * Installs itself as mouse track listener on the subject control. The mouse move listener
		 * gets installed on the area control. The subject control is the element the hover element
		 * is attached to. The area control is the container that holds the subject control. It
		 * denotes the area to be tracked for mouse move events while the hover is open. Usually
		 * this should be the root composite of the current view. If the area is too small, the
		 * hover will not close correctly on some occasions.
		 *
		 * @param subjectControl the subject control
		 * @param areaControl the area control
		 * @since 3.11
		 */
		public void start(Control subjectControl, Control areaControl) {

			fSubjectControl= subjectControl;
			fAreaControl= areaControl;

			if (fSubjectControl != null && !fSubjectControl.isDisposed())
				fSubjectControl.addMouseTrackListener(this);

			fIsInRestartMode= false;
			fIsComputing= false;
			fMouseLostWhileComputing= false;
			fShellDeactivatedWhileComputing= false;
		}

		/**
		 * Stops this mouse tracker. Removes itself  as mouse track, mouse move, and
		 * shell listener from the subject control.
		 */
		public void stop() {
			if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
				fSubjectControl.removeMouseTrackListener(this);
				fSubjectControl.getShell().removeShellListener(this);
			}
			if (fAreaControl != null && !fAreaControl.isDisposed()) {
				fAreaControl.removeMouseMoveListener(this);
			}
		}

		/**
		 * Initiates the computation of the information to be presented. Sets the initial hover area
		 * to a small rectangle around the hover event location. Adds mouse move and shell activation listeners
		 * to track whether the computed information is, after completion, useful for presentation and to
		 * implement the restart function.
		 *
		 * @param event the mouse hover event
		 */
		@Override
		public void mouseHover(MouseEvent event) {
			if (fIsComputing || fIsInRestartMode ||
					(fSubjectControl != null && !fSubjectControl.isDisposed() && fSubjectControl.getShell() != fSubjectControl.getShell().getDisplay().getActiveShell())) {
				if (DEBUG)
					System.out.println("AbstractHoverInformationControlManager...mouseHover: @ " + event.x + "/" + event.y + " : hover cancelled: fIsComputing= " + fIsComputing + ", fIsInRestartMode= " + fIsInRestartMode); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
				return;
			}

			fIsInRestartMode= true;
			fIsComputing= true;
			fMouseLostWhileComputing= false;
			fShellDeactivatedWhileComputing= false;

			fHoverEventStateMask= event.stateMask;
			fHoverEvent= event;
			fHoverArea= new Rectangle(event.x - EPSILON, event.y - EPSILON, 2 * EPSILON, 2 * EPSILON );
			if (fHoverArea.x < 0)
				fHoverArea.x= 0;
			if (fHoverArea.y < 0)
				fHoverArea.y= 0;
			setSubjectArea(fHoverArea);

			if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
				fSubjectControl.getShell().addShellListener(this);
			}
			if (fAreaControl != null && !fAreaControl.isDisposed()) {
				fAreaControl.addMouseMoveListener(this);
			}
			doShowInformation();
		}

		/**
		 * Deactivates this tracker's restart function and enables the information control
		 * manager. Does not have any effect if the tracker is still executing the start function (i.e.
		 * computing the information to be presented.
		 */
		protected void deactivate() {
			if (fIsComputing)
				return;

			fIsInRestartMode= false;
			if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
				fSubjectControl.getShell().removeShellListener(this);
			}
			if (fAreaControl != null && !fAreaControl.isDisposed()) {
				fAreaControl.removeMouseMoveListener(this);
			}
		}

		@Override
		public void mouseEnter(MouseEvent e) {
		}

		@Override
		public void mouseExit(MouseEvent e) {
			if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(getCurrentInformationControl()) || !inKeepUpZone(e.x, e.y, fSubjectControl, fSubjectArea, false)) {
				fMouseLostWhileComputing= true;
				deactivate();
			}
		}

		@Override
		public void mouseMove(MouseEvent event) {
			if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(getCurrentInformationControl())) {
				if (!fSubjectArea.contains(event.x, event.y))
					deactivate();
			} else {
				if (!inKeepUpZone(event.x, event.y, fSubjectControl, fSubjectArea, false))
					deactivate();
			}
		}

		@Override
		public void shellDeactivated(ShellEvent e) {
			fShellDeactivatedWhileComputing= true;
			deactivate();
		}

		@Override
		public void shellIconified(ShellEvent e) {
			fShellDeactivatedWhileComputing= true;
			deactivate();
		}

		/**
		 * Tells this tracker that the start function processing has been completed.
		 */
		public void computationCompleted() {
			fIsComputing= false;
			fMouseLostWhileComputing= false;
			fShellDeactivatedWhileComputing= false;
		}

		/**
		 * Determines whether the computed information is still useful for presentation.
		 * This is not the case, if the shell of the subject control has been deactivated, the mouse
		 * left the subject control, or the mouse moved on, so that it is no longer in the subject
		 * area.
		 *
		 * @return <code>true</code> if information is still useful for presentation, <code>false</code> otherwise
		 */
		public boolean isMouseLost() {

			if (fMouseLostWhileComputing || fShellDeactivatedWhileComputing)
				return true;

			if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
				Display display= fSubjectControl.getDisplay();
				Point p= display.getCursorLocation();
				p= fSubjectControl.toControl(p);
				if (!fSubjectArea.contains(p) && !fHoverArea.contains(p))
					return true;
			}

			return false;
		}
	}

	/**
	 * The delay in {@link ITextViewerExtension8.EnrichMode#AFTER_DELAY} mode after which
	 * the hover is enriched when the mouse has stopped moving inside the hover.
	 * @since 3.4
	 */
	private static final long HOVER_AUTO_REPLACING_DELAY= 200;

	/** The mouse tracker on the subject control */
	private MouseTracker fMouseTracker= new MouseTracker();
	/**
	 * The remembered hover event.
     * @since 3.0
	 */
	private MouseEvent fHoverEvent= null;
	/** The remembered hover event state mask of the keyboard modifiers */
	private int fHoverEventStateMask= 0;
	/**
	 * The thread that delays replacing of the hover information control.
	 * To be accessed in the UI thread only!
	 *
	 * @since 3.4
	 */
	private Job fReplacingDelayJob;

	/**
	 * The {@link ITextViewerExtension8.EnrichMode}, may be <code>null</code>.
	 * @since 3.4
	 */
	private EnrichMode fEnrichMode;

	/**
	 * Indicates whether we have received a MouseDown event and are waiting for a MouseUp
	 * (and don't replace the information control until that happened).
	 * @since 3.4
	 */
	private boolean fWaitForMouseUp= false;

	/**
	 * Control area for the mouse tracker.
	 */
	private Control fAreaControl;

	/**
	 * Creates a new hover information control manager using the given information control creator.
	 * By default a <code>Closer</code> instance is set as this manager's closer.
	 *
	 * @param creator the information control creator
	 */
	protected AbstractHoverInformationControlManager(IInformationControlCreator creator) {
		super(creator);
		setCloser(new Closer());
		setHoverEnrichMode(ITextViewerExtension8.EnrichMode.AFTER_DELAY);
	}

	/**
	 * Tests whether a given mouse location is within the keep-up zone.
	 * The hover should not be hidden as long as the mouse stays inside this zone.
	 *
	 * @param x the x coordinate, relative to the <em>subject control</em>
	 * @param y the y coordinate, relative to the <em>subject control</em>
	 * @param subjectControl the subject control
	 * @param subjectArea the area for which the presented information is valid
	 * @param blowUp If <code>true</code>, then calculate for the closer, i.e. blow up the keepUp area.
	 *        If <code>false</code>, then use tight bounds for hover detection.
	 *
	 * @return <code>true</code> iff the mouse event occurred in the keep-up zone
	 * @since 3.4
	 */
	private boolean inKeepUpZone(int x, int y, Control subjectControl, Rectangle subjectArea, boolean blowUp) {
		if (subjectArea.contains(x, y))
			return true;

		IInformationControl iControl= getCurrentInformationControl();
		if ((iControl instanceof IInformationControlExtension5 && !((IInformationControlExtension5) iControl).isVisible())) {
			iControl= null;
			if (getInformationControlReplacer() != null) {
				iControl= getInformationControlReplacer().getCurrentInformationControl2();
				if ((iControl instanceof IInformationControlExtension5 && !((IInformationControlExtension5) iControl).isVisible())) {
					return false;
				}
			}
		}
		if (iControl instanceof IInformationControlExtension3) {
			IInformationControlExtension3 iControl3= (IInformationControlExtension3) iControl;

			Rectangle iControlBounds= subjectControl.getDisplay().map(null, subjectControl, iControl3.getBounds());
			Rectangle totalBounds= Geometry.copy(iControlBounds);
			if (blowUp && isReplaceInProgress()) {
				//Problem: blown up iControl overlaps rest of subjectArea's line
				// solution for now: only blow up for keep up (closer), but not for further hover detection
				int margin= getInformationControlReplacer().getKeepUpMargin();
				Geometry.expand(totalBounds, margin, margin, margin, margin);
			}

			if (!blowUp) {
				if (iControlBounds.contains(x, y))
					return true;

				if (subjectArea.y + subjectArea.height < iControlBounds.y) {
					// special case for hover events: subjectArea totally above iControl:
					//  +-----------+
					//  |subjectArea|
					//  +-----------+
					//  |also keepUp|
					// ++-----------+-------+
					// | InformationControl |
					// +--------------------+
					if (subjectArea.y + subjectArea.height <= y && y <= totalBounds.y) {
						// is vertically between subject area and iControl
						if (subjectArea.x <= x && x <= subjectArea.x + subjectArea.width) {
							// is below subject area (in a vertical projection)
							return true;
						}
						// FIXME: cases when subjectArea extends to left or right of iControl?
					}
					return false;

				} else if (iControlBounds.x + iControlBounds.width < subjectArea.x) {
					// special case for hover events (e.g. in overview ruler): iControl totally left of subjectArea
					// +--------------------+-----------+
					// |                    |           +-----------+
					// | InformationControl |also keepUp|subjectArea|
					// |                    |           +-----------+
					// +--------------------+-----------+
					if (iControlBounds.x + iControlBounds.width <= x && x <= subjectArea.x) {
						// is horizontally between iControl and subject area
						if (iControlBounds.y <= y && y <= iControlBounds.y + iControlBounds.height) {
							// is to the right of iControl (in a horizontal projection)
							return true;
						}
					}
					return false;

				} else if (subjectArea.x + subjectArea.width < iControlBounds.x) {
					// special case for hover events (e.g. in annotation ruler): subjectArea totally left of iControl
					//             +-----------+--------------------+
					// +-----------+           |                    |
					// |subjectArea|also keepUp| InformationControl |
					// +-----------+           |                    |
					//             +-----------+--------------------+
					if (subjectArea.x + subjectArea.width <= x && x <= iControlBounds.x) {
						// is horizontally between subject area and iControl
						if (iControlBounds.y <= y && y <= iControlBounds.y + iControlBounds.height) {
							// is to the left of iControl (in a horizontal projection)
							return true;
						}
					}
					return false;
				}
			}

			// FIXME: should maybe use convex hull, not bounding box
			totalBounds.add(subjectArea);
			if (totalBounds.contains(x, y))
				return true;
		}
		return false;
	}

	/**
	 * Tests whether the given information control allows the mouse to be moved
	 * into it.
	 *
	 * @param iControl information control or <code>null</code> if none
	 * @return <code>true</code> if information control allows mouse move into
	 *         control, <code>false</code> otherwise
	 */
	boolean canMoveIntoInformationControl(IInformationControl iControl) {
		return fEnrichMode != null && canReplace(iControl);
	}

	@Override
	protected void hideInformationControl() {
		cancelReplacingDelay();
		super.hideInformationControl();
	}

	/**
	 * Sets the hover enrich mode. Only applicable when an information
	 * control replacer has been set with
	 * {@link #setInformationControlReplacer(InformationControlReplacer)} .
	 *
	 * @param mode the enrich mode
	 * @since 3.4
	 * @see ITextViewerExtension8#setHoverEnrichMode(org.eclipse.jface.text.ITextViewerExtension8.EnrichMode)
	 */
	void setHoverEnrichMode(EnrichMode mode) {
		fEnrichMode= mode;
	}

	@Override
	void replaceInformationControl(boolean takeFocus) {
		fWaitForMouseUp= false;
		super.replaceInformationControl(takeFocus);
	}

	/**
	 * Cancels the replacing delay job.
	 * @return <code>true</code> iff canceling was successful, <code>false</code> if replacing has already started
	 */
	boolean cancelReplacingDelay() {
		fWaitForMouseUp= false;
		if (fReplacingDelayJob != null && fReplacingDelayJob.getState() != Job.RUNNING) {
			boolean cancelled= fReplacingDelayJob.cancel();
			fReplacingDelayJob= null;
//			if (DEBUG)
//				System.out.println("AbstractHoverInformationControlManager.cancelReplacingDelay(): cancelled=" + cancelled); //$NON-NLS-1$
			return cancelled;
		}
//		if (DEBUG)
//			System.out.println("AbstractHoverInformationControlManager.cancelReplacingDelay(): not delayed"); //$NON-NLS-1$
		return true;
	}

	/**
	 * Starts replacing the information control, considering the current
	 * {@link ITextViewerExtension8.EnrichMode}.
	 * If set to {@link ITextViewerExtension8.EnrichMode#AFTER_DELAY}, this
	 * method cancels previous requests and restarts the delay timer.
	 *
	 * @param display the display to be used for the call to
	 *        {@link #replaceInformationControl(boolean)} in the UI thread
	 */
	private void startReplaceInformationControl(final Display display) {
		if (fEnrichMode == EnrichMode.ON_CLICK)
			return;

		if (fReplacingDelayJob != null) {
			if (fReplacingDelayJob.getState() != Job.RUNNING) {
				if (fReplacingDelayJob.cancel()) {
					if (fEnrichMode == EnrichMode.IMMEDIATELY) {
						fReplacingDelayJob= null;
						if (! fWaitForMouseUp)
							replaceInformationControl(false);
					} else {
//						if (DEBUG)
//							System.out.println("AbstractHoverInformationControlManager.startReplaceInformationControl(): rescheduled"); //$NON-NLS-1$
						fReplacingDelayJob.schedule(HOVER_AUTO_REPLACING_DELAY);
					}
				}
			}
			return;
		}

		fReplacingDelayJob= new Job("AbstractHoverInformationControlManager Replace Delayer") { //$NON-NLS-1$
			@Override
			public IStatus run(final IProgressMonitor monitor) {
		        if (monitor.isCanceled() || display.isDisposed()) {
					return Status.CANCEL_STATUS;
				}
				display.syncExec(new Runnable() {
					@Override
					public void run() {
						fReplacingDelayJob= null;
						if (monitor.isCanceled())
							return;
						if (! fWaitForMouseUp)
							replaceInformationControl(false);
					}
				});
				return Status.OK_STATUS;
			}
		};
		fReplacingDelayJob.setSystem(true);
		fReplacingDelayJob.setPriority(Job.INTERACTIVE);
//		if (DEBUG)
//			System.out.println("AbstractHoverInformationControlManager.startReplaceInformationControl(): scheduled"); //$NON-NLS-1$
		fReplacingDelayJob.schedule(HOVER_AUTO_REPLACING_DELAY);
	}

	@Override
	protected void presentInformation() {
		if (fMouseTracker == null) {
			super.presentInformation();
			return;
		}

		Rectangle area= getSubjectArea();
		if (area != null)
			fMouseTracker.setSubjectArea(area);

		if (fMouseTracker.isMouseLost()) {
			fMouseTracker.computationCompleted();
			fMouseTracker.deactivate();
		} else {
			fMouseTracker.computationCompleted();
			super.presentInformation();
		}
	}

	/**
	 * {@inheritDoc}
	 * @deprecated visibility will be changed to protected
	 */
	@Deprecated
	@Override
	public void setEnabled(boolean enabled) {

		boolean was= isEnabled();
		super.setEnabled(enabled);
		boolean is= isEnabled();

		if (was != is && fMouseTracker != null) {
			if (is)
				fMouseTracker.start(getSubjectControl(), fAreaControl);
			else
				fMouseTracker.stop();
		}
	}

	/**
	 * Disposes this manager's information control.
	 */
	@Override
	public void dispose() {
		if (fMouseTracker != null) {
			fMouseTracker.stop();
			fMouseTracker.fSubjectControl= null;
			fMouseTracker.fSubjectArea= null;
			fMouseTracker= null;
		}
		super.dispose();
	}

	/**
	 * Returns the location at which the most recent mouse hover event
	 * has been issued.
	 *
	 * @return the location of the most recent mouse hover event
	 */
	protected Point getHoverEventLocation() {
		return fHoverEvent != null ? new Point(fHoverEvent.x, fHoverEvent.y) : new Point(-1, -1);
	}

	/**
	 * Returns the most recent mouse hover event.
	 *
	 * @return the most recent mouse hover event or <code>null</code>
	 * @since 3.0
	 */
	protected MouseEvent getHoverEvent() {
		return fHoverEvent;
	}

 	/**
	 * Returns the SWT event state of the most recent mouse hover event.
	 *
	 * @return the SWT event state of the most recent mouse hover event
	 */
	protected int getHoverEventStateMask() {
		return fHoverEventStateMask;
 	}

	/**
	 * Returns an adapter that gives access to internal methods.
	 * <p>
	 * <strong>Note:</strong> This method is not intended to be referenced or overridden by clients.</p>
	 *
	 * @return the replaceable information control accessor
	 * @since 3.4
	 * @noreference This method is not intended to be referenced by clients.
	 * @nooverride This method is not intended to be re-implemented or extended by clients.
	 */
	@Override
	public InternalAccessor getInternalAccessor() {
		return new MyInternalAccessor() {
			@Override
			public void setHoverEnrichMode(EnrichMode mode) {
				AbstractHoverInformationControlManager.this.setHoverEnrichMode(mode);
			}
		};
	}

	/**
	 * Installs this manager on the given subject control. The hover control is now taking the role
	 * of the subject control. This implementation sets the control also as the information control
	 * closer's subject control and automatically enables this manager. The area control typically
	 * is the root composite of the display element (e.g. a window or a dialog) the subject control
	 * is embedded in. It is needed to correctly close popups when the mouse pointer leaves the
	 * popup area.
	 *
	 * @param subjectControl the subject control
	 * @param areaControl the area control
	 * @since 3.11
	 */
	public void install(Control subjectControl, Control areaControl) {
		fAreaControl= (areaControl != null) ? areaControl : subjectControl;
		super.install(subjectControl);
	}

	/**
	 * {@inheritDoc}
	 */
	public void install(Control subjectControl) {
		install(subjectControl, subjectControl);
	}
}
