/**
 * *******************************************************************************
 *  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.SemaphoreAccessType;
import org.eclipse.app4mc.amalthea.generator.configuration.SemaphoreRequestOrder;

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 Access Properties</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.SemaphoreAccessPropertiesImpl#getPerUnitReadAccessCount <em>Per Unit Read Access Count</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.SemaphoreAccessPropertiesImpl#getPerUnitWriteAccessCount <em>Per Unit Write Access Count</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.SemaphoreAccessPropertiesImpl#getRequestOrder <em>Request Order</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.SemaphoreAccessPropertiesImpl#getAccessType <em>Access Type</em>}</li>
 * </ul>
 *
 * @generated
 */
public class SemaphoreAccessPropertiesImpl extends MinimalEObjectImpl.Container implements SemaphoreAccessProperties {
	/**
	 * The cached value of the '{@link #getPerUnitReadAccessCount() <em>Per Unit Read Access Count</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getPerUnitReadAccessCount()
	 * @generated
	 * @ordered
	 */
	protected IntegerDistribution perUnitReadAccessCount;

	/**
	 * The cached value of the '{@link #getPerUnitWriteAccessCount() <em>Per Unit Write Access Count</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getPerUnitWriteAccessCount()
	 * @generated
	 * @ordered
	 */
	protected IntegerDistribution perUnitWriteAccessCount;

	/**
	 * The default value of the '{@link #getRequestOrder() <em>Request Order</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getRequestOrder()
	 * @generated
	 * @ordered
	 */
	protected static final SemaphoreRequestOrder REQUEST_ORDER_EDEFAULT = SemaphoreRequestOrder.NONE;

	/**
	 * The cached value of the '{@link #getRequestOrder() <em>Request Order</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getRequestOrder()
	 * @generated
	 * @ordered
	 */
	protected SemaphoreRequestOrder requestOrder = REQUEST_ORDER_EDEFAULT;

	/**
	 * The default value of the '{@link #getAccessType() <em>Access Type</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAccessType()
	 * @generated
	 * @ordered
	 */
	protected static final SemaphoreAccessType ACCESS_TYPE_EDEFAULT = SemaphoreAccessType.RAND_RUNNABLE;

	/**
	 * The cached value of the '{@link #getAccessType() <em>Access Type</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAccessType()
	 * @generated
	 * @ordered
	 */
	protected SemaphoreAccessType accessType = ACCESS_TYPE_EDEFAULT;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetPerUnitReadAccessCount(IntegerDistribution newPerUnitReadAccessCount, NotificationChain msgs) {
		IntegerDistribution oldPerUnitReadAccessCount = perUnitReadAccessCount;
		perUnitReadAccessCount = newPerUnitReadAccessCount;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__PER_UNIT_READ_ACCESS_COUNT, oldPerUnitReadAccessCount, newPerUnitReadAccessCount);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetPerUnitWriteAccessCount(IntegerDistribution newPerUnitWriteAccessCount, NotificationChain msgs) {
		IntegerDistribution oldPerUnitWriteAccessCount = perUnitWriteAccessCount;
		perUnitWriteAccessCount = newPerUnitWriteAccessCount;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__PER_UNIT_WRITE_ACCESS_COUNT, oldPerUnitWriteAccessCount, newPerUnitWriteAccessCount);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public SemaphoreRequestOrder getRequestOrder() {
		return requestOrder;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setRequestOrder(SemaphoreRequestOrder newRequestOrder) {
		SemaphoreRequestOrder oldRequestOrder = requestOrder;
		requestOrder = newRequestOrder == null ? REQUEST_ORDER_EDEFAULT : newRequestOrder;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__REQUEST_ORDER, oldRequestOrder, requestOrder));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public SemaphoreAccessType getAccessType() {
		return accessType;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setAccessType(SemaphoreAccessType newAccessType) {
		SemaphoreAccessType oldAccessType = accessType;
		accessType = newAccessType == null ? ACCESS_TYPE_EDEFAULT : newAccessType;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__ACCESS_TYPE, oldAccessType, accessType));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__PER_UNIT_READ_ACCESS_COUNT:
				return basicSetPerUnitReadAccessCount(null, msgs);
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__PER_UNIT_WRITE_ACCESS_COUNT:
				return basicSetPerUnitWriteAccessCount(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_ACCESS_PROPERTIES__PER_UNIT_READ_ACCESS_COUNT:
				return getPerUnitReadAccessCount();
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__PER_UNIT_WRITE_ACCESS_COUNT:
				return getPerUnitWriteAccessCount();
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__REQUEST_ORDER:
				return getRequestOrder();
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__ACCESS_TYPE:
				return getAccessType();
		}
		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_ACCESS_PROPERTIES__PER_UNIT_READ_ACCESS_COUNT:
				setPerUnitReadAccessCount((IntegerDistribution)newValue);
				return;
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__PER_UNIT_WRITE_ACCESS_COUNT:
				setPerUnitWriteAccessCount((IntegerDistribution)newValue);
				return;
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__REQUEST_ORDER:
				setRequestOrder((SemaphoreRequestOrder)newValue);
				return;
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__ACCESS_TYPE:
				setAccessType((SemaphoreAccessType)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__PER_UNIT_READ_ACCESS_COUNT:
				setPerUnitReadAccessCount((IntegerDistribution)null);
				return;
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__PER_UNIT_WRITE_ACCESS_COUNT:
				setPerUnitWriteAccessCount((IntegerDistribution)null);
				return;
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__REQUEST_ORDER:
				setRequestOrder(REQUEST_ORDER_EDEFAULT);
				return;
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__ACCESS_TYPE:
				setAccessType(ACCESS_TYPE_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__PER_UNIT_READ_ACCESS_COUNT:
				return perUnitReadAccessCount != null;
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__PER_UNIT_WRITE_ACCESS_COUNT:
				return perUnitWriteAccessCount != null;
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__REQUEST_ORDER:
				return requestOrder != REQUEST_ORDER_EDEFAULT;
			case RTMGCPackage.SEMAPHORE_ACCESS_PROPERTIES__ACCESS_TYPE:
				return accessType != ACCESS_TYPE_EDEFAULT;
		}
		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(" (requestOrder: ");
		result.append(requestOrder);
		result.append(", accessType: ");
		result.append(accessType);
		result.append(')');
		return result.toString();
	}

} //SemaphoreAccessPropertiesImpl
