/**
 * Copyright (c) 2011, 2017 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *  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:  
 *  		Joerg Riegel - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.statemachine.impl;

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

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

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

import org.eclipse.osbp.xtext.reportdsl.Report;

import org.eclipse.osbp.xtext.statemachine.FSMActionFieldConcatenation;
import org.eclipse.osbp.xtext.statemachine.FSMActionPeripheralPrintReport;
import org.eclipse.osbp.xtext.statemachine.FSMStorage;
import org.eclipse.osbp.xtext.statemachine.StatemachineDSLPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>FSM Action Peripheral Print Report</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.statemachine.impl.FSMActionPeripheralPrintReportImpl#getReport <em>Report</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.statemachine.impl.FSMActionPeripheralPrintReportImpl#getKey <em>Key</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.statemachine.impl.FSMActionPeripheralPrintReportImpl#isHasFilter <em>Has Filter</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.statemachine.impl.FSMActionPeripheralPrintReportImpl#isHasPrintService <em>Has Print Service</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.statemachine.impl.FSMActionPeripheralPrintReportImpl#getPrintService <em>Print Service</em>}</li>
 * </ul>
 *
 * @generated
 */
public class FSMActionPeripheralPrintReportImpl extends FSMLazyResolverImpl implements FSMActionPeripheralPrintReport {
	/**
	 * The cached value of the '{@link #getReport() <em>Report</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getReport()
	 * @generated
	 * @ordered
	 */
	protected Report report;

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

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

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

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

	/**
	 * The cached value of the '{@link #isHasPrintService() <em>Has Print Service</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHasPrintService()
	 * @generated
	 * @ordered
	 */
	protected boolean hasPrintService = HAS_PRINT_SERVICE_EDEFAULT;

	/**
	 * The cached value of the '{@link #getPrintService() <em>Print Service</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getPrintService()
	 * @generated
	 * @ordered
	 */
	protected FSMActionFieldConcatenation printService;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Report getReport() {
		if (report != null && report.eIsProxy()) {
			InternalEObject oldReport = (InternalEObject)report;
			report = (Report)eResolveProxy(oldReport);
			if (report != oldReport) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__REPORT, oldReport, report));
			}
		}
		return report;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Report basicGetReport() {
		return report;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setReport(Report newReport) {
		Report oldReport = report;
		report = newReport;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__REPORT, oldReport, report));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FSMStorage getKey() {
		if (key != null && key.eIsProxy()) {
			InternalEObject oldKey = (InternalEObject)key;
			key = (FSMStorage)eResolveProxy(oldKey);
			if (key != oldKey) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__KEY, oldKey, key));
			}
		}
		return key;
	}

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHasFilter(boolean newHasFilter) {
		boolean oldHasFilter = hasFilter;
		hasFilter = newHasFilter;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__HAS_FILTER, oldHasFilter, hasFilter));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHasPrintService(boolean newHasPrintService) {
		boolean oldHasPrintService = hasPrintService;
		hasPrintService = newHasPrintService;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__HAS_PRINT_SERVICE, oldHasPrintService, hasPrintService));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FSMActionFieldConcatenation getPrintService() {
		return printService;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetPrintService(FSMActionFieldConcatenation newPrintService, NotificationChain msgs) {
		FSMActionFieldConcatenation oldPrintService = printService;
		printService = newPrintService;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__PRINT_SERVICE, oldPrintService, newPrintService);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setPrintService(FSMActionFieldConcatenation newPrintService) {
		if (newPrintService != printService) {
			NotificationChain msgs = null;
			if (printService != null)
				msgs = ((InternalEObject)printService).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__PRINT_SERVICE, null, msgs);
			if (newPrintService != null)
				msgs = ((InternalEObject)newPrintService).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__PRINT_SERVICE, null, msgs);
			msgs = basicSetPrintService(newPrintService, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__PRINT_SERVICE, newPrintService, newPrintService));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__PRINT_SERVICE:
				return basicSetPrintService(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__REPORT:
				if (resolve) return getReport();
				return basicGetReport();
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__KEY:
				if (resolve) return getKey();
				return basicGetKey();
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__HAS_FILTER:
				return isHasFilter();
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__HAS_PRINT_SERVICE:
				return isHasPrintService();
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__PRINT_SERVICE:
				return getPrintService();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__REPORT:
				setReport((Report)newValue);
				return;
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__KEY:
				setKey((FSMStorage)newValue);
				return;
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__HAS_FILTER:
				setHasFilter((Boolean)newValue);
				return;
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__HAS_PRINT_SERVICE:
				setHasPrintService((Boolean)newValue);
				return;
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__PRINT_SERVICE:
				setPrintService((FSMActionFieldConcatenation)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__REPORT:
				setReport((Report)null);
				return;
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__KEY:
				setKey((FSMStorage)null);
				return;
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__HAS_FILTER:
				setHasFilter(HAS_FILTER_EDEFAULT);
				return;
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__HAS_PRINT_SERVICE:
				setHasPrintService(HAS_PRINT_SERVICE_EDEFAULT);
				return;
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__PRINT_SERVICE:
				setPrintService((FSMActionFieldConcatenation)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__REPORT:
				return report != null;
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__KEY:
				return key != null;
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__HAS_FILTER:
				return hasFilter != HAS_FILTER_EDEFAULT;
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__HAS_PRINT_SERVICE:
				return hasPrintService != HAS_PRINT_SERVICE_EDEFAULT;
			case StatemachineDSLPackage.FSM_ACTION_PERIPHERAL_PRINT_REPORT__PRINT_SERVICE:
				return printService != 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(" (hasFilter: ");
		result.append(hasFilter);
		result.append(", hasPrintService: ");
		result.append(hasPrintService);
		result.append(')');
		return result.toString();
	}

} //FSMActionPeripheralPrintReportImpl
