/*******************************************************************************
 * Copyright (c) 2000, 2007 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.ui.forms.widgets;

import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.IMessage;
import org.eclipse.ui.forms.events.IHyperlinkListener;
import org.eclipse.ui.internal.forms.widgets.FormHeading;
import org.eclipse.ui.internal.forms.widgets.FormUtil;

/**
 * Form is a custom control that renders a title and an optional background
 * image above the body composite. It can be used alone when part of parents
 * that are scrolled. If scrolling is required, use <code>ScrolledForm</code>
 * instead because it has an instance of <code>Form</code> and adds scrolling
 * capability.
 * <p>
 * Form can have a title if set. If not set, title area will not be left empty -
 * form body will be resized to fill the entire form. In addition, an optional
 * title image can be set and is rendered to the left of the title (since 3.2).
 * <p>
 * Form can have a title drop down menu if the menu bar manager is not empty
 * (since 3.3).
 * <p>
 * Form title can support drag and drop if drag and drop support methods are
 * invoked. When used, additional decoration is rendered behind the title to
 * reinforce the drag and drop ability (since 3.3).
 * <p>
 * The form supports status messages. These messages can have various severity
 * (error, warning, info or none). If status hyperlink handler is specified, the
 * messages with the specified severity other than none will be rendered as
 * hyperlinks.
 * <p>
 * Form can have a background image behind the title text. The image is tiled as
 * many times as needed to fill the title area. Alternatively, gradient
 * background can be painted vertically or horizontally.
 * <p>
 * Form can be put in a 'busy' state. While in this state, title image is
 * replaced with an animation that lasts as long as the 'busy' state is active.
 * <p>
 * It is possible to create an optional head client control. When created, this
 * control is placed in the form heading as a second row.
 * <p>
 * Form has a custom layout manager that is wrap-enabled. If a form is placed in
 * a composite whose layout manager implements ILayoutExtension, the body of the
 * form will participate in wrapping as long as its layout manager implements
 * ILayoutExtension as well.
 * <p>
 * Children of the form should typically be created using FormToolkit to match
 * the appearance and behaviour. When creating children, use the form body as a
 * parent by calling 'getBody()' on the form instance. Example:
 * 
 * <pre>
 * FormToolkit toolkit = new FormToolkit(parent.getDisplay());
 * Form form = toolkit.createForm(parent);
 * form.setText(&quot;Sample form&quot;);
 * form.getBody().setLayout(new GridLayout());
 * toolkit.createButton(form.getBody(), &quot;Checkbox&quot;, SWT.CHECK);
 * </pre>
 * 
 * <p>
 * No layout manager has been set on the body. Clients are required to set the
 * desired layout manager explicitly.
 * <p>
 * Although the class is not final, it should not be subclassed.
 * 
 * @since 3.0
 */
public class Form extends Composite {
	private FormHeading head;

	private Composite body;

	private SizeCache bodyCache = new SizeCache();

	private SizeCache headCache = new SizeCache();

	private FormText selectionText;

	private class FormLayout extends Layout implements ILayoutExtension {
		public int computeMinimumWidth(Composite composite, boolean flushCache) {
			return computeSize(composite, 5, SWT.DEFAULT, flushCache).x;
		}

		public int computeMaximumWidth(Composite composite, boolean flushCache) {
			return computeSize(composite, SWT.DEFAULT, SWT.DEFAULT, flushCache).x;
		}

		public Point computeSize(Composite composite, int wHint, int hHint,
				boolean flushCache) {
			if (flushCache) {
				bodyCache.flush();
				headCache.flush();
			}
			bodyCache.setControl(body);
			headCache.setControl(head);

			int width = 0;
			int height = 0;

			Point hsize = headCache.computeSize(FormUtil.getWidthHint(wHint,
					head), SWT.DEFAULT);
			width = Math.max(hsize.x, width);
			height = hsize.y;
			
			boolean ignoreBody=getData(FormUtil.IGNORE_BODY)!=null;
			
			Point bsize;
			if (ignoreBody)
				bsize = new Point(0,0);
			else
				bsize = bodyCache.computeSize(FormUtil.getWidthHint(wHint,
					body), SWT.DEFAULT);
			width = Math.max(bsize.x, width);
			height += bsize.y;
			return new Point(width, height);
		}

		protected void layout(Composite composite, boolean flushCache) {
			if (flushCache) {
				bodyCache.flush();
				headCache.flush();
			}
			bodyCache.setControl(body);
			headCache.setControl(head);
			Rectangle carea = composite.getClientArea();

			Point hsize = headCache.computeSize(carea.width, SWT.DEFAULT);
			headCache.setBounds(0, 0, carea.width, hsize.y);
			bodyCache
					.setBounds(0, hsize.y, carea.width, carea.height - hsize.y);
		}
	}

	/**
	 * Creates the form content control as a child of the provided parent.
	 * 
	 * @param parent
	 *            the parent widget
	 */
	public Form(Composite parent, int style) {
		super(parent, SWT.NO_BACKGROUND | style);
		super.setLayout(new FormLayout());
		head = new FormHeading(this, SWT.NULL);
		head.setMenu(parent.getMenu());
		body = new LayoutComposite(this, SWT.NULL);
		body.setMenu(parent.getMenu());
	}

	/**
	 * Passes the menu to the form body.
	 * 
	 * @param menu
	 *            the parent menu
	 */
	public void setMenu(Menu menu) {
		super.setMenu(menu);
		head.setMenu(menu);
		body.setMenu(menu);
	}

	/**
	 * Fully delegates the size computation to the internal layout manager.
	 */
	public final Point computeSize(int wHint, int hHint, boolean changed) {
		return ((FormLayout) getLayout()).computeSize(this, wHint, hHint,
				changed);
	}

	/**
	 * Prevents from changing the custom control layout.
	 */
	public final void setLayout(Layout layout) {
	}

	/**
	 * Returns the title text that will be rendered at the top of the form.
	 * 
	 * @return the title text
	 */
	public String getText() {
		return head.getText();
	}

	/**
	 * Returns the title image that will be rendered to the left of the title.
	 * 
	 * @return the title image or <code>null</code> if not set.
	 * @since 3.2
	 */
	public Image getImage() {
		return head.getImage();
	}

	/**
	 * Sets the foreground color of the form. This color will also be used for
	 * the body.
	 * 
	 * @param fg
	 *            the foreground color
	 */
	public void setForeground(Color fg) {
		super.setForeground(fg);
		head.setForeground(fg);
		body.setForeground(fg);
	}

	/**
	 * Sets the background color of the form. This color will also be used for
	 * the body.
	 * 
	 * @param bg
	 *            the background color
	 */
	public void setBackground(Color bg) {
		super.setBackground(bg);
		head.setBackground(bg);
		body.setBackground(bg);
	}

	/**
	 * Sets the font of the header text.
	 * 
	 * @param font
	 *            the new font
	 */
	public void setFont(Font font) {
		super.setFont(font);
		head.setFont(font);
	}

	/**
	 * Sets the text to be rendered at the top of the form above the body as a
	 * title.
	 * <p>
	 * <strong>Note:</strong> Mnemonics are indicated by an '&amp;' that causes
	 * the next character to be the mnemonic. Mnemonics are not applicable in
	 * the case of the form title but need to be taken into acount due to the
	 * usage of the underlying widget that renders mnemonics in the title area.
	 * The mnemonic indicator character '&amp;' can be escaped by doubling it in
	 * the string, causing a single '&amp;' to be displayed.
	 * </p>
	 * 
	 * @param text
	 *            the title text
	 */
	public void setText(String text) {
		head.setText(text);
		layout();
		redraw();
	}

	/**
	 * Sets the image to be rendered to the left of the title. This image will
	 * be temporarily hidden in two cases:
	 * 
	 * <ol>
	 * <li>When the form is busy - replaced with a busy animation</li>
	 * <li>When the form has message set - replaced with the image indicating
	 * message severity</li>
	 * </ol>
	 * 
	 * @param image
	 *            the title image or <code>null</code> to show no image.
	 * @since 3.2
	 */
	public void setImage(Image image) {
		head.setImage(image);
		layout();
		redraw();
	}

	/**
	 * Sets the background colors to be painted behind the title text in a
	 * gradient. Note that this method will reset color previously set by
	 * {@link #setBackground(Color)}. This is necessary for the simulated
	 * transparency of the heading in all of its children control.
	 * 
	 * @param gradientColors
	 *            the array of colors that form the gradient
	 * @param percents
	 *            the partition of the overall space between the gradient colors
	 * @param vertical
	 *            of <code>true</code>, the gradient will be rendered
	 *            vertically, if <code>false</code> the orientation will be
	 *            horizontal.
	 */

	public void setTextBackground(Color[] gradientColors, int[] percents,
			boolean vertical) {
		head.setTextBackground(gradientColors, percents, vertical);
	}

	/**
	 * Returns the optional background image of the form head.
	 * 
	 * @return the background image or <code>null</code> if not specified.
	 */
	public Image getBackgroundImage() {
		return head.getHeadingBackgroundImage();
	}

	/**
	 * Sets the optional background image to be rendered behind the title
	 * starting at the position 0,0. If the image is smaller than the container
	 * in any dimension, it will be tiled.
	 * 
	 * @since 3.2
	 * 
	 * @param backgroundImage
	 *            the head background image.
	 * 
	 */
	public void setBackgroundImage(Image backgroundImage) {
		head.setHeadingBackgroundImage(backgroundImage);
	}

	/**
	 * Returns the tool bar manager that is used to manage tool items in the
	 * form's title area.
	 * 
	 * @return form tool bar manager
	 */
	public IToolBarManager getToolBarManager() {
		return head.getToolBarManager();
	}

	/**
	 * Sets the tool bar vertical alignment relative to the header. Can be
	 * useful when there is more free space at the second row (with the head
	 * client).
	 * 
	 * @param alignment
	 *            SWT.TOP or SWT.BOTTOM
	 * @since 3.3
	 */

	public void setToolBarVerticalAlignment(int alignment) {
		head.setToolBarAlignment(alignment);
	}

	/**
	 * Returns the current tool bar alignment (if used).
	 * 
	 * @return SWT.TOP or SWT.BOTTOM
	 * @since 3.3
	 */

	public int getToolBarVerticalAlignment() {
		return head.getToolBarAlignment();
	}

	/**
	 * Returns the menu manager that is used to manage title area drop-down menu
	 * items.
	 * 
	 * @return title area drop-down menu manager
	 * @since 3.3
	 */
	public IMenuManager getMenuManager() {
		return head.getMenuManager();
	}

	/**
	 * Updates the local tool bar manager if used. Does nothing if local tool
	 * bar manager has not been created yet.
	 */
	public void updateToolBar() {
		head.updateToolBar();
	}

	/**
	 * Returns the container that occupies the head of the form (the form area
	 * above the body). Use this container as a parent for the head client.
	 * 
	 * @return the head of the form.
	 * @since 3.2
	 */
	public Composite getHead() {
		return head;
	}

	/**
	 * Returns the optional head client if set.
	 * 
	 * @return the head client or <code>null</code> if not set.
	 * @see #setHeadClient(Control)
	 * @since 3.2
	 */
	public Control getHeadClient() {
		return head.getHeadClient();
	}

	/**
	 * Sets the optional head client. Head client is placed after the form
	 * title. This option causes the tool bar to be placed in the second raw of
	 * the header (below the head client).
	 * <p>
	 * The head client must be a child of the composite returned by
	 * <code>getHead()</code> method.
	 * 
	 * @param headClient
	 *            the optional child of the head
	 * @since 3.2
	 */
	public void setHeadClient(Control headClient) {
		head.setHeadClient(headClient);
		layout();
	}

	/**
	 * Returns the container that occupies the body of the form (the form area
	 * below the title). Use this container as a parent for the controls that
	 * should be in the form. No layout manager has been set on the form body.
	 * 
	 * @return Returns the body of the form.
	 */
	public Composite getBody() {
		return body;
	}

	/**
	 * Tests if the background image is tiled to cover the entire area of the
	 * form heading.
	 * 
	 * @return <code>true</code> if heading background image is tiled,
	 *         <code>false</code> otherwise.
	 */
	public boolean isBackgroundImageTiled() {
		return head.isBackgroundImageTiled();
	}

	/**
	 * Sets whether the header background image is repeated to cover the entire
	 * heading area or not.
	 * 
	 * @param backgroundImageTiled
	 *            set <code>true</code> to tile the image, or
	 *            <code>false</code> to paint the background image only once
	 *            at 0,0
	 */
	public void setBackgroundImageTiled(boolean backgroundImageTiled) {
		head.setBackgroundImageTiled(backgroundImageTiled);
	}

	/**
	 * Returns the background image alignment.
	 * 
	 * @deprecated due to the underlying widget limitations, background image is
	 *             either painted at 0,0 and/or tiled.
	 * @return SWT.LEFT
	 */
	public int getBackgroundImageAlignment() {
		return SWT.LEFT;
	}

	/**
	 * Sets the background image alignment.
	 * 
	 * @deprecated due to the underlying widget limitations, background image is
	 *             always tiled and alignment cannot be controlled.
	 * @param backgroundImageAlignment
	 *            The backgroundImageAlignment to set.
	 * @since 3.1
	 */
	public void setBackgroundImageAlignment(int backgroundImageAlignment) {
	}

	/**
	 * Tests if background image is clipped.
	 * 
	 * @deprecated due to the underlying widget limitations, background image is
	 *             always clipped.
	 * @return true
	 * @since 3.1
	 */
	public boolean isBackgroundImageClipped() {
		return true;
	}

	/**
	 * Sets whether the background image is clipped.
	 * 
	 * @deprecated due to the underlying widget limitations, background image is
	 *             always clipped.
	 * @param backgroundImageClipped
	 *            the value to set
	 * @since 3.1
	 */
	public void setBackgroundImageClipped(boolean backgroundImageClipped) {
	}

	/**
	 * Tests if the form head separator is visible.
	 * 
	 * @return <code>true</code> if the head/body separator is visible,
	 *         <code>false</code> otherwise
	 * @since 3.2
	 */
	public boolean isSeparatorVisible() {
		return head.isSeparatorVisible();
	}

	/**
	 * If set, adds a separator between the head and body. Since 3.3, the colors
	 * that are used to render it are {@link IFormColors#H_BOTTOM_KEYLINE1} and
	 * {@link IFormColors#H_BOTTOM_KEYLINE2}.
	 * 
	 * @param addSeparator
	 *            <code>true</code> to make the separator visible,
	 *            <code>false</code> otherwise.
	 * @since 3.2
	 */
	public void setSeparatorVisible(boolean addSeparator) {
		head.setSeparatorVisible(addSeparator);
	}

	/**
	 * Returns the color used to render the optional head separator. If gradient
	 * text background is used additional colors from the gradient will be used
	 * to render the separator.
	 * 
	 * @return separator color or <code>null</code> if not set.
	 * @since 3.2
	 * @deprecated use <code>getHeadColor(IFormColors.H_BOTTOM_KEYLINE2)</code>
	 */

	public Color getSeparatorColor() {
		return head.getColor(IFormColors.H_BOTTOM_KEYLINE2);
	}

	/**
	 * Sets the color to be used to render the optional head separator.
	 * 
	 * @param separatorColor
	 *            the color to render the head separator or <code>null</code>
	 *            to use the default color.
	 * @since 3.2
	 * @deprecated use
	 *             <code>setHeadColor(IFormColors.H_BOTTOM_KEYLINE2, separatorColor)</code>
	 */
	public void setSeparatorColor(Color separatorColor) {
		head.putColor(IFormColors.H_BOTTOM_KEYLINE2, separatorColor);
	}

	/**
	 * Sets the color used to paint an aspect of the form heading.
	 * 
	 * @param key
	 *            a valid form heading color key as defined in
	 *            {@link IFormColors}. Relevant keys all start with an H_
	 *            prefix.
	 * @param color
	 *            the color to use for the provided key
	 * @since 3.3
	 */

	public void setHeadColor(String key, Color color) {
		head.putColor(key, color);
	}

	/**
	 * Returns the color that is currently use to paint an aspect of the form
	 * heading, or <code>null</code> if not defined.
	 * 
	 * @param key
	 *            the color key
	 * @return the color object or <code>null</code> if not set.
	 * @since 3.3
	 */

	public Color getHeadColor(String key) {
		return head.getColor(key);
	}

	/**
	 * Sets the message for this form. Message text is rendered in the form head
	 * when shown.
	 * 
	 * @param message
	 *            the message, or <code>null</code> to clear the message
	 * @see #setMessage(String, int)
	 * @since 3.2
	 */
	public void setMessage(String message) {
		this.setMessage(message, 0, null);
	}

	/**
	 * Sets the message for this form 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> defined in IMessageProvider interface.
	 * </p>
	 * 
	 * @param newMessage
	 *            the message, or <code>null</code> to clear the message
	 * @param newType
	 *            the message type
	 * @see org.eclipse.jface.dialogs.IMessageProvider
	 * @since 3.2
	 */

	public void setMessage(String newMessage, int newType) {
		this.setMessage(newMessage, newType, null);
	}

	/**
	 * Sets the message for this form 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> defined in IMessageProvider interface.
	 * </p>
	 * <p>
	 * In addition to the summary message, this method also sets an array of
	 * individual messages.
	 * 
	 * 
	 * @param newMessage
	 *            the message, or <code>null</code> to clear the message
	 * @param newType
	 *            the message type
	 * @param children
	 *            the individual messages that contributed to the overall
	 *            message
	 * @see org.eclipse.jface.dialogs.IMessageProvider
	 * @since 3.3
	 */

	public void setMessage(String newMessage, int newType, IMessage[] children) {
		head.showMessage(newMessage, newType, children);
		layout();
	}

	/**
	 * Adds a message hyperlink listener. If at least one listener is present,
	 * messages will be rendered as hyperlinks.
	 * 
	 * @param listener
	 * @see #removeMessageHyperlinkListener(IHyperlinkListener)
	 * @since 3.3
	 */
	public void addMessageHyperlinkListener(IHyperlinkListener listener) {
		head.addMessageHyperlinkListener(listener);
	}

	/**
	 * Remove the message hyperlink listener.
	 * 
	 * @param listener
	 * @see #addMessageHyperlinkListener(IHyperlinkListener)
	 * @since 3.3
	 */
	public void removeMessageHyperlinkListener(IHyperlinkListener listener) {
		head.removeMessageHyperlinkListener(listener);
	}

	/**
	 * Tests if the form is in the 'busy' state. Busy form displays 'busy'
	 * animation in the area of the title image.
	 * 
	 * @return <code>true</code> if busy, <code>false</code> otherwise.
	 * @since 3.2
	 */

	public boolean isBusy() {
		return head.isBusy();
	}

	/**
	 * Sets the form's busy state. Busy form will display 'busy' animation in
	 * the area of the title image.
	 * 
	 * @param busy
	 *            the form's busy state
	 * @since 3.2
	 */

	public void setBusy(boolean busy) {
		head.setBusy(busy);
	}

	/**
	 * Adds support for dragging items out of the form title area via a user
	 * drag-and-drop operation.
	 * 
	 * @param operations
	 *            a bitwise OR of the supported drag and drop operation types (
	 *            <code>DROP_COPY</code>,<code>DROP_LINK</code>, and
	 *            <code>DROP_MOVE</code>)
	 * @param transferTypes
	 *            the transfer types that are supported by the drag operation
	 * @param listener
	 *            the callback that will be invoked to set the drag data and to
	 *            cleanup after the drag and drop operation finishes
	 * @see org.eclipse.swt.dnd.DND
	 * @since 3.3
	 */
	public void addTitleDragSupport(int operations, Transfer[] transferTypes,
			DragSourceListener listener) {
		head.addDragSupport(operations, transferTypes, listener);
	}

	/**
	 * Adds support for dropping items into the form title area via a user
	 * drag-and-drop operation.
	 * 
	 * @param operations
	 *            a bitwise OR of the supported drag and drop operation types (
	 *            <code>DROP_COPY</code>,<code>DROP_LINK</code>, and
	 *            <code>DROP_MOVE</code>)
	 * @param transferTypes
	 *            the transfer types that are supported by the drop operation
	 * @param listener
	 *            the callback that will be invoked after the drag and drop
	 *            operation finishes
	 * @see org.eclipse.swt.dnd.DND
	 * @since 3.3
	 */
	public void addTitleDropSupport(int operations, Transfer[] transferTypes,
			DropTargetListener listener) {
		head.addDropSupport(operations, transferTypes, listener);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.IMessageProvider#getMessage()
	 */
	public String getMessage() {
		return head.getMessage();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.IMessageProvider#getMessageType()
	 */
	public int getMessageType() {
		return head.getMessageType();
	}

	/**
	 * Returns the children messages that the cause of the summary message
	 * currently set on the form.
	 * 
	 * @return an array of children messages or <code>null</code> if not set.
	 * @see #setMessage(String, int, IMessage[])
	 * @since 3.3
	 */
	public IMessage[] getChildrenMessages() {
		return head.getChildrenMessages();
	}

	void setSelectionText(FormText text) {
		if (selectionText != null && selectionText != text) {
			selectionText.clearSelection();
		}
		this.selectionText = text;
	}
}