/**
 * *******************************************************************************
 *  Copyright (c) 2015-2021 Robert Bosch GmbH and others.
 * 
 *  This program and the accompanying materials are made
 *  available under the terms of the Eclipse Public License 2.0
 *  which is available at https://www.eclipse.org/legal/epl-2.0/
 * 
 *  SPDX-License-Identifier: EPL-2.0
 * 
 *     Generated using Eclipse EMF
 * 
 * *******************************************************************************
 */
package org.eclipse.app4mc.amalthea.model.impl;

import java.lang.reflect.InvocationTargetException;

import java.util.Map;
import org.eclipse.app4mc.amalthea.model.AmaltheaExtensions;
import org.eclipse.app4mc.amalthea.model.AmaltheaPackage;
import org.eclipse.app4mc.amalthea.model.AmaltheaValidations;
import org.eclipse.app4mc.amalthea.model.INamed;
import org.eclipse.app4mc.amalthea.model.IReferable;
import org.eclipse.app4mc.amalthea.model.Namespace;
import org.eclipse.app4mc.amalthea.model.ReferableBaseObject;
import org.eclipse.app4mc.amalthea.model.Value;

import org.eclipse.app4mc.amalthea.model.emf.AmaltheaEObjectImpl;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.EMap;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.emf.ecore.impl.ENotificationImpl;

import org.eclipse.emf.ecore.util.EcoreEMap;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.ecore.xcore.lib.XcoreCollectionLiterals;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Referable Base Object</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.ReferableBaseObjectImpl#getCustomProperties <em>Custom Properties</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.ReferableBaseObjectImpl#getName <em>Name</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.ReferableBaseObjectImpl#getQualifiedName <em>Qualified Name</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.ReferableBaseObjectImpl#getUniqueName <em>Unique Name</em>}</li>
 * </ul>
 *
 * @generated
 */
public abstract class ReferableBaseObjectImpl extends AmaltheaEObjectImpl implements ReferableBaseObject {
	/**
	 * The cached value of the '{@link #getCustomProperties() <em>Custom Properties</em>}' map.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCustomProperties()
	 * @generated
	 * @ordered
	 */
	protected EMap<String, Value> customProperties;

	/**
	 * The default value of the '{@link #getName() <em>Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getName()
	 * @generated
	 * @ordered
	 */
	protected static final String NAME_EDEFAULT = "";

	/**
	 * The cached value of the '{@link #getName() <em>Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getName()
	 * @generated
	 * @ordered
	 */
	protected String name = NAME_EDEFAULT;

	/**
	 * The default value of the '{@link #getQualifiedName() <em>Qualified Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getQualifiedName()
	 * @generated
	 * @ordered
	 */
	protected static final String QUALIFIED_NAME_EDEFAULT = null;

	/**
	 * The default value of the '{@link #getUniqueName() <em>Unique Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getUniqueName()
	 * @generated
	 * @ordered
	 */
	protected static final String UNIQUE_NAME_EDEFAULT = null;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected ReferableBaseObjectImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return AmaltheaPackage.eINSTANCE.getReferableBaseObject();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EMap<String, Value> getCustomProperties() {
		if (customProperties == null) {
			customProperties = new EcoreEMap<String,Value>(AmaltheaPackage.eINSTANCE.getCustomProperty(), CustomPropertyImpl.class, this, AmaltheaPackage.REFERABLE_BASE_OBJECT__CUSTOM_PROPERTIES);
		}
		return customProperties;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getName() {
		return name;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setName(String newName) {
		String oldName = name;
		name = newName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AmaltheaPackage.REFERABLE_BASE_OBJECT__NAME, oldName, name));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getQualifiedName() {
		return AmaltheaExtensions.toPlainString(this.getQualifiedNameSegments(), this.getDefaultNameSeparator());
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getUniqueName() {
		String _encodedQualifiedName = this.getEncodedQualifiedName();
		String _plus = (_encodedQualifiedName + "?type=");
		String _name = this.eClass().getName();
		return (_plus + _name);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getEncodedQualifiedName() {
		return AmaltheaExtensions.toEncodedString(this.getQualifiedNameSegments());
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean validateInvariants(final DiagnosticChain diagnostics, final Map<Object, Object> context) {
		return AmaltheaValidations.validateInvariants(this, diagnostics);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public INamed getNamedContainer() {
		INamed _xifexpression = null;
		EObject _eContainer = this.eContainer();
		if ((_eContainer instanceof INamed)) {
			EObject _eContainer_1 = this.eContainer();
			_xifexpression = ((INamed) _eContainer_1);
		}
		else {
			_xifexpression = null;
		}
		return _xifexpression;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getNamePrefix() {
		String _xifexpression = null;
		Namespace _namespace = this.getNamespace();
		boolean _tripleEquals = (_namespace == null);
		if (_tripleEquals) {
			return "";
		}
		else {
			_xifexpression = AmaltheaExtensions.toPlainString(this.getNamePrefixSegments(), this.getDefaultNameSeparator());
		}
		return _xifexpression;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<String> getQualifiedNameSegments() {
		final EList<String> segments = this.getNamePrefixSegments();
		String _name = this.getName();
		boolean _tripleNotEquals = (_name != null);
		if (_tripleNotEquals) {
			segments.add(this.getName());
		}
		return segments;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getDefaultNameSeparator() {
		return ".";
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Namespace getNamespace() {
		return null;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<String> getNamePrefixSegments() {
		EList<String> _elvis = null;
		Namespace _namespace = this.getNamespace();
		EList<String> _qualifiedNameSegments = null;
		if (_namespace!=null) {
			_qualifiedNameSegments=_namespace.getQualifiedNameSegments();
		}
		if (_qualifiedNameSegments != null) {
			_elvis = _qualifiedNameSegments;
		} else {
			BasicEList<String> _newBasicEList = XcoreCollectionLiterals.<String>newBasicEList();
			_elvis = _newBasicEList;
		}
		return _elvis;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case AmaltheaPackage.REFERABLE_BASE_OBJECT__CUSTOM_PROPERTIES:
				return ((InternalEList<?>)getCustomProperties()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case AmaltheaPackage.REFERABLE_BASE_OBJECT__CUSTOM_PROPERTIES:
				if (coreType) return getCustomProperties();
				else return getCustomProperties().map();
			case AmaltheaPackage.REFERABLE_BASE_OBJECT__NAME:
				return getName();
			case AmaltheaPackage.REFERABLE_BASE_OBJECT__QUALIFIED_NAME:
				return getQualifiedName();
			case AmaltheaPackage.REFERABLE_BASE_OBJECT__UNIQUE_NAME:
				return getUniqueName();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case AmaltheaPackage.REFERABLE_BASE_OBJECT__CUSTOM_PROPERTIES:
				((EStructuralFeature.Setting)getCustomProperties()).set(newValue);
				return;
			case AmaltheaPackage.REFERABLE_BASE_OBJECT__NAME:
				setName((String)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case AmaltheaPackage.REFERABLE_BASE_OBJECT__CUSTOM_PROPERTIES:
				getCustomProperties().clear();
				return;
			case AmaltheaPackage.REFERABLE_BASE_OBJECT__NAME:
				setName(NAME_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case AmaltheaPackage.REFERABLE_BASE_OBJECT__CUSTOM_PROPERTIES:
				return customProperties != null && !customProperties.isEmpty();
			case AmaltheaPackage.REFERABLE_BASE_OBJECT__NAME:
				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
			case AmaltheaPackage.REFERABLE_BASE_OBJECT__QUALIFIED_NAME:
				return QUALIFIED_NAME_EDEFAULT == null ? getQualifiedName() != null : !QUALIFIED_NAME_EDEFAULT.equals(getQualifiedName());
			case AmaltheaPackage.REFERABLE_BASE_OBJECT__UNIQUE_NAME:
				return UNIQUE_NAME_EDEFAULT == null ? getUniqueName() != null : !UNIQUE_NAME_EDEFAULT.equals(getUniqueName());
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) {
		if (baseClass == INamed.class) {
			switch (derivedFeatureID) {
				case AmaltheaPackage.REFERABLE_BASE_OBJECT__NAME: return AmaltheaPackage.INAMED__NAME;
				case AmaltheaPackage.REFERABLE_BASE_OBJECT__QUALIFIED_NAME: return AmaltheaPackage.INAMED__QUALIFIED_NAME;
				default: return -1;
			}
		}
		if (baseClass == IReferable.class) {
			switch (derivedFeatureID) {
				case AmaltheaPackage.REFERABLE_BASE_OBJECT__UNIQUE_NAME: return AmaltheaPackage.IREFERABLE__UNIQUE_NAME;
				default: return -1;
			}
		}
		return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) {
		if (baseClass == INamed.class) {
			switch (baseFeatureID) {
				case AmaltheaPackage.INAMED__NAME: return AmaltheaPackage.REFERABLE_BASE_OBJECT__NAME;
				case AmaltheaPackage.INAMED__QUALIFIED_NAME: return AmaltheaPackage.REFERABLE_BASE_OBJECT__QUALIFIED_NAME;
				default: return -1;
			}
		}
		if (baseClass == IReferable.class) {
			switch (baseFeatureID) {
				case AmaltheaPackage.IREFERABLE__UNIQUE_NAME: return AmaltheaPackage.REFERABLE_BASE_OBJECT__UNIQUE_NAME;
				default: return -1;
			}
		}
		return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eDerivedOperationID(int baseOperationID, Class<?> baseClass) {
		if (baseClass == INamed.class) {
			switch (baseOperationID) {
				case AmaltheaPackage.INAMED___GET_NAMED_CONTAINER: return AmaltheaPackage.REFERABLE_BASE_OBJECT___GET_NAMED_CONTAINER;
				case AmaltheaPackage.INAMED___GET_NAME_PREFIX: return AmaltheaPackage.REFERABLE_BASE_OBJECT___GET_NAME_PREFIX;
				case AmaltheaPackage.INAMED___GET_QUALIFIED_NAME_SEGMENTS: return AmaltheaPackage.REFERABLE_BASE_OBJECT___GET_QUALIFIED_NAME_SEGMENTS;
				case AmaltheaPackage.INAMED___GET_DEFAULT_NAME_SEPARATOR: return AmaltheaPackage.REFERABLE_BASE_OBJECT___GET_DEFAULT_NAME_SEPARATOR;
				case AmaltheaPackage.INAMED___GET_NAMESPACE: return AmaltheaPackage.REFERABLE_BASE_OBJECT___GET_NAMESPACE;
				case AmaltheaPackage.INAMED___GET_NAME_PREFIX_SEGMENTS: return AmaltheaPackage.REFERABLE_BASE_OBJECT___GET_NAME_PREFIX_SEGMENTS;
				default: return -1;
			}
		}
		if (baseClass == IReferable.class) {
			switch (baseOperationID) {
				case AmaltheaPackage.IREFERABLE___GET_ENCODED_QUALIFIED_NAME: return AmaltheaPackage.REFERABLE_BASE_OBJECT___GET_ENCODED_QUALIFIED_NAME;
				case AmaltheaPackage.IREFERABLE___VALIDATE_INVARIANTS__DIAGNOSTICCHAIN_MAP: return AmaltheaPackage.REFERABLE_BASE_OBJECT___VALIDATE_INVARIANTS__DIAGNOSTICCHAIN_MAP;
				default: return -1;
			}
		}
		return super.eDerivedOperationID(baseOperationID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	@SuppressWarnings("unchecked")
	public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException {
		switch (operationID) {
			case AmaltheaPackage.REFERABLE_BASE_OBJECT___GET_ENCODED_QUALIFIED_NAME:
				return getEncodedQualifiedName();
			case AmaltheaPackage.REFERABLE_BASE_OBJECT___VALIDATE_INVARIANTS__DIAGNOSTICCHAIN_MAP:
				return validateInvariants((DiagnosticChain)arguments.get(0), (Map<Object, Object>)arguments.get(1));
			case AmaltheaPackage.REFERABLE_BASE_OBJECT___GET_NAMED_CONTAINER:
				return getNamedContainer();
			case AmaltheaPackage.REFERABLE_BASE_OBJECT___GET_NAME_PREFIX:
				return getNamePrefix();
			case AmaltheaPackage.REFERABLE_BASE_OBJECT___GET_QUALIFIED_NAME_SEGMENTS:
				return getQualifiedNameSegments();
			case AmaltheaPackage.REFERABLE_BASE_OBJECT___GET_DEFAULT_NAME_SEPARATOR:
				return getDefaultNameSeparator();
			case AmaltheaPackage.REFERABLE_BASE_OBJECT___GET_NAMESPACE:
				return getNamespace();
			case AmaltheaPackage.REFERABLE_BASE_OBJECT___GET_NAME_PREFIX_SEGMENTS:
				return getNamePrefixSegments();
		}
		return super.eInvoke(operationID, arguments);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuilder result = new StringBuilder(super.toString());
		result.append(" (name: ");
		result.append(name);
		result.append(')');
		return result.toString();
	}

} //ReferableBaseObjectImpl
