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

import java.util.Collection;

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

import org.eclipse.emf.common.util.EList;

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

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

import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;

import org.eclipse.osbp.xtext.chart.ChartDSLPackage;
import org.eclipse.osbp.xtext.chart.ChartGauge;
import org.eclipse.osbp.xtext.chart.ChartInterval;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Chart Gauge</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartGaugeImpl#isLabeled <em>Labeled</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartGaugeImpl#getLabelValue <em>Label Value</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartGaugeImpl#isHasTicks <em>Has Ticks</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartGaugeImpl#getMinValue <em>Min Value</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartGaugeImpl#getMaxValue <em>Max Value</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartGaugeImpl#isHasIntervals <em>Has Intervals</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartGaugeImpl#getIntervals <em>Intervals</em>}</li>
 * </ul>
 *
 * @generated
 */
public class ChartGaugeImpl extends ChartLazyResolverImpl implements ChartGauge {
	/**
	 * The default value of the '{@link #isLabeled() <em>Labeled</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isLabeled()
	 * @generated
	 * @ordered
	 */
	protected static final boolean LABELED_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isLabeled() <em>Labeled</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isLabeled()
	 * @generated
	 * @ordered
	 */
	protected boolean labeled = LABELED_EDEFAULT;

	/**
	 * The default value of the '{@link #getLabelValue() <em>Label Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLabelValue()
	 * @generated
	 * @ordered
	 */
	protected static final String LABEL_VALUE_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getLabelValue() <em>Label Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLabelValue()
	 * @generated
	 * @ordered
	 */
	protected String labelValue = LABEL_VALUE_EDEFAULT;

	/**
	 * The default value of the '{@link #isHasTicks() <em>Has Ticks</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHasTicks()
	 * @generated
	 * @ordered
	 */
	protected static final boolean HAS_TICKS_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isHasTicks() <em>Has Ticks</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHasTicks()
	 * @generated
	 * @ordered
	 */
	protected boolean hasTicks = HAS_TICKS_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getMinValue() <em>Min Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMinValue()
	 * @generated
	 * @ordered
	 */
	protected int minValue = MIN_VALUE_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getMaxValue() <em>Max Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMaxValue()
	 * @generated
	 * @ordered
	 */
	protected int maxValue = MAX_VALUE_EDEFAULT;

	/**
	 * The default value of the '{@link #isHasIntervals() <em>Has Intervals</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHasIntervals()
	 * @generated
	 * @ordered
	 */
	protected static final boolean HAS_INTERVALS_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isHasIntervals() <em>Has Intervals</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHasIntervals()
	 * @generated
	 * @ordered
	 */
	protected boolean hasIntervals = HAS_INTERVALS_EDEFAULT;

	/**
	 * The cached value of the '{@link #getIntervals() <em>Intervals</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIntervals()
	 * @generated
	 * @ordered
	 */
	protected EList<ChartInterval> intervals;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isLabeled() {
		return labeled;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setLabeled(boolean newLabeled) {
		boolean oldLabeled = labeled;
		labeled = newLabeled;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART_GAUGE__LABELED, oldLabeled, labeled));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String getLabelValue() {
		return labelValue;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setLabelValue(String newLabelValue) {
		String oldLabelValue = labelValue;
		labelValue = newLabelValue;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART_GAUGE__LABEL_VALUE, oldLabelValue, labelValue));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isHasTicks() {
		return hasTicks;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHasTicks(boolean newHasTicks) {
		boolean oldHasTicks = hasTicks;
		hasTicks = newHasTicks;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART_GAUGE__HAS_TICKS, oldHasTicks, hasTicks));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMinValue(int newMinValue) {
		int oldMinValue = minValue;
		minValue = newMinValue;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART_GAUGE__MIN_VALUE, oldMinValue, minValue));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMaxValue(int newMaxValue) {
		int oldMaxValue = maxValue;
		maxValue = newMaxValue;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART_GAUGE__MAX_VALUE, oldMaxValue, maxValue));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isHasIntervals() {
		return hasIntervals;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHasIntervals(boolean newHasIntervals) {
		boolean oldHasIntervals = hasIntervals;
		hasIntervals = newHasIntervals;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART_GAUGE__HAS_INTERVALS, oldHasIntervals, hasIntervals));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<ChartInterval> getIntervals() {
		if (intervals == null) {
			intervals = new EObjectContainmentEList<ChartInterval>(ChartInterval.class, this, ChartDSLPackage.CHART_GAUGE__INTERVALS);
		}
		return intervals;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ChartDSLPackage.CHART_GAUGE__INTERVALS:
				return ((InternalEList<?>)getIntervals()).basicRemove(otherEnd, 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_GAUGE__LABELED:
				return isLabeled();
			case ChartDSLPackage.CHART_GAUGE__LABEL_VALUE:
				return getLabelValue();
			case ChartDSLPackage.CHART_GAUGE__HAS_TICKS:
				return isHasTicks();
			case ChartDSLPackage.CHART_GAUGE__MIN_VALUE:
				return getMinValue();
			case ChartDSLPackage.CHART_GAUGE__MAX_VALUE:
				return getMaxValue();
			case ChartDSLPackage.CHART_GAUGE__HAS_INTERVALS:
				return isHasIntervals();
			case ChartDSLPackage.CHART_GAUGE__INTERVALS:
				return getIntervals();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case ChartDSLPackage.CHART_GAUGE__LABELED:
				setLabeled((Boolean)newValue);
				return;
			case ChartDSLPackage.CHART_GAUGE__LABEL_VALUE:
				setLabelValue((String)newValue);
				return;
			case ChartDSLPackage.CHART_GAUGE__HAS_TICKS:
				setHasTicks((Boolean)newValue);
				return;
			case ChartDSLPackage.CHART_GAUGE__MIN_VALUE:
				setMinValue((Integer)newValue);
				return;
			case ChartDSLPackage.CHART_GAUGE__MAX_VALUE:
				setMaxValue((Integer)newValue);
				return;
			case ChartDSLPackage.CHART_GAUGE__HAS_INTERVALS:
				setHasIntervals((Boolean)newValue);
				return;
			case ChartDSLPackage.CHART_GAUGE__INTERVALS:
				getIntervals().clear();
				getIntervals().addAll((Collection<? extends ChartInterval>)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ChartDSLPackage.CHART_GAUGE__LABELED:
				setLabeled(LABELED_EDEFAULT);
				return;
			case ChartDSLPackage.CHART_GAUGE__LABEL_VALUE:
				setLabelValue(LABEL_VALUE_EDEFAULT);
				return;
			case ChartDSLPackage.CHART_GAUGE__HAS_TICKS:
				setHasTicks(HAS_TICKS_EDEFAULT);
				return;
			case ChartDSLPackage.CHART_GAUGE__MIN_VALUE:
				setMinValue(MIN_VALUE_EDEFAULT);
				return;
			case ChartDSLPackage.CHART_GAUGE__MAX_VALUE:
				setMaxValue(MAX_VALUE_EDEFAULT);
				return;
			case ChartDSLPackage.CHART_GAUGE__HAS_INTERVALS:
				setHasIntervals(HAS_INTERVALS_EDEFAULT);
				return;
			case ChartDSLPackage.CHART_GAUGE__INTERVALS:
				getIntervals().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ChartDSLPackage.CHART_GAUGE__LABELED:
				return labeled != LABELED_EDEFAULT;
			case ChartDSLPackage.CHART_GAUGE__LABEL_VALUE:
				return LABEL_VALUE_EDEFAULT == null ? labelValue != null : !LABEL_VALUE_EDEFAULT.equals(labelValue);
			case ChartDSLPackage.CHART_GAUGE__HAS_TICKS:
				return hasTicks != HAS_TICKS_EDEFAULT;
			case ChartDSLPackage.CHART_GAUGE__MIN_VALUE:
				return minValue != MIN_VALUE_EDEFAULT;
			case ChartDSLPackage.CHART_GAUGE__MAX_VALUE:
				return maxValue != MAX_VALUE_EDEFAULT;
			case ChartDSLPackage.CHART_GAUGE__HAS_INTERVALS:
				return hasIntervals != HAS_INTERVALS_EDEFAULT;
			case ChartDSLPackage.CHART_GAUGE__INTERVALS:
				return intervals != null && !intervals.isEmpty();
		}
		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(" (labeled: ");
		result.append(labeled);
		result.append(", labelValue: ");
		result.append(labelValue);
		result.append(", hasTicks: ");
		result.append(hasTicks);
		result.append(", minValue: ");
		result.append(minValue);
		result.append(", maxValue: ");
		result.append(maxValue);
		result.append(", hasIntervals: ");
		result.append(hasIntervals);
		result.append(')');
		return result.toString();
	}

} //ChartGaugeImpl
