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

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

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.command.CopyCommand.Helper;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.IEditingDomainItemProvider;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.edit.provider.ViewerNotification;
import org.eclipse.epf.library.edit.ICachedChildrenItemProvider;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.process.command.WorkProductDescriptorCreateCopyCommand;
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.Artifact;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.Deliverable;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.epf.uma.util.UmaUtil;


/**
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class WorkProductDescriptorItemProvider extends DescriptorItemProvider
implements ICachedChildrenItemProvider
{
	protected Collection cachedChildren;
	
	/**
	 * @param adapterFactory
	 */
	public WorkProductDescriptorItemProvider(AdapterFactory adapterFactory,
			ItemProviderAdapter delegateItemProvider) {
		super(adapterFactory, delegateItemProvider);
	}

	public Activity getActivity(Object object) {
		for (Object parent = getParent(object); parent != null;) {
			if (parent instanceof Activity)
				return (Activity) parent;
			AdapterFactory aFactory = getRootAdapterFactory();
			ItemProviderAdapter adapter = (ItemProviderAdapter) aFactory.adapt(
					parent, ITreeItemContentProvider.class);
			parent = adapter.getParent(parent);
		}
		return null;
	}

	private Object getDescriptor(Activity activity, Artifact artifact) {
		if (activity == null)
			return null;
		List list = activity.getBreakdownElements();
		int size = list.size();
		for (int i = 0; i < size; i++) {
			Object obj = list.get(i);
			if ((obj instanceof WorkProductDescriptor)
					&& (artifact == ((WorkProductDescriptor) obj)
							.getWorkProduct())) {
				return obj;
			}
		}
		return null;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildrenFeatures(java.lang.Object)
	 */
	public Collection getChildrenFeatures(Object object) {
		// if (childrenFeatures == null)
		// {
		// childrenFeatures = new ArrayList();
		// childrenFeatures.add(UmaPackage.eINSTANCE.getWorkProductDescriptor_DeliverableParts());
		// }
		// return childrenFeatures;

		return Collections.EMPTY_LIST;
	}
	
	private void updateCachedChildren(Collection children) {
//		if(cachedChildren == null) {
//			cachedChildren = new ArrayList(children);
//		}
//		else {
//			cachedChildren.clear();
//			cachedChildren.addAll(children);
//		}
	}
	
	protected void addContainedArtifactDescriptors(WorkProductDescriptor wpDesc, Collection children) {
		Activity activity = UmaUtil.getParentActivity(wpDesc);
		if(activity != null) {
			Artifact artifact = (Artifact) wpDesc.getWorkProduct();
			List list = artifact.getContainedArtifacts();
			int size = list.size();
			if(size > 0) {
				ArrayList artifactDescriptors = new ArrayList();
				for (int i = 0; i < size; i++) {
					Object descriptor = getDescriptor(activity, (Artifact) list
							.get(i));
					if (descriptor != null) {
						artifactDescriptors.add(descriptor);
					}
				}
				if(!artifactDescriptors.isEmpty()) {
					Collections.sort(artifactDescriptors, Comparators.PRESENTATION_NAME_COMPARATOR);
					children.addAll(artifactDescriptors);
				}
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildren(java.lang.Object)
	 */
	public Collection getChildren(Object object) {
		WorkProductDescriptor wpDesc = (WorkProductDescriptor) object;
		
		// don't show the children of the non-deliverable work product descriptor
		// that is deliverable part of a deliverable work product descriptor
		//
		if(!(wpDesc.getWorkProduct() instanceof Deliverable)) {
			Object parent = TngUtil.unwrap(getParent(object));
			if(parent instanceof WorkProductDescriptor
					&& ((WorkProductDescriptor)parent).getWorkProduct() instanceof Deliverable) {				
				updateCachedChildren(Collections.EMPTY_LIST);
				return Collections.EMPTY_LIST;
			}
		}
		
		Collection children = super.getChildren(object);

		// add deliverable parts
		//
		if(!wpDesc.getDeliverableParts().isEmpty()) {
			for (Iterator iter = wpDesc.getDeliverableParts().iterator(); iter
			.hasNext();) {
				WorkProductDescriptor desc = (WorkProductDescriptor) iter.next();
				if (desc.getSuperActivities() == null) {
					children.add(desc);
				}
			}
		}
		
		// get descriptors of contained artifacts
		//		
		if (wpDesc.getWorkProduct() instanceof Artifact) {
			addContainedArtifactDescriptors(wpDesc, children);
		}

		// set parent
		//
		AdapterFactory aFactory = getRootAdapterFactory();

		for (Iterator iter = children.iterator(); iter.hasNext();) {
			IBSItemProvider adapter = (IBSItemProvider) aFactory.adapt(iter
					.next(), ITreeItemContentProvider.class);
			adapter.setParent(object);
		}
		
		updateCachedChildren(children);
		
		return children;
	}
	
	/**
	 * Gets children from cache, fill the children cache if it is not initialized yet
	 * 
	 * @return
	 */
	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;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.edit.process.BreakdownElementItemProvider#dispose()
	 */
	public void dispose() {
		if(cachedChildren != null) {
			cachedChildren.clear();
			cachedChildren = null;
		}
		
		super.dispose();
	}

	public void notifyChanged(Notification notification) {
		switch (notification.getFeatureID(WorkProductDescriptor.class)) {
//		case UmaPackage.WORK_PRODUCT_DESCRIPTOR__MANDATORY_INPUT_TO:
//		case UmaPackage.WORK_PRODUCT_DESCRIPTOR__OPTIONAL_INPUT_TO:
//		case UmaPackage.WORK_PRODUCT_DESCRIPTOR__EXTERNAL_INPUT_TO:
//		case UmaPackage.WORK_PRODUCT_DESCRIPTOR__OUTPUT_FROM:
		case UmaPackage.WORK_PRODUCT_DESCRIPTOR__ACTIVITY_ENTRY_STATE:
		case UmaPackage.WORK_PRODUCT_DESCRIPTOR__ACTIVITY_EXIT_STATE:
			fireNotifyChanged(new ViewerNotification(notification, notification
					.getNotifier(), false, true));
			return;
		case UmaPackage.WORK_PRODUCT_DESCRIPTOR__DELIVERABLE_PARTS:
			List elements = ProcessUtil.getAffectedElements(notification, null);
			int eventType = notification.getEventType();
			boolean refresh = false;
			for (Iterator iter = elements.iterator(); iter.hasNext();) {
				BreakdownElement e = (BreakdownElement) iter.next();
				if (eventType == Notification.ADD
						|| eventType == Notification.ADD_MANY) {
					ProcessUtil.addToContainer(e, this, false);
				}
				if (e.getSuperActivities() != null) {
					fireNotifyChanged(new ViewerNotification(notification, e,
							false, true));
				} else {
					refresh = true;
				}
			}

			if (refresh) {
				fireNotifyChanged(new ViewerNotification(notification,
						notification.getNotifier(), true, false));
			}

			return;
		case UmaPackage.DESCRIBABLE_ELEMENT__PRESENTATION_NAME:
			WorkProductDescriptor wpd = (WorkProductDescriptor) notification
					.getNotifier();
			fireNotifyChanged(new ViewerNotification(notification, wpd, false,
					true));
			if (wpd.getWorkProduct() instanceof Deliverable) {
				for (Iterator iter = wpd.getDeliverableParts().iterator(); iter
						.hasNext();) {
					Object descriptor = iter.next();
					fireNotifyChanged(new ViewerNotification(notification,
							descriptor, false, true));
				}
			}
			return;
		case UmaPackage.WORK_PRODUCT_DESCRIPTOR__SUPPRESSED:
			Object notifier = notification.getNotifier();
			WorkProduct wp;
			boolean contentRefresh = notifier instanceof WorkProductDescriptor
				&& ((wp = ((WorkProductDescriptor)notifier).getWorkProduct()) instanceof Artifact
						|| wp instanceof Deliverable);
			fireNotifyChanged(new ViewerNotification(notification, notification
					.getNotifier(), contentRefresh, true));
			return;
		}

		super.notifyChanged(notification);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.IBSItemProvider#setAttribute(java.lang.Object,
	 *      java.lang.String, java.lang.String)
	 */
	public void setAttribute(Object object, String prop, String txt) {
		WorkProductDescriptor wpd = (WorkProductDescriptor) object;

		if (prop == IBSItemProvider.COL_ENTRY_STATE) {
			wpd.setActivityEntryState(txt);
		} else if (prop == IBSItemProvider.COL_EXIT_STATE) {
			wpd.setActivityExitState(txt);
		} else {
			super.setAttribute(object, prop, txt);
		}
	}

	// private boolean isTopLevelArtifactInActivity(Activity activity, Object
	// obj)
	// {
	// AdapterFactory aFactory = TngUtil.getBestAdapterFactory(adapterFactory);
	//        
	// BSActivityItemProvider adapter = (BSActivityItemProvider)
	// aFactory.adapt(activity, ITreeItemContentProvider.class);
	// Collection children = adapter.getChildren(activity);
	// if (children.contains(obj))
	// {
	// //System.out.println("child - " + obj);
	// return true;
	// }
	// return false;
	// }

	public Collection getEClasses() {
		return ProcessUtil.getPBSEclasses();
	}

	public void moveUp(Object obj, IActionManager actionMgr) {
		Object parent = this.getParent(obj);
		if ((parent != null) && (parent instanceof Activity)) {
			TngUtil.moveUp((Activity) parent, obj, getEClasses(), actionMgr);
		}
		if ((parent != null) && (parent instanceof WorkProductDescriptor)) {
			WorkProduct wp = ((WorkProductDescriptor) parent).getWorkProduct();
			if (wp instanceof Artifact) {
				Artifact artifact = (Artifact) wp;
				List list = artifact.getContainedArtifacts();
				WorkProduct objWP = ((WorkProductDescriptor) obj)
						.getWorkProduct();

				int location = 0;
				// List newList = new ArrayList();
				for (int i = 0; i < list.size(); i++) {
					if (objWP.equals(list.get(i))) {
						location = i;
						break;
					}
				}

				((EList) artifact.getContainedArtifacts()).move(location,
						location - 1);
			}

			Activity activity = this.getActivity(obj);
			TngUtil.moveUp(activity, obj, getEClasses(), actionMgr);
		}
	}

	public void moveDown(Object obj, IActionManager actionMgr) {
		Object parent = this.getParent(obj);
		if ((parent != null) && (parent instanceof Activity)) {
			TngUtil.moveDown((Activity) parent, obj, getEClasses(), actionMgr);
		}
		if ((parent != null) && (parent instanceof WorkProductDescriptor)) {
			WorkProduct wp = ((WorkProductDescriptor) parent).getWorkProduct();
			if (wp instanceof Artifact) {
				Artifact artifact = (Artifact) wp;
				List list = artifact.getContainedArtifacts();
				WorkProduct objWP = ((WorkProductDescriptor) obj)
						.getWorkProduct();

				int location = 0;
				// List newList = new ArrayList();
				for (int i = 0; i < list.size(); i++) {
					if (objWP.equals(list.get(i))) {
						location = i;
						break;
					}
				}

				((EList) artifact.getContainedArtifacts()).move(location,
						location + 1);
			}

			Activity activity = this.getActivity(obj);
			TngUtil.moveDown(activity, obj, getEClasses(), actionMgr);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.BreakdownElementItemProvider#createCreateCopyCommand(org.eclipse.emf.edit.domain.EditingDomain,
	 *      org.eclipse.emf.ecore.EObject,
	 *      org.eclipse.emf.edit.command.CopyCommand.Helper)
	 */
	protected Command createCreateCopyCommand(EditingDomain domain,
			EObject owner, Helper helper) {
		return new WorkProductDescriptorCreateCopyCommand(domain, owner, helper);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#factorRemoveCommand(org.eclipse.emf.edit.domain.EditingDomain, org.eclipse.emf.edit.command.CommandParameter)
	 */
	protected Command factorRemoveCommand(EditingDomain domain, CommandParameter commandParameter) {
		if(!(commandParameter.getOwner() instanceof Activity)) {
			Activity act = getActivity(target);
			if(act != null) {
				IEditingDomainItemProvider adapter = (IEditingDomainItemProvider) adapterFactory.adapt(act, IEditingDomainItemProvider.class);
				commandParameter.setOwner(act);
				return adapter.createCommand(act, domain, RemoveCommand.class, commandParameter);				
			}
		}
		return super.factorRemoveCommand(domain, commandParameter);
	}
	
	public String getAttribute(Object object, String property) {
		// EPF bug#: 144820 Some nested work product descriptors show wrong model info in work product usage view
		// for defect, override the method, previously DescriptorItemProvide.getAttribute use to have this code, moved to here. 
		if (property == IBSItemProvider.COL_MODEL_INFO) {
			StringBuffer modelInfo = new StringBuffer();
				if (object instanceof WorkProductDescriptor) {
//					ProcessUtil.getModelInfoForWorkProductDescriptor(modelInfo,
//							(WorkProductDescriptor) object);
					ProcessUtil.getWPDModelInfo(modelInfo, object, this);
				}
//			}
			return modelInfo.toString(); 
		}
		return super.getAttribute(object, property);
	}

}
