/**
 * 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.table.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.action.ActionToolbar;

import org.eclipse.osbp.xtext.table.RowHeaderMode;
import org.eclipse.osbp.xtext.table.TableDSLPackage;
import org.eclipse.osbp.xtext.table.TableDatamart;
import org.eclipse.osbp.xtext.table.TableTable;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Table Table</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.table.impl.TableTableImpl#isFiltering <em>Filtering</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.table.impl.TableTableImpl#getToolbar <em>Toolbar</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.table.impl.TableTableImpl#isEmbedded <em>Embedded</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.table.impl.TableTableImpl#isSelectById <em>Select By Id</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.table.impl.TableTableImpl#isSelectalways <em>Selectalways</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.table.impl.TableTableImpl#getHeaderMode <em>Header Mode</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.table.impl.TableTableImpl#getSource <em>Source</em>}</li>
 * </ul>
 *
 * @generated
 */
public class TableTableImpl extends TableLazyResolverImpl implements TableTable {
	/**
	 * The default value of the '{@link #isFiltering() <em>Filtering</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isFiltering()
	 * @generated
	 * @ordered
	 */
	protected static final boolean FILTERING_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isFiltering() <em>Filtering</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isFiltering()
	 * @generated
	 * @ordered
	 */
	protected boolean filtering = FILTERING_EDEFAULT;

	/**
	 * The cached value of the '{@link #getToolbar() <em>Toolbar</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getToolbar()
	 * @generated
	 * @ordered
	 */
	protected ActionToolbar toolbar;

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

	/**
	 * The cached value of the '{@link #isEmbedded() <em>Embedded</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isEmbedded()
	 * @generated
	 * @ordered
	 */
	protected boolean embedded = EMBEDDED_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #isSelectById() <em>Select By Id</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isSelectById()
	 * @generated
	 * @ordered
	 */
	protected boolean selectById = SELECT_BY_ID_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #isSelectalways() <em>Selectalways</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isSelectalways()
	 * @generated
	 * @ordered
	 */
	protected boolean selectalways = SELECTALWAYS_EDEFAULT;

	/**
	 * The default value of the '{@link #getHeaderMode() <em>Header Mode</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getHeaderMode()
	 * @generated
	 * @ordered
	 */
	protected static final RowHeaderMode HEADER_MODE_EDEFAULT = RowHeaderMode.HIDDEN;

	/**
	 * The cached value of the '{@link #getHeaderMode() <em>Header Mode</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getHeaderMode()
	 * @generated
	 * @ordered
	 */
	protected RowHeaderMode headerMode = HEADER_MODE_EDEFAULT;

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

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setFiltering(boolean newFiltering) {
		boolean oldFiltering = filtering;
		filtering = newFiltering;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, TableDSLPackage.TABLE_TABLE__FILTERING, oldFiltering, filtering));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ActionToolbar getToolbar() {
		if (toolbar != null && toolbar.eIsProxy()) {
			InternalEObject oldToolbar = (InternalEObject)toolbar;
			toolbar = (ActionToolbar)eResolveProxy(oldToolbar);
			if (toolbar != oldToolbar) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, TableDSLPackage.TABLE_TABLE__TOOLBAR, oldToolbar, toolbar));
			}
		}
		return toolbar;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ActionToolbar basicGetToolbar() {
		return toolbar;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setToolbar(ActionToolbar newToolbar) {
		ActionToolbar oldToolbar = toolbar;
		toolbar = newToolbar;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, TableDSLPackage.TABLE_TABLE__TOOLBAR, oldToolbar, toolbar));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setEmbedded(boolean newEmbedded) {
		boolean oldEmbedded = embedded;
		embedded = newEmbedded;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, TableDSLPackage.TABLE_TABLE__EMBEDDED, oldEmbedded, embedded));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setSelectById(boolean newSelectById) {
		boolean oldSelectById = selectById;
		selectById = newSelectById;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, TableDSLPackage.TABLE_TABLE__SELECT_BY_ID, oldSelectById, selectById));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setSelectalways(boolean newSelectalways) {
		boolean oldSelectalways = selectalways;
		selectalways = newSelectalways;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, TableDSLPackage.TABLE_TABLE__SELECTALWAYS, oldSelectalways, selectalways));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public RowHeaderMode getHeaderMode() {
		return headerMode;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHeaderMode(RowHeaderMode newHeaderMode) {
		RowHeaderMode oldHeaderMode = headerMode;
		headerMode = newHeaderMode == null ? HEADER_MODE_EDEFAULT : newHeaderMode;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, TableDSLPackage.TABLE_TABLE__HEADER_MODE, oldHeaderMode, headerMode));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public TableDatamart getSource() {
		return source;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetSource(TableDatamart newSource, NotificationChain msgs) {
		TableDatamart oldSource = source;
		source = newSource;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, TableDSLPackage.TABLE_TABLE__SOURCE, oldSource, newSource);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setSource(TableDatamart newSource) {
		if (newSource != source) {
			NotificationChain msgs = null;
			if (source != null)
				msgs = ((InternalEObject)source).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - TableDSLPackage.TABLE_TABLE__SOURCE, null, msgs);
			if (newSource != null)
				msgs = ((InternalEObject)newSource).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - TableDSLPackage.TABLE_TABLE__SOURCE, null, msgs);
			msgs = basicSetSource(newSource, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, TableDSLPackage.TABLE_TABLE__SOURCE, newSource, newSource));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case TableDSLPackage.TABLE_TABLE__SOURCE:
				return basicSetSource(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 TableDSLPackage.TABLE_TABLE__FILTERING:
				return isFiltering();
			case TableDSLPackage.TABLE_TABLE__TOOLBAR:
				if (resolve) return getToolbar();
				return basicGetToolbar();
			case TableDSLPackage.TABLE_TABLE__EMBEDDED:
				return isEmbedded();
			case TableDSLPackage.TABLE_TABLE__SELECT_BY_ID:
				return isSelectById();
			case TableDSLPackage.TABLE_TABLE__SELECTALWAYS:
				return isSelectalways();
			case TableDSLPackage.TABLE_TABLE__HEADER_MODE:
				return getHeaderMode();
			case TableDSLPackage.TABLE_TABLE__SOURCE:
				return getSource();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case TableDSLPackage.TABLE_TABLE__FILTERING:
				setFiltering((Boolean)newValue);
				return;
			case TableDSLPackage.TABLE_TABLE__TOOLBAR:
				setToolbar((ActionToolbar)newValue);
				return;
			case TableDSLPackage.TABLE_TABLE__EMBEDDED:
				setEmbedded((Boolean)newValue);
				return;
			case TableDSLPackage.TABLE_TABLE__SELECT_BY_ID:
				setSelectById((Boolean)newValue);
				return;
			case TableDSLPackage.TABLE_TABLE__SELECTALWAYS:
				setSelectalways((Boolean)newValue);
				return;
			case TableDSLPackage.TABLE_TABLE__HEADER_MODE:
				setHeaderMode((RowHeaderMode)newValue);
				return;
			case TableDSLPackage.TABLE_TABLE__SOURCE:
				setSource((TableDatamart)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case TableDSLPackage.TABLE_TABLE__FILTERING:
				setFiltering(FILTERING_EDEFAULT);
				return;
			case TableDSLPackage.TABLE_TABLE__TOOLBAR:
				setToolbar((ActionToolbar)null);
				return;
			case TableDSLPackage.TABLE_TABLE__EMBEDDED:
				setEmbedded(EMBEDDED_EDEFAULT);
				return;
			case TableDSLPackage.TABLE_TABLE__SELECT_BY_ID:
				setSelectById(SELECT_BY_ID_EDEFAULT);
				return;
			case TableDSLPackage.TABLE_TABLE__SELECTALWAYS:
				setSelectalways(SELECTALWAYS_EDEFAULT);
				return;
			case TableDSLPackage.TABLE_TABLE__HEADER_MODE:
				setHeaderMode(HEADER_MODE_EDEFAULT);
				return;
			case TableDSLPackage.TABLE_TABLE__SOURCE:
				setSource((TableDatamart)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case TableDSLPackage.TABLE_TABLE__FILTERING:
				return filtering != FILTERING_EDEFAULT;
			case TableDSLPackage.TABLE_TABLE__TOOLBAR:
				return toolbar != null;
			case TableDSLPackage.TABLE_TABLE__EMBEDDED:
				return embedded != EMBEDDED_EDEFAULT;
			case TableDSLPackage.TABLE_TABLE__SELECT_BY_ID:
				return selectById != SELECT_BY_ID_EDEFAULT;
			case TableDSLPackage.TABLE_TABLE__SELECTALWAYS:
				return selectalways != SELECTALWAYS_EDEFAULT;
			case TableDSLPackage.TABLE_TABLE__HEADER_MODE:
				return headerMode != HEADER_MODE_EDEFAULT;
			case TableDSLPackage.TABLE_TABLE__SOURCE:
				return source != 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(" (filtering: ");
		result.append(filtering);
		result.append(", embedded: ");
		result.append(embedded);
		result.append(", selectById: ");
		result.append(selectById);
		result.append(", selectalways: ");
		result.append(selectalways);
		result.append(", headerMode: ");
		result.append(headerMode);
		result.append(')');
		return result.toString();
	}

} //TableTableImpl
