//------------------------------------------------------------------------------
// 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.layout.elements;

import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.edit.util.Comparators;
import org.eclipse.epf.library.layout.ElementLayoutManager;
import org.eclipse.epf.library.layout.diagram.MethodElementDiagram;
import org.eclipse.epf.library.layout.diagram.RoleDiagramPublisher;
import org.eclipse.epf.library.layout.util.XmlElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.ecore.util.OppositeFeature;
import org.eclipse.epf.uma.util.AssociationHelper;

/**
 * The element layout for a Role.
 * 
 * @author Jinhua Xi
 * @author Kelvin Low
 * @since 1.0
 */
public class RoleLayout extends AbstractElementLayout {

	protected Map referenceMap = new HashMap();

	public RoleLayout() {
		super();
	}

	public void init(ElementLayoutManager layoutManager, MethodElement element) {
		super.__init(layoutManager, element);
	}

	public XmlElement getXmlElement(boolean includeReferences) {
		XmlElement elementXml = super.getXmlElement(includeReferences);
		if (includeReferences) {
			List performs = ConfigurationHelper.calc0nFeatureValue(
					super.element, AssociationHelper.Role_Primary_Tasks,
					layoutManager.getElementRealizer());
			referenceMap.put("performs", performs); //$NON-NLS-1$

			// NO, this is wrong! should calculate the realized feature value!
			// moved to acceptFeatureValue to get the realized value and save to
			// the map
			// if (super.element instanceof RoleImpl)
			// {
			// referenceMap.put("responsibleFor",
			// ((RoleImpl)super.element).getResponsibleFor());
			// }

			List additionallyPerforms = ConfigurationHelper.calc0nFeatureValue(
					super.element, AssociationHelper.Role_Secondary_Tasks,
					layoutManager.getElementRealizer());
			// referenceMap.put("additionallyPerforms", additionallyPerforms);
			// //$NON-NLS-1$
			addReferences(AssociationHelper.Role_Secondary_Tasks, elementXml,
					"additionallyPerforms", additionallyPerforms); //$NON-NLS-1$
			RoleDiagramPublisher diagramPublisher = new RoleDiagramPublisher();
			MethodElementDiagram diagram = diagramPublisher.publish(this,
					new File(layoutManager.getPublishDir()));

			if (diagram != null)
				elementXml.setContent("diagram", diagram.getHTML()); //$NON-NLS-1$

			List roleSets = ConfigurationHelper.calc0nFeatureValue(
					super.element, AssociationHelper.Role_RoleSets,
					layoutManager.getElementRealizer());
			addReferences(AssociationHelper.Role_RoleSets, elementXml,
					"roleSets", roleSets); //$NON-NLS-1$
		}
		return elementXml;
	}

	public List getPerforms() {
		List list = (List) referenceMap.get("performs"); //$NON-NLS-1$
		Collections.sort(list, Comparators.PRESENTATION_NAME_COMPARATOR);
		return list;
	}

	public List getAdditionallyPerforms() {
		List list = (List) referenceMap.get("additionallyPerforms"); //$NON-NLS-1$
		Collections.sort(list, Comparators.PRESENTATION_NAME_COMPARATOR);
		return list;		
	}

	public List getResponsibleFor() {
		List list =  (List) referenceMap.get("responsibleFor"); //$NON-NLS-1$
		Collections.sort(list, Comparators.PRESENTATION_NAME_COMPARATOR);
		return list;		
	}

	public List getModifies() {
		List list =  (List) referenceMap.get("modifies"); //$NON-NLS-1$
		Collections.sort(list, Comparators.PRESENTATION_NAME_COMPARATOR);
		return list;		
	}

	/**
	 * some layout need to have the feature values for further processing. So
	 * this method will be called when a feature is calculated in this abstract
	 * class
	 * 
	 * @param name
	 * @param value
	 */
	protected void notifyFeatureValue(String name, Object value) {
		referenceMap.put(name, value);
	}

	/**
	 * some layout need to have the feature values for further processing. So
	 * this method will be called when a feature is calculated in this abstract
	 * class
	 * 
	 * @param name
	 * @param value
	 */
	protected boolean acceptFeatureValue(EStructuralFeature feature,
			Object value) {

		// save the feature value for diagram generation
		if (feature == UmaPackage.eINSTANCE.getRole_ResponsibleFor()) {
			referenceMap.put("responsibleFor", value);
		}

		return super.acceptFeatureValue(feature, value);
	}

	protected boolean acceptFeatureValue(OppositeFeature feature, Object value) {
		return super.acceptFeatureValue(feature, value);
	}

}
