/*******************************************************************************
 * Copyright (c) 2008, 2016 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.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Slider;
import org.eclipse.swt.widgets.ToolBar;

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

import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.internal.text.revisions.Colors;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.Geometry;


/**
 * An abstract information control that can show content inside a shell.
 * The information control can be created in two styles:
 * <ul>
 * 	<li>non-resizable tooltip with optional status</li>
 * 	<li>resizable tooltip with optional tool bar</li>
 * </ul>
 * Additionally it can present either a status line containing a status text or
 * a toolbar containing toolbar buttons.
 * <p>
 * Subclasses must either override {@link IInformationControl#setInformation(String)}
 * or implement {@link IInformationControlExtension2}.
 * They should also extend {@link #computeTrim()} if they create a content area
 * with additional trim (e.g. scrollbars) and override {@link #getInformationPresenterControlCreator()}.
 * </p>
 *
 * @since 3.4
 */
public abstract class AbstractInformationControl implements IInformationControl, IInformationControlExtension, IInformationControlExtension3, IInformationControlExtension4, IInformationControlExtension5 {

	/** The information control's shell. */
	private final Shell fShell;
	/** Composite containing the content created by subclasses. */
	private final Composite fContentComposite;
	/** Whether the information control is resizable. */
	private final boolean fResizable;

	/** Composite containing the status line content or <code>null</code> if none. */
	private Composite fStatusComposite;
	/** Separator between content and status line or <code>null</code> if none. */
	private Label fSeparator;
	/** Label in the status line or <code>null</code> if none. */
	private Label fStatusLabel;
	/**
	 * Font for the label in the status line or <code>null</code> if none.
	 * @since 3.4.2
	 */
	private Font fStatusLabelFont;
	/**
	 * Color for the label in the status line or <code>null</code> if none.
	 *
	 * @since 3.6
	 */
	private Color fStatusLabelForeground;
	/** The toolbar manager used by the toolbar or <code>null</code> if none. */
	private final ToolBarManager fToolBarManager;
	/** Status line toolbar or <code>null</code> if none. */
	private ToolBar fToolBar;

	/** Listener for shell activation and deactivation. */
	private Listener fShellListener;
	/** All focus listeners registered to this information control. */
	private final ListenerList<FocusListener> fFocusListeners= new ListenerList<>(ListenerList.IDENTITY);

	/** Size constraints, x is the maxWidth and y is the maxHeight, or <code>null</code> if not set. */
	private Point fSizeConstraints;
	/** The size of the resize handle if already set, -1 otherwise */
	private int fResizeHandleSize;

	/**
	 * Creates an abstract information control with the given shell as parent.
	 * The control will not be resizable and optionally show a status line with
	 * the given status field text.
	 * <p>
	 * <em>Important: Subclasses are required to call {@link #create()} at the end of their constructor.</em>
	 * </p>
	 *
	 * @param parentShell the parent of this control's shell
	 * @param statusFieldText the text to be used in the status field or <code>null</code> to hide the status field
	 */
	public AbstractInformationControl(Shell parentShell, String statusFieldText) {
		this(parentShell, SWT.TOOL | SWT.ON_TOP, statusFieldText, null);
	}

	/**
	 * Creates an abstract information control with the given shell as parent.
	 * The control will be resizable and optionally show a tool bar managed by
	 * the given tool bar manager.
	 * <p>
	 * <em>Important: Subclasses are required to call {@link #create()} at the end of their constructor.</em>
	 * </p>
	 *
	 * @param parentShell the parent of this control's shell
	 * @param toolBarManager the manager or <code>null</code> if toolbar is not desired
	 */
	public AbstractInformationControl(Shell parentShell, ToolBarManager toolBarManager) {
		this(parentShell, SWT.TOOL | SWT.ON_TOP | SWT.RESIZE, null, toolBarManager);
	}

	/**
	 * Creates an abstract information control with the given shell as parent.
	 * <p>
	 * <em>Important: Subclasses are required to call {@link #create()} at the end of their constructor.</em>
	 * </p>
	 *
	 * @param parentShell the parent of this control's shell
	 * @param isResizable <code>true</code> if the control should be resizable
	 */
	public AbstractInformationControl(Shell parentShell, boolean isResizable) {
		this(parentShell, SWT.TOOL | SWT.ON_TOP | (isResizable ? SWT.RESIZE : 0), null, null);
	}

	/**
	 * Creates an abstract information control with the given shell as parent.
	 * The given shell style is used for the shell (NO_TRIM will be removed to make sure there's a border).
	 * <p>
	 * The control will optionally show either a status line or a tool bar.
	 * At most one of <code>toolBarManager</code> or <code>statusFieldText</code> can be non-null.
	 * </p>
	 * <p>
	 * <strong>Important:</strong>: Subclasses are required to call {@link #create()} at the end of their constructor.
	 * </p>
	 *
	 * @param parentShell the parent of this control's shell
	 * @param shellStyle style of this control's shell
	 * @param statusFieldText the text to be used in the status field or <code>null</code> to hide the status field
	 * @param toolBarManager the manager or <code>null</code> if toolbar is not desired
	 *
	 * @deprecated clients should use one of the public constructors
	 */
	@Deprecated
	AbstractInformationControl(Shell parentShell, int shellStyle, final String statusFieldText, final ToolBarManager toolBarManager) {
		Assert.isTrue(statusFieldText == null || toolBarManager == null);
		fResizeHandleSize= -1;
		fToolBarManager= toolBarManager;

		if ((shellStyle & SWT.NO_TRIM) != 0)
			shellStyle&= ~(SWT.NO_TRIM | SWT.SHELL_TRIM); // make sure we get the OS border but no other trims

		fResizable= (shellStyle & SWT.RESIZE) != 0;
		fShell= new Shell(parentShell, shellStyle);
		Display display= fShell.getDisplay();

		ColorRegistry colorRegistry =  JFaceResources.getColorRegistry();
		Color foreground= colorRegistry.get("org.eclipse.ui.workbench.HOVER_FOREGROUND"); //$NON-NLS-1$
		if (foreground == null) {
			foreground = display.getSystemColor(SWT.COLOR_INFO_FOREGROUND);
		}
		Color background= colorRegistry.get("org.eclipse.ui.workbench.HOVER_BACKGROUND"); //$NON-NLS-1$
		if (background == null) {
			background = display.getSystemColor(SWT.COLOR_INFO_BACKGROUND);
		}
		setColor(fShell, foreground, background);

		GridLayout layout= new GridLayout(1, false);
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		layout.verticalSpacing= 0;
		fShell.setLayout(layout);

		fContentComposite= new Composite(fShell, SWT.NONE);
		fContentComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		fContentComposite.setLayout(new FillLayout());
		setColor(fContentComposite, foreground, background);

		createStatusComposite(statusFieldText, toolBarManager, foreground, background);

		addDisposeListener(new DisposeListener() {
			@Override
			public void widgetDisposed(DisposeEvent e) {
				handleDispose();
			}
		});

	}

	private void createStatusComposite(final String statusFieldText, final ToolBarManager toolBarManager, Color foreground, Color background) {
		if (toolBarManager == null && statusFieldText == null)
			return;

		fStatusComposite= new Composite(fShell, SWT.NONE);
		GridData gridData= new GridData(SWT.FILL, SWT.BOTTOM, true, false);
		fStatusComposite.setLayoutData(gridData);
		GridLayout statusLayout= new GridLayout(1, false);
		statusLayout.marginHeight= 0;
		statusLayout.marginWidth= 0;
		statusLayout.verticalSpacing= 1;
		fStatusComposite.setLayout(statusLayout);

		fSeparator= new Label(fStatusComposite, SWT.SEPARATOR | SWT.HORIZONTAL);
		fSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		if (statusFieldText != null) {
			createStatusLabel(statusFieldText, foreground, background);
		} else {
			createToolBar(toolBarManager);
		}
	}

	private void createStatusLabel(final String statusFieldText, Color foreground, Color background) {
		fStatusLabel= new Label(fStatusComposite, SWT.RIGHT);
		fStatusLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		fStatusLabel.setText(statusFieldText);

		FontData[] fontDatas= JFaceResources.getDialogFont().getFontData();
		for (int i= 0; i < fontDatas.length; i++) {
			fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10);
		}
		fStatusLabelFont= new Font(fStatusLabel.getDisplay(), fontDatas);
		fStatusLabel.setFont(fStatusLabelFont);

		fStatusLabelForeground= new Color(fStatusLabel.getDisplay(), Colors.blend(background.getRGB(), foreground.getRGB(), 0.56f));
		setColor(fStatusLabel, fStatusLabelForeground, background);
		setColor(fStatusComposite, foreground, background);
	}

	private void createToolBar(ToolBarManager toolBarManager) {
		final Composite bars= new Composite(fStatusComposite, SWT.NONE);
		bars.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));

		GridLayout layout= new GridLayout(3, false);
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		layout.horizontalSpacing= 0;
		layout.verticalSpacing= 0;
		bars.setLayout(layout);

		fToolBar= toolBarManager.createControl(bars);
		GridData gd= new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false);
		fToolBar.setLayoutData(gd);

		Composite spacer= new Composite(bars, SWT.NONE);
		gd= new GridData(SWT.FILL, SWT.FILL, true, true);
		gd.widthHint= 0;
		gd.heightHint= 0;
		spacer.setLayoutData(gd);

		addMoveSupport(spacer);
		addResizeSupportIfNecessary(bars);
	}

	private void addResizeSupportIfNecessary(final Composite bars) {
		// XXX: workarounds for
		// - https://bugs.eclipse.org/bugs/show_bug.cgi?id=219139 : API to add resize grip / grow box in lower right corner of shell
		// - https://bugs.eclipse.org/bugs/show_bug.cgi?id=23980 : platform specific shell resize behavior
		String platform= SWT.getPlatform();
		final boolean isWin= platform.equals("win32"); //$NON-NLS-1$
		if (!isWin && !platform.equals("gtk")) //$NON-NLS-1$
			return;

		final Canvas resizer= new Canvas(bars, SWT.NONE);

		int size= getResizeHandleSize(bars);

		GridData data= new GridData(SWT.END, SWT.END, false, true);
		data.widthHint= size;
		data.heightHint= size;
		resizer.setLayoutData(data);
		resizer.addPaintListener(new PaintListener() {
			@Override
			public void paintControl(PaintEvent e) {
				Point s= resizer.getSize();
				int x= s.x - 2;
				int y= s.y - 2;
				int min= Math.min(x, y);
				if (isWin) {
					// draw dots
					e.gc.setBackground(resizer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
					int end= min - 1;
					for (int i= 0; i <= 2; i++)
						for (int j= 0; j <= 2 - i; j++)
							e.gc.fillRectangle(end - 4 * i, end - 4 * j, 2, 2);
					end--;
					e.gc.setBackground(resizer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
					for (int i= 0; i <= 2; i++)
						for (int j= 0; j <= 2 - i; j++)
							e.gc.fillRectangle(end - 4 * i, end - 4 * j, 2, 2);

				} else {
					// draw diagonal lines
					e.gc.setForeground(resizer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
					for (int i= 1; i < min; i+= 4) {
						e.gc.drawLine(i, y, x, i);
					}
					e.gc.setForeground(resizer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
					for (int i= 2; i < min; i+= 4) {
						e.gc.drawLine(i, y, x, i);
					}
				}
			}
		});

		final boolean isRTL= (resizer.getShell().getStyle() & SWT.RIGHT_TO_LEFT) != 0;
		resizer.setCursor(resizer.getDisplay().getSystemCursor(isRTL ? SWT.CURSOR_SIZESW : SWT.CURSOR_SIZESE));
		MouseAdapter resizeSupport= new MouseAdapter() {
			private MouseMoveListener fResizeListener;

			@Override
			public void mouseDown(MouseEvent e) {
				Rectangle shellBounds= fShell.getBounds();
				final int shellX= shellBounds.x;
				final int shellY= shellBounds.y;
				final int shellWidth= shellBounds.width;
				final int shellHeight= shellBounds.height;
				Point mouseLoc= resizer.toDisplay(e.x, e.y);
				final int mouseX= mouseLoc.x;
				final int mouseY= mouseLoc.y;
				fResizeListener= new MouseMoveListener() {
					@Override
					public void mouseMove(MouseEvent e2) {
						Point mouseLoc2= resizer.toDisplay(e2.x, e2.y);
						int dx= mouseLoc2.x - mouseX;
						int dy= mouseLoc2.y - mouseY;
						if (isRTL) {
							setLocation(new Point(shellX + dx, shellY));
							setSize(shellWidth - dx, shellHeight + dy);
						} else {
							setSize(shellWidth + dx, shellHeight + dy);
						}
					}
				};
				resizer.addMouseMoveListener(fResizeListener);
			}

			@Override
			public void mouseUp(MouseEvent e) {
				resizer.removeMouseMoveListener(fResizeListener);
				fResizeListener= null;
			}
		};
		resizer.addMouseListener(resizeSupport);
	}

	private int getResizeHandleSize(Composite parent) {
		if (fResizeHandleSize == -1) {
			Slider sliderV= new Slider(parent, SWT.VERTICAL);
			Slider sliderH= new Slider(parent, SWT.HORIZONTAL);
			int width= sliderV.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
			int height= sliderH.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
			sliderV.dispose();
			sliderH.dispose();
			fResizeHandleSize= Math.min(width, height);
		}

		return fResizeHandleSize;
	}

	/**
	 * Adds support to move the shell by dragging the given control.
	 *
	 * @param control the control that can be used to move the shell
	 */
	private void addMoveSupport(final Control control) {
		MouseAdapter moveSupport= new MouseAdapter() {
			private MouseMoveListener fMoveListener;

			@Override
			public void mouseDown(MouseEvent e) {
				Point shellLoc= fShell.getLocation();
				final int shellX= shellLoc.x;
				final int shellY= shellLoc.y;
				Point mouseLoc= control.toDisplay(e.x, e.y);
				final int mouseX= mouseLoc.x;
				final int mouseY= mouseLoc.y;
				fMoveListener= new MouseMoveListener() {
					@Override
					public void mouseMove(MouseEvent e2) {
						Point mouseLoc2= control.toDisplay(e2.x, e2.y);
						int dx= mouseLoc2.x - mouseX;
						int dy= mouseLoc2.y - mouseY;
						fShell.setLocation(shellX + dx, shellY + dy);
					}
				};
				control.addMouseMoveListener(fMoveListener);
			}

			@Override
			public void mouseUp(MouseEvent e) {
				control.removeMouseMoveListener(fMoveListener);
				fMoveListener= null;
			}
		};
		control.addMouseListener(moveSupport);
	}

	/**
	 * Utility to set the foreground and the background color of the given
	 * control
	 *
	 * @param control the control to modify
	 * @param foreground the color to use for the foreground
	 * @param background the color to use for the background
	 */
	private static void setColor(Control control, Color foreground, Color background) {
		control.setForeground(foreground);
		control.setBackground(background);
	}

	/**
	 * The shell of the popup window.
	 *
	 * @return the shell used for the popup window
	 */
	protected final Shell getShell() {
		return fShell;
	}

	/**
	 * The toolbar manager used to manage the toolbar, or <code>null</code> if
	 * no toolbar is shown.
	 *
	 * @return the tool bar manager or <code>null</code>
	 */
	protected final ToolBarManager getToolBarManager() {
		return fToolBarManager;
	}

	/**
	 * Creates the content of this information control. Subclasses must call
	 * this method at the end of their constructor(s).
	 */
	protected final void create() {
		createContent(fContentComposite);
	}

	/**
	 * Creates the content of the popup window.
	 * <p>
	 * Implementors will usually take over {@link Composite#getBackground()} and
	 * {@link Composite#getForeground()} from <code>parent</code>.
	 * </p>
	 * <p>
	 * Implementors must either use the dialog font or override
	 * {@link #computeSizeConstraints(int, int)}.
	 * </p>
	 * <p>
	 * Implementors are expected to consider {@link #isResizable()}: If <code>true</code>, they
	 * should show scrollbars if their content may exceed the size of the information control. If
	 * <code>false</code>, they should never show scrollbars.
	 * </p>
	 * <p>
	 * The given <code>parent</code> comes with a {@link FillLayout}. Subclasses may set a different
	 * layout.
	 * </p>
	 *
	 * @param parent the container of the content
	 */
	protected abstract void createContent(Composite parent);

	/**
	 * Sets the information to be presented by this information control.
	 * <p>
	 * The default implementation does nothing. Subclasses must either override this method
	 * or implement {@link IInformationControlExtension2}.
	 *
	 * @param information the information to be presented
	 *
	 * @see org.eclipse.jface.text.IInformationControl#setInformation(java.lang.String)
	 */
	@Override
	public void setInformation(String information) {

	}

	/**
	 * Returns whether the information control is resizable.
	 *
	 * @return <code>true</code> if the information control is resizable,
	 *         <code>false</code> if it is not resizable.
	 */
	public boolean isResizable() {
		return fResizable;
	}

	@Override
	public void setVisible(boolean visible) {
		if (fShell.isVisible() == visible)
			return;

		fShell.setVisible(visible);
	}

	@Override
	public void dispose() {
		if (fShell != null && !fShell.isDisposed())
			fShell.dispose();
	}

	/**
	 * Frees all resources allocated by this information control. Internally called when the
	 * information control's shell has been disposed.
	 *
	 * @since 3.6
	 */
	protected void handleDispose() {
		if (fStatusLabelFont != null) {
			fStatusLabelFont.dispose();
			fStatusLabelFont= null;
		}
		if (fStatusLabelForeground != null) {
			fStatusLabelForeground.dispose();
			fStatusLabelForeground= null;
		}
	}

	@Override
	public void setSize(int width, int height) {
		fShell.setSize(width, height);
	}

	@Override
	public void setLocation(Point location) {
		fShell.setLocation(location);
	}

	@Override
	public void setSizeConstraints(int maxWidth, int maxHeight) {
		fSizeConstraints= new Point(maxWidth, maxHeight);
	}

	/**
	 * Returns the size constraints.
	 *
	 * @return the size constraints or <code>null</code> if not set
	 * @see #setSizeConstraints(int, int)
	 */
	protected final Point getSizeConstraints() {
		return fSizeConstraints != null ? Geometry.copy(fSizeConstraints) : null;
	}

	@Override
	public Point computeSizeHint() {
		// XXX: Verify whether this is a good default implementation. If yes, document it.
		Point constrains= getSizeConstraints();
		if (constrains == null)
			return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);

		return fShell.computeSize(constrains.x, constrains.y, true);
	}

	/**
	 * Computes the trim (status text and tool bar are considered as trim).
	 * Subclasses can extend this method to add additional trim (e.g. scroll
	 * bars for resizable information controls).
	 *
	 * @see org.eclipse.jface.text.IInformationControlExtension3#computeTrim()
	 */
	@Override
	public Rectangle computeTrim() {
		Rectangle trim= fShell.computeTrim(0, 0, 0, 0);

		if (fStatusComposite != null)
			trim.height+= fStatusComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;

		return trim;
	}

	@Override
	public Rectangle getBounds() {
		return fShell.getBounds();
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * The default implementation always returns <code>false</code>.
	 * </p>
	 * @see org.eclipse.jface.text.IInformationControlExtension3#restoresLocation()
	 */
	@Override
	public boolean restoresLocation() {
		return false;
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * The default implementation always returns <code>false</code>.
	 * </p>
	 * @see org.eclipse.jface.text.IInformationControlExtension3#restoresSize()
	 */
	@Override
	public boolean restoresSize() {
		return false;
	}

	@Override
	public void addDisposeListener(DisposeListener listener) {
		fShell.addDisposeListener(listener);
	}

	@Override
	public void removeDisposeListener(DisposeListener listener) {
		fShell.removeDisposeListener(listener);
	}

	@Override
	public void setForegroundColor(Color foreground) {
		fContentComposite.setForeground(foreground);
	}

	@Override
	public void setBackgroundColor(Color background) {
		fContentComposite.setBackground(background);
	}

	/**
	 * {@inheritDoc}
	 * This method is not intended to be overridden by subclasses.
	 */
	@Override
	public boolean isFocusControl() {
		return fShell.getDisplay().getActiveShell() == fShell;
	}

	/**
	 * This default implementation sets the focus on the popup shell.
	 * Subclasses can override or extend.
	 *
	 * @see IInformationControl#setFocus()
	 */
	@Override
	public void setFocus() {
		boolean focusTaken= fShell.setFocus();
		if (!focusTaken)
			fShell.forceFocus();
	}

	/**
	 * {@inheritDoc}
	 * This method is not intended to be overridden by subclasses.
	 */
	@Override
	public void addFocusListener(final FocusListener listener) {
		if (fFocusListeners.isEmpty()) {
			fShellListener= new Listener() {

				@Override
				public void handleEvent(Event event) {
					for (FocusListener focusListener : fFocusListeners) {
						if (event.type == SWT.Activate) {
							focusListener.focusGained(new FocusEvent(event));
						} else {
							focusListener.focusLost(new FocusEvent(event));
						}
					}
				}
			};
			fShell.addListener(SWT.Deactivate, fShellListener);
			fShell.addListener(SWT.Activate, fShellListener);
		}
		fFocusListeners.add(listener);
	}

	/**
	 * {@inheritDoc}
	 * This method is not intended to be overridden by subclasses.
	 */
	@Override
	public void removeFocusListener(FocusListener listener) {
		fFocusListeners.remove(listener);
		if (fFocusListeners.isEmpty()) {
			fShell.removeListener(SWT.Activate, fShellListener);
			fShell.removeListener(SWT.Deactivate, fShellListener);
			fShellListener= null;
		}
	}

	/**
	 * Sets the text of the status field.
	 * <p>
	 * The default implementation currently only updates the status field when
	 * the popup shell is not visible. The status field can currently only be
	 * shown if the information control has been created with a non-null status
	 * field text.
	 * </p>
	 *
	 * @param statusFieldText the text to be used in the optional status field
	 *        or <code>null</code> if the status field should be hidden
	 *
	 * @see org.eclipse.jface.text.IInformationControlExtension4#setStatusText(java.lang.String)
	 */
	@Override
	public void setStatusText(String statusFieldText) {
		if (fStatusLabel != null && ! getShell().isVisible()) {
			if (statusFieldText == null	) {
				fStatusComposite.setVisible(false);
			} else {
				fStatusLabel.setText(statusFieldText);
				fStatusComposite.setVisible(true);
			}
		}
	}

	@Override
	public boolean containsControl(Control control) {
		do {
			if (control == fShell)
				return true;
			if (control instanceof Shell)
				return false;
			control= control.getParent();
		} while (control != null);
		return false;
	}

	@Override
	public boolean isVisible() {
		return fShell != null && !fShell.isDisposed() && fShell.isVisible();
	}

	/**
	 * {@inheritDoc}
	 * This default implementation returns <code>null</code>. Subclasses may override.
	 */
	@Override
	public IInformationControlCreator getInformationPresenterControlCreator() {
		return null;
	}

	/**
	 * Computes the size constraints based on the
	 * {@link JFaceResources#getDialogFont() dialog font}. Subclasses can
	 * override or extend.
	 *
	 * @see org.eclipse.jface.text.IInformationControlExtension5#computeSizeConstraints(int, int)
	 */
	@Override
	public Point computeSizeConstraints(int widthInChars, int heightInChars) {
		GC gc= new GC(fContentComposite);
		gc.setFont(JFaceResources.getDialogFont());
		int width= gc.getFontMetrics().getAverageCharWidth();
		int height= gc.getFontMetrics().getHeight();
		gc.dispose();

		return new Point(widthInChars * width, heightInChars * height);
	}

}
