/*=============================================================================#
 # Copyright (c) 2012, 2019 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 java.util.Collection;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.EObjectImpl;
import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;

import org.eclipse.statet.rtm.ggplot.GGPlotPackage;
import org.eclipse.statet.rtm.ggplot.WrapFacetLayout;
import org.eclipse.statet.rtm.rtdata.types.RTypedExpr;


/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Wrap Facet Layout</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.statet.rtm.ggplot.impl.WrapFacetLayoutImpl#getColVars <em>Col Vars</em>}</li>
 *   <li>{@link org.eclipse.statet.rtm.ggplot.impl.WrapFacetLayoutImpl#getColNum <em>Col Num</em>}</li>
 * </ul>
 * </p>
 * 
 * @generated
 */
public class WrapFacetLayoutImpl extends EObjectImpl implements WrapFacetLayout {
	/**
	 * The cached value of the '{@link #getColVars() <em>Col Vars</em>}' attribute list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getColVars()
	 * @generated
	 * @ordered
	 */
	protected EList<RTypedExpr> colVars;

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

	/**
	 * The cached value of the '{@link #getColNum() <em>Col Num</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getColNum()
	 * @generated
	 * @ordered
	 */
	protected RTypedExpr colNum= COL_NUM_EDEFAULT;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<RTypedExpr> getColVars() {
		if (this.colVars == null) {
			this.colVars= new EDataTypeUniqueEList<>(RTypedExpr.class, this, GGPlotPackage.WRAP_FACET_LAYOUT__COL_VARS);
		}
		return this.colVars;
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setColNum(final RTypedExpr newColNum) {
		final RTypedExpr oldColNum= this.colNum;
		this.colNum= newColNum;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, GGPlotPackage.WRAP_FACET_LAYOUT__COL_NUM, oldColNum, this.colNum));
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(final int featureID, final boolean resolve, final boolean coreType) {
		switch (featureID) {
			case GGPlotPackage.WRAP_FACET_LAYOUT__COL_VARS:
				return getColVars();
			case GGPlotPackage.WRAP_FACET_LAYOUT__COL_NUM:
				return getColNum();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(final int featureID, final Object newValue) {
		switch (featureID) {
			case GGPlotPackage.WRAP_FACET_LAYOUT__COL_VARS:
				getColVars().clear();
				getColVars().addAll((Collection<? extends RTypedExpr>)newValue);
				return;
			case GGPlotPackage.WRAP_FACET_LAYOUT__COL_NUM:
				setColNum((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.WRAP_FACET_LAYOUT__COL_VARS:
				getColVars().clear();
				return;
			case GGPlotPackage.WRAP_FACET_LAYOUT__COL_NUM:
				setColNum(COL_NUM_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(final int featureID) {
		switch (featureID) {
			case GGPlotPackage.WRAP_FACET_LAYOUT__COL_VARS:
				return this.colVars != null && !this.colVars.isEmpty();
			case GGPlotPackage.WRAP_FACET_LAYOUT__COL_NUM:
				return COL_NUM_EDEFAULT == null ? this.colNum != null : !COL_NUM_EDEFAULT.equals(this.colNum);
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- 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(" (colVars: "); //$NON-NLS-1$
		result.append(this.colVars);
		result.append(", colNum: "); //$NON-NLS-1$
		result.append(this.colNum);
		result.append(')');
		return result.toString();
	}

} //WrapFacetLayoutImpl
