/**
 * Copyright (c) 2011, 2016 - Lunifera GmbH (Wien), Loetz GmbH&Co.KG (Heidelberg)
 *  All rights reserved. This program and the accompanying materials 
 *  are made available under the terms of the Eclipse Public License v1.0 
 *  which accompanies this distribution, and is available at 
 *  http://www.eclipse.org/legal/epl-v10.html 
 * 
 *  Based on ideas from Xtext, Xtend, Xcore
 *   
 *  Contributors:  
 *  		Florian Pirchner - Initial implementation 
 *  
 */
package org.eclipse.osbp.dsl.semantic.common.types.impl;

import java.lang.reflect.InvocationTargetException;

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.osbp.dsl.semantic.common.types.LConstraintSeverity;
import org.eclipse.osbp.dsl.semantic.common.types.LDtCDigits;
import org.eclipse.osbp.dsl.semantic.common.types.OSBPTypesPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>LDt CDigits</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.common.types.impl.LDtCDigitsImpl#getMsgCode <em>Msg Code</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.common.types.impl.LDtCDigitsImpl#getMsgI18nKey <em>Msg I1 8n Key</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.common.types.impl.LDtCDigitsImpl#getSeverity <em>Severity</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.common.types.impl.LDtCDigitsImpl#getIntDigits <em>Int Digits</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.common.types.impl.LDtCDigitsImpl#getFractionDigits <em>Fraction Digits</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class LDtCDigitsImpl extends LLazyResolverImpl implements LDtCDigits {
	/**
	 * The default value of the '{@link #getMsgCode() <em>Msg Code</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMsgCode()
	 * @generated
	 * @ordered
	 */
	protected static final String MSG_CODE_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getMsgCode() <em>Msg Code</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMsgCode()
	 * @generated
	 * @ordered
	 */
	protected String msgCode = MSG_CODE_EDEFAULT;

	/**
	 * The default value of the '{@link #getMsgI18nKey() <em>Msg I1 8n Key</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMsgI18nKey()
	 * @generated
	 * @ordered
	 */
	protected static final String MSG_I1_8N_KEY_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getMsgI18nKey() <em>Msg I1 8n Key</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMsgI18nKey()
	 * @generated
	 * @ordered
	 */
	protected String msgI18nKey = MSG_I1_8N_KEY_EDEFAULT;

	/**
	 * The default value of the '{@link #getSeverity() <em>Severity</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSeverity()
	 * @generated
	 * @ordered
	 */
	protected static final LConstraintSeverity SEVERITY_EDEFAULT = LConstraintSeverity.INFO;

	/**
	 * The cached value of the '{@link #getSeverity() <em>Severity</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSeverity()
	 * @generated
	 * @ordered
	 */
	protected LConstraintSeverity severity = SEVERITY_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getIntDigits() <em>Int Digits</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIntDigits()
	 * @generated
	 * @ordered
	 */
	protected int intDigits = INT_DIGITS_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getFractionDigits() <em>Fraction Digits</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFractionDigits()
	 * @generated
	 * @ordered
	 */
	protected int fractionDigits = FRACTION_DIGITS_EDEFAULT;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String getMsgCode() {
		return msgCode;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMsgCode(String newMsgCode) {
		String oldMsgCode = msgCode;
		msgCode = newMsgCode;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPTypesPackage.LDT_CDIGITS__MSG_CODE, oldMsgCode, msgCode));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String getMsgI18nKey() {
		return msgI18nKey;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMsgI18nKey(String newMsgI18nKey) {
		String oldMsgI18nKey = msgI18nKey;
		msgI18nKey = newMsgI18nKey;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPTypesPackage.LDT_CDIGITS__MSG_I1_8N_KEY, oldMsgI18nKey, msgI18nKey));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LConstraintSeverity getSeverity() {
		return severity;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setSeverity(LConstraintSeverity newSeverity) {
		LConstraintSeverity oldSeverity = severity;
		severity = newSeverity == null ? SEVERITY_EDEFAULT : newSeverity;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPTypesPackage.LDT_CDIGITS__SEVERITY, oldSeverity, severity));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setIntDigits(int newIntDigits) {
		int oldIntDigits = intDigits;
		intDigits = newIntDigits;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPTypesPackage.LDT_CDIGITS__INT_DIGITS, oldIntDigits, intDigits));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setFractionDigits(int newFractionDigits) {
		int oldFractionDigits = fractionDigits;
		fractionDigits = newFractionDigits;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPTypesPackage.LDT_CDIGITS__FRACTION_DIGITS, oldFractionDigits, fractionDigits));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case OSBPTypesPackage.LDT_CDIGITS__MSG_CODE:
				return getMsgCode();
			case OSBPTypesPackage.LDT_CDIGITS__MSG_I1_8N_KEY:
				return getMsgI18nKey();
			case OSBPTypesPackage.LDT_CDIGITS__SEVERITY:
				return getSeverity();
			case OSBPTypesPackage.LDT_CDIGITS__INT_DIGITS:
				return getIntDigits();
			case OSBPTypesPackage.LDT_CDIGITS__FRACTION_DIGITS:
				return getFractionDigits();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case OSBPTypesPackage.LDT_CDIGITS__MSG_CODE:
				setMsgCode((String)newValue);
				return;
			case OSBPTypesPackage.LDT_CDIGITS__MSG_I1_8N_KEY:
				setMsgI18nKey((String)newValue);
				return;
			case OSBPTypesPackage.LDT_CDIGITS__SEVERITY:
				setSeverity((LConstraintSeverity)newValue);
				return;
			case OSBPTypesPackage.LDT_CDIGITS__INT_DIGITS:
				setIntDigits((Integer)newValue);
				return;
			case OSBPTypesPackage.LDT_CDIGITS__FRACTION_DIGITS:
				setFractionDigits((Integer)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case OSBPTypesPackage.LDT_CDIGITS__MSG_CODE:
				setMsgCode(MSG_CODE_EDEFAULT);
				return;
			case OSBPTypesPackage.LDT_CDIGITS__MSG_I1_8N_KEY:
				setMsgI18nKey(MSG_I1_8N_KEY_EDEFAULT);
				return;
			case OSBPTypesPackage.LDT_CDIGITS__SEVERITY:
				setSeverity(SEVERITY_EDEFAULT);
				return;
			case OSBPTypesPackage.LDT_CDIGITS__INT_DIGITS:
				setIntDigits(INT_DIGITS_EDEFAULT);
				return;
			case OSBPTypesPackage.LDT_CDIGITS__FRACTION_DIGITS:
				setFractionDigits(FRACTION_DIGITS_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case OSBPTypesPackage.LDT_CDIGITS__MSG_CODE:
				return MSG_CODE_EDEFAULT == null ? msgCode != null : !MSG_CODE_EDEFAULT.equals(msgCode);
			case OSBPTypesPackage.LDT_CDIGITS__MSG_I1_8N_KEY:
				return MSG_I1_8N_KEY_EDEFAULT == null ? msgI18nKey != null : !MSG_I1_8N_KEY_EDEFAULT.equals(msgI18nKey);
			case OSBPTypesPackage.LDT_CDIGITS__SEVERITY:
				return severity != SEVERITY_EDEFAULT;
			case OSBPTypesPackage.LDT_CDIGITS__INT_DIGITS:
				return intDigits != INT_DIGITS_EDEFAULT;
			case OSBPTypesPackage.LDT_CDIGITS__FRACTION_DIGITS:
				return fractionDigits != FRACTION_DIGITS_EDEFAULT;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException {
		switch (operationID) {
			case OSBPTypesPackage.LDT_CDIGITS___IS_FOR_PRIMITIVES:
				return isForPrimitives();
		}
		return super.eInvoke(operationID, arguments);
	}

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

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (msgCode: ");
		result.append(msgCode);
		result.append(", msgI18nKey: ");
		result.append(msgI18nKey);
		result.append(", severity: ");
		result.append(severity);
		result.append(", intDigits: ");
		result.append(intDigits);
		result.append(", fractionDigits: ");
		result.append(fractionDigits);
		result.append(')');
		return result.toString();
	}

} //LDtCDigitsImpl
