/**
 * Copyright (c) 2020 CEA LIST, Committer Name, and others.
 * 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:
 * CEA LIST - Initial API and implementation
 * Patrick Tessier (CEA LIST) patrick.tessier@cea.fr  
 * Gabriel Pedroza (CEA LIST) gabriel.pedroza@cea.fr  
 * 
 */
package org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.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.EObjectWithInverseResolvingEList;
import org.eclipse.emf.ecore.util.InternalEList;

import org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Consent;
import org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Pdp4engCommonGDPRPackage;
import org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Purpose;

import org.eclipse.uml2.uml.NamedElement;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Purpose</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.impl.PurposeImpl#getBase_NamedElement <em>Base Named Element</em>}</li>
 *   <li>{@link org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.impl.PurposeImpl#getProcesses <em>Processes</em>}</li>
 *   <li>{@link org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.impl.PurposeImpl#getConsent <em>Consent</em>}</li>
 * </ul>
 *
 * @generated
 */
public class PurposeImpl extends MinimalEObjectImpl.Container implements Purpose {
	/**
	 * The cached value of the '{@link #getBase_NamedElement() <em>Base Named Element</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getBase_NamedElement()
	 * @generated
	 * @ordered
	 */
	protected NamedElement base_NamedElement;

	/**
	 * The cached value of the '{@link #getProcesses() <em>Processes</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getProcesses()
	 * @generated
	 * @ordered
	 */
	protected EList<org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Process> processes;

	/**
	 * The cached value of the '{@link #getConsent() <em>Consent</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getConsent()
	 * @generated
	 * @ordered
	 */
	protected Consent consent;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NamedElement getBase_NamedElement() {
		if (base_NamedElement != null && base_NamedElement.eIsProxy()) {
			InternalEObject oldBase_NamedElement = (InternalEObject)base_NamedElement;
			base_NamedElement = (NamedElement)eResolveProxy(oldBase_NamedElement);
			if (base_NamedElement != oldBase_NamedElement) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, Pdp4engCommonGDPRPackage.PURPOSE__BASE_NAMED_ELEMENT, oldBase_NamedElement, base_NamedElement));
			}
		}
		return base_NamedElement;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NamedElement basicGetBase_NamedElement() {
		return base_NamedElement;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setBase_NamedElement(NamedElement newBase_NamedElement) {
		NamedElement oldBase_NamedElement = base_NamedElement;
		base_NamedElement = newBase_NamedElement;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Pdp4engCommonGDPRPackage.PURPOSE__BASE_NAMED_ELEMENT, oldBase_NamedElement, base_NamedElement));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Process> getProcesses() {
		if (processes == null) {
			processes = new EObjectWithInverseResolvingEList<org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Process>(org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Process.class, this, Pdp4engCommonGDPRPackage.PURPOSE__PROCESSES, Pdp4engCommonGDPRPackage.PROCESS__CONTRIBUTED_TO);
		}
		return processes;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Consent getConsent() {
		if (consent != null && consent.eIsProxy()) {
			InternalEObject oldConsent = (InternalEObject)consent;
			consent = (Consent)eResolveProxy(oldConsent);
			if (consent != oldConsent) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, Pdp4engCommonGDPRPackage.PURPOSE__CONSENT, oldConsent, consent));
			}
		}
		return consent;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Consent basicGetConsent() {
		return consent;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetConsent(Consent newConsent, NotificationChain msgs) {
		Consent oldConsent = consent;
		consent = newConsent;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, Pdp4engCommonGDPRPackage.PURPOSE__CONSENT, oldConsent, newConsent);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setConsent(Consent newConsent) {
		if (newConsent != consent) {
			NotificationChain msgs = null;
			if (consent != null)
				msgs = ((InternalEObject)consent).eInverseRemove(this, Pdp4engCommonGDPRPackage.CONSENT__PURPOSE, Consent.class, msgs);
			if (newConsent != null)
				msgs = ((InternalEObject)newConsent).eInverseAdd(this, Pdp4engCommonGDPRPackage.CONSENT__PURPOSE, Consent.class, msgs);
			msgs = basicSetConsent(newConsent, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Pdp4engCommonGDPRPackage.PURPOSE__CONSENT, newConsent, newConsent));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case Pdp4engCommonGDPRPackage.PURPOSE__PROCESSES:
				return ((InternalEList<InternalEObject>)(InternalEList<?>)getProcesses()).basicAdd(otherEnd, msgs);
			case Pdp4engCommonGDPRPackage.PURPOSE__CONSENT:
				if (consent != null)
					msgs = ((InternalEObject)consent).eInverseRemove(this, Pdp4engCommonGDPRPackage.CONSENT__PURPOSE, Consent.class, msgs);
				return basicSetConsent((Consent)otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case Pdp4engCommonGDPRPackage.PURPOSE__PROCESSES:
				return ((InternalEList<?>)getProcesses()).basicRemove(otherEnd, msgs);
			case Pdp4engCommonGDPRPackage.PURPOSE__CONSENT:
				return basicSetConsent(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 Pdp4engCommonGDPRPackage.PURPOSE__BASE_NAMED_ELEMENT:
				if (resolve) return getBase_NamedElement();
				return basicGetBase_NamedElement();
			case Pdp4engCommonGDPRPackage.PURPOSE__PROCESSES:
				return getProcesses();
			case Pdp4engCommonGDPRPackage.PURPOSE__CONSENT:
				if (resolve) return getConsent();
				return basicGetConsent();
		}
		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 Pdp4engCommonGDPRPackage.PURPOSE__BASE_NAMED_ELEMENT:
				setBase_NamedElement((NamedElement)newValue);
				return;
			case Pdp4engCommonGDPRPackage.PURPOSE__PROCESSES:
				getProcesses().clear();
				getProcesses().addAll((Collection<? extends org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Process>)newValue);
				return;
			case Pdp4engCommonGDPRPackage.PURPOSE__CONSENT:
				setConsent((Consent)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case Pdp4engCommonGDPRPackage.PURPOSE__BASE_NAMED_ELEMENT:
				setBase_NamedElement((NamedElement)null);
				return;
			case Pdp4engCommonGDPRPackage.PURPOSE__PROCESSES:
				getProcesses().clear();
				return;
			case Pdp4engCommonGDPRPackage.PURPOSE__CONSENT:
				setConsent((Consent)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case Pdp4engCommonGDPRPackage.PURPOSE__BASE_NAMED_ELEMENT:
				return base_NamedElement != null;
			case Pdp4engCommonGDPRPackage.PURPOSE__PROCESSES:
				return processes != null && !processes.isEmpty();
			case Pdp4engCommonGDPRPackage.PURPOSE__CONSENT:
				return consent != null;
		}
		return super.eIsSet(featureID);
	}

} //PurposeImpl
