/**
 * 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:  
 *  		Joerg Riegel - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.datamartdsl.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.datamartdsl.AttributeFillerUnsignedDoubleRange;
import org.eclipse.osbp.xtext.datamartdsl.DatamartDSLPackage;

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return DatamartDSLPackage.Literals.ATTRIBUTE_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, DatamartDSLPackage.ATTRIBUTE_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, DatamartDSLPackage.ATTRIBUTE_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, DatamartDSLPackage.ATTRIBUTE_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, DatamartDSLPackage.ATTRIBUTE_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, DatamartDSLPackage.ATTRIBUTE_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, DatamartDSLPackage.ATTRIBUTE_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, DatamartDSLPackage.ATTRIBUTE_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, DatamartDSLPackage.ATTRIBUTE_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 DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__DECIMALS:
				return getDecimals();
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE:
				return getBeginRange();
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE:
				return getEndRange();
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE_REF:
				if (resolve) return getBeginRangeRef();
				return basicGetBeginRangeRef();
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE_REF:
				if (resolve) return getEndRangeRef();
				return basicGetEndRangeRef();
			case DatamartDSLPackage.ATTRIBUTE_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 DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__DECIMALS:
				setDecimals((Integer)newValue);
				return;
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE:
				setBeginRange((Double)newValue);
				return;
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE:
				setEndRange((Double)newValue);
				return;
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE_REF:
				setBeginRangeRef((LEntityAttribute)newValue);
				return;
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE_REF:
				setEndRangeRef((LEntityAttribute)newValue);
				return;
			case DatamartDSLPackage.ATTRIBUTE_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 DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__DECIMALS:
				setDecimals(DECIMALS_EDEFAULT);
				return;
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE:
				setBeginRange(BEGIN_RANGE_EDEFAULT);
				return;
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE:
				setEndRange(END_RANGE_EDEFAULT);
				return;
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE_REF:
				setBeginRangeRef((LEntityAttribute)null);
				return;
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE_REF:
				setEndRangeRef((LEntityAttribute)null);
				return;
			case DatamartDSLPackage.ATTRIBUTE_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 DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__DECIMALS:
				return decimals != DECIMALS_EDEFAULT;
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE:
				return beginRange != BEGIN_RANGE_EDEFAULT;
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE:
				return endRange != END_RANGE_EDEFAULT;
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__BEGIN_RANGE_REF:
				return beginRangeRef != null;
			case DatamartDSLPackage.ATTRIBUTE_FILLER_UNSIGNED_DOUBLE_RANGE__END_RANGE_REF:
				return endRangeRef != null;
			case DatamartDSLPackage.ATTRIBUTE_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();
	}

} //AttributeFillerUnsignedDoubleRangeImpl
