/**
 * 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 v1.0 
 *  which accompanies this distribution, and is available at 
 *  http://www.eclipse.org/legal/epl-v10.html 
 * 
 *  Based on ideas from Xtext, Xtend, Xcore
 *   
 *  Contributors:  
 *  		Christophe Loetz  (Loetz GmbH&Co.KG) - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.reportdsl.impl;

import java.util.Collection;

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

import org.eclipse.emf.common.util.EList;

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

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

import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;

import org.eclipse.osbp.xtext.reportdsl.DatamartTableProperty;
import org.eclipse.osbp.xtext.reportdsl.ReportDSLPackage;
import org.eclipse.osbp.xtext.reportdsl.Style;
import org.eclipse.osbp.xtext.reportdsl.TableImage;
import org.eclipse.osbp.xtext.reportdsl.TableInterval;
import org.eclipse.osbp.xtext.reportdsl.TableLookup;
import org.eclipse.osbp.xtext.reportdsl.TableValueElement;
import org.eclipse.osbp.xtext.reportdsl.WithStyle;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Datamart Table Property</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.reportdsl.impl.DatamartTablePropertyImpl#getStyle <em>Style</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.reportdsl.impl.DatamartTablePropertyImpl#getColumn <em>Column</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.reportdsl.impl.DatamartTablePropertyImpl#getIntervals <em>Intervals</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.reportdsl.impl.DatamartTablePropertyImpl#isHideLabelInterval <em>Hide Label Interval</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.reportdsl.impl.DatamartTablePropertyImpl#getLookups <em>Lookups</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.reportdsl.impl.DatamartTablePropertyImpl#isHideLabelLookup <em>Hide Label Lookup</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.reportdsl.impl.DatamartTablePropertyImpl#isHasImage <em>Has Image</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.reportdsl.impl.DatamartTablePropertyImpl#getImage <em>Image</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class DatamartTablePropertyImpl extends ReportLazyResolverImpl implements DatamartTableProperty {
	/**
	 * The cached value of the '{@link #getStyle() <em>Style</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getStyle()
	 * @generated
	 * @ordered
	 */
	protected Style style;

	/**
	 * The cached value of the '{@link #getColumn() <em>Column</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getColumn()
	 * @generated
	 * @ordered
	 */
	protected TableValueElement column;

	/**
	 * The cached value of the '{@link #getIntervals() <em>Intervals</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIntervals()
	 * @generated
	 * @ordered
	 */
	protected EList<TableInterval> intervals;

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

	/**
	 * The cached value of the '{@link #isHideLabelInterval() <em>Hide Label Interval</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHideLabelInterval()
	 * @generated
	 * @ordered
	 */
	protected boolean hideLabelInterval = HIDE_LABEL_INTERVAL_EDEFAULT;

	/**
	 * The cached value of the '{@link #getLookups() <em>Lookups</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLookups()
	 * @generated
	 * @ordered
	 */
	protected EList<TableLookup> lookups;

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

	/**
	 * The cached value of the '{@link #isHideLabelLookup() <em>Hide Label Lookup</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHideLabelLookup()
	 * @generated
	 * @ordered
	 */
	protected boolean hideLabelLookup = HIDE_LABEL_LOOKUP_EDEFAULT;

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

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

	/**
	 * The cached value of the '{@link #getImage() <em>Image</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getImage()
	 * @generated
	 * @ordered
	 */
	protected TableImage image;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Style getStyle() {
		if (style != null && style.eIsProxy()) {
			InternalEObject oldStyle = (InternalEObject)style;
			style = (Style)eResolveProxy(oldStyle);
			if (style != oldStyle) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ReportDSLPackage.DATAMART_TABLE_PROPERTY__STYLE, oldStyle, style));
			}
		}
		return style;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Style basicGetStyle() {
		return style;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setStyle(Style newStyle) {
		Style oldStyle = style;
		style = newStyle;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ReportDSLPackage.DATAMART_TABLE_PROPERTY__STYLE, oldStyle, style));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public TableValueElement getColumn() {
		return column;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetColumn(TableValueElement newColumn, NotificationChain msgs) {
		TableValueElement oldColumn = column;
		column = newColumn;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ReportDSLPackage.DATAMART_TABLE_PROPERTY__COLUMN, oldColumn, newColumn);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setColumn(TableValueElement newColumn) {
		if (newColumn != column) {
			NotificationChain msgs = null;
			if (column != null)
				msgs = ((InternalEObject)column).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ReportDSLPackage.DATAMART_TABLE_PROPERTY__COLUMN, null, msgs);
			if (newColumn != null)
				msgs = ((InternalEObject)newColumn).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ReportDSLPackage.DATAMART_TABLE_PROPERTY__COLUMN, null, msgs);
			msgs = basicSetColumn(newColumn, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ReportDSLPackage.DATAMART_TABLE_PROPERTY__COLUMN, newColumn, newColumn));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<TableInterval> getIntervals() {
		if (intervals == null) {
			intervals = new EObjectContainmentEList<TableInterval>(TableInterval.class, this, ReportDSLPackage.DATAMART_TABLE_PROPERTY__INTERVALS);
		}
		return intervals;
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHideLabelInterval(boolean newHideLabelInterval) {
		boolean oldHideLabelInterval = hideLabelInterval;
		hideLabelInterval = newHideLabelInterval;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ReportDSLPackage.DATAMART_TABLE_PROPERTY__HIDE_LABEL_INTERVAL, oldHideLabelInterval, hideLabelInterval));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<TableLookup> getLookups() {
		if (lookups == null) {
			lookups = new EObjectContainmentEList<TableLookup>(TableLookup.class, this, ReportDSLPackage.DATAMART_TABLE_PROPERTY__LOOKUPS);
		}
		return lookups;
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHideLabelLookup(boolean newHideLabelLookup) {
		boolean oldHideLabelLookup = hideLabelLookup;
		hideLabelLookup = newHideLabelLookup;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ReportDSLPackage.DATAMART_TABLE_PROPERTY__HIDE_LABEL_LOOKUP, oldHideLabelLookup, hideLabelLookup));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHasImage(boolean newHasImage) {
		boolean oldHasImage = hasImage;
		hasImage = newHasImage;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ReportDSLPackage.DATAMART_TABLE_PROPERTY__HAS_IMAGE, oldHasImage, hasImage));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public TableImage getImage() {
		return image;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetImage(TableImage newImage, NotificationChain msgs) {
		TableImage oldImage = image;
		image = newImage;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ReportDSLPackage.DATAMART_TABLE_PROPERTY__IMAGE, oldImage, newImage);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setImage(TableImage newImage) {
		if (newImage != image) {
			NotificationChain msgs = null;
			if (image != null)
				msgs = ((InternalEObject)image).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ReportDSLPackage.DATAMART_TABLE_PROPERTY__IMAGE, null, msgs);
			if (newImage != null)
				msgs = ((InternalEObject)newImage).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ReportDSLPackage.DATAMART_TABLE_PROPERTY__IMAGE, null, msgs);
			msgs = basicSetImage(newImage, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ReportDSLPackage.DATAMART_TABLE_PROPERTY__IMAGE, newImage, newImage));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__COLUMN:
				return basicSetColumn(null, msgs);
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__INTERVALS:
				return ((InternalEList<?>)getIntervals()).basicRemove(otherEnd, msgs);
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__LOOKUPS:
				return ((InternalEList<?>)getLookups()).basicRemove(otherEnd, msgs);
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__IMAGE:
				return basicSetImage(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 ReportDSLPackage.DATAMART_TABLE_PROPERTY__STYLE:
				if (resolve) return getStyle();
				return basicGetStyle();
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__COLUMN:
				return getColumn();
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__INTERVALS:
				return getIntervals();
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__HIDE_LABEL_INTERVAL:
				return isHideLabelInterval();
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__LOOKUPS:
				return getLookups();
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__HIDE_LABEL_LOOKUP:
				return isHideLabelLookup();
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__HAS_IMAGE:
				return isHasImage();
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__IMAGE:
				return getImage();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__STYLE:
				setStyle((Style)newValue);
				return;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__COLUMN:
				setColumn((TableValueElement)newValue);
				return;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__INTERVALS:
				getIntervals().clear();
				getIntervals().addAll((Collection<? extends TableInterval>)newValue);
				return;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__HIDE_LABEL_INTERVAL:
				setHideLabelInterval((Boolean)newValue);
				return;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__LOOKUPS:
				getLookups().clear();
				getLookups().addAll((Collection<? extends TableLookup>)newValue);
				return;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__HIDE_LABEL_LOOKUP:
				setHideLabelLookup((Boolean)newValue);
				return;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__HAS_IMAGE:
				setHasImage((Boolean)newValue);
				return;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__IMAGE:
				setImage((TableImage)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__STYLE:
				setStyle((Style)null);
				return;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__COLUMN:
				setColumn((TableValueElement)null);
				return;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__INTERVALS:
				getIntervals().clear();
				return;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__HIDE_LABEL_INTERVAL:
				setHideLabelInterval(HIDE_LABEL_INTERVAL_EDEFAULT);
				return;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__LOOKUPS:
				getLookups().clear();
				return;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__HIDE_LABEL_LOOKUP:
				setHideLabelLookup(HIDE_LABEL_LOOKUP_EDEFAULT);
				return;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__HAS_IMAGE:
				setHasImage(HAS_IMAGE_EDEFAULT);
				return;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__IMAGE:
				setImage((TableImage)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__STYLE:
				return style != null;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__COLUMN:
				return column != null;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__INTERVALS:
				return intervals != null && !intervals.isEmpty();
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__HIDE_LABEL_INTERVAL:
				return hideLabelInterval != HIDE_LABEL_INTERVAL_EDEFAULT;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__LOOKUPS:
				return lookups != null && !lookups.isEmpty();
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__HIDE_LABEL_LOOKUP:
				return hideLabelLookup != HIDE_LABEL_LOOKUP_EDEFAULT;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__HAS_IMAGE:
				return hasImage != HAS_IMAGE_EDEFAULT;
			case ReportDSLPackage.DATAMART_TABLE_PROPERTY__IMAGE:
				return image != null;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) {
		if (baseClass == WithStyle.class) {
			switch (derivedFeatureID) {
				case ReportDSLPackage.DATAMART_TABLE_PROPERTY__STYLE: return ReportDSLPackage.WITH_STYLE__STYLE;
				default: return -1;
			}
		}
		return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) {
		if (baseClass == WithStyle.class) {
			switch (baseFeatureID) {
				case ReportDSLPackage.WITH_STYLE__STYLE: return ReportDSLPackage.DATAMART_TABLE_PROPERTY__STYLE;
				default: return -1;
			}
		}
		return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
	}

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

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (hideLabelInterval: ");
		result.append(hideLabelInterval);
		result.append(", hideLabelLookup: ");
		result.append(hideLabelLookup);
		result.append(", hasImage: ");
		result.append(hasImage);
		result.append(')');
		return result.toString();
	}

} //DatamartTablePropertyImpl
