package org.eclipse.epf.library.realization.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.configuration.DefaultElementRealizer;
import org.eclipse.epf.library.configuration.ElementRealizer;
import org.eclipse.epf.library.edit.realization.IRealizedWorkProductDescriptor;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.Artifact;
import org.eclipse.epf.uma.Deliverable;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.WorkProductDescriptor;

public class RealizedWorkProductDescriptor extends
		RealizedDescriptor implements IRealizedWorkProductDescriptor {

	private static Set<EStructuralFeature> featureSet = new HashSet<EStructuralFeature>();
	static {
		UmaPackage up = UmaPackage.eINSTANCE;		
//		featureSet.add(up.getNamedElement_Name());
//		featureSet.add(up.getMethodElement_PresentationName());
	}
	
	public RealizedWorkProductDescriptor(WorkProductDescriptor wpd) {
		super(wpd);
	}
	
	
	public boolean handleFeature(EStructuralFeature feature) {
		if (featureSet.contains(feature)) {
			return true;
		}
		return super.handleFeature(feature);
	}
	
	protected MethodElement getRawLinkedElement() {
		return getWorkProductDescriptor().getWorkProduct();
	}
	
	private WorkProductDescriptor getWorkProductDescriptor() {
		return (WorkProductDescriptor) getElement();
	}
	
	public List<WorkProductDescriptor> getDeliverableParts() {
		if (!(getLinkedElement() instanceof Deliverable)) {
			return Collections.EMPTY_LIST;
		}
		UmaPackage up = UmaPackage.eINSTANCE;
		EReference wpdReference = up
				.getWorkProductDescriptor_DeliverableParts();
		List<WorkProductDescriptor> wpdList = (List<WorkProductDescriptor>) getCachedValue(wpdReference);
		if (wpdList == null) {
			EReference[] wpdFeatures = { wpdReference,
					up.getWorkProductDescriptor_DeliverablePartsExclude(), };
			wpdList = (List<WorkProductDescriptor>) getDescriptorList(up
					.getDeliverable_DeliveredWorkProducts(), wpdFeatures);
			storeCachedValue(wpdReference, wpdList);
		}
		return wpdList;
	}
	
	public List<WorkProductDescriptor> getContainedArtifacts() {
		if (!(getLinkedElement() instanceof Artifact)) {
			return Collections.EMPTY_LIST;
		}
		UmaPackage up = UmaPackage.eINSTANCE;
		EReference wpdReference = ArtifactDescriptor_ContainedArtifacts;
		List<WorkProductDescriptor> wpdList = (List<WorkProductDescriptor>) getCachedValue(wpdReference);
		if (wpdList == null) {
			wpdList = new ArrayList<WorkProductDescriptor>();
			ElementRealizer realizer = DefaultElementRealizer
					.newElementRealizer(getConfig());
			List<MethodElement> elementList = ConfigurationHelper
					.calc0nFeatureValue(getLinkedElement(), up
							.getArtifact_ContainedArtifacts(), realizer);
			if (elementList != null && !elementList.isEmpty()) {
				Activity parentAct = getDescriptor().getSuperActivities();
				if (parentAct != null) {

					for (MethodElement me : elementList) {
						WorkProductDescriptor des = (WorkProductDescriptor) getMgr()
								.getDescriptor(getDescriptor(), parentAct, me,
										wpdReference);
						wpdList.add(des);
					}
				}
			}
			storeCachedValue(wpdReference, wpdList);
		}
		return wpdList;
	}
	
	@Override
	public Set<Descriptor> getAllReferenced() {
		Set<Descriptor> referenced = new HashSet<Descriptor>();
		addToSet(referenced, getDeliverableParts());
		addToSet(referenced, getContainedArtifacts());
		return referenced;
	}
	
	
}
