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

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

import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.ecore.util.OppositeFeature;

/**
 * realized feature value for a toMany opposite feature
 * 
 * @author Jinhua Xi
 * @since 1.0
 *
 */
public class ToManyOppositeFeatureValue extends ToManyFeatureValue {
	
	/**
	 * @see construct a feature value object for to-many opposite feature
	 * 
	 * @param element
	 * @param feature
	 * @param realizer
	 */
	public ToManyOppositeFeatureValue(MethodElement element, OppositeFeature feature, ElementRealizer realizer) {
		super(element, null, feature, realizer);
	}

	

	/**
	 * @see org.eclipse.epf.library.configuration.ToManyFeatureValue#add(VariabilityElement, Object)
	 */
	public void add(VariabilityElement owner, Object value) {
		
		// work around for opposite feature value that still return a single value instead of a list
		if ( value instanceof MethodElement ) {
			ArrayList v = new ArrayList();
			v.add(value);
			value = v;
		}
		
		if ( !(value instanceof List) ) {	
			return;
		}
			
		OppositeFeature of = (OppositeFeature)feature;
		EStructuralFeature f = of.getTargetFeature();

		for (Iterator it = ((List) value).iterator(); it.hasNext();) {
			MethodElement e = (MethodElement) it.next();

			// Replace does not completely remove
			// outgoing associations
			// if the opposite feature value has replacer in the
			// configuration
			// it's outgoing associations (i.e., this element) will be
			// replaced by the replacing element
			// as a result, the opposite feature value should drop the
			// replaced element
			//
			// for example, R1 -> responsible for A1, R2 responsible for
			// A2
			// if R2 replaces R1, then R2 still responsible for A2
			// but A1 does not have a responsible role (not R2)
			// so for A1's responsible role opposite feature,
			// the value R1 should be dropped instead of realize to R2
			// Jinhua Xi, 10/27/2005
			
			// check the replacer is not enough. If the base element is replaced, 
			// all the contributors to the base should also be considered as replaced.
			// so realize the element, see if it is a replacer
			// Bug 199686 - Replacing roles does not update responsible work product's pages
			VariabilityElement replacer = null;
			if ( e instanceof VariabilityElement ) {
				//replacer = ConfigurationHelper.getReplacer((VariabilityElement) e, realizer.getConfiguration());
				replacer = (VariabilityElement)ConfigurationHelper.getCalculatedElement(e, realizer);
				if ( (replacer == e) || !ConfigurationHelper.isReplacer(replacer) ) {
					replacer = null;
				}
				
			}
			boolean isValueReplaced = (replacer != null);

			boolean keep = !isValueReplaced;
			if ( isValueReplaced && 
					(ConfigurationHelper.isExtendReplacer(replacer) 
					|| ElementRealizer.isExtendReplaceEnabled()) ) {
				// if the value is replaced, but the out going feature is inherited by the replacer
				// then we should keep this value, so we need to calculate the feature value 
				// of the replacer
				if ( f.isMany() ) {
					List items = ConfigurationHelper.calc0nFeatureValue(replacer, f, realizer);
					keep = items.contains(owner);
				} else {
					MethodElement item = ConfigurationHelper.calc01FeatureValue(replacer, f, realizer);
					keep = (item == owner);
				}
			}
			
			// if the value's feature to this element is to-one, 
			// then this value's feature value should be the element,
			// otherwise drop the value
			// for example, 
			// T1 -> R1 (primary performaer)
			// T2 -> R2
			// T2 contributes to T1
			// since T1 already has R1, so R2 is droped
			// so when calculating R2's performing tasks, T1 should not be included
			if ( keep ) {
				MethodElement ve = ConfigurationHelper.getCalculatedElement(e, realizer);
				if ( ve != null ) {
					
					// check if this is a to-one feature, currently only Task->Primary Role and TD -> Primary RD
					EStructuralFeature f1 = ConfigurationHelper.get01Feature(of);
					if ( f1 != null ) {
						MethodElement item = ConfigurationHelper.calc01FeatureValue(ve, f1, realizer);
						
						// if the value element's to-one feature value item is not the current element, 
						// then the element's opposite feature value should not contain this value.
						// say, the value element is a task and the current element is a role,
						// then if the task's primary performer (item above) is not this role (the current element), 
						// then the role's performing tasks (the opposite feature value) 
						// should not contain this task (the value, ve above)
						if ( item != element) {
							keep = false;
						}
					}
				}
			}
			
			
			if ( keep ) {
					
				MethodElement ce = ConfigurationHelper.getCalculatedElement(e, realizer);

				// calculated element can be null if it can't show
				if (ce != null && !values.contains(ce)) {
					values.add(ce);
				}
			}
			
			
			// if the element e has extenders and the extender's feature is the owner element, 
			// then we also need to include the extender
			processExtenders(e, f);
		}	
	}
	
	private void processExtenders(MethodElement e, EStructuralFeature f) {
		if ( !(e instanceof VariabilityElement) ) {
			return;
		}
		
		VariabilityElement ve = (VariabilityElement)e;
		
		List items = ConfigurationHelper.getExtenders( ve, realizer.getConfiguration());
		if ( items.size() > 0 ) {		
			for (Iterator it = items.iterator(); it.hasNext();) {
				MethodElement me = (MethodElement) it.next();
				boolean keep = false;
				if ( f.isMany() ) {
					List vx = ConfigurationHelper.calc0nFeatureValue(me, f, realizer);
					// if the value contains the owner element, then include it
					keep = (vx != null) && vx.contains(super.element);
				} else {
					MethodElement v = ConfigurationHelper.calc01FeatureValue(me, f, realizer);
					
					// if the feature value is the owner element, then this value should be included
					keep = (v == super.element);
				}
				
				if (keep && !super.values.contains(me) ) {
					super.values.add(me);
					processExtenders(me, f);
				}
			}
		}
		
		// if the element is a contributor or replacer, also need to check the extenders of the base element
		if ( ConfigurationHelper.isContributor(ve) || ConfigurationHelper.isReplacer(ve) ) {
			processExtenders(ve.getVariabilityBasedOnElement(), f);
		}
	}
}
