/*******************************************************************************
 * Copyright (c) 2007, 2010 BMW Car IT, Technische Universitaet Muenchen, 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:
 * BMW Car IT - Initial API and implementation
 * Technische Universitaet Muenchen - Major refactoring and extension
 *******************************************************************************/
package org.eclipse.emf.edapt.declaration.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.EObjectContainmentWithInverseEList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.edapt.declaration.Constraint;
import org.eclipse.emf.edapt.declaration.DeclarationPackage;
import org.eclipse.emf.edapt.declaration.Library;
import org.eclipse.emf.edapt.declaration.Operation;
import org.eclipse.emf.edapt.declaration.Parameter;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Operation</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 * <li>{@link org.eclipse.emf.edapt.declaration.impl.OperationImpl#getLibrary <em>Library</em>}</li>
 * <li>{@link org.eclipse.emf.edapt.declaration.impl.OperationImpl#getParameters <em>Parameters</em>}</li>
 * <li>{@link org.eclipse.emf.edapt.declaration.impl.OperationImpl#getConstraints <em>Constraints</em>}</li>
 * <li>{@link org.eclipse.emf.edapt.declaration.impl.OperationImpl#isDeprecated <em>Deprecated</em>}</li>
 * <li>{@link org.eclipse.emf.edapt.declaration.impl.OperationImpl#getBefore <em>Before</em>}</li>
 * <li>{@link org.eclipse.emf.edapt.declaration.impl.OperationImpl#getAfter <em>After</em>}</li>
 * <li>{@link org.eclipse.emf.edapt.declaration.impl.OperationImpl#getImplementation <em>Implementation</em>}</li>
 * <li>{@link org.eclipse.emf.edapt.declaration.impl.OperationImpl#getLabel <em>Label</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class OperationImpl extends IdentifiedElementImpl implements Operation {
	/**
	 * 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<Parameter> parameters;

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

	/**
	 * The default value of the '{@link #isDeprecated() <em>Deprecated</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @see #isDeprecated()
	 * @generated
	 * @ordered
	 */
	protected static final boolean DEPRECATED_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isDeprecated() <em>Deprecated</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @see #isDeprecated()
	 * @generated
	 * @ordered
	 */
	protected boolean deprecated = DEPRECATED_EDEFAULT;

	/**
	 * The default value of the '{@link #getBefore() <em>Before</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @see #getBefore()
	 * @generated
	 * @ordered
	 */
	protected static final String BEFORE_EDEFAULT = null;

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

	/**
	 * The default value of the '{@link #getAfter() <em>After</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @see #getAfter()
	 * @generated
	 * @ordered
	 */
	protected static final String AFTER_EDEFAULT = null;

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

	/**
	 * The cached value of the '{@link #getImplementation() <em>Implementation</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @see #getImplementation()
	 * @generated
	 * @ordered
	 */
	protected Class implementation;

	/**
	 * The default value of the '{@link #getLabel() <em>Label</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @see #getLabel()
	 * @generated
	 * @ordered
	 */
	protected static final String LABEL_EDEFAULT = null;

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

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public void setLabel(String newLabel) {
		final String oldLabel = label;
		label = newLabel;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, DeclarationPackage.OPERATION__LABEL, oldLabel, label));
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public Library getLibrary() {
		if (eContainerFeatureID() != DeclarationPackage.OPERATION__LIBRARY) {
			return null;
		}
		return (Library) eContainer();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public NotificationChain basicSetLibrary(Library newLibrary, NotificationChain msgs) {
		msgs = eBasicSetContainer((InternalEObject) newLibrary, DeclarationPackage.OPERATION__LIBRARY, msgs);
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public void setLibrary(Library newLibrary) {
		if (newLibrary != eInternalContainer()
			|| eContainerFeatureID() != DeclarationPackage.OPERATION__LIBRARY && newLibrary != null) {
			if (EcoreUtil.isAncestor(this, newLibrary)) {
				throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); //$NON-NLS-1$
			}
			NotificationChain msgs = null;
			if (eInternalContainer() != null) {
				msgs = eBasicRemoveFromContainer(msgs);
			}
			if (newLibrary != null) {
				msgs = ((InternalEObject) newLibrary).eInverseAdd(this, DeclarationPackage.LIBRARY__OPERATIONS,
					Library.class, msgs);
			}
			msgs = basicSetLibrary(newLibrary, msgs);
			if (msgs != null) {
				msgs.dispatch();
			}
		}
		else if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, DeclarationPackage.OPERATION__LIBRARY, newLibrary,
				newLibrary));
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public EList<Parameter> getParameters() {
		if (parameters == null) {
			parameters = new EObjectContainmentWithInverseEList<Parameter>(Parameter.class, this,
				DeclarationPackage.OPERATION__PARAMETERS, DeclarationPackage.PARAMETER__OPERATION);
		}
		return parameters;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public EList<Constraint> getConstraints() {
		if (constraints == null) {
			constraints = new EObjectContainmentWithInverseEList<Constraint>(Constraint.class, this,
				DeclarationPackage.OPERATION__CONSTRAINTS, DeclarationPackage.CONSTRAINT__OPERATION);
		}
		return constraints;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public boolean isDeprecated() {
		return deprecated;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public void setDeprecated(boolean newDeprecated) {
		final boolean oldDeprecated = deprecated;
		deprecated = newDeprecated;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, DeclarationPackage.OPERATION__DEPRECATED,
				oldDeprecated, deprecated));
		}
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public void setBefore(String newBefore) {
		final String oldBefore = before;
		before = newBefore;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, DeclarationPackage.OPERATION__BEFORE, oldBefore,
				before));
		}
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public void setAfter(String newAfter) {
		final String oldAfter = after;
		after = newAfter;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, DeclarationPackage.OPERATION__AFTER, oldAfter, after));
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public Class getImplementation() {
		return implementation;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public void setImplementation(Class newImplementation) {
		final Class oldImplementation = implementation;
		implementation = newImplementation;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, DeclarationPackage.OPERATION__IMPLEMENTATION,
				oldImplementation, implementation));
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public Parameter getParameter(String name) {
		for (final Parameter parameter : getParameters()) {
			if (name.equals(parameter.getName())) {
				return parameter;
			}
		}
		return null;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public Parameter getMainParameter() {
		for (final Parameter parameter : getParameters()) {
			if (parameter.isMain()) {
				return parameter;
			}
		}
		return null;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public boolean refines() {
		return getBefore() != null || getAfter() != null;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public Constraint getConstraint(String name) {
		for (final Constraint constraint : getConstraints()) {
			if (name.equals(constraint.getName())) {
				return constraint;
			}
		}
		return null;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
		case DeclarationPackage.OPERATION__LIBRARY:
			if (eInternalContainer() != null) {
				msgs = eBasicRemoveFromContainer(msgs);
			}
			return basicSetLibrary((Library) otherEnd, msgs);
		case DeclarationPackage.OPERATION__PARAMETERS:
			return ((InternalEList<InternalEObject>) (InternalEList<?>) getParameters()).basicAdd(otherEnd, msgs);
		case DeclarationPackage.OPERATION__CONSTRAINTS:
			return ((InternalEList<InternalEObject>) (InternalEList<?>) getConstraints()).basicAdd(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 DeclarationPackage.OPERATION__LIBRARY:
			return basicSetLibrary(null, msgs);
		case DeclarationPackage.OPERATION__PARAMETERS:
			return ((InternalEList<?>) getParameters()).basicRemove(otherEnd, msgs);
		case DeclarationPackage.OPERATION__CONSTRAINTS:
			return ((InternalEList<?>) getConstraints()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) {
		switch (eContainerFeatureID()) {
		case DeclarationPackage.OPERATION__LIBRARY:
			return eInternalContainer().eInverseRemove(this, DeclarationPackage.LIBRARY__OPERATIONS, Library.class,
				msgs);
		}
		return super.eBasicRemoveFromContainerFeature(msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
		case DeclarationPackage.OPERATION__LIBRARY:
			return getLibrary();
		case DeclarationPackage.OPERATION__PARAMETERS:
			return getParameters();
		case DeclarationPackage.OPERATION__CONSTRAINTS:
			return getConstraints();
		case DeclarationPackage.OPERATION__DEPRECATED:
			return isDeprecated();
		case DeclarationPackage.OPERATION__BEFORE:
			return getBefore();
		case DeclarationPackage.OPERATION__AFTER:
			return getAfter();
		case DeclarationPackage.OPERATION__IMPLEMENTATION:
			return getImplementation();
		case DeclarationPackage.OPERATION__LABEL:
			return getLabel();
		}
		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 DeclarationPackage.OPERATION__LIBRARY:
			setLibrary((Library) newValue);
			return;
		case DeclarationPackage.OPERATION__PARAMETERS:
			getParameters().clear();
			getParameters().addAll((Collection<? extends Parameter>) newValue);
			return;
		case DeclarationPackage.OPERATION__CONSTRAINTS:
			getConstraints().clear();
			getConstraints().addAll((Collection<? extends Constraint>) newValue);
			return;
		case DeclarationPackage.OPERATION__DEPRECATED:
			setDeprecated((Boolean) newValue);
			return;
		case DeclarationPackage.OPERATION__BEFORE:
			setBefore((String) newValue);
			return;
		case DeclarationPackage.OPERATION__AFTER:
			setAfter((String) newValue);
			return;
		case DeclarationPackage.OPERATION__IMPLEMENTATION:
			setImplementation((Class) newValue);
			return;
		case DeclarationPackage.OPERATION__LABEL:
			setLabel((String) newValue);
			return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
		case DeclarationPackage.OPERATION__LIBRARY:
			setLibrary((Library) null);
			return;
		case DeclarationPackage.OPERATION__PARAMETERS:
			getParameters().clear();
			return;
		case DeclarationPackage.OPERATION__CONSTRAINTS:
			getConstraints().clear();
			return;
		case DeclarationPackage.OPERATION__DEPRECATED:
			setDeprecated(DEPRECATED_EDEFAULT);
			return;
		case DeclarationPackage.OPERATION__BEFORE:
			setBefore(BEFORE_EDEFAULT);
			return;
		case DeclarationPackage.OPERATION__AFTER:
			setAfter(AFTER_EDEFAULT);
			return;
		case DeclarationPackage.OPERATION__IMPLEMENTATION:
			setImplementation((Class) null);
			return;
		case DeclarationPackage.OPERATION__LABEL:
			setLabel(LABEL_EDEFAULT);
			return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
		case DeclarationPackage.OPERATION__LIBRARY:
			return getLibrary() != null;
		case DeclarationPackage.OPERATION__PARAMETERS:
			return parameters != null && !parameters.isEmpty();
		case DeclarationPackage.OPERATION__CONSTRAINTS:
			return constraints != null && !constraints.isEmpty();
		case DeclarationPackage.OPERATION__DEPRECATED:
			return deprecated != DEPRECATED_EDEFAULT;
		case DeclarationPackage.OPERATION__BEFORE:
			return BEFORE_EDEFAULT == null ? before != null : !BEFORE_EDEFAULT.equals(before);
		case DeclarationPackage.OPERATION__AFTER:
			return AFTER_EDEFAULT == null ? after != null : !AFTER_EDEFAULT.equals(after);
		case DeclarationPackage.OPERATION__IMPLEMENTATION:
			return implementation != null;
		case DeclarationPackage.OPERATION__LABEL:
			return LABEL_EDEFAULT == null ? label != null : !LABEL_EDEFAULT.equals(label);
		}
		return super.eIsSet(featureID);
	}

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

		final StringBuffer result = new StringBuffer(super.toString());
		result.append(" (deprecated: "); //$NON-NLS-1$
		result.append(deprecated);
		result.append(", before: "); //$NON-NLS-1$
		result.append(before);
		result.append(", after: "); //$NON-NLS-1$
		result.append(after);
		result.append(", implementation: "); //$NON-NLS-1$
		result.append(implementation);
		result.append(", label: "); //$NON-NLS-1$
		result.append(label);
		result.append(')');
		return result.toString();
	}

} // OperationImpl
