/*******************************************************************************
 * 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
 *     Michael Williamson (eclipse-bugs@magnaworks.com) - patch (see Bugzilla #92545) 
 *       
 *******************************************************************************/
package org.eclipse.ui.forms.widgets;

import java.util.Hashtable;

import org.eclipse.core.runtime.Assert;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
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.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.internal.forms.widgets.FormUtil;

/**
 * A variation of the expandable composite that adds optional description below
 * the title. Section is often used as a basic building block in forms because
 * it provides for logical grouping of information.
 * <p>
 * In case of the TITLE_BAR style, Section renders the title bar in a way
 * compatible with the rest of the workbench. Since it is a widget, all the
 * colors must be supplied directly. When created by the form toolkit, these
 * colors are supplied by the toolkit. The toolkit initializes these colors
 * based on the system colors. For this reason, it is recommended to create the
 * section by the toolkit instead of through its own constructor.
 * <p>
 * Since 3.1, it is possible to set a control to be used for section
 * description. If used, <code>DESCRIPTION</code> style should not be set. A
 * typical way to take advantage of the new method is to set an instance of
 * <code>FormText</code> to provide for hyperlinks and images in the
 * description area.
 * 
 * @since 3.0
 */
public class Section extends ExpandableComposite {
	/**
	 * Description style. If used, description will be rendered below the title.
	 */
	public static final int DESCRIPTION = 1 << 7;

	private Control descriptionControl;

	private Control separator;

	private Hashtable titleColors;

	private static final String COLOR_BG = "bg"; //$NON-NLS-1$

	private static final String COLOR_GBG = "gbg"; //$NON-NLS-1$

	private static final String COLOR_BORDER = "border"; //$NON-NLS-1$

	/**
	 * Creates a new section instance in the provided parent.
	 * 
	 * @param parent
	 *            the parent composite
	 * @param style
	 *            the style to use
	 */
	public Section(Composite parent, int style) {
		this(parent, SWT.NULL, style);
	}

	Section(Composite parent, int cstyle, int style) {
		super(parent, cstyle | getBackgroundStyle(style), style);
		int rtl = cstyle & SWT.RIGHT_TO_LEFT;
		if ((style & DESCRIPTION) != 0) {
			descriptionControl = new Text(this, SWT.READ_ONLY | SWT.WRAP | rtl);
		}
		if ((style & TITLE_BAR) != 0) {
			Listener listener = new Listener() {
				public void handleEvent(Event e) {
					Image image = Section.super.getBackgroundImage();
					if (image != null)
						image.dispose();
					Section.super.setBackgroundImage(null);
				}
			};
			addListener(SWT.Dispose, listener);
			addListener(SWT.Resize, listener);
		}
	}

	private static int getBackgroundStyle(int estyle) {
		return ((estyle & TITLE_BAR) != 0) ? SWT.NO_BACKGROUND : SWT.NULL;
	}

	protected void internalSetExpanded(boolean expanded) {
		super.internalSetExpanded(expanded);
		if ((getExpansionStyle() & TITLE_BAR) != 0) {
			if (!expanded)
				super.setBackgroundImage(null);
		}
		reflow();
	}

	/**
	 * Reflows this section and all the parents up the hierarchy until a
	 * ScrolledForm is reached.
	 */
	protected void reflow() {
		Composite c = this;
		while (c != null) {
			c.setRedraw(false);
			c = c.getParent();
			if (c instanceof ScrolledForm) {
				break;
			}
		}
		c = this;
		while (c != null) {
			c.layout(true);
			c = c.getParent();
			if (c instanceof ScrolledForm) {
				((ScrolledForm) c).reflow(true);
				break;
			}
		}
		c = this;
		while (c != null) {
			c.setRedraw(true);
			c = c.getParent();
			if (c instanceof ScrolledForm) {
				break;
			}
		}
	}

	/**
	 * Sets the description text. Has no effect if DESCRIPTION style was not
	 * used to create the control.
	 * 
	 * @param description
	 */
	public void setDescription(String description) {
		if (descriptionControl instanceof Text)
			((Text) descriptionControl).setText(description);
	}

	/**
	 * Returns the current description text.
	 * 
	 * @return description text or <code>null</code> if DESCRIPTION style was
	 *         not used to create the control.
	 */
	public String getDescription() {
		if (descriptionControl instanceof Text)
			return ((Text) descriptionControl).getText();
		return null;
	}

	/**
	 * Sets the separator control of this section. The separator must not be
	 * <samp>null </samp> and must be a direct child of this container. If
	 * defined, separator will be placed below the title text and will remain
	 * visible regardless of the expansion state.
	 * 
	 * @param separator
	 *            the separator that will be placed below the title text.
	 */
	public void setSeparatorControl(Control separator) {
		Assert.isTrue(separator != null && separator.getParent().equals(this));
		this.separator = separator;
	}

	/**
	 * Returns the control that is used as a separator betweeen the title and
	 * the client, or <samp>null </samp> if not set.
	 * 
	 * @return separator control or <samp>null </samp> if not set.
	 */
	public Control getSeparatorControl() {
		return separator;
	}

	/**
	 * Sets the background of the section.
	 * 
	 * @param bg
	 *            the new background
	 */
	public void setBackground(Color bg) {
		super.setBackground(bg);
		if (descriptionControl != null
				&& (getExpansionStyle() & DESCRIPTION) != 0)
			descriptionControl.setBackground(bg);
	}

	/**
	 * Sets the foreground of the section.
	 * 
	 * @param fg
	 *            the new foreground.
	 */
	public void setForeground(Color fg) {
		super.setForeground(fg);
		if (descriptionControl != null
				&& (getExpansionStyle() & DESCRIPTION) != 0)
			descriptionControl.setForeground(fg);
	}

	/**
	 * Returns the control used to render the description. In 3.1, this method
	 * was promoted to public.
	 * 
	 * @return description control or <code>null</code> if DESCRIPTION style
	 *         was not used to create the control and description control was
	 *         not set by the client.
	 * @see #setDescriptionControl(org.eclipse.swt.widgets.Control)
	 */
	public Control getDescriptionControl() {
		return descriptionControl;
	}

	/**
	 * Sets the description control of this section. The control must not be
	 * <samp>null</samp> and must be a direct child of this container. If
	 * defined, contol will be placed below the title text and the separator and
	 * will be hidden int he collapsed state.
	 * <p>
	 * This method and <code>DESCRIPTION</code> style are mutually exclusive.
	 * Use the method only if you want to create the description control
	 * yourself.
	 * 
	 * @since 3.1
	 * @param descriptionControl
	 *            the control that will be placed below the title text.
	 */
	public void setDescriptionControl(Control descriptionControl) {
		Assert.isTrue((getExpansionStyle() & DESCRIPTION) == 0);
		Assert.isTrue(descriptionControl != null
				&& descriptionControl.getParent().equals(this));
		this.descriptionControl = descriptionControl;
	}

	/**
	 * Sets the color of the title bar border when TITLE_BAR style is used.
	 * 
	 * @param color
	 *            the title bar border color
	 */
	public void setTitleBarBorderColor(Color color) {
		putTitleBarColor(COLOR_BORDER, color);
	}

	/**
	 * Sets the color of the title bar background when TITLE_BAR style is used.
	 * This color is used as a starting color for the vertical gradient.
	 * 
	 * @param color
	 *            the title bar border background
	 */
	public void setTitleBarBackground(Color color) {
		putTitleBarColor(COLOR_BG, color);
	}

	/**
	 * Sets the color of the title bar gradient background when TITLE_BAR style
	 * is used. This color is used at the height where title controls end
	 * (toggle, tool bar).
	 * 
	 * @param color
	 *            the title bar gradient background
	 */
	public void setTitleBarGradientBackground(Color color) {
		putTitleBarColor(COLOR_GBG, color);
	}

	/**
	 * Returns the title bar border color when TITLE_BAR style is used.
	 * 
	 * @return the title bar border color
	 */
	public Color getTitleBarBorderColor() {
		if (titleColors == null)
			return null;
		return (Color) titleColors.get(COLOR_BORDER);
	}

	/**
	 * Returns the title bar gradient background color when TITLE_BAR style is
	 * used.
	 * 
	 * @return the title bar gradient background
	 */
	public Color getTitleBarGradientBackground() {
		if (titleColors == null)
			return null;
		if ((getExpansionStyle() & SHORT_TITLE_BAR) != 0)
			return getBackground();
		return (Color) titleColors.get(COLOR_GBG);
	}

	/**
	 * Returns the title bar background when TITLE_BAR style is used.
	 * 
	 * @return the title bar background
	 */
	public Color getTitleBarBackground() {
		if (titleColors == null)
			return null;
		return (Color) titleColors.get(COLOR_BG);
	}

	private void putTitleBarColor(String key, Color color) {
		if (color == null)
			return;
		if (titleColors == null)
			titleColors = new Hashtable();
		titleColors.put(key, color);
	}

	protected void onPaint(PaintEvent e) {
		Color bg = null;
		Color fg = null;
		Color border = null;

		GC gc = e.gc;
		Image buffer = null;
		Rectangle bounds = getClientArea();

		if ((getExpansionStyle() & TITLE_BAR) != 0) {
			buffer = new Image(getDisplay(), bounds.width, bounds.height);
			buffer.setBackground(getBackground());
			gc = new GC(buffer);
		}
		if (titleColors != null) {
			bg = (Color) titleColors.get(COLOR_BG);
			fg = getTitleBarForeground();
			border = (Color) titleColors.get(COLOR_BORDER);
		}
		if (bg == null)
			bg = getBackground();
		if (fg == null)
			fg = getForeground();
		if (border == null)
			border = fg;
		int theight = 0;
		int gradientheight = 0;
		int tvmargin = IGAP;
		if ((getExpansionStyle() & TITLE_BAR) != 0) {
			Point tsize = null;
			Point tcsize = null;
			if (toggle != null)
				tsize = toggle.getSize();
			int twidth = bounds.width - marginWidth - marginWidth;
			if (tsize != null)
				twidth -= tsize.x + IGAP;
			if (getTextClient() != null)
				tcsize = getTextClient().getSize();
			if (tcsize != null)
				twidth -= tcsize.x + IGAP;
			Point size = textLabel.getSize();
			if (tsize != null)
				theight += Math.max(theight, tsize.y);
			gradientheight = theight;
			if (tcsize != null) {
				theight = Math.max(theight, tcsize.y);
			}
			theight = Math.max(theight, size.y);
			gradientheight = Math.max(gradientheight, size.y);
			theight += tvmargin + tvmargin;
			gradientheight += tvmargin + tvmargin;
		} else {
			theight = 5;
		}
		if ((getExpansionStyle() & TITLE_BAR) != 0) {
			if (getBackgroundImage() == null)
				updateHeaderImage(bg, bounds, gradientheight, theight);
			gc.setBackground(getBackground());
			gc.fillRectangle(bounds.x, bounds.y, bounds.width, bounds.height);
			drawBackground(gc, bounds.x, bounds.y, bounds.width, theight);
			if (marginWidth > 0) {
				// fix up margins
				gc.setBackground(getBackground());
				gc.fillRectangle(0, 0, marginWidth, theight);
				gc.fillRectangle(bounds.x + bounds.width - marginWidth, 0,
						marginWidth, theight);
			}
		} else if (isExpanded()) {
			gc.setForeground(bg);
			gc.setBackground(getBackground());
			gc.fillGradientRectangle(marginWidth, marginHeight, bounds.width
					- marginWidth - marginWidth, theight, true);
		}
		gc.setBackground(getBackground());
		FormUtil.setAntialias(gc, SWT.ON);
		// repair the upper left corner
		gc.fillPolygon(new int[] { marginWidth, marginHeight, marginWidth,
				marginHeight + 2, marginWidth + 2, marginHeight });
		// repair the upper right corner
		gc.fillPolygon(new int[] { bounds.width - marginWidth - 3,
				marginHeight, bounds.width - marginWidth, marginHeight,
				bounds.width - marginWidth, marginHeight + 3 });
		gc.setForeground(border);
		if (isExpanded() || (getExpansionStyle() & TITLE_BAR) != 0) {
			// top left curve
			gc.drawLine(marginWidth, marginHeight + 2, marginWidth + 2,
					marginHeight);
			// top edge
			gc.drawLine(marginWidth + 2, marginHeight, bounds.width
					- marginWidth - 3, marginHeight);
			// top right curve
			gc.drawLine(bounds.width - marginWidth - 3, marginHeight,
					bounds.width - marginWidth - 1, marginHeight + 2);
		} else {
			// collapsed short title bar
			// top edge
			gc.drawLine(marginWidth, marginHeight, bounds.width - 1,
					marginHeight);
		}
		if ((getExpansionStyle() & TITLE_BAR) != 0 || isExpanded()) {
			// left vertical edge gradient
			gc.fillGradientRectangle(marginWidth, marginHeight + 2, 1,
					gradientheight - 2, true);
			// right vertical edge gradient
			gc.fillGradientRectangle(bounds.width - marginWidth - 1,
					marginHeight + 2, 1, gradientheight - 2, true);
		}
		if ((getExpansionStyle() & TITLE_BAR) != 0) {
			// New in 3.3 - edge treatmant
			gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE));
			gc.drawPolyline(new int[] { marginWidth + 1,
					marginHeight + gradientheight - 1, marginWidth + 1,
					marginHeight + 2, marginWidth + 2, marginHeight + 2,
					marginWidth + 2, marginHeight + 1,
					bounds.width - marginWidth - 3, marginHeight + 1,
					bounds.width - marginWidth - 3, marginHeight + 2,
					bounds.width - marginWidth - 2, marginHeight + 2,
					bounds.width - marginWidth - 2,
					marginHeight + gradientheight - 1 });
		}
		if (buffer != null) {
			gc.dispose();
			e.gc.drawImage(buffer, 0, 0);
			buffer.dispose();
		}
	}

	private void updateHeaderImage(Color bg, Rectangle bounds, int theight,
			int realtheight) {
		Image image = new Image(getDisplay(), 1, realtheight);
		image.setBackground(getBackground());
		GC gc = new GC(image);
		gc.setBackground(getBackground());
		gc.fillRectangle(0, 0, 1, realtheight);
		gc.setForeground(bg);
		gc.setBackground(getBackground());
		gc.fillGradientRectangle(0, marginHeight + 2, 1, theight - 2, true);
		gc.dispose();
		super.setBackgroundImage(image);
	}

	/**
	 * Background image is used for the title gradient - does nothing.
	 */
	public final void setBackgroundImage(Image image) {
	}
}
