/**
 * *******************************************************************************
 *  Copyright (c) 2017 Timing-Architects Embedded Systems GmbH and others.
 *  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
 * 
 *     Generated using Eclipse EMF
 * 
 * *******************************************************************************
 */
package org.eclipse.app4mc.amalthea.generator.configuration.impl;

import org.eclipse.app4mc.amalthea.generator.configuration.IntegerDistribution;
import org.eclipse.app4mc.amalthea.generator.configuration.RTMGCPackage;
import org.eclipse.app4mc.amalthea.generator.configuration.SemaphoreAccessProperties;
import org.eclipse.app4mc.amalthea.generator.configuration.SemaphoreProperties;
import org.eclipse.app4mc.amalthea.generator.configuration.SemaphoreType;
import org.eclipse.app4mc.amalthea.generator.configuration.WaitModes;

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>Semaphore Properties</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.SemaphorePropertiesImpl#getCount <em>Count</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.SemaphorePropertiesImpl#isPriorityCeilingProtocol <em>Priority Ceiling Protocol</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.SemaphorePropertiesImpl#getSemaphoreType <em>Semaphore Type</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.SemaphorePropertiesImpl#getWaitMode <em>Wait Mode</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.SemaphorePropertiesImpl#getSemaphoreAccess <em>Semaphore Access</em>}</li>
 * </ul>
 *
 * @generated
 */
public class SemaphorePropertiesImpl extends MinimalEObjectImpl.Container implements SemaphoreProperties {
	/**
	 * The cached value of the '{@link #getCount() <em>Count</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCount()
	 * @generated
	 * @ordered
	 */
	protected IntegerDistribution count;

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

	/**
	 * The cached value of the '{@link #isPriorityCeilingProtocol() <em>Priority Ceiling Protocol</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isPriorityCeilingProtocol()
	 * @generated
	 * @ordered
	 */
	protected boolean priorityCeilingProtocol = PRIORITY_CEILING_PROTOCOL_EDEFAULT;

	/**
	 * The default value of the '{@link #getSemaphoreType() <em>Semaphore Type</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSemaphoreType()
	 * @generated
	 * @ordered
	 */
	protected static final SemaphoreType SEMAPHORE_TYPE_EDEFAULT = SemaphoreType.COUNTING;

	/**
	 * The cached value of the '{@link #getSemaphoreType() <em>Semaphore Type</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSemaphoreType()
	 * @generated
	 * @ordered
	 */
	protected SemaphoreType semaphoreType = SEMAPHORE_TYPE_EDEFAULT;

	/**
	 * The default value of the '{@link #getWaitMode() <em>Wait Mode</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getWaitMode()
	 * @generated
	 * @ordered
	 */
	protected static final WaitModes WAIT_MODE_EDEFAULT = WaitModes.POLLING;

	/**
	 * The cached value of the '{@link #getWaitMode() <em>Wait Mode</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getWaitMode()
	 * @generated
	 * @ordered
	 */
	protected WaitModes waitMode = WAIT_MODE_EDEFAULT;

	/**
	 * The cached value of the '{@link #getSemaphoreAccess() <em>Semaphore Access</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSemaphoreAccess()
	 * @generated
	 * @ordered
	 */
	protected SemaphoreAccessProperties semaphoreAccess;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IntegerDistribution getCount() {
		return count;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetCount(IntegerDistribution newCount, NotificationChain msgs) {
		IntegerDistribution oldCount = count;
		count = newCount;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, RTMGCPackage.SEMAPHORE_PROPERTIES__COUNT, oldCount, newCount);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setCount(IntegerDistribution newCount) {
		if (newCount != count) {
			NotificationChain msgs = null;
			if (count != null)
				msgs = ((InternalEObject)count).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.SEMAPHORE_PROPERTIES__COUNT, null, msgs);
			if (newCount != null)
				msgs = ((InternalEObject)newCount).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.SEMAPHORE_PROPERTIES__COUNT, null, msgs);
			msgs = basicSetCount(newCount, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.SEMAPHORE_PROPERTIES__COUNT, newCount, newCount));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setPriorityCeilingProtocol(boolean newPriorityCeilingProtocol) {
		boolean oldPriorityCeilingProtocol = priorityCeilingProtocol;
		priorityCeilingProtocol = newPriorityCeilingProtocol;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.SEMAPHORE_PROPERTIES__PRIORITY_CEILING_PROTOCOL, oldPriorityCeilingProtocol, priorityCeilingProtocol));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public SemaphoreType getSemaphoreType() {
		return semaphoreType;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setSemaphoreType(SemaphoreType newSemaphoreType) {
		SemaphoreType oldSemaphoreType = semaphoreType;
		semaphoreType = newSemaphoreType == null ? SEMAPHORE_TYPE_EDEFAULT : newSemaphoreType;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.SEMAPHORE_PROPERTIES__SEMAPHORE_TYPE, oldSemaphoreType, semaphoreType));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public WaitModes getWaitMode() {
		return waitMode;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setWaitMode(WaitModes newWaitMode) {
		WaitModes oldWaitMode = waitMode;
		waitMode = newWaitMode == null ? WAIT_MODE_EDEFAULT : newWaitMode;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.SEMAPHORE_PROPERTIES__WAIT_MODE, oldWaitMode, waitMode));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public SemaphoreAccessProperties getSemaphoreAccess() {
		return semaphoreAccess;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetSemaphoreAccess(SemaphoreAccessProperties newSemaphoreAccess, NotificationChain msgs) {
		SemaphoreAccessProperties oldSemaphoreAccess = semaphoreAccess;
		semaphoreAccess = newSemaphoreAccess;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, RTMGCPackage.SEMAPHORE_PROPERTIES__SEMAPHORE_ACCESS, oldSemaphoreAccess, newSemaphoreAccess);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setSemaphoreAccess(SemaphoreAccessProperties newSemaphoreAccess) {
		if (newSemaphoreAccess != semaphoreAccess) {
			NotificationChain msgs = null;
			if (semaphoreAccess != null)
				msgs = ((InternalEObject)semaphoreAccess).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.SEMAPHORE_PROPERTIES__SEMAPHORE_ACCESS, null, msgs);
			if (newSemaphoreAccess != null)
				msgs = ((InternalEObject)newSemaphoreAccess).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.SEMAPHORE_PROPERTIES__SEMAPHORE_ACCESS, null, msgs);
			msgs = basicSetSemaphoreAccess(newSemaphoreAccess, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.SEMAPHORE_PROPERTIES__SEMAPHORE_ACCESS, newSemaphoreAccess, newSemaphoreAccess));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case RTMGCPackage.SEMAPHORE_PROPERTIES__COUNT:
				return basicSetCount(null, msgs);
			case RTMGCPackage.SEMAPHORE_PROPERTIES__SEMAPHORE_ACCESS:
				return basicSetSemaphoreAccess(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 RTMGCPackage.SEMAPHORE_PROPERTIES__COUNT:
				return getCount();
			case RTMGCPackage.SEMAPHORE_PROPERTIES__PRIORITY_CEILING_PROTOCOL:
				return isPriorityCeilingProtocol();
			case RTMGCPackage.SEMAPHORE_PROPERTIES__SEMAPHORE_TYPE:
				return getSemaphoreType();
			case RTMGCPackage.SEMAPHORE_PROPERTIES__WAIT_MODE:
				return getWaitMode();
			case RTMGCPackage.SEMAPHORE_PROPERTIES__SEMAPHORE_ACCESS:
				return getSemaphoreAccess();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case RTMGCPackage.SEMAPHORE_PROPERTIES__COUNT:
				setCount((IntegerDistribution)newValue);
				return;
			case RTMGCPackage.SEMAPHORE_PROPERTIES__PRIORITY_CEILING_PROTOCOL:
				setPriorityCeilingProtocol((Boolean)newValue);
				return;
			case RTMGCPackage.SEMAPHORE_PROPERTIES__SEMAPHORE_TYPE:
				setSemaphoreType((SemaphoreType)newValue);
				return;
			case RTMGCPackage.SEMAPHORE_PROPERTIES__WAIT_MODE:
				setWaitMode((WaitModes)newValue);
				return;
			case RTMGCPackage.SEMAPHORE_PROPERTIES__SEMAPHORE_ACCESS:
				setSemaphoreAccess((SemaphoreAccessProperties)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case RTMGCPackage.SEMAPHORE_PROPERTIES__COUNT:
				setCount((IntegerDistribution)null);
				return;
			case RTMGCPackage.SEMAPHORE_PROPERTIES__PRIORITY_CEILING_PROTOCOL:
				setPriorityCeilingProtocol(PRIORITY_CEILING_PROTOCOL_EDEFAULT);
				return;
			case RTMGCPackage.SEMAPHORE_PROPERTIES__SEMAPHORE_TYPE:
				setSemaphoreType(SEMAPHORE_TYPE_EDEFAULT);
				return;
			case RTMGCPackage.SEMAPHORE_PROPERTIES__WAIT_MODE:
				setWaitMode(WAIT_MODE_EDEFAULT);
				return;
			case RTMGCPackage.SEMAPHORE_PROPERTIES__SEMAPHORE_ACCESS:
				setSemaphoreAccess((SemaphoreAccessProperties)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case RTMGCPackage.SEMAPHORE_PROPERTIES__COUNT:
				return count != null;
			case RTMGCPackage.SEMAPHORE_PROPERTIES__PRIORITY_CEILING_PROTOCOL:
				return priorityCeilingProtocol != PRIORITY_CEILING_PROTOCOL_EDEFAULT;
			case RTMGCPackage.SEMAPHORE_PROPERTIES__SEMAPHORE_TYPE:
				return semaphoreType != SEMAPHORE_TYPE_EDEFAULT;
			case RTMGCPackage.SEMAPHORE_PROPERTIES__WAIT_MODE:
				return waitMode != WAIT_MODE_EDEFAULT;
			case RTMGCPackage.SEMAPHORE_PROPERTIES__SEMAPHORE_ACCESS:
				return semaphoreAccess != null;
		}
		return super.eIsSet(featureID);
	}

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

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (priorityCeilingProtocol: ");
		result.append(priorityCeilingProtocol);
		result.append(", semaphoreType: ");
		result.append(semaphoreType);
		result.append(", waitMode: ");
		result.append(waitMode);
		result.append(')');
		return result.toString();
	}

} //SemaphorePropertiesImpl
