/*******************************************************************************
 * Copyright (c) 2000, 2005 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.jface.util.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.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;

/**
 * A variation of the expandable composite that adds optional description below
 * the title. Section is often used as a basic building block if 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, style);
		int rtl = cstyle & SWT.RIGHT_TO_LEFT;
		if ((style & DESCRIPTION) != 0) {
			descriptionControl = new Label(this, SWT.WRAP | rtl);
		}
	}

	protected void internalSetExpanded(boolean expanded) {
		super.internalSetExpanded(expanded);
		reflow();
	}

	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 Label)
			((Label) 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 Label)
			return ((Label) 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);
		if ((getExpansionStyle() & TITLE_BAR) != 0) {
			textLabel.setBackground(color);
			if (toggle != null)
				toggle.setBackground(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 gbg = null;
		Color fg = null;
		Color border = null;
		if (titleColors != null) {
			bg = (Color) titleColors.get(COLOR_BG);
			gbg = (Color) titleColors.get(COLOR_GBG);
			fg = getTitleBarForeground();
			border = (Color) titleColors.get(COLOR_BORDER);
		}
		if (bg == null)
			bg = getBackground();
		if (fg == null)
			fg = getForeground();
		if (border == null)
			border = fg;
		if (gbg == null)
			gbg = bg;
		Rectangle bounds = getClientArea();
		int theight = 0;
		int tvmargin = GAP;
		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 + GAP;
			if (getTextClient() != null)
				tcsize = getTextClient().getSize();
			if (tcsize != null)
				twidth -= tcsize.x + GAP;
			Point size = textLabel.getSize();
			if (tsize != null)
				theight += Math.max(theight, tsize.y);
			if (tcsize != null)
				theight = Math.max(theight, tcsize.y);
			theight = Math.max(theight, size.y);
			theight += tvmargin + tvmargin;
		} else {
			theight = 5;
		}
		int midpoint = (theight * 66) / 100;
		int rem = theight - midpoint;
		GC gc = e.gc;
		if ((getExpansionStyle() & TITLE_BAR) != 0) {
			gc.setForeground(bg);
			gc.setBackground(gbg);
			gc.fillGradientRectangle(marginWidth, marginHeight, bounds.width
					- 1 - marginWidth - marginWidth, midpoint - 1, true);
			gc.setForeground(gbg);
			gc.setBackground(getBackground());
			gc
					.fillGradientRectangle(marginWidth, marginHeight + midpoint
							- 1, bounds.width - 1 - marginWidth - marginWidth,
							rem - 1, true);
		} else if (isExpanded()) {
			gc.setForeground(bg);
			gc.setBackground(getBackground());
			gc.fillGradientRectangle(marginWidth, marginHeight, bounds.width
					- marginWidth - marginWidth, theight, true);
		}
		gc.setBackground(getBackground());
		// 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 - 1, marginHeight,
				bounds.width - marginWidth - 1, marginHeight + 2 });
		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 && toggle != null
				&& !isExpanded()) {
			// left vertical edge
			gc.drawLine(marginWidth, marginHeight + 2, marginWidth,
					marginHeight + theight - 1);
			// right vertical edge
			gc.drawLine(bounds.width - marginWidth - 1, marginHeight + 2,
					bounds.width - marginWidth - 1, marginHeight + theight - 1);
			// bottom edge (if closed)
			gc.drawLine(marginWidth, marginHeight + theight - 1, bounds.width
					- marginWidth - 1, marginHeight + theight - 1);
		} else if (isExpanded()) {
			// left vertical edge gradient
			gc.fillGradientRectangle(marginWidth, marginHeight + 2, 1,
					theight - 2, true);
			// right vertical edge gradient
			gc.fillGradientRectangle(bounds.width - marginWidth - 1,
					marginHeight + 2, 1, theight - 2, true);
		}
	}
}