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

import java.util.Iterator;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
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.MouseTrackAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
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.core.runtime.Assert;

import org.eclipse.jface.internal.text.InformationControlReplacer;
import org.eclipse.jface.internal.text.InternalAccessor;

import org.eclipse.jface.text.AbstractHoverInformationControlManager;
import org.eclipse.jface.text.AbstractInformationControlManager;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.ITextViewerExtension8.EnrichMode;
import org.eclipse.jface.text.JFaceTextUtil;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextUtilities;


/**
 * This manager controls the layout, content, and visibility of an information
 * control in reaction to mouse hover events issued by the vertical ruler of a
 * source viewer.
 * @since 2.0
 */
public class AnnotationBarHoverManager extends AbstractHoverInformationControlManager {

	/**
	 * The information control closer for the hover information. Closes the information control as soon as the mouse pointer leaves the subject area, a mouse button is pressed, the user presses a key, or the subject control is resized or moved.
	 *
	 * @since 3.0
	 * @deprecated As of 3.4, no longer used as closer from super class is used
	 */
	@Deprecated
	protected class Closer extends MouseTrackAdapter implements IInformationControlCloser, MouseListener, MouseMoveListener, ControlListener, KeyListener, DisposeListener, ShellListener, 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 information control. */
		private IInformationControl fInformationControlToClose;
		/**
		 * <code>true</code> if a wheel handler is installed.
		 * @since 3.2
		 */
		private boolean fHasWheelFilter= false;
		/**
		 * The cached display.
		 * @since 3.2
		 */
		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) {
			fInformationControlToClose= control;
		}

		@Override
		public void start(Rectangle subjectArea) {

			if (fIsActive) return;
			fIsActive= true;

			fSubjectArea= subjectArea;

			fInformationControlToClose.addDisposeListener(this);
			if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
				fSubjectControl.addMouseListener(this);
				fSubjectControl.addMouseMoveListener(this);
				fSubjectControl.addMouseTrackListener(this);
				fSubjectControl.getShell().addShellListener(this);
				fSubjectControl.addControlListener(this);
				fSubjectControl.addKeyListener(this);

				fDisplay= fSubjectControl.getDisplay();
				if (!fDisplay.isDisposed() && fHideOnMouseWheel) {
					fHasWheelFilter= true;
					fDisplay.addFilter(SWT.MouseHorizontalWheel, this);
					fDisplay.addFilter(SWT.MouseVerticalWheel, this);
				}
			}
		}

		@Override
		public void stop() {

			if (!fIsActive)
				return;
			fIsActive= false;

			if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
				fSubjectControl.removeMouseListener(this);
				fSubjectControl.removeMouseMoveListener(this);
				fSubjectControl.removeMouseTrackListener(this);
				fSubjectControl.getShell().removeShellListener(this);
				fSubjectControl.removeControlListener(this);
				fSubjectControl.removeKeyListener(this);
			}

			if (fDisplay != null && !fDisplay.isDisposed() && fHasWheelFilter) {
				fDisplay.removeFilter(SWT.MouseHorizontalWheel, this);
				fDisplay.removeFilter(SWT.MouseVerticalWheel, this);
			}
			fHasWheelFilter= false;

			fDisplay= null;

		}

		/**
		 * Stops the information control and if <code>delayRestart</code> is set allows restart only after a certain delay.
		 *
		 * @param delayRestart <code>true</code> if restart should be delayed
		 * @deprecated As of 3.4, replaced by {@link #stop()}. Note that <code>delayRestart</code> was never honored.
		 */
		@Deprecated
		protected void stop(boolean delayRestart) {
			stop();
		}

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

		@Override
		public void mouseUp(MouseEvent event) {
		}

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

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

		@Override
		public void handleEvent(Event event) {
			if (event.type == SWT.MouseHorizontalWheel || event.type == SWT.MouseVerticalWheel)
				hideInformationControl();
		}

		@Override
		public void mouseExit(MouseEvent event) {
			if (!fAllowMouseExit)
				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 shellActivated(ShellEvent e) {
		}

		@Override
		public void shellClosed(ShellEvent e) {
		}

		@Override
		public void shellDeactivated(ShellEvent e) {
			hideInformationControl();
		}

		@Override
		public void shellDeiconified(ShellEvent e) {
		}

		@Override
		public void shellIconified(ShellEvent e) {
		}

		@Override
		public void widgetDisposed(DisposeEvent e) {
			hideInformationControl();
		}
	}

	/** The source viewer the manager is connected to */
	private ISourceViewer fSourceViewer;
	/** The vertical ruler the manager is registered with */
	private IVerticalRulerInfo fVerticalRulerInfo;
	/** The annotation hover the manager uses to retrieve the information to display. Can be <code>null</code>. */
	private IAnnotationHover fAnnotationHover;
	/**
	 * Indicates whether the mouse cursor is allowed to leave the subject area without closing the hover.
	 * @since 3.0
	 */
	protected boolean fAllowMouseExit= false;
	/**
	 * Whether we should hide the over on mouse wheel action.
	 *
	 * @since 3.2
	 */
	private boolean fHideOnMouseWheel= true;

	/**
	 * The current annotation hover.
	 * @since 3.2
	 */
	private IAnnotationHover fCurrentHover;

	/**
	 * Creates an annotation hover manager with the given parameters. In addition,
	 * the hovers anchor is RIGHT and the margin is 5 points to the right.
	 *
	 * @param sourceViewer the source viewer this manager connects to
	 * @param ruler the vertical ruler this manager connects to
	 * @param annotationHover the annotation hover providing the information to be displayed
	 * @param creator the information control creator
	 * @deprecated As of 2.1, replaced by {@link AnnotationBarHoverManager#AnnotationBarHoverManager(IVerticalRulerInfo, ISourceViewer, IAnnotationHover, IInformationControlCreator)}
	 */
	@Deprecated
	public AnnotationBarHoverManager(ISourceViewer sourceViewer, IVerticalRuler ruler, IAnnotationHover annotationHover, IInformationControlCreator creator) {
		this(ruler, sourceViewer, annotationHover, creator);
	}

	/**
	 * Creates an annotation hover manager with the given parameters. In addition,
	 * the hovers anchor is RIGHT and the margin is 5 points to the right.
	 *
	 * @param rulerInfo the vertical ruler this manager connects to
	 * @param sourceViewer the source viewer this manager connects to
	 * @param annotationHover the annotation hover providing the information to be displayed or <code>null</code> if none
	 * @param creator the information control creator
	 * @since 2.1
	 */
	public AnnotationBarHoverManager(IVerticalRulerInfo rulerInfo, ISourceViewer sourceViewer, IAnnotationHover annotationHover, IInformationControlCreator creator) {
		super(creator);

		Assert.isNotNull(sourceViewer);

		fSourceViewer= sourceViewer;
		fVerticalRulerInfo= rulerInfo;
		fAnnotationHover= annotationHover;

		setAnchor(ANCHOR_RIGHT);
		setMargins(5, 0);
		// use closer from super class
	}

	@Override
	protected void computeInformation() {
		fAllowMouseExit= false;
		MouseEvent event= getHoverEvent();
		if ((event.stateMask & SWT.BUTTON_MASK) != 0) {
			setInformation(null, null);
			return;
		}
		IAnnotationHover hover= getHover(event);
		if (hover == null) {
			setInformation(null, null);
			return;
		}

		int line= getHoverLine(event);

		if (hover instanceof IAnnotationHoverExtension) {
			IAnnotationHoverExtension extension= (IAnnotationHoverExtension) hover;
			ILineRange range= extension.getHoverLineRange(fSourceViewer, line);
			setCustomInformationControlCreator(extension.getHoverControlCreator());
			range= adaptLineRange(range, line);
			if (range != null)
				setInformation(extension.getHoverInfo(fSourceViewer, range, computeNumberOfVisibleLines()), computeArea(range));
			else
				setInformation(null, null);

		} else {
			setCustomInformationControlCreator(null);
			setInformation(hover.getHoverInfo(fSourceViewer, line), computeArea(line));
		}

	}

	@Override
	protected void showInformationControl(Rectangle subjectArea) {
	    super.showInformationControl(subjectArea);
	    fCurrentHover= getHover(getHoverEvent());
	}

	@Override
	protected void hideInformationControl() {
		fCurrentHover= null;
	    super.hideInformationControl();
	}

	/**
	 * Adapts a given line range so that the result is a line range that does
	 * not overlap with any collapsed region and fits into the view port of the
	 * attached viewer.
	 *
	 * @param lineRange the original line range
	 * @param line the anchor line
	 * @return the adapted line range
	 * @since 3.0
	 */
	private ILineRange adaptLineRange(ILineRange lineRange, int line) {
		if (lineRange != null) {
			lineRange= adaptLineRangeToFolding(lineRange, line);
			if (lineRange != null)
				return adaptLineRangeToViewport(lineRange);
		}
		return null;
	}

	/**
	 * Adapts a given line range so that the result is a line range that does
	 * not overlap with any collapsed region of the attached viewer.
	 *
	 * @param lineRange the original line range
	 * @param line the anchor line
	 * @return the adapted line range
	 * @since 3.0
	 */
	private ILineRange adaptLineRangeToFolding(ILineRange lineRange, int line) {

		if (fSourceViewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 extension= (ITextViewerExtension5) fSourceViewer;

			try {
				IRegion region= convertToRegion(lineRange);
				IRegion[] coverage= extension.getCoveredModelRanges(region);
				if (coverage != null && coverage.length > 0) {
					IRegion container= findRegionContainingLine(coverage, line);
					if (container != null)
						return convertToLineRange(container);
				}

			} catch (BadLocationException x) {
			}

			return null;
		}

		return lineRange;
	}

	/**
	 * Adapts a given line range so that the result is a line range that fits
	 * into the view port of the attached viewer.
	 *
	 * @param lineRange the original line range
	 * @return the adapted line range
	 * @since 3.0
	 */
	private ILineRange adaptLineRangeToViewport(ILineRange lineRange) {

		try {
			StyledText text= fSourceViewer.getTextWidget();

			int topLine= text.getTopIndex();
			int rangeTopLine= getWidgetLineNumber(lineRange.getStartLine());
			int topDelta= Math.max(topLine - rangeTopLine, 0);

			Rectangle size= text.getClientArea();
			Rectangle trim= text.computeTrim(0, 0, 0, 0);
			int height= size.height - trim.height;

			int lines= JFaceTextUtil.getLineIndex(text, height) - text.getTopIndex();

			int bottomLine= topLine + lines;

			int rangeBottomLine= getWidgetLineNumber(lineRange.getStartLine() + lineRange.getNumberOfLines() - 1);
			int bottomDelta= Math.max(rangeBottomLine - bottomLine, 0);

			return new LineRange(lineRange.getStartLine() + topDelta, lineRange.getNumberOfLines() - bottomDelta - topDelta);

		} catch (BadLocationException ex) {
		}

		return null;
	}

	/**
	 * Converts a line range into a character range.
	 *
	 * @param lineRange the line range
	 * @return the corresponding character range
	 * @throws BadLocationException in case the given line range is invalid
	 */
	private IRegion convertToRegion(ILineRange lineRange) throws BadLocationException {
		IDocument document= fSourceViewer.getDocument();
		int startOffset= document.getLineOffset(lineRange.getStartLine());
		int endLine= lineRange.getStartLine() + Math.max(0, lineRange.getNumberOfLines() - 1);
		IRegion lineInfo= document.getLineInformation(endLine);
		int endOffset= lineInfo.getOffset() + lineInfo.getLength();
		return new Region(startOffset, endOffset - startOffset);
	}

	/**
	 * Returns the region out of the given set that contains the given line or
	 * <code>null</code>.
	 *
	 * @param regions the set of regions
	 * @param line the line
	 * @return the region of the set that contains the line
	 * @throws BadLocationException in case line is invalid
	 */
	private IRegion findRegionContainingLine(IRegion[] regions, int line) throws BadLocationException {
		IDocument document= fSourceViewer.getDocument();
		IRegion lineInfo= document.getLineInformation(line);
		for (int i= 0; i < regions.length; i++) {
			if (TextUtilities.overlaps(regions[i], lineInfo))
				return regions[i];
		}
		return null;
	}

	/**
	 * Converts a given character region into a line range.
	 *
	 * @param region the character region
	 * @return the corresponding line range
	 * @throws BadLocationException in case the given region in invalid
	 */
	private ILineRange convertToLineRange(IRegion region) throws BadLocationException {
		IDocument document= fSourceViewer.getDocument();
		int startLine= document.getLineOfOffset(region.getOffset());
		int endLine= document.getLineOfOffset(region.getOffset() + region.getLength());
		return new LineRange(startLine, endLine - startLine + 1);
	}

	/**
	 * Returns the visible area of the vertical ruler covered by the given line
	 * range.
	 *
	 * @param lineRange the line range
	 * @return the visible area
	 */
	private Rectangle computeArea(ILineRange lineRange) {
		try {
			StyledText text= fSourceViewer.getTextWidget();
			final int startLine= getWidgetLineNumber(lineRange.getStartLine());
			int y= JFaceTextUtil.computeLineHeight(text, 0, startLine, startLine) - text.getTopPixel();
			int height= JFaceTextUtil.computeLineHeight(text, startLine, startLine + lineRange.getNumberOfLines(), lineRange.getNumberOfLines());
			Point size= fVerticalRulerInfo.getControl().getSize();
			return new Rectangle(0, y, size.x, height);
		} catch (BadLocationException x) {
		}
		return null;
	}

	/**
	 * Returns the number of the currently visible lines.
	 *
	 * @return the number of the currently visible lines
	 */
	private int computeNumberOfVisibleLines() {
		StyledText textWidget= fSourceViewer.getTextWidget();
		int lineHeight= textWidget.getLineHeight();
		int clientAreaHeight= textWidget.getClientArea().height;
		return clientAreaHeight / lineHeight;
	}

	/**
	 * Determines the hover to be used to display information based on the source of the
	 * mouse hover event. If <code>fVerticalRulerInfo</code> is not a composite ruler, the
	 * standard hover is returned.
	 *
	 * @param event the source of the mouse hover event
	 * @return the hover depending on <code>source</code>, or <code>fAnnotationHover</code> if none can be found.
	 * @since 3.0
	 */
	private IAnnotationHover getHover(MouseEvent event) {
		if (event == null || event.getSource() == null)
			return fAnnotationHover;

		if (fVerticalRulerInfo instanceof CompositeRuler) {
			CompositeRuler comp= (CompositeRuler) fVerticalRulerInfo;
			for (Iterator<IVerticalRulerColumn> it= comp.getDecoratorIterator(); it.hasNext();) {
				Object o= it.next();
				if (o instanceof IVerticalRulerInfoExtension && o instanceof IVerticalRulerInfo) {
					if (((IVerticalRulerInfo) o).getControl() == event.getSource()) {
						IAnnotationHover hover= ((IVerticalRulerInfoExtension) o).getHover();
						if (hover != null)
							return hover;
					}
				}
			}
		}
		return fAnnotationHover;
	}

	/**
	 * Returns the line of interest deduced from the mouse hover event.
	 *
	 * @param event a mouse hover event that triggered hovering
	 * @return the document model line number on which the hover event occurred or <code>-1</code> if there is no event
	 * @since 3.0
	 */
	private int getHoverLine(MouseEvent event) {
		return event == null ? -1 : fVerticalRulerInfo.toDocumentLineNumber(event.y);
	}

	/**
	 * Returns for the widget line number for the given document line number.
	 *
	 * @param line the absolute line number
	 * @return the line number relative to the viewer's visible region
	 * @throws BadLocationException if <code>line</code> is not valid in the viewer's document
	 */
	private int getWidgetLineNumber(int line) throws BadLocationException {
		if (fSourceViewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 extension= (ITextViewerExtension5) fSourceViewer;
			return extension.modelLine2WidgetLine(line);
		}

		IRegion region= fSourceViewer.getVisibleRegion();
		int firstLine= fSourceViewer.getDocument().getLineOfOffset(region.getOffset());
		return line - firstLine;
	}

	/**
	 * Determines graphical area covered by the given line.
	 *
	 * @param line the number of the line in the viewer whose graphical extend in the vertical ruler must be computed
	 * @return the graphical extend of the given line
	 */
	private Rectangle computeArea(int line) {
		try {
			StyledText text= fSourceViewer.getTextWidget();
			int widgetLine= getWidgetLineNumber(line);
			int y= JFaceTextUtil.computeLineHeight(text, 0, widgetLine, widgetLine) - text.getTopPixel();
			Point size= fVerticalRulerInfo.getControl().getSize();
			return new Rectangle(0, y, size.x, text.getLineHeight(text.getOffsetAtLine(widgetLine)));
		} catch (IllegalArgumentException ex) {
		} catch (BadLocationException ex) {
		}
		return null;
	}

	/**
	 * Returns the annotation hover for this hover manager.
	 *
	 * @return the annotation hover for this hover manager or <code>null</code> if none
	 * @since 2.1
	 */
	protected IAnnotationHover getAnnotationHover() {
		return fAnnotationHover;
	}

	/**
	 * Returns the source viewer for this hover manager.
	 *
	 * @return the source viewer for this hover manager
	 * @since 2.1
	 */
	protected ISourceViewer getSourceViewer() {
		return fSourceViewer;
	}

	/**
	 * Returns the vertical ruler info for this hover manager
	 *
	 * @return the vertical ruler info for this hover manager
	 * @since 2.1
	 */
	protected IVerticalRulerInfo getVerticalRulerInfo() {
		return fVerticalRulerInfo;
	}

	@Override
	protected Point computeSizeConstraints(Control subjectControl, Rectangle subjectArea, IInformationControl informationControl) {

		Point constraints= super.computeSizeConstraints(subjectControl, subjectArea, informationControl);

		// make as big as text area, if possible
		StyledText styledText= fSourceViewer.getTextWidget();
		if (styledText != null) {
			Rectangle r= styledText.getClientArea();
			if (r != null) {
				constraints.x= r.width;
				constraints.y= r.height;
			}
		}

		return constraints;
	}

	@Override
	protected Point computeInformationControlLocation(Rectangle subjectArea, Point controlSize) {
		MouseEvent event= getHoverEvent();
		IAnnotationHover hover= getHover(event);

		if (hover instanceof IAnnotationHoverExtension) {
			IAnnotationHoverExtension extension= (IAnnotationHoverExtension) hover;
			boolean allowMouseExit= extension.canHandleMouseCursor();
			if (allowMouseExit) {
				return computeLocation(subjectArea, controlSize, ANCHOR_RIGHT);
			}
		}
		return super.computeInformationControlLocation(subjectArea, controlSize);
	}
	
	@Override
	protected Point computeLocation(Rectangle subjectArea, Point controlSize, Anchor anchor) {
		MouseEvent event= getHoverEvent();
		IAnnotationHover hover= getHover(event);

		boolean allowMouseExit= false;
		if (hover instanceof IAnnotationHoverExtension) {
			IAnnotationHoverExtension extension= (IAnnotationHoverExtension) hover;
			allowMouseExit= extension.canHandleMouseCursor();
		}
		boolean hideOnMouseWheel= true;
		if (hover instanceof IAnnotationHoverExtension2) {
			IAnnotationHoverExtension2 extension= (IAnnotationHoverExtension2) hover;
			hideOnMouseWheel= !extension.canHandleMouseWheel();
		}
		fHideOnMouseWheel= hideOnMouseWheel;

		if (allowMouseExit) {
			fAllowMouseExit= true;

			Control subjectControl= getSubjectControl();
			// return a location that just overlaps the annotation on the bar
			if (anchor == AbstractInformationControlManager.ANCHOR_RIGHT)
				return subjectControl.toDisplay(subjectArea.x - 4, subjectArea.y - 2);
			else if (anchor == AbstractInformationControlManager.ANCHOR_LEFT)
				return subjectControl.toDisplay(subjectArea.x + subjectArea.width - controlSize.x + 4, subjectArea.y - 2);
		}

		fAllowMouseExit= false;
		return super.computeLocation(subjectArea, controlSize, anchor);
	}

	/**
	 * Returns the currently shown annotation hover or <code>null</code> if none
	 * hover is shown.
	 *
	 * @return the currently shown annotation hover or <code>null</code>
	 * @since 3.2
	 */
    public IAnnotationHover getCurrentAnnotationHover() {
	    return fCurrentHover;
    }

	/**
	 * 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 InternalAccessor() {
			@Override
			public IInformationControl getCurrentInformationControl() {
				return AnnotationBarHoverManager.super.getInternalAccessor().getCurrentInformationControl();
			}

			@Override
			public void setInformationControlReplacer(InformationControlReplacer replacer) {
				AnnotationBarHoverManager.super.getInternalAccessor().setInformationControlReplacer(replacer);
			}

			@Override
			public InformationControlReplacer getInformationControlReplacer() {
				return AnnotationBarHoverManager.super.getInternalAccessor().getInformationControlReplacer();
			}

			@Override
			public boolean canReplace(IInformationControl control) {
				return AnnotationBarHoverManager.super.getInternalAccessor().canReplace(control);
			}

			@Override
			public boolean isReplaceInProgress() {
				return AnnotationBarHoverManager.super.getInternalAccessor().isReplaceInProgress();
			}

			@Override
			public void replaceInformationControl(boolean takeFocus) {
				AnnotationBarHoverManager.super.getInternalAccessor().replaceInformationControl(takeFocus);
			}

			@Override
			public void cropToClosestMonitor(Rectangle bounds) {
				AnnotationBarHoverManager.super.getInternalAccessor().cropToClosestMonitor(bounds);
			}

			@Override
			public void setHoverEnrichMode(EnrichMode mode) {
				AnnotationBarHoverManager.super.getInternalAccessor().setHoverEnrichMode(mode);
			}

			@Override
			public boolean getAllowMouseExit() {
				return fAllowMouseExit;
			}
		};
    }
}

