/**
 * *******************************************************************************
 *  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.Collection;
import org.eclipse.app4mc.amalthea.model.AmaltheaExtensions;
import org.eclipse.app4mc.amalthea.model.AmaltheaPackage;
import org.eclipse.app4mc.amalthea.model.DataType;
import org.eclipse.app4mc.amalthea.model.INamed;
import org.eclipse.app4mc.amalthea.model.ITaggable;
import org.eclipse.app4mc.amalthea.model.Namespace;
import org.eclipse.app4mc.amalthea.model.StructEntry;
import org.eclipse.app4mc.amalthea.model.Tag;

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.EList;

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

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

import org.eclipse.emf.ecore.util.EObjectResolvingEList;
import org.eclipse.emf.ecore.xcore.lib.XcoreCollectionLiterals;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Struct Entry</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.StructEntryImpl#getName <em>Name</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.StructEntryImpl#getQualifiedName <em>Qualified Name</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.StructEntryImpl#getTags <em>Tags</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.StructEntryImpl#getDataType <em>Data Type</em>}</li>
 * </ul>
 *
 * @generated
 */
public class StructEntryImpl extends BaseObjectImpl implements StructEntry {
	/**
	 * 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 cached value of the '{@link #getTags() <em>Tags</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTags()
	 * @generated
	 * @ordered
	 */
	protected EList<Tag> tags;

	/**
	 * The cached value of the '{@link #getDataType() <em>Data Type</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDataType()
	 * @generated
	 * @ordered
	 */
	protected DataType dataType;

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

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

	/**
	 * <!-- 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.STRUCT_ENTRY__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 EList<Tag> getTags() {
		if (tags == null) {
			tags = new EObjectResolvingEList<Tag>(Tag.class, this, AmaltheaPackage.STRUCT_ENTRY__TAGS);
		}
		return tags;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public DataType getDataType() {
		return dataType;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetDataType(DataType newDataType, NotificationChain msgs) {
		DataType oldDataType = dataType;
		dataType = newDataType;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, AmaltheaPackage.STRUCT_ENTRY__DATA_TYPE, oldDataType, newDataType);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setDataType(DataType newDataType) {
		if (newDataType != dataType) {
			NotificationChain msgs = null;
			if (dataType != null)
				msgs = ((InternalEObject)dataType).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - AmaltheaPackage.STRUCT_ENTRY__DATA_TYPE, null, msgs);
			if (newDataType != null)
				msgs = ((InternalEObject)newDataType).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - AmaltheaPackage.STRUCT_ENTRY__DATA_TYPE, null, msgs);
			msgs = basicSetDataType(newDataType, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AmaltheaPackage.STRUCT_ENTRY__DATA_TYPE, newDataType, newDataType));
	}

	/**
	 * <!-- 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.STRUCT_ENTRY__DATA_TYPE:
				return basicSetDataType(null, 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.STRUCT_ENTRY__NAME:
				return getName();
			case AmaltheaPackage.STRUCT_ENTRY__QUALIFIED_NAME:
				return getQualifiedName();
			case AmaltheaPackage.STRUCT_ENTRY__TAGS:
				return getTags();
			case AmaltheaPackage.STRUCT_ENTRY__DATA_TYPE:
				return getDataType();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case AmaltheaPackage.STRUCT_ENTRY__NAME:
				setName((String)newValue);
				return;
			case AmaltheaPackage.STRUCT_ENTRY__TAGS:
				getTags().clear();
				getTags().addAll((Collection<? extends Tag>)newValue);
				return;
			case AmaltheaPackage.STRUCT_ENTRY__DATA_TYPE:
				setDataType((DataType)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case AmaltheaPackage.STRUCT_ENTRY__NAME:
				setName(NAME_EDEFAULT);
				return;
			case AmaltheaPackage.STRUCT_ENTRY__TAGS:
				getTags().clear();
				return;
			case AmaltheaPackage.STRUCT_ENTRY__DATA_TYPE:
				setDataType((DataType)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case AmaltheaPackage.STRUCT_ENTRY__NAME:
				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
			case AmaltheaPackage.STRUCT_ENTRY__QUALIFIED_NAME:
				return QUALIFIED_NAME_EDEFAULT == null ? getQualifiedName() != null : !QUALIFIED_NAME_EDEFAULT.equals(getQualifiedName());
			case AmaltheaPackage.STRUCT_ENTRY__TAGS:
				return tags != null && !tags.isEmpty();
			case AmaltheaPackage.STRUCT_ENTRY__DATA_TYPE:
				return dataType != null;
		}
		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.STRUCT_ENTRY__NAME: return AmaltheaPackage.INAMED__NAME;
				case AmaltheaPackage.STRUCT_ENTRY__QUALIFIED_NAME: return AmaltheaPackage.INAMED__QUALIFIED_NAME;
				default: return -1;
			}
		}
		if (baseClass == ITaggable.class) {
			switch (derivedFeatureID) {
				case AmaltheaPackage.STRUCT_ENTRY__TAGS: return AmaltheaPackage.ITAGGABLE__TAGS;
				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.STRUCT_ENTRY__NAME;
				case AmaltheaPackage.INAMED__QUALIFIED_NAME: return AmaltheaPackage.STRUCT_ENTRY__QUALIFIED_NAME;
				default: return -1;
			}
		}
		if (baseClass == ITaggable.class) {
			switch (baseFeatureID) {
				case AmaltheaPackage.ITAGGABLE__TAGS: return AmaltheaPackage.STRUCT_ENTRY__TAGS;
				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.STRUCT_ENTRY___GET_NAMED_CONTAINER;
				case AmaltheaPackage.INAMED___GET_NAME_PREFIX: return AmaltheaPackage.STRUCT_ENTRY___GET_NAME_PREFIX;
				case AmaltheaPackage.INAMED___GET_QUALIFIED_NAME_SEGMENTS: return AmaltheaPackage.STRUCT_ENTRY___GET_QUALIFIED_NAME_SEGMENTS;
				case AmaltheaPackage.INAMED___GET_DEFAULT_NAME_SEPARATOR: return AmaltheaPackage.STRUCT_ENTRY___GET_DEFAULT_NAME_SEPARATOR;
				case AmaltheaPackage.INAMED___GET_NAMESPACE: return AmaltheaPackage.STRUCT_ENTRY___GET_NAMESPACE;
				case AmaltheaPackage.INAMED___GET_NAME_PREFIX_SEGMENTS: return AmaltheaPackage.STRUCT_ENTRY___GET_NAME_PREFIX_SEGMENTS;
				default: return -1;
			}
		}
		if (baseClass == ITaggable.class) {
			switch (baseOperationID) {
				default: return -1;
			}
		}
		return super.eDerivedOperationID(baseOperationID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException {
		switch (operationID) {
			case AmaltheaPackage.STRUCT_ENTRY___GET_NAMED_CONTAINER:
				return getNamedContainer();
			case AmaltheaPackage.STRUCT_ENTRY___GET_NAME_PREFIX:
				return getNamePrefix();
			case AmaltheaPackage.STRUCT_ENTRY___GET_QUALIFIED_NAME_SEGMENTS:
				return getQualifiedNameSegments();
			case AmaltheaPackage.STRUCT_ENTRY___GET_DEFAULT_NAME_SEPARATOR:
				return getDefaultNameSeparator();
			case AmaltheaPackage.STRUCT_ENTRY___GET_NAMESPACE:
				return getNamespace();
			case AmaltheaPackage.STRUCT_ENTRY___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();
	}

} //StructEntryImpl
