/**
 *                                                                            
 *  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.osbp.ecview.extension.grid.renderer.CxGridPriceRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridRendererPackage;

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

import org.eclipse.emf.ecore.EClass;

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

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Cx Grid Price Renderer</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.renderer.impl.CxGridPriceRendererImpl#getValuePropertyPath <em>Value Property Path</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.renderer.impl.CxGridPriceRendererImpl#getCurrencyPropertyPath <em>Currency Property Path</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.renderer.impl.CxGridPriceRendererImpl#getNullRepresentation <em>Null Representation</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.renderer.impl.CxGridPriceRendererImpl#getHtmlPattern <em>Html Pattern</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.renderer.impl.CxGridPriceRendererImpl#getNumberFormat <em>Number Format</em>}</li>
 * </ul>
 *
 * @generated
 */
public class CxGridPriceRendererImpl extends CxGridRendererImpl implements CxGridPriceRenderer {
	
	/**
	 * The default value of the '{@link #getValuePropertyPath() <em>Value Property Path</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getValuePropertyPath()
	 * @generated
	 * @ordered
	 */
	protected static final String VALUE_PROPERTY_PATH_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getValuePropertyPath() <em>Value Property Path</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getValuePropertyPath()
	 * @generated
	 * @ordered
	 */
	protected String valuePropertyPath = VALUE_PROPERTY_PATH_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getCurrencyPropertyPath() <em>Currency Property Path</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCurrencyPropertyPath()
	 * @generated
	 * @ordered
	 */
	protected String currencyPropertyPath = CURRENCY_PROPERTY_PATH_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getNullRepresentation() <em>Null Representation</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNullRepresentation()
	 * @generated
	 * @ordered
	 */
	protected String nullRepresentation = NULL_REPRESENTATION_EDEFAULT;

	/**
	 * The default value of the '{@link #getHtmlPattern() <em>Html Pattern</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getHtmlPattern()
	 * @generated
	 * @ordered
	 */
	protected static final String HTML_PATTERN_EDEFAULT = "<b>{@value}</b> <i>{@currency}</i>";

	/**
	 * The cached value of the '{@link #getHtmlPattern() <em>Html Pattern</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getHtmlPattern()
	 * @generated
	 * @ordered
	 */
	protected String htmlPattern = HTML_PATTERN_EDEFAULT;

	/**
	 * The default value of the '{@link #getNumberFormat() <em>Number Format</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNumberFormat()
	 * @generated
	 * @ordered
	 */
	protected static final String NUMBER_FORMAT_EDEFAULT = "#,##0.00";

	/**
	 * The cached value of the '{@link #getNumberFormat() <em>Number Format</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNumberFormat()
	 * @generated
	 * @ordered
	 */
	protected String numberFormat = NUMBER_FORMAT_EDEFAULT;

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

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getValuePropertyPath()
	 *         <em>Value Property Path</em>}' attribute
	 * @generated
	 */
	public String getValuePropertyPath() {
		return valuePropertyPath;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newValuePropertyPath
	 *            the new cached value of the '{@link #getValuePropertyPath()
	 *            <em>Value Property Path</em>}' attribute
	 * @generated
	 */
	public void setValuePropertyPath(String newValuePropertyPath) {
		String oldValuePropertyPath = valuePropertyPath;
		valuePropertyPath = newValuePropertyPath;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridRendererPackage.CX_GRID_PRICE_RENDERER__VALUE_PROPERTY_PATH, oldValuePropertyPath, valuePropertyPath));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getCurrencyPropertyPath()
	 *         <em>Currency Property Path</em>}' attribute
	 * @generated
	 */
	public String getCurrencyPropertyPath() {
		return currencyPropertyPath;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newCurrencyPropertyPath
	 *            the new cached value of the '
	 *            {@link #getCurrencyPropertyPath()
	 *            <em>Currency Property Path</em>}' attribute
	 * @generated
	 */
	public void setCurrencyPropertyPath(String newCurrencyPropertyPath) {
		String oldCurrencyPropertyPath = currencyPropertyPath;
		currencyPropertyPath = newCurrencyPropertyPath;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridRendererPackage.CX_GRID_PRICE_RENDERER__CURRENCY_PROPERTY_PATH, oldCurrencyPropertyPath, currencyPropertyPath));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getNullRepresentation()
	 *         <em>Null Representation</em>}' attribute
	 * @generated
	 */
	public String getNullRepresentation() {
		return nullRepresentation;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newNullRepresentation
	 *            the new cached value of the '{@link #getNullRepresentation()
	 *            <em>Null Representation</em>}' attribute
	 * @generated
	 */
	public void setNullRepresentation(String newNullRepresentation) {
		String oldNullRepresentation = nullRepresentation;
		nullRepresentation = newNullRepresentation;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridRendererPackage.CX_GRID_PRICE_RENDERER__NULL_REPRESENTATION, oldNullRepresentation, nullRepresentation));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getHtmlPattern()
	 *         <em>Html Pattern</em>}' attribute
	 * @generated
	 */
	public String getHtmlPattern() {
		return htmlPattern;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newHtmlPattern
	 *            the new cached value of the '{@link #getHtmlPattern()
	 *            <em>Html Pattern</em>}' attribute
	 * @generated
	 */
	public void setHtmlPattern(String newHtmlPattern) {
		String oldHtmlPattern = htmlPattern;
		htmlPattern = newHtmlPattern;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridRendererPackage.CX_GRID_PRICE_RENDERER__HTML_PATTERN, oldHtmlPattern, htmlPattern));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getNumberFormat()
	 *         <em>Number Format</em>}' attribute
	 * @generated
	 */
	public String getNumberFormat() {
		return numberFormat;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newNumberFormat
	 *            the new cached value of the '{@link #getNumberFormat()
	 *            <em>Number Format</em>}' attribute
	 * @generated
	 */
	public void setNumberFormat(String newNumberFormat) {
		String oldNumberFormat = numberFormat;
		numberFormat = newNumberFormat;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridRendererPackage.CX_GRID_PRICE_RENDERER__NUMBER_FORMAT, oldNumberFormat, numberFormat));
	}

	/**
	 * <!-- 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_PRICE_RENDERER__VALUE_PROPERTY_PATH:
				return getValuePropertyPath();
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__CURRENCY_PROPERTY_PATH:
				return getCurrencyPropertyPath();
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__NULL_REPRESENTATION:
				return getNullRepresentation();
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__HTML_PATTERN:
				return getHtmlPattern();
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__NUMBER_FORMAT:
				return getNumberFormat();
		}
		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_PRICE_RENDERER__VALUE_PROPERTY_PATH:
				setValuePropertyPath((String)newValue);
				return;
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__CURRENCY_PROPERTY_PATH:
				setCurrencyPropertyPath((String)newValue);
				return;
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__NULL_REPRESENTATION:
				setNullRepresentation((String)newValue);
				return;
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__HTML_PATTERN:
				setHtmlPattern((String)newValue);
				return;
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__NUMBER_FORMAT:
				setNumberFormat((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_PRICE_RENDERER__VALUE_PROPERTY_PATH:
				setValuePropertyPath(VALUE_PROPERTY_PATH_EDEFAULT);
				return;
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__CURRENCY_PROPERTY_PATH:
				setCurrencyPropertyPath(CURRENCY_PROPERTY_PATH_EDEFAULT);
				return;
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__NULL_REPRESENTATION:
				setNullRepresentation(NULL_REPRESENTATION_EDEFAULT);
				return;
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__HTML_PATTERN:
				setHtmlPattern(HTML_PATTERN_EDEFAULT);
				return;
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__NUMBER_FORMAT:
				setNumberFormat(NUMBER_FORMAT_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_PRICE_RENDERER__VALUE_PROPERTY_PATH:
				return VALUE_PROPERTY_PATH_EDEFAULT == null ? valuePropertyPath != null : !VALUE_PROPERTY_PATH_EDEFAULT.equals(valuePropertyPath);
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__CURRENCY_PROPERTY_PATH:
				return CURRENCY_PROPERTY_PATH_EDEFAULT == null ? currencyPropertyPath != null : !CURRENCY_PROPERTY_PATH_EDEFAULT.equals(currencyPropertyPath);
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__NULL_REPRESENTATION:
				return NULL_REPRESENTATION_EDEFAULT == null ? nullRepresentation != null : !NULL_REPRESENTATION_EDEFAULT.equals(nullRepresentation);
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__HTML_PATTERN:
				return HTML_PATTERN_EDEFAULT == null ? htmlPattern != null : !HTML_PATTERN_EDEFAULT.equals(htmlPattern);
			case CxGridRendererPackage.CX_GRID_PRICE_RENDERER__NUMBER_FORMAT:
				return NUMBER_FORMAT_EDEFAULT == null ? numberFormat != null : !NUMBER_FORMAT_EDEFAULT.equals(numberFormat);
		}
		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(" (valuePropertyPath: ");
		result.append(valuePropertyPath);
		result.append(", currencyPropertyPath: ");
		result.append(currencyPropertyPath);
		result.append(", nullRepresentation: ");
		result.append(nullRepresentation);
		result.append(", htmlPattern: ");
		result.append(htmlPattern);
		result.append(", numberFormat: ");
		result.append(numberFormat);
		result.append(')');
		return result.toString();
	}

}