/**
 * Copyright (c) 2011, 2016 - Lunifera GmbH (Gross Enzersdorf), Loetz GmbH&Co.KG (Heidelberg)
 *  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.dsl.semantic.dto.impl;

import com.google.common.base.Objects;

import com.google.common.collect.Iterables;
import java.util.Collection;
import java.util.List;

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.EObjectWithInverseResolvingEList;
import org.eclipse.emf.ecore.util.InternalEList;

import org.eclipse.osbp.dsl.semantic.common.types.LAttribute;
import org.eclipse.osbp.dsl.semantic.common.types.LFeature;
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType;
import org.eclipse.osbp.dsl.semantic.common.types.LType;

import org.eclipse.osbp.dsl.semantic.common.types.impl.LClassImpl;

import org.eclipse.osbp.dsl.semantic.dto.LDto;
import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractAttribute;
import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractReference;
import org.eclipse.osbp.dsl.semantic.dto.LDtoAttribute;
import org.eclipse.osbp.dsl.semantic.dto.LDtoFeature;
import org.eclipse.osbp.dsl.semantic.dto.LDtoInheritedAttribute;
import org.eclipse.osbp.dsl.semantic.dto.LDtoOperation;
import org.eclipse.osbp.dsl.semantic.dto.OSBPDtoPackage;
import org.eclipse.osbp.dsl.semantic.entity.LEntity;
import org.eclipse.osbp.runtime.common.annotations.HistIsCurrent;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>LDto</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.dto.impl.LDtoImpl#getFeatures <em>Features</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.dto.impl.LDtoImpl#getSuperType <em>Super Type</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.dto.impl.LDtoImpl#getSubTypes <em>Sub Types</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.dto.impl.LDtoImpl#getWrappedType <em>Wrapped Type</em>}</li>
 * </ul>
 *
 * @generated
 */
public class LDtoImpl extends LClassImpl implements LDto {
	/**
	 * The cached value of the '{@link #getFeatures() <em>Features</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFeatures()
	 * @generated
	 * @ordered
	 */
	protected EList<LDtoFeature> features;

	/**
	 * The cached value of the '{@link #getSuperType() <em>Super Type</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSuperType()
	 * @generated
	 * @ordered
	 */
	protected LDto superType;

	/**
	 * The cached value of the '{@link #getSubTypes() <em>Sub Types</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSubTypes()
	 * @generated
	 * @ordered
	 */
	protected EList<LDto> subTypes;

	/**
	 * The cached value of the '{@link #getWrappedType() <em>Wrapped Type</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getWrappedType()
	 * @generated
	 * @ordered
	 */
	protected LType wrappedType;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<LDtoFeature> getFeatures() {
		if (features == null) {
			features = new EObjectContainmentEList<LDtoFeature>(LDtoFeature.class, this, OSBPDtoPackage.LDTO__FEATURES);
		}
		return features;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LDto getSuperType() {
		if (superType != null && superType.eIsProxy()) {
			InternalEObject oldSuperType = (InternalEObject)superType;
			superType = (LDto)eResolveProxy(oldSuperType);
			if (superType != oldSuperType) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, OSBPDtoPackage.LDTO__SUPER_TYPE, oldSuperType, superType));
			}
		}
		return superType;
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetSuperType(LDto newSuperType, NotificationChain msgs) {
		LDto oldSuperType = superType;
		superType = newSuperType;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, OSBPDtoPackage.LDTO__SUPER_TYPE, oldSuperType, newSuperType);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setSuperType(LDto newSuperType) {
		if (newSuperType != superType) {
			NotificationChain msgs = null;
			if (superType != null)
				msgs = ((InternalEObject)superType).eInverseRemove(this, OSBPDtoPackage.LDTO__SUB_TYPES, LDto.class, msgs);
			if (newSuperType != null)
				msgs = ((InternalEObject)newSuperType).eInverseAdd(this, OSBPDtoPackage.LDTO__SUB_TYPES, LDto.class, msgs);
			msgs = basicSetSuperType(newSuperType, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPDtoPackage.LDTO__SUPER_TYPE, newSuperType, newSuperType));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<LDto> getSubTypes() {
		if (subTypes == null) {
			subTypes = new EObjectWithInverseResolvingEList<LDto>(LDto.class, this, OSBPDtoPackage.LDTO__SUB_TYPES, OSBPDtoPackage.LDTO__SUPER_TYPE);
		}
		return subTypes;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LType getWrappedType() {
		if (wrappedType != null && wrappedType.eIsProxy()) {
			InternalEObject oldWrappedType = (InternalEObject)wrappedType;
			wrappedType = (LType)eResolveProxy(oldWrappedType);
			if (wrappedType != oldWrappedType) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, OSBPDtoPackage.LDTO__WRAPPED_TYPE, oldWrappedType, wrappedType));
			}
		}
		return wrappedType;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LType basicGetWrappedType() {
		return wrappedType;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setWrappedType(LType newWrappedType) {
		LType oldWrappedType = wrappedType;
		wrappedType = newWrappedType;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPDtoPackage.LDTO__WRAPPED_TYPE, oldWrappedType, wrappedType));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public List<LDtoOperation> getOperations() {
		return IterableExtensions.<LDtoOperation>toList(Iterables.<LDtoOperation>filter(this.getFeatures(), LDtoOperation.class));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public List<LDtoAbstractReference> getReferences() {
		return IterableExtensions.<LDtoAbstractReference>toList(Iterables.<LDtoAbstractReference>filter(this.getFeatures(), LDtoAbstractReference.class));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public List<LDtoAbstractAttribute> getAttributes() {
		return IterableExtensions.<LDtoAbstractAttribute>toList(Iterables.<LDtoAbstractAttribute>filter(this.getFeatures(), LDtoAbstractAttribute.class));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public List<? extends LFeature> getAllFeatures() {
		final List<LDtoFeature> result = CollectionLiterals.<LDtoFeature>newArrayList();
		this.collectAllOSBPFeatures(this, result);
		return result;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LAttribute getIdAttribute() {
		final Function1<LDtoAbstractAttribute, Boolean> _function = new Function1<LDtoAbstractAttribute, Boolean>() {
			public Boolean apply(final LDtoAbstractAttribute it) {
				boolean _matched = false;
				if (it instanceof LDtoInheritedAttribute) {
					_matched=true;
					boolean _or = false;
					LAttribute _inheritedFeature = ((LDtoInheritedAttribute)it).getInheritedFeature();
					boolean _isId = false;
					if (_inheritedFeature!=null) {
						_isId=_inheritedFeature.isId();
					}
					if (_isId) {
						_or = true;
					} else {
						LAttribute _inheritedFeature_1 = ((LDtoInheritedAttribute)it).getInheritedFeature();
						boolean _isUuid = false;
						if (_inheritedFeature_1!=null) {
							_isUuid=_inheritedFeature_1.isUuid();
						}
						_or = _isUuid;
					}
					return Boolean.valueOf(_or);
				}
				if (!_matched) {
					if (it instanceof LDtoAttribute) {
						_matched=true;
						return Boolean.valueOf((((LDtoAttribute)it).isId() || ((LDtoAttribute)it).isUuid()));
					}
				}
				return Boolean.valueOf(false);
			}
		};
		final LDtoAbstractAttribute feature = IterableExtensions.<LDtoAbstractAttribute>findFirst(Iterables.<LDtoAbstractAttribute>filter(this.getAllFeatures(), LDtoAbstractAttribute.class), _function);
		boolean _matched = false;
		if (feature instanceof LDtoAttribute) {
			_matched=true;
			return feature;
		}
		if (!_matched) {
			if (feature instanceof LDtoInheritedAttribute) {
				_matched=true;
				return ((LDtoInheritedAttribute)feature).getInheritedFeature();
			}
		}
		return null;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void collectAllOSBPFeatures(final LDto current, final List<LDtoFeature> result) {
		if ((current == null)) {
			return;
		}
		result.addAll(current.getFeatures());
		this.collectAllOSBPFeatures(current.getSuperType(), result);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LDtoAbstractAttribute getPrimaryKeyAttribute() {
		final Function1<LDtoAbstractAttribute, Boolean> _function = new Function1<LDtoAbstractAttribute, Boolean>() {
			public Boolean apply(final LDtoAbstractAttribute it) {
				boolean _matched = false;
				if (it instanceof LDtoInheritedAttribute) {
					_matched=true;
					boolean _or = false;
					LAttribute _inheritedFeature = ((LDtoInheritedAttribute)it).getInheritedFeature();
					boolean _isId = false;
					if (_inheritedFeature!=null) {
						_isId=_inheritedFeature.isId();
					}
					if (_isId) {
						_or = true;
					} else {
						LAttribute _inheritedFeature_1 = ((LDtoInheritedAttribute)it).getInheritedFeature();
						boolean _isUuid = false;
						if (_inheritedFeature_1!=null) {
							_isUuid=_inheritedFeature_1.isUuid();
						}
						_or = _isUuid;
					}
					return Boolean.valueOf(_or);
				}
				if (!_matched) {
					if (it instanceof LDtoAttribute) {
						_matched=true;
						return Boolean.valueOf((((LDtoAttribute)it).isId() || ((LDtoAttribute)it).isUuid()));
					}
				}
				return Boolean.valueOf(false);
			}
		};
		return IterableExtensions.<LDtoAbstractAttribute>findFirst(Iterables.<LDtoAbstractAttribute>filter(this.getAllFeatures(), LDtoAbstractAttribute.class), _function);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String getIdAttributeName() {
		LDtoAbstractAttribute attribute = this.getPrimaryKeyAttribute();
		boolean _matched = false;
		if (attribute instanceof LDtoInheritedAttribute) {
			_matched=true;
			return ((LDtoInheritedAttribute)attribute).getInheritedFeature().getName();
		}
		if (!_matched) {
			if (attribute instanceof LDtoAttribute) {
				_matched=true;
				return ((LDtoAttribute)attribute).getName();
			}
		}
		return null;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LScalarType getIdAttributeType() {
		LDtoAbstractAttribute attribute = this.getPrimaryKeyAttribute();
		boolean _matched = false;
		if (attribute instanceof LDtoInheritedAttribute) {
			_matched=true;
			return ((LDtoInheritedAttribute)attribute).getInheritedFeature().getType();
		}
		if (!_matched) {
			if (Objects.equal(attribute, LDtoAttribute.class)) {
				_matched=true;
				return attribute.getType();
			}
		}
		return null;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isHistorized() {
		LType _wrappedType = this.getWrappedType();
		if ((_wrappedType instanceof LEntity)) {
			LType _wrappedType_1 = this.getWrappedType();
			final LEntity entity = ((LEntity) _wrappedType_1);
			return entity.isHistorizedWithParent();
		}
		return false;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isTimedependent() {
		LType _wrappedType = this.getWrappedType();
		if ((_wrappedType instanceof LEntity)) {
			LType _wrappedType_1 = this.getWrappedType();
			final LEntity entity = ((LEntity) _wrappedType_1);
			return entity.isTimedependentWithParent();
		}
		return false;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isHistorizedOrTimedependent() {
		return (this.isHistorized() || this.isTimedependent());
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LDtoAbstractAttribute getHistCurrentAttribute() {
		final Function1<LDtoAbstractAttribute, Boolean> _function = new Function1<LDtoAbstractAttribute, Boolean>() {
			public Boolean apply(final LDtoAbstractAttribute it) {
				return Boolean.valueOf(it.getResolvedAnnotations().contains(HistIsCurrent.class));
			}
		};
		return IterableExtensions.<LDtoAbstractAttribute>findFirst(Iterables.<LDtoAbstractAttribute>filter(this.getAllFeatures(), LDtoAbstractAttribute.class), _function);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case OSBPDtoPackage.LDTO__SUPER_TYPE:
				if (superType != null)
					msgs = ((InternalEObject)superType).eInverseRemove(this, OSBPDtoPackage.LDTO__SUB_TYPES, LDto.class, msgs);
				return basicSetSuperType((LDto)otherEnd, msgs);
			case OSBPDtoPackage.LDTO__SUB_TYPES:
				return ((InternalEList<InternalEObject>)(InternalEList<?>)getSubTypes()).basicAdd(otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case OSBPDtoPackage.LDTO__FEATURES:
				return ((InternalEList<?>)getFeatures()).basicRemove(otherEnd, msgs);
			case OSBPDtoPackage.LDTO__SUPER_TYPE:
				return basicSetSuperType(null, msgs);
			case OSBPDtoPackage.LDTO__SUB_TYPES:
				return ((InternalEList<?>)getSubTypes()).basicRemove(otherEnd, 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 OSBPDtoPackage.LDTO__FEATURES:
				return getFeatures();
			case OSBPDtoPackage.LDTO__SUPER_TYPE:
				if (resolve) return getSuperType();
				return basicGetSuperType();
			case OSBPDtoPackage.LDTO__SUB_TYPES:
				return getSubTypes();
			case OSBPDtoPackage.LDTO__WRAPPED_TYPE:
				if (resolve) return getWrappedType();
				return basicGetWrappedType();
		}
		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 OSBPDtoPackage.LDTO__FEATURES:
				getFeatures().clear();
				getFeatures().addAll((Collection<? extends LDtoFeature>)newValue);
				return;
			case OSBPDtoPackage.LDTO__SUPER_TYPE:
				setSuperType((LDto)newValue);
				return;
			case OSBPDtoPackage.LDTO__SUB_TYPES:
				getSubTypes().clear();
				getSubTypes().addAll((Collection<? extends LDto>)newValue);
				return;
			case OSBPDtoPackage.LDTO__WRAPPED_TYPE:
				setWrappedType((LType)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case OSBPDtoPackage.LDTO__FEATURES:
				getFeatures().clear();
				return;
			case OSBPDtoPackage.LDTO__SUPER_TYPE:
				setSuperType((LDto)null);
				return;
			case OSBPDtoPackage.LDTO__SUB_TYPES:
				getSubTypes().clear();
				return;
			case OSBPDtoPackage.LDTO__WRAPPED_TYPE:
				setWrappedType((LType)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case OSBPDtoPackage.LDTO__FEATURES:
				return features != null && !features.isEmpty();
			case OSBPDtoPackage.LDTO__SUPER_TYPE:
				return superType != null;
			case OSBPDtoPackage.LDTO__SUB_TYPES:
				return subTypes != null && !subTypes.isEmpty();
			case OSBPDtoPackage.LDTO__WRAPPED_TYPE:
				return wrappedType != null;
		}
		return super.eIsSet(featureID);
	}

} //LDtoImpl
