/**
 * Copyright (c) 2011, 2016 - 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.perspective.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.dto.LDto;

import org.eclipse.osbp.xtext.dialogdsl.Dialog;

import org.eclipse.osbp.xtext.perspective.PerspectiveDslPackage;
import org.eclipse.osbp.xtext.perspective.PerspectiveKanban;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Perspective Kanban</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.perspective.impl.PerspectiveKanbanImpl#getDtoRef <em>Dto Ref</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.perspective.impl.PerspectiveKanbanImpl#getCardRef <em>Card Ref</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.perspective.impl.PerspectiveKanbanImpl#getDialogRef <em>Dialog Ref</em>}</li>
 * </ul>
 *
 * @generated
 */
public class PerspectiveKanbanImpl extends PerspectiveLazyResolverImpl implements PerspectiveKanban {
	/**
	 * The cached value of the '{@link #getDtoRef() <em>Dto Ref</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDtoRef()
	 * @generated
	 * @ordered
	 */
	protected LDto dtoRef;

	/**
	 * The cached value of the '{@link #getCardRef() <em>Card Ref</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCardRef()
	 * @generated
	 * @ordered
	 */
	protected Dialog cardRef;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LDto getDtoRef() {
		if (dtoRef != null && dtoRef.eIsProxy()) {
			InternalEObject oldDtoRef = (InternalEObject)dtoRef;
			dtoRef = (LDto)eResolveProxy(oldDtoRef);
			if (dtoRef != oldDtoRef) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, PerspectiveDslPackage.PERSPECTIVE_KANBAN__DTO_REF, oldDtoRef, dtoRef));
			}
		}
		return dtoRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LDto basicGetDtoRef() {
		return dtoRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDtoRef(LDto newDtoRef) {
		LDto oldDtoRef = dtoRef;
		dtoRef = newDtoRef;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, PerspectiveDslPackage.PERSPECTIVE_KANBAN__DTO_REF, oldDtoRef, dtoRef));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Dialog getCardRef() {
		if (cardRef != null && cardRef.eIsProxy()) {
			InternalEObject oldCardRef = (InternalEObject)cardRef;
			cardRef = (Dialog)eResolveProxy(oldCardRef);
			if (cardRef != oldCardRef) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, PerspectiveDslPackage.PERSPECTIVE_KANBAN__CARD_REF, oldCardRef, cardRef));
			}
		}
		return cardRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Dialog basicGetCardRef() {
		return cardRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setCardRef(Dialog newCardRef) {
		Dialog oldCardRef = cardRef;
		cardRef = newCardRef;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, PerspectiveDslPackage.PERSPECTIVE_KANBAN__CARD_REF, oldCardRef, cardRef));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Dialog getDialogRef() {
		if (dialogRef != null && dialogRef.eIsProxy()) {
			InternalEObject oldDialogRef = (InternalEObject)dialogRef;
			dialogRef = (Dialog)eResolveProxy(oldDialogRef);
			if (dialogRef != oldDialogRef) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, PerspectiveDslPackage.PERSPECTIVE_KANBAN__DIALOG_REF, oldDialogRef, dialogRef));
			}
		}
		return dialogRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Dialog basicGetDialogRef() {
		return dialogRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDialogRef(Dialog newDialogRef) {
		Dialog oldDialogRef = dialogRef;
		dialogRef = newDialogRef;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, PerspectiveDslPackage.PERSPECTIVE_KANBAN__DIALOG_REF, oldDialogRef, dialogRef));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case PerspectiveDslPackage.PERSPECTIVE_KANBAN__DTO_REF:
				if (resolve) return getDtoRef();
				return basicGetDtoRef();
			case PerspectiveDslPackage.PERSPECTIVE_KANBAN__CARD_REF:
				if (resolve) return getCardRef();
				return basicGetCardRef();
			case PerspectiveDslPackage.PERSPECTIVE_KANBAN__DIALOG_REF:
				if (resolve) return getDialogRef();
				return basicGetDialogRef();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case PerspectiveDslPackage.PERSPECTIVE_KANBAN__DTO_REF:
				setDtoRef((LDto)newValue);
				return;
			case PerspectiveDslPackage.PERSPECTIVE_KANBAN__CARD_REF:
				setCardRef((Dialog)newValue);
				return;
			case PerspectiveDslPackage.PERSPECTIVE_KANBAN__DIALOG_REF:
				setDialogRef((Dialog)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case PerspectiveDslPackage.PERSPECTIVE_KANBAN__DTO_REF:
				setDtoRef((LDto)null);
				return;
			case PerspectiveDslPackage.PERSPECTIVE_KANBAN__CARD_REF:
				setCardRef((Dialog)null);
				return;
			case PerspectiveDslPackage.PERSPECTIVE_KANBAN__DIALOG_REF:
				setDialogRef((Dialog)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case PerspectiveDslPackage.PERSPECTIVE_KANBAN__DTO_REF:
				return dtoRef != null;
			case PerspectiveDslPackage.PERSPECTIVE_KANBAN__CARD_REF:
				return cardRef != null;
			case PerspectiveDslPackage.PERSPECTIVE_KANBAN__DIALOG_REF:
				return dialogRef != null;
		}
		return super.eIsSet(featureID);
	}

} //PerspectiveKanbanImpl
