/**
 * File:    FeatureFullDescription.java
 * Created: 11.07.2008
 *
 *
/*******************************************************************************
 * Copyright (c) 2005-2011
 * University of Augsburg, Germany <www.ds-lab.org>
 *
 * 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
 *
 *    Mickael Istria, Open Wide, France
 *      - Creation and Implementation
 *******************************************************************************/

package org.eclipse.jwt.transformations.properties.extension;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;

/**
 * 
 * This class represents the name of a {@link EStructuralFeature}.
 * Thus it containes EMF package, class and feature names
 */
public class FeatureFullDescription {
	private String featureName;
	private String className;
	private String packageName;
	
	/**
	 * Creates the description of a feature from feature, class and package name
	 * @param featureName
	 * @param className
	 * @param packageName
	 */
	public FeatureFullDescription(String featureName, String className, String packageName) {
		this.featureName = featureName;
		this.className = className;
		this.packageName = packageName;
	}
	
	/**
	 * Creates the description of a feature from eObject and property Descriptor
	 * (featureName is computed with propertyDescriptor.getId(eObject))
	 * @param eObject
	 * @param propertyDescriptor
	 */
	public FeatureFullDescription(Object eObject, IItemPropertyDescriptor propertyDescriptor) {
		if (!(eObject instanceof EObject))
			throw new ClassCastException("object [ " + eObject.toString() + "] is not an EObject"); //$NON-NLS-1$ //$NON-NLS-2$
		this.featureName = propertyDescriptor.getId(eObject);
		this.className = ((EObject)eObject).eClass().getName();
		this.packageName = ((EObject)eObject).eClass().getEPackage().getNsURI();
	}
	
	/**
	 * 
	 * @param object the eObject
	 * @param featureName the name of the feature
	 */
	public FeatureFullDescription(Object eObject, String featureName) {
		this.featureName = featureName;
		this.className = ((EObject)eObject).eClass().getName();
		this.packageName = ((EObject)eObject).eClass().getEPackage().getNsURI();
	}

	/**
	 * Two {@link FeatureFullDescription} are equal if package, class and feature are equal
	 */
	@Override
	public boolean equals(Object o) {
		if (! (o instanceof FeatureFullDescription))
			return false;
		FeatureFullDescription dest = (FeatureFullDescription)o;
		return (dest.className == this.className
				&& dest.packageName == this.packageName
				&& dest.featureName == this.featureName);
	}
	
	/**
	 *  Hash of (packageName + className + featureName)
	 */
	@Override
	public int hashCode() {
		return new String(packageName + className + featureName).hashCode();
	}
	
	/**
	 * checks whether the current feature is in fact the baseFeature (maybe seen from a subclass)
	 * @param baseFeature
	 * @return true if current feature is the same feature as a featureToCompare 
	 */
	public boolean isFeatureFromSuperclass(FeatureFullDescription baseFeature) {
		EClass thisFeatureEClass = null;
		EClass baseFeatureEClass = null;
		try {
			EPackage featurePackage = EPackage.Registry.INSTANCE.getEPackage(this.packageName);
			if (featurePackage == null) {
				// happens for packages of non registered dynamic (reflexive rather than generated) ecores,
				// ex. for standalone dynamic aspects
				return false;
			}
			thisFeatureEClass = (EClass) featurePackage.getEClassifier(this.className);
			baseFeatureEClass = (EClass) EPackage.Registry.INSTANCE.getEPackage(baseFeature.getPackageName()).getEClassifier(baseFeature.getClassName());
		} catch (Throwable ex) {
			return false;
		}
		
		return baseFeatureEClass.isSuperTypeOf(thisFeatureEClass)
				&& this.featureName.equals(baseFeature.getFeatureName());
	}

	public String getFeatureName() {
		return featureName;
	}

	public String getClassName() {
		return className;
	}

	public String getPackageName() {
		return packageName;
	}
}
