//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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.common.util.BasicEList;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.epf.authoring.ui.providers.VariabilityElementLabelProvider;
import org.eclipse.epf.library.edit.IConfigurationApplicator;
import org.eclipse.epf.library.edit.Providers;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.util.DescriptorPropUtil;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.jface.resource.FontRegistry;
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.ITableFontProvider;
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.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ListSelectionDialog;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;


/**
 * The task descriptor - step section
 * 
 * @author Shilpa Toraskar
 * @since 1.0
 * 
 */
public class TaskDescriptorStepSection extends AbstractSection {
	private TaskDescriptor element;

	private IActionManager actionMgr;

	private FormToolkit toolkit;

	private Button ctrl_add, ctrl_remove, ctrl_up, ctrl_down;

	private Table ctrl_selected;

	private TableViewer viewer;

	// private Text ctrl_brief_desc;
	private Image titleImage;


	/* (non-Javadoc)
	 * @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 steps section
		createStepSection(parent);

		addListeners();

	}

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

		// get toolkit
		toolkit = getWidgetFactory();

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


	/* (non-Javadoc)
	 * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
	 */
	public void refresh() {
		try {
			if (getElement() instanceof TaskDescriptor) {
				element = (TaskDescriptor) getElement();
			
				// hide/refresh controls
				updateControls();
				
				if (isSyncFree()) {
					syncFreeUpdateControls();
				}
				
				initContentProvider();
				initLabelProvider();
				
				viewer.refresh();
			}
		} catch (Exception ex) {
			logger.logError("Error refreshing TaskDescriptor step section" + element, ex);  //$NON-NLS-1$
		}
	}

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

	/**
	 * Update controls based on editable flag. Controls will be either editable 
	 * or read-only after updating this.
	 */
	public void updateControls() {
		ctrl_add.setEnabled(editable);
		if (element.getTask() == null)
			ctrl_add.setEnabled(false);
		else {
			List steps = getSteps();
			if (steps != null && steps.size() > 0) 
				ctrl_add.setEnabled(true);
			else 
				ctrl_add.setEnabled(false);
		}
		
		IStructuredSelection selection = (IStructuredSelection) viewer
				.getSelection();
		if (selection.size() > 0 && editable) {
			ctrl_remove.setEnabled(editable);
			ctrl_up.setEnabled(editable);
			ctrl_down.setEnabled(editable);
		} else {
			ctrl_remove.setEnabled(false);
			ctrl_up.setEnabled(false);
			ctrl_down.setEnabled(false);

		}
	}
		
	/**
	 * Create Step section on the given composite
	 * @param composite
	 */
	private void createStepSection(Composite composite) {
		// create step section
		Section stepSection = FormUI
				.createSection(
						toolkit,
						composite,
						PropertiesResources.TaskDescriptor_stepInformationTitle, 
						PropertiesResources.TaskDescriptor_stepInformationDescription); 

		// create step composite
		Composite stepComposite = FormUI.createComposite(toolkit, stepSection,
				2, false);

		// create table composite
		Composite pane1 = FormUI.createComposite(toolkit, stepComposite,
				GridData.FILL_BOTH);
		FormUI.createLabel(toolkit, pane1, PropertiesResources.TaskDescriptor_Selected_Steps); 

		ctrl_selected = FormUI.createTable(toolkit, pane1);
		viewer = new TableViewer(ctrl_selected);
		initContentProvider();
		initLabelProvider();
		viewer.setInput(element);

		// create button composite
		Composite pane2 = FormUI.createComposite(toolkit, stepComposite,
				GridData.VERTICAL_ALIGN_CENTER
						| GridData.HORIZONTAL_ALIGN_CENTER);

		// create buttons
		ctrl_add = FormUI.createButton(toolkit, pane2, PropertiesResources.Process_Add);
		ctrl_add.setEnabled(false);
		ctrl_remove = FormUI.createButton(toolkit, pane2, PropertiesResources.Process_Remove); 
		ctrl_remove.setEnabled(false);
		ctrl_up = FormUI.createButton(toolkit, pane2, PropertiesResources.Process_Up); 
		ctrl_down = FormUI.createButton(toolkit, pane2, PropertiesResources.Process_Down); 

		if (element.getTask() != null) {
			List steps = getSteps();
			if (steps != null && steps.size() > 0) {
				ctrl_add.setEnabled(true);
			}
		}
		// create brief description
		// int heightHint = 40;
		// int horizontalSpan = 2;
		// Label label = FormUI.createLabel(toolkit, stepComposite,
		// PropertiesResources.getString("Process.briefDescription"),
		// heightHint);
		// ctrl_brief_desc = FormUI.createText(toolkit, stepComposite,
		// heightHint, heightHint);
		// ctrl_brief_desc.setEditable(false);
		//		
		toolkit.paintBordersFor(stepComposite);
		toolkit.paintBordersFor(pane1);
	}

	/**
	 * Add listeners
	 */
	private void addListeners() {
		// Add focus listener on primary tasks list
		ctrl_selected.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				IStructuredSelection selection = (IStructuredSelection) viewer
						.getSelection();
				if ((selection.size() > 0) && editable) {
					ctrl_remove.setEnabled(editable);
					ctrl_up.setEnabled(editable);
					ctrl_down.setEnabled(editable);
				}
				
				if (isSyncFree()) {
					syncFreeUpdateControls();
				}
			}
		});

		viewer.addSelectionChangedListener(new ISelectionChangedListener() {

			public void selectionChanged(SelectionChangedEvent event) {
				IStructuredSelection selection = (IStructuredSelection) viewer
						.getSelection();
				if ((selection.size() > 0) && editable) {
					ctrl_remove.setEnabled(true);

					if (viewer.getTable().getSelectionIndex() > 0
							&& selection.size() == 1) {
						ctrl_up.setEnabled(true);
					} else
						ctrl_up.setEnabled(false);

					if (viewer.getTable().getSelectionIndex() < viewer
							.getTable().getItemCount() - 1
							&& selection.size() == 1) {
						ctrl_down.setEnabled(true);
					} else
						ctrl_down.setEnabled(false);

				}

				if (selection.size() == 1) {
					String desc = ((MethodElement) selection.getFirstElement())
							.getBriefDescription();
					if (desc == null) {
						desc = ""; //$NON-NLS-1$
					}
					// ctrl_brief_desc.setText(desc);
				} else if (selection.size() > 1) {
					// ctrl_brief_desc.setText(PropertiesResources.getString("Process.MultipleSelection")
					// + " - " + selection.size());
				}
				
				if (isSyncFree()) {
					syncFreeUpdateControls();
				}
			}
		});

		ctrl_add.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (isSyncFree()) {
					IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();					
					addSteps(selection.toArray());			
					viewer.refresh();
					syncFreeUpdateControls();
					
					return;
				}
				
				IStructuredContentProvider stepContentProvider = new AdapterFactoryContentProvider(
						TngAdapterFactory.INSTANCE
								.getNavigatorView_ComposedAdapterFactory()) {
					public Object[] getElements(Object object) {

						return getSteps().toArray();
//						// get all steps
//						IConfigurationApplicator configApplicator = Providers
//								.getConfigurationApplicator();
//						MethodConfiguration config = TngUtil.getOwningProcess(
//								element).getDefaultContext();
//						List steps = (List) configApplicator.getReference(
//								element.getTask(), UmaPackage.eINSTANCE
//										.getTask_Steps(), config);
//
//						// remove already existing steps
//						steps.removeAll(element.getSelectedSteps());
//						return steps.toArray();
					}
				};

				ILabelProvider stepLabelProvider = new VariabilityElementLabelProvider(
						TngAdapterFactory.INSTANCE
								.getNavigatorView_ComposedAdapterFactory()) {

					public boolean isExternal(Object obj) {

						boolean flag = !element.getTask().getPresentation()
								.getSections().contains(obj);
						return flag;
					}
				};

				ListSelectionDialog dlg = new ListSelectionDialog(PlatformUI
						.getWorkbench().getActiveWorkbenchWindow().getShell(),
						element.getTask(), stepContentProvider,
						stepLabelProvider, PropertiesResources.TaskDescriptor_StepDialogMessage); 
				titleImage = Display.getCurrent().getActiveShell().getImage();
				ListSelectionDialog.setDefaultImage(titleImage);
				dlg.setTitle(PropertiesResources.TaskDescriptor_StepDialogTitle);
				dlg.setBlockOnOpen(true);
				dlg.open();

				addSteps(dlg.getResult());
				
				// enable/disable add button
				List steps = getSteps();
				if (steps != null && steps.size() > 0) 
					ctrl_add.setEnabled(true);
				else 
					ctrl_add.setEnabled(false);
				
				viewer.refresh();
			}
		});

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

					// clear the selection
					viewer.setSelection(null, true);
					// ctrl_brief_desc.setText("");
				}
				// ctrl_remove.setEnabled(false);
				
				// enable/disable add button
				List steps = getSteps();
				if (steps != null && steps.size() > 0) 
					ctrl_add.setEnabled(true);
				else 
					ctrl_add.setEnabled(false);
				
				if (isSyncFree()) {
					syncFreeUpdateControls();
				}
			}
		});

		ctrl_up.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				ArrayList steps = new ArrayList();
				IStructuredSelection selection = (IStructuredSelection) viewer
						.getSelection();
				if (selection.size() > 0) {
					ArrayList items = new ArrayList();
					items.addAll(selection.toList());
					BasicEList stepList = (BasicEList) element
							.getSelectedSteps();

					for (Iterator it = items.iterator(); it.hasNext();) {
						Object object = it.next();
						int index = stepList.indexOf(object);
						if (index > 0)
							stepList.move(index - 1, object);

					}
					steps.addAll(stepList);
					// TODO - write a command. 
					// activate dirty flag
					actionMgr.doAction(IActionManager.REMOVE_MANY, element,
							UmaPackage.eINSTANCE
									.getTaskDescriptor_SelectedSteps(),
							stepList, -1);
					actionMgr.doAction(IActionManager.ADD_MANY, element,
							UmaPackage.eINSTANCE
									.getTaskDescriptor_SelectedSteps(), steps,
							-1);

					viewer.refresh();
				}

				if (viewer.getTable().getSelectionIndex() > 0 && editable)
					ctrl_up.setEnabled(true);
				else
					ctrl_up.setEnabled(false);

				if (viewer.getTable().getSelectionIndex() < viewer.getTable()
						.getItemCount() - 1
						&& editable)
					ctrl_down.setEnabled(true);
				else
					ctrl_down.setEnabled(false);
			}

		});

		ctrl_down.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				ArrayList steps = new ArrayList();
				IStructuredSelection selection = (IStructuredSelection) viewer
						.getSelection();
				if (selection.size() > 0) {
					ArrayList items = new ArrayList();
					items.addAll(selection.toList());
					BasicEList stepList = (BasicEList) element
							.getSelectedSteps();

					for (Iterator it = items.iterator(); it.hasNext();) {
						Object object = it.next();
						int index = stepList.indexOf(object);

						if (index < stepList.size() - 1)
							stepList.move(index + items.size(), object);

					}
					steps.addAll(stepList);

					// TODO - write a cmmand. Hacking it for now to activate
					// dirty flag
					actionMgr.doAction(IActionManager.REMOVE_MANY, element,
							UmaPackage.eINSTANCE
									.getTaskDescriptor_SelectedSteps(),
							stepList, -1);
					actionMgr.doAction(IActionManager.ADD_MANY, element,
							UmaPackage.eINSTANCE
									.getTaskDescriptor_SelectedSteps(), steps,
							-1);

					viewer.refresh();
				}

				if (viewer.getTable().getSelectionIndex() > 0 && editable)
					ctrl_up.setEnabled(true);
				else
					ctrl_up.setEnabled(false);

				if (viewer.getTable().getSelectionIndex() < viewer.getTable()
						.getItemCount() - 1
						&& editable)
					ctrl_down.setEnabled(true);
				else
					ctrl_down.setEnabled(false);

			}

		});
	}

	/**
	 * Assign Steps to task descriptor
	 * @param addItems
	 * 			List of steps
	 */
	private void addSteps(Object[] addItems) {
		// update the model
		if (addItems != null) {
			for (int i = 0; i < addItems.length; i++) {
				org.eclipse.epf.uma.Section item = (org.eclipse.epf.uma.Section) addItems[i];

				actionMgr.doAction(IActionManager.ADD, element,
						UmaPackage.eINSTANCE.getTaskDescriptor_SelectedSteps(),
						item, -1);
				if (isSyncFree()) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getTaskDescriptor_SelectedStepsExclude(),
							item, -1);
				}
			}
		}
	}

	/**
	 * Remove assigned steps for the task descriptor
	 * @param rmItems
	 * 			List of steps 
	 */
	private void removeSteps(List rmItems) {
		// update the model
		if (!rmItems.isEmpty()) {
			for (Iterator it = rmItems.iterator(); it.hasNext();) {
				org.eclipse.epf.uma.Section item = (org.eclipse.epf.uma.Section) it.next();

				actionMgr.doAction(IActionManager.REMOVE, element,
						UmaPackage.eINSTANCE.getTaskDescriptor_SelectedSteps(),
						item, -1);
				if (isSyncFree()) {
					actionMgr.doAction(IActionManager.ADD, element,
							UmaPackage.eINSTANCE.getTaskDescriptor_SelectedStepsExclude(),
							item, -1);
				}
			}
		}
	}
	
	/**
	 * Get steps that could be assigned to this task descriptor
	 * @return
	 */
	private List getSteps(){
		//	get all steps
		IConfigurationApplicator configApplicator = Providers
				.getConfigurationApplicator();
		MethodConfiguration config = TngUtil.getOwningProcess(
				element).getDefaultContext();
		List steps = (List) configApplicator.getReference(
				element.getTask(), UmaPackage.eINSTANCE
						.getTask_Steps(), config);

		// remove already existing steps
		steps.removeAll(element.getSelectedSteps());
		return steps;
	}
	
	private boolean isSyncFree() {
		return ProcessUtil.isSynFree();
	}
	
	private void initContentProvider() {
		IStructuredContentProvider contentProvider = new AdapterFactoryContentProvider(
				TngAdapterFactory.INSTANCE.getNavigatorView_ComposedAdapterFactory()) {
			public Object[] getElements(Object object) {
				List elements = new ArrayList();				
				elements.addAll(element.getSelectedSteps());
				
				if (isSyncFree() && !DescriptorPropUtil.getDesciptorPropUtil().isNoAutoSyn(element)) {
					//This is a work around on UI for data layer under sync free
					elements = syncFreeReOrder(elements);
					
					elements.addAll(element.getSelectedStepsExclude());
				}
				
				return elements.toArray();
			}
		};
		
		viewer.setContentProvider(contentProvider);
	}
	
	private List syncFreeReOrder(List steps) {
		List result = new ArrayList();
		
		if (element.getTask() != null) {
			List originalSteps = element.getTask().getSteps();
			
			for (Object obj : originalSteps) {
				if (steps.contains(obj)) {
					result.add(obj);
				}
			}
		} else {
			result = steps;
		}
		
		return result;
	}
	
	private void initLabelProvider() {
		ILabelProvider labelProvider = null;
		
		if (isSyncFree()) {
			labelProvider = new StepsSyncFreeLabelProvider(
					TngAdapterFactory.INSTANCE.getNavigatorView_ComposedAdapterFactory(),
					element,
					UmaPackage.eINSTANCE.getTaskDescriptor_SelectedSteps(),
					getConfiguration()
					);			
		} else {
			labelProvider = new AdapterFactoryLabelProvider(
					TngAdapterFactory.INSTANCE.getNavigatorView_ComposedAdapterFactory());
		}
		
		viewer.setLabelProvider(labelProvider);
	}
	
	private void syncFreeUpdateControls() {
		ctrl_up.setEnabled(false);
		ctrl_down.setEnabled(false);
		
		IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
		if ((selection.size() > 0) && (editable)) {
			if (isAllDynamic(selection)) {
				ctrl_add.setEnabled(false);
				ctrl_remove.setEnabled(true);
			} else if (isAllExcluded(selection)) {
				ctrl_add.setEnabled(true);
				ctrl_remove.setEnabled(false);
			} else {
				ctrl_add.setEnabled(false);
				ctrl_remove.setEnabled(false);
			}			
		} else {
			ctrl_add.setEnabled(false);
			ctrl_remove.setEnabled(false);
		}
	}
	
	private boolean isAllDynamic(IStructuredSelection selection) {
		List<org.eclipse.epf.uma.Section> allDynamic = element.getSelectedSteps();
		
		for (Object obj : selection.toArray()) {
			if (obj instanceof org.eclipse.epf.uma.Section) {
				if (!allDynamic.contains((org.eclipse.epf.uma.Section)obj)) {
					return false;
				}				
			}
		}
		
		return true;	
	}
	
	private boolean isAllExcluded(IStructuredSelection selection) {
		List<org.eclipse.epf.uma.Section> allExcluded = element.getSelectedStepsExclude();
		
		for (Object obj : selection.toArray()) {
			if (obj instanceof org.eclipse.epf.uma.Section) {
				if (!allExcluded.contains((org.eclipse.epf.uma.Section)obj)) {
					return false;
				}				
			}
		}
		
		return true;
	}
	
	public class StepsSyncFreeLabelProvider extends AdapterFactoryLabelProvider implements ITableFontProvider {
		private FontRegistry registry = new FontRegistry();
		private DescriptorPropUtil propUtil = DescriptorPropUtil.getDesciptorPropUtil();
		
		private Font systemFont;
		private Descriptor desc;
		private EReference ref;
		private MethodConfiguration config;

		public StepsSyncFreeLabelProvider(AdapterFactory adapterFactory, Descriptor desc, EReference ref, MethodConfiguration config) {
			super(adapterFactory);
			this.desc = desc;
			this.ref = ref;		
			this.config = config;
		}
	    
	    public Font getFont(Object obj, int columnIndex) {
	    	if (systemFont == null) {
	    		systemFont = Display.getCurrent().getSystemFont();
	    	}
	    	
    		return registry.getBold(systemFont.getFontData()[0].getName());
	    }	    	
	    
	    public String getColumnText(Object obj, int columnIndex) {
	    	String original = super.getColumnText(obj, columnIndex);
	    	
	    	if (propUtil.isDynamicAndExclude(obj, desc, ref, config)) {
	    		return "<<<" + original + ">>>";	    		 //$NON-NLS-1$ //$NON-NLS-2$
	    	}
	    	
	    	return original;	    	
	    }
	}
	
}
