/******************************************************************************
 * Copyright (c) 2004, 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 API and implementation 
 ****************************************************************************/

package org.eclipse.gmf.runtime.emf.core.internal.util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.ResourceLocator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.gmf.runtime.common.core.util.Trace;
import org.eclipse.gmf.runtime.emf.core.internal.plugin.EMFCoreDebugOptions;
import org.eclipse.gmf.runtime.emf.core.internal.plugin.EMFCorePlugin;

/**
 * This class manages meta-models and provide localization of meta-class names.
 * 
 * @author rafikj
 * @author Christian W. Damus (cdamus)
 */
public class MetamodelManager {

	// used to get resource locators when none are provided to us
	private static final ComposedAdapterFactory adapterFactory =
		new ComposedAdapterFactory(
			ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
	
	private final static Map METAMODEL_MAP = new HashMap();

	private final static Map REVERSE_METAMODEL_MAP = new HashMap();

	/**
	 * Register meta-model object.
	 */
	public static void register(ENamedElement element) {
		register(element, null);
	}
	
	/**
	 * Register meta-model object.
	 */
	public static void register(ENamedElement element,
			ResourceLocator resourceLocator) {

		if (element instanceof EOperation)
			return;

		if (element instanceof EParameter)
			return;

		String id = getNonCachedID(element);

		String name = element.getName();

		String displayName = null;

		if ((resourceLocator == null) && (element instanceof EPackage)) {
			// get a resource locator from the adapter factory registered
			//     against the IItemLabelProvider adapter type
			resourceLocator = findResourceLocator((EPackage) element);
		}
		
		if (resourceLocator != null) {

			if (element instanceof EClass) {
				displayName = resourceLocator.getString("_UI_" + name //$NON-NLS-1$
					+ "_type"); //$NON-NLS-1$

			} else if (element instanceof EStructuralFeature) {

				EClass eClass = ((EStructuralFeature) element)
					.getEContainingClass();

				if (eClass != null)
					displayName = resourceLocator.getString("_UI_" //$NON-NLS-1$
						+ eClass.getName() + "_" + name + "_feature"); //$NON-NLS-1$//$NON-NLS-2$

			} else if (element instanceof EEnumLiteral) {

				EEnum eEnum = ((EEnumLiteral) element).getEEnum();

				if (eEnum != null)
					displayName = resourceLocator.getString("_UI_" //$NON-NLS-1$
						+ eEnum.getName() + "_" + name + "_literal"); //$NON-NLS-1$//$NON-NLS-2$
			}
		}

		if (displayName == null)
			displayName = name;

		METAMODEL_MAP.put(element, new MetaModelDescriptor(id, displayName));

		REVERSE_METAMODEL_MAP.put(id, element);

		for (Iterator i = element.eContents().iterator(); i.hasNext();) {

			Object child = i.next();

			if (child instanceof ENamedElement)
				register((ENamedElement) child, resourceLocator);
		}
	}
	
	/**
	 * Attempts to find a resource locator for the specified metamodel package,
	 * using a heuristic that assumes that item-provider adapters implement
	 * the ResourceLocator interface (which is the default code generation).
	 * 
	 * @param pkg a package for which we need a resource locator
	 * 
	 * @return the resource locator if we could find one; <code>null</code> otherwise
	 */
	private static ResourceLocator findResourceLocator(EPackage pkg) {
		ResourceLocator result = null;
		
		// the compased adapter factory has a registry of pairs by EPackage
		//    and adapter class
		List types = new java.util.ArrayList(2);
		types.add(pkg);
		types.add(IItemLabelProvider.class);
		
		AdapterFactory factory = adapterFactory.getFactoryForTypes(types);
		
		if (factory != null) {
			// find some EClass to instantiate to get an item provider for it
			EObject instance = null;
			
			for (Iterator iter = pkg.getEClassifiers().iterator(); iter.hasNext();) {
				Object next = iter.next();
				
				if ((next instanceof EClass) && !((EClass) next).isAbstract()) {
					instance = pkg.getEFactoryInstance().create((EClass) next);
					break;
				}
			}
			
			if (instance != null) {
				Object adapter = factory.adapt(instance, IItemLabelProvider.class);
				
				if (adapter instanceof ResourceLocator) {
					result = (ResourceLocator) adapter;
				}
			}
		}
		
		return result;
	}
	
	/**
	 * Get the ID of a meta-model object.
	 */
	public static String getID(ENamedElement element) {

		if (element instanceof EOperation) {

			RuntimeException e = new IllegalArgumentException(
				"EOperation does not support IDs"); //$NON-NLS-1$

			Trace.throwing(EMFCorePlugin.getDefault(),
				EMFCoreDebugOptions.EXCEPTIONS_THROWING, MetamodelManager.class,
				"getID", e); //$NON-NLS-1$

			throw e;
		}

		if (element instanceof EParameter) {

			RuntimeException e = new IllegalArgumentException(
				"EParameter does not support IDs"); //$NON-NLS-1$

			Trace.throwing(EMFCorePlugin.getDefault(),
				EMFCoreDebugOptions.EXCEPTIONS_THROWING, MetamodelManager.class,
				"getID", e); //$NON-NLS-1$

			throw e;
		}

		MetaModelDescriptor descriptor = (MetaModelDescriptor) METAMODEL_MAP
			.get(element);

		if (descriptor != null)
			return descriptor.id;

		return getNonCachedID(element);
	}

	/**
	 * Get the localized name of a meta-model object. Name does not contain
	 * spaces.
	 */
	public static String getLocalName(ENamedElement element) {

		tryRegisterElement(element);
		
		MetaModelDescriptor descriptor = (MetaModelDescriptor) METAMODEL_MAP
			.get(element);

		if (descriptor != null)
			return descriptor.localName;
		
		

		return element.getName();
	}

	/**
	 * Get the localized name of a meta-model object. Name may contain spaces.
	 */
	public static String getDisplayName(ENamedElement element) {

		tryRegisterElement(element);

		MetaModelDescriptor descriptor = (MetaModelDescriptor) METAMODEL_MAP
			.get(element);

		if (descriptor != null)
			return descriptor.displayName;

		return element.getName();
	}

	/**
	 * Find meta-model object given its ID.
	 */
	public static ENamedElement getElement(String id) {
		ENamedElement result = (ENamedElement) REVERSE_METAMODEL_MAP.get(id);
		
		if ((result == null) && (id != null)) {
			// not registered, yet.  Look it up in the registry
			result = findInPackageRegistry(id);
		}
		
		return result;
	}

	/**
	 * Find the specified named element by ID in the global package registry.
	 * <b>Side-effect:</b>  registers the package when found so that we don't
	 * need to do this again.
	 * 
	 * @param id the ID to find.  Must not be <code>null</code>
	 * @return the named element, or <code>null</code> if not found
	 */
	private static ENamedElement findInPackageRegistry(String id) {
		ENamedElement result = null;
		
		int dot = id.indexOf('.');
		
		String pkgName = (dot >= 0)? id.substring(0, dot) : id;
		
		for (Iterator iter = EPackage.Registry.INSTANCE.values().iterator(); iter.hasNext();) {
			Object next = iter.next();
			
			if (next instanceof EPackage) {
				// skip descriptors because if the EPackage hasn't been
				//    instantiated then it cannot be in use by the client
				EPackage pkg = (EPackage) next;
				
				if (pkgName.equals(pkg.getName())) {
					result = findElement(pkg, id);
					if (result != null) {
						// register the package for subsequent look-ups
						register(pkg, null);
						break;
					}
				}
			}
		}
		
		return result;
	}
	
	private static ENamedElement findElement(ENamedElement element, String id) {
		ENamedElement result = null;
		int dot = id.indexOf('.');
		
		if (dot < 0) {
			if (id.equals(element.getName())) {
				// got the final result
				result = element;
			} // else the element is not found here
		} else {
			String name = id.substring(0, dot);
			
			if (name.equals(element.getName())) {
				// search recursively in the sub-tree
				id = id.substring(dot + 1);
				
				for (Iterator iter = element.eContents().iterator();
						(result == null) && iter.hasNext();) {
					
					Object next = iter.next();
					
					if (next instanceof ENamedElement) {
						result = findElement((ENamedElement) next, id);
					}
				}
			}
		}
		
		return result;
	}
	
	/**
	 * Get the non-cached ID of a meta-model object.
	 */
	private static String getNonCachedID(ENamedElement element) {

		StringBuffer id = new StringBuffer();
		ENamedElement current = element;

		while (current != null) {

			id.insert(0, current.getName());
			EObject container = current.eContainer();

			current = null;

			if (container != null) {
				if ((container instanceof ENamedElement)) {
	
					current = (ENamedElement) container;
	
					id.insert(0, '.');
				} else {
					// ENamedElements not contained by named elements (e.g.,
					//     contained in annotations) are not supported
					return null;
				}
			}
		}

		return id.toString();
	}

	/**
	 * This class describes a meta-model object.
	 */
	private static class MetaModelDescriptor {

		public String id = null;

		public String localName = null;

		public String displayName = null;

		public MetaModelDescriptor(String id, String displayName) {

			super();

			this.id = id.intern();
			this.localName = displayName.replaceAll(" ", "").intern(); //$NON-NLS-1$//$NON-NLS-2$
			this.displayName = displayName.intern();
		}
	}
	
	/**
	 * Registers the package an element belongs to. All elements of the package
	 * are registered with the package
	 * 
	 * @param element An element that will be tried to get registered
	 */
	private static void tryRegisterElement(ENamedElement element)
	{
		// EOperation and EParameter can't have ids and hence cannot be registered
		if (element instanceof EOperation || element instanceof EParameter)
			return;
		
		String id = getID(element);
		
		if (id == null)
			return;
		
		int dot = id.indexOf('.');
		
		// It is assumed that package names are equal to their IDs
		String pkgName = (dot >= 0)? id.substring(0, dot) : id;
		
		// If package is registered than no need to register it again
		if (REVERSE_METAMODEL_MAP.get(pkgName)!=null)
			return;
		
		for (Iterator iter = EPackage.Registry.INSTANCE.values().iterator(); iter.hasNext();) {
			Object next = iter.next();
			
			if (next instanceof EPackage) {
				// skip descriptors because if the EPackage hasn't been
				//    instantiated then it cannot be in use by the client
				EPackage pkg = (EPackage) next;
				
				if (pkgName.equals(pkg.getName())) {
					register(pkg, null);
				}
			}
		}		
	}
}