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

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

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

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

import org.eclipse.papyrus.aiml.profile.AIML.Transformer_layers.Transformer;
import org.eclipse.papyrus.aiml.profile.AIML.Transformer_layers.TransformerDecoder;
import org.eclipse.papyrus.aiml.profile.AIML.Transformer_layers.TransformerEncoder;
import org.eclipse.papyrus.aiml.profile.AIML.Transformer_layers.Transformer_layersPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Transformer</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.Transformer_layers.impl.TransformerImpl#getNum_encoder_layers <em>Num encoder layers</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.Transformer_layers.impl.TransformerImpl#getNum_decoder_layers <em>Num decoder layers</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.Transformer_layers.impl.TransformerImpl#getCustom_encoder <em>Custom encoder</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aiml.profile.AIML.Transformer_layers.impl.TransformerImpl#getCustom_decoder <em>Custom decoder</em>}</li>
 * </ul>
 *
 * @generated
 */
public class TransformerImpl extends Transformer_layers_1Impl implements Transformer {
	/**
	 * The default value of the '{@link #getNum_encoder_layers() <em>Num encoder layers</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNum_encoder_layers()
	 * @generated
	 * @ordered
	 */
	protected static final int NUM_ENCODER_LAYERS_EDEFAULT = 0;

	/**
	 * The cached value of the '{@link #getNum_encoder_layers() <em>Num encoder layers</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNum_encoder_layers()
	 * @generated
	 * @ordered
	 */
	protected int num_encoder_layers = NUM_ENCODER_LAYERS_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getNum_decoder_layers() <em>Num decoder layers</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNum_decoder_layers()
	 * @generated
	 * @ordered
	 */
	protected int num_decoder_layers = NUM_DECODER_LAYERS_EDEFAULT;

	/**
	 * The cached value of the '{@link #getCustom_encoder() <em>Custom encoder</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCustom_encoder()
	 * @generated
	 * @ordered
	 */
	protected TransformerEncoder custom_encoder;

	/**
	 * The cached value of the '{@link #getCustom_decoder() <em>Custom decoder</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCustom_decoder()
	 * @generated
	 * @ordered
	 */
	protected TransformerDecoder custom_decoder;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setNum_encoder_layers(int newNum_encoder_layers) {
		int oldNum_encoder_layers = num_encoder_layers;
		num_encoder_layers = newNum_encoder_layers;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Transformer_layersPackage.TRANSFORMER__NUM_ENCODER_LAYERS, oldNum_encoder_layers, num_encoder_layers));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setNum_decoder_layers(int newNum_decoder_layers) {
		int oldNum_decoder_layers = num_decoder_layers;
		num_decoder_layers = newNum_decoder_layers;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Transformer_layersPackage.TRANSFORMER__NUM_DECODER_LAYERS, oldNum_decoder_layers, num_decoder_layers));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public TransformerEncoder getCustom_encoder() {
		if (custom_encoder != null && custom_encoder.eIsProxy()) {
			InternalEObject oldCustom_encoder = (InternalEObject)custom_encoder;
			custom_encoder = (TransformerEncoder)eResolveProxy(oldCustom_encoder);
			if (custom_encoder != oldCustom_encoder) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, Transformer_layersPackage.TRANSFORMER__CUSTOM_ENCODER, oldCustom_encoder, custom_encoder));
			}
		}
		return custom_encoder;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public TransformerEncoder basicGetCustom_encoder() {
		return custom_encoder;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setCustom_encoder(TransformerEncoder newCustom_encoder) {
		TransformerEncoder oldCustom_encoder = custom_encoder;
		custom_encoder = newCustom_encoder;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Transformer_layersPackage.TRANSFORMER__CUSTOM_ENCODER, oldCustom_encoder, custom_encoder));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public TransformerDecoder getCustom_decoder() {
		if (custom_decoder != null && custom_decoder.eIsProxy()) {
			InternalEObject oldCustom_decoder = (InternalEObject)custom_decoder;
			custom_decoder = (TransformerDecoder)eResolveProxy(oldCustom_decoder);
			if (custom_decoder != oldCustom_decoder) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, Transformer_layersPackage.TRANSFORMER__CUSTOM_DECODER, oldCustom_decoder, custom_decoder));
			}
		}
		return custom_decoder;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public TransformerDecoder basicGetCustom_decoder() {
		return custom_decoder;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setCustom_decoder(TransformerDecoder newCustom_decoder) {
		TransformerDecoder oldCustom_decoder = custom_decoder;
		custom_decoder = newCustom_decoder;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, Transformer_layersPackage.TRANSFORMER__CUSTOM_DECODER, oldCustom_decoder, custom_decoder));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case Transformer_layersPackage.TRANSFORMER__NUM_ENCODER_LAYERS:
				return getNum_encoder_layers();
			case Transformer_layersPackage.TRANSFORMER__NUM_DECODER_LAYERS:
				return getNum_decoder_layers();
			case Transformer_layersPackage.TRANSFORMER__CUSTOM_ENCODER:
				if (resolve) return getCustom_encoder();
				return basicGetCustom_encoder();
			case Transformer_layersPackage.TRANSFORMER__CUSTOM_DECODER:
				if (resolve) return getCustom_decoder();
				return basicGetCustom_decoder();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case Transformer_layersPackage.TRANSFORMER__NUM_ENCODER_LAYERS:
				setNum_encoder_layers((Integer)newValue);
				return;
			case Transformer_layersPackage.TRANSFORMER__NUM_DECODER_LAYERS:
				setNum_decoder_layers((Integer)newValue);
				return;
			case Transformer_layersPackage.TRANSFORMER__CUSTOM_ENCODER:
				setCustom_encoder((TransformerEncoder)newValue);
				return;
			case Transformer_layersPackage.TRANSFORMER__CUSTOM_DECODER:
				setCustom_decoder((TransformerDecoder)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case Transformer_layersPackage.TRANSFORMER__NUM_ENCODER_LAYERS:
				setNum_encoder_layers(NUM_ENCODER_LAYERS_EDEFAULT);
				return;
			case Transformer_layersPackage.TRANSFORMER__NUM_DECODER_LAYERS:
				setNum_decoder_layers(NUM_DECODER_LAYERS_EDEFAULT);
				return;
			case Transformer_layersPackage.TRANSFORMER__CUSTOM_ENCODER:
				setCustom_encoder((TransformerEncoder)null);
				return;
			case Transformer_layersPackage.TRANSFORMER__CUSTOM_DECODER:
				setCustom_decoder((TransformerDecoder)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case Transformer_layersPackage.TRANSFORMER__NUM_ENCODER_LAYERS:
				return num_encoder_layers != NUM_ENCODER_LAYERS_EDEFAULT;
			case Transformer_layersPackage.TRANSFORMER__NUM_DECODER_LAYERS:
				return num_decoder_layers != NUM_DECODER_LAYERS_EDEFAULT;
			case Transformer_layersPackage.TRANSFORMER__CUSTOM_ENCODER:
				return custom_encoder != null;
			case Transformer_layersPackage.TRANSFORMER__CUSTOM_DECODER:
				return custom_decoder != null;
		}
		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_encoder_layers: "); //$NON-NLS-1$
		result.append(num_encoder_layers);
		result.append(", num_decoder_layers: "); //$NON-NLS-1$
		result.append(num_decoder_layers);
		result.append(')');
		return result.toString();
	}

} //TransformerImpl
