/*******************************************************************************
 * Copyright (c) 2000, 2010 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Sean Montgomery, sean_montgomery@comcast.net - https://bugs.eclipse.org/bugs/show_bug.cgi?id=45095
 *******************************************************************************/

package org.eclipse.jface.text;


import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.GC;
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.Monitor;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.Platform;

import org.eclipse.jface.dialogs.IDialogSettings;
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;


/**
 * Manages the life cycle, visibility, layout, and contents of an
 * {@link org.eclipse.jface.text.IInformationControl}. This manager can be
 * installed on and removed from a control, referred to as the subject control,
 * i.e. the one from which the subject of the information to be shown is
 * retrieved. Also a manager can be enabled or disabled. An installed and
 * enabled manager can be forced to show information in its information control
 * using <code>showInformation</code>. An information control manager uses an
 * <code>IInformationControlCloser</code> to define the behavior when a
 * presented information control must be closed. The disposal of the subject and
 * the information control are internally handled by the information control
 * manager and are not the responsibility of the information control closer.
 *
 * @see org.eclipse.jface.text.IInformationControl
 * @since 2.0
 */
abstract public class AbstractInformationControlManager {

	/**
	 * An internal class that gives access to internal methods.
	 *
	 * @since 3.4
	 */
	class MyInternalAccessor extends InternalAccessor {
		@Override
		public IInformationControl getCurrentInformationControl() {
			return AbstractInformationControlManager.this.getCurrentInformationControl();
		}

		@Override
		public void setInformationControlReplacer(InformationControlReplacer replacer) {
			AbstractInformationControlManager.this.setInformationControlReplacer(replacer);
		}

		@Override
		public InformationControlReplacer getInformationControlReplacer() {
			return AbstractInformationControlManager.this.getInformationControlReplacer();
		}

		@Override
		public boolean canReplace(IInformationControl control) {
			return AbstractInformationControlManager.this.canReplace(control);
		}

		@Override
		public boolean isReplaceInProgress() {
			return AbstractInformationControlManager.this.isReplaceInProgress();
		}

		@Override
		public void replaceInformationControl(boolean takeFocus) {
			AbstractInformationControlManager.this.replaceInformationControl(takeFocus);
		}

		@Override
		public void cropToClosestMonitor(Rectangle bounds) {
			AbstractInformationControlManager.this.cropToClosestMonitor(bounds);
		}

		@Override
		public void setHoverEnrichMode(EnrichMode mode) {
			throw new UnsupportedOperationException("only implemented in AbstractHoverInformationControlManager"); //$NON-NLS-1$
		}

		@Override
		public boolean getAllowMouseExit() {
			throw new UnsupportedOperationException("only implemented in AnnotationBarHoverManager"); //$NON-NLS-1$
		}
	}

	/**
	 * Interface of an information control closer. An information control closer
	 * monitors its information control and its subject control and closes the
	 * information control if necessary.
	 * <p>
	 * Clients must implement this interface in order to equip an information
	 * control manager accordingly.
	 */
	public interface IInformationControlCloser {

		/**
		 * Sets the closer's subject control. This is the control that parents
		 * the information control and from which the subject of the information
		 * to be shown is retrieved. <p>
		 * Must be called before <code>start</code>. May again be called
		 * between <code>start</code> and <code>stop</code>.
		 *
		 * @param subject the subject control
		 */
		public void setSubjectControl(Control subject);

		/**
		 * Sets the closer's information control, the one to close if necessary. <p>
		 * Must be called before <code>start</code>. May again be called
		 * between <code>start</code> and <code>stop</code>.
		 *
		 * @param control the information control
		 */
		public void setInformationControl(IInformationControl control);

		/**
		 * Tells this closer to start monitoring the subject and the information
		 * control. The presented information is considered valid for the given
		 * area of the subject control's display.
		 *
		 * @param subjectArea the area for which the presented information is valid
		 */
		public void start(Rectangle subjectArea);

		/**
		 * Tells this closer to stop monitoring the subject and the information control.
		 */
		public void stop();
	}



	/**
	 * Constitutes entities to enumerate anchors for the layout of the information control.
	 */
	public static final class Anchor {
		private final int fFlag;
		private Anchor(int flag) {
			fFlag= flag;
		}
		/**
		 * Returns the SWT direction flag. One of {@link SWT#BOTTOM}, {@link SWT#TOP},
		 * {@link SWT#LEFT}, {@link SWT#RIGHT}, {@link SWT#CENTER},
		 *
		 * @return the SWT direction flag
		 * @since 3.3
		 */
		int getSWTFlag() {
			return fFlag;
		}

		@Override
		public String toString() {
			switch (fFlag) {
				case SWT.BOTTOM: return "BOTTOM"; //$NON-NLS-1$
				case SWT.TOP: return "TOP"; //$NON-NLS-1$
				case SWT.LEFT: return "LEFT"; //$NON-NLS-1$
				case SWT.RIGHT: return "RIGHT"; //$NON-NLS-1$
				case SWT.CENTER: return "CENTER"; //$NON-NLS-1$
				default: return Integer.toHexString(fFlag);
			}
		}
	}

	/** Internal anchor list. */
	private final static Anchor[] ANCHORS= { new Anchor(SWT.TOP), new Anchor(SWT.BOTTOM), new Anchor(SWT.LEFT), new Anchor(SWT.RIGHT) };

	/** Anchor representing the top of the information area */
	public final static Anchor ANCHOR_TOP=  ANCHORS[0];
	/** Anchor representing the bottom of the information area */
	public final static Anchor ANCHOR_BOTTOM=  ANCHORS[1];
	/** Anchor representing the left side of the information area */
	public final static Anchor ANCHOR_LEFT=  ANCHORS[2];
	/** Anchor representing the right side of the information area */
	public final static Anchor ANCHOR_RIGHT= ANCHORS[3];
	/**
	 * Anchor representing the middle of the subject control
	 * @since 2.1
	 */
	public final static Anchor ANCHOR_GLOBAL= new Anchor(SWT.CENTER);

	/**
	 * Dialog store constant for the location's x-coordinate.
	 * @since 3.0
	 */
	public static final String STORE_LOCATION_X= "location.x"; //$NON-NLS-1$
	/**
	 * Dialog store constant for the location's y-coordinate.
	 * @since 3.0
	 */
	public static final String STORE_LOCATION_Y= "location.y"; //$NON-NLS-1$
	/**
	 * Dialog store constant for the size's width.
	 * @since 3.0
	 */
	public static final String STORE_SIZE_WIDTH= "size.width"; //$NON-NLS-1$
	/**
	 * Dialog store constant for the size's height.
	 * @since 3.0
	 */
	public static final String STORE_SIZE_HEIGHT= "size.height"; //$NON-NLS-1$

	/**
	 * Tells whether this class and its subclasses are in debug mode.
	 * <p>
	 * Subclasses may use this.
	 * </p>
	 * @since 3.4
	 */
	protected static final boolean DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jface.text/debug/AbstractInformationControlManager"));  //$NON-NLS-1$//$NON-NLS-2$


	/** The subject control of the information control */
	private Control  fSubjectControl;

	/** The display area for which the information to be presented is valid */
	private Rectangle fSubjectArea;

	/** The information to be presented */
	private Object fInformation;

	/** Indicates whether the information control takes focus when visible */
	private boolean fTakesFocusWhenVisible= false;

	/**
	 * The information control.
	 *
	 * <p>This field should not be referenced by subclasses. It is <code>protected</code> for API
	 * compatibility reasons.
	 */
	protected IInformationControl fInformationControl;

	/**
	 * The information control creator.
	 *
	 * <p>This field should not be referenced by subclasses. It is <code>protected</code> for API
	 * compatibility reasons.
	 */
	protected IInformationControlCreator fInformationControlCreator;

	/**
	 * The information control closer.
	 *
	 * <p>This field should not be referenced by subclasses. It is <code>protected</code> for API
	 * compatibility reasons.
	 */
	protected IInformationControlCloser fInformationControlCloser;

	/**
	 * Indicates that the information control has been disposed.
	 *
	 * <p>This field should not be referenced by subclasses. It is <code>protected</code> for API
	 * compatibility reasons.
	 */
	protected boolean fDisposed= false;

	/**
	 * The information control replacer to be used when this information control
	 * needs to be replaced with another information control.
	 *
	 * @since 3.4
	 */
	private InformationControlReplacer fInformationControlReplacer;

	/** Indicates the enable state of this manager */
	private boolean fEnabled= false;

	/** Cached, computed size constraints of the information control in points */
	private Point fSizeConstraints;

	/** The vertical margin when laying out the information control */
	private int fMarginY= 5;

	/** The horizontal margin when laying out the information control */
	private int fMarginX= 5;

	/** The width constraint of the information control in characters */
	private int fWidthConstraint= 60;

	/** The height constraint of the information control  in characters */
	private int fHeightConstraint= 6;

	/** Indicates whether the size constraints should be enforced as minimal control size */
	private boolean fEnforceAsMinimalSize= false;

	/** Indicates whether the size constraints should be enforced as maximal control size */
	private boolean fEnforceAsMaximalSize= false;

	/** The anchor for laying out the information control in relation to the subject control */
	private Anchor fAnchor= ANCHOR_BOTTOM;

	/**
	 * The anchor sequence used to layout the information control if the original anchor
	 * can not be used because the information control would not fit in the display client area.
	 * <p>
	 * The fallback anchor for a given anchor is the one that comes directly after the given anchor or
	 * is the first one in the sequence if the given anchor is the last one in the sequence.
	 * <p>
	 * </p>
	 * Note: This sequence is ignored if the original anchor is not contained in this sequence.
	 * </p>
	 *
	 * @see #fAnchor
	 */
	private Anchor[] fFallbackAnchors= ANCHORS;

	/**
	 * The custom information control creator.
	 * @since 3.0
	 */
	private volatile IInformationControlCreator fCustomInformationControlCreator;

	/**
	 * Tells whether a custom information control is in use.
	 * @since 3.0
	 */
	private boolean fIsCustomInformationControl= false;

	/**
	 * The dialog settings for the control's bounds.
	 * @since 3.0
	 */
	private IDialogSettings fDialogSettings;

	/**
	 * Tells whether the control's location should be read
	 * from the dialog settings and whether the last
	 * valid control's size is stored back into the  settings.
	 *
	 * @since 3.0
	 */
	private boolean fIsRestoringLocation;

	/**
	 * Tells whether the control's size should be read
	 * from the dialog settings and whether the last
	 * valid control's size is stored back into the  settings.
	 *
	 * @since 3.0
	 */
	private boolean fIsRestoringSize;

	/**
	 * The dispose listener on the subject control.
	 *
	 * @since 3.1
	 */
	private DisposeListener fSubjectControlDisposeListener;


	/**
	 * Creates a new information control manager using the given information control creator.
	 * By default the following configuration is given:
	 * <ul>
	 * <li> enabled == false
	 * <li> horizontal margin == 5 points
	 * <li> vertical margin == 5 points
	 * <li> width constraint == 60 characters
	 * <li> height constraint == 6 characters
	 * <li> enforce constraints as minimal size == false
	 * <li> enforce constraints as maximal size == false
	 * <li> layout anchor == ANCHOR_BOTTOM
	 * <li> fall back anchors == { ANCHOR_TOP, ANCHOR_BOTTOM, ANCHOR_LEFT, ANCHOR_RIGHT, ANCHOR_GLOBAL }
	 * <li> takes focus when visible == false
	 * </ul>
	 *
	 * @param creator the information control creator
	 */
	protected AbstractInformationControlManager(IInformationControlCreator creator) {
		Assert.isNotNull(creator);
		fInformationControlCreator= creator;
	}

	/**
	 * Computes the information to be displayed and the area in which the computed
	 * information is valid. Implementation of this method must finish their computation
	 * by setting the computation results using <code>setInformation</code>.
	 */
	abstract protected void computeInformation();

	/**
	 * Sets the parameters of the information to be displayed. These are the information itself and
	 * the area for which the given information is valid. This so called subject area is a graphical
	 * region of the information control's subject control. This method calls <code>presentInformation()</code>
	 * to trigger the presentation of the computed information.
	 *
	 * @param information the information, or <code>null</code> if none is available
	 * @param subjectArea the subject area, or <code>null</code> if none is available
	 */
	protected final void setInformation(String information, Rectangle subjectArea) {
		setInformation((Object)information, subjectArea);
	}

	/**
	 * Sets the parameters of the information to be displayed. These are the information itself and
	 * the area for which the given information is valid. This so called subject area is a graphical
	 * region of the information control's subject control. This method calls <code>presentInformation()</code>
	 * to trigger the presentation of the computed information.
	 *
	 * @param information the information, or <code>null</code> if none is available
	 * @param subjectArea the subject area, or <code>null</code> if none is available
	 * @since  2.1
	 */
	protected final void setInformation(Object information, Rectangle subjectArea) {
		fInformation= information;
		fSubjectArea= subjectArea;
		presentInformation();
	}

	/**
	 * Sets the information control closer for this manager.
	 *
	 * @param closer the information control closer for this manager
	 */
	protected void setCloser(IInformationControlCloser closer) {
		fInformationControlCloser= closer;
	}

	/**
	 * Sets the information control replacer for this manager and disposes the
	 * old one if set.
	 *
	 * @param replacer the information control replacer for this manager, or
	 *            <code>null</code> if no information control replacing should
	 *            take place
	 * @since 3.4
	 */
	void setInformationControlReplacer(InformationControlReplacer replacer) {
		if (fInformationControlReplacer != null)
			fInformationControlReplacer.dispose();
		fInformationControlReplacer= replacer;
	}

	/**
	 * Returns the current information control replacer or <code>null</code> if none has been installed.
	 *
	 * @return the current information control replacer or <code>null</code> if none has been installed
	 * @since 3.4
	 */
	InformationControlReplacer getInformationControlReplacer() {
		return fInformationControlReplacer;
	}

	/**
	 * Returns whether an information control replacer has been installed.
	 *
	 * @return whether an information control replacer has been installed
	 * @since 3.4
	 */
	boolean hasInformationControlReplacer() {
		return fInformationControlReplacer != null;
	}

	/**
	 * Tests whether the given information control is replaceable.
	 *
	 * @param iControl information control or <code>null</code> if none
	 * @return <code>true</code> if information control is replaceable, <code>false</code> otherwise
	 * @since 3.4
	 */
	boolean canReplace(IInformationControl iControl) {
		return iControl instanceof IInformationControlExtension3
				&& iControl instanceof IInformationControlExtension5
				&& ((IInformationControlExtension5) iControl).getInformationPresenterControlCreator() != null;
	}

	/**
	 * Returns the current information control, or <code>null</code> if none.
	 *
	 * @return the current information control, or <code>null</code> if none
	 * @since 3.4
	 */
	IInformationControl getCurrentInformationControl() {
		return fInformationControl;
	}

	/**
	 * Tells whether this manager's information control is currently being replaced.
	 *
	 * @return <code>true</code> if a replace is in progress
	 * @since 3.4
	 */
	boolean isReplaceInProgress() {
		return fInformationControlReplacer != null && fInformationControlReplacer.isReplacing();
	}

	/**
	 * Sets the horizontal and vertical margin to be used when laying out the
	 * information control relative to the subject control.
	 *
	 * @param xMargin the x-margin
	 * @param yMargin the y-Margin
	 */
	public void setMargins(int xMargin, int yMargin) {
		fMarginX= xMargin;
		fMarginY= yMargin;
	}

	/**
	 * Sets the width- and height constraints of the information control.
	 *
	 * @param widthInChar the width constraint in number of characters
	 * @param heightInChar the height constrain in number of characters
	 * @param enforceAsMinimalSize indicates whether the constraints describe the minimal allowed size of the control
	 * @param enforceAsMaximalSize indicates whether the constraints describe the maximal allowed size of the control
	 */
	public void setSizeConstraints(int widthInChar, int heightInChar, boolean enforceAsMinimalSize, boolean enforceAsMaximalSize) {
		fSizeConstraints= null;
		fWidthConstraint= widthInChar;
		fHeightConstraint= heightInChar;
		fEnforceAsMinimalSize= enforceAsMinimalSize;
		fEnforceAsMaximalSize= enforceAsMaximalSize;

	}

	/**
	 * Tells this information control manager to open the information control with the values
	 * contained in the given dialog settings and to store the control's last valid size in the
	 * given dialog settings.
	 * <p>
	 * Note: This API is only valid if the information control implements
	 * {@link IInformationControlExtension3}. Not following this restriction will later result in an
	 * {@link UnsupportedOperationException}.
	 * </p>
	 * <p>
	 * The constants used to store the values are:
	 * <ul>
	 * <li>{@link AbstractInformationControlManager#STORE_LOCATION_X}</li>
	 * <li>{@link AbstractInformationControlManager#STORE_LOCATION_Y}</li>
	 * <li>{@link AbstractInformationControlManager#STORE_SIZE_WIDTH}</li>
	 * <li>{@link AbstractInformationControlManager#STORE_SIZE_HEIGHT}</li>
	 * </ul>
	 * </p>
	 *
	 * @param dialogSettings the dialog settings
	 * @param restoreLocation <code>true</code> iff the location is must be (re-)stored
	 * @param restoreSize <code>true</code>iff the size is (re-)stored
	 * @since 3.0
	 */
	public void setRestoreInformationControlBounds(IDialogSettings dialogSettings, boolean restoreLocation, boolean restoreSize) {
		Assert.isTrue(dialogSettings != null && (restoreLocation || restoreSize));
		fDialogSettings= dialogSettings;
		fIsRestoringLocation= restoreLocation;
		fIsRestoringSize= restoreSize;
	}

	/**
	 * Sets the anchor used for laying out the information control relative to the
	 * subject control. E.g, using <code>ANCHOR_TOP</code> indicates that the
	 * information control is position above the area for which the information to
	 * be displayed is valid.
	 *
	 * @param anchor the layout anchor
	 */
	public void setAnchor(Anchor anchor) {
		fAnchor= anchor;
	}

	/**
	 * Sets the anchors fallback sequence used to layout the information control if the original
	 * anchor can not be used because the information control would not fit in the display client
	 * area.
	 * <p>
	 * The fallback anchor for a given anchor is the one that comes directly after the given anchor or
	 * is the first one in the sequence if the given anchor is the last one in the sequence.
	 * <p>
	 * </p>
	 * Note: This sequence is ignored if the original anchor is not contained in this list.
	 * </p>
	 *
	 * @param fallbackAnchors the array with the anchor fallback sequence
	 * @see #setAnchor(AbstractInformationControlManager.Anchor)
	 */
	public void setFallbackAnchors(Anchor[] fallbackAnchors) {
		if (fallbackAnchors != null) {
			fFallbackAnchors= new Anchor[fallbackAnchors.length];
			System.arraycopy(fallbackAnchors, 0, fFallbackAnchors, 0, fallbackAnchors.length);
		} else
			fFallbackAnchors= null;
	}

	/**
	 * Sets the temporary custom control creator, overriding this manager's default information control creator.
	 *
	 * @param informationControlCreator the creator, possibly <code>null</code>
	 * @since 3.0
	 */
	protected void setCustomInformationControlCreator(IInformationControlCreator informationControlCreator)  {
		if (informationControlCreator != null && fCustomInformationControlCreator  instanceof IInformationControlCreatorExtension) {
			IInformationControlCreatorExtension extension= (IInformationControlCreatorExtension) fCustomInformationControlCreator;
			if (extension.canReplace(informationControlCreator))
				return;
		}
		fCustomInformationControlCreator= informationControlCreator;
	}

	/**
	 * Tells the manager whether it should set the focus to the information control when made visible.
	 *
	 * @param takesFocus <code>true</code> if information control should take focus when made visible
	 */
	public void takesFocusWhenVisible(boolean takesFocus) {
		fTakesFocusWhenVisible= takesFocus;
	}

	/**
	 * Tells whether the control takes focus when visible.
	 *
	 * @return <code>true</code> if the control takes focus when visible, <code>false</code>
	 *         otherwise
	 * @since 3.7
	 */
	protected boolean isTakingFocusWhenVisible() {
		return fTakesFocusWhenVisible;
	}

	/**
	 * Handles the disposal of the subject control. By default, the information control
	 * is disposed by calling <code>disposeInformationControl</code>. Subclasses may extend
	 * this method.
	 */
	protected void handleSubjectControlDisposed() {
		disposeInformationControl();
	}

	/**
	 * Installs this manager on the given control. The 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.
	 *
	 * @param subjectControl the subject control
	 */
	public void install(Control subjectControl) {
		if (fSubjectControl != null && !fSubjectControl.isDisposed() && fSubjectControlDisposeListener != null)
			fSubjectControl.removeDisposeListener(fSubjectControlDisposeListener);

		fSubjectControl= subjectControl;

		if (fSubjectControl != null)
			fSubjectControl.addDisposeListener(getSubjectControlDisposeListener());

		if (fInformationControlCloser != null)
			fInformationControlCloser.setSubjectControl(subjectControl);

		setEnabled(true);
		fDisposed= false;
	}

	/**
	 * Returns the dispose listener which gets added
	 * to the subject control.
	 *
	 * @return the dispose listener
	 * @since 3.1
	 */
	private DisposeListener getSubjectControlDisposeListener() {
		if (fSubjectControlDisposeListener == null) {
			fSubjectControlDisposeListener= new DisposeListener() {
				@Override
				public void widgetDisposed(DisposeEvent e) {
					handleSubjectControlDisposed();
				}
			};
		}
		return fSubjectControlDisposeListener;
	}

	/**
	 * Returns the subject control of this manager/information control.
	 *
	 * @return the subject control
	 */
	protected Control getSubjectControl() {
		return fSubjectControl;
	}

	/**
	 * Returns the actual subject area.
	 *
	 * @return the actual subject area
	 */
	protected Rectangle getSubjectArea() {
		return fSubjectArea;
	}

	/**
	 * Sets the enable state of this manager.
	 *
	 * @param enabled the enable state
	 * @deprecated visibility will be changed to protected
	 */
	@Deprecated
	public void setEnabled(boolean enabled) {
		fEnabled= enabled;
	}

	/**
	 * Returns whether this manager is enabled or not.
	 *
	 * @return <code>true</code> if this manager is enabled otherwise <code>false</code>
	 */
	protected boolean isEnabled() {
		return fEnabled;
	}

	/**
	 * Computes the size constraints of the information control in points based on the
	 * default font of the given subject control as well as the size constraints in character
	 * width.
	 *
	 * @param subjectControl the subject control
	 * @param informationControl the information control whose size constraints are computed
	 * @return the computed size constraints in points
	 */
	protected Point computeSizeConstraints(Control subjectControl, IInformationControl informationControl) {

		if (fSizeConstraints == null) {
			if (informationControl instanceof IInformationControlExtension5) {
				IInformationControlExtension5 iControl5= (IInformationControlExtension5) informationControl;
				fSizeConstraints= iControl5.computeSizeConstraints(fWidthConstraint, fHeightConstraint);
				if (fSizeConstraints != null)
					return Geometry.copy(fSizeConstraints);
			}
			if (subjectControl == null)
				return null;

			GC gc= new GC(subjectControl);
			gc.setFont(subjectControl.getFont());
			int width= gc.getFontMetrics().getAverageCharWidth();
			int height = gc.getFontMetrics().getHeight();
			gc.dispose();

			fSizeConstraints= new Point (fWidthConstraint * width, fHeightConstraint * height);
		}

		return new Point(fSizeConstraints.x, fSizeConstraints.y);
	}

	/**
	 * Computes the size constraints of the information control in points.
	 *
	 * @param subjectControl the subject control
	 * @param subjectArea the subject area
	 * @param informationControl the information control whose size constraints are computed
	 * @return the computed size constraints in points
	 * @since 3.0
	 */
	protected Point computeSizeConstraints(Control subjectControl, Rectangle subjectArea, IInformationControl informationControl) {
		return computeSizeConstraints(subjectControl, informationControl);
	}

	/**
	 * Handles the disposal of the information control. By default, the information
	 * control closer is stopped.
	 */
	protected void handleInformationControlDisposed() {

		storeInformationControlBounds();

		if (fInformationControl instanceof IInformationControlExtension5)
			fSizeConstraints= null;
		fInformationControl= null;
		if (fInformationControlCloser != null) {
			fInformationControlCloser.setInformationControl(null); //XXX: null is against the spec
			fInformationControlCloser.stop();
		}
	}

	/**
	 * Returns the information control. If the information control has not been created yet,
	 * it is automatically created.
	 *
	 * @return the information control
	 */
	protected IInformationControl getInformationControl() {

		if (fDisposed)
			return fInformationControl;

		IInformationControlCreator creator= null;

		if (fCustomInformationControlCreator == null) {
			creator= fInformationControlCreator;
			if (fIsCustomInformationControl && fInformationControl != null) {
				if (fInformationControl instanceof IInformationControlExtension5)
					fSizeConstraints= null;
				fInformationControl.dispose();
				fInformationControl= null;
			}
			fIsCustomInformationControl= false;

		} else  {

			creator= fCustomInformationControlCreator;
			if (creator instanceof IInformationControlCreatorExtension)  {
				IInformationControlCreatorExtension extension= (IInformationControlCreatorExtension) creator;
				if (fInformationControl != null && extension.canReuse(fInformationControl))
					return fInformationControl;
			}
			if (fInformationControl != null)  {
				if (fInformationControl instanceof IInformationControlExtension5)
					fSizeConstraints= null;
				fInformationControl.dispose();
				fInformationControl= null;
			}
			fIsCustomInformationControl= true;
		}

		if (fInformationControl == null) {
			fInformationControl= creator.createInformationControl(fSubjectControl.getShell());
			fInformationControl.addDisposeListener(new DisposeListener() {
				@Override
				public void widgetDisposed(DisposeEvent e) {
					handleInformationControlDisposed();
				}
			});

			if (fInformationControlCloser != null)
				fInformationControlCloser.setInformationControl(fInformationControl);
		}

		return fInformationControl;
	}

	/**
	 * Computes the display location of the information control. The location is computed
	 * considering the given subject area, the anchor at the subject area, and the
	 * size of the information control. This method does not care about whether the information
	 * control would be completely visible when placed at the result location.
	 *
	 * @param subjectArea the subject area
	 * @param controlSize the size of the information control
	 * @param anchor the anchor at the subject area
	 * @return the display location of the information control
	 */
	protected Point computeLocation(Rectangle subjectArea, Point controlSize, Anchor anchor) {
		int xShift= 0;
		int yShift= 0;

		switch (anchor.getSWTFlag()) {
			case SWT.CENTER:
				Point subjectControlSize= fSubjectControl.getSize();
				Point location= new Point(subjectControlSize.x / 2, subjectControlSize.y / 2);
				location.x -= (controlSize.x / 2);
				location.y -= (controlSize.y / 2);
				return fSubjectControl.toDisplay(location);
			case SWT.BOTTOM:
				yShift= subjectArea.height + fMarginY;
				break;
			case SWT.RIGHT:
				xShift= fMarginX + subjectArea.width;
				break;
			case SWT.TOP:
				yShift= -controlSize.y - fMarginY;
				break;
			case SWT.LEFT:
				xShift= -controlSize.x - fMarginX;
				break;
		}

		boolean isRTL= fSubjectControl != null && (fSubjectControl.getStyle() & SWT.RIGHT_TO_LEFT) != 0;
		if (isRTL)
			xShift += controlSize.x;

		return  fSubjectControl.toDisplay(new Point(subjectArea.x + xShift, subjectArea.y + yShift));
	}

	/**
	 * Computes the area available for an information control given an anchor and the subject area
	 * within <code>bounds</code>.
	 *
	 * @param subjectArea the subject area
	 * @param bounds the bounds
	 * @param anchor the anchor at the subject area
	 * @return the area available at the given anchor relative to the subject area, confined to the
	 *         monitor's client area
	 * @since 3.3
	 */
	protected Rectangle computeAvailableArea(Rectangle subjectArea, Rectangle bounds, Anchor anchor) {
		Rectangle area;
		switch (anchor.getSWTFlag()) {
			case SWT.CENTER:
				area= bounds;
				break;
			case SWT.BOTTOM:
				int y= subjectArea.y + subjectArea.height + fMarginY;
				area= new Rectangle(bounds.x, y, bounds.width, bounds.y + bounds.height - y);
				break;
			case SWT.RIGHT:
				int x= subjectArea.x + subjectArea.width + fMarginX;
				area= new Rectangle(x, bounds.y, bounds.x + bounds.width - x, bounds.height);
				break;
			case SWT.TOP:
				area= new Rectangle(bounds.x, bounds.y, bounds.width, subjectArea.y - bounds.y - fMarginY);
				break;
			case SWT.LEFT:
				area= new Rectangle(bounds.x, bounds.y, subjectArea.x - bounds.x - fMarginX, bounds.height);
				break;
			default:
				Assert.isLegal(false);
				return null;
		}

		// Don't return negative areas if the subjectArea overlaps with the monitor bounds.
		area.intersect(bounds);
		return area;
	}

	/**
	 * Checks whether a control of the given size at the given location would be completely visible
	 * in the given display area when laid out by using the given anchor. If not, this method tries
	 * to shift the control orthogonal to the direction given by the anchor to make it visible. If possible
	 * it updates the location.<p>
	 * This method returns <code>true</code> if the potentially updated position results in a
	 * completely visible control, or <code>false</code> otherwise.
	 *
	 *
	 * @param location the location of the control
	 * @param size the size of the control
	 * @param displayArea the display area in which the control should be visible
	 * @param anchor anchor for lying out the control
	 * @return <code>true</code>if the updated location is useful
	 */
	protected boolean updateLocation(Point location, Point size, Rectangle displayArea, Anchor anchor) {

		int displayLowerRightX= displayArea.x + displayArea.width;
		int displayLowerRightY= displayArea.y + displayArea.height;
		int lowerRightX= location.x + size.x;
		int lowerRightY= location.y + size.y;

		if (ANCHOR_BOTTOM == anchor || ANCHOR_TOP == anchor) {

			if (ANCHOR_BOTTOM == anchor) {
				if (lowerRightY > displayLowerRightY)
					return false;
			} else {
				if (location.y < displayArea.y)
					return false;
			}

			if (lowerRightX > displayLowerRightX)
				location.x= location.x - (lowerRightX - displayLowerRightX);

			return (location.x >= displayArea.x && location.y >= displayArea.y);

		} else if (ANCHOR_RIGHT == anchor || ANCHOR_LEFT == anchor) {

			if (ANCHOR_RIGHT == anchor) {
				if (lowerRightX > displayLowerRightX)
					return false;
			} else {
				if (location.x < displayArea.x)
					return false;
			}

			if (lowerRightY > displayLowerRightY)
				location.y= location.y - (lowerRightY - displayLowerRightY);

			return (location.x >= displayArea.x && location.y >= displayArea.y);

		} else if (ANCHOR_GLOBAL == anchor) {

			if (lowerRightX > displayLowerRightX)
				location.x= location.x - (lowerRightX - displayLowerRightX);

			if (lowerRightY > displayLowerRightY)
				location.y= location.y - (lowerRightY - displayLowerRightY);

			return (location.x >= displayArea.x && location.y >= displayArea.y);
		}

		return false;
	}

	/**
	 * Returns the next fallback anchor as specified by this manager's
	 * fallback anchor sequence.
	 * <p>
	 * The fallback anchor for the given anchor is the one that comes directly after
	 * the given anchor or is the first one in the sequence if the given anchor is the
	 * last one in the sequence.
	 * </p>
	 * <p>
	 * Note: It is the callers responsibility to prevent an endless loop i.e. to test
	 * whether a given anchor has already been used once.
	 * then
	 * </p>
	 *
	 * @param anchor the current anchor
	 * @return the next fallback anchor or <code>null</code> if no fallback anchor is available
	 */
	protected Anchor getNextFallbackAnchor(Anchor anchor) {

		if (anchor == null || fFallbackAnchors == null)
			return null;

		for (int i= 0; i < fFallbackAnchors.length; i++) {
			if (fFallbackAnchors[i] == anchor)
				return fFallbackAnchors[i + 1 == fFallbackAnchors.length ? 0 : i + 1];
		}

		return null;
	}

	/**
	 * Computes the location of the information control depending on the
	 * subject area and the size of the information control. This method attempts
	 * to find a location at which the information control lies completely in the display's
	 * client area while honoring the manager's default anchor. If this isn't possible using the
	 * default anchor, the fallback anchors are tried out.
	 *
	 * @param subjectArea the information area
	 * @param controlSize the size of the information control
	 * @return the computed location of the information control
	 */
	protected Point computeInformationControlLocation(Rectangle subjectArea, Point controlSize) {
		Rectangle subjectAreaDisplayRelative= Geometry.toDisplay(fSubjectControl, subjectArea);

		Point upperLeft;
		Anchor testAnchor= fAnchor;
		Rectangle bestBounds= null;
		int bestArea= Integer.MIN_VALUE;
		Anchor bestAnchor= null;
		do {

			upperLeft= computeLocation(subjectArea, controlSize, testAnchor);
			Monitor monitor= getClosestMonitor(subjectAreaDisplayRelative, testAnchor);
			if (updateLocation(upperLeft, controlSize, monitor.getClientArea(), testAnchor))
				return upperLeft;

			// compute available area for this anchor and update if better than best
			Rectangle available= computeAvailableArea(subjectAreaDisplayRelative, monitor.getClientArea(), testAnchor);
			Rectangle proposed= new Rectangle(upperLeft.x, upperLeft.y, controlSize.x, controlSize.y);
			available.intersect(proposed);
			int area= available.width * available.height;
			if (area > bestArea) {
				bestArea= area;
				bestBounds= available;
				bestAnchor= testAnchor;
			}

			testAnchor= getNextFallbackAnchor(testAnchor);

		} while (testAnchor != fAnchor && testAnchor != null);

		// no anchor is perfect - select the one with larges area and set the size to not overlap with the subjectArea
		if (bestAnchor != ANCHOR_GLOBAL)
			Geometry.set(controlSize, Geometry.getSize(bestBounds));
		return Geometry.getLocation(bestBounds);
	}

	/**
	 * Gets the closest monitor given an anchor and the subject area.
	 *
	 * @param area the subject area
	 * @param anchor the anchor
	 * @return the monitor closest to the edge of <code>area</code> defined by
	 *         <code>anchor</code>
	 * @since 3.3
	 */
	private Monitor getClosestMonitor(Rectangle area, Anchor anchor) {
		Point center;
		if (ANCHOR_GLOBAL == anchor)
			center= Geometry.centerPoint(area);
		else
			center= Geometry.centerPoint(Geometry.getExtrudedEdge(area, 0, anchor.getSWTFlag()));
		return getClosestMonitor(fSubjectControl.getDisplay(), Geometry.createRectangle(center, new Point(0, 0)));
	}

	/**
	 * Copied from org.eclipse.jface.window.Window. Returns the monitor whose client area contains
	 * the given point. If no monitor contains the point, returns the monitor that is closest to the
	 * point. If this is ever made public, it should be moved into a separate utility class.
	 *
	 * @param display the display to search for monitors
	 * @param rectangle the rectangle to find the closest monitor for (display coordinates)
	 * @return the monitor closest to the given point
	 * @since 3.3
	 */
	private Monitor getClosestMonitor(Display display, Rectangle rectangle) {
		int closest = Integer.MAX_VALUE;

		Point toFind= Geometry.centerPoint(rectangle);
		Monitor[] monitors = display.getMonitors();
		Monitor result = monitors[0];

		for (int idx = 0; idx < monitors.length; idx++) {
			Monitor current = monitors[idx];

			Rectangle clientArea = current.getClientArea();

			if (clientArea.contains(toFind)) {
				return current;
			}

			int distance = Geometry.distanceSquared(Geometry.centerPoint(clientArea), toFind);
			if (distance < closest) {
				closest = distance;
				result = current;
			}
		}

		return result;
	}

	/**
	 * Computes information to be displayed as well as the subject area
	 * and initiates that this information is presented in the information control.
	 * This happens only if this controller is enabled.
	 */
	public void showInformation() {
		if (fEnabled)
			doShowInformation();
	}

	/**
	 * Computes information to be displayed as well as the subject area
	 * and initiates that this information is presented in the information control.
	 */
	protected void doShowInformation() {
		fSubjectArea= null;
		fInformation= null;
		computeInformation();
	}

	/**
	 * Presents the information in the information control or hides the information
	 * control if no information should be presented. The information has previously
	 * been set using <code>setInformation</code>.
	 * <p>
	 * This method should only be called from overriding methods or from <code>setInformation</code>.
	 * </p>
	 */
	protected void presentInformation() {
		boolean hasContents= false;
		if (fInformation instanceof String)
			hasContents= ((String)fInformation).trim().length() > 0;
		else
			hasContents= (fInformation != null);

		if (fSubjectArea != null && hasContents)
			internalShowInformationControl(fSubjectArea, fInformation);
		else
			hideInformationControl();
	}

	/**
	 * Opens the information control with the given information and the specified
	 * subject area. It also activates the information control closer.
	 *
	 * @param subjectArea the information area
	 * @param information the information
	 */
	private void internalShowInformationControl(Rectangle subjectArea, Object information) {
		if (this instanceof InformationControlReplacer) {
			((InformationControlReplacer) this).showInformationControl(subjectArea, information);
			return;
		}

		IInformationControl informationControl= getInformationControl();
		if (informationControl != null) {

			Point sizeConstraints= computeSizeConstraints(fSubjectControl, fSubjectArea, informationControl);
			if (informationControl instanceof IInformationControlExtension3) {
				IInformationControlExtension3 iControl3= (IInformationControlExtension3) informationControl;
				Rectangle trim= iControl3.computeTrim();
				sizeConstraints.x += trim.width;
				sizeConstraints.y += trim.height;
			}
			informationControl.setSizeConstraints(sizeConstraints.x, sizeConstraints.y);

			if (informationControl instanceof IInformationControlExtension2)
				((IInformationControlExtension2)informationControl).setInput(information);
			else
				informationControl.setInformation(information.toString());

			if (informationControl instanceof IInformationControlExtension) {
				IInformationControlExtension extension= (IInformationControlExtension)informationControl;
				if (!extension.hasContents())
					return;
			}

			Point size= null;
			Point location= null;
			Rectangle bounds= restoreInformationControlBounds();

			if (bounds != null) {
				if (bounds.x > -1 && bounds.y > -1)
					location= Geometry.getLocation(bounds);

				if (bounds.width > -1 && bounds.height > -1)
					size= Geometry.getSize(bounds);
			}

			if (size == null)
				size= informationControl.computeSizeHint();

			if (fEnforceAsMinimalSize)
				size= Geometry.max(size, sizeConstraints);
			if (fEnforceAsMaximalSize)
				size= Geometry.min(size, sizeConstraints);

			if (location == null)
				location= computeInformationControlLocation(subjectArea, size);

			Rectangle controlBounds= Geometry.createRectangle(location, size);
			cropToClosestMonitor(controlBounds);
			location= Geometry.getLocation(controlBounds);
			size= Geometry.getSize(controlBounds);
			informationControl.setLocation(location);
			informationControl.setSize(size.x, size.y);

			showInformationControl(subjectArea);
		}
	}

	/**
	 * Crops the given bounds such that they lie completely on the closest monitor.
	 *
	 * @param bounds shell bounds to crop
	 * @since 3.4
	 */
	void cropToClosestMonitor(Rectangle bounds) {
		Rectangle monitorBounds= getClosestMonitor(fSubjectControl.getDisplay(), bounds).getClientArea();
		bounds.intersect(monitorBounds);
	}

	/**
	 * Hides the information control and stops the information control closer.
	 */
	protected void hideInformationControl() {
		if (fInformationControl != null) {
			storeInformationControlBounds();
			fInformationControl.setVisible(false);
			if (fInformationControlCloser != null)
				fInformationControlCloser.stop();
		}
		if (canClearDataOnHide()) {
			fSubjectArea= null;
			fInformation= null; // allow garbage collection of potentially large object
		}
	}

	/**
	 * Tells whether internal data can be cleared on hide.
	 *
	 * @return <code>true</code> if data can be cleared on hide
	 * @see #hideInformationControl()
	 * @since 3.6
	 */
	protected boolean canClearDataOnHide() {
		return true;
	}

	/**
	 * Shows the information control and starts the information control closer.
	 * This method may not be called by clients.
	 *
	 * @param subjectArea the information area
	 */
	protected void showInformationControl(Rectangle subjectArea) {
		fInformationControl.setVisible(true);

		if (fInformationControl == null)
			return; // could already be disposed if setVisible(..) runs the display loop

		if (fTakesFocusWhenVisible)
			fInformationControl.setFocus();

		if (fInformationControlCloser != null)
			fInformationControlCloser.start(subjectArea);
	}

	/**
	 * Replaces this manager's information control as defined by
	 * the information control replacer.
	 * <strong>Must only be called when {@link #fInformationControl} instanceof {@link IInformationControlExtension3}!</strong>
	 *
	 * @param takeFocus <code>true</code> iff the replacing information control should take focus
	 *
	 * @since 3.4
	 */
	void replaceInformationControl(boolean takeFocus) {
		if (fInformationControlReplacer != null && canReplace(fInformationControl)) {
			IInformationControlExtension3 iControl3= (IInformationControlExtension3) fInformationControl;
			Rectangle b= iControl3.getBounds();
			Rectangle t= iControl3.computeTrim();
			Rectangle contentBounds= new Rectangle(b.x - t.x, b.y - t.y, b.width - t.width, b.height - t.height);
			IInformationControlCreator informationPresenterControlCreator= ((IInformationControlExtension5) fInformationControl).getInformationPresenterControlCreator();
			fInformationControlReplacer.replaceInformationControl(informationPresenterControlCreator, contentBounds, fInformation, fSubjectArea, takeFocus);
		}
		hideInformationControl();
	}

	/**
	 * Disposes this manager's information control.
	 */
	public void disposeInformationControl() {
		if (fInformationControl != null) {
			fInformationControl.dispose();
			handleInformationControlDisposed();
		}
	}

	/**
	 * Disposes this manager and if necessary all dependent parts such as
	 * the information control. For symmetry it first disables this manager.
	 */
	public void dispose() {
		if (!fDisposed) {

			fDisposed= true;

			setEnabled(false);
			disposeInformationControl();

			if (fInformationControlReplacer != null) {
				fInformationControlReplacer.dispose();
				fInformationControlReplacer= null;
			}

			if (fSubjectControl != null && !fSubjectControl.isDisposed() && fSubjectControlDisposeListener != null)
				fSubjectControl.removeDisposeListener(fSubjectControlDisposeListener);
			fSubjectControl= null;
			fSubjectControlDisposeListener= null;

			fIsCustomInformationControl= false;
			fCustomInformationControlCreator= null;
			fInformationControlCreator= null;
			fInformationControlCloser= null;
		}
	}

	// ------ control's size handling dialog settings ------

	/**
	 * Stores the information control's bounds.
	 *
	 * @since 3.0
	 */
	protected void storeInformationControlBounds() {
		if (fDialogSettings == null || fInformationControl == null || !(fIsRestoringLocation || fIsRestoringSize))
			return;

		if (!(fInformationControl instanceof IInformationControlExtension3))
			throw new UnsupportedOperationException();

		boolean controlRestoresSize= ((IInformationControlExtension3)fInformationControl).restoresSize();
		boolean controlRestoresLocation= ((IInformationControlExtension3)fInformationControl).restoresLocation();

		Rectangle bounds= ((IInformationControlExtension3)fInformationControl).getBounds();
		if (bounds == null)
			return;

		if (fIsRestoringSize && controlRestoresSize) {
			fDialogSettings.put(STORE_SIZE_WIDTH, bounds.width);
			fDialogSettings.put(STORE_SIZE_HEIGHT, bounds.height);
		}
		if (fIsRestoringLocation && controlRestoresLocation) {
			fDialogSettings.put(STORE_LOCATION_X, bounds.x);
			fDialogSettings.put(STORE_LOCATION_Y, bounds.y);
		}
	}
	/**
	 * Restores the information control's bounds.
	 *
	 * @return the stored bounds
	 * @since 3.0
	 */
	protected Rectangle restoreInformationControlBounds() {
		if (fDialogSettings == null || !(fIsRestoringLocation || fIsRestoringSize))
			return null;

		if (!(fInformationControl instanceof IInformationControlExtension3))
			throw new UnsupportedOperationException();

		boolean controlRestoresSize= ((IInformationControlExtension3)fInformationControl).restoresSize();
		boolean controlRestoresLocation= ((IInformationControlExtension3)fInformationControl).restoresLocation();

		Rectangle bounds= new Rectangle(-1, -1, -1, -1);

		if (fIsRestoringSize && controlRestoresSize) {
			try {
				bounds.width= fDialogSettings.getInt(STORE_SIZE_WIDTH);
				bounds.height= fDialogSettings.getInt(STORE_SIZE_HEIGHT);
			} catch (NumberFormatException ex) {
				bounds.width= -1;
				bounds.height= -1;
			}
		}

		if (fIsRestoringLocation && controlRestoresLocation) {
			try {
				bounds.x= fDialogSettings.getInt(STORE_LOCATION_X);
				bounds.y= fDialogSettings.getInt(STORE_LOCATION_Y);
			} catch (NumberFormatException ex) {
				bounds.x= -1;
				bounds.y= -1;
			}
		}

		// sanity check
		if (bounds.x == -1 && bounds.y == -1 && bounds.width == -1 && bounds.height == -1)
			return null;

		Rectangle maxBounds= null;
		if (fSubjectControl != null && !fSubjectControl.isDisposed())
			maxBounds= fSubjectControl.getDisplay().getBounds();
		else {
			// fallback
			Display display= Display.getCurrent();
			if (display == null)
				display= Display.getDefault();
			if (display != null && !display.isDisposed())
				maxBounds= display.getBounds();
		}


		if (bounds.width > -1 && bounds.height > -1) {
			if (maxBounds != null) {
				bounds.width= Math.min(bounds.width, maxBounds.width);
				bounds.height= Math.min(bounds.height, maxBounds.height);
			}

			// Enforce an absolute minimal size
			bounds.width= Math.max(bounds.width, 30);
			bounds.height= Math.max(bounds.height, 30);
		}

		if (bounds.x > -1 && bounds.y > -1 && maxBounds != null) {
			bounds.x= Math.max(bounds.x, maxBounds.x);
			bounds.y= Math.max(bounds.y, maxBounds.y);

			if (bounds .width > -1 && bounds.height > -1) {
				bounds.x= Math.min(bounds.x, maxBounds.width - bounds.width);
				bounds.y= Math.min(bounds.y, maxBounds.height - bounds.height);
			}
		}

		return bounds;
	}

	/**
	 * 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.
	 */
	public InternalAccessor getInternalAccessor() {
		return new MyInternalAccessor();
	}
}
