/**
 * Copyright (c) 2014, Loetz GmbH&Co.KG (Heidelberg)
 *  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:  
 *  		Loetz GmbH&Co.KG - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.blip.impl;

import org.eclipse.bpmn2.CallActivity;

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.blip.BlipCallActivity;
import org.eclipse.osbp.xtext.blip.BlipDSLPackage;

import org.eclipse.osbp.xtext.functionlibrarydsl.FunctionLibraryFunction;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Blip Call Activity</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipCallActivityImpl#getCallActivity <em>Call Activity</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipCallActivityImpl#getOnEntry <em>On Entry</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipCallActivityImpl#getOnExit <em>On Exit</em>}</li>
 * </ul>
 *
 * @generated
 */
public class BlipCallActivityImpl extends BlipItemImpl implements BlipCallActivity {
	/**
	 * The cached value of the '{@link #getCallActivity() <em>Call Activity</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCallActivity()
	 * @generated
	 * @ordered
	 */
	protected CallActivity callActivity;

	/**
	 * The cached value of the '{@link #getOnEntry() <em>On Entry</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getOnEntry()
	 * @generated
	 * @ordered
	 */
	protected FunctionLibraryFunction onEntry;

	/**
	 * The cached value of the '{@link #getOnExit() <em>On Exit</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getOnExit()
	 * @generated
	 * @ordered
	 */
	protected FunctionLibraryFunction onExit;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public CallActivity getCallActivity() {
		if (callActivity != null && callActivity.eIsProxy()) {
			InternalEObject oldCallActivity = (InternalEObject)callActivity;
			callActivity = (CallActivity)eResolveProxy(oldCallActivity);
			if (callActivity != oldCallActivity) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, BlipDSLPackage.BLIP_CALL_ACTIVITY__CALL_ACTIVITY, oldCallActivity, callActivity));
			}
		}
		return callActivity;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public CallActivity basicGetCallActivity() {
		return callActivity;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setCallActivity(CallActivity newCallActivity) {
		CallActivity oldCallActivity = callActivity;
		callActivity = newCallActivity;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP_CALL_ACTIVITY__CALL_ACTIVITY, oldCallActivity, callActivity));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FunctionLibraryFunction getOnEntry() {
		if (onEntry != null && onEntry.eIsProxy()) {
			InternalEObject oldOnEntry = (InternalEObject)onEntry;
			onEntry = (FunctionLibraryFunction)eResolveProxy(oldOnEntry);
			if (onEntry != oldOnEntry) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, BlipDSLPackage.BLIP_CALL_ACTIVITY__ON_ENTRY, oldOnEntry, onEntry));
			}
		}
		return onEntry;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FunctionLibraryFunction basicGetOnEntry() {
		return onEntry;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setOnEntry(FunctionLibraryFunction newOnEntry) {
		FunctionLibraryFunction oldOnEntry = onEntry;
		onEntry = newOnEntry;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP_CALL_ACTIVITY__ON_ENTRY, oldOnEntry, onEntry));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FunctionLibraryFunction getOnExit() {
		if (onExit != null && onExit.eIsProxy()) {
			InternalEObject oldOnExit = (InternalEObject)onExit;
			onExit = (FunctionLibraryFunction)eResolveProxy(oldOnExit);
			if (onExit != oldOnExit) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, BlipDSLPackage.BLIP_CALL_ACTIVITY__ON_EXIT, oldOnExit, onExit));
			}
		}
		return onExit;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FunctionLibraryFunction basicGetOnExit() {
		return onExit;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setOnExit(FunctionLibraryFunction newOnExit) {
		FunctionLibraryFunction oldOnExit = onExit;
		onExit = newOnExit;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP_CALL_ACTIVITY__ON_EXIT, oldOnExit, onExit));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case BlipDSLPackage.BLIP_CALL_ACTIVITY__CALL_ACTIVITY:
				if (resolve) return getCallActivity();
				return basicGetCallActivity();
			case BlipDSLPackage.BLIP_CALL_ACTIVITY__ON_ENTRY:
				if (resolve) return getOnEntry();
				return basicGetOnEntry();
			case BlipDSLPackage.BLIP_CALL_ACTIVITY__ON_EXIT:
				if (resolve) return getOnExit();
				return basicGetOnExit();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case BlipDSLPackage.BLIP_CALL_ACTIVITY__CALL_ACTIVITY:
				setCallActivity((CallActivity)newValue);
				return;
			case BlipDSLPackage.BLIP_CALL_ACTIVITY__ON_ENTRY:
				setOnEntry((FunctionLibraryFunction)newValue);
				return;
			case BlipDSLPackage.BLIP_CALL_ACTIVITY__ON_EXIT:
				setOnExit((FunctionLibraryFunction)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case BlipDSLPackage.BLIP_CALL_ACTIVITY__CALL_ACTIVITY:
				setCallActivity((CallActivity)null);
				return;
			case BlipDSLPackage.BLIP_CALL_ACTIVITY__ON_ENTRY:
				setOnEntry((FunctionLibraryFunction)null);
				return;
			case BlipDSLPackage.BLIP_CALL_ACTIVITY__ON_EXIT:
				setOnExit((FunctionLibraryFunction)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case BlipDSLPackage.BLIP_CALL_ACTIVITY__CALL_ACTIVITY:
				return callActivity != null;
			case BlipDSLPackage.BLIP_CALL_ACTIVITY__ON_ENTRY:
				return onEntry != null;
			case BlipDSLPackage.BLIP_CALL_ACTIVITY__ON_EXIT:
				return onExit != null;
		}
		return super.eIsSet(featureID);
	}

} //BlipCallActivityImpl
