//------------------------------------------------------------------------------
// 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.text.MessageFormat;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.edit.provider.IStructuredItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
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.MethodElementEditor;
import org.eclipse.epf.authoring.ui.preferences.AuthoringUIPreferences;
import org.eclipse.epf.authoring.ui.richtext.IMethodRichText;
import org.eclipse.epf.authoring.ui.util.EditorsContextHelper;
import org.eclipse.epf.authoring.ui.util.UIHelper;
import org.eclipse.epf.diagram.core.services.DiagramManager;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.navigator.ConfigurationsItemProvider;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.IValidator;
import org.eclipse.epf.library.edit.validation.IValidatorFactory;
import org.eclipse.epf.library.ui.LibraryUIText;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.dialogs.ListSelectionDialog;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;


/**
 * The Description page for the process description.
 * 
 * @author Shilpa Toraskar
 * @author Phong Nguyen Le
 * @author Kelvin Low
 * @since 1.0
 * 
 * TODO: Rename this class to ProcessDescriptionPage
 */
public class ProcessDescription extends ProcessFormPage {

	private static final String FORM_PAGE_ID = "processDescriptionPage"; //$NON-NLS-1$

	private static final int DEFAULT_VERTICAL_INDENT = 2;

	private IStructuredContentProvider contentProvider = new AdapterFactoryContentProvider(
			TngAdapterFactory.INSTANCE
					.getNavigatorView_ComposedAdapterFactory()) {
	};

	private ILabelProvider labelProvider = new AdapterFactoryLabelProvider(
			TngAdapterFactory.INSTANCE
					.getNavigatorView_ComposedAdapterFactory());

	private IMethodRichText ctrl_scope, ctrl_usage_notes;

	private IMethodRichText ctrl_alternatives, ctrl_how_to_staff,
			ctrl_key_consideration;

	private Section configSection;

	protected Composite configComposite;

	protected boolean configSectionExpandFlag = false;

	private org.eclipse.swt.widgets.List list_configurations;

	private ListViewer configListViewer;

	protected Button buttonAdd;

	protected Button buttonRemove;

	// private Button buttonEdit;
	protected Button buttonMakeDefault;

	private Text textConfigDescription;

	private ItemProviderAdapter configListAdapter;

	protected ModifyListener modifyListener;

	protected ModifyListener contentModifyListener;

//	private Adapter processListener;

	private String processType;

	private MethodElementEditor editor;

	private ModifyListener nameModifyListener;

	private boolean disposed;
	 

	/**
	 * Creates a new instance.
	 */
	public ProcessDescription(FormEditor editor) {
		super(editor, FORM_PAGE_ID, AuthoringUIResources.descriptionPage_title); 
	}
	
	@Override
	public void init(IEditorSite site, IEditorInput input) {
		super.init(site, input);
		processType = LibraryUIText.getUITextLower(process);
		versionSectionOn = false;
		variabilitySectionOn = false;
		externalIdOn = true;
		purposeOn = true;
	}

	/**
	 * Creates the editor tab content
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 */
	protected void createEditorContent(FormToolkit toolkit) {
		super.createEditorContent(toolkit);
		createConfigurationSection(toolkit);
		// Set focus on the Name text control.
		Display display = form.getBody().getDisplay();
		if (!(display == null || display.isDisposed())) {
			display.asyncExec(new Runnable() {
				public void run() {
					if(ctrl_name.isDisposed()) return;
					ctrl_name.setFocus();
					ctrl_name.setSelection(0, ctrl_name.getText().length());
				}
			});
		}
	}

	/**
	 * Create general section
	 */
	protected void createGeneralSection(FormToolkit toolkit) {
		// create General Information section
		generalSection = createSection(toolkit, sectionComposite, 
				AuthoringUIText.GENERAL_INFO_SECTION_NAME, 
				MessageFormat.format(
						AuthoringUIText.GENERAL_INFO_SECTION_DESC,
						new String[] { processType }));
		generalComposite = createComposite(toolkit, generalSection);

		// name
		ctrl_name = createTextEditWithLabel(toolkit, generalComposite,
				AuthoringUIText.NAME_TEXT);

		// Presentation name
		ctrl_presentation_name = createTextEditWithLabel(toolkit,
				generalComposite, AuthoringUIText.PRESENTATION_NAME_TEXT);
		
		// Long Presentation name
		if (longPresentationNameOn && AuthoringUIPreferences.getEnableUIFields()) {
			ctrl_long_presentation_name = createTextEditWithLabel(toolkit,
					generalComposite, AuthoringUIText.LONG_PRESENTATION_NAME_TEXT);
		}

		// brief desc
		ctrl_brief_desc = createTextEditWithLabel2(toolkit, generalComposite,
				AuthoringUIText.BRIEF_DESCRIPTION_TEXT);

		// External Id
		if (AuthoringUIPreferences.getEnableUIFields()) {
			ctrl_external_id = createTextEditWithLabel(toolkit, generalComposite,
					AuthoringUIResources.Process_ExternalID);
		}

		// Purpose
		ctrl_purpose = createRichTextEditWithLinkForSection(
				toolkit,
				generalComposite,
				AuthoringUIResources.Process_Purpose, 40, 400, GENERAL_SECTION_ID); 
		
		toolkit.paintBordersFor(generalComposite);
	}

	/**
	 * Create detail section
	 *
	 */
	protected void createDetailSection(FormToolkit toolkit) {
		// create detail section
		detailSection = createSection(toolkit, sectionComposite, 
				AuthoringUIText.DETAIL_SECTION_NAME, 
				MessageFormat.format(
						AuthoringUIText.DETAIL_SECTION_DESC,
						new String[] { processType }));
		detailComposite = createComposite(toolkit, detailSection);

		// full description
		ctrl_full_desc = createRichTextEditWithLinkForSection(toolkit,
				detailComposite, AuthoringUIText.MAIN_DESCRIPTION_TEXT, 100,
				400, DETAIL_SECTION_ID);

		// scope
		ctrl_scope = createRichTextEditWithLinkForSection(toolkit,
				detailComposite, AuthoringUIResources.Process_Scope, 40, 400, DETAIL_SECTION_ID); 

		// usage notes
		ctrl_usage_notes = createRichTextEditWithLinkForSection(
				toolkit,
				detailComposite,
				AuthoringUIResources.Process_UsageNotes, 40, 400, DETAIL_SECTION_ID); 

		// alternatives
		ctrl_alternatives = createRichTextEditWithLinkForSection(
				toolkit,
				detailComposite,
				AuthoringUIResources.Process_Alternatives, 40, 400, DETAIL_SECTION_ID); 

		// how to staff
		ctrl_how_to_staff = createRichTextEditWithLinkForSection(
				toolkit,
				detailComposite,
				AuthoringUIResources.Process_HowToStaff, 40, 400, DETAIL_SECTION_ID); 

		// key consideration
		ctrl_key_consideration = createRichTextEditWithLinkForSection(
				toolkit,
				detailComposite,
				AuthoringUIResources.Process_KeyConsideration, 40, 400, DETAIL_SECTION_ID); 

		toolkit.paintBordersFor(detailComposite);
	}

	/**
	 * Create configuration section
	 */
	protected void createConfigurationSection(FormToolkit toolkit) {
		// create Configuration section
		configSection = createSection(toolkit, sectionComposite, 
				AuthoringUIResources.processDescription_configurationSectionTitle, 
				AuthoringUIResources.processDescription_configurationSectionMessage);
		configComposite = createComposite(toolkit, configSection);
		((GridLayout) configComposite.getLayout()).numColumns = 2;

		Label l_element = toolkit
				.createLabel(
						configComposite,
						AuthoringUIResources.processDescription_configurations); 
		{
			GridData gridData = new GridData(SWT.BEGINNING, SWT.END, true,
					true, 2, 1);
			l_element.setLayoutData(gridData);
		}

		list_configurations = UIHelper.createList(toolkit, configComposite,
				SWT.SINGLE | SWT.BORDER);
		{
			GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
			gridData.verticalIndent = DEFAULT_VERTICAL_INDENT;
			gridData.heightHint = 80;
			gridData.widthHint = 200;
			list_configurations.setLayoutData(gridData);
		}
		configListViewer = new ListViewer(list_configurations);
		configListViewer.setContentProvider(contentProvider);
		configListViewer.setLabelProvider(new LabelProvider() {
			public org.eclipse.swt.graphics.Image getImage(Object element) {
				if (element == process.getDefaultContext()) {
					return AuthoringUIPlugin.getDefault().getSharedImage(
							"icons/checked.gif"); //$NON-NLS-1$
				}
				return null;
			}

			public String getText(Object element) {
				String txt = labelProvider.getText(element);
				if (element == process.getDefaultContext()) {
					txt = txt
							+ " " + AuthoringUIResources.processDescription_default; //$NON-NLS-1$ 
				}
				return txt;
			}
		});

		Composite buttonPanel = toolkit.createComposite(configComposite);
		{
			GridData gridData = new GridData(SWT.CENTER, SWT.CENTER, false,
					false);
			// gridData.widthHint = 80;
			gridData.horizontalIndent = 4;
			buttonPanel.setLayoutData(gridData);
			buttonPanel.setLayout(new GridLayout());

		}
		// Add button
		Button button = toolkit.createButton(buttonPanel, AuthoringUIResources.addButton_text, SWT.NONE); 
		{
			GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
			button.setLayoutData(gridData);
		}
		buttonAdd = button;

		// Remove button
		button = toolkit.createButton(buttonPanel, AuthoringUIResources.removeButton_text, SWT.NONE); 
		{
			GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
			button.setLayoutData(gridData);
		}
		buttonRemove = button;

		// // Edit button
		// button = toolkit.createButton(buttonPanel, "Edit...", SWT.NONE);
		// {
		// GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		// gridData.verticalIndent = DEFAULT_VERTICAL_INDENT * 6;
		// button.setLayoutData(gridData);
		// }
		// buttonEdit = button;
		//		
		//		
		// Make Default button
		button = toolkit.createButton(buttonPanel, AuthoringUIResources.makeDefaultButton_text, SWT.NONE); 
		{
			GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
			button.setLayoutData(gridData);
		}
		buttonMakeDefault = button;

		// configuration description
		Label label = toolkit
				.createLabel(
						configComposite,
						AuthoringUIResources.processDescription_configurationDescription); 
		{
			GridData gridData = new GridData(SWT.BEGINNING, SWT.END, true,
					false, 2, 1);
			label.setLayoutData(gridData);
		}

		textConfigDescription = toolkit.createText(configComposite, ""); //$NON-NLS-1$
		{
			GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
			gridData.verticalIndent = DEFAULT_VERTICAL_INDENT;
			gridData.heightHint = 80;
			gridData.widthHint = 400;
			textConfigDescription.setLayoutData(gridData);
		}
		textConfigDescription.setEditable(false);
		toolkit.paintBordersFor(configComposite);
	}

	/**
	 * @see org.eclipse.ui.forms.editor.FormPage#dispose()
	 */
	public void dispose() {
//		if (processListener != null) {
//			process.eAdapters().remove(processListener);
//		}

		if (configListAdapter != null) {
			configListAdapter.dispose();
		}

		super.dispose();

		if (contentProvider != null) {
			contentProvider.dispose();
		}
		if (labelProvider != null) {
			labelProvider.dispose();
		}
		
		disposed = true;
	}

	/**
	 * Content provider for configurations
	 *
	 */
	class ConfigListItemProvider extends ItemProviderAdapter implements
			IStructuredItemContentProvider {
		
		/**
		 * Creates an instance
		 * @param adapterFactory
		 */
		public ConfigListItemProvider(AdapterFactory adapterFactory) {
			super(adapterFactory);
			process.eAdapters().add(this);
		}

		/**
		 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildren(java.lang.Object)
		 */
		public java.util.Collection getChildren(Object object) {
			MethodConfiguration defaultConfig = process.getDefaultContext();

			if (defaultConfig != null
					&& !process.getValidContext().contains(defaultConfig)) {
				process.getValidContext().add(0, defaultConfig);
			}
			return process.getValidContext();
		}

		/**
		 * @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.eclipse.emf.common.notify.Notification)
		 */
		public void notifyChanged(org.eclipse.emf.common.notify.Notification msg) {
			boolean refresh = false;
			switch (msg.getFeatureID(Process.class)) {
			case UmaPackage.PROCESS__VALID_CONTEXT:
				switch (msg.getEventType()) {
				case Notification.ADD:
				case Notification.ADD_MANY:
				case Notification.REMOVE:
				case Notification.REMOVE_MANY:
					refresh = true;
				}
				break;
			case UmaPackage.PROCESS__DEFAULT_CONTEXT:
				refresh = true;
				break;
			}
			if (refresh)
				configListViewer.refresh();
		}
	};

	private void updateModelControls() {
		if ((ctrl_name != null) && (!ctrl_name.isDisposed())) {
			updateControl(ctrl_name, process.getName());
		}
		if ((ctrl_brief_desc != null) && (!ctrl_brief_desc.isDisposed())) {
			updateControl(ctrl_brief_desc, process.getBriefDescription());
		}
		if ((ctrl_presentation_name != null)
				&& (!ctrl_presentation_name.isDisposed())) {
			updateControl(ctrl_presentation_name, process.getPresentationName());
		}
		if (longPresentationNameOn && AuthoringUIPreferences.getEnableUIFields()) {
			if ((ctrl_long_presentation_name != null)
					&& (!ctrl_long_presentation_name.isDisposed())) {
				updateControl(ctrl_long_presentation_name, process
						.getPresentation().getLongPresentationName());
			}
		}
	}

	/**
	 * Updates the Text control iff the newText is different than what's there
	 * @param text
	 * @param newText
	 * @return
	 */
	private boolean updateControl(Text text, String newText) {
		if (!text.getText().equals(TngUtil.checkNull(newText))) {
			text.setText(TngUtil.checkNull(newText));
		}
		return false;
	}
	
	/**
	 * Updates the IMethodRichText control iff the newText is different than what's there
	 * @param text
	 * @param newText
	 * @return
	 */
	private boolean updateControl(IMethodRichText text, String newText) {
		if (!text.getText().equals(TngUtil.checkNull(newText))) {
			text.setText(TngUtil.checkNull(newText));
		}
		return false;
	}

	/**
	 * Loads initial data from model
	 * 
	 */
	public void loadData() {
		org.eclipse.epf.uma.ProcessDescription content = (org.eclipse.epf.uma.ProcessDescription) process
				.getPresentation();

		String externalID = content.getExternalId();
		String purpose = content.getPurpose();
		String fullDesc = content.getMainDescription();
		String scope = content.getScope();
		String usageNotes = content.getUsageNotes();
		String alternatives = content.getAlternatives();
		String howToStaff = content.getHowtoStaff();
		String keyConsideration = content.getKeyConsiderations();

		updateModelControls();

		if (AuthoringUIPreferences.getEnableUIFields()) {
			if ((ctrl_external_id != null) && (!ctrl_external_id.isDisposed())) {
				updateControl(ctrl_external_id, externalID);
			}
		}
		
		updateControl(ctrl_purpose, purpose);
		updateControl(ctrl_full_desc, fullDesc);
		updateControl(ctrl_scope, scope);
		updateControl(ctrl_usage_notes, usageNotes);
		updateControl(ctrl_alternatives, alternatives);
		updateControl(ctrl_how_to_staff, howToStaff);
		updateControl(ctrl_key_consideration, keyConsideration);

		if (configListAdapter == null) {
			configListAdapter = new ConfigListItemProvider(
					TngAdapterFactory.INSTANCE
							.getNavigatorView_ComposedAdapterFactory());
		}

		configListViewer.setInput(configListAdapter);
	}

	/**
	 * Add listeners
	 * 
	 */
	protected void addListeners() {
//		super.addListeners();
		this.editor = ((MethodElementEditor) getEditor());
		final IActionManager actionMgr = editor.getActionManager();
		final org.eclipse.epf.uma.ProcessDescription content = (org.eclipse.epf.uma.ProcessDescription) process
				.getPresentation();
		modifyListener = editor.createModifyListener(process);
		contentModifyListener = editor.createModifyListener(process
				.getPresentation());

		form.addControlListener(new ControlListener() {
			public void controlResized(ControlEvent e) {
				if (!descExpandFlag)
					return;
				if (ctrl_expanded != null) {
					((GridData) ctrl_expanded.getLayoutData()).heightHint = getRichTextEditorHeight();
					((GridData) ctrl_expanded.getLayoutData()).widthHint = getRichTextEditorWidth();
				}
				formSection.layout(true, true);
			}

			public void controlMoved(ControlEvent e) {
			}
		});

		form.getParent().addListener(SWT.Activate, new Listener() {

			public void handleEvent(Event event) {
				if (TngUtil.isLocked(process)) {
					refresh(false);
				} else {
					refresh(true);
				}
			}
		});
		
		nameModifyListener = editor.createModifyListener(process.eContainer(),
				true);
		ctrl_name.addModifyListener(nameModifyListener);
		ctrl_name.addListener(SWT.Deactivate, new Listener() {
			public void handleEvent(Event e) {
				String oldContent = process.getName();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						e.widget, oldContent)) {
					return;
				}
				String newName = ctrl_name.getText().trim();
				if (newName.equals(process.getName())) {
					return;
				}

				ProcessComponent procComp = (ProcessComponent) process.eContainer();
				
				String msg = null;
				if (newName.indexOf('&') > -1) { //FIXME: this must go to validator code
					msg = NLS.bind(LibraryEditResources.invalidElementNameError4_msg, newName);
				} else {
					IValidator validator = IValidatorFactory.INSTANCE
					.createNameValidator(
							procComp,
							TngAdapterFactory.INSTANCE
									.getNavigatorView_ComposedAdapterFactory());
					msg = validator.isValid(newName);
				}
				
				if (msg == null) {
					String title = AuthoringUIResources.processDescriptionNameChangeConfirm_title; 
					String message = AuthoringUIResources.processDescriptionNameChangeConfirm_message; 
					if (AuthoringUIPlugin.getDefault().getMsgDialog()
							.displayConfirmation(title, message)) {
						e.doit = true;

						boolean status = actionMgr.doAction(IActionManager.SET,
								process, UmaPackage.eINSTANCE
										.getNamedElement_Name(), ctrl_name
										.getText(), -1);
						if (!status) {
							ctrl_name.setText(process.getName());
							return;
						}
						actionMgr.doAction(IActionManager.SET, procComp,
								UmaPackage.eINSTANCE.getNamedElement_Name(),
								ctrl_name.getText(), -1);

						setFormText();

						// adjust plugin location and save the editor
						//
						BusyIndicator.showWhile(getSite().getShell()
								.getDisplay(), new Runnable() {
							public void run() {
								MethodElementEditor editor = (MethodElementEditor) getEditor();
								editor
										.doSave(new NullProgressMonitor());
								if(editor.isDirty()) {
									// save failed
									//
									return;
								}
								ILibraryPersister.FailSafeMethodLibraryPersister persister = editor
										.getPersister();
								try {
									persister.adjustLocation(process
													.eResource());
									persister.commit();
								} catch (RuntimeException e) {
									persister.rollback();
									throw e;
								}
								// adjust diagram resource as well
								//
								DiagramManager mgr = DiagramManager.getInstance(process, this);
								if(mgr != null) {
									try {
										mgr.updateResourceURI();
									}
									catch(Exception e) {
										AuthoringUIPlugin.getDefault().getLogger().logError(e);
									}
									finally {
										mgr.removeConsumer(this);
									}
								}
							}
						});
					} else {
						ctrl_name.setText(process.getName());
						return;
					}
				} else {
					AuthoringUIPlugin
							.getDefault()
							.getMsgDialog()
							.displayError(
									AuthoringUIResources.renameDialog_title, msg); 
					ctrl_name.setText(process.getName());
					e.doit = false;
					ctrl_name.getDisplay().asyncExec(new Runnable() {
						public void run() {
							ctrl_name.setFocus();
							ctrl_name.selectAll();
						}
					});
				}
			}
		});
		ctrl_name.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				((MethodElementEditor) getEditor()).setCurrentFeatureEditor(e.widget,
						UmaPackage.eINSTANCE.getNamedElement_Name());
			}
		});
		
		ctrl_presentation_name.addModifyListener(modifyListener);
		ctrl_presentation_name.addListener(SWT.Deactivate, new Listener() {
			public void handleEvent(Event e) {
				String oldContent = process.getPresentationName();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						e.widget, oldContent)) {
					return;
				}
				if ((ctrl_presentation_name.getText() != null)
						&& (!ctrl_presentation_name.getText().equals(""))) //$NON-NLS-1$
				{
					e.doit = true;
					if (!ctrl_presentation_name.getText().equals(oldContent)) {

						boolean status = actionMgr
								.doAction(
										IActionManager.SET,
										process,
										UmaPackage.eINSTANCE
												.getMethodElement_PresentationName(),
										ctrl_presentation_name.getText(), -1);
						if (!status) {
							ctrl_presentation_name.setText(oldContent);
							return;
						}
//						LibraryView elementsView = LibraryView.getView();
//						if (elementsView != null)
//							elementsView.getViewer().refresh();
					}
				} else {
					// restore the old name first, then present the error
					// message box
					ctrl_presentation_name.setText(process
							.getPresentationName());
					AuthoringUIPlugin
							.getDefault()
							.getMsgDialog()
							.displayError(
									AuthoringUIResources.editDialog_title, 
									AuthoringUIResources.invalidPresentationNameError_msg); 
					e.doit = false;
					ctrl_presentation_name.getDisplay().asyncExec(
							new Runnable() {
								public void run() {
									ctrl_presentation_name.setFocus();
								}
							});
				}
			}
		});
		ctrl_presentation_name.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				((MethodElementEditor) getEditor()).setCurrentFeatureEditor(e.widget,
						UmaPackage.eINSTANCE.getMethodElement_PresentationName());
				// when user tab to this field, select all text
				ctrl_presentation_name.selectAll();

			}
			public void focusLost(FocusEvent e) {
				// clear the selection when the focus of the component is lost 
				if(ctrl_presentation_name.getSelectionCount() > 0){
					ctrl_presentation_name.clearSelection();
				} }
		});

		if (longPresentationNameOn && AuthoringUIPreferences.getEnableUIFields()) { 
			ctrl_long_presentation_name.addModifyListener(modifyListener);
			ctrl_long_presentation_name.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					((MethodElementEditor) getEditor()).setCurrentFeatureEditor(e.widget,
							UmaPackage.eINSTANCE.getContentDescription_LongPresentationName());
				}
	
				public void focusLost(FocusEvent e) {
					String oldContent = content.getLongPresentationName();
					if (((MethodElementEditor) getEditor()).mustRestoreValue(
							ctrl_long_presentation_name, oldContent)) {
						return;
					}
					String newContent = ctrl_long_presentation_name.getText();
					if (!newContent.equals(oldContent)) {
						boolean success = actionMgr.doAction(IActionManager.SET,
								process.getPresentation(), UmaPackage.eINSTANCE
										.getContentDescription_LongPresentationName(),
								newContent, -1);
						if (success) {
							ctrl_long_presentation_name.setText(newContent);
						}
					}
				}
			});
		}
		
		ctrl_brief_desc.addModifyListener(modifyListener);
		ctrl_brief_desc.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				((MethodElementEditor) getEditor()).setCurrentFeatureEditor(e.widget,
						UmaPackage.eINSTANCE.getMethodElement_BriefDescription());
			}

			public void focusLost(FocusEvent e) {
				String oldContent = process.getBriefDescription();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						e.widget, oldContent)) {
					return;
				}
				String newContent = ctrl_brief_desc.getText();
				if (!newContent.equals(oldContent)) {
					boolean success = actionMgr.doAction(IActionManager.SET,
							process, UmaPackage.eINSTANCE
									.getMethodElement_BriefDescription(),
							newContent, -1);
					if (success) {
						ctrl_brief_desc.setText(newContent);
					}
				}
			}
		});

		if (AuthoringUIPreferences.getEnableUIFields())  {
			ctrl_external_id.addModifyListener(contentModifyListener);
			ctrl_external_id.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					((MethodElementEditor) getEditor()).setCurrentFeatureEditor(e.widget,
							UmaPackage.eINSTANCE.getContentDescription_ExternalId());
				}
	
				public void focusLost(FocusEvent e) {
					String oldContent = content.getExternalId();
					if (((MethodElementEditor) getEditor()).mustRestoreValue(
							ctrl_external_id, oldContent)) {
						return;
					}
					String newContent = ctrl_external_id.getText();
					if (!newContent.equals(oldContent)) {
						boolean success = actionMgr.doAction(IActionManager.SET,
								process.getPresentation(), UmaPackage.eINSTANCE
										.getContentDescription_ExternalId(),
								newContent, -1);
						if (success) {
							ctrl_external_id.setText(newContent);
						}
					}
				}
			});
		}

		ctrl_purpose.setModalObject(process.getPresentation());
		ctrl_purpose.setModalObjectFeature(UmaPackage.eINSTANCE
				.getActivityDescription_Purpose());
		ctrl_purpose.addModifyListener(contentModifyListener);
		ctrl_purpose.addListener(SWT.Deactivate, new Listener() {
			public void handleEvent(Event e) {
				IMethodRichText control = descExpandFlag ? ctrl_expanded
						: ctrl_purpose;
				if (!control.getModified()) {
					return;
				}
				String oldContent = content.getPurpose();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						ctrl_purpose, oldContent)) {
					return;
				}
				String newContent = control.getText();
				if (!newContent.equals(oldContent)) {
					actionMgr.doAction(IActionManager.SET, process
							.getPresentation(), UmaPackage.eINSTANCE
							.getActivityDescription_Purpose(), newContent, -1);
				}
			}
		});

		ctrl_full_desc.setModalObject(process.getPresentation());
		ctrl_full_desc.setModalObjectFeature(UmaPackage.eINSTANCE
				.getContentDescription_MainDescription());
		ctrl_full_desc.addModifyListener(contentModifyListener);
		ctrl_full_desc.addListener(SWT.Deactivate, new Listener() {
			public void handleEvent(Event e) {
				IMethodRichText control = descExpandFlag ? ctrl_expanded
						: ctrl_full_desc;
				if (!control.getModified()) {
					return;
				}
				String oldContent = content.getMainDescription();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						ctrl_full_desc, oldContent)) {
					return;
				}
				String newContent = control.getText();
				if (!newContent.equals(oldContent)) {
					actionMgr.doAction(IActionManager.SET, process
							.getPresentation(), UmaPackage.eINSTANCE
							.getContentDescription_MainDescription(),
							newContent, -1);
				}
			}
		});

		ctrl_scope.setModalObject(process.getPresentation());
		ctrl_scope.setModalObjectFeature(UmaPackage.eINSTANCE
				.getProcessDescription_Scope());
		ctrl_scope.addModifyListener(contentModifyListener);
		ctrl_scope.addListener(SWT.Deactivate, new Listener() {
			public void handleEvent(Event e) {
				IMethodRichText control = descExpandFlag ? ctrl_expanded
						: ctrl_scope;
				if (!control.getModified()) {
					return;
				}
				String oldContent = content.getScope();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						ctrl_scope, oldContent)) {
					return;
				}
				String newContent = control.getText();
				if (!newContent.equals(oldContent)) {
					actionMgr.doAction(IActionManager.SET, process
							.getPresentation(), UmaPackage.eINSTANCE
							.getProcessDescription_Scope(), newContent, -1);
				}
			}
		});

		ctrl_usage_notes.setModalObject(process.getPresentation());
		ctrl_usage_notes.setModalObjectFeature(UmaPackage.eINSTANCE
				.getProcessDescription_UsageNotes());
		ctrl_usage_notes.addModifyListener(contentModifyListener);
		ctrl_usage_notes.addListener(SWT.Deactivate, new Listener() {
			public void handleEvent(Event e) {
				IMethodRichText control = descExpandFlag ? ctrl_expanded
						: ctrl_usage_notes;
				if (!control.getModified()) {
					return;
				}
				String oldContent = content.getUsageNotes();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						ctrl_usage_notes, oldContent)) {
					return;
				}
				String newContent = control.getText();
				if (!newContent.equals(oldContent)) {
					actionMgr
							.doAction(IActionManager.SET, process
									.getPresentation(), UmaPackage.eINSTANCE
									.getProcessDescription_UsageNotes(),
									newContent, -1);
				}
			}
		});

		ctrl_alternatives.setModalObject(process.getPresentation());
		ctrl_alternatives.setModalObjectFeature(UmaPackage.eINSTANCE
				.getActivityDescription_Alternatives());
		ctrl_alternatives.addModifyListener(contentModifyListener);
		ctrl_alternatives.addListener(SWT.Deactivate, new Listener() {
			public void handleEvent(Event e) {
				IMethodRichText control = descExpandFlag ? ctrl_expanded
						: ctrl_alternatives;
				if (!control.getModified()) {
					return;
				}
				String oldContent = content.getAlternatives();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						ctrl_alternatives, oldContent)) {
					return;
				}
				String newContent = control.getText();
				if (!newContent.equals(oldContent)) {
					actionMgr.doAction(IActionManager.SET, process
							.getPresentation(), UmaPackage.eINSTANCE
							.getActivityDescription_Alternatives(), newContent,
							-1);
				}
			}
		});

		ctrl_how_to_staff.setModalObject(process.getPresentation());
		ctrl_how_to_staff.setModalObjectFeature(UmaPackage.eINSTANCE
				.getActivityDescription_HowtoStaff());
		ctrl_how_to_staff.addModifyListener(contentModifyListener);
		ctrl_how_to_staff.addListener(SWT.Deactivate, new Listener() {
			public void handleEvent(Event e) {
				IMethodRichText control = descExpandFlag ? ctrl_expanded
						: ctrl_how_to_staff;
				if (!control.getModified()) {
					return;
				}
				String oldContent = content.getHowtoStaff();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						ctrl_how_to_staff, oldContent)) {
					return;
				}
				String newContent = control.getText();
				if (!newContent.equals(oldContent)) {
					actionMgr.doAction(IActionManager.SET, process
							.getPresentation(), UmaPackage.eINSTANCE
							.getActivityDescription_HowtoStaff(), newContent,
							-1);
				}
			}
		});

		ctrl_key_consideration.setModalObject(process.getPresentation());
		ctrl_key_consideration.setModalObjectFeature(UmaPackage.eINSTANCE
				.getContentDescription_KeyConsiderations());
		ctrl_key_consideration.addModifyListener(contentModifyListener);
		ctrl_key_consideration.addListener(SWT.Deactivate, new Listener() {
			public void handleEvent(Event e) {
				IMethodRichText control = descExpandFlag ? ctrl_expanded
						: ctrl_key_consideration;
				if (!control.getModified()) {
					return;
				}
				String oldContent = content.getKeyConsiderations();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						ctrl_key_consideration, oldContent)) {
					return;
				}
				String newContent = control.getText();
				if (!newContent.equals(oldContent)) {
					actionMgr.doAction(IActionManager.SET, process
							.getPresentation(), UmaPackage.eINSTANCE
							.getContentDescription_KeyConsiderations(),
							newContent, -1);
				}
			}
		});

		configListViewer
				.addSelectionChangedListener(new ISelectionChangedListener() {
					public void selectionChanged(SelectionChangedEvent event) {
						IStructuredSelection selection = (IStructuredSelection) configListViewer
								.getSelection();
						if (selection.size() == 1) {
							MethodConfiguration config = ((MethodConfiguration) selection
									.getFirstElement());
							if (!TngUtil.isLocked(methodElement)) {
								if (config == process.getDefaultContext()) {
									buttonRemove.setEnabled(false);
								} else {
									buttonRemove.setEnabled(true);
								}
							}
							String desc = config.getBriefDescription();
							if (desc == null) {
								desc = ""; //$NON-NLS-1$
							}
							textConfigDescription.setText(desc);
						}
					}
				});

		buttonAdd.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				MethodLibrary lib = UmaUtil.getMethodLibrary(process);

				final ConfigurationsItemProvider input = new ConfigurationsItemProvider(
						TngAdapterFactory.INSTANCE
								.getNavigatorView_ComposedAdapterFactory(),
						lib, ""); //$NON-NLS-1$

				ListSelectionDialog dlg = new ListSelectionDialog(
						Display.getCurrent().getActiveShell(),
						input,
						contentProvider,
						labelProvider,
						AuthoringUIResources.ProcessDescription_selectConfiguration) { 
					protected Control createDialogArea(Composite parent) {
						Control control = super.createDialogArea(parent);
						getViewer().addFilter(new ViewerFilter() {

							public boolean select(Viewer viewer,
									Object parentElement, Object element) {
								// int count =
								// configListViewer.getList().getItemCount();
								// for(int i = 0; i < count; i++) {
								// if(element ==
								// configListViewer.getElementAt(i)) return
								// false;
								// }
								// return true;
								return !process.getValidContext().contains(
										element);
							}

						});
						return control;
					}

					public boolean close() {
						input.dispose();
						return super.close();
					}
				};
				if (dlg.open() == Window.OK) {
					Object obs[] = dlg.getResult();
					MethodConfiguration config;
					// get default configuration
//					MethodConfiguration defaultConfig = process
//							.getDefaultContext();
					for (int i = 0; i < obs.length; i++) {
						config = (MethodConfiguration) obs[i];
						if (config != null) {
//								|| checkValidityForSuperSet(defaultConfig,
//										config)) {
							actionMgr.doAction(IActionManager.ADD, process,
									UmaPackage.eINSTANCE
											.getProcess_ValidContext(), config,
									-1);
						} else {
							AuthoringUIPlugin
									.getDefault()
									.getMsgDialog()
									.displayError(
											AuthoringUIResources.addConfigErrorDialog_title, 
											AuthoringUIResources.bind(AuthoringUIResources.invalidConfigError_msg, config.getName())); 
						}
					}
				}
			}
		});

		buttonRemove.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				IStructuredSelection selection = (IStructuredSelection) configListViewer
						.getSelection();
				actionMgr.doAction(IActionManager.REMOVE_MANY, process,
						UmaPackage.eINSTANCE.getProcess_ValidContext(),
						selection.toList(), -1);
			}
		});

		buttonMakeDefault.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				IStructuredSelection selection = (IStructuredSelection) configListViewer
						.getSelection();
				if (selection.size() == 1) {
					MethodConfiguration currentConfig = process
							.getDefaultContext();

					if (currentConfig != selection.getFirstElement()) {
//						boolean isValid = true;
//						List validContext = process.getValidContext();
//						for (Iterator itor = validContext.iterator(); itor
//								.hasNext();) {
//							MethodConfiguration config = (MethodConfiguration) itor
//									.next();
//							if (!(checkValidityForSuperSet(
//									(MethodConfiguration) selection
//											.getFirstElement(), config))) {
//								isValid = false;
//								break;
//							}
//						}
//						if (isValid) {
							boolean status = actionMgr.doAction(
									IActionManager.SET, process,
									UmaPackage.eINSTANCE
											.getProcess_DefaultContext(),
									selection.getFirstElement(), -1);
							if (!status)
								return;
							buttonRemove.setEnabled(false);
//						} else {
//							String selectedConfigName = ((MethodConfiguration) selection
//									.getFirstElement()).getName();
//							AuthoringUIPlugin
//									.getDefault()
//									.getMsgDialog()
//									.displayError(
//											AuthoringUIResources.setDefaultConfigErrorDialog_title, 
//											AuthoringUIResources.bind(AuthoringUIResources.setDefaultConfigError_msg, selectedConfigName)); 
//						}
					}
				}
			}
		});
	}

	/**
	 * Refresh all the controls
	 * 
	 * @param editable
	 */
	protected void refresh(boolean editable) {
		if (!ctrl_name.isDisposed()) {
			ctrl_name.setEditable(editable);
		}
		if (!ctrl_presentation_name.isDisposed()) {
			ctrl_presentation_name.setEditable(editable);
		}
		if (longPresentationNameOn && AuthoringUIPreferences.getEnableUIFields()) {
			if (!ctrl_long_presentation_name.isDisposed()) {
				ctrl_long_presentation_name.setEditable(editable);
			}
		}
		if (!ctrl_brief_desc.isDisposed()) {
			ctrl_brief_desc.setEditable(editable);
		}
		if (!ctrl_purpose.isDisposed()) {
			ctrl_purpose.setEditable(editable);
		}
		if (!ctrl_full_desc.isDisposed()) {
			ctrl_full_desc.setEditable(editable);
		}
		if (!ctrl_alternatives.isDisposed()) {
			ctrl_alternatives.setEditable(editable);
		}
		if (AuthoringUIPreferences.getEnableUIFields()) {
			if (!ctrl_external_id.isDisposed())
				ctrl_external_id.setEditable(editable);
		}
		if (!ctrl_key_consideration.isDisposed())
			ctrl_key_consideration.setEditable(editable);
		if (!ctrl_how_to_staff.isDisposed())
			ctrl_how_to_staff.setEditable(editable);
		if (!ctrl_scope.isDisposed())
			ctrl_scope.setEditable(editable);
		if (!ctrl_usage_notes.isDisposed())
			ctrl_usage_notes.setEditable(editable);
		if (ctrl_expanded != null && !ctrl_expanded.isDisposed()) {
			ctrl_expanded.setEditable(editable);
		}
		
		IStructuredSelection selection = (IStructuredSelection) configListViewer
				.getSelection();
		if (selection.size() == 1) {
			MethodConfiguration config = ((MethodConfiguration) selection
					.getFirstElement());
			if (config == process.getDefaultContext()) {
				if (!buttonRemove.isDisposed())
					buttonRemove.setEnabled(false);
			} else {
				if (!buttonRemove.isDisposed())
					buttonRemove.setEnabled(editable);
			}
			String desc = config.getBriefDescription();
			if (desc == null) {
				desc = ""; //$NON-NLS-1$
			}
			textConfigDescription.setText(desc);
		}
		if (!buttonAdd.isDisposed())
			buttonAdd.setEnabled(editable);
		if (!buttonMakeDefault.isDisposed())
			buttonMakeDefault.setEnabled(editable);
		if (!buttonRemove.isDisposed() && !editable)
			buttonRemove.setEnabled(editable);
	}

	/**
	 * Checks whether default configuration is superset of selected
	 * configuration or not
	 * 
	 * @param config
	 * @return
	 */
	private boolean checkValidityForSuperSet(MethodConfiguration defaultConfig,
			MethodConfiguration config) {
		// get default plugins and packages
		List defaultPlugins = defaultConfig.getMethodPluginSelection();
		List defaultPackages = defaultConfig.getMethodPackageSelection();

		// get confiugration plugins and pacakges
		List packages = config.getMethodPackageSelection();
		List plugins = config.getMethodPluginSelection();
		boolean pluginContains = false;
		boolean packageContains = false;
		if ((plugins != null) ) {
			pluginContains = defaultPlugins.containsAll(plugins);
		}
		if ((packages != null) ) {
			packageContains = defaultPackages.containsAll(packages);
		}

		return (pluginContains) && (packageContains);
	}

	protected void enableSections(boolean enable) {
		generalSection.setVisible(enable);
		if (enable) {
			generalSection.setExpanded(generalSectionExpandFlag);
		} else {
			generalSectionExpandFlag = generalSection.isExpanded();
			generalSection.setExpanded(enable);
		}

		detailSection.setVisible(enable);
		if (enable) {
			detailSection.setExpanded(detailSectionExpandFlag);
		} else {
			detailSectionExpandFlag = detailSection.isExpanded();
			detailSection.setExpanded(enable);
		}
		configSection.setVisible(enable);
		if (enable) {
			configSection.setExpanded(configSectionExpandFlag);
		} else {
			configSectionExpandFlag = configSection.isExpanded();
			configSection.setExpanded(enable);
		}
	}

	/**
	 * Set name for the form
	 */
	public void setFormText() {

		form.setText(LibraryUIText.getUIText(process)
				+ ": " + methodElement.getName()); //$NON-NLS-1$
	}

	/**
	 * Refresh form name
	 * @param newName
	 */
	public void refreshElementName(final String newName) {
		if (newName != null) {
			if ((ctrl_name != null) && !(ctrl_name.isDisposed())) {
				Runnable runnable = new Runnable() {

					public void run() {
						ctrl_name.removeModifyListener(nameModifyListener);
						ctrl_name.setText(newName);
						ctrl_name.addModifyListener(nameModifyListener);
						setFormText();
					}
					
				};
				if (ctrl_name.getDisplay().getThread() == Thread.currentThread()) {
					runnable.run();
				} else {
					ctrl_name.getDisplay().syncExec(runnable);
				}

			}
		}
	}

	@Override
	protected void setContextHelp() {
		super.setContextHelp();
		EditorsContextHelper.setHelp(getPartControl(), processType);
	}
}
