/*******************************************************************************
 * Copyright (c) 2018 Willink Transformations and others.
 * 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
 *
 * Contributors:
 *     Adolfo Sanchez-Barbudo Herrera - initial API and implementation
 *******************************************************************************/
/**
 * generated by Xtext 2.10.0
 */
package org.eclipse.qvtd.doc.minioclcs.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.qvtd.doc.minioclcs.ExpCS;
import org.eclipse.qvtd.doc.minioclcs.LetExpCS;
import org.eclipse.qvtd.doc.minioclcs.LetVarCS;
import org.eclipse.qvtd.doc.minioclcs.MinioclcsPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Let Exp CS</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.qvtd.doc.minioclcs.impl.LetExpCSImpl#getLetVars <em>Let Vars</em>}</li>
 *   <li>{@link org.eclipse.qvtd.doc.minioclcs.impl.LetExpCSImpl#getInExp <em>In Exp</em>}</li>
 * </ul>
 *
 * @generated
 */
public class LetExpCSImpl extends PrimaryExpCSImpl implements LetExpCS
{
  /**
	 * The cached value of the '{@link #getLetVars() <em>Let Vars</em>}' containment reference list.
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @see #getLetVars()
	 * @generated
	 * @ordered
	 */
  protected EList<LetVarCS> letVars;

  /**
	 * The cached value of the '{@link #getInExp() <em>In Exp</em>}' containment reference.
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @see #getInExp()
	 * @generated
	 * @ordered
	 */
  protected ExpCS inExp;

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

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

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  public EList<LetVarCS> getLetVars()
  {
		if (letVars == null) {
			letVars = new EObjectContainmentEList<LetVarCS>(LetVarCS.class, this, MinioclcsPackage.LET_EXP_CS__LET_VARS);
		}
		return letVars;
	}

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  public ExpCS getInExp()
  {
		return inExp;
	}

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  public NotificationChain basicSetInExp(ExpCS newInExp, NotificationChain msgs)
  {
		ExpCS oldInExp = inExp;
		inExp = newInExp;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, MinioclcsPackage.LET_EXP_CS__IN_EXP, oldInExp, newInExp);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  public void setInExp(ExpCS newInExp)
  {
		if (newInExp != inExp) {
			NotificationChain msgs = null;
			if (inExp != null)
				msgs = ((InternalEObject)inExp).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - MinioclcsPackage.LET_EXP_CS__IN_EXP, null, msgs);
			if (newInExp != null)
				msgs = ((InternalEObject)newInExp).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - MinioclcsPackage.LET_EXP_CS__IN_EXP, null, msgs);
			msgs = basicSetInExp(newInExp, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, MinioclcsPackage.LET_EXP_CS__IN_EXP, newInExp, newInExp));
	}

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  @Override
  public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs)
  {
		switch (featureID) {
			case MinioclcsPackage.LET_EXP_CS__LET_VARS:
				return ((InternalEList<?>)getLetVars()).basicRemove(otherEnd, msgs);
			case MinioclcsPackage.LET_EXP_CS__IN_EXP:
				return basicSetInExp(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 MinioclcsPackage.LET_EXP_CS__LET_VARS:
				return getLetVars();
			case MinioclcsPackage.LET_EXP_CS__IN_EXP:
				return getInExp();
		}
		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 MinioclcsPackage.LET_EXP_CS__LET_VARS:
				getLetVars().clear();
				getLetVars().addAll((Collection<? extends LetVarCS>)newValue);
				return;
			case MinioclcsPackage.LET_EXP_CS__IN_EXP:
				setInExp((ExpCS)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  @Override
  public void eUnset(int featureID)
  {
		switch (featureID) {
			case MinioclcsPackage.LET_EXP_CS__LET_VARS:
				getLetVars().clear();
				return;
			case MinioclcsPackage.LET_EXP_CS__IN_EXP:
				setInExp((ExpCS)null);
				return;
		}
		super.eUnset(featureID);
	}

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  @Override
  public boolean eIsSet(int featureID)
  {
		switch (featureID) {
			case MinioclcsPackage.LET_EXP_CS__LET_VARS:
				return letVars != null && !letVars.isEmpty();
			case MinioclcsPackage.LET_EXP_CS__IN_EXP:
				return inExp != null;
		}
		return super.eIsSet(featureID);
	}

} //LetExpCSImpl
