/**
 * Copyright (c) 2011, 2018 - 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
 *  
 *  Contributors:                                                      
 *     Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 *  
 *  generated from SignalDSL.xcore
 * 
 *  
 */
package org.eclipse.osbp.xtext.signal.impl;

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

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

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

import org.eclipse.osbp.xtext.datainterchange.DataInterchange;

import org.eclipse.osbp.xtext.signal.SignalActionEnum;
import org.eclipse.osbp.xtext.signal.SignalDSLPackage;
import org.eclipse.osbp.xtext.signal.SignalDatainterchange;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Signal Datainterchange</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.signal.impl.SignalDatainterchangeImpl#getDataAction <em>Data Action</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.signal.impl.SignalDatainterchangeImpl#getDataRef <em>Data Ref</em>}</li>
 * </ul>
 *
 * @generated
 */
public class SignalDatainterchangeImpl extends SignalLazyResolverImpl implements SignalDatainterchange {
	/**
	 * The default value of the '{@link #getDataAction() <em>Data Action</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDataAction()
	 * @generated
	 * @ordered
	 */
	protected static final SignalActionEnum DATA_ACTION_EDEFAULT = SignalActionEnum.DATAIMPORT;

	/**
	 * The cached value of the '{@link #getDataAction() <em>Data Action</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDataAction()
	 * @generated
	 * @ordered
	 */
	protected SignalActionEnum dataAction = DATA_ACTION_EDEFAULT;

	/**
	 * The cached value of the '{@link #getDataRef() <em>Data Ref</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDataRef()
	 * @generated
	 * @ordered
	 */
	protected DataInterchange dataRef;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public SignalActionEnum getDataAction() {
		return dataAction;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDataAction(SignalActionEnum newDataAction) {
		SignalActionEnum oldDataAction = dataAction;
		dataAction = newDataAction == null ? DATA_ACTION_EDEFAULT : newDataAction;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, SignalDSLPackage.SIGNAL_DATAINTERCHANGE__DATA_ACTION, oldDataAction, dataAction));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public DataInterchange getDataRef() {
		if (dataRef != null && dataRef.eIsProxy()) {
			InternalEObject oldDataRef = (InternalEObject)dataRef;
			dataRef = (DataInterchange)eResolveProxy(oldDataRef);
			if (dataRef != oldDataRef) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, SignalDSLPackage.SIGNAL_DATAINTERCHANGE__DATA_REF, oldDataRef, dataRef));
			}
		}
		return dataRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public DataInterchange basicGetDataRef() {
		return dataRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDataRef(DataInterchange newDataRef) {
		DataInterchange oldDataRef = dataRef;
		dataRef = newDataRef;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, SignalDSLPackage.SIGNAL_DATAINTERCHANGE__DATA_REF, oldDataRef, dataRef));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case SignalDSLPackage.SIGNAL_DATAINTERCHANGE__DATA_ACTION:
				return getDataAction();
			case SignalDSLPackage.SIGNAL_DATAINTERCHANGE__DATA_REF:
				if (resolve) return getDataRef();
				return basicGetDataRef();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case SignalDSLPackage.SIGNAL_DATAINTERCHANGE__DATA_ACTION:
				setDataAction((SignalActionEnum)newValue);
				return;
			case SignalDSLPackage.SIGNAL_DATAINTERCHANGE__DATA_REF:
				setDataRef((DataInterchange)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case SignalDSLPackage.SIGNAL_DATAINTERCHANGE__DATA_ACTION:
				setDataAction(DATA_ACTION_EDEFAULT);
				return;
			case SignalDSLPackage.SIGNAL_DATAINTERCHANGE__DATA_REF:
				setDataRef((DataInterchange)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case SignalDSLPackage.SIGNAL_DATAINTERCHANGE__DATA_ACTION:
				return dataAction != DATA_ACTION_EDEFAULT;
			case SignalDSLPackage.SIGNAL_DATAINTERCHANGE__DATA_REF:
				return dataRef != 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(" (dataAction: ");
		result.append(dataAction);
		result.append(')');
		return result.toString();
	}

} //SignalDatainterchangeImpl
