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

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.edit.provider.WrapperItemProvider;
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.editors.ColumnDescriptor;
import org.eclipse.epf.authoring.ui.editors.ProcessEditor;
import org.eclipse.epf.common.serviceability.MsgDialog;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.ui.LibraryUIText;
import org.eclipse.epf.uma.Milestone;
import org.eclipse.epf.uma.TeamProfile;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.WorkBreakdownElement;
import org.eclipse.epf.uma.WorkOrder;
import org.eclipse.epf.uma.WorkOrderType;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.ICellEditorValidator;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
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.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.PlatformUI;


/**
 * The general tab section for WorkBreakdownElement
 * 
 * @author Shilpa Toraskar
 * @since 1.0
 * 
 */
public class WorkBreakdownElementGeneralSection extends
		BreakdownElementGeneralSection {
	protected WorkBreakdownElement element;

	protected Button eventDrivenButton, ongoingButton, repeatableButton;

	// protected Text predecessorText;
	protected Button addButton, editButton, removeButton;

	// private SelectionListener eventDrivenButtonSelectionListener;
	// private SelectionListener ongoingButtonSelectionListener;
	// private SelectionListener repeatableButtonSelectionListener;

	// private Listener predecessorsListener;

	// private ComposedAdapterFactory adapterFactory;

	private TableViewer viewer;

	// private Table table;
	private TextCellEditor textCellEditor;

	private ValidatingTextCellEditor idCellEditor;

	private ComboBoxCellEditor comboBoxCellEditor;

	// predecessor map list
	private List predMapList = new ArrayList();

	private class ValidatingTextCellEditor extends TextCellEditor {
		protected Object lastInvalidElement;

		private int columnIndex;

		/**
		 * @param parent
		 */
		public ValidatingTextCellEditor(Composite parent) {
			super(parent);
		}

		void setColumnIndex(int columnIndex) {
			this.columnIndex = columnIndex;
		}

		public int getColumnIndex() {
			return columnIndex;
		}

		public Object getLastInvalidElement() {
			return lastInvalidElement;
		}

		String isValid(String txt) {
			IStructuredSelection selection = (IStructuredSelection) viewer
					.getSelection();
			if (selection.size() == 1) {
				Object e = selection.getFirstElement();
				String msg = isValid(e, txt);
				if (msg != null) {
					lastInvalidElement = e;
				} else {
					lastInvalidElement = null;
				}
				return msg;
			}
			return null;
		}

		protected String isValid(Object e, String txt) {
			return null;
		}
	}

	/** Dependency Literals * */
	private static final String FINISH_TO_START = PropertiesResources.WorkOrderType_FINISH_TO_START; //$NON-NLS-1$

	private static final String FINISH_TO_FINISH = PropertiesResources.WorkOrderType_FINISH_TO_FINISH; //$NON-NLS-1$

	private static final String START_TO_START = PropertiesResources.WorkOrderType_START_TO_START; //$NON-NLS-1$

	private static final String START_TO_FINISH = PropertiesResources.WorkOrderType_START_TO_FINISH; //$NON-NLS-1$

	/** Column ids * */
	private static final String COL_ID = IBSItemProvider.COL_ID;

	private static final String COL_PRESENTATION_NAME = IBSItemProvider.COL_PRESENTATION_NAME;

	private static final String COL_DEPENDENCY = "dependency"; //$NON-NLS-1$

	/** Column descriptor constants */
	public static final ColumnDescriptor COL_DESC_ID = new ColumnDescriptor(
			COL_ID,
			PropertiesResources.WorkBreakdownElement_Dependency_COL_ID_TEXT, 0, 100, true, ColumnDescriptor.CELL_EDITOR_TYPE_TEXT, SWT.CENTER); //$NON-NLS-1$

	public static final ColumnDescriptor COL_DESC_PRESENTATION_NAME = new ColumnDescriptor(
			COL_PRESENTATION_NAME,
			PropertiesResources.WorkBreakdownElement_Dependency_COL_PRESENTATION_NAME_TEXT, 1, 250, true, ColumnDescriptor.CELL_EDITOR_TYPE_NONE); //$NON-NLS-1$

	public static final ColumnDescriptor COL_DESC_DEPENDENCY = new ColumnDescriptor(
			COL_DEPENDENCY,
			PropertiesResources.WorkBreakdownElement_Dependency_COL_DEPENDENCY_TEXT, 2, 100, true, ColumnDescriptor.CELL_EDITOR_TYPE_COMBO_BOOLEAN); //$NON-NLS-1$

	ColumnDescriptor[] columnDescriptors = new ColumnDescriptor[] {
			COL_DESC_ID, COL_DESC_PRESENTATION_NAME, COL_DESC_DEPENDENCY };

	private static class CellEditorValidator implements ICellEditorValidator {

		private ValidatingTextCellEditor cellEditor;

		/**
		 * 
		 */
		public CellEditorValidator(ValidatingTextCellEditor cellEditor) {
			this.cellEditor = cellEditor;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.viewers.ICellEditorValidator#isValid(java.lang.Object)
		 */
		public String isValid(Object value) {
			return cellEditor.isValid((String) value);
		}

	}

	private class ValidatingDeactivateListener implements Listener {
		private ValidatingTextCellEditor cellEditor;

		ValidatingDeactivateListener(ValidatingTextCellEditor cellEditor) {
			this.cellEditor = cellEditor;
		}

		public void handleEvent(Event e) {
			Display.getCurrent().asyncExec(new Runnable() {
				public void run() {
					// System.out.println("ValidatDeactivatee::run");
					if (cellEditor.getLastInvalidElement() != null) {
						String message = cellEditor.getErrorMessage();
						String title = getEditor().getTitle();
						String problem = PropertiesResources.ProcessEditorFormProperties_textEditCell_problem_msg; //$NON-NLS-1$
						MsgDialog dialog = AuthoringUIPlugin.getDefault()
								.getMsgDialog();
						dialog.displayError(title, problem, message); //$NON-NLS-1$
						viewer.editElement(cellEditor.getLastInvalidElement(),
								cellEditor.getColumnIndex());
					}
				}

			});
		}
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.properties.BreakdownElementGeneralSection#init()
	 */
	protected void init() {
		super.init();

		// get workbreakdownelement object
		element = (WorkBreakdownElement) getElement();
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.properties.BreakdownElementGeneralSection#createGeneralSection(org.eclipse.swt.widgets.Composite)
	 */
	protected void createGeneralSection(Composite composite) {
		super.createGeneralSection(composite);

		// Event Driven
		eventDrivenButton = FormUI.createCheckButton(toolkit, checkBoxComposite,
				1);
		eventDrivenButton.setText(PropertiesResources.WorkBreakdownElement_EventDriven); //$NON-NLS-1$

		// Ongoing
		ongoingButton = FormUI.createCheckButton(toolkit, checkBoxComposite,
				1);
		ongoingButton.setText(PropertiesResources.WorkBreakdownElement_Ongoing); //$NON-NLS-1$

		// repeatable
		repeatableButton = FormUI.createCheckButton(toolkit, checkBoxComposite,
				2);
		repeatableButton.setText(PropertiesResources.WorkBreakdownElement_Repeatable); //$NON-NLS-1$

		// predecessors
		// FormUI.createLabel(toolkit, generalComposite,
		// PropertiesResources.getString("WorkBreakdownElement.Predecessors"));
		// predecessorText = FormUI.createText(toolkit, generalComposite,
		// SWT.DEFAULT, horizontalSpan);
		// predecessorText.setText(getPredecessorsList());

		// depenency type

		FormUI.createLabel(toolkit, generalComposite, PropertiesResources.WorkBreakdownElement_Dependency); //$NON-NLS-1$

		try {
			// create viewer
			createViewer(generalComposite, 2);
		} catch (Exception ex) {
			logger
					.logError(
							"Error creating viewer for workbreakdown element general section: ", ex); //$NON-NLS-1$
		}

		// create button pane
		Composite buttonPane = toolkit.createComposite(generalComposite);
		buttonPane.setLayoutData(new GridData(GridData.FILL_VERTICAL));
		buttonPane.setLayout(new GridLayout());

		FormUI.createLabel(toolkit, buttonPane, ""); //$NON-NLS-1$
		addButton = FormUI.createButton(toolkit, buttonPane,
				PropertiesResources.WorkBreakdownElement_Dependency_Add); //$NON-NLS-1$
		editButton = FormUI.createButton(toolkit, buttonPane,
				PropertiesResources.WorkBreakdownElement_Dependency_Edit); //$NON-NLS-1$
		removeButton = FormUI.createButton(toolkit, buttonPane,
				PropertiesResources.WorkBreakdownElement_Dependency_Remove); //$NON-NLS-1$
		editButton.setEnabled(false);
		removeButton.setEnabled(false);
	}

	protected void addListeners() {
		super.addListeners();

		eventDrivenButton.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				element = (WorkBreakdownElement) getElement();
				boolean status = actionMgr.doAction(IActionManager.SET,
						element, UmaPackage.eINSTANCE
								.getWorkBreakdownElement_IsEventDriven(),
						Boolean.valueOf(eventDrivenButton.getSelection()), -1);
				if (!status)
					eventDrivenButton.setSelection(element.getIsEventDriven()
							.booleanValue());

			}

			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});

		ongoingButton.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				element = (WorkBreakdownElement) getElement();
				boolean status = actionMgr.doAction(IActionManager.SET,
						element, UmaPackage.eINSTANCE
								.getWorkBreakdownElement_IsOngoing(), Boolean
								.valueOf(ongoingButton.getSelection()), -1);
				if (!status)
					ongoingButton.setSelection(element.getIsOngoing()
							.booleanValue());

			}

			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});

		repeatableButton.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				element = (WorkBreakdownElement) getElement();
				boolean status = actionMgr.doAction(IActionManager.SET,
						element, UmaPackage.eINSTANCE
								.getWorkBreakdownElement_IsRepeatable(),
						Boolean.valueOf(repeatableButton.getSelection()), -1);
				if (!status)
					repeatableButton.setSelection(element.getIsRepeatable()
							.booleanValue());

			}

			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});

		addButton.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				// List predList = element.getLinkToPredecessor();
				WorkOrder o = UmaFactory.eINSTANCE.createWorkOrder();
				o.setLinkType(WorkOrderType.FINISH_TO_START_LITERAL);

				// predList.add(o);

				PredecessorMap map = new PredecessorMap(-1, (WorkOrder) o);
				predMapList.add(map);

				viewer.refresh();
				viewer.editElement(map, 0);
			}

			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});

		editButton.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				// get selection
				IStructuredSelection selection = (IStructuredSelection) viewer
						.getSelection();
				if (selection.size() > 0) {
					PredecessorMap predMap = (PredecessorMap) selection
							.getFirstElement();
					IBSItemProvider adapter = (IBSItemProvider) getBSAdapter();
					Object process = adapter.getTopItem();

					PredecessorDialog dlg = new PredecessorDialog(PlatformUI
							.getWorkbench().getActiveWorkbenchWindow()
							.getShell(), element, process, getAdapterFactory(),
							predMap, predMapList, actionMgr);
					dlg.open();

					viewer.refresh();

				}
			}

			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});

		removeButton.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection selection = (IStructuredSelection) viewer
						.getSelection();
				if (selection.size() > 0) {
					PredecessorMap map = (PredecessorMap) selection
							.getFirstElement();
					predMapList.remove(map);

					WorkOrder wo = map.getWorkOrder();
					WorkBreakdownElement wbe = (WorkBreakdownElement) getElement();
					actionMgr
							.doAction(
									IActionManager.REMOVE,
									wbe,
									UmaPackage.eINSTANCE
											.getWorkBreakdownElement_LinkToPredecessor(),
									wo, -1);
					viewer.refresh();

				}

			}

			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});

		viewer.addSelectionChangedListener(new ISelectionChangedListener() {

			public void selectionChanged(SelectionChangedEvent event) {
				IStructuredSelection selection = (IStructuredSelection) viewer
						.getSelection();
				if (selection.size() == 1 && editable) {
					removeButton.setEnabled(true);
					editButton.setEnabled(true);
				}
			}
		});

	}

	/**
	 * Returns comma separated list of predecessors
	 * 
	 * @return
	 */
	// private String getPredecessorsList()
	// {
	// IBSItemProvider adapter = (IBSItemProvider) getBSAdapter();
	// return adapter.getAttribute(element, IBSItemProvider.COL_PREDECESSORS);
	// }
	// protected void addListeners()
	// {
	// super.addListeners();
	//		
	// eventDrivenButton.addSelectionListener(eventDrivenButtonSelectionListener);
	// ongoingButton.addSelectionListener(ongoingButtonSelectionListener);
	// repeatableButton.addSelectionListener(repeatableButtonSelectionListener);
	// //predecessorText.addListener(SWT.Deactivate, predecessorsListener);
	// }
	//	
	// protected void removeListeners()
	// {
	// super.removeListeners();
	//			
	// eventDrivenButton.removeSelectionListener(eventDrivenButtonSelectionListener);
	// ongoingButton.removeSelectionListener(ongoingButtonSelectionListener);
	// repeatableButton.removeSelectionListener(repeatableButtonSelectionListener);
	// //predecessorText.removeListener(SWT.Deactivate, predecessorsListener);
	// }
	protected void updateControls() {
		super.updateControls();
		eventDrivenButton.setEnabled(editable);
		ongoingButton.setEnabled(editable);
		repeatableButton.setEnabled(editable);
		viewer.getTable().setEnabled(editable);
		addButton.setEnabled(editable);

		IStructuredSelection selection = (IStructuredSelection) viewer
				.getSelection();
		if (selection.size() == 1 && editable) {
			removeButton.setEnabled(editable);
			editButton.setEnabled(editable);
		} else {
			removeButton.setEnabled(false);
			editButton.setEnabled(false);
		}

//		if ((EPFPropertySheetPage.formPageID
//				.equals(ProcessEditor.TA_FORM_ID))
//				|| (EPFPropertySheetPage.formPageID
//						.equals(ProcessEditor.WPBS_FORM_ID))) {
		if (!(EPFPropertySheetPage.formPageID.equals(ProcessEditor.WBS_FORM_ID) || EPFPropertySheetPage.formPageID
				.equals(ProcessEditor.CONSOLIDATED_FORM_ID))) {
			addButton.setEnabled(false);
			removeButton.setEnabled(false);
			editButton.setEnabled(false);
			viewer.getTable().setEnabled(false);
		}
	}

	
	/**
	 * @see org.eclipse.epf.authoring.ui.properties.BreakdownElementGeneralSection#refresh()
	 */
	public void refresh() {
		try {
			if (getElement() instanceof WorkBreakdownElement) {
				super.refresh();
				element = (WorkBreakdownElement) getElement();

				eventDrivenButton.setSelection(element.getIsEventDriven()
						.booleanValue());
				ongoingButton.setSelection(element.getIsOngoing()
						.booleanValue());
				repeatableButton.setSelection(element.getIsRepeatable()
						.booleanValue());
				// predecessorText.setText(getPredecessorsList());

				// re-initialize predList
				predMapList = new ArrayList();
				initializePredList();
				viewer.refresh();
			}

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

	private void createViewer(Composite parent, int horizontalSpan) {
		// create process viewer
		viewer = new TableViewer(parent, SWT.SINGLE | SWT.H_SCROLL
				| SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION);
		GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
		gridData.verticalIndent = 10;
		gridData.heightHint = 50;
		gridData.horizontalSpan = horizontalSpan;
		viewer.getControl().setLayoutData(gridData);

		// set up columns
		String[] colProps = new String[columnDescriptors.length];
		for (int i = 0; i < columnDescriptors.length; i++) {
			colProps[i] = columnDescriptors[i].id;
			TableColumn column = new TableColumn(viewer.getTable(),
					columnDescriptors[i].alignment);
			column.setText(columnDescriptors[i].label);
			column.setResizable(columnDescriptors[i].resizable);
			column.setWidth(columnDescriptors[i].width);

		}
		viewer.getTable().setHeaderVisible(true);
		viewer.setColumnProperties(colProps);

		// table = viewer.getTable();

		// final TableCursor cursor = new TableCursor(table, SWT.NONE);
		// final ControlEditor editor = new ControlEditor(cursor);
		// editor.grabHorizontal = true;
		// editor.grabVertical = true;

		// final TableCursor cursor = new TableCursor(table, SWT.NONE);
		// // create an editor to edit the cell when the user hits "ENTER"
		// // while over a cell in the table
		// final ControlEditor editor = new ControlEditor(cursor);
		// editor.grabHorizontal = true;
		// editor.grabVertical = true;
		//
		// cursor.addSelectionListener(new SelectionAdapter() {
		// // when the TableEditor is over a cell, select the corresponding row
		// in
		// // the table
		// public void widgetSelected(SelectionEvent e) {
		// table.setSelection(new TableItem[] { cursor.getRow()});
		// }
		// // when the user hits "ENTER" in the TableCursor, pop up a text
		// editor so that
		// // they can change the text of the cell
		// public void widgetDefaultSelected(SelectionEvent e) {
		// final Text text = new Text(cursor, SWT.NONE);
		// TableItem row = cursor.getRow();
		// int column = cursor.getColumn();
		// text.setText(row.getText(column));
		// text.addKeyListener(new KeyAdapter() {
		// public void keyPressed(KeyEvent e) {
		// // close the text editor and copy the data over
		// // when the user hits "ENTER"
		// if (e.character == SWT.CR) {
		// TableItem row = cursor.getRow();
		// int column = cursor.getColumn();
		// if (column == 1) return;
		// row.setText(column, text.getText());
		// text.dispose();
		// }
		// // close the text editor when the user hits "ESC"
		// if (e.character == SWT.ESC) {
		// text.dispose();
		// }
		// }
		// });
		// editor.setEditor(text);
		// text.setFocus();
		// }
		// });
		// // Hide the TableCursor when the user hits the "CTRL" or "SHIFT" key.
		// // This alows the user to select multiple items in the table.
		// cursor.addKeyListener(new KeyAdapter() {
		// public void keyPressed(KeyEvent e) {
		// if (e.keyCode == SWT.CTRL
		// || e.keyCode == SWT.SHIFT
		// || (e.stateMask & SWT.CONTROL) != 0
		// || (e.stateMask & SWT.SHIFT) != 0) {
		// cursor.setVisible(false);
		// }
		// }
		// });
		// // Show the TableCursor when the user releases the "SHIFT" or "CTRL"
		// key.
		// // This signals the end of the multiple selection task.
		// table.addKeyListener(new KeyAdapter() {
		// public void keyReleased(KeyEvent e) {
		// if (e.keyCode == SWT.CONTROL && (e.stateMask & SWT.SHIFT) != 0)
		// return;
		// if (e.keyCode == SWT.SHIFT && (e.stateMask & SWT.CONTROL) != 0)
		// return;
		// if (e.keyCode != SWT.CONTROL
		// && (e.stateMask & SWT.CONTROL) != 0)
		// return;
		// if (e.keyCode != SWT.SHIFT && (e.stateMask & SWT.SHIFT) != 0)
		// return;
		//
		// TableItem[] selection = table.getSelection();
		// TableItem row = (selection.length == 0) ?
		// table.getItem(table.getTopIndex()) : selection[0];
		// table.showItem(row);
		// cursor.setSelection(row, 0);
		// cursor.setVisible(true);
		// cursor.setFocus();
		// }
		// });

		IStructuredContentProvider contentProvider = new AdapterFactoryContentProvider(
				getAdapterFactory()) {
			public Object[] getElements(Object obj) {
				// System.out.println("PredMapList::"+predMapList);
				if (obj instanceof List) {
					return ((List) predMapList).toArray();
				}
				return null;
			}
		};

		viewer.setContentProvider(contentProvider);
		ILabelProvider labelProvider = new AdapterFactoryLabelProvider(
				getAdapterFactory()) {
			public String getColumnText(Object obj, int i) {
				// System.out.println("WorkBreakdownElementGeneralSection::labelProvider
				// Object- " + obj);
				if (obj instanceof PredecessorMap) {
					int id = ((PredecessorMap) obj).getId();
					WorkOrder wo = ((PredecessorMap) obj).getWorkOrder();

					if (i == 0) {
						return String.valueOf(id);
					}
					if (i == 1) {
						String name = ""; //$NON-NLS-1$
						if (wo.getPred() != null) {
							name = wo.getPred().getPresentationName();
							if (StrUtil.isBlank(name)) {
								return wo.getPred().getName();
							}
						}
						return name;
					}
					if (i == 2) {
						if (wo.getLinkType().getValue() == WorkOrderType.FINISH_TO_FINISH)
							return FINISH_TO_FINISH;
						else if (wo.getLinkType().getValue() == WorkOrderType.FINISH_TO_START)
							return FINISH_TO_START;
						else if (wo.getLinkType().getValue() == WorkOrderType.START_TO_START)
							return START_TO_START;
						else if (wo.getLinkType().getValue() == WorkOrderType.START_TO_FINISH)
							return START_TO_FINISH;
						return wo.getLinkType().getName();
					}
				}
				return ""; //$NON-NLS-1$
			}
		};

		viewer.setLabelProvider(labelProvider);

		textCellEditor = new TextCellEditor(viewer.getTable());
		comboBoxCellEditor = new ComboBoxCellEditor(viewer.getTable(),
				new String[] { FINISH_TO_START, FINISH_TO_FINISH,
						START_TO_START, START_TO_FINISH });

		setCellEditors();
		setCellModifiers();

		initializePredList();
		viewer.setInput(predMapList);
		viewer.refresh();

	}

	private int getCellEditorType(String property) {
		for (int i = 0; i < columnDescriptors.length; i++) {
			ColumnDescriptor desc = columnDescriptors[i];
			if (desc.id == property) {
				return desc.cellEditorType;
			}
		}
		return ColumnDescriptor.CELL_EDITOR_TYPE_NONE;
	}

	public CellEditor getCellEditor(String columnID, int columnIndex) {
		if (columnID == COL_ID) {
			if (idCellEditor == null) {
				idCellEditor = new ValidatingTextCellEditor(viewer.getTable()) {
					protected String isValid(Object e, String txt) {
						// System.out.println("ValidatingTextCellEditor::isValid");
						e = TngUtil.unwrap(e);

						IBSItemProvider adapter = (IBSItemProvider) getBSAdapter();
						Object process = adapter.getTopItem();

						List predecessors = new ArrayList();
						WorkBreakdownElement wbe = (WorkBreakdownElement) getElement();
						String str = getPredId();
						String result = ProcessUtil
								.checkPredecessorList(wbe, str,
										getAdapterFactory(), process,
										predecessors);

						return result;
					}
				};

				idCellEditor
						.setValidator(new CellEditorValidator(idCellEditor));
				idCellEditor.getControl().addListener(SWT.Deactivate,
						new ValidatingDeactivateListener(idCellEditor));
			}
			idCellEditor.setColumnIndex(columnIndex);

			return idCellEditor;
		}

		return null;
	}

	private void setCellEditors() {
		CellEditor[] cellEditors = new CellEditor[columnDescriptors.length];
		for (int i = 0; i < columnDescriptors.length; i++) {
			CellEditor cellEditor = getCellEditor(columnDescriptors[i].id, i);
			if (cellEditor != null) {
				cellEditors[i] = cellEditor;
			} else {
				switch (columnDescriptors[i].cellEditorType) {
				case ColumnDescriptor.CELL_EDITOR_TYPE_TEXT:
					cellEditors[i] = textCellEditor;
					break;
				case ColumnDescriptor.CELL_EDITOR_TYPE_COMBO_BOOLEAN:
					cellEditors[i] = comboBoxCellEditor;
					break;
				default:
					cellEditors[i] = null;
				}
			}
		}
		viewer.setCellEditors(cellEditors);
	}

	private void setCellModifiers() {
		// Set the cell modifier
		viewer.setCellModifier(new ICellModifier() {
			public boolean canModify(Object element, String property) {
				// System.out.println("canModify: element="+element+",
				// property="+property);
				if (!(element instanceof PredecessorMap))
					return false;
				if (property == COL_PRESENTATION_NAME) {
					return false;
				}

				return true;
			}

			public Object getValue(Object element, String property) {
				// System.out.println("getValue: element="+element+",
				// property="+property);

				String val = null;
				switch (getCellEditorType(property)) {
				case ColumnDescriptor.CELL_EDITOR_TYPE_TEXT:
					val = new Integer(((PredecessorMap) element).getId())
							.toString();
					return val;
				case ColumnDescriptor.CELL_EDITOR_TYPE_COMBO_BOOLEAN:
					int value = (((PredecessorMap) element).getWorkOrder())
							.getLinkType().getValue();
					if (WorkOrderType.FINISH_TO_START == value) {
						return new Integer(0);
					} else if (WorkOrderType.FINISH_TO_FINISH == value) {
						return new Integer(1);
					} else if (WorkOrderType.START_TO_START == value) {
						return new Integer(2);
					} else
						return new Integer(3);

				default:
					return ""; //$NON-NLS-1$
				}
			}

			public void modify(final Object element, String property,
					Object value) {
				// System.out.println("modify: element="+element+",
				// property="+property+", value="+value);
				TableItem item = (TableItem) element;
				PredecessorMap predMap = (PredecessorMap) item.getData();
				WorkOrder wo = predMap.getWorkOrder();

				if (property.equals(COL_ID)) {
					item.setText(0, value.toString());

					int predId;
					try {
						predId = new Integer(value.toString()).intValue();
						if (predId < 0)
							throw new Exception();
					} catch (Exception e) {
						AuthoringUIPlugin
								.getDefault()
								.getMsgDialog()
								.displayWarning(
										PropertiesResources.Process_predecessors_validNumberTitle, //$NON-NLS-1$
										PropertiesResources.Process_predecessors_validNumberMessage); //$NON-NLS-1$
						predMapList.remove(predMap);
						viewer.refresh();
						return;
					}
					predMap.setId(predId);
				}

				final int columnIndex = getColumnIndex(property);
				CellEditor cellEditor = viewer.getCellEditors()[columnIndex];
				String errMsg = cellEditor.getErrorMessage();
				if (errMsg != null) {
					return;
				}

				WorkOrderType type;
				switch (getCellEditorType(property)) {
				case ColumnDescriptor.CELL_EDITOR_TYPE_TEXT:

					IBSItemProvider adapter = (IBSItemProvider) getBSAdapter();
					Object process = adapter.getTopItem();

					List predecessors = new ArrayList();
					WorkBreakdownElement wbe = (WorkBreakdownElement) getElement();
					String str = getPredId();
					String result = ProcessUtil.checkPredecessorList(wbe, str,
							getAdapterFactory(), process, predecessors);

					if (result == null) {
						WorkOrder o = null;
						int size = wbe.getLinkToPredecessor().size();
						for (Iterator iter = wbe.getLinkToPredecessor()
								.iterator(); iter.hasNext();) {
							o = (WorkOrder) iter.next();
							int id = predecessors.indexOf(o.getPred());
							if (id == -1) {
								iter.remove();
							}
						}

						size = predecessors.size();
						for (int i = 0; i < size; i++) {
							WorkBreakdownElement e = (WorkBreakdownElement) predecessors
									.get(i);
							boolean found = false;
							find_pred: for (Iterator iterator = wbe
									.getLinkToPredecessor().iterator(); iterator
									.hasNext();) {
								o = (WorkOrder) iterator.next();
								if (o.getPred() == e) {
									found = true;
									break find_pred;
								}
							}
							if (!found) {
								o = UmaFactory.eINSTANCE.createWorkOrder();
								o.setPred(e);
								o
										.setLinkType(WorkOrderType.FINISH_TO_START_LITERAL);
								boolean status = actionMgr
										.doAction(
												IActionManager.ADD,
												wbe,
												UmaPackage.eINSTANCE
														.getWorkBreakdownElement_LinkToPredecessor(),
												o, -1);
								if (status) {
									predMap.setWorkOrder(o);

								} else {
									predMapList.remove(predMap);
								}
							}
						}
					} else {
						// show error message box
						String title = getEditor().getTitle();
						String problem = PropertiesResources.ProcessEditorFormProperties_cellEditor_invalidPredcessor_problem_msg; //$NON-NLS-1$
						MsgDialog dialog = AuthoringUIPlugin.getDefault()
								.getMsgDialog();
						dialog.displayWarning(title, problem, result); //$NON-NLS-1$
						predMapList.remove(predMap);
					}

					break;
				case ColumnDescriptor.CELL_EDITOR_TYPE_COMBO_BOOLEAN:
					int index = ((Number) value).intValue();
					if (index == 0) {
						type = WorkOrderType.FINISH_TO_START_LITERAL;
					} else if (index == 1) {
						type = WorkOrderType.FINISH_TO_FINISH_LITERAL;
					} else if (index == 2) {
						type = WorkOrderType.START_TO_START_LITERAL;
					} else {
						type = WorkOrderType.START_TO_FINISH_LITERAL;
					}

					// set workproduct type
					// System.out.println("type -"+type);
					actionMgr.doAction(IActionManager.SET, wo,
							UmaPackage.eINSTANCE.getWorkOrder_LinkType(), type,
							-1);
					break;

				default:
					type = WorkOrderType.FINISH_TO_FINISH_LITERAL;
				}

				viewer.refresh();
			}
		});

	}

	/**
	 * This method returns list of item providers for predecessors
	 * 
	 * @return
	 */
	// private Object getPredItemProviders()
	// {
	// IBSItemProvider adapter = (IBSItemProvider) getBSAdapter();
	// if (adapter != null)
	// return adapter.getPredecessors();
	//    	
	// return null;
	// }
	private ItemProviderAdapter getBSAdapter() {
		try {
			AdapterFactory factory = getAdapterFactory();// TngAdapterFactory.INSTANCE.getProcessComposedAdapterFactory();

			element = (WorkBreakdownElement) getElement();

			ItemProviderAdapter provider = (ItemProviderAdapter) factory.adapt(
					element, ITreeItemContentProvider.class);
			return provider;
		} catch (Exception ex) {
			return null;
		}

	}

	/**
	 * Return column index for property
	 * 
	 * @param property
	 * @return
	 */
	private int getColumnIndex(String property) {
		Object[] colProps = viewer.getColumnProperties();
		for (int i = 0; i < colProps.length; i++) {
			if (colProps[i] == property)
				return i;
		}
		return -1;
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.properties.AbstractSection#getNamePrefix()
	 */
	public String getNamePrefix() {
		if (element instanceof TeamProfile) {
			return LibraryUIText.TEXT_TEAM_PROFILE + ": "; //$NON-NLS-1$
		} else if (element instanceof Milestone) {
			return LibraryUIText.TEXT_MILESTONE + ": "; //$NON-NLS-1$
		}
		return LibraryUIText.TEXT_WORK_PRODUCT_ELEMENT + ": "; //$NON-NLS-1$
	}

	private String getPredId() {
		StringBuffer buf = new StringBuffer();

		for (Iterator itor = predMapList.iterator(); itor.hasNext();) {
			PredecessorMap map = (PredecessorMap) itor.next();
			buf.append(map.getId());
			buf.append(","); //$NON-NLS-1$
		}
		return buf.toString();
	}

	/**
	 * Initialize pred list
	 * 
	 */
	private void initializePredList() {
		try {
			List predProviders = null;

			// get work breakdown element
			element = (WorkBreakdownElement) getElement();

			// get predecessor item providers
			AdapterFactory factory = getAdapterFactory();

			if (factory != null) {
				ItemProviderAdapter provider = (ItemProviderAdapter) factory
						.adapt(element, ITreeItemContentProvider.class);
				if (provider instanceof IBSItemProvider) {
					predProviders = ((IBSItemProvider) provider)
							.getPredecessors();
				}
			}

			// need following for special case (WrapperItemProviders).
			ISelection selection = getSelection();
			if (selection instanceof IStructuredSelection) {
				Object input = ((IStructuredSelection) selection)
						.getFirstElement();
				if (input instanceof BreakdownElementWrapperItemProvider) {
					predProviders = ((BreakdownElementWrapperItemProvider) input)
							.getPredecessors();
				}
			}

			// get link to predecessors
			if ((element != null) && (predProviders != null)) {
				List predList = element.getLinkToPredecessor();
				for (Iterator itemIterator = predProviders.iterator(); itemIterator
						.hasNext();) {
					boolean found = false;
					Object itemObj = (Object) itemIterator.next();
					Object targetObj = null;
					if (itemObj instanceof WrapperItemProvider) {
						targetObj = ((WrapperItemProvider) itemObj).getValue();
					}
					if (itemObj instanceof ItemProviderAdapter) {
						targetObj = ((ItemProviderAdapter) itemObj).getTarget();
					}
					if (targetObj != null) {
						int id = ((IBSItemProvider) itemObj).getId();
						found = addPredecessor(predList, id, targetObj);

						if ((!found)
								&& (targetObj instanceof VariabilityElement)) {
							VariabilityElement ve = (VariabilityElement) targetObj;
							if (ve.getVariabilityBasedOnElement() != null) {
								VariabilityElement el = ve
										.getVariabilityBasedOnElement();
								targetObj = el;

								// add base variability object
								addPredecessor(predList, id, targetObj);
							}
						}
					}
				}

				// for (Iterator itor=predList.iterator(); itor.hasNext();)
				// {
				// boolean found = false;
				// Object o = (Object) itor.next();
				// if (o instanceof WorkOrder)
				// {
				// //System.out.println("getElement::WorkOrder = "+ ((WorkOrder)
				// o).getPred());
				// WorkBreakdownElement wbe = ((WorkOrder) o).getPred();
				// if (wbe != null)
				// {
				// for (Iterator itemIterator=predProviders.iterator();
				// itemIterator.hasNext();)
				// {
				// Object itemObj = (Object) itemIterator.next();
				// Object targetObj = null;
				// if (itemObj instanceof WrapperItemProvider)
				// {
				// targetObj = ((WrapperItemProvider) itemObj).getValue();
				// }
				// if (itemObj instanceof ItemProviderAdapter)
				// {
				// targetObj = ((ItemProviderAdapter)itemObj).getTarget();
				// }
				// if (targetObj != null)
				// {
				// if (targetObj.equals(wbe))
				// {
				// // create mapObjectList
				// int id = ((IBSItemProvider) itemObj).getId();
				// PredecessorMap map = new PredecessorMap(id, (WorkOrder) o);
				// predMapList.add(map);
				//		
				// found=true;
				// break;
				// }
				// }
				// }
				// if (!found)
				// {
				// // if provider is not found, then add with id=0
				// // do it only for TeamAllocation and WorkProductUsage view
				// // if
				// ((EPFPropertySheetPage.formPageID.equals(ProcessFormEditor.TA_FORM_ID))
				// ||
				// //
				// (EPFPropertySheetPage.formPageID.equals(ProcessFormEditor.WPBS_FORM_ID)))
				// {
				// PredecessorMap map = new PredecessorMap(0, (WorkOrder) o);
				// predMapList.add(map);
				// }
				// }
				// }
				// }
				// }
			}
		} catch (Exception e) {
			logger.logError("Initializing Predecessor List", e); //$NON-NLS-1$
		}
	}

	private boolean addPredecessor(List predList, int id, Object targetObj) {
		for (Iterator itor = predList.iterator(); itor.hasNext();) {
			Object o = (Object) itor.next();
			if (o instanceof WorkOrder) {
				// System.out.println("getElement::WorkOrder = "+ ((WorkOrder)
				// o).getPred());
				WorkBreakdownElement wbe = ((WorkOrder) o).getPred();

				if (targetObj.equals(wbe)) {
					// create mapObjectList
					PredecessorMap map = new PredecessorMap(id, (WorkOrder) o);
					predMapList.add(map);

					return true;
				}
			}
		}

		return false;
	}
}