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

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Property Filler Unsigned Double Range</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.PropertyFillerUnsignedDoubleRangeImpl#getDecimals <em>Decimals</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.PropertyFillerUnsignedDoubleRangeImpl#getBeginRange <em>Begin Range</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.PropertyFillerUnsignedDoubleRangeImpl#getEndRange <em>End Range</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.PropertyFillerUnsignedDoubleRangeImpl#getBeginRangeRef <em>Begin Range Ref</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.PropertyFillerUnsignedDoubleRangeImpl#getEndRangeRef <em>End Range Ref</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.PropertyFillerUnsignedDoubleRangeImpl#getRounded <em>Rounded</em>}</li>
 * </ul>
 *
 * @generated
 */
public class PropertyFillerUnsignedDoubleRangeImpl extends PropertyFillerDoubleTypeImpl implements PropertyFillerUnsignedDoubleRange {
	/**
	 * 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 PropertyFillerUnsignedDoubleRangeImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return EntityMockDSLPackage.Literals.PROPERTY_FILLER_UNSIGNED_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_UNSIGNED_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_UNSIGNED_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_UNSIGNED_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_UNSIGNED_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_UNSIGNED_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_UNSIGNED_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_UNSIGNED_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_UNSIGNED_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_UNSIGNED_DOUBLE_RANGE__DECIMALS:
				return getDecimals();
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE:
				return getBeginRange();
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE:
				return getEndRange();
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE_REF:
				if (resolve) return getBeginRangeRef();
				return basicGetBeginRangeRef();
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE_REF:
				if (resolve) return getEndRangeRef();
				return basicGetEndRangeRef();
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_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_UNSIGNED_DOUBLE_RANGE__DECIMALS:
				setDecimals((Integer)newValue);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE:
				setBeginRange((Double)newValue);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE:
				setEndRange((Double)newValue);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE_REF:
				setBeginRangeRef((LEntityAttribute)newValue);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE_REF:
				setEndRangeRef((LEntityAttribute)newValue);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_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_UNSIGNED_DOUBLE_RANGE__DECIMALS:
				setDecimals(DECIMALS_EDEFAULT);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE:
				setBeginRange(BEGIN_RANGE_EDEFAULT);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE:
				setEndRange(END_RANGE_EDEFAULT);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE_REF:
				setBeginRangeRef((LEntityAttribute)null);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE_REF:
				setEndRangeRef((LEntityAttribute)null);
				return;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_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_UNSIGNED_DOUBLE_RANGE__DECIMALS:
				return decimals != DECIMALS_EDEFAULT;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE:
				return beginRange != BEGIN_RANGE_EDEFAULT;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE:
				return endRange != END_RANGE_EDEFAULT;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE_REF:
				return beginRangeRef != null;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE_REF:
				return endRangeRef != null;
			case EntityMockDSLPackage.PROPERTY_FILLER_UNSIGNED_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();
	}

} //PropertyFillerUnsignedDoubleRangeImpl
