//------------------------------------------------------------------------------
// 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.properties;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.ecore.EObject;
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.dialogs.ItemsFilterDialog;
import org.eclipse.epf.authoring.ui.filters.ProcessGuidanceFilter;
import org.eclipse.epf.diagram.model.util.DiagramInfo;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.configuration.GuidanceGroupingItemProvider;
import org.eclipse.epf.library.edit.configuration.GuidanceItemProvider;
import org.eclipse.epf.library.edit.itemsfilter.FilterConstants;
import org.eclipse.epf.library.edit.itemsfilter.FilterInitializer;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.process.command.AddGuidanceToActivityCommand;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.Checklist;
import org.eclipse.epf.uma.Concept;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.Example;
import org.eclipse.epf.uma.Guidance;
import org.eclipse.epf.uma.Guideline;
import org.eclipse.epf.uma.ReusableAsset;
import org.eclipse.epf.uma.Roadmap;
import org.eclipse.epf.uma.SupportingMaterial;
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.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Table;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;

/**
 * The activity guidance section. It list all avaiable guidances of an activity
 * 
 * @author Shilpa Toraskar
 * @since 1.0
 * 
 */
public class ActivityGuidanceSection extends AbstractSection {
	protected ILabelProvider labelProvider = new AdapterFactoryLabelProvider(
			TngAdapterFactory.INSTANCE
					.getNavigatorView_ComposedAdapterFactory());

	private FormToolkit toolkit;

	private Button ctrl_add_1, ctrl_remove_1, ctrl_add_2, ctrl_remove_2;

	private Button ctrl_add_3, ctrl_remove_3, ctrl_add_4, ctrl_remove_4;

	private Table ctrl_table_1, ctrl_table_2, ctrl_table_3, ctrl_table_4;

	private Section communicationMaterialSection, educationMaterialSection;

	private TableViewer viewer_1, viewer_2, viewer_3, viewer_4;

	// element
	private Activity element;

	// action manager
	private IActionManager actionMgr;

	public final String tabName = FilterConstants.GUIDANCE;

	private IFilter roadMapFilter = null;

	private IFilter generalGuidanceFilter = null;

	private IFilter supportingMaterialFilter = null;

	/**
	 * Get road map guidance filter
	 */
	public IFilter getRoadMapFilter() {
		if (roadMapFilter == null) {
			roadMapFilter = new ProcessGuidanceFilter(getConfiguration(), null,
					tabName) {
				public boolean childAccept(Object obj) {
					if (obj instanceof GuidanceGroupingItemProvider)
						return true;
					if (obj instanceof GuidanceItemProvider) {
						String name = ((GuidanceItemProvider) obj).getText(obj);
						if (name.equalsIgnoreCase(LibraryEditPlugin.INSTANCE
								.getString("_UI_Guidances_Roadmap")) && //$NON-NLS-1$
								!((GuidanceItemProvider) obj).getChildren(obj)
										.isEmpty())
							return true;
						else
							return false;
					}
					if ((obj instanceof Roadmap))
						return true;
					return false;
				}
			};
		} else {
			((ProcessGuidanceFilter) roadMapFilter).setMethodConfiguration(getConfiguration());
		}

		return roadMapFilter;
	}

	/**
	 * Get General guidance filter
	 * 
	 */
	public IFilter getGeneralGuidanceFilter() {
		if (generalGuidanceFilter == null) {
			generalGuidanceFilter = new ProcessGuidanceFilter(
					getConfiguration(), null, tabName) {
				public boolean childAccept(Object obj) {
					if (super.childAccept(obj))
						return true;
					if (obj instanceof GuidanceItemProvider) {
						if (((GuidanceItemProvider) obj).getChildren(obj)
								.isEmpty())
							return false;
						else
							return true;
					}
					Class cls = FilterInitializer.getInstance()
							.getClassForType(helper.getFilterTypeStr());
					if (cls != null) {
						if (cls.isInstance(obj)) {
							return true;
						} else {
							return false;
						}
					}
					if ((obj instanceof Checklist) || (obj instanceof Concept)
							|| (obj instanceof Example)
							|| (obj instanceof Guideline)
							|| (obj instanceof ReusableAsset)
							|| (obj instanceof SupportingMaterial))
						return true;

					return false;

				}
			};
		}else {
			((ProcessGuidanceFilter) generalGuidanceFilter).setMethodConfiguration(getConfiguration());
		}
		return generalGuidanceFilter;
	}

	/**
	 * Get Supporting materical guidance filter
	 * 
	 */
	public IFilter getSupportingMaterialFilter() {
		if (supportingMaterialFilter == null) {
			supportingMaterialFilter = new ProcessGuidanceFilter(
					getConfiguration(), null, tabName) {
				public boolean childAccept(Object obj) {
					if (super.childAccept(obj))
						return true;
					if ((obj instanceof GuidanceItemProvider)
							|| (obj instanceof SupportingMaterial))
						return true;
					return false;
				}
			};
		} else {
			((ProcessGuidanceFilter) supportingMaterialFilter).setMethodConfiguration(getConfiguration());
		}
		return supportingMaterialFilter;
	}


	/**
	 * @see org.eclipse.epf.authoring.ui.properties.AbstractSection#createControls(org.eclipse.swt.widgets.Composite, org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
	 */
	public void createControls(Composite parent,
			TabbedPropertySheetPage tabbedPropertySheetPage) {

		super.createControls(parent, tabbedPropertySheetPage);
		init();

		parent.setLayout(new GridLayout());
		parent.setLayoutData(new GridData(GridData.FILL_BOTH));

		// create guidance section
		createGuidanceSection(parent);

		// add listeners
		addListeners();

		// update controls
		updateControls();

	}

	/**
	 * Initialize
	 */
	private void init() {
		// get activity object
		element = (Activity) getElement();

		// get toolkit
		toolkit = getWidgetFactory();

		// get action manager
		actionMgr = EPFPropertySheetPage.getActionManager();
	}

	private void toggleSection() {
		if (!(element instanceof DeliveryProcess)) {
			if (communicationMaterialSection.isExpanded())
				communicationMaterialSection.setExpanded(false);
			if (educationMaterialSection.isExpanded())
				educationMaterialSection.setExpanded(false);

			if (communicationMaterialSection.isVisible())
				communicationMaterialSection.setVisible(false);
			if (educationMaterialSection.isVisible())
				educationMaterialSection.setVisible(false);
		} else {
			if (!communicationMaterialSection.isExpanded())
				communicationMaterialSection.setExpanded(true);
			if (!educationMaterialSection.isExpanded())
				educationMaterialSection.setExpanded(true);

			if (!communicationMaterialSection.isVisible())
				communicationMaterialSection.setVisible(true);
			if (!educationMaterialSection.isVisible())
				educationMaterialSection.setVisible(true);
		}

	}

	/**
	 *  Update controls based on editable flag. Controls can become editable or un-editable
	 */
	public void updateControls() {
		ctrl_add_1.setEnabled(editable);
		ctrl_add_2.setEnabled(editable);
		ctrl_add_3.setEnabled(editable);
		ctrl_add_4.setEnabled(editable);

		IStructuredSelection selection = (IStructuredSelection) viewer_1
				.getSelection();
		if (selection.size() > 0 && editable) {
			ctrl_remove_1.setEnabled(true);
		} else {
			ctrl_remove_1.setEnabled(false);
		}

		selection = (IStructuredSelection) viewer_2.getSelection();
		if (selection.size() > 0 && editable) {
			ctrl_remove_2.setEnabled(true);
		} else {
			ctrl_remove_2.setEnabled(false);
		}

		selection = (IStructuredSelection) viewer_3.getSelection();
		if (selection.size() > 0 && editable) {
			ctrl_remove_3.setEnabled(true);
		} else {
			ctrl_remove_3.setEnabled(false);
		}

		selection = (IStructuredSelection) viewer_4.getSelection();
		if (selection.size() > 0 && editable) {
			ctrl_remove_4.setEnabled(true);
		} else {
			ctrl_remove_4.setEnabled(false);
		}
	}


	/**
	 * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
	 */
	public void refresh() {
		try {
			if (getElement() instanceof Activity) {
				element = (Activity) getElement();

				viewer_1.refresh();
				viewer_2.refresh();
				viewer_3.refresh();
				viewer_4.refresh();

				// hide/show certain sections.
				toggleSection();

				// hide/show controls
				updateControls();
			}

		} catch (Exception ex) {
			logger.logError("Error refreshing activity guidance section: ", ex); //$NON-NLS-1$
		}
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.properties.AbstractSection#dispose()
	 */
	public void dispose() {
		super.dispose();

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

	/**
	 * Create guidance section on the given composite
	 * @param composite
	 */
	private void createGuidanceSection(Composite composite) {
		int tableHeight = 50;
		String sectionTitle = null;
		String sectionDesc = null;
		String tableTitle = null;
		// Label tableLabel = null;

		// ROADMAP
		{
			sectionTitle = PropertiesResources.Activity_RoadmapTitle; //$NON-NLS-1$
			sectionDesc = PropertiesResources.Activity_RoadmapDescription; //$NON-NLS-1$
			tableTitle = PropertiesResources.Activity_Selected_Roadmap; //$NON-NLS-1$

			Section section = FormUI.createSection(toolkit, composite,
					sectionTitle, sectionDesc);

			// create composite
			Composite sectionComposite = FormUI.createComposite(toolkit,
					section, 2, false);

			Composite pane1 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.FILL_BOTH);
			FormUI.createLabel(toolkit, pane1, tableTitle);

			ctrl_table_1 = FormUI.createTable(toolkit, pane1, tableHeight);
			viewer_1 = new TableViewer(ctrl_table_1);
			IStructuredContentProvider contentProvider = new AdapterFactoryContentProvider(
					getAdapterFactory()) {
				public Object[] getElements(Object object) {
					return getFilteredList(element.getRoadmaps()).toArray();
				}
			};

			viewer_1.setContentProvider(contentProvider);
			viewer_1.setLabelProvider(labelProvider);
			viewer_1.setInput(element);

			// create buttons for table1
			Composite pane2 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.VERTICAL_ALIGN_CENTER
							| GridData.HORIZONTAL_ALIGN_CENTER);

			ctrl_add_1 = FormUI.createButton(toolkit, pane2,
					PropertiesResources.Process_Add);
			ctrl_remove_1 = FormUI.createButton(toolkit, pane2,
					PropertiesResources.Process_Remove);

			toolkit.paintBordersFor(pane1);
		}

		// GENERAL GUIDANCE
		{
			sectionTitle = PropertiesResources.Activity_GeneralGuidanceTitle; //$NON-NLS-1$
			sectionDesc = PropertiesResources.Activity_GeneralGuidanceDescription; //$NON-NLS-1$
			tableTitle = PropertiesResources.Activity_Selected_GeneralGuidance; //$NON-NLS-1$

			Section section = FormUI.createSection(toolkit, composite,
					sectionTitle, sectionDesc);

			// create composite
			Composite sectionComposite = FormUI.createComposite(toolkit,
					section, 2, false);

			Composite pane1 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.FILL_BOTH);
			FormUI.createLabel(toolkit, pane1, tableTitle);

			ctrl_table_2 = FormUI.createTable(toolkit, pane1, tableHeight);
			viewer_2 = new TableViewer(ctrl_table_2);
			IStructuredContentProvider contentProvider = new AdapterFactoryContentProvider(
					getAdapterFactory()) {
				public Object[] getElements(Object object) {
					return getFilteredList(getSelectedGuidances()).toArray();
				}
			};

			viewer_2.setContentProvider(contentProvider);
			viewer_2.setLabelProvider(labelProvider);
			viewer_2.setInput(element);

			// create buttons for table2
			Composite pane2 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.VERTICAL_ALIGN_CENTER
							| GridData.HORIZONTAL_ALIGN_CENTER);

			ctrl_add_2 = FormUI.createButton(toolkit, pane2,
					PropertiesResources.Process_Add);
			ctrl_remove_2 = FormUI.createButton(toolkit, pane2,
					PropertiesResources.Process_Remove);

			toolkit.paintBordersFor(pane1);
		}

		// COMMUNICATION MATERIAL
		{
			sectionTitle = PropertiesResources.Activity_CommunicationMaterialTitle; //$NON-NLS-1$
			sectionDesc = PropertiesResources.Activity_CommunicationMaterialDescription; //$NON-NLS-1$
			tableTitle = PropertiesResources.Activity_Selected_CommunicationMaterial; //$NON-NLS-1$

			Section section = FormUI.createSection(toolkit, composite,
					sectionTitle, sectionDesc);

			// create composite
			Composite sectionComposite = FormUI.createComposite(toolkit,
					section, 2, false);

			Composite pane1 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.FILL_BOTH);
			FormUI.createLabel(toolkit, pane1, tableTitle);

			ctrl_table_3 = FormUI.createTable(toolkit, pane1, tableHeight);
			viewer_3 = new TableViewer(ctrl_table_3);
			IStructuredContentProvider contentProvider = new AdapterFactoryContentProvider(
					getAdapterFactory()) {
				public Object[] getElements(Object object) {
					if (element instanceof DeliveryProcess) {
						return getFilteredList(
								((DeliveryProcess) element)
										.getCommunicationsMaterials())
								.toArray();
					} else
						return Collections.EMPTY_LIST.toArray();
				}
			};

			viewer_3.setContentProvider(contentProvider);
			viewer_3.setLabelProvider(labelProvider);
			viewer_3.setInput(element);

			// create buttons for table2
			Composite pane2 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.VERTICAL_ALIGN_CENTER
							| GridData.HORIZONTAL_ALIGN_CENTER);

			ctrl_add_3 = FormUI.createButton(toolkit, pane2,
					PropertiesResources.Process_Add);
			ctrl_remove_3 = FormUI.createButton(toolkit, pane2,
					PropertiesResources.Process_Remove);

			toolkit.paintBordersFor(pane1);

			communicationMaterialSection = section;

		}

		// EDUCATION MATERIAL
		{
			sectionTitle = PropertiesResources.Activity_EducationMaterialTitle; //$NON-NLS-1$
			sectionDesc = PropertiesResources.Activity_EducationMaterialDescription; //$NON-NLS-1$
			tableTitle = PropertiesResources.Activity_Selected_EducationMaterial; //$NON-NLS-1$

			Section section = FormUI.createSection(toolkit, composite,
					sectionTitle, sectionDesc);

			// create composite
			Composite sectionComposite = FormUI.createComposite(toolkit,
					section, 2, false);

			Composite pane1 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.FILL_BOTH);
			FormUI.createLabel(toolkit, pane1, tableTitle);

			ctrl_table_4 = FormUI.createTable(toolkit, pane1, tableHeight);
			viewer_4 = new TableViewer(ctrl_table_4);
			IStructuredContentProvider contentProvider = new AdapterFactoryContentProvider(
					getAdapterFactory()) {
				public Object[] getElements(Object object) {
					if (element instanceof DeliveryProcess) {
						return getFilteredList(
								((DeliveryProcess) element)
										.getEducationMaterials()).toArray();
					} else
						return Collections.EMPTY_LIST.toArray();
				}
			};

			viewer_4.setContentProvider(contentProvider);
			viewer_4.setLabelProvider(labelProvider);
			viewer_4.setInput(element);

			// create buttons for table2
			Composite pane2 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.VERTICAL_ALIGN_CENTER
							| GridData.HORIZONTAL_ALIGN_CENTER);

			ctrl_add_4 = FormUI.createButton(toolkit, pane2,
					PropertiesResources.Process_Add);
			ctrl_remove_4 = FormUI.createButton(toolkit, pane2,
					PropertiesResources.Process_Remove);

			toolkit.paintBordersFor(pane1);

			educationMaterialSection = section;

		}

		// hide/show certain sections
		toggleSection();
	}

	/**
	 * Add listeners
	 * 
	 */
	private void addListeners() {
		ItemProviderAdapter adapter = (ItemProviderAdapter) getAdapter();
		Object parent = null;
		if (adapter instanceof IBSItemProvider) {
			IBSItemProvider bsItemProvider = (IBSItemProvider) adapter;
			parent = bsItemProvider.getTopItem();
		} else {
			logger
					.logError("ActivityGuidanceSection::addListeners - IBSItemProvider is null"); //$NON-NLS-1$
			return;
		}

		{
			ctrl_table_1.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					IStructuredSelection selection = (IStructuredSelection) viewer_1
							.getSelection();
					if ((selection.size() > 0) && editable)
						ctrl_remove_1.setEnabled(true);
				}
			});

			viewer_1
					.addSelectionChangedListener(new ISelectionChangedListener() {
						public void selectionChanged(SelectionChangedEvent event) {
							IStructuredSelection selection = (IStructuredSelection) viewer_1
									.getSelection();
							if ((selection.size() > 0) && editable)
								ctrl_remove_1.setEnabled(true);
						}
					});

			ctrl_add_1.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					IFilter filter = getRoadMapFilter();
					ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
							.getWorkbench().getActiveWorkbenchWindow()
							.getShell(), filter, element,
							FilterConstants.ROADMAP, element.getRoadmaps());

					fd.setTitle(FilterConstants.ROADMAP);
					fd.setInput(UmaUtil.getMethodLibrary((EObject) element));
					fd.setBlockOnOpen(true);
					fd.open();
					addGuidances(fd.getSelectedItems());
					viewer_1.refresh();
				}
			});

			ctrl_remove_1.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					IStructuredSelection selection = (IStructuredSelection) viewer_1
							.getSelection();
					if (selection.size() > 0) {
						// update the model
						ArrayList rmItems = new ArrayList();
						rmItems.addAll(selection.toList());
						removeGuidances(rmItems);
						viewer_1.refresh();

						// clear the selection
						viewer_1.setSelection(null, true);
					}
					ctrl_remove_1.setEnabled(false);
				}
			});
		}

		{
			ctrl_table_2.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					IStructuredSelection selection = (IStructuredSelection) viewer_2
							.getSelection();
					if ((selection.size() > 0) && editable)
						ctrl_remove_2.setEnabled(true);
				}
			});

			viewer_2
					.addSelectionChangedListener(new ISelectionChangedListener() {
						public void selectionChanged(SelectionChangedEvent event) {
							IStructuredSelection selection = (IStructuredSelection) viewer_2
									.getSelection();
							if ((selection.size() > 0) && editable)
								ctrl_remove_2.setEnabled(true);
						}
					});

			ctrl_add_2.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					IFilter filter = getGeneralGuidanceFilter();
					ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
							.getWorkbench().getActiveWorkbenchWindow()
							.getShell(), filter, element,
							FilterConstants.GUIDANCE, getExistingElements()); //$NON-NLS-1$

					fd.setTitle(FilterConstants.GUIDANCE);
					fd.setInput(UmaUtil.getMethodLibrary((EObject) element));
					fd.setBlockOnOpen(true);
					fd.setTypes(getFilterTypes());
					fd.open();
					addGuidances(fd.getSelectedItems());
					viewer_2.refresh();
				}
			});

			ctrl_remove_2.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					IStructuredSelection selection = (IStructuredSelection) viewer_2
							.getSelection();
					if (selection.size() > 0) {
						// update the model
						ArrayList rmItems = new ArrayList();
						rmItems.addAll(selection.toList());
						removeGuidances(rmItems);
						viewer_2.refresh();

						// clear the selection
						viewer_2.setSelection(null, true);
					}
					ctrl_remove_2.setEnabled(false);
				}
			});
		}

		{
			ctrl_table_3.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					IStructuredSelection selection = (IStructuredSelection) viewer_3
							.getSelection();
					if ((selection.size() > 0) && editable)
						ctrl_remove_3.setEnabled(true);
				}
			});

			viewer_3
					.addSelectionChangedListener(new ISelectionChangedListener() {
						public void selectionChanged(SelectionChangedEvent event) {
							IStructuredSelection selection = (IStructuredSelection) viewer_3
									.getSelection();
							if ((selection.size() > 0) && editable)
								ctrl_remove_3.setEnabled(true);
						}
					});

			ctrl_add_3.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					if (element instanceof DeliveryProcess) {
						DeliveryProcess proc = (DeliveryProcess) element;

						IFilter filter = getSupportingMaterialFilter();
						ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
								.getWorkbench().getActiveWorkbenchWindow()
								.getShell(), filter, proc,
								FilterConstants.SUPPORTING_MATERIALS, proc
										.getCommunicationsMaterials());

						fd.setTitle(FilterConstants.GUIDANCE);
						fd
								.setInput(UmaUtil
										.getMethodLibrary((EObject) element));
						fd.setBlockOnOpen(true);
						fd.open();

						actionMgr
								.doAction(
										IActionManager.ADD_MANY,
										proc,
										UmaPackage.eINSTANCE
												.getDeliveryProcess_CommunicationsMaterials(),
										fd.getSelectedItems(), -1);
					}

					viewer_3.refresh();
				}
			});

			ctrl_remove_3.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					IStructuredSelection selection = (IStructuredSelection) viewer_3
							.getSelection();
					if (selection.size() > 0) {
						// update the model
						ArrayList rmItems = new ArrayList();
						rmItems.addAll(selection.toList());

						if (element instanceof DeliveryProcess) {
							DeliveryProcess proc = (DeliveryProcess) element;
							actionMgr
									.doAction(
											IActionManager.REMOVE_MANY,
											proc,
											UmaPackage.eINSTANCE
													.getDeliveryProcess_CommunicationsMaterials(),
											rmItems, -1);
						}
						viewer_3.refresh();

						// clear the selection
						viewer_3.setSelection(null, true);
					}
					ctrl_remove_3.setEnabled(false);
				}
			});
		}

		{
			ctrl_table_4.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					IStructuredSelection selection = (IStructuredSelection) viewer_4
							.getSelection();
					if ((selection.size() > 0) && editable)
						ctrl_remove_4.setEnabled(true);
				}
			});

			viewer_4
					.addSelectionChangedListener(new ISelectionChangedListener() {
						public void selectionChanged(SelectionChangedEvent event) {
							IStructuredSelection selection = (IStructuredSelection) viewer_4
									.getSelection();
							if ((selection.size() > 0) && editable)
								ctrl_remove_4.setEnabled(true);
						}
					});

			ctrl_add_4.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					if (element instanceof DeliveryProcess) {
						DeliveryProcess proc = (DeliveryProcess) element;

						IFilter filter = getSupportingMaterialFilter();
						ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
								.getWorkbench().getActiveWorkbenchWindow()
								.getShell(), filter, proc,
								FilterConstants.SUPPORTING_MATERIALS, proc
										.getEducationMaterials());

						fd.setTitle(FilterConstants.GUIDANCE);
						fd
								.setInput(UmaUtil
										.getMethodLibrary((EObject) element));
						fd.setBlockOnOpen(true);
						fd.open();

						actionMgr
								.doAction(
										IActionManager.ADD_MANY,
										proc,
										UmaPackage.eINSTANCE
												.getDeliveryProcess_EducationMaterials(),
										fd.getSelectedItems(), -1);

						viewer_4.refresh();
					}
				}
			});

			ctrl_remove_4.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					IStructuredSelection selection = (IStructuredSelection) viewer_4
							.getSelection();
					if (selection.size() > 0) {
						// update the model
						ArrayList rmItems = new ArrayList();
						rmItems.addAll(selection.toList());
						if (element instanceof DeliveryProcess) {
							DeliveryProcess proc = (DeliveryProcess) element;
							actionMgr
									.doAction(
											IActionManager.REMOVE_MANY,
											proc,
											UmaPackage.eINSTANCE
													.getDeliveryProcess_EducationMaterials(),
											rmItems, -1);
						}
						viewer_4.refresh();

						// clear the selection
						viewer_4.setSelection(null, true);

					}
					ctrl_remove_4.setEnabled(false);
				}
			});
		}

	}

	/**
	 * Add guidances to the element
	 * @param addItems
	 * 				list of guidances to add
	 */
	private void addGuidances(ArrayList addItems) {
		// update the model

		AddGuidanceToActivityCommand command = new AddGuidanceToActivityCommand(
				element, addItems);
		actionMgr.execute(command);
	}

	/**
	 * Remove guidances from the element
	 * @param rmItems
	 * 				list of guidances to remove
	 */
	private void removeGuidances(ArrayList rmItems) {
		// update the model
		if (!rmItems.isEmpty()) {
			for (Iterator it = rmItems.iterator(); it.hasNext();) {
				Guidance item = (Guidance) it.next();

				// guidances for activity
				if (item instanceof Checklist) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getActivity_Checklists(),
							item, -1);
				} else if (item instanceof Concept) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getActivity_Concepts(), item,
							-1);
				} else if (item instanceof Example) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getActivity_Examples(), item,
							-1);
				} else if (item instanceof SupportingMaterial) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE
									.getActivity_SupportingMaterials(), item,
							-1);
				} else if (item instanceof Guideline) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getActivity_Guidelines(),
							item, -1);
				} else if (item instanceof ReusableAsset) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getActivity_ReusableAssets(),
							item, -1);
				} else if (item instanceof Roadmap) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getActivity_Roadmaps(), item,
							-1);
				} else {
					logger
							.logError("Can't remove Guidance: " + item.getType().getName() + ":" + item.getName()); //$NON-NLS-1$ //$NON-NLS-2$
				}
			}
		}
	}

	/**
	 * Get existing guidances of the element
	 * @return
	 * 			list of existing guidances.
	 */
	private List getExistingElements() {

		List itemList = new ArrayList();

		itemList.addAll(element.getChecklists());
		itemList.addAll(element.getConcepts());
		itemList.addAll(element.getExamples());
		itemList.addAll(element.getGuidelines());
		itemList.addAll(element.getReusableAssets());
		itemList.addAll(element.getSupportingMaterials());

		DiagramInfo info = new DiagramInfo((Activity) element);
		if (info.getActivityDiagram() != null)
			itemList.add(info.getActivityDiagram());
		if (info.getActivityDetailDiagram() != null)
			itemList.add(info.getActivityDetailDiagram());
		if (info.getWPDDiagram() != null)
			itemList.add(info.getWPDDiagram());

		return itemList;
	}

	/**
	 * Get selected guidances
	 * @return
	 * 			list of selected guidances
	 */
	private List getSelectedGuidances() {
		List itemList = new ArrayList();

		itemList.addAll(element.getChecklists());
		itemList.addAll(element.getConcepts());
		itemList.addAll(element.getExamples());
		itemList.addAll(element.getGuidelines());
		itemList.addAll(element.getReusableAssets());
		List supportingMaterials = element.getSupportingMaterials();
		DiagramInfo info = new DiagramInfo((Activity) element);
		for (Iterator itor = supportingMaterials.iterator(); itor.hasNext();) {
			Object obj = itor.next();
			if (obj instanceof SupportingMaterial)
				if (!info.isDiagram((SupportingMaterial) obj)) {
					itemList.add(obj);
				}
		}

		return itemList;
	}

	/**
	 * Return list of filter types
	 */
	protected String[] getFilterTypes() {
		String[] str = new String[14];
		int i = 0;
		str[i++] = FilterConstants.GUIDANCE;
		str[i++] = FilterConstants.space + FilterConstants.CHECKLISTS;
		str[i++] = FilterConstants.space + FilterConstants.CONCEPTS;
		str[i++] = FilterConstants.space
				+ FilterConstants.ESTIMATE_CONSIDERATIONS;
		str[i++] = FilterConstants.space + FilterConstants.EXAMPLES;
		str[i++] = FilterConstants.space + FilterConstants.GUIDELINES;
		str[i++] = FilterConstants.space + FilterConstants.PRACTICES;
		str[i++] = FilterConstants.space + FilterConstants.REPORTS;
		str[i++] = FilterConstants.space + FilterConstants.REUSABLE_ASSETS;
		str[i++] = FilterConstants.space + FilterConstants.SUPPORTING_MATERIALS;
		str[i++] = FilterConstants.space + FilterConstants.TEMPLATES;
		str[i++] = FilterConstants.space + FilterConstants.TOOL_MENTORS;
		str[i++] = FilterConstants.space + FilterConstants.WHITE_PAPERS;
		str[i++] = FilterConstants.space + FilterConstants.TERM_DEFINITIONS;
		return str;
	}
}