/**
 * 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 v1.0 
 *  which accompanies this distribution, and is available at 
 *  http://www.eclipse.org/legal/epl-v10.html 
 * 
 *  Based on ideas from Xtext, Xtend, Xcore
 *   
 *  Contributors:  
 *  		José C. Domínguez - Initial implementation
 *  
 */
package org.eclipse.osbp.xtext.cubedsl.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.cubedsl.CubeDSLPackage;
import org.eclipse.osbp.xtext.cubedsl.CubeModel;
import org.eclipse.osbp.xtext.cubedsl.CubePackage;

import org.eclipse.xtext.xtype.XImportSection;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Cube Model</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.cubedsl.impl.CubeModelImpl#getImportSection <em>Import Section</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.cubedsl.impl.CubeModelImpl#getPckg <em>Pckg</em>}</li>
 * </ul>
 *
 * @generated
 */
public class CubeModelImpl extends CubeLazyResolverImpl implements CubeModel {
	/**
	 * The cached value of the '{@link #getImportSection() <em>Import Section</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getImportSection()
	 * @generated
	 * @ordered
	 */
	protected XImportSection importSection;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public XImportSection getImportSection() {
		return importSection;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetImportSection(XImportSection newImportSection, NotificationChain msgs) {
		XImportSection oldImportSection = importSection;
		importSection = newImportSection;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, CubeDSLPackage.CUBE_MODEL__IMPORT_SECTION, oldImportSection, newImportSection);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setImportSection(XImportSection newImportSection) {
		if (newImportSection != importSection) {
			NotificationChain msgs = null;
			if (importSection != null)
				msgs = ((InternalEObject)importSection).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - CubeDSLPackage.CUBE_MODEL__IMPORT_SECTION, null, msgs);
			if (newImportSection != null)
				msgs = ((InternalEObject)newImportSection).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - CubeDSLPackage.CUBE_MODEL__IMPORT_SECTION, null, msgs);
			msgs = basicSetImportSection(newImportSection, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CubeDSLPackage.CUBE_MODEL__IMPORT_SECTION, newImportSection, newImportSection));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public CubePackage getPckg() {
		return pckg;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetPckg(CubePackage newPckg, NotificationChain msgs) {
		CubePackage oldPckg = pckg;
		pckg = newPckg;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, CubeDSLPackage.CUBE_MODEL__PCKG, oldPckg, newPckg);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setPckg(CubePackage newPckg) {
		if (newPckg != pckg) {
			NotificationChain msgs = null;
			if (pckg != null)
				msgs = ((InternalEObject)pckg).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - CubeDSLPackage.CUBE_MODEL__PCKG, null, msgs);
			if (newPckg != null)
				msgs = ((InternalEObject)newPckg).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - CubeDSLPackage.CUBE_MODEL__PCKG, null, msgs);
			msgs = basicSetPckg(newPckg, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CubeDSLPackage.CUBE_MODEL__PCKG, newPckg, newPckg));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case CubeDSLPackage.CUBE_MODEL__IMPORT_SECTION:
				return basicSetImportSection(null, msgs);
			case CubeDSLPackage.CUBE_MODEL__PCKG:
				return basicSetPckg(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 CubeDSLPackage.CUBE_MODEL__IMPORT_SECTION:
				return getImportSection();
			case CubeDSLPackage.CUBE_MODEL__PCKG:
				return getPckg();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case CubeDSLPackage.CUBE_MODEL__IMPORT_SECTION:
				setImportSection((XImportSection)newValue);
				return;
			case CubeDSLPackage.CUBE_MODEL__PCKG:
				setPckg((CubePackage)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case CubeDSLPackage.CUBE_MODEL__IMPORT_SECTION:
				setImportSection((XImportSection)null);
				return;
			case CubeDSLPackage.CUBE_MODEL__PCKG:
				setPckg((CubePackage)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case CubeDSLPackage.CUBE_MODEL__IMPORT_SECTION:
				return importSection != null;
			case CubeDSLPackage.CUBE_MODEL__PCKG:
				return pckg != null;
		}
		return super.eIsSet(featureID);
	}

} //CubeModelImpl
