/*=============================================================================#
 # Copyright (c) 2012, 2021 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.GeomTextLayer;
import org.eclipse.statet.rtm.ggplot.PropAlphaProvider;
import org.eclipse.statet.rtm.ggplot.PropColorProvider;
import org.eclipse.statet.rtm.ggplot.PropSizeProvider;
import org.eclipse.statet.rtm.ggplot.TextStyle;
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 Text Layer</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.statet.rtm.ggplot.impl.GeomTextLayerImpl#getSize <em>Size</em>}</li>
 *   <li>{@link org.eclipse.statet.rtm.ggplot.impl.GeomTextLayerImpl#getColor <em>Color</em>}</li>
 *   <li>{@link org.eclipse.statet.rtm.ggplot.impl.GeomTextLayerImpl#getFontFamily <em>Font Family</em>}</li>
 *   <li>{@link org.eclipse.statet.rtm.ggplot.impl.GeomTextLayerImpl#getFontFace <em>Font Face</em>}</li>
 *   <li>{@link org.eclipse.statet.rtm.ggplot.impl.GeomTextLayerImpl#getHJust <em>HJust</em>}</li>
 *   <li>{@link org.eclipse.statet.rtm.ggplot.impl.GeomTextLayerImpl#getVJust <em>VJust</em>}</li>
 *   <li>{@link org.eclipse.statet.rtm.ggplot.impl.GeomTextLayerImpl#getAngle <em>Angle</em>}</li>
 *   <li>{@link org.eclipse.statet.rtm.ggplot.impl.GeomTextLayerImpl#getAlpha <em>Alpha</em>}</li>
 *   <li>{@link org.eclipse.statet.rtm.ggplot.impl.GeomTextLayerImpl#getLabel <em>Label</em>}</li>
 * </ul>
 * </p>
 * 
 * @generated
 */
public class GeomTextLayerImpl extends XYVarLayerImpl implements GeomTextLayer {
	/**
	 * The default value of the '{@link #getSize() <em>Size</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSize()
	 * @generated
	 * @ordered
	 */
	protected static final RTypedExpr SIZE_EDEFAULT= null;

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

	/**
	 * 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(), "");

	/**
	 * 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 #getFontFamily() <em>Font Family</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFontFamily()
	 * @generated
	 * @ordered
	 */
	protected static final RTypedExpr FONT_FAMILY_EDEFAULT= null;

	/**
	 * The cached value of the '{@link #getFontFamily() <em>Font Family</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFontFamily()
	 * @generated
	 * @ordered
	 */
	protected RTypedExpr fontFamily= FONT_FAMILY_EDEFAULT;

	/**
	 * The default value of the '{@link #getFontFace() <em>Font Face</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFontFace()
	 * @generated
	 * @ordered
	 */
	protected static final RTypedExpr FONT_FACE_EDEFAULT= null;

	/**
	 * The cached value of the '{@link #getFontFace() <em>Font Face</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFontFace()
	 * @generated
	 * @ordered
	 */
	protected RTypedExpr fontFace= FONT_FACE_EDEFAULT;

	/**
	 * The default value of the '{@link #getHJust() <em>HJust</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getHJust()
	 * @generated
	 * @ordered
	 */
	protected static final RTypedExpr HJUST_EDEFAULT= null;

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

	/**
	 * The default value of the '{@link #getVJust() <em>VJust</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getVJust()
	 * @generated
	 * @ordered
	 */
	protected static final RTypedExpr VJUST_EDEFAULT= null;

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

	/**
	 * The default value of the '{@link #getAngle() <em>Angle</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAngle()
	 * @generated
	 * @ordered
	 */
	protected static final RTypedExpr ANGLE_EDEFAULT= null;

	/**
	 * The cached value of the '{@link #getAngle() <em>Angle</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAngle()
	 * @generated
	 * @ordered
	 */
	protected RTypedExpr angle= ANGLE_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;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return GGPlotPackage.Literals.GEOM_TEXT_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_TEXT_LAYER__COLOR, oldColor, this.color));
		}
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setFontFamily(final RTypedExpr newFontFamily) {
		final RTypedExpr oldFontFamily= this.fontFamily;
		this.fontFamily= newFontFamily;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, GGPlotPackage.GEOM_TEXT_LAYER__FONT_FAMILY, oldFontFamily, this.fontFamily));
		}
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setFontFace(final RTypedExpr newFontFace) {
		final RTypedExpr oldFontFace= this.fontFace;
		this.fontFace= newFontFace;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, GGPlotPackage.GEOM_TEXT_LAYER__FONT_FACE, oldFontFace, this.fontFace));
		}
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setHJust(final RTypedExpr newHJust) {
		final RTypedExpr oldHJust= this.hJust;
		this.hJust= newHJust;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, GGPlotPackage.GEOM_TEXT_LAYER__HJUST, oldHJust, this.hJust));
		}
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setVJust(final RTypedExpr newVJust) {
		final RTypedExpr oldVJust= this.vJust;
		this.vJust= newVJust;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, GGPlotPackage.GEOM_TEXT_LAYER__VJUST, oldVJust, this.vJust));
		}
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setAngle(final RTypedExpr newAngle) {
		final RTypedExpr oldAngle= this.angle;
		this.angle= newAngle;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, GGPlotPackage.GEOM_TEXT_LAYER__ANGLE, oldAngle, this.angle));
		}
	}

	/**
	 * <!-- 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_TEXT_LAYER__ALPHA, oldAlpha, this.alpha));
		}
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setLabel(final RTypedExpr newLabel) {
		final RTypedExpr oldLabel= this.label;
		this.label= newLabel;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, GGPlotPackage.GEOM_TEXT_LAYER__LABEL, oldLabel, this.label));
		}
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setSize(final RTypedExpr newSize) {
		final RTypedExpr oldSize= this.size;
		this.size= newSize;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, GGPlotPackage.GEOM_TEXT_LAYER__SIZE, oldSize, this.size));
		}
	}

	/**
	 * <!-- 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_TEXT_LAYER__SIZE:
				return getSize();
			case GGPlotPackage.GEOM_TEXT_LAYER__COLOR:
				return getColor();
			case GGPlotPackage.GEOM_TEXT_LAYER__FONT_FAMILY:
				return getFontFamily();
			case GGPlotPackage.GEOM_TEXT_LAYER__FONT_FACE:
				return getFontFace();
			case GGPlotPackage.GEOM_TEXT_LAYER__HJUST:
				return getHJust();
			case GGPlotPackage.GEOM_TEXT_LAYER__VJUST:
				return getVJust();
			case GGPlotPackage.GEOM_TEXT_LAYER__ANGLE:
				return getAngle();
			case GGPlotPackage.GEOM_TEXT_LAYER__ALPHA:
				return getAlpha();
			case GGPlotPackage.GEOM_TEXT_LAYER__LABEL:
				return getLabel();
		}
		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_TEXT_LAYER__SIZE:
				setSize((RTypedExpr)newValue);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__COLOR:
				setColor((RTypedExpr)newValue);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__FONT_FAMILY:
				setFontFamily((RTypedExpr)newValue);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__FONT_FACE:
				setFontFace((RTypedExpr)newValue);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__HJUST:
				setHJust((RTypedExpr)newValue);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__VJUST:
				setVJust((RTypedExpr)newValue);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__ANGLE:
				setAngle((RTypedExpr)newValue);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__ALPHA:
				setAlpha((RTypedExpr)newValue);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__LABEL:
				setLabel((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_TEXT_LAYER__SIZE:
				setSize(SIZE_EDEFAULT);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__COLOR:
				setColor(COLOR_EDEFAULT);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__FONT_FAMILY:
				setFontFamily(FONT_FAMILY_EDEFAULT);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__FONT_FACE:
				setFontFace(FONT_FACE_EDEFAULT);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__HJUST:
				setHJust(HJUST_EDEFAULT);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__VJUST:
				setVJust(VJUST_EDEFAULT);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__ANGLE:
				setAngle(ANGLE_EDEFAULT);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__ALPHA:
				setAlpha(ALPHA_EDEFAULT);
				return;
			case GGPlotPackage.GEOM_TEXT_LAYER__LABEL:
				setLabel(LABEL_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(final int featureID) {
		switch (featureID) {
			case GGPlotPackage.GEOM_TEXT_LAYER__SIZE:
				return SIZE_EDEFAULT == null ? this.size != null : !SIZE_EDEFAULT.equals(this.size);
			case GGPlotPackage.GEOM_TEXT_LAYER__COLOR:
				return COLOR_EDEFAULT == null ? this.color != null : !COLOR_EDEFAULT.equals(this.color);
			case GGPlotPackage.GEOM_TEXT_LAYER__FONT_FAMILY:
				return FONT_FAMILY_EDEFAULT == null ? this.fontFamily != null : !FONT_FAMILY_EDEFAULT.equals(this.fontFamily);
			case GGPlotPackage.GEOM_TEXT_LAYER__FONT_FACE:
				return FONT_FACE_EDEFAULT == null ? this.fontFace != null : !FONT_FACE_EDEFAULT.equals(this.fontFace);
			case GGPlotPackage.GEOM_TEXT_LAYER__HJUST:
				return HJUST_EDEFAULT == null ? this.hJust != null : !HJUST_EDEFAULT.equals(this.hJust);
			case GGPlotPackage.GEOM_TEXT_LAYER__VJUST:
				return VJUST_EDEFAULT == null ? this.vJust != null : !VJUST_EDEFAULT.equals(this.vJust);
			case GGPlotPackage.GEOM_TEXT_LAYER__ANGLE:
				return ANGLE_EDEFAULT == null ? this.angle != null : !ANGLE_EDEFAULT.equals(this.angle);
			case GGPlotPackage.GEOM_TEXT_LAYER__ALPHA:
				return ALPHA_EDEFAULT == null ? this.alpha != null : !ALPHA_EDEFAULT.equals(this.alpha);
			case GGPlotPackage.GEOM_TEXT_LAYER__LABEL:
				return LABEL_EDEFAULT == null ? this.label != null : !LABEL_EDEFAULT.equals(this.label);
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eBaseStructuralFeatureID(final int derivedFeatureID, final Class<?> baseClass) {
		if (baseClass == PropSizeProvider.class) {
			switch (derivedFeatureID) {
				case GGPlotPackage.GEOM_TEXT_LAYER__SIZE: return GGPlotPackage.PROP_SIZE_PROVIDER__SIZE;
				default: return -1;
			}
		}
		if (baseClass == PropColorProvider.class) {
			switch (derivedFeatureID) {
				case GGPlotPackage.GEOM_TEXT_LAYER__COLOR: return GGPlotPackage.PROP_COLOR_PROVIDER__COLOR;
				default: return -1;
			}
		}
		if (baseClass == TextStyle.class) {
			switch (derivedFeatureID) {
				case GGPlotPackage.GEOM_TEXT_LAYER__FONT_FAMILY: return GGPlotPackage.TEXT_STYLE__FONT_FAMILY;
				case GGPlotPackage.GEOM_TEXT_LAYER__FONT_FACE: return GGPlotPackage.TEXT_STYLE__FONT_FACE;
				case GGPlotPackage.GEOM_TEXT_LAYER__HJUST: return GGPlotPackage.TEXT_STYLE__HJUST;
				case GGPlotPackage.GEOM_TEXT_LAYER__VJUST: return GGPlotPackage.TEXT_STYLE__VJUST;
				case GGPlotPackage.GEOM_TEXT_LAYER__ANGLE: return GGPlotPackage.TEXT_STYLE__ANGLE;
				default: return -1;
			}
		}
		if (baseClass == PropAlphaProvider.class) {
			switch (derivedFeatureID) {
				case GGPlotPackage.GEOM_TEXT_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 == PropSizeProvider.class) {
			switch (baseFeatureID) {
				case GGPlotPackage.PROP_SIZE_PROVIDER__SIZE: return GGPlotPackage.GEOM_TEXT_LAYER__SIZE;
				default: return -1;
			}
		}
		if (baseClass == PropColorProvider.class) {
			switch (baseFeatureID) {
				case GGPlotPackage.PROP_COLOR_PROVIDER__COLOR: return GGPlotPackage.GEOM_TEXT_LAYER__COLOR;
				default: return -1;
			}
		}
		if (baseClass == TextStyle.class) {
			switch (baseFeatureID) {
				case GGPlotPackage.TEXT_STYLE__FONT_FAMILY: return GGPlotPackage.GEOM_TEXT_LAYER__FONT_FAMILY;
				case GGPlotPackage.TEXT_STYLE__FONT_FACE: return GGPlotPackage.GEOM_TEXT_LAYER__FONT_FACE;
				case GGPlotPackage.TEXT_STYLE__HJUST: return GGPlotPackage.GEOM_TEXT_LAYER__HJUST;
				case GGPlotPackage.TEXT_STYLE__VJUST: return GGPlotPackage.GEOM_TEXT_LAYER__VJUST;
				case GGPlotPackage.TEXT_STYLE__ANGLE: return GGPlotPackage.GEOM_TEXT_LAYER__ANGLE;
				default: return -1;
			}
		}
		if (baseClass == PropAlphaProvider.class) {
			switch (baseFeatureID) {
				case GGPlotPackage.PROP_ALPHA_PROVIDER__ALPHA: return GGPlotPackage.GEOM_TEXT_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(" (size: "); //$NON-NLS-1$
		result.append(this.size);
		result.append(", color: "); //$NON-NLS-1$
		result.append(this.color);
		result.append(", fontFamily: "); //$NON-NLS-1$
		result.append(this.fontFamily);
		result.append(", fontFace: "); //$NON-NLS-1$
		result.append(this.fontFace);
		result.append(", hJust: "); //$NON-NLS-1$
		result.append(this.hJust);
		result.append(", vJust: "); //$NON-NLS-1$
		result.append(this.vJust);
		result.append(", angle: "); //$NON-NLS-1$
		result.append(this.angle);
		result.append(", alpha: "); //$NON-NLS-1$
		result.append(this.alpha);
		result.append(", label: "); //$NON-NLS-1$
		result.append(this.label);
		result.append(')');
		return result.toString();
	}

} //GeomTextLayerImpl
