/**
 * 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 2.0  
 *  which accompanies this distribution, and is available at 
 *  https://www.eclipse.org/legal/epl-2.0/ 
 *  
 *  SPDX-License-Identifier: EPL-2.0 
 * 
 *  Based on ideas from Xtext, Xtend, Xcore
 *   
 *  Contributors:  
 *  		Joerg Riegel - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.chart.impl;

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

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

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

import org.eclipse.osbp.xtext.action.ActionToolbar;

import org.eclipse.osbp.xtext.chart.Chart;
import org.eclipse.osbp.xtext.chart.ChartDSLPackage;
import org.eclipse.osbp.xtext.chart.ChartDatamart;
import org.eclipse.osbp.xtext.chart.ChartOption;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Chart</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartImpl#isSelectById <em>Select By Id</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartImpl#isDescription <em>Description</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartImpl#getDescriptionValue <em>Description Value</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartImpl#getCharttype <em>Charttype</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartImpl#getSource <em>Source</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.chart.impl.ChartImpl#getToolbar <em>Toolbar</em>}</li>
 * </ul>
 *
 * @generated
 */
public class ChartImpl extends ChartBaseImpl implements Chart {
	/**
	 * The default value of the '{@link #isSelectById() <em>Select By Id</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isSelectById()
	 * @generated
	 * @ordered
	 */
	protected static final boolean SELECT_BY_ID_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isSelectById() <em>Select By Id</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isSelectById()
	 * @generated
	 * @ordered
	 */
	protected boolean selectById = SELECT_BY_ID_EDEFAULT;

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

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

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

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

	/**
	 * The cached value of the '{@link #getCharttype() <em>Charttype</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCharttype()
	 * @generated
	 * @ordered
	 */
	protected ChartOption charttype;

	/**
	 * The cached value of the '{@link #getSource() <em>Source</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSource()
	 * @generated
	 * @ordered
	 */
	protected ChartDatamart source;

	/**
	 * The cached value of the '{@link #getToolbar() <em>Toolbar</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getToolbar()
	 * @generated
	 * @ordered
	 */
	protected ActionToolbar toolbar;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setSelectById(boolean newSelectById) {
		boolean oldSelectById = selectById;
		selectById = newSelectById;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART__SELECT_BY_ID, oldSelectById, selectById));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDescription(boolean newDescription) {
		boolean oldDescription = description;
		description = newDescription;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART__DESCRIPTION, oldDescription, description));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDescriptionValue(String newDescriptionValue) {
		String oldDescriptionValue = descriptionValue;
		descriptionValue = newDescriptionValue;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART__DESCRIPTION_VALUE, oldDescriptionValue, descriptionValue));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ChartOption getCharttype() {
		return charttype;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetCharttype(ChartOption newCharttype, NotificationChain msgs) {
		ChartOption oldCharttype = charttype;
		charttype = newCharttype;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART__CHARTTYPE, oldCharttype, newCharttype);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setCharttype(ChartOption newCharttype) {
		if (newCharttype != charttype) {
			NotificationChain msgs = null;
			if (charttype != null)
				msgs = ((InternalEObject)charttype).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ChartDSLPackage.CHART__CHARTTYPE, null, msgs);
			if (newCharttype != null)
				msgs = ((InternalEObject)newCharttype).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ChartDSLPackage.CHART__CHARTTYPE, null, msgs);
			msgs = basicSetCharttype(newCharttype, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART__CHARTTYPE, newCharttype, newCharttype));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ChartDatamart getSource() {
		return source;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetSource(ChartDatamart newSource, NotificationChain msgs) {
		ChartDatamart oldSource = source;
		source = newSource;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART__SOURCE, oldSource, newSource);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setSource(ChartDatamart newSource) {
		if (newSource != source) {
			NotificationChain msgs = null;
			if (source != null)
				msgs = ((InternalEObject)source).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ChartDSLPackage.CHART__SOURCE, null, msgs);
			if (newSource != null)
				msgs = ((InternalEObject)newSource).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ChartDSLPackage.CHART__SOURCE, null, msgs);
			msgs = basicSetSource(newSource, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART__SOURCE, newSource, newSource));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ActionToolbar getToolbar() {
		if (toolbar != null && toolbar.eIsProxy()) {
			InternalEObject oldToolbar = (InternalEObject)toolbar;
			toolbar = (ActionToolbar)eResolveProxy(oldToolbar);
			if (toolbar != oldToolbar) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ChartDSLPackage.CHART__TOOLBAR, oldToolbar, toolbar));
			}
		}
		return toolbar;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ActionToolbar basicGetToolbar() {
		return toolbar;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setToolbar(ActionToolbar newToolbar) {
		ActionToolbar oldToolbar = toolbar;
		toolbar = newToolbar;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ChartDSLPackage.CHART__TOOLBAR, oldToolbar, toolbar));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ChartDSLPackage.CHART__CHARTTYPE:
				return basicSetCharttype(null, msgs);
			case ChartDSLPackage.CHART__SOURCE:
				return basicSetSource(null, 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__SELECT_BY_ID:
				return isSelectById();
			case ChartDSLPackage.CHART__DESCRIPTION:
				return isDescription();
			case ChartDSLPackage.CHART__DESCRIPTION_VALUE:
				return getDescriptionValue();
			case ChartDSLPackage.CHART__CHARTTYPE:
				return getCharttype();
			case ChartDSLPackage.CHART__SOURCE:
				return getSource();
			case ChartDSLPackage.CHART__TOOLBAR:
				if (resolve) return getToolbar();
				return basicGetToolbar();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case ChartDSLPackage.CHART__SELECT_BY_ID:
				setSelectById((Boolean)newValue);
				return;
			case ChartDSLPackage.CHART__DESCRIPTION:
				setDescription((Boolean)newValue);
				return;
			case ChartDSLPackage.CHART__DESCRIPTION_VALUE:
				setDescriptionValue((String)newValue);
				return;
			case ChartDSLPackage.CHART__CHARTTYPE:
				setCharttype((ChartOption)newValue);
				return;
			case ChartDSLPackage.CHART__SOURCE:
				setSource((ChartDatamart)newValue);
				return;
			case ChartDSLPackage.CHART__TOOLBAR:
				setToolbar((ActionToolbar)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ChartDSLPackage.CHART__SELECT_BY_ID:
				setSelectById(SELECT_BY_ID_EDEFAULT);
				return;
			case ChartDSLPackage.CHART__DESCRIPTION:
				setDescription(DESCRIPTION_EDEFAULT);
				return;
			case ChartDSLPackage.CHART__DESCRIPTION_VALUE:
				setDescriptionValue(DESCRIPTION_VALUE_EDEFAULT);
				return;
			case ChartDSLPackage.CHART__CHARTTYPE:
				setCharttype((ChartOption)null);
				return;
			case ChartDSLPackage.CHART__SOURCE:
				setSource((ChartDatamart)null);
				return;
			case ChartDSLPackage.CHART__TOOLBAR:
				setToolbar((ActionToolbar)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ChartDSLPackage.CHART__SELECT_BY_ID:
				return selectById != SELECT_BY_ID_EDEFAULT;
			case ChartDSLPackage.CHART__DESCRIPTION:
				return description != DESCRIPTION_EDEFAULT;
			case ChartDSLPackage.CHART__DESCRIPTION_VALUE:
				return DESCRIPTION_VALUE_EDEFAULT == null ? descriptionValue != null : !DESCRIPTION_VALUE_EDEFAULT.equals(descriptionValue);
			case ChartDSLPackage.CHART__CHARTTYPE:
				return charttype != null;
			case ChartDSLPackage.CHART__SOURCE:
				return source != null;
			case ChartDSLPackage.CHART__TOOLBAR:
				return toolbar != null;
		}
		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(" (selectById: ");
		result.append(selectById);
		result.append(", description: ");
		result.append(description);
		result.append(", descriptionValue: ");
		result.append(descriptionValue);
		result.append(')');
		return result.toString();
	}

} //ChartImpl
