/*******************************************************************************
 * 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.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.Label;
import org.eclipse.swt.widgets.Listener;

/**
 * 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|getBackgroundStyle(style), style);
		int rtl = cstyle & SWT.RIGHT_TO_LEFT;
		if ((style & DESCRIPTION) != 0) {
			descriptionControl = new Label(this, SWT.WRAP | rtl);
		}
		if ((style & TITLE_BAR) != 0) {
			addListener(SWT.Resize, new Listener() {
				public void handleEvent(Event e) {
					Image image = Section.super.getBackgroundImage();
					if (image != null)
						image.dispose();
					Section.super.setBackgroundImage(null);
				}
			});
		}
	}
	
	private static int getBackgroundStyle(int estyle) {
		return ((estyle & TITLE_BAR)!=0)?SWT.NO_BACKGROUND:SWT.NULL;
	}

	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;

		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);
			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;
		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;

		if ((getExpansionStyle() & TITLE_BAR) != 0) {
			if (getBackgroundImage() == null)
				updateHeaderImage(bg, gbg, bounds, theight, midpoint, rem);
			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);
			}
			/*
			 * 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);
		}
		if (buffer != null) {
			// e.gc.drawImage(buffer, bounds.x, bounds.y);
			e.gc.drawImage(buffer, 0, 0);
			gc.dispose();
			buffer.dispose();
		}
	}

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

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