/**
 * 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.Sparse_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.Module.impl.ModelImpl;
import org.eclipse.papyrus.aiml.profile.AIML.Sparse_layers.Sparse_layers;
import org.eclipse.papyrus.aiml.profile.AIML.Sparse_layers.Sparse_layersPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Sparse layers</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.Sparse_layers.impl.Sparse_layersImpl#getNum_embeddings <em>Num embeddings</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.Sparse_layers.impl.Sparse_layersImpl#getEmbedding_dim <em>Embedding dim</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.Sparse_layers.impl.Sparse_layersImpl#getMax_norm <em>Max norm</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.Sparse_layers.impl.Sparse_layersImpl#getNorm_type <em>Norm type</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.Sparse_layers.impl.Sparse_layersImpl#isSparse <em>Sparse</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.Sparse_layers.impl.Sparse_layersImpl#isScale_grad_by_freq <em>Scale grad by freq</em>}</li>
 * </ul>
 *
 * @generated
 */
public abstract class Sparse_layersImpl extends ModelImpl implements Sparse_layers {
	/**
	 * The default value of the '{@link #getNum_embeddings() <em>Num embeddings</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNum_embeddings()
	 * @generated
	 * @ordered
	 */
	protected static final int NUM_EMBEDDINGS_EDEFAULT = 0;

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

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

	/**
	 * The cached value of the '{@link #getEmbedding_dim() <em>Embedding dim</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEmbedding_dim()
	 * @generated
	 * @ordered
	 */
	protected int embedding_dim = EMBEDDING_DIM_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getMax_norm() <em>Max norm</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMax_norm()
	 * @generated
	 * @ordered
	 */
	protected double max_norm = MAX_NORM_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getNorm_type() <em>Norm type</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNorm_type()
	 * @generated
	 * @ordered
	 */
	protected double norm_type = NORM_TYPE_EDEFAULT;

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

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

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

	/**
	 * The cached value of the '{@link #isScale_grad_by_freq() <em>Scale grad by freq</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isScale_grad_by_freq()
	 * @generated
	 * @ordered
	 */
	protected boolean scale_grad_by_freq = SCALE_GRAD_BY_FREQ_EDEFAULT;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setNum_embeddings(int newNum_embeddings) {
		int oldNum_embeddings = num_embeddings;
		num_embeddings = newNum_embeddings;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Sparse_layersPackage.SPARSE_LAYERS__NUM_EMBEDDINGS, oldNum_embeddings, num_embeddings));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setEmbedding_dim(int newEmbedding_dim) {
		int oldEmbedding_dim = embedding_dim;
		embedding_dim = newEmbedding_dim;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Sparse_layersPackage.SPARSE_LAYERS__EMBEDDING_DIM, oldEmbedding_dim, embedding_dim));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setMax_norm(double newMax_norm) {
		double oldMax_norm = max_norm;
		max_norm = newMax_norm;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Sparse_layersPackage.SPARSE_LAYERS__MAX_NORM, oldMax_norm, max_norm));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setNorm_type(double newNorm_type) {
		double oldNorm_type = norm_type;
		norm_type = newNorm_type;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Sparse_layersPackage.SPARSE_LAYERS__NORM_TYPE, oldNorm_type, norm_type));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setSparse(boolean newSparse) {
		boolean oldSparse = sparse;
		sparse = newSparse;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Sparse_layersPackage.SPARSE_LAYERS__SPARSE, oldSparse, sparse));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setScale_grad_by_freq(boolean newScale_grad_by_freq) {
		boolean oldScale_grad_by_freq = scale_grad_by_freq;
		scale_grad_by_freq = newScale_grad_by_freq;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Sparse_layersPackage.SPARSE_LAYERS__SCALE_GRAD_BY_FREQ, oldScale_grad_by_freq, scale_grad_by_freq));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case Sparse_layersPackage.SPARSE_LAYERS__NUM_EMBEDDINGS:
				return getNum_embeddings();
			case Sparse_layersPackage.SPARSE_LAYERS__EMBEDDING_DIM:
				return getEmbedding_dim();
			case Sparse_layersPackage.SPARSE_LAYERS__MAX_NORM:
				return getMax_norm();
			case Sparse_layersPackage.SPARSE_LAYERS__NORM_TYPE:
				return getNorm_type();
			case Sparse_layersPackage.SPARSE_LAYERS__SPARSE:
				return isSparse();
			case Sparse_layersPackage.SPARSE_LAYERS__SCALE_GRAD_BY_FREQ:
				return isScale_grad_by_freq();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case Sparse_layersPackage.SPARSE_LAYERS__NUM_EMBEDDINGS:
				setNum_embeddings((Integer)newValue);
				return;
			case Sparse_layersPackage.SPARSE_LAYERS__EMBEDDING_DIM:
				setEmbedding_dim((Integer)newValue);
				return;
			case Sparse_layersPackage.SPARSE_LAYERS__MAX_NORM:
				setMax_norm((Double)newValue);
				return;
			case Sparse_layersPackage.SPARSE_LAYERS__NORM_TYPE:
				setNorm_type((Double)newValue);
				return;
			case Sparse_layersPackage.SPARSE_LAYERS__SPARSE:
				setSparse((Boolean)newValue);
				return;
			case Sparse_layersPackage.SPARSE_LAYERS__SCALE_GRAD_BY_FREQ:
				setScale_grad_by_freq((Boolean)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case Sparse_layersPackage.SPARSE_LAYERS__NUM_EMBEDDINGS:
				setNum_embeddings(NUM_EMBEDDINGS_EDEFAULT);
				return;
			case Sparse_layersPackage.SPARSE_LAYERS__EMBEDDING_DIM:
				setEmbedding_dim(EMBEDDING_DIM_EDEFAULT);
				return;
			case Sparse_layersPackage.SPARSE_LAYERS__MAX_NORM:
				setMax_norm(MAX_NORM_EDEFAULT);
				return;
			case Sparse_layersPackage.SPARSE_LAYERS__NORM_TYPE:
				setNorm_type(NORM_TYPE_EDEFAULT);
				return;
			case Sparse_layersPackage.SPARSE_LAYERS__SPARSE:
				setSparse(SPARSE_EDEFAULT);
				return;
			case Sparse_layersPackage.SPARSE_LAYERS__SCALE_GRAD_BY_FREQ:
				setScale_grad_by_freq(SCALE_GRAD_BY_FREQ_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case Sparse_layersPackage.SPARSE_LAYERS__NUM_EMBEDDINGS:
				return num_embeddings != NUM_EMBEDDINGS_EDEFAULT;
			case Sparse_layersPackage.SPARSE_LAYERS__EMBEDDING_DIM:
				return embedding_dim != EMBEDDING_DIM_EDEFAULT;
			case Sparse_layersPackage.SPARSE_LAYERS__MAX_NORM:
				return max_norm != MAX_NORM_EDEFAULT;
			case Sparse_layersPackage.SPARSE_LAYERS__NORM_TYPE:
				return norm_type != NORM_TYPE_EDEFAULT;
			case Sparse_layersPackage.SPARSE_LAYERS__SPARSE:
				return sparse != SPARSE_EDEFAULT;
			case Sparse_layersPackage.SPARSE_LAYERS__SCALE_GRAD_BY_FREQ:
				return scale_grad_by_freq != SCALE_GRAD_BY_FREQ_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_embeddings: "); //$NON-NLS-1$
		result.append(num_embeddings);
		result.append(", embedding_dim: "); //$NON-NLS-1$
		result.append(embedding_dim);
		result.append(", max_norm: "); //$NON-NLS-1$
		result.append(max_norm);
		result.append(", norm_type: "); //$NON-NLS-1$
		result.append(norm_type);
		result.append(", sparse: "); //$NON-NLS-1$
		result.append(sparse);
		result.append(", scale_grad_by_freq: "); //$NON-NLS-1$
		result.append(scale_grad_by_freq);
		result.append(')');
		return result.toString();
	}

} //Sparse_layersImpl
