/**
 * *******************************************************************************
 *  Copyright (c) 2015-2021 Robert Bosch GmbH and others.
 * 
 *  This program and the accompanying materials are made
 *  available under the terms of the Eclipse Public License 2.0
 *  which is available at https://www.eclipse.org/legal/epl-2.0/
 * 
 *  SPDX-License-Identifier: EPL-2.0
 * 
 *     Generated using Eclipse EMF
 * 
 * *******************************************************************************
 */
package org.eclipse.app4mc.amalthea.model.impl;

import java.lang.reflect.InvocationTargetException;

import java.util.Collection;

import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
import org.eclipse.app4mc.amalthea.model.AmaltheaExtensions;
import org.eclipse.app4mc.amalthea.model.AmaltheaPackage;
import org.eclipse.app4mc.amalthea.model.ConditionDisjunction;
import org.eclipse.app4mc.amalthea.model.IActivityGraphItemContainer;
import org.eclipse.app4mc.amalthea.model.INamed;
import org.eclipse.app4mc.amalthea.model.Namespace;
import org.eclipse.app4mc.amalthea.model.SwitchEntry;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
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.emf.ecore.xcore.lib.XcoreCollectionLiterals;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Switch Entry</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.SwitchEntryImpl#getName <em>Name</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.SwitchEntryImpl#getQualifiedName <em>Qualified Name</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.SwitchEntryImpl#getItems <em>Items</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.SwitchEntryImpl#getCondition <em>Condition</em>}</li>
 * </ul>
 *
 * @generated
 */
public class SwitchEntryImpl extends BaseObjectImpl implements SwitchEntry {
	/**
	 * The default value of the '{@link #getName() <em>Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getName()
	 * @generated
	 * @ordered
	 */
	protected static final String NAME_EDEFAULT = "";

	/**
	 * The cached value of the '{@link #getName() <em>Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getName()
	 * @generated
	 * @ordered
	 */
	protected String name = NAME_EDEFAULT;

	/**
	 * The default value of the '{@link #getQualifiedName() <em>Qualified Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getQualifiedName()
	 * @generated
	 * @ordered
	 */
	protected static final String QUALIFIED_NAME_EDEFAULT = null;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return AmaltheaPackage.eINSTANCE.getSwitchEntry();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getName() {
		return name;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setName(String newName) {
		String oldName = name;
		name = newName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AmaltheaPackage.SWITCH_ENTRY__NAME, oldName, name));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getQualifiedName() {
		return AmaltheaExtensions.toPlainString(this.getQualifiedNameSegments(), this.getDefaultNameSeparator());
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<ActivityGraphItem> getItems() {
		if (items == null) {
			items = new EObjectContainmentEList<ActivityGraphItem>(ActivityGraphItem.class, this, AmaltheaPackage.SWITCH_ENTRY__ITEMS);
		}
		return items;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public ConditionDisjunction getCondition() {
		return condition;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetCondition(ConditionDisjunction newCondition, NotificationChain msgs) {
		ConditionDisjunction oldCondition = condition;
		condition = newCondition;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, AmaltheaPackage.SWITCH_ENTRY__CONDITION, oldCondition, newCondition);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setCondition(ConditionDisjunction newCondition) {
		if (newCondition != condition) {
			NotificationChain msgs = null;
			if (condition != null)
				msgs = ((InternalEObject)condition).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - AmaltheaPackage.SWITCH_ENTRY__CONDITION, null, msgs);
			if (newCondition != null)
				msgs = ((InternalEObject)newCondition).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - AmaltheaPackage.SWITCH_ENTRY__CONDITION, null, msgs);
			msgs = basicSetCondition(newCondition, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AmaltheaPackage.SWITCH_ENTRY__CONDITION, newCondition, newCondition));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public INamed getNamedContainer() {
		INamed _xifexpression = null;
		EObject _eContainer = this.eContainer();
		if ((_eContainer instanceof INamed)) {
			EObject _eContainer_1 = this.eContainer();
			_xifexpression = ((INamed) _eContainer_1);
		}
		else {
			_xifexpression = null;
		}
		return _xifexpression;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getNamePrefix() {
		String _xifexpression = null;
		Namespace _namespace = this.getNamespace();
		boolean _tripleEquals = (_namespace == null);
		if (_tripleEquals) {
			return "";
		}
		else {
			_xifexpression = AmaltheaExtensions.toPlainString(this.getNamePrefixSegments(), this.getDefaultNameSeparator());
		}
		return _xifexpression;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<String> getQualifiedNameSegments() {
		final EList<String> segments = this.getNamePrefixSegments();
		String _name = this.getName();
		boolean _tripleNotEquals = (_name != null);
		if (_tripleNotEquals) {
			segments.add(this.getName());
		}
		return segments;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getDefaultNameSeparator() {
		return ".";
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Namespace getNamespace() {
		return null;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<String> getNamePrefixSegments() {
		EList<String> _elvis = null;
		Namespace _namespace = this.getNamespace();
		EList<String> _qualifiedNameSegments = null;
		if (_namespace!=null) {
			_qualifiedNameSegments=_namespace.getQualifiedNameSegments();
		}
		if (_qualifiedNameSegments != null) {
			_elvis = _qualifiedNameSegments;
		} else {
			BasicEList<String> _newBasicEList = XcoreCollectionLiterals.<String>newBasicEList();
			_elvis = _newBasicEList;
		}
		return _elvis;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case AmaltheaPackage.SWITCH_ENTRY__ITEMS:
				return ((InternalEList<?>)getItems()).basicRemove(otherEnd, msgs);
			case AmaltheaPackage.SWITCH_ENTRY__CONDITION:
				return basicSetCondition(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 AmaltheaPackage.SWITCH_ENTRY__NAME:
				return getName();
			case AmaltheaPackage.SWITCH_ENTRY__QUALIFIED_NAME:
				return getQualifiedName();
			case AmaltheaPackage.SWITCH_ENTRY__ITEMS:
				return getItems();
			case AmaltheaPackage.SWITCH_ENTRY__CONDITION:
				return getCondition();
		}
		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 AmaltheaPackage.SWITCH_ENTRY__NAME:
				setName((String)newValue);
				return;
			case AmaltheaPackage.SWITCH_ENTRY__ITEMS:
				getItems().clear();
				getItems().addAll((Collection<? extends ActivityGraphItem>)newValue);
				return;
			case AmaltheaPackage.SWITCH_ENTRY__CONDITION:
				setCondition((ConditionDisjunction)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case AmaltheaPackage.SWITCH_ENTRY__NAME:
				setName(NAME_EDEFAULT);
				return;
			case AmaltheaPackage.SWITCH_ENTRY__ITEMS:
				getItems().clear();
				return;
			case AmaltheaPackage.SWITCH_ENTRY__CONDITION:
				setCondition((ConditionDisjunction)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case AmaltheaPackage.SWITCH_ENTRY__NAME:
				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
			case AmaltheaPackage.SWITCH_ENTRY__QUALIFIED_NAME:
				return QUALIFIED_NAME_EDEFAULT == null ? getQualifiedName() != null : !QUALIFIED_NAME_EDEFAULT.equals(getQualifiedName());
			case AmaltheaPackage.SWITCH_ENTRY__ITEMS:
				return items != null && !items.isEmpty();
			case AmaltheaPackage.SWITCH_ENTRY__CONDITION:
				return condition != null;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) {
		if (baseClass == INamed.class) {
			switch (derivedFeatureID) {
				case AmaltheaPackage.SWITCH_ENTRY__NAME: return AmaltheaPackage.INAMED__NAME;
				case AmaltheaPackage.SWITCH_ENTRY__QUALIFIED_NAME: return AmaltheaPackage.INAMED__QUALIFIED_NAME;
				default: return -1;
			}
		}
		if (baseClass == IActivityGraphItemContainer.class) {
			switch (derivedFeatureID) {
				case AmaltheaPackage.SWITCH_ENTRY__ITEMS: return AmaltheaPackage.IACTIVITY_GRAPH_ITEM_CONTAINER__ITEMS;
				default: return -1;
			}
		}
		return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) {
		if (baseClass == INamed.class) {
			switch (baseFeatureID) {
				case AmaltheaPackage.INAMED__NAME: return AmaltheaPackage.SWITCH_ENTRY__NAME;
				case AmaltheaPackage.INAMED__QUALIFIED_NAME: return AmaltheaPackage.SWITCH_ENTRY__QUALIFIED_NAME;
				default: return -1;
			}
		}
		if (baseClass == IActivityGraphItemContainer.class) {
			switch (baseFeatureID) {
				case AmaltheaPackage.IACTIVITY_GRAPH_ITEM_CONTAINER__ITEMS: return AmaltheaPackage.SWITCH_ENTRY__ITEMS;
				default: return -1;
			}
		}
		return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eDerivedOperationID(int baseOperationID, Class<?> baseClass) {
		if (baseClass == INamed.class) {
			switch (baseOperationID) {
				case AmaltheaPackage.INAMED___GET_NAMED_CONTAINER: return AmaltheaPackage.SWITCH_ENTRY___GET_NAMED_CONTAINER;
				case AmaltheaPackage.INAMED___GET_NAME_PREFIX: return AmaltheaPackage.SWITCH_ENTRY___GET_NAME_PREFIX;
				case AmaltheaPackage.INAMED___GET_QUALIFIED_NAME_SEGMENTS: return AmaltheaPackage.SWITCH_ENTRY___GET_QUALIFIED_NAME_SEGMENTS;
				case AmaltheaPackage.INAMED___GET_DEFAULT_NAME_SEPARATOR: return AmaltheaPackage.SWITCH_ENTRY___GET_DEFAULT_NAME_SEPARATOR;
				case AmaltheaPackage.INAMED___GET_NAMESPACE: return AmaltheaPackage.SWITCH_ENTRY___GET_NAMESPACE;
				case AmaltheaPackage.INAMED___GET_NAME_PREFIX_SEGMENTS: return AmaltheaPackage.SWITCH_ENTRY___GET_NAME_PREFIX_SEGMENTS;
				default: return -1;
			}
		}
		if (baseClass == IActivityGraphItemContainer.class) {
			switch (baseOperationID) {
				default: return -1;
			}
		}
		return super.eDerivedOperationID(baseOperationID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException {
		switch (operationID) {
			case AmaltheaPackage.SWITCH_ENTRY___GET_NAMED_CONTAINER:
				return getNamedContainer();
			case AmaltheaPackage.SWITCH_ENTRY___GET_NAME_PREFIX:
				return getNamePrefix();
			case AmaltheaPackage.SWITCH_ENTRY___GET_QUALIFIED_NAME_SEGMENTS:
				return getQualifiedNameSegments();
			case AmaltheaPackage.SWITCH_ENTRY___GET_DEFAULT_NAME_SEPARATOR:
				return getDefaultNameSeparator();
			case AmaltheaPackage.SWITCH_ENTRY___GET_NAMESPACE:
				return getNamespace();
			case AmaltheaPackage.SWITCH_ENTRY___GET_NAME_PREFIX_SEGMENTS:
				return getNamePrefixSegments();
		}
		return super.eInvoke(operationID, arguments);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuilder result = new StringBuilder(super.toString());
		result.append(" (name: ");
		result.append(name);
		result.append(')');
		return result.toString();
	}

} //SwitchEntryImpl
