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

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.command.Command;
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.ecore.resource.Resource;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.command.CopyCommand.Helper;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.ILibraryItemProvider;
import org.eclipse.epf.library.edit.IStatefulItemProvider;
import org.eclipse.epf.library.edit.PresentationContext;
import org.eclipse.epf.library.edit.command.MethodElementAddCommand;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.ContentPackage;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.edit.command.MethodElementCreateCopyCommand;
import org.eclipse.epf.uma.edit.command.MethodElementInitializeCopyCommand;

/**
 * The item provider adapter for the "Content Packages" folder in the Library
 * view.
 * <p>
 * This class will be renamed as ContentPackagesItemProvider in EPF M5.
 * 
 * @author Phong Nguyen Le
 * @author Kelvin Low
 * @since 1.0
 */
public class ContentPackageItemProvider extends
		org.eclipse.epf.uma.provider.ContentPackageItemProvider implements
		IElementItemProvider, ILibraryItemProvider, IStatefulItemProvider {

	protected RolesItemProvider roles;

	protected TasksItemProvider tasks;

	protected WorkProductsItemProvider workProducts;

	protected GuidancesItemProvider guidances;

	protected String label;

	protected Object parent;

	/**
	 * Creates a new instance.
	 */
	public ContentPackageItemProvider(AdapterFactory adapterFactory) {
		super(adapterFactory);
	}

	/**
	 * @return Returns the roles.
	 */
	public RolesItemProvider getRoles() {
		return roles;
	}

	/**
	 * @return Returns the tasks.
	 */
	public TasksItemProvider getTasks() {
		return tasks;
	}

	/**
	 * @return Returns the workProducts.
	 */
	public WorkProductsItemProvider getWorkProducts() {
		return workProducts;
	}

	/*
	 * (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.getMethodPackage_ChildPackages());
	// }
	// return childrenFeatures;
	// }
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildren(java.lang.Object)
	 */
	public Collection getChildren(Object object) {
		List allChildren = new ArrayList();
		ChildrenStore store = getChildrenStore(object);
		List result = null;
		if (store == null) {
			store = createChildrenStore(object);
			result = store != null ? null : new ArrayList();
			EObject eObject = (EObject) object;

			for (Iterator i = getChildrenFeatures(object).iterator(); i
					.hasNext();) {
				EStructuralFeature feature = (EStructuralFeature) i.next();
				if (feature.isMany()) {
					List children = (List) eObject.eGet(feature);
					List contentPkgs = new ArrayList();
					int index = 0;
					for (Iterator ci = children.iterator(); ci.hasNext(); index++) {
						Object child = ci.next();
						if (child instanceof ContentPackage) {
							child = wrap(eObject, feature, child, index);
							// if (store != null)
							// {
							// store.getList(feature).add(child);
							// }
							// else
							// {
							// result.add(child);
							// }
							contentPkgs.add(child);
						}
					}
					
					// clear parent for children
					//
					for (Iterator iter = children.iterator(); iter.hasNext();) {
						Object child = (Object) iter.next();
						Object adapter = adapterFactory.adapt(child,
								ITreeItemContentProvider.class);
						if (adapter instanceof ILibraryItemProvider) {
							((ILibraryItemProvider) adapter).setParent(null);
						}
					}

					// sorting the content packages
					//
					Collections.sort(contentPkgs, PresentationContext.INSTANCE
							.getComparator());

					if (store != null) {
						store.getList(feature).addAll(contentPkgs);
					} else {
						result.addAll(contentPkgs);
					}
				} else {
					Object child = eObject.eGet(feature);
					if (child instanceof ContentPackage) {
						child = wrap(eObject, feature, child,
								CommandParameter.NO_INDEX);
						if (store != null) {
							store.setValue(feature, child);
						} else {
							result.add(child);
						}
					}
				}
			}
		}
		allChildren.addAll(store != null ? store.getChildren() : result);
		ContentPackage contentPkg = (ContentPackage) object;

		// remove old adapters (roles, tasks, workproducts) from the the
		// contentPkg
		//
		// EObject eObj = (EObject) object;
		if (roles == null) {
			// eObj.eAdapters().remove(roles);
			roles = new RolesItemProvider(adapterFactory, contentPkg);
		}
		if (tasks == null) {
			// eObj.eAdapters().remove(tasks);
			tasks = new TasksItemProvider(adapterFactory, contentPkg);
		}
		if (workProducts == null) {
			// eObj.eAdapters().remove(workProducts);
			workProducts = new WorkProductsItemProvider(adapterFactory,
					contentPkg);
		}
		if (guidances == null) {
			// eObj.eAdapters().remove(guidances);
			guidances = new GuidancesItemProvider(adapterFactory, contentPkg);
		}

		allChildren.add(roles);
		allChildren.add(tasks);
		allChildren.add(workProducts);
		allChildren.add(guidances);
		return allChildren;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#collectNewChildDescriptors(java.util.Collection,
	 *      java.lang.Object)
	 */
	protected void collectNewChildDescriptors(Collection<Object> newChildDescriptors,
			Object object) {
		newChildDescriptors.add(createChildParameter(UmaPackage.eINSTANCE
				.getMethodPackage_ChildPackages(), UmaFactory.eINSTANCE
				.createContentPackage()));
	}

	// /* (non-Javadoc)
	// * @see
	// org.eclipse.emf.edit.provider.ItemProviderAdapter#createCommand(java.lang.Object,
	// org.eclipse.emf.edit.domain.EditingDomain, java.lang.Class,
	// org.eclipse.emf.edit.command.CommandParameter)
	// */
	// public Command createCommand(Object object, EditingDomain domain,
	// Class commandClass, CommandParameter commandParameter) {
	// // commandParameter.setOwner(((EObject)object).eContainer());
	// Command cmd = super.createCommand(object, domain, commandClass,
	// commandParameter);
	// System.out.println(getClass().getName() + "#createCommand: " +
	// commandClass + ", can execute: " + cmd.canExecute() + ", owner: " +
	// commandParameter.getOwner() + ", collection: " +
	// commandParameter.getCollection());
	// return cmd;
	// }

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getText(java.lang.Object)
	 */
	public String getText(Object object) {
		String txt;
		if (label != null) {
			txt = label;
		} else {
			txt = TngUtil
					.getLabel(object, getString("_UI_ContentPackage_type")); //$NON-NLS-1$
		}
		// check if the object has its own resource and it is modified to add
		// the dirty flag
		//
		Resource res = ((EObject) object).eResource();
		if (res != null && res.getContents().get(0) == object
				&& res.isModified()) {
			txt = txt + "*"; //$NON-NLS-1$
		}
		return txt;
	}

	private void setDefaultName(Object obj) {
		ContentPackage contentPackage = (ContentPackage) target;
		if (obj instanceof ContentPackage) {
			TngUtil.setDefaultName(contentPackage.getChildPackages(),
					(MethodElement) obj, "content_package"); //$NON-NLS-1$
		} else {
			TngUtil.setDefaultName(contentPackage.getChildPackages(),
					(MethodElement) obj, "method_package"); //$NON-NLS-1$
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
	 */
	public void notifyChanged(Notification msg) {
		TngUtil.refreshParentIfNameChanged(msg, this);

		switch (msg.getFeatureID(ContentPackage.class)) {
		case UmaPackage.CONTENT_PACKAGE__CONTENT_ELEMENTS:
			return;
		case UmaPackage.CONTENT_PACKAGE__CHILD_PACKAGES:
			switch (msg.getEventType()) {
			case Notification.ADD:
				setDefaultName(msg.getNewValue());
				break;
			case Notification.ADD_MANY:
				for (Iterator iter = ((Collection) msg.getNewValue())
						.iterator(); iter.hasNext();) {
					setDefaultName(iter.next());
				}
				break;
			}
		}

		super.notifyChanged(msg);
	}

	/**
	 * @return
	 */
	public GuidancesItemProvider getGuidances() {
		return guidances;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.IConfigurable#setFilter(com.ibm.library.edit.IFilter)
	 */
	public void setFilter(IFilter filter) {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.IConfigurable#setLabel(java.lang.String)
	 */
	public void setLabel(String label) {
		this.label = label;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.IConfigurable#setParent(java.lang.Object)
	 */
	public void setParent(Object parent) {
		this.parent = parent;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getParent(java.lang.Object)
	 */
	public Object getParent(Object object) {
		if (parent != null)
			return parent;
		return super.getParent(object);
	}

	// public Object getImage(Object object) {
	// return TngEditPlugin.INSTANCE.getImage("full/obj16/MethodPackages");
	// }

	protected Command createInitializeCopyCommand(EditingDomain domain,
			EObject owner, Helper helper) {
		return new MethodElementInitializeCopyCommand(domain, owner, helper);
	}

	protected Command createCreateCopyCommand(EditingDomain domain,
			EObject owner, Helper helper) {
		return new MethodElementCreateCopyCommand(domain, owner, helper);
	}

	protected Command createAddCommand(EditingDomain domain, EObject owner,
			EStructuralFeature feature, Collection collection, int index) {
		ArrayList selection = new ArrayList();
		for (Iterator iter = collection.iterator(); iter.hasNext();) {
			Object element = iter.next();

			// make sure that you cannot add MethodPackage that is not a
			// ContentPackage
			//
			if (element instanceof MethodPackage
					&& !(element instanceof ContentPackage)) {
				continue;
			}

			selection.add(element);
		}

		return new MethodElementAddCommand((AddCommand) super.createAddCommand(
				domain, owner, feature, selection, index));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#dispose()
	 */
	public void dispose() {
		if (guidances != null) {
			guidances.dispose();
			guidances = null;
		}
		if (roles != null) {
			roles.dispose();
			roles = null;
		}
		if (tasks != null) {
			tasks.dispose();
			tasks = null;
		}
		if (workProducts != null) {
			workProducts.dispose();
			workProducts = null;
		}
		super.dispose();
	}

}
