/**
 * *******************************************************************************
 * Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency 
 * 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:
 *      Regent L'Archeveque - initial API and implementation
 *         
 * SPDX-License-Identifier: EPL-1.0    
 * *******************************************************************************
 */
package org.eclipse.apogy.core.environment.earth.orbit.planner.impl;

import org.eclipse.apogy.core.environment.earth.orbit.planner.AbstractStatefulCostFunction;
import org.eclipse.apogy.core.environment.earth.orbit.planner.ApogyCoreEnvironmentEarthOrbitPlannerPackage;
import org.eclipse.apogy.core.environment.earth.orbit.planner.CostFunctionState;
import org.eclipse.apogy.core.environment.earth.orbit.planner.StatefulCostFunctionMapEntryValue;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;

import org.eclipse.emf.common.util.BasicEMap;
import org.eclipse.emf.common.util.EMap;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Stateful Cost Function Map Entry</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.apogy.core.environment.earth.orbit.planner.impl.StatefulCostFunctionMapEntryImpl#getTypedKey <em>Key</em>}</li>
 *   <li>{@link org.eclipse.apogy.core.environment.earth.orbit.planner.impl.StatefulCostFunctionMapEntryImpl#getTypedValue <em>Value</em>}</li>
 * </ul>
 *
 * @generated
 */
public class StatefulCostFunctionMapEntryImpl extends MinimalEObjectImpl.Container implements BasicEMap.Entry<AbstractStatefulCostFunction<CostFunctionState>,StatefulCostFunctionMapEntryValue> {
	/**
	 * The cached value of the '{@link #getTypedKey() <em>Key</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTypedKey()
	 * @generated
	 * @ordered
	 */
	protected AbstractStatefulCostFunction<CostFunctionState> key;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	public AbstractStatefulCostFunction<CostFunctionState> getTypedKey() {
		if (key != null && key.eIsProxy()) {
			InternalEObject oldKey = (InternalEObject)key;
			key = (AbstractStatefulCostFunction<CostFunctionState>)eResolveProxy(oldKey);
			if (key != oldKey) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__KEY, oldKey, key));
			}
		}
		return key;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public AbstractStatefulCostFunction<CostFunctionState> basicGetTypedKey() {
		return key;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setTypedKey(AbstractStatefulCostFunction<CostFunctionState> newKey) {
		AbstractStatefulCostFunction<CostFunctionState> oldKey = key;
		key = newKey;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__KEY, oldKey, key));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public StatefulCostFunctionMapEntryValue getTypedValue() {
		return value;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetTypedValue(StatefulCostFunctionMapEntryValue newValue, NotificationChain msgs) {
		StatefulCostFunctionMapEntryValue oldValue = value;
		value = newValue;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__VALUE, oldValue, newValue);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setTypedValue(StatefulCostFunctionMapEntryValue newValue) {
		if (newValue != value) {
			NotificationChain msgs = null;
			if (value != null)
				msgs = ((InternalEObject)value).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__VALUE, null, msgs);
			if (newValue != null)
				msgs = ((InternalEObject)newValue).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__VALUE, null, msgs);
			msgs = basicSetTypedValue(newValue, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__VALUE, newValue, newValue));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__VALUE:
				return basicSetTypedValue(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 ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__KEY:
				if (resolve) return getTypedKey();
				return basicGetTypedKey();
			case ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__VALUE:
				return getTypedValue();
		}
		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 ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__KEY:
				setTypedKey((AbstractStatefulCostFunction<CostFunctionState>)newValue);
				return;
			case ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__VALUE:
				setTypedValue((StatefulCostFunctionMapEntryValue)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__KEY:
				setTypedKey((AbstractStatefulCostFunction<CostFunctionState>)null);
				return;
			case ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__VALUE:
				setTypedValue((StatefulCostFunctionMapEntryValue)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__KEY:
				return key != null;
			case ApogyCoreEnvironmentEarthOrbitPlannerPackage.STATEFUL_COST_FUNCTION_MAP_ENTRY__VALUE:
				return value != null;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected int hash = -1;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public int getHash() {
		if (hash == -1) {
			Object theKey = getKey();
			hash = (theKey == null ? 0 : theKey.hashCode());
		}
		return hash;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHash(int hash) {
		this.hash = hash;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public AbstractStatefulCostFunction<CostFunctionState> getKey() {
		return getTypedKey();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setKey(AbstractStatefulCostFunction<CostFunctionState> key) {
		setTypedKey(key);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public StatefulCostFunctionMapEntryValue getValue() {
		return getTypedValue();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public StatefulCostFunctionMapEntryValue setValue(StatefulCostFunctionMapEntryValue value) {
		StatefulCostFunctionMapEntryValue oldValue = getValue();
		setTypedValue(value);
		return oldValue;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	public EMap<AbstractStatefulCostFunction<CostFunctionState>, StatefulCostFunctionMapEntryValue> getEMap() {
		EObject container = eContainer();
		return container == null ? null : (EMap<AbstractStatefulCostFunction<CostFunctionState>, StatefulCostFunctionMapEntryValue>)container.eGet(eContainmentFeature());
	}

} //StatefulCostFunctionMapEntryImpl
