//------------------------------------------------------------------------------
// 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.ArrayList;
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.IElementLayout;
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.library.util.LibraryUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.Descriptor;
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);
	}

	/**
	 * @see org.eclipse.epf.library.layout.IElementLayout#getXmlElement(boolean)
	 */
	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$
			
			// add the descriptors referencing this element
			super.processDescriptors(elementXml);
			
		}
		
		elementXml.setAttribute("ShowFullMethodContent", (layoutManager.getValidator().showExtraInfoForDescriptors()) ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		
		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); //$NON-NLS-1$
		}

		return super.acceptFeatureValue(feature, value);
	}

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

}
