/**
 * 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 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:  
 *  		Christophe Loetz  (Loetz GmbH&Co.KG) - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.entitymock.impl;

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.dsl.semantic.entity.LEntityAttribute;

import org.eclipse.osbp.xtext.entitymock.EntityMockDSLPackage;
import org.eclipse.osbp.xtext.entitymock.PropertyFillerSignedIntegerRange;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Property Filler Signed Integer Range</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.PropertyFillerSignedIntegerRangeImpl#getBeginRange <em>Begin Range</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.PropertyFillerSignedIntegerRangeImpl#getEndRange <em>End Range</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.PropertyFillerSignedIntegerRangeImpl#getBeginRangeRef <em>Begin Range Ref</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.PropertyFillerSignedIntegerRangeImpl#getEndRangeRef <em>End Range Ref</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.PropertyFillerSignedIntegerRangeImpl#getRounded <em>Rounded</em>}</li>
 * </ul>
 *
 * @generated
 */
public class PropertyFillerSignedIntegerRangeImpl extends PropertyFillerIntegerTypeImpl implements PropertyFillerSignedIntegerRange {
	/**
	 * The default value of the '{@link #getBeginRange() <em>Begin Range</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getBeginRange()
	 * @generated
	 * @ordered
	 */
	protected static final int BEGIN_RANGE_EDEFAULT = 0;

	/**
	 * The cached value of the '{@link #getBeginRange() <em>Begin Range</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getBeginRange()
	 * @generated
	 * @ordered
	 */
	protected int beginRange = BEGIN_RANGE_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getEndRange() <em>End Range</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEndRange()
	 * @generated
	 * @ordered
	 */
	protected int endRange = END_RANGE_EDEFAULT;

	/**
	 * The cached value of the '{@link #getBeginRangeRef() <em>Begin Range Ref</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getBeginRangeRef()
	 * @generated
	 * @ordered
	 */
	protected LEntityAttribute beginRangeRef;

	/**
	 * The cached value of the '{@link #getEndRangeRef() <em>End Range Ref</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEndRangeRef()
	 * @generated
	 * @ordered
	 */
	protected LEntityAttribute endRangeRef;

	/**
	 * The default value of the '{@link #getRounded() <em>Rounded</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getRounded()
	 * @generated
	 * @ordered
	 */
	protected static final int ROUNDED_EDEFAULT = 0;

	/**
	 * The cached value of the '{@link #getRounded() <em>Rounded</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getRounded()
	 * @generated
	 * @ordered
	 */
	protected int rounded = ROUNDED_EDEFAULT;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setBeginRange(int newBeginRange) {
		int oldBeginRange = beginRange;
		beginRange = newBeginRange;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__BEGIN_RANGE, oldBeginRange, beginRange));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setEndRange(int newEndRange) {
		int oldEndRange = endRange;
		endRange = newEndRange;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__END_RANGE, oldEndRange, endRange));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityAttribute getBeginRangeRef() {
		if (beginRangeRef != null && beginRangeRef.eIsProxy()) {
			InternalEObject oldBeginRangeRef = (InternalEObject)beginRangeRef;
			beginRangeRef = (LEntityAttribute)eResolveProxy(oldBeginRangeRef);
			if (beginRangeRef != oldBeginRangeRef) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__BEGIN_RANGE_REF, oldBeginRangeRef, beginRangeRef));
			}
		}
		return beginRangeRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityAttribute basicGetBeginRangeRef() {
		return beginRangeRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setBeginRangeRef(LEntityAttribute newBeginRangeRef) {
		LEntityAttribute oldBeginRangeRef = beginRangeRef;
		beginRangeRef = newBeginRangeRef;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__BEGIN_RANGE_REF, oldBeginRangeRef, beginRangeRef));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityAttribute getEndRangeRef() {
		if (endRangeRef != null && endRangeRef.eIsProxy()) {
			InternalEObject oldEndRangeRef = (InternalEObject)endRangeRef;
			endRangeRef = (LEntityAttribute)eResolveProxy(oldEndRangeRef);
			if (endRangeRef != oldEndRangeRef) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__END_RANGE_REF, oldEndRangeRef, endRangeRef));
			}
		}
		return endRangeRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityAttribute basicGetEndRangeRef() {
		return endRangeRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setEndRangeRef(LEntityAttribute newEndRangeRef) {
		LEntityAttribute oldEndRangeRef = endRangeRef;
		endRangeRef = newEndRangeRef;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__END_RANGE_REF, oldEndRangeRef, endRangeRef));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setRounded(int newRounded) {
		int oldRounded = rounded;
		rounded = newRounded;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__ROUNDED, oldRounded, rounded));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__BEGIN_RANGE:
				return getBeginRange();
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__END_RANGE:
				return getEndRange();
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__BEGIN_RANGE_REF:
				if (resolve) return getBeginRangeRef();
				return basicGetBeginRangeRef();
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__END_RANGE_REF:
				if (resolve) return getEndRangeRef();
				return basicGetEndRangeRef();
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__ROUNDED:
				return getRounded();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__BEGIN_RANGE:
				setBeginRange((Integer)newValue);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__END_RANGE:
				setEndRange((Integer)newValue);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__BEGIN_RANGE_REF:
				setBeginRangeRef((LEntityAttribute)newValue);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__END_RANGE_REF:
				setEndRangeRef((LEntityAttribute)newValue);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__ROUNDED:
				setRounded((Integer)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__BEGIN_RANGE:
				setBeginRange(BEGIN_RANGE_EDEFAULT);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__END_RANGE:
				setEndRange(END_RANGE_EDEFAULT);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__BEGIN_RANGE_REF:
				setBeginRangeRef((LEntityAttribute)null);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__END_RANGE_REF:
				setEndRangeRef((LEntityAttribute)null);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__ROUNDED:
				setRounded(ROUNDED_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__BEGIN_RANGE:
				return beginRange != BEGIN_RANGE_EDEFAULT;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__END_RANGE:
				return endRange != END_RANGE_EDEFAULT;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__BEGIN_RANGE_REF:
				return beginRangeRef != null;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__END_RANGE_REF:
				return endRangeRef != null;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_INTEGER_RANGE__ROUNDED:
				return rounded != ROUNDED_EDEFAULT;
		}
		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(" (beginRange: ");
		result.append(beginRange);
		result.append(", endRange: ");
		result.append(endRange);
		result.append(", rounded: ");
		result.append(rounded);
		result.append(')');
		return result.toString();
	}

} //PropertyFillerSignedIntegerRangeImpl
