/**
 * *******************************************************************************
 *  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.AmaltheaExtensions;
import org.eclipse.app4mc.amalthea.model.AmaltheaPackage;
import org.eclipse.app4mc.amalthea.model.HwAccessElement;
import org.eclipse.app4mc.amalthea.model.HwAccessPath;
import org.eclipse.app4mc.amalthea.model.HwPathElement;
import org.eclipse.app4mc.amalthea.model.INamed;
import org.eclipse.app4mc.amalthea.model.Namespace;

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

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Hw Access Path</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.HwAccessPathImpl#getName <em>Name</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.HwAccessPathImpl#getQualifiedName <em>Qualified Name</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.HwAccessPathImpl#getContainingAccessElement <em>Containing Access Element</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.HwAccessPathImpl#getPathElements <em>Path Elements</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.HwAccessPathImpl#getStartAddress <em>Start Address</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.HwAccessPathImpl#getEndAddress <em>End Address</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.HwAccessPathImpl#getMemOffset <em>Mem Offset</em>}</li>
 * </ul>
 *
 * @generated
 */
public class HwAccessPathImpl extends HwPathImpl implements HwAccessPath {
	/**
	 * 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 #getPathElements() <em>Path Elements</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getPathElements()
	 * @generated
	 * @ordered
	 */
	protected EList<HwPathElement> pathElements;

	/**
	 * The default value of the '{@link #getStartAddress() <em>Start Address</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getStartAddress()
	 * @generated
	 * @ordered
	 */
	protected static final long START_ADDRESS_EDEFAULT = 0L;

	/**
	 * The cached value of the '{@link #getStartAddress() <em>Start Address</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getStartAddress()
	 * @generated
	 * @ordered
	 */
	protected long startAddress = START_ADDRESS_EDEFAULT;

	/**
	 * The default value of the '{@link #getEndAddress() <em>End Address</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEndAddress()
	 * @generated
	 * @ordered
	 */
	protected static final long END_ADDRESS_EDEFAULT = 0L;

	/**
	 * The cached value of the '{@link #getEndAddress() <em>End Address</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEndAddress()
	 * @generated
	 * @ordered
	 */
	protected long endAddress = END_ADDRESS_EDEFAULT;

	/**
	 * The default value of the '{@link #getMemOffset() <em>Mem Offset</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMemOffset()
	 * @generated
	 * @ordered
	 */
	protected static final long MEM_OFFSET_EDEFAULT = 0L;

	/**
	 * The cached value of the '{@link #getMemOffset() <em>Mem Offset</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMemOffset()
	 * @generated
	 * @ordered
	 */
	protected long memOffset = MEM_OFFSET_EDEFAULT;

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

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

	/**
	 * <!-- 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.HW_ACCESS_PATH__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 HwAccessElement getContainingAccessElement() {
		if (eContainerFeatureID() != AmaltheaPackage.HW_ACCESS_PATH__CONTAINING_ACCESS_ELEMENT) return null;
		return (HwAccessElement)eContainer();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public HwAccessElement basicGetContainingAccessElement() {
		if (eContainerFeatureID() != AmaltheaPackage.HW_ACCESS_PATH__CONTAINING_ACCESS_ELEMENT) return null;
		return (HwAccessElement)eInternalContainer();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<HwPathElement> getPathElements() {
		if (pathElements == null) {
			pathElements = new EObjectResolvingEList<HwPathElement>(HwPathElement.class, this, AmaltheaPackage.HW_ACCESS_PATH__PATH_ELEMENTS);
		}
		return pathElements;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public long getStartAddress() {
		return startAddress;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setStartAddress(long newStartAddress) {
		long oldStartAddress = startAddress;
		startAddress = newStartAddress;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AmaltheaPackage.HW_ACCESS_PATH__START_ADDRESS, oldStartAddress, startAddress));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public long getEndAddress() {
		return endAddress;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setEndAddress(long newEndAddress) {
		long oldEndAddress = endAddress;
		endAddress = newEndAddress;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AmaltheaPackage.HW_ACCESS_PATH__END_ADDRESS, oldEndAddress, endAddress));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public long getMemOffset() {
		return memOffset;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setMemOffset(long newMemOffset) {
		long oldMemOffset = memOffset;
		memOffset = newMemOffset;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AmaltheaPackage.HW_ACCESS_PATH__MEM_OFFSET, oldMemOffset, memOffset));
	}

	/**
	 * <!-- 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 eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case AmaltheaPackage.HW_ACCESS_PATH__CONTAINING_ACCESS_ELEMENT:
				if (eInternalContainer() != null)
					msgs = eBasicRemoveFromContainer(msgs);
				return eBasicSetContainer(otherEnd, AmaltheaPackage.HW_ACCESS_PATH__CONTAINING_ACCESS_ELEMENT, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case AmaltheaPackage.HW_ACCESS_PATH__CONTAINING_ACCESS_ELEMENT:
				return eBasicSetContainer(null, AmaltheaPackage.HW_ACCESS_PATH__CONTAINING_ACCESS_ELEMENT, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) {
		switch (eContainerFeatureID()) {
			case AmaltheaPackage.HW_ACCESS_PATH__CONTAINING_ACCESS_ELEMENT:
				return eInternalContainer().eInverseRemove(this, AmaltheaPackage.HW_ACCESS_ELEMENT__ACCESS_PATH, HwAccessElement.class, msgs);
		}
		return super.eBasicRemoveFromContainerFeature(msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case AmaltheaPackage.HW_ACCESS_PATH__NAME:
				return getName();
			case AmaltheaPackage.HW_ACCESS_PATH__QUALIFIED_NAME:
				return getQualifiedName();
			case AmaltheaPackage.HW_ACCESS_PATH__CONTAINING_ACCESS_ELEMENT:
				if (resolve) return getContainingAccessElement();
				return basicGetContainingAccessElement();
			case AmaltheaPackage.HW_ACCESS_PATH__PATH_ELEMENTS:
				return getPathElements();
			case AmaltheaPackage.HW_ACCESS_PATH__START_ADDRESS:
				return getStartAddress();
			case AmaltheaPackage.HW_ACCESS_PATH__END_ADDRESS:
				return getEndAddress();
			case AmaltheaPackage.HW_ACCESS_PATH__MEM_OFFSET:
				return getMemOffset();
		}
		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.HW_ACCESS_PATH__NAME:
				setName((String)newValue);
				return;
			case AmaltheaPackage.HW_ACCESS_PATH__PATH_ELEMENTS:
				getPathElements().clear();
				getPathElements().addAll((Collection<? extends HwPathElement>)newValue);
				return;
			case AmaltheaPackage.HW_ACCESS_PATH__START_ADDRESS:
				setStartAddress((Long)newValue);
				return;
			case AmaltheaPackage.HW_ACCESS_PATH__END_ADDRESS:
				setEndAddress((Long)newValue);
				return;
			case AmaltheaPackage.HW_ACCESS_PATH__MEM_OFFSET:
				setMemOffset((Long)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case AmaltheaPackage.HW_ACCESS_PATH__NAME:
				setName(NAME_EDEFAULT);
				return;
			case AmaltheaPackage.HW_ACCESS_PATH__PATH_ELEMENTS:
				getPathElements().clear();
				return;
			case AmaltheaPackage.HW_ACCESS_PATH__START_ADDRESS:
				setStartAddress(START_ADDRESS_EDEFAULT);
				return;
			case AmaltheaPackage.HW_ACCESS_PATH__END_ADDRESS:
				setEndAddress(END_ADDRESS_EDEFAULT);
				return;
			case AmaltheaPackage.HW_ACCESS_PATH__MEM_OFFSET:
				setMemOffset(MEM_OFFSET_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case AmaltheaPackage.HW_ACCESS_PATH__NAME:
				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
			case AmaltheaPackage.HW_ACCESS_PATH__QUALIFIED_NAME:
				return QUALIFIED_NAME_EDEFAULT == null ? getQualifiedName() != null : !QUALIFIED_NAME_EDEFAULT.equals(getQualifiedName());
			case AmaltheaPackage.HW_ACCESS_PATH__CONTAINING_ACCESS_ELEMENT:
				return basicGetContainingAccessElement() != null;
			case AmaltheaPackage.HW_ACCESS_PATH__PATH_ELEMENTS:
				return pathElements != null && !pathElements.isEmpty();
			case AmaltheaPackage.HW_ACCESS_PATH__START_ADDRESS:
				return startAddress != START_ADDRESS_EDEFAULT;
			case AmaltheaPackage.HW_ACCESS_PATH__END_ADDRESS:
				return endAddress != END_ADDRESS_EDEFAULT;
			case AmaltheaPackage.HW_ACCESS_PATH__MEM_OFFSET:
				return memOffset != MEM_OFFSET_EDEFAULT;
		}
		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.HW_ACCESS_PATH__NAME: return AmaltheaPackage.INAMED__NAME;
				case AmaltheaPackage.HW_ACCESS_PATH__QUALIFIED_NAME: return AmaltheaPackage.INAMED__QUALIFIED_NAME;
				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.HW_ACCESS_PATH__NAME;
				case AmaltheaPackage.INAMED__QUALIFIED_NAME: return AmaltheaPackage.HW_ACCESS_PATH__QUALIFIED_NAME;
				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.HW_ACCESS_PATH___GET_NAMED_CONTAINER;
				case AmaltheaPackage.INAMED___GET_NAME_PREFIX: return AmaltheaPackage.HW_ACCESS_PATH___GET_NAME_PREFIX;
				case AmaltheaPackage.INAMED___GET_QUALIFIED_NAME_SEGMENTS: return AmaltheaPackage.HW_ACCESS_PATH___GET_QUALIFIED_NAME_SEGMENTS;
				case AmaltheaPackage.INAMED___GET_DEFAULT_NAME_SEPARATOR: return AmaltheaPackage.HW_ACCESS_PATH___GET_DEFAULT_NAME_SEPARATOR;
				case AmaltheaPackage.INAMED___GET_NAMESPACE: return AmaltheaPackage.HW_ACCESS_PATH___GET_NAMESPACE;
				case AmaltheaPackage.INAMED___GET_NAME_PREFIX_SEGMENTS: return AmaltheaPackage.HW_ACCESS_PATH___GET_NAME_PREFIX_SEGMENTS;
				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.HW_ACCESS_PATH___GET_NAMED_CONTAINER:
				return getNamedContainer();
			case AmaltheaPackage.HW_ACCESS_PATH___GET_NAME_PREFIX:
				return getNamePrefix();
			case AmaltheaPackage.HW_ACCESS_PATH___GET_QUALIFIED_NAME_SEGMENTS:
				return getQualifiedNameSegments();
			case AmaltheaPackage.HW_ACCESS_PATH___GET_DEFAULT_NAME_SEPARATOR:
				return getDefaultNameSeparator();
			case AmaltheaPackage.HW_ACCESS_PATH___GET_NAMESPACE:
				return getNamespace();
			case AmaltheaPackage.HW_ACCESS_PATH___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(", startAddress: ");
		result.append(startAddress);
		result.append(", endAddress: ");
		result.append(endAddress);
		result.append(", memOffset: ");
		result.append(memOffset);
		result.append(')');
		return result.toString();
	}

} //HwAccessPathImpl
