/**
 * 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 2.0  
 *  which accompanies this distribution, and is available at 
 *  https://www.eclipse.org/legal/epl-2.0/ 
 * 
 *  SPDX-License-Identifier: EPL-2.0 
 * 
 *  Based on ideas from Xtext, Xtend, Xcore
 *   
 *  Contributors:  
 *  		Joerg Riegel - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.statemachine.impl;

import java.util.Collection;

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

import org.eclipse.emf.common.util.EList;

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

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

import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;

import org.eclipse.osbp.xtext.statemachine.FSMActionFieldConcatenation;
import org.eclipse.osbp.xtext.statemachine.FSMActionFieldSource;
import org.eclipse.osbp.xtext.statemachine.StatemachineDSLPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>FSM Action Field Concatenation</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.statemachine.impl.FSMActionFieldConcatenationImpl#getFirst <em>First</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.statemachine.impl.FSMActionFieldConcatenationImpl#getMore <em>More</em>}</li>
 * </ul>
 *
 * @generated
 */
public class FSMActionFieldConcatenationImpl extends FSMLazyResolverImpl implements FSMActionFieldConcatenation {
	/**
	 * The cached value of the '{@link #getFirst() <em>First</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFirst()
	 * @generated
	 * @ordered
	 */
	protected FSMActionFieldSource first;

	/**
	 * The cached value of the '{@link #getMore() <em>More</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMore()
	 * @generated
	 * @ordered
	 */
	protected EList<FSMActionFieldSource> more;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FSMActionFieldSource getFirst() {
		return first;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetFirst(FSMActionFieldSource newFirst, NotificationChain msgs) {
		FSMActionFieldSource oldFirst = first;
		first = newFirst;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, StatemachineDSLPackage.FSM_ACTION_FIELD_CONCATENATION__FIRST, oldFirst, newFirst);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setFirst(FSMActionFieldSource newFirst) {
		if (newFirst != first) {
			NotificationChain msgs = null;
			if (first != null)
				msgs = ((InternalEObject)first).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - StatemachineDSLPackage.FSM_ACTION_FIELD_CONCATENATION__FIRST, null, msgs);
			if (newFirst != null)
				msgs = ((InternalEObject)newFirst).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - StatemachineDSLPackage.FSM_ACTION_FIELD_CONCATENATION__FIRST, null, msgs);
			msgs = basicSetFirst(newFirst, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StatemachineDSLPackage.FSM_ACTION_FIELD_CONCATENATION__FIRST, newFirst, newFirst));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<FSMActionFieldSource> getMore() {
		if (more == null) {
			more = new EObjectContainmentEList<FSMActionFieldSource>(FSMActionFieldSource.class, this, StatemachineDSLPackage.FSM_ACTION_FIELD_CONCATENATION__MORE);
		}
		return more;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case StatemachineDSLPackage.FSM_ACTION_FIELD_CONCATENATION__FIRST:
				return basicSetFirst(null, msgs);
			case StatemachineDSLPackage.FSM_ACTION_FIELD_CONCATENATION__MORE:
				return ((InternalEList<?>)getMore()).basicRemove(otherEnd, 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.FSM_ACTION_FIELD_CONCATENATION__FIRST:
				return getFirst();
			case StatemachineDSLPackage.FSM_ACTION_FIELD_CONCATENATION__MORE:
				return getMore();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case StatemachineDSLPackage.FSM_ACTION_FIELD_CONCATENATION__FIRST:
				setFirst((FSMActionFieldSource)newValue);
				return;
			case StatemachineDSLPackage.FSM_ACTION_FIELD_CONCATENATION__MORE:
				getMore().clear();
				getMore().addAll((Collection<? extends FSMActionFieldSource>)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case StatemachineDSLPackage.FSM_ACTION_FIELD_CONCATENATION__FIRST:
				setFirst((FSMActionFieldSource)null);
				return;
			case StatemachineDSLPackage.FSM_ACTION_FIELD_CONCATENATION__MORE:
				getMore().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case StatemachineDSLPackage.FSM_ACTION_FIELD_CONCATENATION__FIRST:
				return first != null;
			case StatemachineDSLPackage.FSM_ACTION_FIELD_CONCATENATION__MORE:
				return more != null && !more.isEmpty();
		}
		return super.eIsSet(featureID);
	}

} //FSMActionFieldConcatenationImpl
