//------------------------------------------------------------------------------
// 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 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.Descriptor;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Milestone;
import org.eclipse.epf.uma.TeamProfile;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.jface.viewers.Viewer;


/**
 * 
 * @author Phong Le
 * @author Shilpa Toraskar
 * @since 1.0
 *
 */
public class ProcessConfigurator extends ConfigurationFilter {

	private boolean checkOwningProcess;

	/**
	 * @param methodConfig
	 * @param viewer
	 */
	public ProcessConfigurator(MethodConfiguration methodConfig, Viewer viewer) {
		super(methodConfig, viewer);
	}
	
	/**
	 * @param methodConfig
	 * @param viewer
	 * @param checkOwningProcess if true will check on owning process of activities whether it is in the configuration.
	 *          This check is not required in process editor and skipping it helps the performance.
	 */
	public ProcessConfigurator(MethodConfiguration methodConfig, Viewer viewer, boolean checkOwningProcess) {
		this(methodConfig, viewer);
		this.checkOwningProcess = checkOwningProcess;
	}

	public void setMethodConfiguration(MethodConfiguration newConfig) {
		methodConfig = newConfig;
	}

	public boolean accept(Object obj) {
		if (methodConfig == null)
			return true;

		if (obj instanceof BreakdownElement) {
			return accept((BreakdownElement)obj);
		}
		
		return super.accept(obj);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.configuration.ProcessConfigurator#accept(org.eclipse.epf.uma.Descriptor)
	 */
	protected boolean accept(BreakdownElement e) {
		if (e instanceof Milestone || e instanceof TeamProfile) {
			// accept all process elements that are not associated with any content
			// element
			//
			return true;
		} else if (e instanceof Activity) {
			Activity act = ((Activity) e);
			Activity base = (Activity) act.getVariabilityBasedOnElement();
			VariabilityType type = act.getVariabilityType();
			if (base == null)
			{
				if(checkOwningProcess) {
					return ConfigurationHelper.inConfig(TngUtil.getOwningProcess(act), methodConfig);
				}
				else {
					return true;
				}
			}
			else if(type == VariabilityType.EXTENDS_LITERAL || type == VariabilityType.LOCAL_CONTRIBUTION_LITERAL || type == VariabilityType.LOCAL_REPLACEMENT_LITERAL)
			{
				// check owning process of base activity only for extends and local contribution/replacement
				//
				return ConfigurationHelper.inConfig(TngUtil.getOwningProcess(base), methodConfig);
			}
			else {
				return true;
			}
		}
		else if(e instanceof Descriptor) {
			// TODO: need to consider checking on owning process of the descriptor whether it is in the configuration.
			// Currently, this check is not required and skipping it helps the performance.
			// But this check might affect the current code, e.g.: process properties view.
			//
			MethodElement linked_obj = ProcessUtil.getAssociatedElement((Descriptor) e);
			if (linked_obj == null || linked_obj.eIsProxy()) {
				// this is the processes own descriptor (independent from the content)
				// always accept it
				return true;
			} else {
				// make sure that element with replacer might still be accepted
				//
				linked_obj = ConfigurationHelper.getCalculatedElement(linked_obj, methodConfig);

				// if the linked element is not in config, don't accept it
				return ConfigurationHelper.inConfig(linked_obj, methodConfig);
			}		
		}
		
		return super.accept(e);
	}
}