/**
 * Copyright (c) 2011, 2014 - 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:  
 *  		José C. Domínguez - Initial implementation
 *  
 */
package org.eclipse.osbp.xtext.cubedsl.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.entity.LEntity;
import org.eclipse.osbp.dsl.semantic.entity.LEntityFeature;

import org.eclipse.osbp.xtext.cubedsl.CubeDSLPackage;
import org.eclipse.osbp.xtext.cubedsl.CubeEntity;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Cube Entity</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.cubedsl.impl.CubeEntityImpl#isKey <em>Key</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.cubedsl.impl.CubeEntityImpl#getEntityValue <em>Entity Value</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.cubedsl.impl.CubeEntityImpl#getKeyValue <em>Key Value</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class CubeEntityImpl extends CubeLazyResolverImpl implements CubeEntity {
	/**
	 * The default value of the '{@link #isKey() <em>Key</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isKey()
	 * @generated
	 * @ordered
	 */
	protected static final boolean KEY_EDEFAULT = false;

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

	/**
	 * The cached value of the '{@link #getEntityValue() <em>Entity Value</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEntityValue()
	 * @generated
	 * @ordered
	 */
	protected LEntity entityValue;

	/**
	 * The cached value of the '{@link #getKeyValue() <em>Key Value</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getKeyValue()
	 * @generated
	 * @ordered
	 */
	protected LEntityFeature keyValue;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setKey(boolean newKey) {
		boolean oldKey = key;
		key = newKey;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CubeDSLPackage.CUBE_ENTITY__KEY, oldKey, key));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntity getEntityValue() {
		if (entityValue != null && entityValue.eIsProxy()) {
			InternalEObject oldEntityValue = (InternalEObject)entityValue;
			entityValue = (LEntity)eResolveProxy(oldEntityValue);
			if (entityValue != oldEntityValue) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, CubeDSLPackage.CUBE_ENTITY__ENTITY_VALUE, oldEntityValue, entityValue));
			}
		}
		return entityValue;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntity basicGetEntityValue() {
		return entityValue;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setEntityValue(LEntity newEntityValue) {
		LEntity oldEntityValue = entityValue;
		entityValue = newEntityValue;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CubeDSLPackage.CUBE_ENTITY__ENTITY_VALUE, oldEntityValue, entityValue));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityFeature getKeyValue() {
		if (keyValue != null && keyValue.eIsProxy()) {
			InternalEObject oldKeyValue = (InternalEObject)keyValue;
			keyValue = (LEntityFeature)eResolveProxy(oldKeyValue);
			if (keyValue != oldKeyValue) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, CubeDSLPackage.CUBE_ENTITY__KEY_VALUE, oldKeyValue, keyValue));
			}
		}
		return keyValue;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityFeature basicGetKeyValue() {
		return keyValue;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setKeyValue(LEntityFeature newKeyValue) {
		LEntityFeature oldKeyValue = keyValue;
		keyValue = newKeyValue;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CubeDSLPackage.CUBE_ENTITY__KEY_VALUE, oldKeyValue, keyValue));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case CubeDSLPackage.CUBE_ENTITY__KEY:
				return isKey();
			case CubeDSLPackage.CUBE_ENTITY__ENTITY_VALUE:
				if (resolve) return getEntityValue();
				return basicGetEntityValue();
			case CubeDSLPackage.CUBE_ENTITY__KEY_VALUE:
				if (resolve) return getKeyValue();
				return basicGetKeyValue();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case CubeDSLPackage.CUBE_ENTITY__KEY:
				setKey((Boolean)newValue);
				return;
			case CubeDSLPackage.CUBE_ENTITY__ENTITY_VALUE:
				setEntityValue((LEntity)newValue);
				return;
			case CubeDSLPackage.CUBE_ENTITY__KEY_VALUE:
				setKeyValue((LEntityFeature)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case CubeDSLPackage.CUBE_ENTITY__KEY:
				setKey(KEY_EDEFAULT);
				return;
			case CubeDSLPackage.CUBE_ENTITY__ENTITY_VALUE:
				setEntityValue((LEntity)null);
				return;
			case CubeDSLPackage.CUBE_ENTITY__KEY_VALUE:
				setKeyValue((LEntityFeature)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case CubeDSLPackage.CUBE_ENTITY__KEY:
				return key != KEY_EDEFAULT;
			case CubeDSLPackage.CUBE_ENTITY__ENTITY_VALUE:
				return entityValue != null;
			case CubeDSLPackage.CUBE_ENTITY__KEY_VALUE:
				return keyValue != 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(" (key: ");
		result.append(key);
		result.append(')');
		return result.toString();
	}

} //CubeEntityImpl
