/*=============================================================================#
 # Copyright (c) 2012, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.rtm.ggplot.impl;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.impl.ENotificationImpl;

import org.eclipse.statet.rtm.ggplot.GGPlotPackage;
import org.eclipse.statet.rtm.ggplot.GeomBoxplotLayer;
import org.eclipse.statet.rtm.ggplot.PropAlphaProvider;
import org.eclipse.statet.rtm.ggplot.PropColorProvider;
import org.eclipse.statet.rtm.ggplot.PropFillProvider;
import org.eclipse.statet.rtm.rtdata.RtDataFactory;
import org.eclipse.statet.rtm.rtdata.RtDataPackage;
import org.eclipse.statet.rtm.rtdata.types.RTypedExpr;


/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Geom Boxplot Layer</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.statet.rtm.ggplot.impl.GeomBoxplotLayerImpl#getColor <em>Color</em>}</li>
 *   <li>{@link org.eclipse.statet.rtm.ggplot.impl.GeomBoxplotLayerImpl#getFill <em>Fill</em>}</li>
 *   <li>{@link org.eclipse.statet.rtm.ggplot.impl.GeomBoxplotLayerImpl#getAlpha <em>Alpha</em>}</li>
 * </ul>
 * </p>
 * 
 * @generated
 */
public class GeomBoxplotLayerImpl extends XVarLayerImpl implements GeomBoxplotLayer {
	/**
	 * The default value of the '{@link #getColor() <em>Color</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getColor()
	 * @generated
	 * @ordered
	 */
	protected static final RTypedExpr COLOR_EDEFAULT= (RTypedExpr)RtDataFactory.eINSTANCE.createFromString(RtDataPackage.eINSTANCE.getRColor(), ""); //$NON-NLS-1$

	/**
	 * The cached value of the '{@link #getColor() <em>Color</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getColor()
	 * @generated
	 * @ordered
	 */
	protected RTypedExpr color= COLOR_EDEFAULT;

	/**
	 * The default value of the '{@link #getFill() <em>Fill</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFill()
	 * @generated
	 * @ordered
	 */
	protected static final RTypedExpr FILL_EDEFAULT= (RTypedExpr)RtDataFactory.eINSTANCE.createFromString(RtDataPackage.eINSTANCE.getRColor(), "");

	/**
	 * The cached value of the '{@link #getFill() <em>Fill</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFill()
	 * @generated
	 * @ordered
	 */
	protected RTypedExpr fill= FILL_EDEFAULT;

	/**
	 * The default value of the '{@link #getAlpha() <em>Alpha</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAlpha()
	 * @generated
	 * @ordered
	 */
	protected static final RTypedExpr ALPHA_EDEFAULT= (RTypedExpr)RtDataFactory.eINSTANCE.createFromString(RtDataPackage.eINSTANCE.getRAlpha(), ""); //$NON-NLS-1$

	/**
	 * The cached value of the '{@link #getAlpha() <em>Alpha</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAlpha()
	 * @generated
	 * @ordered
	 */
	protected RTypedExpr alpha= ALPHA_EDEFAULT;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public RTypedExpr getColor() {
		return this.color;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setColor(final RTypedExpr newColor) {
		final RTypedExpr oldColor= this.color;
		this.color= newColor;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, GGPlotPackage.GEOM_BOXPLOT_LAYER__COLOR, oldColor, this.color));
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public RTypedExpr getFill() {
		return this.fill;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setFill(final RTypedExpr newFill) {
		final RTypedExpr oldFill= this.fill;
		this.fill= newFill;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, GGPlotPackage.GEOM_BOXPLOT_LAYER__FILL, oldFill, this.fill));
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public RTypedExpr getAlpha() {
		return this.alpha;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setAlpha(final RTypedExpr newAlpha) {
		final RTypedExpr oldAlpha= this.alpha;
		this.alpha= newAlpha;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, GGPlotPackage.GEOM_BOXPLOT_LAYER__ALPHA, oldAlpha, this.alpha));
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(final int featureID, final boolean resolve, final boolean coreType) {
		switch (featureID) {
			case GGPlotPackage.GEOM_BOXPLOT_LAYER__COLOR:
				return getColor();
			case GGPlotPackage.GEOM_BOXPLOT_LAYER__FILL:
				return getFill();
			case GGPlotPackage.GEOM_BOXPLOT_LAYER__ALPHA:
				return getAlpha();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(final int featureID, final Object newValue) {
		switch (featureID) {
			case GGPlotPackage.GEOM_BOXPLOT_LAYER__COLOR:
				setColor((RTypedExpr)newValue);
				return;
			case GGPlotPackage.GEOM_BOXPLOT_LAYER__FILL:
				setFill((RTypedExpr)newValue);
				return;
			case GGPlotPackage.GEOM_BOXPLOT_LAYER__ALPHA:
				setAlpha((RTypedExpr)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(final int featureID) {
		switch (featureID) {
			case GGPlotPackage.GEOM_BOXPLOT_LAYER__COLOR:
				setColor(COLOR_EDEFAULT);
				return;
			case GGPlotPackage.GEOM_BOXPLOT_LAYER__FILL:
				setFill(FILL_EDEFAULT);
				return;
			case GGPlotPackage.GEOM_BOXPLOT_LAYER__ALPHA:
				setAlpha(ALPHA_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(final int featureID) {
		switch (featureID) {
			case GGPlotPackage.GEOM_BOXPLOT_LAYER__COLOR:
				return COLOR_EDEFAULT == null ? this.color != null : !COLOR_EDEFAULT.equals(this.color);
			case GGPlotPackage.GEOM_BOXPLOT_LAYER__FILL:
				return FILL_EDEFAULT == null ? this.fill != null : !FILL_EDEFAULT.equals(this.fill);
			case GGPlotPackage.GEOM_BOXPLOT_LAYER__ALPHA:
				return ALPHA_EDEFAULT == null ? this.alpha != null : !ALPHA_EDEFAULT.equals(this.alpha);
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eBaseStructuralFeatureID(final int derivedFeatureID, final Class<?> baseClass) {
		if (baseClass == PropColorProvider.class) {
			switch (derivedFeatureID) {
				case GGPlotPackage.GEOM_BOXPLOT_LAYER__COLOR: return GGPlotPackage.PROP_COLOR_PROVIDER__COLOR;
				default: return -1;
			}
		}
		if (baseClass == PropFillProvider.class) {
			switch (derivedFeatureID) {
				case GGPlotPackage.GEOM_BOXPLOT_LAYER__FILL: return GGPlotPackage.PROP_FILL_PROVIDER__FILL;
				default: return -1;
			}
		}
		if (baseClass == PropAlphaProvider.class) {
			switch (derivedFeatureID) {
				case GGPlotPackage.GEOM_BOXPLOT_LAYER__ALPHA: return GGPlotPackage.PROP_ALPHA_PROVIDER__ALPHA;
				default: return -1;
			}
		}
		return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eDerivedStructuralFeatureID(final int baseFeatureID, final Class<?> baseClass) {
		if (baseClass == PropColorProvider.class) {
			switch (baseFeatureID) {
				case GGPlotPackage.PROP_COLOR_PROVIDER__COLOR: return GGPlotPackage.GEOM_BOXPLOT_LAYER__COLOR;
				default: return -1;
			}
		}
		if (baseClass == PropFillProvider.class) {
			switch (baseFeatureID) {
				case GGPlotPackage.PROP_FILL_PROVIDER__FILL: return GGPlotPackage.GEOM_BOXPLOT_LAYER__FILL;
				default: return -1;
			}
		}
		if (baseClass == PropAlphaProvider.class) {
			switch (baseFeatureID) {
				case GGPlotPackage.PROP_ALPHA_PROVIDER__ALPHA: return GGPlotPackage.GEOM_BOXPLOT_LAYER__ALPHA;
				default: return -1;
			}
		}
		return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) {
			return super.toString();
		}

		final StringBuffer result= new StringBuffer(super.toString());
		result.append(" (color: "); //$NON-NLS-1$
		result.append(this.color);
		result.append(", fill: "); //$NON-NLS-1$
		result.append(this.fill);
		result.append(", alpha: "); //$NON-NLS-1$
		result.append(this.alpha);
		result.append(')');
		return result.toString();
	}

} //GeomBoxplotLayerImpl
