/**
 * Copyright (c) 2011, 2017 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *  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 
 * 
 *  Based on ideas from Xtext, Xtend, Xcore
 *   
 *  Contributors:  
 *  		Christophe Loetz (Loetz GmbH&Co.KG) - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.statemachine.impl;

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.osbp.xtext.statemachine.StatemachineActionFieldConcatenation;
import org.eclipse.osbp.xtext.statemachine.StatemachineActionPeripheralPTAuthorization;
import org.eclipse.osbp.xtext.statemachine.StatemachineDSLPackage;
import org.eclipse.osbp.xtext.statemachine.StatemachinePeripheralDevicePT;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Statemachine Action Peripheral PT Authorization</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.statemachine.impl.StatemachineActionPeripheralPTAuthorizationImpl#getDevice <em>Device</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.statemachine.impl.StatemachineActionPeripheralPTAuthorizationImpl#getAmount <em>Amount</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class StatemachineActionPeripheralPTAuthorizationImpl extends StatemachineLazyResolverImpl implements StatemachineActionPeripheralPTAuthorization {
	/**
	 * The cached value of the '{@link #getDevice() <em>Device</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDevice()
	 * @generated
	 * @ordered
	 */
	protected StatemachinePeripheralDevicePT device;

	/**
	 * The cached value of the '{@link #getAmount() <em>Amount</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAmount()
	 * @generated
	 * @ordered
	 */
	protected StatemachineActionFieldConcatenation amount;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public StatemachinePeripheralDevicePT getDevice() {
		if (device != null && device.eIsProxy()) {
			InternalEObject oldDevice = (InternalEObject)device;
			device = (StatemachinePeripheralDevicePT)eResolveProxy(oldDevice);
			if (device != oldDevice) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__DEVICE, oldDevice, device));
			}
		}
		return device;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public StatemachinePeripheralDevicePT basicGetDevice() {
		return device;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDevice(StatemachinePeripheralDevicePT newDevice) {
		StatemachinePeripheralDevicePT oldDevice = device;
		device = newDevice;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__DEVICE, oldDevice, device));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public StatemachineActionFieldConcatenation getAmount() {
		return amount;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetAmount(StatemachineActionFieldConcatenation newAmount, NotificationChain msgs) {
		StatemachineActionFieldConcatenation oldAmount = amount;
		amount = newAmount;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__AMOUNT, oldAmount, newAmount);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setAmount(StatemachineActionFieldConcatenation newAmount) {
		if (newAmount != amount) {
			NotificationChain msgs = null;
			if (amount != null)
				msgs = ((InternalEObject)amount).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__AMOUNT, null, msgs);
			if (newAmount != null)
				msgs = ((InternalEObject)newAmount).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__AMOUNT, null, msgs);
			msgs = basicSetAmount(newAmount, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__AMOUNT, newAmount, newAmount));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__AMOUNT:
				return basicSetAmount(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 StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__DEVICE:
				if (resolve) return getDevice();
				return basicGetDevice();
			case StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__AMOUNT:
				return getAmount();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__DEVICE:
				setDevice((StatemachinePeripheralDevicePT)newValue);
				return;
			case StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__AMOUNT:
				setAmount((StatemachineActionFieldConcatenation)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__DEVICE:
				setDevice((StatemachinePeripheralDevicePT)null);
				return;
			case StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__AMOUNT:
				setAmount((StatemachineActionFieldConcatenation)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__DEVICE:
				return device != null;
			case StatemachineDSLPackage.STATEMACHINE_ACTION_PERIPHERAL_PT_AUTHORIZATION__AMOUNT:
				return amount != null;
		}
		return super.eIsSet(featureID);
	}

} //StatemachineActionPeripheralPTAuthorizationImpl
