/**
 */
package io.shell.admin.aas.abac._2._0.impl;

import io.shell.admin.aas._2._0.BlobT;

import io.shell.admin.aas.abac._2._0.BlobCertificateT;
import io.shell.admin.aas.abac._2._0.ContainedExtensionsT;
import io.shell.admin.aas.abac._2._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;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Blob Certificate T</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link io.shell.admin.aas.abac._2._0.impl.BlobCertificateTImpl#getBlobCertificate <em>Blob Certificate</em>}</li>
 *   <li>{@link io.shell.admin.aas.abac._2._0.impl.BlobCertificateTImpl#getContainedExtensions <em>Contained Extensions</em>}</li>
 *   <li>{@link io.shell.admin.aas.abac._2._0.impl.BlobCertificateTImpl#isLastCertificate <em>Last Certificate</em>}</li>
 * </ul>
 *
 * @generated
 */
public class BlobCertificateTImpl extends CertificateAbstractTImpl implements BlobCertificateT {
	/**
	 * The cached value of the '{@link #getBlobCertificate() <em>Blob Certificate</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getBlobCertificate()
	 * @generated
	 * @ordered
	 */
	protected BlobT blobCertificate;

	/**
	 * The cached value of the '{@link #getContainedExtensions() <em>Contained Extensions</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getContainedExtensions()
	 * @generated
	 * @ordered
	 */
	protected ContainedExtensionsT containedExtensions;

	/**
	 * The default value of the '{@link #isLastCertificate() <em>Last Certificate</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isLastCertificate()
	 * @generated
	 * @ordered
	 */
	protected static final boolean LAST_CERTIFICATE_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isLastCertificate() <em>Last Certificate</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isLastCertificate()
	 * @generated
	 * @ordered
	 */
	protected boolean lastCertificate = LAST_CERTIFICATE_EDEFAULT;

	/**
	 * This is true if the Last Certificate attribute has been set.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 * @ordered
	 */
	protected boolean lastCertificateESet;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public BlobT getBlobCertificate() {
		return blobCertificate;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetBlobCertificate(BlobT newBlobCertificate, NotificationChain msgs) {
		BlobT oldBlobCertificate = blobCertificate;
		blobCertificate = newBlobCertificate;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, _0Package.BLOB_CERTIFICATE_T__BLOB_CERTIFICATE, oldBlobCertificate, newBlobCertificate);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setBlobCertificate(BlobT newBlobCertificate) {
		if (newBlobCertificate != blobCertificate) {
			NotificationChain msgs = null;
			if (blobCertificate != null)
				msgs = ((InternalEObject)blobCertificate).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - _0Package.BLOB_CERTIFICATE_T__BLOB_CERTIFICATE, null, msgs);
			if (newBlobCertificate != null)
				msgs = ((InternalEObject)newBlobCertificate).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - _0Package.BLOB_CERTIFICATE_T__BLOB_CERTIFICATE, null, msgs);
			msgs = basicSetBlobCertificate(newBlobCertificate, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.BLOB_CERTIFICATE_T__BLOB_CERTIFICATE, newBlobCertificate, newBlobCertificate));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ContainedExtensionsT getContainedExtensions() {
		return containedExtensions;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetContainedExtensions(ContainedExtensionsT newContainedExtensions, NotificationChain msgs) {
		ContainedExtensionsT oldContainedExtensions = containedExtensions;
		containedExtensions = newContainedExtensions;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, _0Package.BLOB_CERTIFICATE_T__CONTAINED_EXTENSIONS, oldContainedExtensions, newContainedExtensions);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setContainedExtensions(ContainedExtensionsT newContainedExtensions) {
		if (newContainedExtensions != containedExtensions) {
			NotificationChain msgs = null;
			if (containedExtensions != null)
				msgs = ((InternalEObject)containedExtensions).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - _0Package.BLOB_CERTIFICATE_T__CONTAINED_EXTENSIONS, null, msgs);
			if (newContainedExtensions != null)
				msgs = ((InternalEObject)newContainedExtensions).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - _0Package.BLOB_CERTIFICATE_T__CONTAINED_EXTENSIONS, null, msgs);
			msgs = basicSetContainedExtensions(newContainedExtensions, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.BLOB_CERTIFICATE_T__CONTAINED_EXTENSIONS, newContainedExtensions, newContainedExtensions));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isLastCertificate() {
		return lastCertificate;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setLastCertificate(boolean newLastCertificate) {
		boolean oldLastCertificate = lastCertificate;
		lastCertificate = newLastCertificate;
		boolean oldLastCertificateESet = lastCertificateESet;
		lastCertificateESet = true;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.BLOB_CERTIFICATE_T__LAST_CERTIFICATE, oldLastCertificate, lastCertificate, !oldLastCertificateESet));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void unsetLastCertificate() {
		boolean oldLastCertificate = lastCertificate;
		boolean oldLastCertificateESet = lastCertificateESet;
		lastCertificate = LAST_CERTIFICATE_EDEFAULT;
		lastCertificateESet = false;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.UNSET, _0Package.BLOB_CERTIFICATE_T__LAST_CERTIFICATE, oldLastCertificate, LAST_CERTIFICATE_EDEFAULT, oldLastCertificateESet));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isSetLastCertificate() {
		return lastCertificateESet;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case _0Package.BLOB_CERTIFICATE_T__BLOB_CERTIFICATE:
				return basicSetBlobCertificate(null, msgs);
			case _0Package.BLOB_CERTIFICATE_T__CONTAINED_EXTENSIONS:
				return basicSetContainedExtensions(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.BLOB_CERTIFICATE_T__BLOB_CERTIFICATE:
				return getBlobCertificate();
			case _0Package.BLOB_CERTIFICATE_T__CONTAINED_EXTENSIONS:
				return getContainedExtensions();
			case _0Package.BLOB_CERTIFICATE_T__LAST_CERTIFICATE:
				return isLastCertificate();
		}
		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.BLOB_CERTIFICATE_T__BLOB_CERTIFICATE:
				setBlobCertificate((BlobT)newValue);
				return;
			case _0Package.BLOB_CERTIFICATE_T__CONTAINED_EXTENSIONS:
				setContainedExtensions((ContainedExtensionsT)newValue);
				return;
			case _0Package.BLOB_CERTIFICATE_T__LAST_CERTIFICATE:
				setLastCertificate((Boolean)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case _0Package.BLOB_CERTIFICATE_T__BLOB_CERTIFICATE:
				setBlobCertificate((BlobT)null);
				return;
			case _0Package.BLOB_CERTIFICATE_T__CONTAINED_EXTENSIONS:
				setContainedExtensions((ContainedExtensionsT)null);
				return;
			case _0Package.BLOB_CERTIFICATE_T__LAST_CERTIFICATE:
				unsetLastCertificate();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case _0Package.BLOB_CERTIFICATE_T__BLOB_CERTIFICATE:
				return blobCertificate != null;
			case _0Package.BLOB_CERTIFICATE_T__CONTAINED_EXTENSIONS:
				return containedExtensions != null;
			case _0Package.BLOB_CERTIFICATE_T__LAST_CERTIFICATE:
				return isSetLastCertificate();
		}
		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(" (lastCertificate: ");
		if (lastCertificateESet) result.append(lastCertificate); else result.append("<unset>");
		result.append(')');
		return result.toString();
	}

} //BlobCertificateTImpl
