/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Konstantin Scheglov <scheglov_ke@nlmk.ru > - Fix for bug 41172
 *     [Dialogs] Bug with Image in TitleAreaDialog
 *     Sebastian Davids <sdavids@gmx.de> - Fix for bug 82064
 *     [Dialogs] TitleAreaDialog#setTitleImage cannot be called before open()
 *******************************************************************************/
package org.eclipse.jface.dialogs;

import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.ACC;
import org.eclipse.swt.accessibility.AccessibleAttributeAdapter;
import org.eclipse.swt.accessibility.AccessibleAttributeEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
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.Shell;
import org.eclipse.swt.widgets.Text;

/**
 * A dialog that has a title area for displaying a title and an image as well as
 * a common area for displaying a description, a message, or an error message.
 * <p>
 * This dialog class may be subclassed.
 */
public class TitleAreaDialog extends TrayDialog {
	/**
	 * Image registry key for error message image.
	 */
	public static final String DLG_IMG_TITLE_ERROR = DLG_IMG_MESSAGE_ERROR;

	/**
	 * Image registry key for banner image (value
	 * <code>"dialog_title_banner_image"</code>).
	 */
	public static final String DLG_IMG_TITLE_BANNER = "dialog_title_banner_image";//$NON-NLS-1$

	/**
	 * Message type constant used to display an info icon with the message.
	 *
	 * @since 2.0
	 * @deprecated
	 */
	@Deprecated
	public static final String INFO_MESSAGE = "INFO_MESSAGE"; //$NON-NLS-1$

	/**
	 * Message type constant used to display a warning icon with the message.
	 *
	 * @since 2.0
	 * @deprecated
	 */
	@Deprecated
	public static final String WARNING_MESSAGE = "WARNING_MESSAGE"; //$NON-NLS-1$

	// Space between an image and a label
	private static final int H_GAP_IMAGE = 5;

	// Minimum dialog width (in dialog units)
	private static final int MIN_DIALOG_WIDTH = 350;

	// Minimum dialog height (in dialog units)
	private static final int MIN_DIALOG_HEIGHT = 150;

	private Label titleLabel;

	private Label titleImageLabel;

	private Label bottomFillerLabel;

	private Label leftFillerLabel;

	private RGB titleAreaRGB;

	Color titleAreaColor;

	private String message = ""; //$NON-NLS-1$

	private String errorMessage;

	private Text messageLabel;

	private Composite workArea;

	private Label messageImageLabel;

	private Image messageImage;

	private boolean showingError = false;

	private boolean titleImageLargest = true;

	private int messageLabelHeight;

	private Image titleAreaImage;

	private int xTrim;

	private int yTrim;

	/**
	 * Instantiate a new title area dialog.
	 *
	 * @param parentShell
	 *            the parent SWT shell
	 */
	public TitleAreaDialog(Shell parentShell) {
		super(parentShell);
	}

	/*
	 * @see Dialog.createContents(Composite)
	 */
	@Override
	protected Control createContents(Composite parent) {
		// create the overall composite
		Composite contents = new Composite(parent, SWT.NONE);
		contents.setLayoutData(new GridData(GridData.FILL_BOTH));
		// initialize the dialog units
		initializeDialogUnits(contents);
		FormLayout layout = new FormLayout();
		contents.setLayout(layout);
		// Now create a work area for the rest of the dialog
		workArea = new Composite(contents, SWT.NONE);
		GridLayout childLayout = new GridLayout();
		childLayout.marginHeight = 0;
		childLayout.marginWidth = 0;
		childLayout.verticalSpacing = 0;
		workArea.setLayout(childLayout);
		Control top = createTitleArea(contents);
		resetWorkAreaAttachments(top);
		workArea.setFont(JFaceResources.getDialogFont());
		// initialize the dialog units
		initializeDialogUnits(workArea);
		// create the dialog area and button bar
		dialogArea = createDialogArea(workArea);
		buttonBar = createButtonBar(workArea);

		// computing trim for later
		Rectangle rect = messageLabel.computeTrim(0, 0, 100, 100);
		xTrim = rect.width - 100;
		yTrim = rect.height - 100;

		// need to react to new size of title area
		getShell().addListener(SWT.Resize, event -> layoutForNewMessage(true));
		return contents;
	}

	/**
	 * Creates and returns the contents of the upper part of this dialog (above
	 * the button bar).
	 * <p>
	 * The <code>Dialog</code> implementation of this framework method creates
	 * and returns a new <code>Composite</code> with no margins and spacing.
	 * Subclasses should override.
	 * </p>
	 *
	 * @param parent
	 *            The parent composite to contain the dialog area
	 * @return the dialog area control
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		// create the top level composite for the dialog area
		Composite composite = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		layout.verticalSpacing = 0;
		layout.horizontalSpacing = 0;
		composite.setLayout(layout);
		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
		composite.setFont(parent.getFont());
		// Build the separator line
		Label titleBarSeparator = new Label(composite, SWT.HORIZONTAL
				| SWT.SEPARATOR);
		titleBarSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		return composite;
	}

	/**
	 * Creates the dialog's title area.
	 *
	 * @param parent
	 *            the SWT parent for the title area widgets
	 * @return Control with the highest x axis value.
	 */
	private Control createTitleArea(Composite parent) {

		// add a dispose listener
		parent.addDisposeListener(e -> {
			if (titleAreaColor != null) {
				titleAreaColor.dispose();
			}
		});
		// Determine the background color of the title bar
		Display display = parent.getDisplay();
		Color background;
		Color foreground;
		if (titleAreaRGB != null) {
			titleAreaColor = new Color(display, titleAreaRGB);
			background = titleAreaColor;
			foreground = null;
		} else {
			background = JFaceColors.getBannerBackground(display);
			foreground = JFaceColors.getBannerForeground(display);
		}

		parent.setBackground(background);
		int verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
		int horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
		// Dialog image @ right
		titleImageLabel = new Label(parent, SWT.CENTER);
		titleImageLabel.setBackground(background);
		if (titleAreaImage == null)
			titleImageLabel.setImage(JFaceResources
					.getImage(DLG_IMG_TITLE_BANNER));
		else
			titleImageLabel.setImage(titleAreaImage);

		FormData imageData = new FormData();
		imageData.top = new FormAttachment(0, 0);
		// Note: do not use horizontalSpacing on the right as that would be a
		// regression from
		// the R2.x style where there was no margin on the right and images are
		// flush to the right
		// hand side. see reopened comments in 41172
		imageData.right = new FormAttachment(100, 0); // horizontalSpacing
		titleImageLabel.setLayoutData(imageData);
		// Title label @ top, left
		titleLabel = new Label(parent, SWT.LEFT);
		JFaceColors.setColors(titleLabel, foreground, background);
		titleLabel.setFont(JFaceResources.getBannerFont());
		titleLabel.setText(" ");//$NON-NLS-1$
		FormData titleData = new FormData();
		titleData.top = new FormAttachment(0, verticalSpacing);
		titleData.right = new FormAttachment(titleImageLabel);
		titleData.left = new FormAttachment(0, horizontalSpacing);
		titleLabel.setLayoutData(titleData);
		// Message image @ bottom, left
		messageImageLabel = new Label(parent, SWT.CENTER);
		messageImageLabel.setBackground(background);
		// Message label @ bottom, center
		messageLabel = new Text(parent, SWT.WRAP | SWT.READ_ONLY);
		JFaceColors.setColors(messageLabel, foreground, background);
		messageLabel.setText(" \n "); // two lines//$NON-NLS-1$
		messageLabel.setFont(JFaceResources.getDialogFont());
		// Bug 248410 -  This snippet will only work with Windows screen readers.
		messageLabel.getAccessible().addAccessibleAttributeListener(
				new AccessibleAttributeAdapter() {
					@Override
					public void getAttributes(AccessibleAttributeEvent e) {
						e.attributes = new String[] { "container-live", //$NON-NLS-1$
								"polite", "live", "polite",   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
								"container-live-role", "status", }; //$NON-NLS-1$ //$NON-NLS-2$
					}
				});
		messageLabelHeight = messageLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
		// Filler labels
		leftFillerLabel = new Label(parent, SWT.CENTER);
		leftFillerLabel.setBackground(background);
		bottomFillerLabel = new Label(parent, SWT.CENTER);
		bottomFillerLabel.setBackground(background);
		setLayoutsForNormalMessage(verticalSpacing, horizontalSpacing);
		determineTitleImageLargest();
		if (titleImageLargest)
			return titleImageLabel;
		return messageLabel;
	}

	/**
	 * Determine if the title image is larger than the title message and message
	 * area. This is used for layout decisions.
	 */
	private void determineTitleImageLargest() {
		int titleY = titleImageLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
		int verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
		int labelY = titleLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
		labelY += verticalSpacing;
		labelY += messageLabelHeight;
		labelY += verticalSpacing;
		titleImageLargest = titleY > labelY;
	}

	/**
	 * Set the layout values for the messageLabel, messageImageLabel and
	 * fillerLabel for the case where there is a normal message.
	 *
	 * @param verticalSpacing
	 *            int The spacing between widgets on the vertical axis.
	 * @param horizontalSpacing
	 *            int The spacing between widgets on the horizontal axis.
	 */
	private void setLayoutsForNormalMessage(int verticalSpacing,
			int horizontalSpacing) {
		FormData messageImageData = new FormData();
		messageImageData.top = new FormAttachment(titleLabel, verticalSpacing);
		messageImageData.left = new FormAttachment(0, H_GAP_IMAGE);
		messageImageLabel.setLayoutData(messageImageData);
		FormData messageLabelData = new FormData();
		messageLabelData.top = new FormAttachment(titleLabel, verticalSpacing);
		messageLabelData.right = new FormAttachment(titleImageLabel);
		messageLabelData.left = new FormAttachment(messageImageLabel,
				horizontalSpacing);
		messageLabelData.height = messageLabelHeight;
		if (titleImageLargest)
			messageLabelData.bottom = new FormAttachment(titleImageLabel, 0,
					SWT.BOTTOM);
		messageLabel.setLayoutData(messageLabelData);
		FormData fillerData = new FormData();
		fillerData.left = new FormAttachment(0, horizontalSpacing);
		fillerData.top = new FormAttachment(messageImageLabel, 0);
		fillerData.bottom = new FormAttachment(messageLabel, 0, SWT.BOTTOM);
		bottomFillerLabel.setLayoutData(fillerData);
		FormData data = new FormData();
		data.top = new FormAttachment(messageImageLabel, 0, SWT.TOP);
		data.left = new FormAttachment(0, 0);
		data.bottom = new FormAttachment(messageImageLabel, 0, SWT.BOTTOM);
		data.right = new FormAttachment(messageImageLabel, 0);
		leftFillerLabel.setLayoutData(data);
	}

	/**
	 * The <code>TitleAreaDialog</code> implementation of this
	 * <code>Window</code> methods returns an initial size which is at least
	 * some reasonable minimum.
	 *
	 * @return the initial size of the dialog
	 */
	@Override
	protected Point getInitialSize() {
		Point shellSize = super.getInitialSize();
		return new Point(Math.max(
				convertHorizontalDLUsToPixels(MIN_DIALOG_WIDTH), shellSize.x),
				Math.max(convertVerticalDLUsToPixels(MIN_DIALOG_HEIGHT),
						shellSize.y));
	}

	/**
	 * Retained for backward compatibility.
	 *
	 * Returns the title area composite. There is no composite in this
	 * implementation so the shell is returned.
	 *
	 * @return Composite
	 * @deprecated
	 */
	@Deprecated
	protected Composite getTitleArea() {
		return getShell();
	}

	/**
	 * Returns the title image label.
	 *
	 * @return the title image label
	 */
	protected Label getTitleImageLabel() {
		return titleImageLabel;
	}

	/**
	 * Display the given error message. The currently displayed message is saved
	 * and will be redisplayed when the error message is set to
	 * <code>null</code>.
	 *
	 * @param newErrorMessage
	 *            the newErrorMessage to display or <code>null</code>
	 */
	public void setErrorMessage(String newErrorMessage) {
		// Any change?
		if (errorMessage == null ? newErrorMessage == null : errorMessage
				.equals(newErrorMessage))
			return;
		errorMessage = newErrorMessage;

		// Clear or set error message.
		if (errorMessage == null) {
			if (showingError) {
				// we were previously showing an error
				showingError = false;
			}
			// show the message
			// avoid calling setMessage in case it is overridden to call
			// setErrorMessage,
			// which would result in a recursive infinite loop
			if (message == null) // this should probably never happen since
				// setMessage does this conversion....
				message = ""; //$NON-NLS-1$
			updateMessage(message);
			messageImageLabel.setImage(messageImage);
			setImageLabelVisible(messageImage != null);
		} else {
			// Add in a space for layout purposes but do not
			// change the instance variable
			String displayedErrorMessage = " " + errorMessage; //$NON-NLS-1$
			updateMessage(displayedErrorMessage);
			if (!showingError) {
				// we were not previously showing an error
				showingError = true;
				messageImageLabel.setImage(JFaceResources
						.getImage(DLG_IMG_TITLE_ERROR));
				setImageLabelVisible(true);
			}
		}
		layoutForNewMessage(false);
	}

	/**
	 * Re-layout the labels for the new message.
	 *
	 * @param forceLayout
	 *            <code>true</code> to force a layout of the shell
	 */
	private void layoutForNewMessage(boolean forceLayout) {
		int verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
		int horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
		// If there are no images then layout as normal
		if (errorMessage == null && messageImage == null) {
			setImageLabelVisible(false);
			setLayoutsForNormalMessage(verticalSpacing, horizontalSpacing);
		} else {
			messageImageLabel.setVisible(true);
			bottomFillerLabel.setVisible(true);
			leftFillerLabel.setVisible(true);
			/**
			 * Note that we do not use horizontalSpacing here as when the
			 * background of the messages changes there will be gaps between the
			 * icon label and the message that are the background color of the
			 * shell. We add a leading space elsewhere to compendate for this.
			 */
			FormData data = new FormData();
			data.left = new FormAttachment(0, H_GAP_IMAGE);
			data.top = new FormAttachment(titleLabel, verticalSpacing);
			messageImageLabel.setLayoutData(data);
			data = new FormData();
			data.top = new FormAttachment(messageImageLabel, 0);
			data.left = new FormAttachment(0, 0);
			data.bottom = new FormAttachment(messageLabel, 0, SWT.BOTTOM);
			data.right = new FormAttachment(messageImageLabel, 0, SWT.RIGHT);
			bottomFillerLabel.setLayoutData(data);
			data = new FormData();
			data.top = new FormAttachment(messageImageLabel, 0, SWT.TOP);
			data.left = new FormAttachment(0, 0);
			data.bottom = new FormAttachment(messageImageLabel, 0, SWT.BOTTOM);
			data.right = new FormAttachment(messageImageLabel, 0);
			leftFillerLabel.setLayoutData(data);
			FormData messageLabelData = new FormData();
			messageLabelData.top = new FormAttachment(titleLabel,
					verticalSpacing);
			messageLabelData.right = new FormAttachment(titleImageLabel);
			messageLabelData.left = new FormAttachment(messageImageLabel, 0);
			messageLabelData.height = messageLabelHeight;
			if (titleImageLargest)
				messageLabelData.bottom = new FormAttachment(titleImageLabel,
						0, SWT.BOTTOM);
			messageLabel.setLayoutData(messageLabelData);
		}

		if (forceLayout) {
			getShell().layout();
		} else {
			// Do not layout before the dialog area has been created
			// to avoid incomplete calculations.
			if (dialogArea != null)
				workArea.getParent().layout(true);
		}

		int messageLabelUnclippedHeight = messageLabel.computeSize(messageLabel.getSize().x - xTrim, SWT.DEFAULT, true).y;
		boolean messageLabelClipped = messageLabelUnclippedHeight > messageLabel.getSize().y - yTrim;
		if (messageLabel.getData() instanceof ToolTip) {
			ToolTip toolTip = (ToolTip) messageLabel.getData();
			toolTip.hide();
			toolTip.deactivate();
			messageLabel.setData(null);
		}
		if (messageLabelClipped) {
			ToolTip tooltip = new ToolTip(messageLabel, ToolTip.NO_RECREATE, false) {

				@Override
				protected Composite createToolTipContentArea(Event event, Composite parent) {
					Composite result = new Composite(parent, SWT.NONE);
					result.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
					result.setLayout(new GridLayout());
					Text text = new Text(result, SWT.WRAP);
					text.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
					text.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
					text.setText(messageLabel.getText());
					GridData gridData = new GridData();
					gridData.widthHint = messageLabel.getSize().x;
					text.setLayoutData(gridData);
					Dialog.applyDialogFont(result);
					return result;
				}
				@Override
				public Point getLocation(Point tipSize, Event event) {
					return messageLabel.getShell().toDisplay(messageLabel.getLocation());
				}
			};
			messageLabel.setData(tooltip);
			tooltip.setPopupDelay(0);
			tooltip.activate();
		}
	}

	/**
	 * Set the message text. If the message line currently displays an error,
	 * the message is saved and will be redisplayed when the error message is
	 * set to <code>null</code>.
	 * <p>
	 * Shortcut for <code>setMessage(newMessage, IMessageProvider.NONE)</code>
	 * </p>
	 * This method should be called after the dialog has been opened as it
	 * updates the message label immediately.
	 *
	 * @param newMessage
	 *            the message, or <code>null</code> to clear the message
	 */
	public void setMessage(String newMessage) {
		setMessage(newMessage, IMessageProvider.NONE);
	}

	/**
	 * Sets the message for this dialog with an indication of what type of
	 * message it is.
	 * <p>
	 * The valid message types are one of <code>NONE</code>,
	 * <code>INFORMATION</code>,<code>WARNING</code>, or
	 * <code>ERROR</code>.
	 * </p>
	 * <p>
	 * Note that for backward compatibility, a message of type
	 * <code>ERROR</code> is different than an error message (set using
	 * <code>setErrorMessage</code>). An error message overrides the current
	 * message until the error message is cleared. This method replaces the
	 * current message and does not affect the error message.
	 * </p>
	 *
	 * @param newMessage
	 *            the message, or <code>null</code> to clear the message
	 * @param newType
	 *            the message type
	 * @since 2.0
	 */
	public void setMessage(String newMessage, int newType) {
		Image newImage = null;
		if (newMessage != null) {
			switch (newType) {
			case IMessageProvider.NONE:
				break;
			case IMessageProvider.INFORMATION:
				newImage = JFaceResources.getImage(DLG_IMG_MESSAGE_INFO);
				break;
			case IMessageProvider.WARNING:
				newImage = JFaceResources.getImage(DLG_IMG_MESSAGE_WARNING);
				break;
			case IMessageProvider.ERROR:
				newImage = JFaceResources.getImage(DLG_IMG_MESSAGE_ERROR);
				break;
			}
		}
		showMessage(newMessage, newImage);
	}

	/**
	 * Show the new message and image.
	 *
	 * @param newMessage
	 * @param newImage
	 */
	private void showMessage(String newMessage, Image newImage) {
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=249915
		if (newMessage == null)
			newMessage = ""; //$NON-NLS-1$

		// Any change?
		if (message.equals(newMessage) && messageImage == newImage) {
			return;
		}
		message = newMessage;

		// Message string to be shown - if there is an image then add in
		// a space to the message for layout purposes
		String shownMessage = (newImage == null) ? message : " " + message; //$NON-NLS-1$
		messageImage = newImage;
		if (!showingError) {
			// we are not showing an error
			updateMessage(shownMessage);
			messageImageLabel.setImage(messageImage);
			setImageLabelVisible(messageImage != null);
			layoutForNewMessage(false);
		}
	}

	/**
	 * Update the contents of the messageLabel.
	 *
	 * @param newMessage
	 *            the message to use
	 */
	private void updateMessage(String newMessage) {
		String oldMessage = messageLabel.getText();
		messageLabel.setText(newMessage);
		// Bug 248410 -  This snippet will only work with Windows screen readers.
		messageLabel.getAccessible().sendEvent(ACC.EVENT_ATTRIBUTE_CHANGED,
				null);
		messageLabel.getAccessible().sendEvent(
				ACC.EVENT_TEXT_CHANGED,
				new Object[] { Integer.valueOf(ACC.TEXT_DELETE), Integer.valueOf(0),
						Integer.valueOf(oldMessage.length()), oldMessage });
		messageLabel.getAccessible().sendEvent(
				ACC.EVENT_TEXT_CHANGED,
				new Object[] { Integer.valueOf(ACC.TEXT_INSERT), Integer.valueOf(0),
						Integer.valueOf(newMessage.length()), newMessage });
	}

	/**
	 * Sets the title to be shown in the title area of this dialog.
	 *
	 * @param newTitle
	 *            the title show
	 */
	public void setTitle(String newTitle) {
		if (titleLabel == null)
			return;
		String title = newTitle;
		if (title == null)
			title = "";//$NON-NLS-1$
		titleLabel.setText(title);
	}

	/**
	 * Sets the title bar color for this dialog.
	 *
	 * @param color
	 *            the title bar color
	 */
	public void setTitleAreaColor(RGB color) {
		titleAreaRGB = color;
	}

	/**
	 * Sets the title image to be shown in the title area of this dialog.
	 *
	 * @param newTitleImage
	 *            the title image to be shown
	 */
	public void setTitleImage(Image newTitleImage) {

		titleAreaImage = newTitleImage;
		if (titleImageLabel != null) {
			titleImageLabel.setImage(newTitleImage);
			determineTitleImageLargest();
			Control top;
			if (titleImageLargest)
				top = titleImageLabel;
			else
				top = messageLabel;
			resetWorkAreaAttachments(top);
		}
	}

	/**
	 * Make the label used for displaying error images visible depending on
	 * boolean.
	 *
	 * @param visible
	 *            If <code>true</code> make the image visible, if not then
	 *            make it not visible.
	 */
	private void setImageLabelVisible(boolean visible) {
		messageImageLabel.setVisible(visible);
		bottomFillerLabel.setVisible(visible);
		leftFillerLabel.setVisible(visible);
	}

	/**
	 * Reset the attachment of the workArea to now attach to top as the top
	 * control.
	 *
	 * @param top
	 */
	private void resetWorkAreaAttachments(Control top) {
		FormData childData = new FormData();
		childData.top = new FormAttachment(top);
		childData.right = new FormAttachment(100, 0);
		childData.left = new FormAttachment(0, 0);
		childData.bottom = new FormAttachment(100, 0);
		workArea.setLayoutData(childData);
	}

	/**
	 * Returns the current message text for this dialog.  This message is
	 * displayed in the message line of the dialog when the error message
	 * is <code>null</code>.  If there is a non-null error message, this
	 * message is not shown, but is stored so that it can be shown in
	 * the message line whenever {@link #setErrorMessage(String)} is called with
	 * a <code>null</code> parameter.
	 *
	 * @return the message text, which is never <code>null</code>.
	 *
	 * @see #setMessage(String)
	 * @see #setErrorMessage(String)
	 *
	 * @since 3.6
	 */

    public String getMessage() {
    	return message;
    }

	/**
	 * Returns the current error message being shown in the dialog, or
	 * <code>null</code> if there is no error message being shown.
	 *
	 * @return the error message, which may be <code>null</code>.
	 *
	 * @see #setErrorMessage(String)
	 * @see #setMessage(String)
	 *
	 * @since 3.6
	 */

    public String getErrorMessage() {
    	return errorMessage;
    }
}
