/**
 * File:    EMFUtils.java
 * Created: 20.07.2008
 *
 *
/*******************************************************************************
 * Copyright (c) 2008-2009 Open Wide SA <www.openwide.fr>
 *
 * 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:
 *    Marc Dutoo, Open Wide SA 
 *    	- initial API and implementation
 *******************************************************************************/

package org.eclipse.jwt.we.conf.model.plugin.internal;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.EPackage.Registry;
import org.eclipse.emf.ecore.resource.Resource;


/**
 * Test-minded EMF utils
 * 
 * @version $Id: EMFUtils.java,v 1.1 2010-05-10 08:27:22 chsaad Exp $
 * @author Marc Dutoo, Open Wide SA
 */
public class EMFUtils {

	/**
	 * The Logger.
	 */
	private static Logger logger = Logger.getLogger(EMFUtils.class);


	/**
	 * Helper
	 * @param element of the decorated model
	 * @return its root element
	 */
	public static final EObject getRootEObject(Object modelElement) {
		if (!(modelElement instanceof EObject)) {
			return null;
		} // else not null eObject
		
		EObject eModelElement = (EObject) modelElement;
		EObject eContainer = null;
		while ((eContainer = eModelElement.eContainer()) != null) {
			eModelElement = eContainer;
		}
		return eModelElement;
	}
	
	
	/**
	 * Returns the resource URI, and if no resource the proxy URI if any
	 * @param object
	 * @return
	 */
	public static URI getResourceOrProxyURI(EObject eObject) {
		URI eObjectResourceURI = null;
		Resource eObjectResource = eObject.eResource();
		if (eObjectResource != null) {
			// regular case : the external referenced model exists, and its resource has a uri
			eObjectResourceURI  = eObjectResource.getURI();
			
		} else if (eObject.eIsProxy() && eObject instanceof InternalEObject) {
			// case when the referenced model doesn't exist : get the reference URI and remove its fragment (ex. #/)
			URI eObjectURI = ((InternalEObject) eObject).eProxyURI();
			eObjectResourceURI = eObjectURI.trimFragment();
		}
		return eObjectResourceURI;
	}

	public final static void updateResourceOrProxyURI(EObject eObject, URI newURI) {
		Resource eObjectResource = eObject.eResource();
		if (eObjectResource != null) {
			eObjectResource.setURI(newURI);
		} else {
			if (eObject.eIsProxy()) {
				URI eObjectURI = ((InternalEObject) eObject).eProxyURI();
				URI newEObjectURI = newURI.appendFragment(eObjectURI.fragment());
				((InternalEObject) eObject).eSetProxyURI(newEObjectURI);
			}
		}
	}
	
	
	/**
	 * 
	 * @param modelElementEType
	 * @return
	 */
	public static EClass toEClass(String modelElementEType) {
		int packageEndIndex = Math.max(modelElementEType.lastIndexOf('.'), modelElementEType.lastIndexOf('/'));
		String targetEPackageName = modelElementEType.substring(0, packageEndIndex);
		String targetEClassName = modelElementEType.substring(packageEndIndex + 1);
		EPackage targetEPackage = Registry.INSTANCE.getEPackage(targetEPackageName);
		if (targetEPackage == null) {
			return null;
		}
		EClass targetEClass = (EClass) targetEPackage.getEClassifier(targetEClassName);
		if (targetEClass == null) {
			return null;
		}
		return targetEClass;
	}
	
	public static EPackage getETypeEPackage(URI eTypeURI) {
		EPackage foundEPackage = EPackage.Registry.INSTANCE.getEPackage(eTypeURI.trimFragment().toString());
		return foundEPackage;
	}
	
	public static EClassifier getETypeEClassifier(URI eTypeURI) {
		EPackage foundEPackage = getETypeEPackage(eTypeURI);
		if (foundEPackage == null) {
			return null;
		}
		return getETypeEClassifier(eTypeURI, foundEPackage);
	}
	
	public static EClassifier getETypeEClassifier(URI eTypeURI, EPackage eTypeEPackage) {
        Resource eTypeResource = eTypeEPackage.eResource();
        if (eTypeResource != null) {
        	EObject foundEObject = eTypeResource.getEObject(eTypeURI.fragment().toString());
        	if (foundEObject instanceof EClassifier) {
            	return (EClassifier) foundEObject;
        	} else {
        		logger.warning("Can't find eClassifier of eType " + eTypeURI + " in ePackage " + eTypeEPackage); //$NON-NLS-1$ //$NON-NLS-2$
        	}
        }
		return null;
	}
	
}
