/**
 * 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.Normalization_layers.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.Normalization_layers.GroupNorm;
import org.eclipse.papyrus.aiml.profile.AIML.Normalization_layers.Normalization_layersPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Group Norm</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.Normalization_layers.impl.GroupNormImpl#getNum_groups <em>Num groups</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.Normalization_layers.impl.GroupNormImpl#getNum_channels <em>Num channels</em>}</li>
 * </ul>
 *
 * @generated
 */
public class GroupNormImpl extends Normalization_layers_1_1Impl implements GroupNorm {
	/**
	 * The default value of the '{@link #getNum_groups() <em>Num groups</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNum_groups()
	 * @generated
	 * @ordered
	 */
	protected static final int NUM_GROUPS_EDEFAULT = 0;

	/**
	 * The cached value of the '{@link #getNum_groups() <em>Num groups</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNum_groups()
	 * @generated
	 * @ordered
	 */
	protected int num_groups = NUM_GROUPS_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getNum_channels() <em>Num channels</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNum_channels()
	 * @generated
	 * @ordered
	 */
	protected int num_channels = NUM_CHANNELS_EDEFAULT;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setNum_groups(int newNum_groups) {
		int oldNum_groups = num_groups;
		num_groups = newNum_groups;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Normalization_layersPackage.GROUP_NORM__NUM_GROUPS, oldNum_groups, num_groups));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setNum_channels(int newNum_channels) {
		int oldNum_channels = num_channels;
		num_channels = newNum_channels;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Normalization_layersPackage.GROUP_NORM__NUM_CHANNELS, oldNum_channels, num_channels));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case Normalization_layersPackage.GROUP_NORM__NUM_GROUPS:
				return getNum_groups();
			case Normalization_layersPackage.GROUP_NORM__NUM_CHANNELS:
				return getNum_channels();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case Normalization_layersPackage.GROUP_NORM__NUM_GROUPS:
				setNum_groups((Integer)newValue);
				return;
			case Normalization_layersPackage.GROUP_NORM__NUM_CHANNELS:
				setNum_channels((Integer)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case Normalization_layersPackage.GROUP_NORM__NUM_GROUPS:
				setNum_groups(NUM_GROUPS_EDEFAULT);
				return;
			case Normalization_layersPackage.GROUP_NORM__NUM_CHANNELS:
				setNum_channels(NUM_CHANNELS_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case Normalization_layersPackage.GROUP_NORM__NUM_GROUPS:
				return num_groups != NUM_GROUPS_EDEFAULT;
			case Normalization_layersPackage.GROUP_NORM__NUM_CHANNELS:
				return num_channels != NUM_CHANNELS_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(" (num_groups: "); //$NON-NLS-1$
		result.append(num_groups);
		result.append(", num_channels: "); //$NON-NLS-1$
		result.append(num_channels);
		result.append(')');
		return result.toString();
	}

} //GroupNormImpl
