/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.forms.widgets;
import java.util.Vector;

import org.eclipse.jface.util.Assert;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.forms.events.*;
import org.eclipse.ui.internal.forms.widgets.*;
/**
 * This composite is capable of expanding or collapsing a single client that is
 * its direct child. The composite renders an expansion toggle affordance
 * (according to the chosen style), and a title that also acts as a hyperlink
 * (can be selected and is traversable). The client is layed out below the
 * title when expanded, or hidden when collapsed.
 * <p>The widget can be instantiated as-is, or subclassed to
 * modify some aspects of it.
 * 
 * @see Section
 * @since 3.0
 */
public class ExpandableComposite extends Composite {
	/**
	 * If this style is used, a twistie will be used to render the expansion
	 * toggle.
	 */
	public static final int TWISTIE = 1 << 1;
	/**
	 * If this style is used, a tree node with either + or - signs will be used
	 * to render the expansion toggle.
	 */
	public static final int TREE_NODE = 1 << 2;
	/**
	 * If this style is used, the title text will be rendered as a hyperlink
	 * that can individually accept focus. Otherwise, it will still act like a
	 * hyperlink, but only the toggle control will accept focus.
	 */
	public static final int FOCUS_TITLE = 1 << 3;
	/**
	 * If this style is used, the client origin will be vertically aligned with
	 * the title text. Otherwise, it will start at x = 0.
	 */
	public static final int CLIENT_INDENT = 1 << 4;
	/**
	 * If this style is used, computed size of the composite will take the
	 * client width into consideration only in the expanded state. Otherwise,
	 * client width will always be taken into acount.
	 */
	public static final int COMPACT = 1 << 5;
	/**
	 * If this style is used, the control will be created in the expanded
	 * state. This state can later be changed programmatically or by the user
	 * if TWISTIE or TREE_NODE style is used.
	 */
	public static final int EXPANDED = 1 << 6;
	/**
	 * If this style is used, title bar decoration will be painted behind
	 * the text.
	 */
	public static final int TITLE_BAR = 1 << 8;
	/**
	 * If this style is used, title will not be rendered.
	 */
	public static final int NO_TITLE = 1<<12;
	/**
	 * Width of the margin that will be added around the control (default is
	 * 0).
	 */	
	public int marginWidth = 0;
	/**
	 * Height of the margin that will be added around the control (default is
	 * 0).
	 */
	public int marginHeight = 0;
	private int VSPACE = 3;
	public int clientVerticalSpacing = VSPACE;
	protected int GAP = 4;

	private int SEPARATOR_HEIGHT = 2;
	private int expansionStyle = TWISTIE | FOCUS_TITLE | EXPANDED;
	private boolean expanded;
	private Control textClient;
	private Control client;
	private Vector listeners;
	protected ToggleHyperlink toggle;
	protected Control textLabel;
	private class ExpandableLayout extends Layout implements ILayoutExtension {
		protected void layout(Composite parent, boolean changed) {
			Rectangle clientArea = parent.getClientArea();
			int thmargin = 0;
			int tvmargin = 0;
			
			if ((expansionStyle & TITLE_BAR)!=0) {
				thmargin = GAP;
				tvmargin = GAP;
			}
			int x = marginWidth + thmargin;
			int y = marginHeight + tvmargin;
			Point tsize = null;
			Point tcsize = null;
			if (toggle != null)
				tsize = toggle.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed);
			int twidth = clientArea.width - marginWidth - marginWidth - thmargin - thmargin;
			if (tsize != null)
				twidth -= tsize.x + GAP;
			if (textClient !=null)
				tcsize = textClient.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed);
			if (tcsize!=null)
				twidth -= tcsize.x + GAP;
			Point size = null;
			if (textLabel!=null)
				size = textLabel.computeSize(twidth, SWT.DEFAULT, changed);
			if (textLabel instanceof Label) {
				Point defSize = textLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT,
						changed);
				if (defSize.y == size.y) {
					// One line - pick the smaller of the two widths
					size.x = Math.min(defSize.x, size.x);
				}
			}
			if (toggle != null) {
				GC gc = new GC(ExpandableComposite.this);
				gc.setFont(getFont());
				FontMetrics fm = gc.getFontMetrics();
				int fontHeight = fm.getHeight();
				gc.dispose();
				int ty = fontHeight / 2 - tsize.y / 2 + 1;
				ty = Math.max(ty, 0);
				ty += marginHeight + tvmargin;
				toggle.setLocation(x, ty);
				toggle.setSize(tsize);
				x += tsize.x + GAP;
			}
			if (textLabel!=null)
				textLabel.setBounds(x, y, size.x, size.y);
			if (textClient!=null) {
				int tcx = clientArea.width - tcsize.x-thmargin;
				textClient.setBounds(tcx, y, tcsize.x, tcsize.y);
			}
			if (size!=null)
				y += size.y;
			if ((expansionStyle & TITLE_BAR) != 0) 
				y += tvmargin;
			if (getSeparatorControl() != null) {
				y += VSPACE;
				getSeparatorControl().setBounds(marginWidth, y,
						clientArea.width - marginWidth - marginWidth,
						SEPARATOR_HEIGHT);
				y += SEPARATOR_HEIGHT;
				if (expanded)
					y += VSPACE;
			}
			if (expanded) {
				int areaWidth = clientArea.width - marginWidth - marginWidth - thmargin-thmargin;
				int cx = marginWidth + thmargin;
				if ((expansionStyle & CLIENT_INDENT) != 0) {
					cx = x;
					areaWidth -= x;
				}
				if (client != null) {
					Point dsize = null;
					Control desc = getDescriptionControl();
					if (desc != null) {
						dsize = desc.computeSize(areaWidth, SWT.DEFAULT,
								changed);
						desc.setBounds(cx, y, dsize.x, dsize.y);
						y += dsize.y + clientVerticalSpacing;
					}
					else
						y += clientVerticalSpacing - VSPACE;
					//int cwidth = clientArea.width - marginWidth - marginWidth
							//- cx;
					int cwidth = areaWidth;
					int cheight = clientArea.height - marginHeight
							- marginHeight - y;
					client.setBounds(cx, y, cwidth, cheight);
				}
			}
		}
		protected Point computeSize(Composite parent, int wHint, int hHint,
				boolean changed) {
			int width = 0, height = 0;
			Point tsize = null;
			int twidth = 0;
			if (toggle != null) {
				tsize = toggle.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed);
				twidth = tsize.x + GAP;
			}
			int thmargin = 0;
			int tvmargin = 0;
			
			if ((expansionStyle & TITLE_BAR)!=0) {
				thmargin = GAP;
				tvmargin = GAP;
			}
			int innerwHint = wHint;
			if (innerwHint != SWT.DEFAULT)
				innerwHint -= twidth;
			
			int innertHint = innerwHint;
			
			Point tcsize = null;
			if (textClient!=null) {
				tcsize = textClient.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed);
				if (innertHint!=SWT.DEFAULT)
					innertHint -= GAP + tcsize.x;
			}
			Point size = null;
			
			if (textLabel!=null)
				size = textLabel.computeSize(innertHint, SWT.DEFAULT, changed);
			if (textLabel instanceof Label) {
				Point defSize = textLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT,
						changed);
				if (defSize.y == size.y) {
					// One line - pick the smaller of the two widths
					size.x = Math.min(defSize.x, size.x);
				}
			}
			if (size!=null)
				width = size.x;
			int sizey = size!=null?size.y:0;
			height = tcsize!=null?Math.max(tcsize.y, sizey):sizey;
			if (getSeparatorControl() != null) {
				height += VSPACE + SEPARATOR_HEIGHT;
				if (expanded && client != null)
					height += VSPACE;
			}
			if ((expansionStyle & TITLE_BAR) != 0) 
				height += VSPACE;
			if ((expanded || (expansionStyle & COMPACT) == 0) && client != null) {
				int cwHint = wHint;
				
				if (cwHint!=SWT.DEFAULT)
					cwHint -= tvmargin + tvmargin;
				if ((expansionStyle & CLIENT_INDENT) != 0)
					cwHint = innerwHint;
				Point dsize = null;
				Point csize = client.computeSize(FormUtil.getWidthHint(cwHint,
						client), SWT.DEFAULT, changed);
				if (getDescriptionControl() != null) {
					int dwHint = cwHint;
					if (dwHint == SWT.DEFAULT) {
						dwHint = csize.x - tvmargin - tvmargin;
						if ((expansionStyle & CLIENT_INDENT) != 0)
							dwHint -= twidth;
					}
					dsize = getDescriptionControl().computeSize(dwHint,
							SWT.DEFAULT, changed);
				}
				if (dsize != null) {
					if ((expansionStyle & CLIENT_INDENT) != 0)
						dsize.x -= twidth;
					width = Math.max(width, dsize.x);
					if (expanded)
						height += dsize.y + clientVerticalSpacing;
				}
				else
					height += clientVerticalSpacing - VSPACE;
				if ((expansionStyle & CLIENT_INDENT) != 0)
					csize.x -= twidth;
				width = Math.max(width, csize.x);
				if (expanded)
					height += csize.y;
			}
			if (toggle != null) {
				height = height - sizey + Math.max(sizey, tsize.y);
				width += twidth;
			}
			return new Point(width + marginWidth + marginWidth+thmargin+thmargin, height
					+ marginHeight + marginHeight+tvmargin+tvmargin);
		}
		public int computeMinimumWidth(Composite parent, boolean changed) {
			int width = 0;
			Point size = null;
			if (textLabel!=null)
				size = textLabel.computeSize(5, SWT.DEFAULT, changed);
			Point tcsize=null;
			if (textClient!=null) {
				tcsize = textClient.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed);
			}
			int thmargin = 0;
			int tvmargin = 0;
			
			if ((expansionStyle & TITLE_BAR)!=0) {
				thmargin = GAP;
				tvmargin = GAP;
			}			
			if (size!=null)
				width = size.x;
			if (tcsize!=null)
				width += GAP + tcsize.x;

			if ((expanded || (expansionStyle & COMPACT) == 0) && client != null) {
				Point dsize = null;
				if (getDescriptionControl() != null) {
					dsize = getDescriptionControl().computeSize(5, SWT.DEFAULT,
							changed);
					width = Math.max(width, dsize.x);
				}
				int cwidth = FormUtil.computeMinimumWidth(client, changed);
				width = Math.max(width, cwidth);
			}
			if (toggle != null) {
				Point tsize = toggle.computeSize(SWT.DEFAULT, SWT.DEFAULT,
						changed);
				width += tsize.x + GAP;
			}
			return width + marginWidth + marginWidth+thmargin+thmargin;
		}
		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.ui.forms.parts.ILayoutExtension#computeMinimumWidth(org.eclipse.swt.widgets.Composite,
		 *      boolean)
		 */
		public int computeMaximumWidth(Composite parent, boolean changed) {
			int width = 0;
			Point size = null;
			if (textLabel!=null)
				textLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT,
					changed);
			Point tcsize=null;
			int thmargin = 0;
			int tvmargin = 0;
			
			if ((expansionStyle & TITLE_BAR)!=0) {
				thmargin = GAP;
				tvmargin = GAP;
			}			
			if (textClient!=null) {
				tcsize = textClient.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed);
			}
			if (size!=null)
				width = size.x;
			if (tcsize!=null)
				width += GAP + tcsize.x;
			if ((expanded || (expansionStyle & COMPACT) == 0) && client != null) {
				Point dsize = null;
				if (getDescriptionControl() != null) {
					dsize = getDescriptionControl().computeSize(SWT.DEFAULT,
							SWT.DEFAULT, changed);
					width = Math.max(width, dsize.x);
				}
				int cwidth = FormUtil.computeMaximumWidth(client, changed);
				width = Math.max(width, cwidth);
			}
			if (toggle != null) {
				Point tsize = toggle.computeSize(SWT.DEFAULT, SWT.DEFAULT,
						changed);
				width += tsize.x + GAP;
			}
			return width + marginWidth + marginWidth+thmargin+thmargin;
		}
	}
	/**
	 * Creates an expandable composite using a TWISTIE toggle.
	 * 
	 * @param parent
	 *            the parent composite
	 * @param style
	 *            SWT style bits
	 */
	public ExpandableComposite(Composite parent, int style) {
		this(parent, style, TWISTIE);
	}
	/**
	 * Creates the expandable composite in the provided parent.
	 * 
	 * @param parent
	 *            the parent
	 * @param style
	 *            the control style
	 * @param expansionStyle
	 *            the style of the expansion widget (TREE_NODE, TWISTIE,
	 *            CLIENT_INDENT, COMPACT, FOCUS_TITLE)
	 */
	public ExpandableComposite(Composite parent, int style, int expansionStyle) {
		super(parent, style);
		this.expansionStyle = expansionStyle;
		super.setLayout(new ExpandableLayout());
		listeners = new Vector();
		if ((expansionStyle & TITLE_BAR) != 0) {
			this.addPaintListener(new PaintListener() {
				public void paintControl(PaintEvent e) {
					onPaint(e);
				}
			});
		}
		if ((expansionStyle & TWISTIE) != 0)
			toggle = new Twistie(this, SWT.NULL);
		else if ((expansionStyle & TREE_NODE) != 0)
			toggle = new TreeNode(this, SWT.NULL);
		else
			expanded = true;
		if ((expansionStyle & EXPANDED) != 0)
			expanded = true;
		if (toggle != null) {
			toggle.setExpanded(expanded);
			toggle.addHyperlinkListener(new HyperlinkAdapter() {
				public void linkActivated(HyperlinkEvent e) {
					toggleState();
				}
			});
		}
		if ((expansionStyle & FOCUS_TITLE) != 0) {
			Hyperlink link = new Hyperlink(this, SWT.WRAP);
			link.addHyperlinkListener(new HyperlinkAdapter() {
				public void linkActivated(HyperlinkEvent e) {
					toggle.setExpanded(!toggle.isExpanded());
					toggleState();
				}
			});
			textLabel = link;
		} else if ((expansionStyle & NO_TITLE) == 0) {
			final Label label = new Label(this, SWT.WRAP);
			if (!isFixedStyle()) {
				label.setCursor(FormsResources.getHandCursor());
				label.addListener(SWT.MouseDown, new Listener() {
					public void handleEvent(Event e) {
						if (toggle != null)
							toggle.setFocus();
					}
				});
				label.addListener(SWT.MouseUp, new Listener() {
					public void handleEvent(Event e) {
						label.setCursor(FormsResources.getBusyCursor());
						toggle.setExpanded(!toggle.isExpanded());
						toggleState();
						label.setCursor(FormsResources.getHandCursor());
					}
				});
			}
			textLabel = label;
		}
		if (textLabel!=null)
			textLabel.setMenu(getMenu());
	}
	/**
	 * Prevents assignment of the layout manager - expandable composite uses
	 * its own layout.
	 */
	public final void setLayout(Layout layout) {
	}
	/**
	 * Sets the background of all the custom controls in the expandable.
	 */
	public void setBackground(Color bg) {
		super.setBackground(bg);
		if (textLabel!=null)
			textLabel.setBackground(bg);
		if (toggle != null)
			toggle.setBackground(bg);
	}
	/**
	 * Sets the foreground of all the custom controls in the expandable.
	 */
	public void setForeground(Color fg) {
		super.setForeground(fg);
		if (textLabel!=null)
			textLabel.setForeground(fg);
		if (toggle != null)
			toggle.setForeground(fg);
	}
	/**
	 * Sets the color of the toggle control.
	 * 
	 * @param c
	 *            the color object
	 */
	public void setToggleColor(Color c) {
		if (toggle != null)
			toggle.setDecorationColor(c);
	}
	/**
	 * Sets the active color of the toggle control (when the mouse enters the
	 * toggle area).
	 * 
	 * @param c
	 *            the active color object
	 */
	public void setActiveToggleColor(Color c) {
		if (toggle != null)
			toggle.setHoverDecorationColor(c);
	}
	/**
	 * Sets the fonts of all the custom controls in the expandable.
	 */
	public void setFont(Font font) {
		super.setFont(font);
		if (textLabel!=null)
			textLabel.setFont(font);
		if (toggle != null)
			toggle.setFont(font);
	}
	/**
	 * Sets the client of this expandable composite. The client must not be
	 * <samp>null </samp> and must be a direct child of this container.
	 * 
	 * @param client
	 *            the client that will be expanded or collapsed
	 */
	public void setClient(Control client) {
		Assert.isTrue(client != null && client.getParent().equals(this));
		this.client = client;
	}
	/**
	 * Returns the current expandable client.
	 * 
	 * @return the client control
	 */
	public Control getClient() {
		return client;
	}
	/**
	 * Sets the title of the expandable composite. The title will act as a
	 * hyperlink and activating it will toggle the client between expanded and
	 * collapsed state.
	 * 
	 * @param title
	 *            the new title string
	 * @see #getTitle
	 */
	public void setText(String title) {
		if (textLabel instanceof Label)
			((Label) textLabel).setText(title);
		else if (textLabel instanceof Hyperlink)
			((Hyperlink) textLabel).setText(title);
	}
	/**
	 * Returns the title string.
	 * 
	 * @return the title string
	 * @see #setTitle
	 */
	public String getText() {
		if (textLabel instanceof Label)
			return ((Label) textLabel).getText();
		else if (textLabel instanceof Hyperlink)
			return ((Hyperlink) textLabel).getText();
		else
			return "";
	}
	/**
	 * Tests the expanded state of the composite.
	 * 
	 * @return <samp>true </samp> if expanded, <samp>false </samp> if
	 *         collapsed.
	 */
	public boolean isExpanded() {
		return expanded;
	}
	/**
	 * Returns the bitwise-ORed style bits for the expansion control.
	 * 
	 * @return
	 */
	public int getExpansionStyle() {
		return expansionStyle;
	}
	/**
	 * Programmatically changes expanded state.
	 * 
	 * @param expanded
	 *            the new expanded state
	 */
	public void setExpanded(boolean expanded) {
		internalSetExpanded(expanded);
		if (toggle != null)
			toggle.setExpanded(expanded);
	}
	/**
	 * Performs the expansion state change for the expandable control.
	 * 
	 * @param expanded
	 *            the expansion state
	 */
	protected void internalSetExpanded(boolean expanded) {
		if (this.expanded != expanded) {
			this.expanded = expanded;
			if (getDescriptionControl() != null)
				getDescriptionControl().setVisible(expanded);
			if (client != null)
				client.setVisible(expanded);
			layout();
		}
	}
	/**
	 * Adds the listener that will be notified when the expansion state
	 * changes.
	 * 
	 * @param listener
	 *            the listener to add
	 */
	public void addExpansionListener(IExpansionListener listener) {
		if (!listeners.contains(listener))
			listeners.add(listener);
	}
	/**
	 * Removes the expansion listener.
	 * 
	 * @param listener
	 *            the listner to remove
	 */
	public void removeExpansionListener(IExpansionListener listener) {
		if (listeners.contains(listener))
			listeners.remove(listener);
	}
	private void toggleState() {
		boolean newState = !isExpanded();
		fireExpanding(newState, true);
		internalSetExpanded(!isExpanded());
		fireExpanding(newState, false);
	}
/**
 * If TITLE_BAR style is used, title bar decoration will
 * be painted behind the text in this method. The default
 * implementation does nothing - subclasses are responsible
 * for rendering the title area.
 * @param e the paint event
 */
	protected void onPaint(PaintEvent e) {
	}
	private void fireExpanding(boolean state, boolean before) {
		int size = listeners.size();
		if (size == 0)
			return;
		ExpansionEvent e = new ExpansionEvent(this, state);
		for (int i = 0; i < size; i++) {
			IExpansionListener listener = (IExpansionListener) listeners.get(i);
			if (before)
				listener.expansionStateChanging(e);
			else
				listener.expansionStateChanged(e);
		}
	}
	/**
	 * Returns description control that will be placed under the title if
	 * present.
	 * 
	 * @return the description control or <samp>null </samp> if not used.
	 */
	protected Control getDescriptionControl() {
		return null;
	}
	/**
	 * Returns the separator control that will be placed between the title and
	 * the description if present.
	 * 
	 * @return the separator control or <samp>null </samp> if not used.
	 */
	protected Control getSeparatorControl() {
		return null;
	}
	/**
	 * Computes the size of the expandable composite.
	 * 
	 * @see org.eclipse.swt.widgets.Composite#computeSize
	 */
	public Point computeSize(int wHint, int hHint, boolean changed) {
		checkWidget();
		Point size;
		ExpandableLayout layout = (ExpandableLayout) getLayout();
		if (wHint == SWT.DEFAULT || hHint == SWT.DEFAULT) {
			size = layout.computeSize(this, wHint, hHint, changed);
		} else {
			size = new Point(wHint, hHint);
		}
		Rectangle trim = computeTrim(0, 0, size.x, size.y);
		return new Point(trim.width, trim.height);
	}
	/**
	 * Returns <samp>true </samp> if the composite is fixed i.e. cannot be
	 * expanded or collapsed. Fixed control will still contain the title,
	 * separator and description (if present) as well as the client, but will
	 * be in the permanent expanded state and the toggle affordance will not be
	 * shown.
	 * 
	 * @return <samp>true </samp> if the control is fixed in the expanded
	 *         state, <samp>false </samp> if it can be collapsed.
	 */
	protected boolean isFixedStyle() {
		return (expansionStyle & TWISTIE) == 0
				&& (expansionStyle & TREE_NODE) == 0;
	}
	/**
	 * Returns the text client control.
	 * @return Returns the text client control if specified, or <code>null</code> if
	 * not.
	 */
	public Control getTextClient() {
		return textClient;
	}
	/**
	 * Sets the text client control. Text client is a control that 
	 * is a child of the expandable composite and is placed to the right
	 * of the text. It can be used to place small image hyperlinks. If
	 * more than one control is needed, use Composite to hold them. Care should
	 * be taken that the height of the control is comparable to the
	 * height of the text.
	 * @param textClient the textClient to set or <code>null</code> if not
	 * needed any more.
	 */
	public void setTextClient(Control textClient) {
		if (this.textClient!=null)
			this.textClient.dispose();
		this.textClient = textClient;
	}
}