/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), 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 2.0 
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.ecview.semantic.uisemantics.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.impl.MinimalEObjectImpl;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.xtext.xtype.XImportSection;
import org.eclipse.osbp.ecview.semantic.uisemantics.UiSemanticsPackage;
import org.eclipse.osbp.ecview.semantic.uisemantics.UxAction;
import org.eclipse.osbp.ecview.semantic.uisemantics.UxElementDefinition;
import org.eclipse.osbp.ecview.semantic.uisemantics.UxModel;
import org.eclipse.osbp.ecview.semantic.uisemantics.UxViewCategory;

// TODO: Auto-generated Javadoc
/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Ux Model</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.ecview.semantic.uisemantics.impl.UxModelImpl#getImportSection <em>Import Section</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.semantic.uisemantics.impl.UxModelImpl#getElementDefinitions <em>Element Definitions</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.semantic.uisemantics.impl.UxModelImpl#getViewActions <em>View Actions</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.semantic.uisemantics.impl.UxModelImpl#getCategories <em>Categories</em>}</li>
 * </ul>
 *
 * @generated
 */
public class UxModelImpl extends MinimalEObjectImpl.Container implements UxModel {
	/**
	 * 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 #getElementDefinitions() <em>Element Definitions</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getElementDefinitions()
	 * @generated
	 * @ordered
	 */
	protected EList<UxElementDefinition> elementDefinitions;

	/**
	 * The cached value of the '{@link #getViewActions() <em>View Actions</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getViewActions()
	 * @generated
	 * @ordered
	 */
	protected EList<UxAction> viewActions;

	/**
	 * The cached value of the '{@link #getCategories() <em>Categories</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCategories()
	 * @generated
	 * @ordered
	 */
	protected EList<UxViewCategory> categories;

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the e class
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return UiSemanticsPackage.Literals.UX_MODEL;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getImportSection()
	 *         <em>Import Section</em>}' containment reference
	 * @generated
	 */
	public XImportSection getImportSection() {
		return importSection;
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newImportSection
	 *            the new cached value of the '{@link #getImportSection()
	 *            <em>Import Section</em>}' containment reference
	 * @generated
	 */
	public void setImportSection(XImportSection newImportSection) {
		if (newImportSection != importSection) {
			NotificationChain msgs = null;
			if (importSection != null)
				msgs = ((InternalEObject)importSection).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - UiSemanticsPackage.UX_MODEL__IMPORT_SECTION, null, msgs);
			if (newImportSection != null)
				msgs = ((InternalEObject)newImportSection).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - UiSemanticsPackage.UX_MODEL__IMPORT_SECTION, null, msgs);
			msgs = basicSetImportSection(newImportSection, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UiSemanticsPackage.UX_MODEL__IMPORT_SECTION, newImportSection, newImportSection));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getElementDefinitions()
	 *         <em>Element Definitions</em>}' containment reference list
	 * @generated
	 */
	public EList<UxElementDefinition> getElementDefinitions() {
		if (elementDefinitions == null) {
			elementDefinitions = new EObjectContainmentEList<UxElementDefinition>(UxElementDefinition.class, this, UiSemanticsPackage.UX_MODEL__ELEMENT_DEFINITIONS);
		}
		return elementDefinitions;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getViewActions()
	 *         <em>View Actions</em>}' containment reference list
	 * @generated
	 */
	public EList<UxAction> getViewActions() {
		if (viewActions == null) {
			viewActions = new EObjectContainmentEList<UxAction>(UxAction.class, this, UiSemanticsPackage.UX_MODEL__VIEW_ACTIONS);
		}
		return viewActions;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getCategories()
	 *         <em>Categories</em>}' containment reference list
	 * @generated
	 */
	public EList<UxViewCategory> getCategories() {
		if (categories == null) {
			categories = new EObjectContainmentEList<UxViewCategory>(UxViewCategory.class, this, UiSemanticsPackage.UX_MODEL__CATEGORIES);
		}
		return categories;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param otherEnd
	 *            the other end
	 * @param featureID
	 *            the feature id
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case UiSemanticsPackage.UX_MODEL__IMPORT_SECTION:
				return basicSetImportSection(null, msgs);
			case UiSemanticsPackage.UX_MODEL__ELEMENT_DEFINITIONS:
				return ((InternalEList<?>)getElementDefinitions()).basicRemove(otherEnd, msgs);
			case UiSemanticsPackage.UX_MODEL__VIEW_ACTIONS:
				return ((InternalEList<?>)getViewActions()).basicRemove(otherEnd, msgs);
			case UiSemanticsPackage.UX_MODEL__CATEGORIES:
				return ((InternalEList<?>)getCategories()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @param resolve
	 *            the resolve
	 * @param coreType
	 *            the core type
	 * @return the object
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case UiSemanticsPackage.UX_MODEL__IMPORT_SECTION:
				return getImportSection();
			case UiSemanticsPackage.UX_MODEL__ELEMENT_DEFINITIONS:
				return getElementDefinitions();
			case UiSemanticsPackage.UX_MODEL__VIEW_ACTIONS:
				return getViewActions();
			case UiSemanticsPackage.UX_MODEL__CATEGORIES:
				return getCategories();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @param newValue
	 *            the new value
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case UiSemanticsPackage.UX_MODEL__IMPORT_SECTION:
				setImportSection((XImportSection)newValue);
				return;
			case UiSemanticsPackage.UX_MODEL__ELEMENT_DEFINITIONS:
				getElementDefinitions().clear();
				getElementDefinitions().addAll((Collection<? extends UxElementDefinition>)newValue);
				return;
			case UiSemanticsPackage.UX_MODEL__VIEW_ACTIONS:
				getViewActions().clear();
				getViewActions().addAll((Collection<? extends UxAction>)newValue);
				return;
			case UiSemanticsPackage.UX_MODEL__CATEGORIES:
				getCategories().clear();
				getCategories().addAll((Collection<? extends UxViewCategory>)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case UiSemanticsPackage.UX_MODEL__IMPORT_SECTION:
				setImportSection((XImportSection)null);
				return;
			case UiSemanticsPackage.UX_MODEL__ELEMENT_DEFINITIONS:
				getElementDefinitions().clear();
				return;
			case UiSemanticsPackage.UX_MODEL__VIEW_ACTIONS:
				getViewActions().clear();
				return;
			case UiSemanticsPackage.UX_MODEL__CATEGORIES:
				getCategories().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @return true, if successful
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case UiSemanticsPackage.UX_MODEL__IMPORT_SECTION:
				return importSection != null;
			case UiSemanticsPackage.UX_MODEL__ELEMENT_DEFINITIONS:
				return elementDefinitions != null && !elementDefinitions.isEmpty();
			case UiSemanticsPackage.UX_MODEL__VIEW_ACTIONS:
				return viewActions != null && !viewActions.isEmpty();
			case UiSemanticsPackage.UX_MODEL__CATEGORIES:
				return categories != null && !categories.isEmpty();
		}
		return super.eIsSet(featureID);
	}

} //UxModelImpl
