/**
 * 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.Loss_functions.impl;

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

import org.eclipse.emf.ecore.EClass;

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

import org.eclipse.papyrus.aiml.profile.AIML.Loss_functions.Loss_functionsPackage;
import org.eclipse.papyrus.aiml.profile.AIML.Loss_functions.Loss_functions_1;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Loss functions 1</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.Loss_functions.impl.Loss_functions_1Impl#isSize_average <em>Size average</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.Loss_functions.impl.Loss_functions_1Impl#isReduce <em>Reduce</em>}</li>
 * </ul>
 *
 * @generated
 */
public abstract class Loss_functions_1Impl extends Loss_functionsImpl implements Loss_functions_1 {
	/**
	 * The default value of the '{@link #isSize_average() <em>Size average</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isSize_average()
	 * @generated
	 * @ordered
	 */
	protected static final boolean SIZE_AVERAGE_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isSize_average() <em>Size average</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isSize_average()
	 * @generated
	 * @ordered
	 */
	protected boolean size_average = SIZE_AVERAGE_EDEFAULT;

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

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

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setSize_average(boolean newSize_average) {
		boolean oldSize_average = size_average;
		size_average = newSize_average;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Loss_functionsPackage.LOSS_FUNCTIONS_1__SIZE_AVERAGE, oldSize_average, size_average));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setReduce(boolean newReduce) {
		boolean oldReduce = reduce;
		reduce = newReduce;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Loss_functionsPackage.LOSS_FUNCTIONS_1__REDUCE, oldReduce, reduce));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case Loss_functionsPackage.LOSS_FUNCTIONS_1__SIZE_AVERAGE:
				return isSize_average();
			case Loss_functionsPackage.LOSS_FUNCTIONS_1__REDUCE:
				return isReduce();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case Loss_functionsPackage.LOSS_FUNCTIONS_1__SIZE_AVERAGE:
				setSize_average((Boolean)newValue);
				return;
			case Loss_functionsPackage.LOSS_FUNCTIONS_1__REDUCE:
				setReduce((Boolean)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case Loss_functionsPackage.LOSS_FUNCTIONS_1__SIZE_AVERAGE:
				setSize_average(SIZE_AVERAGE_EDEFAULT);
				return;
			case Loss_functionsPackage.LOSS_FUNCTIONS_1__REDUCE:
				setReduce(REDUCE_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case Loss_functionsPackage.LOSS_FUNCTIONS_1__SIZE_AVERAGE:
				return size_average != SIZE_AVERAGE_EDEFAULT;
			case Loss_functionsPackage.LOSS_FUNCTIONS_1__REDUCE:
				return reduce != REDUCE_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(" (size_average: "); //$NON-NLS-1$
		result.append(size_average);
		result.append(", reduce: "); //$NON-NLS-1$
		result.append(reduce);
		result.append(')');
		return result.toString();
	}

} //Loss_functions_1Impl
