//------------------------------------------------------------------------------
// 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.library.edit.process.consolidated;

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

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.edit.provider.ViewerNotification;
import org.eclipse.emf.edit.provider.WrapperItemProvider;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.configuration.GuidanceItemProvider.CompareByName;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.process.IBreakdownElementWrapperItemProviderFactory;
import org.eclipse.epf.library.edit.util.Comparators;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;


/**
 * @author Phong Nguyen Le
 * @authos Shilpa Toraskar
 * @since 1.0
 */
public class TaskDescriptorItemProvider extends
		org.eclipse.epf.library.edit.process.TaskDescriptorItemProvider {

	protected Collection cachedChildren;

	/**
	 * @param adapterFactory
	 * @param delegateItemProvider
	 */
	public TaskDescriptorItemProvider(AdapterFactory adapterFactory,
			ItemProviderAdapter delegateItemProvider) {
		super(adapterFactory, delegateItemProvider);
	}

	/**
	 * @see com.ibm.library.edit.process.BreakdownElementItemProvider#collectNewChildDescriptors(java.util.Collection,
	 *      java.lang.Object)
	 */
	protected void collectNewChildDescriptors(Collection newChildDescriptors,
			Object object) {
		newChildDescriptors.add(new CommandParameter(target,
				UmaPackage.eINSTANCE.getTaskDescriptor_PerformedPrimarilyBy(),
				UmaFactory.eINSTANCE.createRoleDescriptor()));

		newChildDescriptors.add(createChildParameter(UmaPackage.eINSTANCE
				.getTaskDescriptor_AdditionallyPerformedBy(),
				UmaFactory.eINSTANCE.createRoleDescriptor()));

		newChildDescriptors.add(createChildParameter(UmaPackage.eINSTANCE
				.getTaskDescriptor_AssistedBy(), UmaFactory.eINSTANCE
				.createRoleDescriptor()));

		newChildDescriptors.add(createChildParameter(UmaPackage.eINSTANCE
				.getTaskDescriptor_MandatoryInput(), UmaFactory.eINSTANCE
				.createWorkProductDescriptor()));

		newChildDescriptors.add(createChildParameter(UmaPackage.eINSTANCE
				.getTaskDescriptor_OptionalInput(), UmaFactory.eINSTANCE
				.createWorkProductDescriptor()));
		
		newChildDescriptors.add(createChildParameter(UmaPackage.eINSTANCE
				.getTaskDescriptor_ExternalInput(), UmaFactory.eINSTANCE
				.createWorkProductDescriptor()));
		
		newChildDescriptors.add(createChildParameter(UmaPackage.eINSTANCE
				.getTaskDescriptor_Output(), UmaFactory.eINSTANCE
				.createWorkProductDescriptor()));

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.BreakdownElementItemProvider#getChildrenFeatures(java.lang.Object)
	 */
	public Collection getChildrenFeatures(Object object) {
		if (childrenFeatures == null) {
			childrenFeatures = new ArrayList();
			childrenFeatures.add(UmaPackage.eINSTANCE
					.getTaskDescriptor_PerformedPrimarilyBy());
			childrenFeatures.add(UmaPackage.eINSTANCE
					.getTaskDescriptor_AdditionallyPerformedBy());
			childrenFeatures.add(UmaPackage.eINSTANCE
					.getTaskDescriptor_AssistedBy());
			childrenFeatures.add(UmaPackage.eINSTANCE
					.getTaskDescriptor_MandatoryInput());
			childrenFeatures.add(UmaPackage.eINSTANCE
					.getTaskDescriptor_OptionalInput());
			childrenFeatures.add(UmaPackage.eINSTANCE
					.getTaskDescriptor_ExternalInput());
			childrenFeatures.add(UmaPackage.eINSTANCE
					.getTaskDescriptor_Output());
		}
		return childrenFeatures;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#isWrappingNeeded(java.lang.Object)
	 */
	protected boolean isWrappingNeeded(Object object) {
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getCreateChildText(java.lang.Object,
	 *      java.lang.Object, java.lang.Object, java.util.Collection)
	 */
	public String getCreateChildText(Object owner, Object feature,
			Object child, Collection selection) {
		return getFeatureText(feature);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getCreateChildImage(java.lang.Object,
	 *      java.lang.Object, java.lang.Object, java.util.Collection)
	 */
	public Object getCreateChildImage(Object owner, Object feature,
			Object child, Collection selection) {
		Object img = TngUtil.getImage(child);
		return img != null ? img : super.getCreateChildImage(owner, feature, child, selection);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#createWrapper(org.eclipse.emf.ecore.EObject,
	 *      org.eclipse.emf.ecore.EStructuralFeature, java.lang.Object, int)
	 */
	protected Object createWrapper(EObject object, EStructuralFeature feature,
			Object value, int index) {
		BreakdownElementWrapperItemProvider wrapper = (BreakdownElementWrapperItemProvider) IBreakdownElementWrapperItemProviderFactory.INSTANCE
				.createWrapper(value, object, feature, index, adapterFactory);
		wrapper.setReadOnly(false);
		return wrapper;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.BreakdownElementItemProvider#notifyChanged(org.eclipse.emf.common.notify.Notification)
	 */
	public void notifyChanged(Notification notification) {
		updateChildren(notification);

		switch (notification.getFeatureID(TaskDescriptor.class)) {
		case UmaPackage.TASK_DESCRIPTOR__PERFORMED_PRIMARILY_BY:
		case UmaPackage.TASK_DESCRIPTOR__ADDITIONALLY_PERFORMED_BY:
		case UmaPackage.TASK_DESCRIPTOR__ASSISTED_BY:
		case UmaPackage.TASK_DESCRIPTOR__MANDATORY_INPUT:
		case UmaPackage.TASK_DESCRIPTOR__OPTIONAL_INPUT:
		case UmaPackage.TASK_DESCRIPTOR__EXTERNAL_INPUT:
		case UmaPackage.TASK_DESCRIPTOR__OUTPUT:
			refreshChildren(notification);
		}

		super.notifyChanged(notification);
	}
	
	static void refreshChildren(ItemProviderAdapter ipa, Notification notification) {		
		if (ProcessUtil.isRefreshRequired(notification, null)) {
			ipa.fireNotifyChanged(new ViewerNotification(notification, notification
					.getNotifier(), true, false));

			AdapterFactory adapterFactory = ipa.getAdapterFactory();
			
			if(notification.getNotifier() instanceof BreakdownElement) {
				// need to refresh children of parent activity
				//
				Activity parent = ((BreakdownElement)notification.getNotifier()).getSuperActivities();
				Object adapter = adapterFactory.adapt(parent,
						ITreeItemContentProvider.class);
				if (adapter instanceof ItemProviderAdapter) {
					((ItemProviderAdapter) adapter)
					.fireNotifyChanged(new ViewerNotification(notification,
							parent, true, false));
				}

				// refresh extenders and local contributors of the parent
				//
				if(parent instanceof VariabilityElement) {
					for (Iterator iter = TngUtil.getGeneralizers(parent); iter.hasNext();) {
						VariabilityElement ve = (VariabilityElement) iter.next();
						if(ve.getVariabilityType() == VariabilityType.EXTENDS_LITERAL
								|| ve.getVariabilityType() == VariabilityType.LOCAL_CONTRIBUTION_LITERAL) {
							adapter = TngUtil.getAdapterByType(ve, adapterFactory);
							if (adapter instanceof ItemProviderAdapter) {
								((ItemProviderAdapter) adapter)
								.fireNotifyChanged(new ViewerNotification(notification,
										ve, true, false));
							}
						}
					}
				}
			}
		}
	}

	/**
	 * @param notification
	 */
	private void refreshChildren(Notification notification) {
		refreshChildren(this, notification);
	}

	private void updateCachedChildren(Collection children) {
//		if(cachedChildren == null) {
//			cachedChildren = new ArrayList(children);
//		}
//		else {
//			cachedChildren.clear();
//			cachedChildren.addAll(children);
//		}
	}

	public Collection getChildren(Object obj) {
		Collection children = super.getChildren(obj);
		List newChildren = new ArrayList();
		List primaryPerformers = new ArrayList();
		List additionalPerformers = new ArrayList();
		List assitedBy = new ArrayList();
		List mandatoryInput = new ArrayList();
		List externalInput = new ArrayList();
		List optionalInput = new ArrayList();
		List output = new ArrayList();

		IFilter filter = getFilter(obj);

		for (Iterator itor = children.iterator(); itor.hasNext();) {
			Object o = itor.next();
			if (o instanceof WrapperItemProvider) {
				Object child = ((WrapperItemProvider) o).getValue();
				
				
				if ((filter != null) && (filter.accept(child))) {
					if (((WrapperItemProvider) o).getFeature().equals(
							UmaPackage.eINSTANCE
									.getTaskDescriptor_PerformedPrimarilyBy())) {
						primaryPerformers.add(o);
					} else if (((WrapperItemProvider) o)
							.getFeature()
							.equals(
									UmaPackage.eINSTANCE
											.getTaskDescriptor_AdditionallyPerformedBy())) {
						additionalPerformers.add(o);
					} else if (((WrapperItemProvider) o).getFeature()
							.equals(
									UmaPackage.eINSTANCE
											.getTaskDescriptor_AssistedBy())) {
						assitedBy.add(o);
					} else if (((WrapperItemProvider) o).getFeature().equals(
							UmaPackage.eINSTANCE
									.getTaskDescriptor_MandatoryInput())) {
						mandatoryInput.add(o);
					} else if (((WrapperItemProvider) o).getFeature().equals(
							UmaPackage.eINSTANCE
									.getTaskDescriptor_ExternalInput())) {
						externalInput.add(o);
					} else if (((WrapperItemProvider) o).getFeature().equals(
							UmaPackage.eINSTANCE
									.getTaskDescriptor_OptionalInput())) {
						optionalInput.add(o);
					} else if (((WrapperItemProvider) o).getFeature().equals(
							UmaPackage.eINSTANCE.getTaskDescriptor_Output())) {
						output.add(o);
					}
				}
			}
		}

		// sort for all children
		Collections.sort(primaryPerformers, Comparators.PRESENTATION_NAME_COMPARATOR);
		Collections.sort(additionalPerformers, Comparators.PRESENTATION_NAME_COMPARATOR);
		Collections.sort(assitedBy, Comparators.PRESENTATION_NAME_COMPARATOR);
		Collections.sort(externalInput, Comparators.PRESENTATION_NAME_COMPARATOR);
		Collections.sort(mandatoryInput, Comparators.PRESENTATION_NAME_COMPARATOR);
		Collections.sort(optionalInput, Comparators.PRESENTATION_NAME_COMPARATOR);
		Collections.sort(output, Comparators.PRESENTATION_NAME_COMPARATOR);
		
		newChildren.addAll(primaryPerformers);
		newChildren.addAll(additionalPerformers);
		newChildren.addAll(assitedBy);
		newChildren.addAll(externalInput);
		newChildren.addAll(mandatoryInput);
		newChildren.addAll(optionalInput);
		newChildren.addAll(output);
		
		newChildren = removeSubartifactsFromChildren(newChildren, true);
		updateCachedChildren(newChildren);
		return newChildren;
	}
	
	protected List removeSubartifactsFromChildren(Collection children, boolean unwrap) {
		return ProcessUtil.removeSubartifactsFromChildren(children, unwrap);
	}

	private IFilter getFilter(Object obj) {
		IFilter filter = null;
		Object parent = getParent(obj);
		IBSItemProvider adapter = (IBSItemProvider) getRootAdapterFactory()
				.adapt(parent, ITreeItemContentProvider.class);
		if (adapter instanceof ActivityItemProvider) {
			filter = ((ActivityItemProvider) adapter).getFilter();
		}

		return filter;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.edit.ICachedChildrenItemProvider#getChildrenFromCache()
	 */
	public Collection getChildrenFromCache() {
		if(cachedChildren == null) {
			getChildren(target);
		}
		return cachedChildren;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.edit.ICachedChildrenItemProvider#getRollupChildrenFromCache()
	 */
	public Collection getRollupChildrenFromCache() {
		return Collections.EMPTY_LIST;
	}

	public void dispose() { 
		if(cachedChildren != null) {
			cachedChildren.clear();
			cachedChildren = null;
		}
		super.dispose();
	}
}
