//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.authoring.ui.forms;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.epf.authoring.ui.AuthoringUIImages;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.AuthoringUIText;
import org.eclipse.epf.authoring.ui.editors.MethodElementEditorInput;
import org.eclipse.epf.authoring.ui.richtext.IMethodRichText;
import org.eclipse.epf.authoring.ui.richtext.IMethodRichTextEditor;
import org.eclipse.epf.library.util.ResourceHelper;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodUnit;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
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.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ImageHyperlink;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;


/**
 * The base class for all Method editor form pages.
 * 
 * @author Jeff Hardy
 * @author Kelvin Low
 * @author Shashidhar Kannoori
 * @since 1.0
 * fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=176382
 */
public class BaseFormPage extends FormPage {

	/**
	 * Button types.
	 */
	public static final int ADD_BUTTON = 0;

	public static final int REMOVE_BUTTON = 1;

	public static final int UP_BUTTON = 2;

	public static final int DOWN_BUTTON = 3;

	protected static final int ORDER_BUTTON = 4;

	protected static final int SELECT_BUTTON = 5;

	protected static final int CLEAR_BUTTON = 6;

	protected static final int ATTACH_BUTTON = 7;

	protected static final int DETACH_BUTTON = 8;
	
	protected static final int ATTACH_URL_BUTTON = 9;
	
	/**
	 * Table types.
	 */
	public static final int SMALL_SIZE = 0;

	public static final int MEDIUM_SIZE = 1;

	public static final int LARGE_SIZE = 2;

	public static final int SINGLE_ROW = 3;

	protected boolean debug;

	protected ScrolledForm form;

	protected FormToolkit toolkit;

	protected String editorTabName;

	protected String editorName;

	protected MethodUnit methodUnit;
	
	protected MethodElement methodElement;

	protected ContentElement contentElement = null;

	protected String contentElementPath;

	private int SECTION_ID;

	public static String LABEL_DECORATOR_KEY = "labelControlDecoration"; //$NON-NLS-1$
	
	/**
	 * Creates a new instance.
	 * 
	 * @param editor
	 *            The parent form editor.
	 * @param id
	 *            The unique ID for the form page.
	 * @param title
	 *            The title for the form page.
	 */
	public BaseFormPage(FormEditor editor, String id, String title) {
		super(editor, id, title);
		debug = AuthoringUIPlugin.getDefault().isDebugging();
	}

	/**
	 * @see org.eclipse.ui.forms.editor.FormPage#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
	 */
	public void init(IEditorSite site, IEditorInput input) {
		setSite(site);
		setInput(input);

		// Retrieve the ContentElement object from the editor input.
		MethodElementEditorInput methodElementInput = (MethodElementEditorInput) input;
		methodElement = methodElementInput.getMethodElement();
		MethodElement elementOfPath =  methodElement instanceof ProcessComponent ?
				((ProcessComponent) methodElement).getProcess() : methodElement;
		contentElementPath = ResourceHelper.getFolderAbsolutePath(elementOfPath);
		if (methodElement instanceof MethodUnit) {
			methodUnit = (MethodUnit)methodElement;
		}
		if (methodElement instanceof ContentElement) {
			contentElement = (ContentElement) methodElement;
			ContentDescription contentDescription = contentElement
					.getPresentation();
			methodUnit = contentDescription;
		}
	}

	/**
	 * @see org.eclipse.ui.forms.editor.createFormContent(IManagedForm)
	 */
	protected void createFormContent(IManagedForm managedForm) {
		form = managedForm.getForm();
		toolkit = managedForm.getToolkit();
		form.getBody().setLayout(new TableWrapLayout());
	}

	/**
	 * Called when the expand/collapse button is selected.
	 * 
	 * @param event
	 *            The associated event.
	 */
	protected void toggle(HyperlinkEvent event) {
	}

	/**
	 * Called when the expand/collapse button is selected.
	 * 
	 * @param event
	 *            The associated event.
	 * @param o
	 *            ???
	 */
	protected void toggle(HyperlinkEvent event, int o) {
	}

	/**
	 * Sets the name for the editor.
	 * 
	 * @param editorName
	 *            The name of the editor.
	 */
	public void setEditorName(String editorName) {
		this.editorName = editorName;
	}

	/**
	 * Returns a list of Method elements.
	 * 
	 * @param viewer
	 *            A TableViewer.
	 * @return A list of Method elements.
	 */
	public List<?> retrieveTableViewerContents(TableViewer viewer) {
		Object[] elements = ((IStructuredContentProvider) viewer
				.getContentProvider()).getElements(viewer.getInput());
		List<Object> elementList = new ArrayList<Object>();
		for (int i = 0; i < elements.length; i++)
			elementList.add(elements[i]);
		return elementList;
	}

	/**
	 * Creates a section on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param name
	 *            The section name.
	 * @param description
	 *            The section description.
	 * @return A new <code>Section</code>.
	 */
	protected Section createSection(FormToolkit toolkit, Composite parent,
			String title, String description) {
		Section section = toolkit.createSection(parent, Section.DESCRIPTION
				| Section.TWISTIE | Section.EXPANDED | Section.TITLE_BAR);
		GridData td = new GridData(SWT.FILL, SWT.FILL, true, false);
		section.setLayoutData(td);
		section.setText(title);
//		String text = MessageFormat.format(description,
//				new String[] { LibraryUIText.getUITextLower(methodElement) });
//		section.setDescription(text);
		section.setDescription(description);
		section.setLayout(new GridLayout());
		return section;
	}

	/**
	 * Creates a label on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param text
	 *            The text for the label.
	 * @param gridDataStyle
	 *            The GridData style.
	 * @param horizontalSpan
	 *            The number of column cells taken up by the Label.
	 * @return A new <code>Label</code>.
	 */
	protected static Label createLabel(FormToolkit toolkit, Composite parent,
			String text, int gridDataStyle, int horizontalSpan) {
		Label label = toolkit.createLabel(parent, text, SWT.WRAP);
		GridData gridData = new GridData(gridDataStyle);
		gridData.horizontalSpan = horizontalSpan;
		gridData.verticalAlignment = SWT.TOP;
		gridData.widthHint = (horizontalSpan == 2) ? 115 : 100;
		label.setLayoutData(gridData);
		return label;
	}
	
	/**
	 * Creates a label on a form page without wrap and no widthHint.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param text
	 *            The text for the label.
	 * @param gridDataStyle
	 *            The GridData style.
	 * @param horizontalSpan
	 *            The number of column cells taken up by the Label.
	 * @return A new <code>Label</code>.
	 */
	public static Label createLabelWithNoWrap(FormToolkit toolkit, Composite parent,
			String text, int gridDataStyle, int horizontalSpan) {
		Label label = toolkit.createLabel(parent, text);
		GridData gridData = new GridData(gridDataStyle);
		gridData.horizontalSpan = horizontalSpan;
		gridData.verticalAlignment = SWT.TOP;
		//gridData.widthHint = (horizontalSpan == 2) ? 115 : 100;
		label.setLayoutData(gridData);
		return label;
	}

	/**
	 * Creates a label on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param text
	 *            The text for the label.
	 * @return A new <code>Label</code>.
	 */
	protected static Label createLabel(FormToolkit toolkit, Composite parent,
			String text) {
		return createLabel(toolkit, parent, text, GridData.BEGINNING, 1);
	}

	/**
	 * Creates a label on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param text
	 *            The text for the label.
	 * @param horizontalSpan
	 *            The number of column cells taken up by the Label.
	 * @return A new <code>Label</code>.
	 */
	protected static Label createLabel(FormToolkit toolkit, Composite parent,
			String text, int horizontalSpan) {
		return createLabel(toolkit, parent, text, GridData.BEGINNING,
				horizontalSpan);
	}

	/**
	 * Creates a blank label on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param horizontalSpan
	 *            The number of column cells taken up by the Label.
	 * @return A new <code>Label</code>.
	 */
	protected static Label createBlankLabel(FormToolkit toolkit,
			Composite parent, int horizontalSpan) {
		return createLabel(toolkit, parent,
				"", GridData.FILL_HORIZONTAL, horizontalSpan); //$NON-NLS-1$
	}

	/**
	 * Creates a text control on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param style
	 *            The Text style.
	 * @param gridDataStyle
	 *            The GridData style.
	 * @param heigth
	 *            The height of the control.
	 * @param width
	 *            The width of the text control.
	 * @param horizontalSpan
	 *            The number of column cells taken up by the Text control.
	 * @return A new <code>Text</code> control.
	 */
	protected static Text createTextEdit(FormToolkit toolkit, Composite parent,
			int style, int gridDataStyle, int height, int width,
			int horizontalSpan) {
		Text control = toolkit.createText(parent, "", style); //$NON-NLS-1$
		GridData gridData = new GridData(gridDataStyle);
		gridData.heightHint = height;
		gridData.widthHint = width;
		gridData.horizontalSpan = horizontalSpan;
		control.setLayoutData(gridData);
		return control;
	}

	/**
	 * Creates a single-line text control on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @return A new <code>Text</code> control.
	 */
	protected static Text createTextEdit(FormToolkit toolkit, Composite parent) {
		return createTextEdit(toolkit, parent, SWT.SINGLE | SWT.WRAP,
				GridData.FILL_HORIZONTAL, SWT.DEFAULT, 100, 1);
	}

	/**
	 * Creates a text control with a label on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param textStyle
	 *            The Text style.
	 * @param gridDataStyle
	 *            The GridData style.
	 * @param height
	 *            The height of the control.
	 * @param width
	 *            The width of the text control.
	 * @param horizontalSpan
	 *            The number of column cells taken up by the Text control.
	 * @param labelText
	 *            the text for the label.
	 * @return A new <code>Text</code> control.
	 */
	protected static Text createTextEditWithLabel(FormToolkit toolkit,
			Composite parent, int textStyle, int gridDataStyle, int height,
			int width, int horizontalSpan, String textLabel) {
		createLabel(toolkit, parent, textLabel);
		return createTextEdit(toolkit, parent, textStyle, gridDataStyle,
				height, width, horizontalSpan);
	}

	/**
	 * Creates a single-line text control with a label on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param labelText
	 *            the text for the label.
	 * @return A new <code>Text</code> control.
	 */
	protected static Text createTextEditWithLabel(FormToolkit toolkit,
			Composite parent, String labelText) {
		createLabel(toolkit, parent, labelText, 2);
		return createTextEdit(toolkit, parent);
	}

	/**
	 * Creates a double-line text control with a label on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param labelText
	 *            the text for the label.
	 * @return A new <code>Text</code> control.
	 */
	protected static Text createTextEditWithLabel2(FormToolkit toolkit,
			Composite parent, String labelText) {
		createLabel(toolkit, parent, labelText, 2);
		return createTextEdit(toolkit, parent, SWT.MULTI | SWT.WRAP
				| SWT.V_SCROLL, GridData.FILL_HORIZONTAL
				| GridData.GRAB_HORIZONTAL, 40, 300, 1);
	}

	/**
	 * Creates a single or multi-line text control with a label on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param labelText
	 *            the text for the label.
	 * @return A new <code>Text</code> control.
	 */
	protected static Text createTextEditWithLabel3(FormToolkit toolkit,
			Composite parent, String labelText, int height, int singleOrMulti) {
		createLabel(toolkit, parent, labelText, 2);
		return createTextEdit(toolkit, parent, singleOrMulti | SWT.WRAP
				| SWT.V_SCROLL | SWT.TRAVERSE_TAB_NEXT,
				GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL, height,
				300, 2);
	}

	/**
	 * Creates a single or multi-line text control with a label in a composite.
	 * 
	 * @author hopeshared
	 */
	protected static Text createTextEditWithLabel4(FormToolkit toolkit,
			Composite parent, String labelText, int height, int singleOrMulti, String fillText) {
		createLabel(toolkit, parent, labelText, 2);
		
		int horizontalSpan = calculateSpan(fillText);
		
		if(horizontalSpan==1){
			Text text = createTextEdit(toolkit, parent, singleOrMulti | SWT.WRAP
					| SWT.V_SCROLL | SWT.TRAVERSE_TAB_NEXT, GridData.FILL_HORIZONTAL
					| GridData.GRAB_HORIZONTAL, height, 200, 1);
			Text text2 = createTextEdit(toolkit, parent, singleOrMulti | SWT.WRAP
					| SWT.V_SCROLL, GridData.FILL_HORIZONTAL
					| GridData.GRAB_HORIZONTAL, height, 100, 1);
			text2.setVisible(false);
			createLabel(toolkit, parent,
					"", 1); //$NON-NLS-1$
			return text;
		}else{
			return createTextEdit(toolkit, parent, singleOrMulti | SWT.WRAP
					| SWT.V_SCROLL | SWT.TRAVERSE_TAB_NEXT,
					GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL, height,
					300, 3);
		}
	}
	
	
	/**
	 * Creates a double-line text control with a label on a form page.
	 * @author hopeshared
	 */
	protected static Text createTextEditWithLabel5(FormToolkit toolkit,
			Composite parent, String labelText) {
		createLabel(toolkit, parent, labelText, 2);
		return createTextEdit(toolkit, parent, SWT.MULTI | SWT.WRAP
				| SWT.V_SCROLL, GridData.FILL_HORIZONTAL
				| GridData.GRAB_HORIZONTAL, 40, 300, 2);
	}
	
	/**
	 * Creates a single or multi-line text control with a label on a form page.
	 * @author hopeshared
	 */
	protected static Text createTextEditWithLabel5(FormToolkit toolkit,
			Composite parent, String labelText, int height, int singleOrMulti) {
		createLabel(toolkit, parent, labelText, 2);
		return createTextEdit(toolkit, parent, singleOrMulti | SWT.WRAP
				| SWT.V_SCROLL | SWT.TRAVERSE_TAB_NEXT,
				GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL, height,
				300, 3);
	}
	
	/**
	 * Creates a combobox control with a label on a form page.
	 * 
	 * @author hopeshared
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param labelText
	 *            The text for the Label.
	 * @return A new <code>Combobox</code>.
	 */
	protected Combo createComboWithLabel3(FormToolkit toolkit, Composite parent,
			String labelText) {
		createLabel(toolkit, parent, labelText, 2);
		return createCombo(parent, SWT.SINGLE | SWT.FLAT | SWT.READ_ONLY |SWT.TRAVERSE_TAB_NEXT,
				GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL);
	}
	
	/**
	 * Calculate the text's horizontal span.
	 * 
	 * @author hopeshared
	 */
	protected static int calculateSpan(String fillText){
		int length = fillText.length();

		if(length < 60)
			return 1;
		return 2;
	}


	/**
	 * Creates a large text control with a label on a form page.
	 * <p>
	 * Used for the Brief Description box.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param labelText
	 *            the text for the label.
	 * @return A new <code>Text</code> control.
	 */
	protected static Text createTextEditWithLabelLarge(FormToolkit toolkit,
			Composite parent, String labelText) {
		Label label = createLabel(toolkit, parent, labelText);
		((GridData) label.getLayoutData()).widthHint = SWT.DEFAULT;
		return createTextEdit(toolkit, parent, SWT.MULTI | SWT.WRAP
				| SWT.V_SCROLL, GridData.FILL_HORIZONTAL
				| GridData.GRAB_HORIZONTAL, 80, SWT.DEFAULT, 3);
	}

	/**
	 * Creates an image hyperlink on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param text
	 *            The text for the hyperlink.
	 * @param image
	 *            The hyperlink image.
	 * @return A new <code>ImageHyperlink</code>.
	 */
	protected ImageHyperlink createImageHyperlink(FormToolkit toolkit,
			Composite parent, String text, Image image) {
		ImageHyperlink link = toolkit.createImageHyperlink(parent, SWT.LEFT
				| SWT.TOP);
		GridData gridData = new GridData(GridData.BEGINNING);
		gridData.verticalAlignment = SWT.TOP;
		link.setLayoutData(gridData);
		link.setImage(image);
		if (text != null)
			link.setText(text);
		return link;
	}

	/**
	 * Creates an image hyperlink on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param sectionId
	 *            The sction ID.
	 * @return A new <code>ImageHyperlink</code>.
	 */
	protected ImageHyperlink createHyperLink(FormToolkit toolkit,
			Composite expandedComposite, int sectionID) {
		SECTION_ID = sectionID;
		ImageHyperlink expandLink = toolkit.createImageHyperlink(
				expandedComposite, SWT.NONE);
		expandLink.setImage(AuthoringUIImages.IMG_EXPANDED);
		expandLink.setUnderlined(false);
		expandLink.addHyperlinkListener(new HyperlinkAdapter() {
			public void linkActivated(HyperlinkEvent e) {
				toggle(e, SECTION_ID);
			}
		});
		return expandLink;
	}

	/**
	 * Creates a rich text control on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param style
	 *            The rich text style.
	 * @param height
	 *            The height of the control.
	 * @param width
	 *            The width of the text control.
	 * @param horizontalSpan
	 *            The number of column cells taken up by the Text control.
	 * @return A new <code>IMethodRichText</code>.
	 */
	protected IMethodRichText createRichTextEdit(FormToolkit toolkit,
			Composite parent, int style, int gridDataStyle, int height,
			int width, int horizontalSpan, Label label) {
		IMethodRichText richText = MethodFormToolkit.createRichText(toolkit,
				parent, "", style, contentElementPath, methodElement, label); //$NON-NLS-1$
		GridData gridData = new GridData(gridDataStyle);
		gridData.heightHint = height;
		gridData.widthHint = width;
		gridData.horizontalSpan = horizontalSpan;
		richText.setLayoutData(gridData);
		return richText;
	}

	/**
	 * Creates a rich text control on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @return A new <code>IMethodRichText</code>.
	 */
	protected IMethodRichText createRichTextEdit(FormToolkit toolkit,
			Composite parent) {
		return createRichTextEdit(toolkit, parent, SWT.MULTI | SWT.WRAP
				| SWT.V_SCROLL, GridData.FILL_HORIZONTAL, SWT.DEFAULT,
				SWT.DEFAULT, 1, null);
	}
	
	
	public static Label createDecoratedLabel(FormToolkit toolkit, Composite parent,
			String text) {
		Label decoratedLabel = createLabel(toolkit, parent, text);
		int margin = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth(); 
		((GridData)decoratedLabel.getLayoutData()).horizontalIndent = margin;
		ControlDecoration labelControlDecoration = new ControlDecoration(decoratedLabel, SWT.LEFT | SWT.BOTTOM);
		decoratedLabel.setData(LABEL_DECORATOR_KEY, labelControlDecoration);
		return decoratedLabel;
	}
	
	/**
	 * Creates a rich text control with a image hyperLink and label on a form
	 * page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param labelText
	 *            The text for the label.
	 * @param sectionId
	 *            The section ID.
	 * @return A new <code>IRichMethodText</code>.
	 */
	protected IMethodRichText createRichTextEditWithLink(
			FormToolkit toolkit, Composite parent, String labelText,
			int height, int width, int horizontalSpan) {
		ImageHyperlink link = createImageHyperlink(toolkit, parent, null,
				AuthoringUIImages.IMG_COLLAPSED);
		link.setToolTipText(AuthoringUIResources.openRTE);
		// create label with ControlDecoration here for markers
		Label decoratedLabel = createDecoratedLabel(toolkit, parent, labelText);

		IMethodRichText control = createRichTextEdit(toolkit, parent, SWT.MULTI
				| SWT.WRAP | SWT.V_SCROLL, GridData.FILL_HORIZONTAL, height,
				width, horizontalSpan, decoratedLabel);

		link.setHref(control);
		link.setData("Title", labelText); //$NON-NLS-1$
		link.addHyperlinkListener(new HyperlinkAdapter() {
			public void linkActivated(HyperlinkEvent e) {
				toggle(e);
			}
		});

		return control;
	}


	/**
	 * Creates a rich text control with a image hyperLink and label on a form
	 * page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param labelText
	 *            The text for the label.
	 * @param sectionId
	 *            The section ID.
	 * @return A new <code>IRichMethodText</code>.
	 */
	protected IMethodRichText createRichTextEditWithLinkForSection(
			FormToolkit toolkit, Composite parent, String labelText,
			int height, int width, int sectionID) {
		final int SECTION_ID = sectionID;
		ImageHyperlink link = createImageHyperlink(toolkit, parent, null,
				AuthoringUIImages.IMG_COLLAPSED);
		link.setToolTipText(AuthoringUIResources.openRTE);

		// create label with ControlDecoration here for markers
		Label decoratedLabel = createDecoratedLabel(toolkit, parent, labelText);

		IMethodRichText control = createRichTextEdit(toolkit, parent, SWT.MULTI
				| SWT.WRAP | SWT.V_SCROLL, GridData.FILL_HORIZONTAL, height,
				width, 1, decoratedLabel);

		link.setHref(control);
		link.setData("Title", labelText); //$NON-NLS-1$
		link.addHyperlinkListener(new HyperlinkAdapter() {
			public void linkActivated(HyperlinkEvent e) {
				toggle(e, SECTION_ID);
			}
		});

		return control;
	}

	/**
	 * Creates a rich text editor on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param style
	 *            The rich text style.
	 * @param height
	 *            The height of the control.
	 * @param width
	 *            The width of the text control.
	 * @param horizontalSpan
	 *            The number of column cells taken up by the Text control.
	 * @return The new <code>IMethodRichTextEditor</code>.
	 */
	protected IMethodRichTextEditor createRichTextEditor(FormToolkit toolkit,
			Composite parent, int style, int gridDataStyle, int height,
			int width, int horizontalSpan, Label label) {
		IMethodRichTextEditor editor = MethodFormToolkit.createRichTextEditor(
				toolkit, parent, "", style, contentElementPath, methodElement, label, getEditor().getEditorSite()); //$NON-NLS-1$
		GridData gridData = new GridData(gridDataStyle);
		gridData.heightHint = height;
		gridData.widthHint = width;
		gridData.horizontalSpan = horizontalSpan;
		editor.setLayoutData(gridData);
		return editor;
	}

	/**
	 * Creates a combobox control on a form page.
	 * 
	 * @param parent
	 *            The parent composite.
	 * @param style
	 *            The Combobox style.
	 * @param gridDataStyle
	 *            The GridData style.
	 * @return A new <code>Combobox</code>.
	 */
	protected Combo createCombo(Composite parent, int style, int gridDataStyle) {
		Combo control = new Combo(parent, style);
		return control;
	}

	/**
	 * Creates a combobox control on a form page.
	 * 
	 * @param parent
	 *            The parent composite.
	 * @return A new <code>Combobox</code>.
	 */
	protected Combo createCombo(Composite parent) {
		return createCombo(parent, SWT.SINGLE | SWT.FLAT | SWT.READ_ONLY,
				GridData.FILL_HORIZONTAL);
	}

	/**
	 * Creates a combobox control with a label on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param labelText
	 *            The text for the Label.
	 * @param style
	 *            The Combobox style.
	 * @param gridDataStyle
	 *            The GridData style.
	 * @return A new <code>Combobox</code>.
	 */
	protected Combo createCComboWithLabel(FormToolkit toolkit,
			Composite parent, String textLabel, int style, int gridDataStyle) {
		createLabel(toolkit, parent, textLabel);
		return createCombo(parent, style, gridDataStyle);
	}

	/**
	 * Creates a combobox control with a label on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param labelText
	 *            The text for the Label.
	 * @return A new <code>Combobox</code>.
	 */
	protected Combo createComboWithLabel(FormToolkit toolkit, Composite parent,
			String labelText) {
		createLabel(toolkit, parent, labelText);
		return createCombo(parent, SWT.SINGLE | SWT.FLAT | SWT.READ_ONLY,
				GridData.FILL_HORIZONTAL);
	}

	/**
	 * Creates a composite on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param section
	 *            The parent section.
	 * @return A new <code>Composite</code>.
	 */

	protected Composite createComposite(FormToolkit toolkit, Section section) {
		Composite composite = toolkit.createComposite(section);
		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		composite.setLayout(new GridLayout(3, false));
		section.setClient(composite);
		return composite;
	}

	/**
	 * Creates a composite on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param gridDataStyle
	 *            The GridData style.
	 * @param verticalSpan
	 *            The number of row cells taken up by the Composite.
	 * @param horizontalSpan
	 *            The number of column cells taken up by the Composite.
	 * @param numColumns
	 *            The number of columns in the grid.
	 * @return A new <code>Composite</code>.
	 */
	protected static Composite createComposite(FormToolkit toolkit,
			Composite parent, int gridDataStyle, int verticalSpan,
			int horizontalSpan, int numColumns) {
		Composite composite = toolkit.createComposite(parent, SWT.NONE);
		GridData gridData = new GridData(gridDataStyle);
		gridData.verticalSpan = verticalSpan;
		gridData.horizontalSpan = horizontalSpan;
		composite.setLayoutData(gridData);
		composite.setLayout(new GridLayout(numColumns, false));
		return composite;
	}

	/**
	 * Creates a composite on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param verticalSpan
	 *            The number of row cells taken up by the Composite.
	 * @return A new <code>Composite</code>.
	 */
	protected static Composite createComposite(FormToolkit toolkit,
			Composite parent, int verticalSpan) {
		return createComposite(toolkit, parent, GridData.FILL_BOTH,
				verticalSpan, 1, 1);
	}

	/**
	 * Creates a composite for displaying buttons on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param type
	 *            The Composite type.
	 * @return A new <code>Composite</code>.
	 */
	protected static Composite createCompositeForButtons(FormToolkit toolkit,
			Composite parent) {
		return createComposite(toolkit, parent, GridData.VERTICAL_ALIGN_CENTER
				| GridData.HORIZONTAL_ALIGN_CENTER, SWT.DEFAULT, SWT.DEFAULT, 1);
	}

	/**
	 * Creates a expanded composite in the form
	 * <p>
	 * Used to hold an expanded rich text editor.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @return A new <code>Composite</code>.
	 */
	protected Composite createExpandedComposite(FormToolkit toolkit,
			Composite parent) {
		Composite expandedComposite = toolkit.createComposite(parent, SWT.NONE);
		expandedComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		expandedComposite.setLayout(new GridLayout(2, false));
		expandedComposite.setVisible(false);
		return expandedComposite;
	}

	/**
	 * Creates a table on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param style
	 *            The Table style.
	 * @param gridDataStyle
	 *            The GridData style.
	 * @param height
	 *            The height of the Table.
	 * @param width
	 *            The width of the Table.
	 * @param verticalSpan
	 *            The number of row cells taken up by the Table.
	 * @param horizontalSpan
	 *            The number of column cells taken up by the Table.
	 * @return A new <code>Table</code>.
	 */
	protected static Table createTable(FormToolkit toolkit, Composite parent,
			int style, int gridDataStyle, int height, int width,
			int verticalSpan, int horizontalSpan) {
		Table table = toolkit.createTable(parent, style);
		GridData gridData = new GridData(gridDataStyle);
		gridData.heightHint = height;
		gridData.widthHint = width;
		gridData.verticalSpan = verticalSpan;
		gridData.horizontalSpan = horizontalSpan;
		table.setLayoutData(gridData);
		return table;
	}

	/**
	 * Creates a table on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param type
	 *            The table table.
	 * @return A new <code>Table</code>.
	 */
	protected static Table createTable(FormToolkit toolkit, Composite parent,
			int type) {
		switch (type) {
		case SMALL_SIZE:
			return createTable(toolkit, parent, SWT.MULTI, GridData.FILL_BOTH,
					56, 200, 1, 1);
		case MEDIUM_SIZE:
			return createTable(toolkit, parent, SWT.MULTI, GridData.FILL_BOTH,
					112, 200, 1, 1);
		case LARGE_SIZE:
			return createTable(toolkit, parent, SWT.MULTI, GridData.FILL_BOTH,
					200, 200, 1, 1);
		case SINGLE_ROW:
			return createTable(toolkit, parent, SWT.MULTI,
					GridData.FILL_HORIZONTAL, 20, 200, 1, 1);
		default:
			throw new IllegalArgumentException();
		}
	}

	/**
	 * Creates a button on a form page.
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 * @param parent
	 *            The parent composite.
	 * @param type
	 *            The button type.
	 * @return A new <code>Button</code>.
	 */
	protected static Button createButton(FormToolkit toolkit, Composite parent,
			int type) {
		Button button;
		switch (type) {
		case ADD_BUTTON:
			button = toolkit.createButton(parent,
					AuthoringUIText.ADD_BUTTON_TEXT, SWT.NONE);
			break;
		case REMOVE_BUTTON:
			button = toolkit.createButton(parent,
					AuthoringUIText.REMOVE_BUTTON_TEXT, SWT.NONE);
			break;
		case UP_BUTTON:
			button = toolkit.createButton(parent,
					AuthoringUIText.UP_BUTTON_TEXT, SWT.NONE);
			break;
		case DOWN_BUTTON:
			button = toolkit.createButton(parent,
					AuthoringUIText.DOWN_BUTTON_TEXT, SWT.NONE);
			break;
		case ORDER_BUTTON:
			button = toolkit.createButton(parent,
					AuthoringUIText.ORDER_BUTTON_TEXT, SWT.NONE);
			break;
		case SELECT_BUTTON:
			button = toolkit.createButton(parent,
					AuthoringUIText.SELECT_BUTTON_TEXT, SWT.NONE);
			break;
		case CLEAR_BUTTON:
			button = toolkit.createButton(parent,
					AuthoringUIText.CLEAR_BUTTON_TEXT, SWT.NONE);
			break;
		case ATTACH_BUTTON:
			button = toolkit.createButton(parent,
					AuthoringUIText.ATTACH_BUTTON_TEXT, SWT.NONE);
			break;
		case ATTACH_URL_BUTTON:
			button = toolkit.createButton(parent,
					AuthoringUIText.ATTACH_URL_BUTTON_TEXT, SWT.NONE);
			break;		
		case DETACH_BUTTON:
			button = toolkit.createButton(parent,
					AuthoringUIText.DETACH_BUTTON_TEXT, SWT.NONE);
			break;
		default:
			throw new IllegalArgumentException();
		}
		button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		button.setEnabled(false);
		return button;
	}
	
	/**
	 * Get height of the rich text control
	 * @return
	 * 		Height of the rich text control
	 */
	public int getRichTextEditorHeight() {
		return form.getBounds().height - 3 * 32;
	}

	/**
	 * Get width of the rich text control
	 * @return
	 * 		Width of the rich text control
	 */
	public int getRichTextEditorWidth() {
		return form.getBounds().width - 2 * 32;
	}

	public MethodElement getMethodElement() {
		return methodElement;
	}


}
