/**
 * ****************************************************************************
 *   Copyright (c) 2020 CEA LIST.
 *  
 *  
 *   All rights reserved. This program and the accompanying materials
 *   are made available under the terms of the Eclipse Public License 2.0
 *   which accompanies this distribution, and is available at
 *   https://www.eclipse.org/legal/epl-2.0/
 *  
 *   SPDX-License-Identifier: EPL-2.0
 *  
 *   Contributors:
 *    Asma Smaoui (CEA LIST) asma.smaoui@cea.fr - Initial API and implementation
 *  
 *  ****************************************************************************
 */
package io.shell.admin.aas._1._0.impl;

import io.shell.admin.aas._1._0.QualifierT;
import io.shell.admin.aas._1._0.ReferenceT;
import io.shell.admin.aas._1._0.SemanticIdT;
import io.shell.admin.aas._1._0._0Package;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;

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

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

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Qualifier T</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link io.shell.admin.aas._1._0.impl.QualifierTImpl#getSemanticId <em>Semantic Id</em>}</li>
 *   <li>{@link io.shell.admin.aas._1._0.impl.QualifierTImpl#getQualifierType <em>Qualifier Type</em>}</li>
 *   <li>{@link io.shell.admin.aas._1._0.impl.QualifierTImpl#getQualifierValue <em>Qualifier Value</em>}</li>
 *   <li>{@link io.shell.admin.aas._1._0.impl.QualifierTImpl#getQualifierValueId <em>Qualifier Value Id</em>}</li>
 * </ul>
 *
 * @generated
 */
public class QualifierTImpl extends MinimalEObjectImpl.Container implements QualifierT {
	/**
	 * The cached value of the '{@link #getSemanticId() <em>Semantic Id</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSemanticId()
	 * @generated
	 * @ordered
	 */
	protected SemanticIdT semanticId;

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

	/**
	 * The cached value of the '{@link #getQualifierType() <em>Qualifier Type</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getQualifierType()
	 * @generated
	 * @ordered
	 */
	protected String qualifierType = QUALIFIER_TYPE_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getQualifierValue() <em>Qualifier Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getQualifierValue()
	 * @generated
	 * @ordered
	 */
	protected String qualifierValue = QUALIFIER_VALUE_EDEFAULT;

	/**
	 * The cached value of the '{@link #getQualifierValueId() <em>Qualifier Value Id</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getQualifierValueId()
	 * @generated
	 * @ordered
	 */
	protected ReferenceT qualifierValueId;

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return _0Package.Literals.QUALIFIER_T;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public SemanticIdT getSemanticId() {
		return semanticId;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetSemanticId(SemanticIdT newSemanticId, NotificationChain msgs) {
		SemanticIdT oldSemanticId = semanticId;
		semanticId = newSemanticId;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, _0Package.QUALIFIER_T__SEMANTIC_ID, oldSemanticId, newSemanticId);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setSemanticId(SemanticIdT newSemanticId) {
		if (newSemanticId != semanticId) {
			NotificationChain msgs = null;
			if (semanticId != null)
				msgs = ((InternalEObject)semanticId).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - _0Package.QUALIFIER_T__SEMANTIC_ID, null, msgs);
			if (newSemanticId != null)
				msgs = ((InternalEObject)newSemanticId).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - _0Package.QUALIFIER_T__SEMANTIC_ID, null, msgs);
			msgs = basicSetSemanticId(newSemanticId, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.QUALIFIER_T__SEMANTIC_ID, newSemanticId, newSemanticId));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setQualifierType(String newQualifierType) {
		String oldQualifierType = qualifierType;
		qualifierType = newQualifierType;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.QUALIFIER_T__QUALIFIER_TYPE, oldQualifierType, qualifierType));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setQualifierValue(String newQualifierValue) {
		String oldQualifierValue = qualifierValue;
		qualifierValue = newQualifierValue;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.QUALIFIER_T__QUALIFIER_VALUE, oldQualifierValue, qualifierValue));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ReferenceT getQualifierValueId() {
		return qualifierValueId;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetQualifierValueId(ReferenceT newQualifierValueId, NotificationChain msgs) {
		ReferenceT oldQualifierValueId = qualifierValueId;
		qualifierValueId = newQualifierValueId;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, _0Package.QUALIFIER_T__QUALIFIER_VALUE_ID, oldQualifierValueId, newQualifierValueId);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setQualifierValueId(ReferenceT newQualifierValueId) {
		if (newQualifierValueId != qualifierValueId) {
			NotificationChain msgs = null;
			if (qualifierValueId != null)
				msgs = ((InternalEObject)qualifierValueId).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - _0Package.QUALIFIER_T__QUALIFIER_VALUE_ID, null, msgs);
			if (newQualifierValueId != null)
				msgs = ((InternalEObject)newQualifierValueId).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - _0Package.QUALIFIER_T__QUALIFIER_VALUE_ID, null, msgs);
			msgs = basicSetQualifierValueId(newQualifierValueId, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.QUALIFIER_T__QUALIFIER_VALUE_ID, newQualifierValueId, newQualifierValueId));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case _0Package.QUALIFIER_T__SEMANTIC_ID:
				return basicSetSemanticId(null, msgs);
			case _0Package.QUALIFIER_T__QUALIFIER_VALUE_ID:
				return basicSetQualifierValueId(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 _0Package.QUALIFIER_T__SEMANTIC_ID:
				return getSemanticId();
			case _0Package.QUALIFIER_T__QUALIFIER_TYPE:
				return getQualifierType();
			case _0Package.QUALIFIER_T__QUALIFIER_VALUE:
				return getQualifierValue();
			case _0Package.QUALIFIER_T__QUALIFIER_VALUE_ID:
				return getQualifierValueId();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case _0Package.QUALIFIER_T__SEMANTIC_ID:
				setSemanticId((SemanticIdT)newValue);
				return;
			case _0Package.QUALIFIER_T__QUALIFIER_TYPE:
				setQualifierType((String)newValue);
				return;
			case _0Package.QUALIFIER_T__QUALIFIER_VALUE:
				setQualifierValue((String)newValue);
				return;
			case _0Package.QUALIFIER_T__QUALIFIER_VALUE_ID:
				setQualifierValueId((ReferenceT)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case _0Package.QUALIFIER_T__SEMANTIC_ID:
				setSemanticId((SemanticIdT)null);
				return;
			case _0Package.QUALIFIER_T__QUALIFIER_TYPE:
				setQualifierType(QUALIFIER_TYPE_EDEFAULT);
				return;
			case _0Package.QUALIFIER_T__QUALIFIER_VALUE:
				setQualifierValue(QUALIFIER_VALUE_EDEFAULT);
				return;
			case _0Package.QUALIFIER_T__QUALIFIER_VALUE_ID:
				setQualifierValueId((ReferenceT)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case _0Package.QUALIFIER_T__SEMANTIC_ID:
				return semanticId != null;
			case _0Package.QUALIFIER_T__QUALIFIER_TYPE:
				return QUALIFIER_TYPE_EDEFAULT == null ? qualifierType != null : !QUALIFIER_TYPE_EDEFAULT.equals(qualifierType);
			case _0Package.QUALIFIER_T__QUALIFIER_VALUE:
				return QUALIFIER_VALUE_EDEFAULT == null ? qualifierValue != null : !QUALIFIER_VALUE_EDEFAULT.equals(qualifierValue);
			case _0Package.QUALIFIER_T__QUALIFIER_VALUE_ID:
				return qualifierValueId != null;
		}
		return super.eIsSet(featureID);
	}

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

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

} //QualifierTImpl
