/**
 * 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 2.0  
 *  which accompanies this distribution, and is available at 
 *  https://www.eclipse.org/legal/epl-2.0/ 
 * 
 *  SPDX-License-Identifier: EPL-2.0 
 * 
 *  Based on ideas from Xtext, Xtend, Xcore
 *   
 *  Contributors:  
 *  		Florian Pirchner - Initial implementation 
 *  
 */
package org.eclipse.osbp.dsl.semantic.common.types.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.osbp.dsl.semantic.common.types.LAttribute;
import org.eclipse.osbp.dsl.semantic.common.types.LAttributeMatchingConstraint;
import org.eclipse.osbp.dsl.semantic.common.types.LComparatorType;
import org.eclipse.osbp.dsl.semantic.common.types.LEnumLiteral;
import org.eclipse.osbp.dsl.semantic.common.types.OSBPTypesPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>LAttribute Matching Constraint</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.common.types.impl.LAttributeMatchingConstraintImpl#getAttribute <em>Attribute</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.common.types.impl.LAttributeMatchingConstraintImpl#getComparatorType <em>Comparator Type</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.common.types.impl.LAttributeMatchingConstraintImpl#getMatchingValue <em>Matching Value</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.common.types.impl.LAttributeMatchingConstraintImpl#getMatchingLiteral <em>Matching Literal</em>}</li>
 * </ul>
 *
 * @generated
 */
public class LAttributeMatchingConstraintImpl extends LLazyResolverImpl implements LAttributeMatchingConstraint {
	/**
	 * The cached value of the '{@link #getAttribute() <em>Attribute</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAttribute()
	 * @generated
	 * @ordered
	 */
	protected LAttribute attribute;

	/**
	 * The default value of the '{@link #getComparatorType() <em>Comparator Type</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getComparatorType()
	 * @generated
	 * @ordered
	 */
	protected static final LComparatorType COMPARATOR_TYPE_EDEFAULT = LComparatorType.EQUALS;

	/**
	 * The cached value of the '{@link #getComparatorType() <em>Comparator Type</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getComparatorType()
	 * @generated
	 * @ordered
	 */
	protected LComparatorType comparatorType = COMPARATOR_TYPE_EDEFAULT;

	/**
	 * The default value of the '{@link #getMatchingValue() <em>Matching Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMatchingValue()
	 * @generated
	 * @ordered
	 */
	protected static final String MATCHING_VALUE_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getMatchingValue() <em>Matching Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMatchingValue()
	 * @generated
	 * @ordered
	 */
	protected String matchingValue = MATCHING_VALUE_EDEFAULT;

	/**
	 * The cached value of the '{@link #getMatchingLiteral() <em>Matching Literal</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMatchingLiteral()
	 * @generated
	 * @ordered
	 */
	protected LEnumLiteral matchingLiteral;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LAttribute getAttribute() {
		if (attribute != null && attribute.eIsProxy()) {
			InternalEObject oldAttribute = (InternalEObject)attribute;
			attribute = (LAttribute)eResolveProxy(oldAttribute);
			if (attribute != oldAttribute) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__ATTRIBUTE, oldAttribute, attribute));
			}
		}
		return attribute;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LAttribute basicGetAttribute() {
		return attribute;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setAttribute(LAttribute newAttribute) {
		LAttribute oldAttribute = attribute;
		attribute = newAttribute;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__ATTRIBUTE, oldAttribute, attribute));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LComparatorType getComparatorType() {
		return comparatorType;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setComparatorType(LComparatorType newComparatorType) {
		LComparatorType oldComparatorType = comparatorType;
		comparatorType = newComparatorType == null ? COMPARATOR_TYPE_EDEFAULT : newComparatorType;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__COMPARATOR_TYPE, oldComparatorType, comparatorType));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMatchingValue(String newMatchingValue) {
		String oldMatchingValue = matchingValue;
		matchingValue = newMatchingValue;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__MATCHING_VALUE, oldMatchingValue, matchingValue));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEnumLiteral getMatchingLiteral() {
		if (matchingLiteral != null && matchingLiteral.eIsProxy()) {
			InternalEObject oldMatchingLiteral = (InternalEObject)matchingLiteral;
			matchingLiteral = (LEnumLiteral)eResolveProxy(oldMatchingLiteral);
			if (matchingLiteral != oldMatchingLiteral) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__MATCHING_LITERAL, oldMatchingLiteral, matchingLiteral));
			}
		}
		return matchingLiteral;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEnumLiteral basicGetMatchingLiteral() {
		return matchingLiteral;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMatchingLiteral(LEnumLiteral newMatchingLiteral) {
		LEnumLiteral oldMatchingLiteral = matchingLiteral;
		matchingLiteral = newMatchingLiteral;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__MATCHING_LITERAL, oldMatchingLiteral, matchingLiteral));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__ATTRIBUTE:
				if (resolve) return getAttribute();
				return basicGetAttribute();
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__COMPARATOR_TYPE:
				return getComparatorType();
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__MATCHING_VALUE:
				return getMatchingValue();
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__MATCHING_LITERAL:
				if (resolve) return getMatchingLiteral();
				return basicGetMatchingLiteral();
		}
		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.LATTRIBUTE_MATCHING_CONSTRAINT__ATTRIBUTE:
				setAttribute((LAttribute)newValue);
				return;
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__COMPARATOR_TYPE:
				setComparatorType((LComparatorType)newValue);
				return;
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__MATCHING_VALUE:
				setMatchingValue((String)newValue);
				return;
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__MATCHING_LITERAL:
				setMatchingLiteral((LEnumLiteral)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__ATTRIBUTE:
				setAttribute((LAttribute)null);
				return;
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__COMPARATOR_TYPE:
				setComparatorType(COMPARATOR_TYPE_EDEFAULT);
				return;
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__MATCHING_VALUE:
				setMatchingValue(MATCHING_VALUE_EDEFAULT);
				return;
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__MATCHING_LITERAL:
				setMatchingLiteral((LEnumLiteral)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__ATTRIBUTE:
				return attribute != null;
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__COMPARATOR_TYPE:
				return comparatorType != COMPARATOR_TYPE_EDEFAULT;
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__MATCHING_VALUE:
				return MATCHING_VALUE_EDEFAULT == null ? matchingValue != null : !MATCHING_VALUE_EDEFAULT.equals(matchingValue);
			case OSBPTypesPackage.LATTRIBUTE_MATCHING_CONSTRAINT__MATCHING_LITERAL:
				return matchingLiteral != null;
		}
		return super.eIsSet(featureID);
	}

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

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (comparatorType: ");
		result.append(comparatorType);
		result.append(", matchingValue: ");
		result.append(matchingValue);
		result.append(')');
		return result.toString();
	}

} //LAttributeMatchingConstraintImpl
