/**
 * Copyright (c) 2020 CEA LIST
 * 
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v2.0 which
 * accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 * 
 * SPDX-License-Identifier: EPL-2.0
 * 
 */
package org.eclipse.papyrus.aiml.profile.AIML.SoftMinMaxActivations.impl;

import java.util.Collection;

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

import org.eclipse.emf.common.util.EList;

import org.eclipse.emf.ecore.EClass;

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

import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;

import org.eclipse.papyrus.aiml.profile.AIML.SoftMinMaxActivations.AdaptiveLogSoftmaxWithLoss;
import org.eclipse.papyrus.aiml.profile.AIML.SoftMinMaxActivations.SoftMinMaxActivationsPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Adaptive Log Softmax With Loss</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.SoftMinMaxActivations.impl.AdaptiveLogSoftmaxWithLossImpl#getIn_features <em>In features</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.SoftMinMaxActivations.impl.AdaptiveLogSoftmaxWithLossImpl#getN_classes <em>Nclasses</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.SoftMinMaxActivations.impl.AdaptiveLogSoftmaxWithLossImpl#getCutoffs <em>Cutoffs</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.SoftMinMaxActivations.impl.AdaptiveLogSoftmaxWithLossImpl#getDiv_value <em>Div value</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.SoftMinMaxActivations.impl.AdaptiveLogSoftmaxWithLossImpl#isHead_biais <em>Head biais</em>}</li>
 * </ul>
 *
 * @generated
 */
public class AdaptiveLogSoftmaxWithLossImpl extends SoftMinMaxImpl implements AdaptiveLogSoftmaxWithLoss {
	/**
	 * The default value of the '{@link #getIn_features() <em>In features</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIn_features()
	 * @generated
	 * @ordered
	 */
	protected static final int IN_FEATURES_EDEFAULT = 0;

	/**
	 * The cached value of the '{@link #getIn_features() <em>In features</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIn_features()
	 * @generated
	 * @ordered
	 */
	protected int in_features = IN_FEATURES_EDEFAULT;

	/**
	 * The default value of the '{@link #getN_classes() <em>Nclasses</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getN_classes()
	 * @generated
	 * @ordered
	 */
	protected static final int NCLASSES_EDEFAULT = 0;

	/**
	 * The cached value of the '{@link #getN_classes() <em>Nclasses</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getN_classes()
	 * @generated
	 * @ordered
	 */
	protected int n_classes = NCLASSES_EDEFAULT;

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

	/**
	 * The default value of the '{@link #getDiv_value() <em>Div value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDiv_value()
	 * @generated
	 * @ordered
	 */
	protected static final double DIV_VALUE_EDEFAULT = 0.0;

	/**
	 * The cached value of the '{@link #getDiv_value() <em>Div value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDiv_value()
	 * @generated
	 * @ordered
	 */
	protected double div_value = DIV_VALUE_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #isHead_biais() <em>Head biais</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHead_biais()
	 * @generated
	 * @ordered
	 */
	protected boolean head_biais = HEAD_BIAIS_EDEFAULT;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int getIn_features() {
		return in_features;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setIn_features(int newIn_features) {
		int oldIn_features = in_features;
		in_features = newIn_features;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__IN_FEATURES, oldIn_features, in_features));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int getN_classes() {
		return n_classes;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setN_classes(int newN_classes) {
		int oldN_classes = n_classes;
		n_classes = newN_classes;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__NCLASSES, oldN_classes, n_classes));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<Integer> getCutoffs() {
		if (cutoffs == null) {
			cutoffs = new EDataTypeUniqueEList<Integer>(Integer.class, this, SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__CUTOFFS);
		}
		return cutoffs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public double getDiv_value() {
		return div_value;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setDiv_value(double newDiv_value) {
		double oldDiv_value = div_value;
		div_value = newDiv_value;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__DIV_VALUE, oldDiv_value, div_value));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setHead_biais(boolean newHead_biais) {
		boolean oldHead_biais = head_biais;
		head_biais = newHead_biais;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__HEAD_BIAIS, oldHead_biais, head_biais));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__IN_FEATURES:
				return getIn_features();
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__NCLASSES:
				return getN_classes();
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__CUTOFFS:
				return getCutoffs();
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__DIV_VALUE:
				return getDiv_value();
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__HEAD_BIAIS:
				return isHead_biais();
		}
		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 SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__IN_FEATURES:
				setIn_features((Integer)newValue);
				return;
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__NCLASSES:
				setN_classes((Integer)newValue);
				return;
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__CUTOFFS:
				getCutoffs().clear();
				getCutoffs().addAll((Collection<? extends Integer>)newValue);
				return;
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__DIV_VALUE:
				setDiv_value((Double)newValue);
				return;
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__HEAD_BIAIS:
				setHead_biais((Boolean)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__IN_FEATURES:
				setIn_features(IN_FEATURES_EDEFAULT);
				return;
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__NCLASSES:
				setN_classes(NCLASSES_EDEFAULT);
				return;
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__CUTOFFS:
				getCutoffs().clear();
				return;
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__DIV_VALUE:
				setDiv_value(DIV_VALUE_EDEFAULT);
				return;
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__HEAD_BIAIS:
				setHead_biais(HEAD_BIAIS_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__IN_FEATURES:
				return in_features != IN_FEATURES_EDEFAULT;
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__NCLASSES:
				return n_classes != NCLASSES_EDEFAULT;
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__CUTOFFS:
				return cutoffs != null && !cutoffs.isEmpty();
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__DIV_VALUE:
				return div_value != DIV_VALUE_EDEFAULT;
			case SoftMinMaxActivationsPackage.ADAPTIVE_LOG_SOFTMAX_WITH_LOSS__HEAD_BIAIS:
				return head_biais != HEAD_BIAIS_EDEFAULT;
		}
		return super.eIsSet(featureID);
	}

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

		StringBuilder result = new StringBuilder(super.toString());
		result.append(" (in_features: "); //$NON-NLS-1$
		result.append(in_features);
		result.append(", n_classes: "); //$NON-NLS-1$
		result.append(n_classes);
		result.append(", cutoffs: "); //$NON-NLS-1$
		result.append(cutoffs);
		result.append(", div_value: "); //$NON-NLS-1$
		result.append(div_value);
		result.append(", head_biais: "); //$NON-NLS-1$
		result.append(head_biais);
		result.append(')');
		return result.toString();
	}

} //AdaptiveLogSoftmaxWithLossImpl
