/**
 *                                                                            
 *  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                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Florian Pirchner - Initial implementation
 * 
 */

package org.eclipse.osbp.ecview.extension.grid.renderer.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.ecview.core.common.model.binding.YECViewModelValueBindingEndpoint;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridImageRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridRendererClickEvent;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridRendererPackage;

/**
 * <!-- begin-user-doc --> An implementation of the model object '
 * <em><b>Cx Grid Image Renderer</b></em>'. <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.renderer.impl.CxGridImageRendererImpl#getLastClickEvent <em>Last Click Event</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.renderer.impl.CxGridImageRendererImpl#getEventTopic <em>Event Topic</em>}</li>
 * </ul>
 *
 * @generated
 */
public class CxGridImageRendererImpl extends CxGridRendererImpl implements
		CxGridImageRenderer {
	
	/**
	 * The cached value of the '{@link #getLastClickEvent() <em>Last Click Event</em>}' containment reference.
	 * <!-- begin-user-doc
	 * --> <!-- end-user-doc -->
	 * @see #getLastClickEvent()
	 * @generated
	 * @ordered
	 */
	protected CxGridRendererClickEvent lastClickEvent;

	/**
	 * The default value of the '{@link #getEventTopic() <em>Event Topic</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEventTopic()
	 * @generated
	 * @ordered
	 */
	protected static final String EVENT_TOPIC_EDEFAULT = "";

	/**
	 * The cached value of the '{@link #getEventTopic() <em>Event Topic</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEventTopic()
	 * @generated
	 * @ordered
	 */
	protected String eventTopic = EVENT_TOPIC_EDEFAULT;

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the e class
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return CxGridRendererPackage.Literals.CX_GRID_IMAGE_RENDERER;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getLastClickEvent()
	 *         <em>Last Click Event</em>}' containment reference
	 * @generated
	 */
	public CxGridRendererClickEvent getLastClickEvent() {
		return lastClickEvent;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newLastClickEvent
	 *            the new last click event
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	public NotificationChain basicSetLastClickEvent(
			CxGridRendererClickEvent newLastClickEvent, NotificationChain msgs) {
		CxGridRendererClickEvent oldLastClickEvent = lastClickEvent;
		lastClickEvent = newLastClickEvent;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, CxGridRendererPackage.CX_GRID_IMAGE_RENDERER__LAST_CLICK_EVENT, oldLastClickEvent, newLastClickEvent);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newLastClickEvent
	 *            the new cached value of the '{@link #getLastClickEvent()
	 *            <em>Last Click Event</em>}' containment reference
	 * @generated
	 */
	public void setLastClickEvent(CxGridRendererClickEvent newLastClickEvent) {
		if (newLastClickEvent != lastClickEvent) {
			NotificationChain msgs = null;
			if (lastClickEvent != null)
				msgs = ((InternalEObject)lastClickEvent).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - CxGridRendererPackage.CX_GRID_IMAGE_RENDERER__LAST_CLICK_EVENT, null, msgs);
			if (newLastClickEvent != null)
				msgs = ((InternalEObject)newLastClickEvent).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - CxGridRendererPackage.CX_GRID_IMAGE_RENDERER__LAST_CLICK_EVENT, null, msgs);
			msgs = basicSetLastClickEvent(newLastClickEvent, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridRendererPackage.CX_GRID_IMAGE_RENDERER__LAST_CLICK_EVENT, newLastClickEvent, newLastClickEvent));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getEventTopic()
	 *         <em>Event Topic</em>}' attribute
	 * @generated
	 */
	public String getEventTopic() {
		return eventTopic;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newEventTopic
	 *            the new cached value of the '{@link #getEventTopic()
	 *            <em>Event Topic</em>}' attribute
	 * @generated
	 */
	public void setEventTopic(String newEventTopic) {
		String oldEventTopic = eventTopic;
		eventTopic = newEventTopic;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridRendererPackage.CX_GRID_IMAGE_RENDERER__EVENT_TOPIC, oldEventTopic, eventTopic));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the YEC view model value binding endpoint
	 * @generated
	 */
	public YECViewModelValueBindingEndpoint createLastClickEventEndpoint() {
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param otherEnd
	 *            the other end
	 * @param featureID
	 *            the feature id
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
			case CxGridRendererPackage.CX_GRID_IMAGE_RENDERER__LAST_CLICK_EVENT:
				return basicSetLastClickEvent(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @param resolve
	 *            the resolve
	 * @param coreType
	 *            the core type
	 * @return the object
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case CxGridRendererPackage.CX_GRID_IMAGE_RENDERER__LAST_CLICK_EVENT:
				return getLastClickEvent();
			case CxGridRendererPackage.CX_GRID_IMAGE_RENDERER__EVENT_TOPIC:
				return getEventTopic();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @param newValue
	 *            the new value
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case CxGridRendererPackage.CX_GRID_IMAGE_RENDERER__LAST_CLICK_EVENT:
				setLastClickEvent((CxGridRendererClickEvent)newValue);
				return;
			case CxGridRendererPackage.CX_GRID_IMAGE_RENDERER__EVENT_TOPIC:
				setEventTopic((String)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case CxGridRendererPackage.CX_GRID_IMAGE_RENDERER__LAST_CLICK_EVENT:
				setLastClickEvent((CxGridRendererClickEvent)null);
				return;
			case CxGridRendererPackage.CX_GRID_IMAGE_RENDERER__EVENT_TOPIC:
				setEventTopic(EVENT_TOPIC_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @return true, if successful
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case CxGridRendererPackage.CX_GRID_IMAGE_RENDERER__LAST_CLICK_EVENT:
				return lastClickEvent != null;
			case CxGridRendererPackage.CX_GRID_IMAGE_RENDERER__EVENT_TOPIC:
				return EVENT_TOPIC_EDEFAULT == null ? eventTopic != null : !EVENT_TOPIC_EDEFAULT.equals(eventTopic);
		}
		return super.eIsSet(featureID);
	}

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

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

}