/**
 * Copyright (c) 2011, 2016 - 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.chart.impl;

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

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

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

import org.eclipse.osbp.xtext.chart.ChartDSLPackage;
import org.eclipse.osbp.xtext.chart.ChartNumberInterval;
import org.eclipse.osbp.xtext.chart.ChartRangeElement;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Chart Number Interval</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartNumberIntervalImpl#getNumberIntervalValue <em>Number Interval Value</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartNumberIntervalImpl#getNumberRange <em>Number Range</em>}</li>
 * </ul>
 *
 * @generated
 */
public class ChartNumberIntervalImpl extends ChartLazyResolverImpl implements ChartNumberInterval {
	/**
	 * The default value of the '{@link #getNumberIntervalValue() <em>Number Interval Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNumberIntervalValue()
	 * @generated
	 * @ordered
	 */
	protected static final int NUMBER_INTERVAL_VALUE_EDEFAULT = 0;

	/**
	 * The cached value of the '{@link #getNumberIntervalValue() <em>Number Interval Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNumberIntervalValue()
	 * @generated
	 * @ordered
	 */
	protected int numberIntervalValue = NUMBER_INTERVAL_VALUE_EDEFAULT;

	/**
	 * The cached value of the '{@link #getNumberRange() <em>Number Range</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNumberRange()
	 * @generated
	 * @ordered
	 */
	protected ChartRangeElement numberRange;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public int getNumberIntervalValue() {
		return numberIntervalValue;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setNumberIntervalValue(int newNumberIntervalValue) {
		int oldNumberIntervalValue = numberIntervalValue;
		numberIntervalValue = newNumberIntervalValue;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART_NUMBER_INTERVAL__NUMBER_INTERVAL_VALUE, oldNumberIntervalValue, numberIntervalValue));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ChartRangeElement getNumberRange() {
		return numberRange;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetNumberRange(ChartRangeElement newNumberRange, NotificationChain msgs) {
		ChartRangeElement oldNumberRange = numberRange;
		numberRange = newNumberRange;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART_NUMBER_INTERVAL__NUMBER_RANGE, oldNumberRange, newNumberRange);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setNumberRange(ChartRangeElement newNumberRange) {
		if (newNumberRange != numberRange) {
			NotificationChain msgs = null;
			if (numberRange != null)
				msgs = ((InternalEObject)numberRange).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ChartDSLPackage.CHART_NUMBER_INTERVAL__NUMBER_RANGE, null, msgs);
			if (newNumberRange != null)
				msgs = ((InternalEObject)newNumberRange).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ChartDSLPackage.CHART_NUMBER_INTERVAL__NUMBER_RANGE, null, msgs);
			msgs = basicSetNumberRange(newNumberRange, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART_NUMBER_INTERVAL__NUMBER_RANGE, newNumberRange, newNumberRange));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ChartDSLPackage.CHART_NUMBER_INTERVAL__NUMBER_RANGE:
				return basicSetNumberRange(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 ChartDSLPackage.CHART_NUMBER_INTERVAL__NUMBER_INTERVAL_VALUE:
				return getNumberIntervalValue();
			case ChartDSLPackage.CHART_NUMBER_INTERVAL__NUMBER_RANGE:
				return getNumberRange();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case ChartDSLPackage.CHART_NUMBER_INTERVAL__NUMBER_INTERVAL_VALUE:
				setNumberIntervalValue((Integer)newValue);
				return;
			case ChartDSLPackage.CHART_NUMBER_INTERVAL__NUMBER_RANGE:
				setNumberRange((ChartRangeElement)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ChartDSLPackage.CHART_NUMBER_INTERVAL__NUMBER_INTERVAL_VALUE:
				setNumberIntervalValue(NUMBER_INTERVAL_VALUE_EDEFAULT);
				return;
			case ChartDSLPackage.CHART_NUMBER_INTERVAL__NUMBER_RANGE:
				setNumberRange((ChartRangeElement)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ChartDSLPackage.CHART_NUMBER_INTERVAL__NUMBER_INTERVAL_VALUE:
				return numberIntervalValue != NUMBER_INTERVAL_VALUE_EDEFAULT;
			case ChartDSLPackage.CHART_NUMBER_INTERVAL__NUMBER_RANGE:
				return numberRange != 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(" (numberIntervalValue: ");
		result.append(numberIntervalValue);
		result.append(')');
		return result.toString();
	}

} //ChartNumberIntervalImpl
