/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.common.ui.internal.guiutils;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.custom.TableTree;
import org.eclipse.swt.custom.TableTreeEditor;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;

/**
 * This utility class provides convenience methods in creating controls on
 * preference pages.
 * 
 * @author mengbo
 */
public class SWTUtils {
	// Defaults of controls
	public static final int DEFAULT_BUTTON_WIDTH = 70;

	public static final int DEFAULT_COMBO_WIDTH = 100;

	public static final int DEFAULT_TEXTBOX_WIDTH = 100;

	public static final int DEFAULT_RADIO_FILL = GridData.HORIZONTAL_ALIGN_BEGINNING
			| GridData.VERTICAL_ALIGN_CENTER;

	/**
	 * Creates a new checkbox and sets the default layout data.
	 * 
	 * @param parent
	 *            the composite in which to create the checkbox
	 * @param label
	 *            the string to set into the checkbox
	 * @param numColumns
	 *            the number of columns the new checkbox is to occupy
	 * @return the new checkbox
	 */
	public static Button createCheckBox(Composite parent) {
		return createCheckBox(parent, null, 1, 0);
	}

	/**
	 * Creates a new checkbox and sets the default layout data.
	 * 
	 * @param parent
	 *            the composite in which to create the checkbox
	 * @param label
	 *            the string to set into the checkbox
	 * @param numColumns
	 *            the number of columns the new checkbox is to occupy
	 * @return the new checkbox
	 */
	public static Button createCheckBox(Composite parent, String label,
			int numColumns) {
		return createCheckBox(parent, label, numColumns, 0);
	}

	/**
	 * Creates a new checkbox and sets the default layout data.
	 * 
	 * @param parent
	 *            the composite in which to create the checkbox
	 * @param label
	 *            the string to set into the checkbox
	 * @param numColumns
	 *            the number of columns the new checkbox is to occupy
	 * @param indent
	 *            the number of pixels to indent from the left
	 * @return the new checkbox
	 */
	public static Button createCheckBox(Composite parent, String label,
			int numColumns, int indent) {
		Button button = new Button(parent, SWT.CHECK | SWT.LEFT);
		if (label == null) {
			button.setAlignment(SWT.CENTER);
		}
		GridData data = new GridData(GridData.FILL);
		data.horizontalSpan = numColumns;
		data.horizontalIndent = indent;
		button.setLayoutData(data);
		if (label != null) {
			button.setText(label);
		}
		return button;
	}

	/**
	 * Creates a combo box and sets the default layout data.
	 * 
	 * @param parent
	 *            the composite in which to create the combo
	 * @param items
	 *            the items in the combo
	 * @param numColumns
	 *            the number of columns the new combo is to occupy
	 * @return the new combo box
	 */
	public static Combo createCombo(Composite parent, String[] items,
			int numColumns) {
		return createCombo(parent, items, numColumns, DEFAULT_COMBO_WIDTH);
	}

	/**
	 * Creates a combo box and sets the default layout data.
	 * 
	 * @param parent
	 *            the composite in which to create the combo
	 * @param tokenString
	 *            a tokenized string that will be split into the fields.
	 * @param numColumns
	 *            the number of columns the new combo is to occupy
	 * @return the new combo box
	 */
	public static Combo createCombo(Composite parent, String tokenString,
			int numColumns) {
		return createCombo(parent, getTokenNames(tokenString), numColumns,
				DEFAULT_COMBO_WIDTH);
	}

	/**
	 * Creates a combo box and sets the default layout data.
	 * 
	 * @param parent
	 *            the composite in which to create the combo
	 * @param tokenString
	 *            a tokenized string that will be split into the fields.
	 * @param numColumns
	 *            the number of columns the new combo is to occupy
	 * @param minWidth
	 *            minimum width of combo box in pixels
	 * @return the new combo box
	 */
	public static Combo createCombo(Composite parent, String tokenString,
			int numColumns, int minWidth) {
		return createCombo(parent, getTokenNames(tokenString), numColumns,
				minWidth);
	}

	/**
	 * Creates a combo box and sets the default layout data.
	 * 
	 * @param parent
	 *            the composite in which to create the combo
	 * @param items
	 *            the items in the combo
	 * @param numColumns
	 *            the number of columns the new combo is to occupy
	 * @param minWidth
	 *            minimum width of combo box in pixels
	 * @return the new combo box
	 */
	public static Combo createCombo(Composite parent, String[] items,
			int numColumns, int minWidth) {
		return createCombo(parent, items, numColumns, minWidth, false);
	}

	/**
	 * Creates a combo box and sets the default layout data.
	 * 
	 * @param parent
	 *            the composite in which to create the combo
	 * @param items
	 *            the items in the combo
	 * @param numColumns
	 *            the number of columns the new combo is to occupy
	 * @param minWidth
	 *            minimum width of combo box in pixels
	 * @param editable
	 *            whether the items in the combo is editable
	 * @return the new combo box
	 */
	public static Combo createCombo(Composite parent, String tokenString,
			int numColumns, int minWidth, boolean editable) {
		return createCombo(parent, getTokenNames(tokenString), numColumns,
				minWidth, editable);
	}

	/**
	 * Creates a combo box and sets the default layout data.
	 * 
	 * @param parent
	 *            the composite in which to create the combo
	 * @param items
	 *            the items in the combo
	 * @param numColumns
	 *            the number of columns the new combo is to occupy
	 * @param minWidth
	 *            minimum width of combo box in pixels
	 * @param editable
	 *            whether the items in the combo is editable
	 * @return the new combo box
	 */
	public static Combo createCombo(Composite parent, String[] items,
			int numColumns, int minWidth, boolean editable) {
		Combo combo;
		GridData data;
		if (editable) {
			combo = new Combo(parent, SWT.DROP_DOWN);
			data = new GridData(GridData.FILL_HORIZONTAL);
		} else {
			combo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
			data = new GridData(GridData.FILL);
		}
		data.horizontalSpan = numColumns;
		data.widthHint = minWidth;
		combo.setLayoutData(data);
		combo.setItems(items);
		return combo;
	}

	/**
	 * Creates composite control and sets the default layout data.
	 * 
	 * @param parent
	 *            the parent of the new composite
	 * @param numColumns
	 *            the number of columns for the new composite
	 * @return the newly-created coposite
	 */
	public static Composite createComposite(Composite parent, int numColumns) {
		return createComposite(parent, numColumns, -1, -1,
				GridData.FILL_HORIZONTAL, -1, -1, -1);
	}

	/**
	 * Creates composite control and sets the default layout data.
	 * 
	 * @param parent
	 *            the parent of the new composite
	 * @param numColumns
	 *            the number of columns for the new composite
	 * @param verticalSpacing
	 *            the spacing between rows.
	 * @param horizontalSpan
	 *            the span for this new composite over the original composite.
	 * @return the newly-created coposite
	 */
	public static Composite createComposite(Composite parent, int numColumns,
			int verticalSpacing, int horizontalSpan) {
		return createComposite(parent, numColumns, verticalSpacing,
				horizontalSpan, GridData.FILL_HORIZONTAL, -1, -1, -1);
	}

	/**
	 * Creates composite control and sets the default layout data.
	 * 
	 * @param parent
	 *            the parent of the new composite
	 * @param numColumns
	 *            the number of columns for the new composite
	 * @param verticalSpacing
	 *            the spacing between rows.
	 * @param horizontalSpan
	 *            the span for this new composite over the original composite.
	 * @param gridDataFill
	 *            the fill to use for this composite.
	 * @return the newly-created coposite
	 */
	public static Composite createComposite(Composite parent, int numColumns,
			int verticalSpacing, int horizontalSpan, int gridDataFill) {
		return createComposite(parent, numColumns, verticalSpacing,
				horizontalSpan, gridDataFill, -1, -1, -1);
	}

	/**
	 * Creates composite control and sets the default layout data.
	 * 
	 * @param parent
	 *            the parent of the new composite
	 * @param numColumns
	 *            the number of columns for the new composite
	 * @param verticalSpacing
	 *            the spacing between rows.
	 * @param horizontalSpan
	 *            the span for this new composite over the original composite.
	 * @param gridDataFill
	 *            the fill to use for this composite.
	 * @param horizontalSpacing
	 *            the spacing between objects.
	 * @param marginWidth
	 *            the spacing at start and end of composite.
	 * @param marginHeight
	 *            the spacing above and below composite.
	 * @return the newly-created coposite
	 */
	public static Composite createComposite(Composite parent, int numColumns,
			int verticalSpacing, int horizontalSpan, int gridDataFill,
			int horizontalSpacing, int marginWidth, int marginHeight) {
		Composite composite = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.numColumns = numColumns;
		if (verticalSpacing >= 0) {
			layout.verticalSpacing = verticalSpacing;
		}
		if (horizontalSpacing >= 0) {
			layout.horizontalSpacing = horizontalSpacing;
		}
		if (marginWidth >= 0) {
			layout.marginWidth = marginWidth;
		}
		if (marginHeight >= 0) {
			layout.marginHeight = marginHeight;
		}
		composite.setLayout(layout);
		GridData gd = new GridData(gridDataFill);
		if (horizontalSpan > 0) {
			gd.horizontalSpan = horizontalSpan;
		}
		composite.setLayoutData(gd);

		return composite;
	}

	/**
	 * Utility method that creates a group and sets the default layout data.
	 * 
	 * @param parent
	 *            the parent for the new group
	 * @param title
	 *            the label for the new group
	 * @param numColumns
	 *            the number of columns for the new group
	 * @return the newly created group
	 */
	public static Group createGroup(Composite parent, String title,
			int numColumns) {
		return createGroup(parent, title, numColumns, -1,
				GridData.FILL_HORIZONTAL);
	}

	/**
	 * Utility method that creates a group and sets the default layout data.
	 * 
	 * @param parent
	 *            the parent for the new group
	 * @param title
	 *            the label for the new group
	 * @param numColumns
	 *            the number of columns for the new group
	 * @param horizontalSpan
	 *            the number of columns this group should span on the parent
	 *            composite.
	 * @param fill
	 *            the fill style of the new group -- set to for filling just
	 *            around the object: GridData.BEGINNING | GridData.CENTER
	 * @return the newly created group
	 */
	public static Group createGroup(Composite parent, String title,
			int numColumns, int horizontalSpan, int gridDataFill) {
		Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
		GridLayout layout = new GridLayout();
		layout.numColumns = numColumns;
		group.setLayout(layout);
		GridData data = new GridData(gridDataFill);

		if (horizontalSpan > 0) {
			data.horizontalSpan = horizontalSpan;
		}
		group.setLayoutData(data);
		group.setText(title);
		return group;
	}

	/**
	 * Utility method that creates a label instance and sets the default layout
	 * data.
	 * 
	 * @param parent
	 *            the parent for the new label
	 * @param text
	 *            the text for the new label
	 * @param numColumns
	 *            the number of columns for the new composite
	 * @return the new label
	 */
	public static Label createLabel(Composite parent, String text,
			int numColumns) {
		return createLabel(parent, text, numColumns, 0);
	}

	/**
	 * Utility method that creates a label instance and sets the default layout
	 * data.
	 * 
	 * @param parent
	 *            the parent for the new label
	 * @param text
	 *            the text for the new label
	 * @param numColumns
	 *            the number of columns for the new composite
	 * @param indent
	 *            number of pixels to indent from the left
	 * @return the new label
	 */
	public static Label createLabel(Composite parent, String text,
			int numColumns, int indent) {
		Label label = new Label(parent, SWT.LEFT);
		GridData data = new GridData();
		data.horizontalSpan = numColumns;
		data.horizontalAlignment = GridData.FILL;
		data.horizontalIndent = indent;
		label.setLayoutData(data);
		label.setText(text);
		return label;
	}

	/**
	 * Create a image label for sticking in a composite. The backgroud color is
	 * optional. Because images can have "transparent" natures, you might want
	 * to say the background is something other than the defaults composites
	 * background.
	 * 
	 * NOTE: the caller is responsible for cleanup of the image and color
	 * objects.
	 * 
	 * @param parent
	 *            the parent for the new label
	 * @param theImage
	 *            the image for the new label
	 * @param numColumns
	 *            the number of columns for the new composite
	 * @param background
	 *            pass null to use the composites background.
	 * @return the new label
	 */
	public static Label createLabelImage(Composite parent, Image theImage,
			int numColumns, Color background) {
		Label label = new Label(parent, SWT.LEFT);
		GridData data = new GridData();
		data.horizontalSpan = numColumns;
		data.horizontalAlignment = GridData.FILL;
		label.setLayoutData(data);
		if (background != null) {
			label.setBackground(background);
		}
		label.setImage(theImage);
		return label;
	}

	/**
	 * Utility method that creates a push button instance and sets the default
	 * layout data.
	 * 
	 * @param parent
	 *            the parent for the new button
	 * @param label
	 *            the label for the new button
	 * @return the newly-created button
	 */
	public static Button createPushButton(Composite parent, String label) {
		return createPushButton(parent, label, DEFAULT_BUTTON_WIDTH);
	}

	/**
	 * Utility method that creates a push button instance and sets the default
	 * layout data.
	 * 
	 * @param parent
	 *            the parent for the new button
	 * @param label
	 *            the label for the new button
	 * @param widthHint
	 *            use this width for the button.
	 * @return the newly-created button
	 */
	public static Button createPushButton(Composite parent, String label,
			int widthHint) {
		Button button = new Button(parent, SWT.PUSH);
		GridData data = new GridData();
		data.horizontalAlignment = GridData.FILL_HORIZONTAL;
		data.widthHint = widthHint;
		button.setLayoutData(data);
		button.setText(label);
		return button;
	}

	/**
	 * Utility method that creates a push button instance and sets the default
	 * layout data.
	 * 
	 * @param parent
	 *            the parent for the new button
	 * @param label
	 *            the label for the new button
	 * @param widthHint
	 *            use this width for the button.
	 * @return the newly-created button
	 */
	public static Button createPushButton(Composite parent, Image theImage,
			int widthHint) {
		Button button = new Button(parent, SWT.PUSH);
		GridData data = new GridData();
		data.horizontalAlignment = GridData.FILL_HORIZONTAL;
		data.widthHint = widthHint;
		button.setLayoutData(data);
		button.setImage(theImage);
		button.setAlignment(SWT.CENTER);
		return button;
	}

	/**
	 * Utility method that creates a radio button instance and sets the default
	 * layout data.
	 * 
	 * @param parent
	 *            the parent for the new button
	 * @param label
	 *            the label for the new button
	 * @return the newly-created button
	 */
	public static Button createRadioButton(Composite parent, String label) {
		return createRadioButton(parent, label, DEFAULT_RADIO_FILL);
	}

	/**
	 * Utility method that creates a radio button instance and sets the default
	 * layout data.
	 * 
	 * @param parent
	 *            the parent for the new button
	 * @param label
	 *            the label for the new button
	 * @return the newly-created button
	 */
	public static Button createRadioButton(Composite parent, String label,
			int gridDataFill) {
		return createRadioButton(parent, label, gridDataFill, 1);
	}

	/**
	 * Utility method that creates a radio button instance and sets the default
	 * layout data.
	 * 
	 * @param parent
	 *            the parent for the new button
	 * @param label
	 *            the label for the new button
	 * @param horizontalSpan
	 *            number of columns occupied by button
	 * @return the newly-created button
	 */
	public static Button createRadioButton(Composite parent, String label,
			int gridDataFill, int horizontalSpan) {
		Button button = new Button(parent, SWT.RADIO | SWT.LEFT);
		GridData data = new GridData(gridDataFill);
		data.horizontalSpan = horizontalSpan;
		button.setLayoutData(data);
		button.setText(label);
		return button;
	}

	/**
	 * Utility method that creates an empty line
	 * 
	 * @param parent
	 *            the parent for the new label
	 * @param numColumns
	 *            the number of columns for the new composite
	 */
	public static void createSpacer(Composite parent, int numColumns) {
		createSpacer(parent, numColumns, 0);
	}

	/**
	 * Utility method that creates an empty line
	 * 
	 * @param parent
	 *            the parent for the new label
	 * @param numColumns
	 *            the number of columns for the new composite
	 * @param int
	 *            minimum width of spacer
	 */
	public static void createSpacer(Composite parent, int numColumns,
			int minWidth) {
		Label label = new Label(parent, SWT.NONE);
		GridData data = new GridData();
		data.horizontalSpan = numColumns;
		data.widthHint = minWidth;
		label.setLayoutData(data);
	}

	/**
	 * Create a separator that goes across the entire page
	 * 
	 * @param parent
	 *            the parent for the new label
	 * @param numColumns
	 *            the number of columns for the new composite
	 */
	public static void createSeparator(Composite parent, int numColumns) {
		Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
		GridData data = new GridData();
		data.horizontalSpan = numColumns;
		data.horizontalAlignment = GridData.FILL;
		data.grabExcessHorizontalSpace = true;
		separator.setLayoutData(data);
	}

	/**
	 * Create a table from a TableTree object
	 * 
	 * @param tableTree
	 *            the TableTree this table is to be created from
	 * @param columns
	 *            A string array containing names of the columns in the order
	 *            that they should be displayed in the table, or null if no
	 *            columns need to be created.
	 * @return the new table
	 */
	public static Table createTable(TableTree tableTree, String[] columns) {
		Table table = tableTree.getTable();
		table.setLayoutData(tableTree.getLayoutData());
		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		if (columns != null) {
			for (int i = 0; i < columns.length; i++) {
				/*(void)*/ createTableColumn(table, columns[i], i);
			}
		}

		return table;
	}

	/**
	 * Create a table from a Composite object
	 * 
	 * @param composite
	 *            the Composite this table is to be created from
	 * @param tokenString
	 *            A string containing names of the columns in the order that
	 *            they should be displayed in the table with each column
	 *            separated by a comma(',') or null if no columns need to be
	 *            created.
	 * @param tablewidth
	 *            the minimum width for the table
	 * @return the new table
	 */
	public static Table createTable(Composite composite, String tokenString,
			int tablewidth, int tableHeight) {
		// SINGLE, MULTI, CHECK, FULL_SELECTION, HIDE_SELECTION
		int style = SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE | SWT.BORDER
				| SWT.FULL_SELECTION;
		Table table = new Table(composite, style);
		GridData gridData = new GridData(GridData.FILL_BOTH);
		if (tablewidth > 0) {
			gridData.widthHint = tablewidth;
		}
		if (tableHeight > 0) {
			gridData.heightHint = tableHeight;
		}
		table.setLayoutData(gridData);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		if (tokenString != null) {
			String[] columns = getTokenNames(tokenString);

			int columnSize = 50;
			if (tablewidth > 0) {
				columnSize = tablewidth / columns.length;
			}
			for (int ii = 0; ii < columns.length; ii++) {
				/*(void)*/ createTableColumn(table, columns[ii], ii,
						columnSize);
			}
		}

		return table;
	}

	/**
	 * Create a table from a Composite object
	 * 
	 * @param composite
	 *            the Composite this table is to be created from
	 * @param columns
	 *            A string array containing names of the columns in the order
	 *            that they should be displayed in the table, or null if no
	 *            columns need to be created.
	 * @param tablewidth
	 *            the minimum width for the table
	 * @return the new table
	 */
	public static Table createTable(Composite composite, String[] columns,
			int tablewidth) {
		int style = SWT.BORDER | SWT.FULL_SELECTION;
		Table table = new Table(composite, style);
		GridData gridData = new GridData(GridData.FILL_BOTH);
		gridData.widthHint = tablewidth;
		table.setLayoutData(gridData);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		if (columns != null) {
			for (int i = 0; i < columns.length; i++) {
				/*(void)*/ createTableColumn(table, columns[i], i);
			}
		}

		return table;
	}

	/**
	 * Create a table column
	 * 
	 * @param parent
	 *            the table that contains this column
	 * @param name
	 *            name of this column
	 * @param index
	 *            the column within the parent composite
	 * @return the new table column
	 */
	public static TableColumn createTableColumn(Table parent, String name,
			int index) {
		TableColumn column = new TableColumn(parent, SWT.LEFT, index);
		column.setText(name);
		return column;
	}

	/**
	 * Create a table column with the image and the width of the column is set
	 * to the image width.
	 * 
	 * @param parent
	 *            the table that contains this column
	 * @param image
	 *            iamge for this column
	 * @return the new table column
	 */
	public static TableColumn createTableColumn(Table parent, Image image,
			int index) {
		TableColumn column = new TableColumn(parent, SWT.LEFT, index);
		column.setImage(image);
		column.setWidth(image.getBounds().width);
		column.setResizable(false);
		return column;
	}

	/**
	 * Create a table column
	 * 
	 * @param parent
	 *            the table that contains this column
	 * @param name
	 *            name of this column
	 * @param index
	 *            the column within the parent composite
	 * @param tablewidth
	 *            the width for the column
	 * @return the new table column
	 */
	public static TableColumn createTableColumn(Table parent, String name,
			int index, int tablewidth) {
		TableColumn column = new TableColumn(parent, SWT.LEFT, index);
		column.setText(name);
		column.setWidth(tablewidth);
		return column;
	}

	/**
	 * Create a TableTree object
	 * 
	 * @param parent
	 *            the composite that contains the TableTree
	 * @return the new TableTree object
	 */
	public static TableTree createTableTree(Composite parent) {
		int style = SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL
				| SWT.FULL_SELECTION | SWT.HIDE_SELECTION;
		TableTree tableTree = new TableTree(parent, style);
		GridData gridData = new GridData(GridData.FILL_BOTH);
		gridData.grabExcessVerticalSpace = true;
		gridData.grabExcessHorizontalSpace = true;
		tableTree.setLayoutData(gridData);
		return tableTree;
	}

	/**
	 * Create a TableTreeEditor object
	 * 
	 * @param tableTree
	 *            the TableTree that this editor is for
	 * @return the new TableTreeEditor object
	 */
	public static TableTreeEditor createTableTreeEditor(TableTree tableTree) {
		TableTreeEditor editor = new TableTreeEditor(tableTree);
		editor.horizontalAlignment = SWT.LEFT;
		editor.grabHorizontal = true;
		editor.minimumWidth = 50;
		return editor;
	}

	/**
	 * Create a text field
	 * 
	 * @param parent
	 *            the parent of the new text field
	 * @return the new text field
	 */
	public static Text createTextBox(Composite parent) {
		return createTextBox(parent, 1, DEFAULT_TEXTBOX_WIDTH);
	}

	/**
	 * Create a text field
	 * 
	 * @param parent
	 *            the parent of the new text field
	 * @return the new text field
	 */
	public static Text createTextBox(Composite parent, String text) {
		Text textbox = createTextBox(parent, 1);
		textbox.setText(text);
		return textbox;
	}

	/**
	 * Create a text field
	 * 
	 * @param parent
	 *            the parent of the new text field
	 * @param numColumns
	 *            number of columns the text box is to occupy
	 * @return the new text field
	 */
	public static Text createTextBox(Composite parent, int numColumns) {
		return createTextBox(parent, numColumns, DEFAULT_TEXTBOX_WIDTH);
	}

	/**
	 * Create a text field
	 * 
	 * @param parent
	 *            the parent of the new text field
	 * @param numColumns
	 *            number of columns the text box is to occupy
	 * @param minWidth
	 *            minimum width of text field
	 * @return the new text field
	 */
	public static Text createTextBox(Composite parent, int numColumns,
			int minWidth) {
		return createTextBox(parent, numColumns, minWidth, SWT.DEFAULT);
	}

	/**
	 * Create a text field
	 * 
	 * @param parent
	 *            the parent of the new text field
	 * @param numColumns
	 *            number of columns the text box is to occupy
	 * @param minWidth
	 *            minimum width of text field
	 * @return the new text field
	 */
	public static Text createTextBox(Composite parent, int numColumns,
			int minWidth, int minHeight) {
		Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);
		GridData data = new GridData(GridData.FILL);
		data.horizontalSpan = numColumns;
		data.widthHint = minWidth;
		data.heightHint = minHeight;
		text.setLayoutData(data);
		return text;
	}

	/**
	 * Create a text field that is scrollable.
	 * 
	 * @param parent
	 *            the parent of the new text field
	 * @param numColumns
	 *            number of columns the text box is to occupy
	 * @param minWidth
	 *            minimum width of text field
	 * @param minHeight
	 *            minimum height of text field
	 * @return the new text field
	 */
	public static Text createTextBoxScrollable(Composite parent,
			int numColumns, int minWidth, int minHeight) {
		Text text = new Text(parent, SWT.BORDER | SWT.V_SCROLL | SWT.WRAP);
		GridData data = new GridData((minWidth > 0) ? GridData.FILL
				: GridData.FILL_HORIZONTAL);
		data.horizontalSpan = numColumns;
		if (minWidth > 0) {
			data.widthHint = minWidth;
		}
		data.heightHint = minHeight;

		text.setLayoutData(data);
		return text;
	}

	/**
	 * Create a list with the items listed in it.
	 * 
	 * @param parent
	 *            the parent of the new text field
	 * @param numColumns
	 *            number of columns the text box is to occupy
	 * @param minWidth
	 *            minimum width of text field
	 * @param minHeight
	 *            minimum height of text field
	 * @param items
	 *            the items in the list
	 * @return the new list
	 */
	public static List createList(Composite parent, int numColumns,
			int minWidth, int minHeight, String[] items) {
		return createList(parent, numColumns, minWidth, minHeight, items, true);
	}

	/**
	 * Create a list with the items listed in it.
	 * 
	 * @param parent
	 *            the parent of the new list box
	 * @param numColumns
	 *            number of columns the list box is to occupy
	 * @param minWidth
	 *            minimum width of list box
	 * @param minHeight
	 *            minimum height of list box
	 * @param items
	 *            the items in the list
	 * @param bmulti
	 *            whether multiple item selection is allowed
	 * @param verticalSpan
	 *            the number of rows the list box is to occupy
	 * @return the new list
	 */
	public static List createList(Composite parent, int numColumns,
			int minWidth, int minHeight, String[] items, boolean bmulti) {
		return createList(parent, numColumns, minWidth, minHeight, items,
				bmulti, 1);
	}

	/**
	 * Create a list with the items listed in it.
	 * 
	 * @param parent
	 *            the parent of the new list box
	 * @param numColumns
	 *            number of columns the list box is to occupy
	 * @param minWidth
	 *            minimum width of list box
	 * @param minHeight
	 *            minimum height of list box
	 * @param items
	 *            the items in the list
	 * @param bmulti
	 *            whether multiple item selection is allowed
	 * @param verticalSpan
	 *            the number of rows the list box is to occupy
	 * @return the new list
	 */
	public static List createList(Composite parent, int numColumns,
			int minWidth, int minHeight, String[] items, boolean bmulti,
			int verticalSpan) {
		List theList;
		if (bmulti)
			theList = new List(parent, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI
					| SWT.BORDER);
		else
			theList = new List(parent, SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE
					| SWT.BORDER);
		GridData data = new GridData(GridData.FILL_HORIZONTAL
				| GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_VERTICAL);
		data.horizontalSpan = numColumns;
		data.widthHint = minWidth;
		data.heightHint = minHeight;
		data.verticalSpan = verticalSpan;
		theList.setLayoutData(data);
		if (items != null) {
			theList.setItems(items);
		}

		return theList;
	}

	/**
	 * Computes the size of the composite inside the scroll area so that scroll
	 * bars show up correctly.
	 * 
	 * @param parentComposite
	 * @param childComposite
	 */
	public static void computeScrollArea(ScrolledComposite parentComposite,
			Composite childComposite) {
		// Point pt = childComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
		// childComposite.setSize(pt);

		Point pt = childComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
		parentComposite.setExpandHorizontal(true);
		parentComposite.setExpandVertical(true);
		parentComposite.setMinWidth(pt.x);
		parentComposite.setMinHeight(pt.y);
	}

	/**
	 * Builds an array of strings from a token list string. The token separator
	 * is a comma (',').
	 * 
	 * @param tokenString
	 * @return String[]
	 */
	public static String[] getTokenNames(String tokenString) {
		if (tokenString == null) {
			return new String[0];
		}

		return tokenString.split(",");
	}

	/**
	 * Enable/Disable the widget and all its children.
	 * 
	 * @param widget
	 *            The widget to be enabled/disabled.
	 * @param state
	 *            Enable widget if true. Disable otherwise.
	 */
	public static void setWidgetState(Control widget, boolean state) {
		if (widget instanceof Composite) {
			Control widgets[] = ((Composite) widget).getChildren();
			for (int i = 0; i < widgets.length; i++) {
				setWidgetState(widgets[i], state);
			}
		}
		widget.setEnabled(state);
	}

	// ---------------------------------------------------------------------------
	// following is for workaround eclipse problem
	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=40281
	static ControlListener _listener = new ControlListener() {
		public void controlResized(ControlEvent e) {
			final Composite c = (Composite) e.widget;
			c.getDisplay().asyncExec(new Runnable() {
				public void run() {
					if (!c.isDisposed()) {
						// XXX: in 3.0, should use c.layout(true)
						// in 3.1, should use c.layout(true, true)
						c.layout(true);
						c.redraw();
					}
				}
			});
		}

		public void controlMoved(ControlEvent e) {
		}
	};

	public static void workaroundResize(Composite composite) {
		composite.addControlListener(_listener);
	}
}
