/**
 * 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.PropertyFillerSignedDoubleRange;

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

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

	/**
	 * 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 double BEGIN_RANGE_EDEFAULT = 0.0;

	/**
	 * The cached value of the '{@link #getBeginRange() <em>Begin Range</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getBeginRange()
	 * @generated
	 * @ordered
	 */
	protected double 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 double END_RANGE_EDEFAULT = 0.0;

	/**
	 * The cached value of the '{@link #getEndRange() <em>End Range</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEndRange()
	 * @generated
	 * @ordered
	 */
	protected double 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 double ROUNDED_EDEFAULT = 0.0;

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

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDecimals(int newDecimals) {
		int oldDecimals = decimals;
		decimals = newDecimals;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__DECIMALS, oldDecimals, decimals));
	}

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setEndRange(double newEndRange) {
		double oldEndRange = endRange;
		endRange = newEndRange;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_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_DOUBLE_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_DOUBLE_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_DOUBLE_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_DOUBLE_RANGE__END_RANGE_REF, oldEndRangeRef, endRangeRef));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setRounded(double newRounded) {
		double oldRounded = rounded;
		rounded = newRounded;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_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_DOUBLE_RANGE__DECIMALS:
				return getDecimals();
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__BEGIN_RANGE:
				return getBeginRange();
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__END_RANGE:
				return getEndRange();
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__BEGIN_RANGE_REF:
				if (resolve) return getBeginRangeRef();
				return basicGetBeginRangeRef();
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__END_RANGE_REF:
				if (resolve) return getEndRangeRef();
				return basicGetEndRangeRef();
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_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_DOUBLE_RANGE__DECIMALS:
				setDecimals((Integer)newValue);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__BEGIN_RANGE:
				setBeginRange((Double)newValue);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__END_RANGE:
				setEndRange((Double)newValue);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__BEGIN_RANGE_REF:
				setBeginRangeRef((LEntityAttribute)newValue);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__END_RANGE_REF:
				setEndRangeRef((LEntityAttribute)newValue);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__ROUNDED:
				setRounded((Double)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_DOUBLE_RANGE__DECIMALS:
				setDecimals(DECIMALS_EDEFAULT);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__BEGIN_RANGE:
				setBeginRange(BEGIN_RANGE_EDEFAULT);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__END_RANGE:
				setEndRange(END_RANGE_EDEFAULT);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__BEGIN_RANGE_REF:
				setBeginRangeRef((LEntityAttribute)null);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__END_RANGE_REF:
				setEndRangeRef((LEntityAttribute)null);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_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_DOUBLE_RANGE__DECIMALS:
				return decimals != DECIMALS_EDEFAULT;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__BEGIN_RANGE:
				return beginRange != BEGIN_RANGE_EDEFAULT;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__END_RANGE:
				return endRange != END_RANGE_EDEFAULT;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__BEGIN_RANGE_REF:
				return beginRangeRef != null;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_RANGE__END_RANGE_REF:
				return endRangeRef != null;
			case EntityMockDSLPackage.PROPERTY_FILLER_SIGNED_DOUBLE_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(" (decimals: ");
		result.append(decimals);
		result.append(", beginRange: ");
		result.append(beginRange);
		result.append(", endRange: ");
		result.append(endRange);
		result.append(", rounded: ");
		result.append(rounded);
		result.append(')');
		return result.toString();
	}

} //PropertyFillerSignedDoubleRangeImpl
