/**
 * 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 2.0  
 *  which accompanies this distribution, and is available at 
 *  https://www.eclipse.org/legal/epl-2.0/ 
 *  
 *  SPDX-License-Identifier: EPL-2.0 
 * 
 *  Based on ideas from Xtext, Xtend, Xcore
 *   
 *  Contributors:  
 *  		Christophe Loetz  (Loetz GmbH&Co.KG) - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.messagedsl.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.EDataTypeEList;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;

import org.eclipse.osbp.xtext.messagedsl.MessageDSLPackage;
import org.eclipse.osbp.xtext.messagedsl.MessageItem;
import org.eclipse.osbp.xtext.messagedsl.MessageParameter;
import org.eclipse.osbp.xtext.messagedsl.MessageText;
import org.eclipse.osbp.xtext.messagedsl.SeverityEnum;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Message Item</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.messagedsl.impl.MessageItemImpl#getName <em>Name</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.messagedsl.impl.MessageItemImpl#getParameters <em>Parameters</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.messagedsl.impl.MessageItemImpl#getSeverities <em>Severities</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.messagedsl.impl.MessageItemImpl#getAllOutput <em>All Output</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.messagedsl.impl.MessageItemImpl#getLogOutput <em>Log Output</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.messagedsl.impl.MessageItemImpl#getShowOutput <em>Show Output</em>}</li>
 * </ul>
 *
 * @generated
 */
public class MessageItemImpl extends MinimalEObjectImpl.Container implements MessageItem {
	/**
	 * The default value of the '{@link #getName() <em>Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getName()
	 * @generated
	 * @ordered
	 */
	protected static final String NAME_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getName() <em>Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getName()
	 * @generated
	 * @ordered
	 */
	protected String name = NAME_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getSeverities() <em>Severities</em>}' attribute list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSeverities()
	 * @generated
	 * @ordered
	 */
	protected EList<SeverityEnum> severities;

	/**
	 * The cached value of the '{@link #getAllOutput() <em>All Output</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAllOutput()
	 * @generated
	 * @ordered
	 */
	protected MessageText allOutput;

	/**
	 * The cached value of the '{@link #getLogOutput() <em>Log Output</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLogOutput()
	 * @generated
	 * @ordered
	 */
	protected MessageText logOutput;

	/**
	 * The cached value of the '{@link #getShowOutput() <em>Show Output</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getShowOutput()
	 * @generated
	 * @ordered
	 */
	protected MessageText showOutput;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String getName() {
		return name;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setName(String newName) {
		String oldName = name;
		name = newName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, MessageDSLPackage.MESSAGE_ITEM__NAME, oldName, name));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<MessageParameter> getParameters() {
		if (parameters == null) {
			parameters = new EObjectContainmentEList<MessageParameter>(MessageParameter.class, this, MessageDSLPackage.MESSAGE_ITEM__PARAMETERS);
		}
		return parameters;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<SeverityEnum> getSeverities() {
		if (severities == null) {
			severities = new EDataTypeEList<SeverityEnum>(SeverityEnum.class, this, MessageDSLPackage.MESSAGE_ITEM__SEVERITIES);
		}
		return severities;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public MessageText getAllOutput() {
		return allOutput;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetAllOutput(MessageText newAllOutput, NotificationChain msgs) {
		MessageText oldAllOutput = allOutput;
		allOutput = newAllOutput;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, MessageDSLPackage.MESSAGE_ITEM__ALL_OUTPUT, oldAllOutput, newAllOutput);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setAllOutput(MessageText newAllOutput) {
		if (newAllOutput != allOutput) {
			NotificationChain msgs = null;
			if (allOutput != null)
				msgs = ((InternalEObject)allOutput).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - MessageDSLPackage.MESSAGE_ITEM__ALL_OUTPUT, null, msgs);
			if (newAllOutput != null)
				msgs = ((InternalEObject)newAllOutput).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - MessageDSLPackage.MESSAGE_ITEM__ALL_OUTPUT, null, msgs);
			msgs = basicSetAllOutput(newAllOutput, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, MessageDSLPackage.MESSAGE_ITEM__ALL_OUTPUT, newAllOutput, newAllOutput));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public MessageText getLogOutput() {
		return logOutput;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetLogOutput(MessageText newLogOutput, NotificationChain msgs) {
		MessageText oldLogOutput = logOutput;
		logOutput = newLogOutput;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, MessageDSLPackage.MESSAGE_ITEM__LOG_OUTPUT, oldLogOutput, newLogOutput);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setLogOutput(MessageText newLogOutput) {
		if (newLogOutput != logOutput) {
			NotificationChain msgs = null;
			if (logOutput != null)
				msgs = ((InternalEObject)logOutput).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - MessageDSLPackage.MESSAGE_ITEM__LOG_OUTPUT, null, msgs);
			if (newLogOutput != null)
				msgs = ((InternalEObject)newLogOutput).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - MessageDSLPackage.MESSAGE_ITEM__LOG_OUTPUT, null, msgs);
			msgs = basicSetLogOutput(newLogOutput, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, MessageDSLPackage.MESSAGE_ITEM__LOG_OUTPUT, newLogOutput, newLogOutput));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public MessageText getShowOutput() {
		return showOutput;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetShowOutput(MessageText newShowOutput, NotificationChain msgs) {
		MessageText oldShowOutput = showOutput;
		showOutput = newShowOutput;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, MessageDSLPackage.MESSAGE_ITEM__SHOW_OUTPUT, oldShowOutput, newShowOutput);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setShowOutput(MessageText newShowOutput) {
		if (newShowOutput != showOutput) {
			NotificationChain msgs = null;
			if (showOutput != null)
				msgs = ((InternalEObject)showOutput).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - MessageDSLPackage.MESSAGE_ITEM__SHOW_OUTPUT, null, msgs);
			if (newShowOutput != null)
				msgs = ((InternalEObject)newShowOutput).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - MessageDSLPackage.MESSAGE_ITEM__SHOW_OUTPUT, null, msgs);
			msgs = basicSetShowOutput(newShowOutput, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, MessageDSLPackage.MESSAGE_ITEM__SHOW_OUTPUT, newShowOutput, newShowOutput));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case MessageDSLPackage.MESSAGE_ITEM__PARAMETERS:
				return ((InternalEList<?>)getParameters()).basicRemove(otherEnd, msgs);
			case MessageDSLPackage.MESSAGE_ITEM__ALL_OUTPUT:
				return basicSetAllOutput(null, msgs);
			case MessageDSLPackage.MESSAGE_ITEM__LOG_OUTPUT:
				return basicSetLogOutput(null, msgs);
			case MessageDSLPackage.MESSAGE_ITEM__SHOW_OUTPUT:
				return basicSetShowOutput(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 MessageDSLPackage.MESSAGE_ITEM__NAME:
				return getName();
			case MessageDSLPackage.MESSAGE_ITEM__PARAMETERS:
				return getParameters();
			case MessageDSLPackage.MESSAGE_ITEM__SEVERITIES:
				return getSeverities();
			case MessageDSLPackage.MESSAGE_ITEM__ALL_OUTPUT:
				return getAllOutput();
			case MessageDSLPackage.MESSAGE_ITEM__LOG_OUTPUT:
				return getLogOutput();
			case MessageDSLPackage.MESSAGE_ITEM__SHOW_OUTPUT:
				return getShowOutput();
		}
		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 MessageDSLPackage.MESSAGE_ITEM__NAME:
				setName((String)newValue);
				return;
			case MessageDSLPackage.MESSAGE_ITEM__PARAMETERS:
				getParameters().clear();
				getParameters().addAll((Collection<? extends MessageParameter>)newValue);
				return;
			case MessageDSLPackage.MESSAGE_ITEM__SEVERITIES:
				getSeverities().clear();
				getSeverities().addAll((Collection<? extends SeverityEnum>)newValue);
				return;
			case MessageDSLPackage.MESSAGE_ITEM__ALL_OUTPUT:
				setAllOutput((MessageText)newValue);
				return;
			case MessageDSLPackage.MESSAGE_ITEM__LOG_OUTPUT:
				setLogOutput((MessageText)newValue);
				return;
			case MessageDSLPackage.MESSAGE_ITEM__SHOW_OUTPUT:
				setShowOutput((MessageText)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case MessageDSLPackage.MESSAGE_ITEM__NAME:
				setName(NAME_EDEFAULT);
				return;
			case MessageDSLPackage.MESSAGE_ITEM__PARAMETERS:
				getParameters().clear();
				return;
			case MessageDSLPackage.MESSAGE_ITEM__SEVERITIES:
				getSeverities().clear();
				return;
			case MessageDSLPackage.MESSAGE_ITEM__ALL_OUTPUT:
				setAllOutput((MessageText)null);
				return;
			case MessageDSLPackage.MESSAGE_ITEM__LOG_OUTPUT:
				setLogOutput((MessageText)null);
				return;
			case MessageDSLPackage.MESSAGE_ITEM__SHOW_OUTPUT:
				setShowOutput((MessageText)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case MessageDSLPackage.MESSAGE_ITEM__NAME:
				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
			case MessageDSLPackage.MESSAGE_ITEM__PARAMETERS:
				return parameters != null && !parameters.isEmpty();
			case MessageDSLPackage.MESSAGE_ITEM__SEVERITIES:
				return severities != null && !severities.isEmpty();
			case MessageDSLPackage.MESSAGE_ITEM__ALL_OUTPUT:
				return allOutput != null;
			case MessageDSLPackage.MESSAGE_ITEM__LOG_OUTPUT:
				return logOutput != null;
			case MessageDSLPackage.MESSAGE_ITEM__SHOW_OUTPUT:
				return showOutput != null;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (name: ");
		result.append(name);
		result.append(", severities: ");
		result.append(severities);
		result.append(')');
		return result.toString();
	}

} //MessageItemImpl
