/**
 * Copyright (c) 2014,2016 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 
 * 
 *  Contributors:  
 *  		Loetz GmbH&Co.KG - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.menu.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.impl.LPackageImpl;

import org.eclipse.osbp.xtext.blip.Blip;

import org.eclipse.osbp.xtext.menu.MenuDslPackage;
import org.eclipse.osbp.xtext.menu.MenuEntry;

import org.eclipse.osbp.xtext.perspective.Perspective;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Menu Entry</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.menu.impl.MenuEntryImpl#isHasIcon <em>Has Icon</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.menu.impl.MenuEntryImpl#getIcon <em>Icon</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.menu.impl.MenuEntryImpl#isHasTooltip <em>Has Tooltip</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.menu.impl.MenuEntryImpl#getTooltip <em>Tooltip</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.menu.impl.MenuEntryImpl#isHasProcess <em>Has Process</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.menu.impl.MenuEntryImpl#getProcess <em>Process</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.menu.impl.MenuEntryImpl#isHasPerspective <em>Has Perspective</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.menu.impl.MenuEntryImpl#getPerspective <em>Perspective</em>}</li>
 * </ul>
 *
 * @generated
 */
public class MenuEntryImpl extends LPackageImpl implements MenuEntry {
	/**
	 * The default value of the '{@link #isHasIcon() <em>Has Icon</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHasIcon()
	 * @generated
	 * @ordered
	 */
	protected static final boolean HAS_ICON_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isHasIcon() <em>Has Icon</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHasIcon()
	 * @generated
	 * @ordered
	 */
	protected boolean hasIcon = HAS_ICON_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getIcon() <em>Icon</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIcon()
	 * @generated
	 * @ordered
	 */
	protected String icon = ICON_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #isHasTooltip() <em>Has Tooltip</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHasTooltip()
	 * @generated
	 * @ordered
	 */
	protected boolean hasTooltip = HAS_TOOLTIP_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getTooltip() <em>Tooltip</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTooltip()
	 * @generated
	 * @ordered
	 */
	protected String tooltip = TOOLTIP_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #isHasProcess() <em>Has Process</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHasProcess()
	 * @generated
	 * @ordered
	 */
	protected boolean hasProcess = HAS_PROCESS_EDEFAULT;

	/**
	 * The cached value of the '{@link #getProcess() <em>Process</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getProcess()
	 * @generated
	 * @ordered
	 */
	protected Blip process;

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

	/**
	 * The cached value of the '{@link #isHasPerspective() <em>Has Perspective</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHasPerspective()
	 * @generated
	 * @ordered
	 */
	protected boolean hasPerspective = HAS_PERSPECTIVE_EDEFAULT;

	/**
	 * The cached value of the '{@link #getPerspective() <em>Perspective</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getPerspective()
	 * @generated
	 * @ordered
	 */
	protected Perspective perspective;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHasIcon(boolean newHasIcon) {
		boolean oldHasIcon = hasIcon;
		hasIcon = newHasIcon;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, MenuDslPackage.MENU_ENTRY__HAS_ICON, oldHasIcon, hasIcon));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setIcon(String newIcon) {
		String oldIcon = icon;
		icon = newIcon;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, MenuDslPackage.MENU_ENTRY__ICON, oldIcon, icon));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHasTooltip(boolean newHasTooltip) {
		boolean oldHasTooltip = hasTooltip;
		hasTooltip = newHasTooltip;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, MenuDslPackage.MENU_ENTRY__HAS_TOOLTIP, oldHasTooltip, hasTooltip));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setTooltip(String newTooltip) {
		String oldTooltip = tooltip;
		tooltip = newTooltip;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, MenuDslPackage.MENU_ENTRY__TOOLTIP, oldTooltip, tooltip));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHasProcess(boolean newHasProcess) {
		boolean oldHasProcess = hasProcess;
		hasProcess = newHasProcess;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, MenuDslPackage.MENU_ENTRY__HAS_PROCESS, oldHasProcess, hasProcess));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Blip getProcess() {
		if (process != null && process.eIsProxy()) {
			InternalEObject oldProcess = (InternalEObject)process;
			process = (Blip)eResolveProxy(oldProcess);
			if (process != oldProcess) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, MenuDslPackage.MENU_ENTRY__PROCESS, oldProcess, process));
			}
		}
		return process;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Blip basicGetProcess() {
		return process;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setProcess(Blip newProcess) {
		Blip oldProcess = process;
		process = newProcess;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, MenuDslPackage.MENU_ENTRY__PROCESS, oldProcess, process));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHasPerspective(boolean newHasPerspective) {
		boolean oldHasPerspective = hasPerspective;
		hasPerspective = newHasPerspective;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, MenuDslPackage.MENU_ENTRY__HAS_PERSPECTIVE, oldHasPerspective, hasPerspective));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Perspective getPerspective() {
		if (perspective != null && perspective.eIsProxy()) {
			InternalEObject oldPerspective = (InternalEObject)perspective;
			perspective = (Perspective)eResolveProxy(oldPerspective);
			if (perspective != oldPerspective) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, MenuDslPackage.MENU_ENTRY__PERSPECTIVE, oldPerspective, perspective));
			}
		}
		return perspective;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Perspective basicGetPerspective() {
		return perspective;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setPerspective(Perspective newPerspective) {
		Perspective oldPerspective = perspective;
		perspective = newPerspective;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, MenuDslPackage.MENU_ENTRY__PERSPECTIVE, oldPerspective, perspective));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case MenuDslPackage.MENU_ENTRY__HAS_ICON:
				return isHasIcon();
			case MenuDslPackage.MENU_ENTRY__ICON:
				return getIcon();
			case MenuDslPackage.MENU_ENTRY__HAS_TOOLTIP:
				return isHasTooltip();
			case MenuDslPackage.MENU_ENTRY__TOOLTIP:
				return getTooltip();
			case MenuDslPackage.MENU_ENTRY__HAS_PROCESS:
				return isHasProcess();
			case MenuDslPackage.MENU_ENTRY__PROCESS:
				if (resolve) return getProcess();
				return basicGetProcess();
			case MenuDslPackage.MENU_ENTRY__HAS_PERSPECTIVE:
				return isHasPerspective();
			case MenuDslPackage.MENU_ENTRY__PERSPECTIVE:
				if (resolve) return getPerspective();
				return basicGetPerspective();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case MenuDslPackage.MENU_ENTRY__HAS_ICON:
				setHasIcon((Boolean)newValue);
				return;
			case MenuDslPackage.MENU_ENTRY__ICON:
				setIcon((String)newValue);
				return;
			case MenuDslPackage.MENU_ENTRY__HAS_TOOLTIP:
				setHasTooltip((Boolean)newValue);
				return;
			case MenuDslPackage.MENU_ENTRY__TOOLTIP:
				setTooltip((String)newValue);
				return;
			case MenuDslPackage.MENU_ENTRY__HAS_PROCESS:
				setHasProcess((Boolean)newValue);
				return;
			case MenuDslPackage.MENU_ENTRY__PROCESS:
				setProcess((Blip)newValue);
				return;
			case MenuDslPackage.MENU_ENTRY__HAS_PERSPECTIVE:
				setHasPerspective((Boolean)newValue);
				return;
			case MenuDslPackage.MENU_ENTRY__PERSPECTIVE:
				setPerspective((Perspective)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case MenuDslPackage.MENU_ENTRY__HAS_ICON:
				setHasIcon(HAS_ICON_EDEFAULT);
				return;
			case MenuDslPackage.MENU_ENTRY__ICON:
				setIcon(ICON_EDEFAULT);
				return;
			case MenuDslPackage.MENU_ENTRY__HAS_TOOLTIP:
				setHasTooltip(HAS_TOOLTIP_EDEFAULT);
				return;
			case MenuDslPackage.MENU_ENTRY__TOOLTIP:
				setTooltip(TOOLTIP_EDEFAULT);
				return;
			case MenuDslPackage.MENU_ENTRY__HAS_PROCESS:
				setHasProcess(HAS_PROCESS_EDEFAULT);
				return;
			case MenuDslPackage.MENU_ENTRY__PROCESS:
				setProcess((Blip)null);
				return;
			case MenuDslPackage.MENU_ENTRY__HAS_PERSPECTIVE:
				setHasPerspective(HAS_PERSPECTIVE_EDEFAULT);
				return;
			case MenuDslPackage.MENU_ENTRY__PERSPECTIVE:
				setPerspective((Perspective)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case MenuDslPackage.MENU_ENTRY__HAS_ICON:
				return hasIcon != HAS_ICON_EDEFAULT;
			case MenuDslPackage.MENU_ENTRY__ICON:
				return ICON_EDEFAULT == null ? icon != null : !ICON_EDEFAULT.equals(icon);
			case MenuDslPackage.MENU_ENTRY__HAS_TOOLTIP:
				return hasTooltip != HAS_TOOLTIP_EDEFAULT;
			case MenuDslPackage.MENU_ENTRY__TOOLTIP:
				return TOOLTIP_EDEFAULT == null ? tooltip != null : !TOOLTIP_EDEFAULT.equals(tooltip);
			case MenuDslPackage.MENU_ENTRY__HAS_PROCESS:
				return hasProcess != HAS_PROCESS_EDEFAULT;
			case MenuDslPackage.MENU_ENTRY__PROCESS:
				return process != null;
			case MenuDslPackage.MENU_ENTRY__HAS_PERSPECTIVE:
				return hasPerspective != HAS_PERSPECTIVE_EDEFAULT;
			case MenuDslPackage.MENU_ENTRY__PERSPECTIVE:
				return perspective != 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(" (hasIcon: ");
		result.append(hasIcon);
		result.append(", icon: ");
		result.append(icon);
		result.append(", hasTooltip: ");
		result.append(hasTooltip);
		result.append(", tooltip: ");
		result.append(tooltip);
		result.append(", hasProcess: ");
		result.append(hasProcess);
		result.append(", hasPerspective: ");
		result.append(hasPerspective);
		result.append(')');
		return result.toString();
	}

} //MenuEntryImpl
