/**
 *                                                                            
 *  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                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Florian Pirchner - Initial implementation
 * 
 */
package org.eclipse.osbp.ecview.extension.model.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.common.util.EMap;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EcoreEMap;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.osbp.ecview.core.common.model.core.CoreModelPackage;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable;
import org.eclipse.osbp.ecview.core.common.model.core.YLayout;
import org.eclipse.osbp.ecview.core.common.model.core.YView;
import org.eclipse.osbp.ecview.core.common.model.core.impl.YStringToStringMapImpl;
import org.eclipse.osbp.ecview.extension.model.YECviewFactory;
import org.eclipse.osbp.ecview.extension.model.YECviewPackage;
import org.eclipse.osbp.ecview.extension.model.YLayoutingInfo;
import org.eclipse.osbp.ecview.extension.model.YStrategyLayout;
import org.eclipse.osbp.ecview.extension.model.YSuspect;
import org.eclipse.osbp.ecview.extension.model.YSuspectInfo;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>YLayouting Info</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YLayoutingInfoImpl#getTags <em>Tags</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YLayoutingInfoImpl#getId <em>Id</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YLayoutingInfoImpl#getName <em>Name</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YLayoutingInfoImpl#getProperties <em>Properties</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YLayoutingInfoImpl#getLayout <em>Layout</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YLayoutingInfoImpl#getContent <em>Content</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YLayoutingInfoImpl#getActiveSuspectInfos <em>Active Suspect Infos</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YLayoutingInfoImpl#getFirstFocus <em>First Focus</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class YLayoutingInfoImpl extends MinimalEObjectImpl.Container implements YLayoutingInfo {
	
	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @generated
	 */
	public static final String copyright = "All rights reserved by Loetz GmbH und CoKG Heidelberg 2015.\n\nContributors:\n      Florian Pirchner - initial API and implementation";

	/**
	 * The cached value of the '{@link #getTags() <em>Tags</em>}' attribute list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTags()
	 * @generated
	 * @ordered
	 */
	protected EList<String> tags;

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

	/**
	 * The cached value of the '{@link #getId() <em>Id</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getId()
	 * @generated
	 * @ordered
	 */
	protected String id = ID_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getName() <em>Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getName()
	 * @generated
	 * @ordered
	 */
	protected String name = NAME_EDEFAULT;

	/**
	 * The cached value of the '{@link #getProperties() <em>Properties</em>}' map.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getProperties()
	 * @generated
	 * @ordered
	 */
	protected EMap<String, String> properties;

	/**
	 * The cached value of the '{@link #getLayout() <em>Layout</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLayout()
	 * @generated
	 * @ordered
	 */
	protected YStrategyLayout layout;

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

	/**
	 * The cached value of the '{@link #getActiveSuspectInfos() <em>Active Suspect Infos</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getActiveSuspectInfos()
	 * @generated
	 * @ordered
	 */
	protected EList<YSuspectInfo> activeSuspectInfos;

	/**
	 * The cached value of the '{@link #getFirstFocus() <em>First Focus</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFirstFocus()
	 * @generated
	 * @ordered
	 */
	protected YSuspectInfo firstFocus;

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

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

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newId
	 *            the new cached value of the '{@link #getId() <em>Id</em>}'
	 *            attribute
	 * @generated
	 */
	public void setId(String newId) {
		String oldId = id;
		id = newId;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YLAYOUTING_INFO__ID, oldId, id));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newName
	 *            the new cached value of the '{@link #getName() <em>Name</em>}'
	 *            attribute
	 * @generated
	 */
	public void setName(String newName) {
		String oldName = name;
		name = newName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YLAYOUTING_INFO__NAME, oldName, name));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getTags() <em>Tags</em>}'
	 *         attribute list
	 * @generated
	 */
	public EList<String> getTags() {
		if (tags == null) {
			tags = new EDataTypeUniqueEList<String>(String.class, this, YECviewPackage.YLAYOUTING_INFO__TAGS);
		}
		return tags;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getProperties()
	 *         <em>Properties</em>}' map
	 * @generated
	 */
	public EMap<String, String> getProperties() {
		if (properties == null) {
			properties = new EcoreEMap<String,String>(CoreModelPackage.Literals.YSTRING_TO_STRING_MAP, YStringToStringMapImpl.class, this, YECviewPackage.YLAYOUTING_INFO__PROPERTIES);
		}
		return properties;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getLayout() <em>Layout</em>}'
	 *         reference
	 * @generated
	 */
	public YStrategyLayout getLayout() {
		if (layout != null && layout.eIsProxy()) {
			InternalEObject oldLayout = (InternalEObject)layout;
			layout = (YStrategyLayout)eResolveProxy(oldLayout);
			if (layout != oldLayout) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, YECviewPackage.YLAYOUTING_INFO__LAYOUT, oldLayout, layout));
			}
		}
		return layout;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the y strategy layout
	 * @generated
	 */
	public YStrategyLayout basicGetLayout() {
		return layout;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newLayout
	 *            the new cached value of the '{@link #getLayout()
	 *            <em>Layout</em>}' reference
	 * @generated
	 */
	public void setLayout(YStrategyLayout newLayout) {
		YStrategyLayout oldLayout = layout;
		layout = newLayout;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YLAYOUTING_INFO__LAYOUT, oldLayout, layout));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getContent() <em>Content</em>}'
	 *         containment reference
	 * @generated
	 */
	public YEmbeddable getContent() {
		return content;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newContent
	 *            the new content
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	public NotificationChain basicSetContent(YEmbeddable newContent, NotificationChain msgs) {
		YEmbeddable oldContent = content;
		content = newContent;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, YECviewPackage.YLAYOUTING_INFO__CONTENT, oldContent, newContent);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newContent
	 *            the new cached value of the '{@link #getContent()
	 *            <em>Content</em>}' containment reference
	 * @generated
	 */
	public void setContent(YEmbeddable newContent) {
		if (newContent != content) {
			NotificationChain msgs = null;
			if (content != null)
				msgs = ((InternalEObject)content).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - YECviewPackage.YLAYOUTING_INFO__CONTENT, null, msgs);
			if (newContent != null)
				msgs = ((InternalEObject)newContent).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - YECviewPackage.YLAYOUTING_INFO__CONTENT, null, msgs);
			msgs = basicSetContent(newContent, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YLAYOUTING_INFO__CONTENT, newContent, newContent));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getActiveSuspectInfos()
	 *         <em>Active Suspect Infos</em>}' containment reference list
	 * @generated
	 */
	public EList<YSuspectInfo> getActiveSuspectInfos() {
		if (activeSuspectInfos == null) {
			activeSuspectInfos = new EObjectContainmentEList<YSuspectInfo>(YSuspectInfo.class, this, YECviewPackage.YLAYOUTING_INFO__ACTIVE_SUSPECT_INFOS);
		}
		return activeSuspectInfos;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getFirstFocus()
	 *         <em>First Focus</em>}' reference
	 * @generated
	 */
	public YSuspectInfo getFirstFocus() {
		if (firstFocus != null && firstFocus.eIsProxy()) {
			InternalEObject oldFirstFocus = (InternalEObject)firstFocus;
			firstFocus = (YSuspectInfo)eResolveProxy(oldFirstFocus);
			if (firstFocus != oldFirstFocus) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, YECviewPackage.YLAYOUTING_INFO__FIRST_FOCUS, oldFirstFocus, firstFocus));
			}
		}
		return firstFocus;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the y suspect info
	 * @generated
	 */
	public YSuspectInfo basicGetFirstFocus() {
		return firstFocus;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newFirstFocus
	 *            the new cached value of the '{@link #getFirstFocus()
	 *            <em>First Focus</em>}' reference
	 * @generated
	 */
	public void setFirstFocus(YSuspectInfo newFirstFocus) {
		YSuspectInfo oldFirstFocus = firstFocus;
		firstFocus = newFirstFocus;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YLAYOUTING_INFO__FIRST_FOCUS, oldFirstFocus, firstFocus));
	}

	/**
	 * <!-- 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 YECviewPackage.YLAYOUTING_INFO__PROPERTIES:
				return ((InternalEList<?>)getProperties()).basicRemove(otherEnd, msgs);
			case YECviewPackage.YLAYOUTING_INFO__CONTENT:
				return basicSetContent(null, msgs);
			case YECviewPackage.YLAYOUTING_INFO__ACTIVE_SUSPECT_INFOS:
				return ((InternalEList<?>)getActiveSuspectInfos()).basicRemove(otherEnd, 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 YECviewPackage.YLAYOUTING_INFO__TAGS:
				return getTags();
			case YECviewPackage.YLAYOUTING_INFO__ID:
				return getId();
			case YECviewPackage.YLAYOUTING_INFO__NAME:
				return getName();
			case YECviewPackage.YLAYOUTING_INFO__PROPERTIES:
				if (coreType) return getProperties();
				else return getProperties().map();
			case YECviewPackage.YLAYOUTING_INFO__LAYOUT:
				if (resolve) return getLayout();
				return basicGetLayout();
			case YECviewPackage.YLAYOUTING_INFO__CONTENT:
				return getContent();
			case YECviewPackage.YLAYOUTING_INFO__ACTIVE_SUSPECT_INFOS:
				return getActiveSuspectInfos();
			case YECviewPackage.YLAYOUTING_INFO__FIRST_FOCUS:
				if (resolve) return getFirstFocus();
				return basicGetFirstFocus();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @param newValue
	 *            the new value
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case YECviewPackage.YLAYOUTING_INFO__TAGS:
				getTags().clear();
				getTags().addAll((Collection<? extends String>)newValue);
				return;
			case YECviewPackage.YLAYOUTING_INFO__ID:
				setId((String)newValue);
				return;
			case YECviewPackage.YLAYOUTING_INFO__NAME:
				setName((String)newValue);
				return;
			case YECviewPackage.YLAYOUTING_INFO__PROPERTIES:
				((EStructuralFeature.Setting)getProperties()).set(newValue);
				return;
			case YECviewPackage.YLAYOUTING_INFO__LAYOUT:
				setLayout((YStrategyLayout)newValue);
				return;
			case YECviewPackage.YLAYOUTING_INFO__CONTENT:
				setContent((YEmbeddable)newValue);
				return;
			case YECviewPackage.YLAYOUTING_INFO__ACTIVE_SUSPECT_INFOS:
				getActiveSuspectInfos().clear();
				getActiveSuspectInfos().addAll((Collection<? extends YSuspectInfo>)newValue);
				return;
			case YECviewPackage.YLAYOUTING_INFO__FIRST_FOCUS:
				setFirstFocus((YSuspectInfo)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 YECviewPackage.YLAYOUTING_INFO__TAGS:
				getTags().clear();
				return;
			case YECviewPackage.YLAYOUTING_INFO__ID:
				setId(ID_EDEFAULT);
				return;
			case YECviewPackage.YLAYOUTING_INFO__NAME:
				setName(NAME_EDEFAULT);
				return;
			case YECviewPackage.YLAYOUTING_INFO__PROPERTIES:
				getProperties().clear();
				return;
			case YECviewPackage.YLAYOUTING_INFO__LAYOUT:
				setLayout((YStrategyLayout)null);
				return;
			case YECviewPackage.YLAYOUTING_INFO__CONTENT:
				setContent((YEmbeddable)null);
				return;
			case YECviewPackage.YLAYOUTING_INFO__ACTIVE_SUSPECT_INFOS:
				getActiveSuspectInfos().clear();
				return;
			case YECviewPackage.YLAYOUTING_INFO__FIRST_FOCUS:
				setFirstFocus((YSuspectInfo)null);
				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 YECviewPackage.YLAYOUTING_INFO__TAGS:
				return tags != null && !tags.isEmpty();
			case YECviewPackage.YLAYOUTING_INFO__ID:
				return ID_EDEFAULT == null ? id != null : !ID_EDEFAULT.equals(id);
			case YECviewPackage.YLAYOUTING_INFO__NAME:
				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
			case YECviewPackage.YLAYOUTING_INFO__PROPERTIES:
				return properties != null && !properties.isEmpty();
			case YECviewPackage.YLAYOUTING_INFO__LAYOUT:
				return layout != null;
			case YECviewPackage.YLAYOUTING_INFO__CONTENT:
				return content != null;
			case YECviewPackage.YLAYOUTING_INFO__ACTIVE_SUSPECT_INFOS:
				return activeSuspectInfos != null && !activeSuspectInfos.isEmpty();
			case YECviewPackage.YLAYOUTING_INFO__FIRST_FOCUS:
				return firstFocus != null;
		}
		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(" (tags: ");
		result.append(tags);
		result.append(", id: ");
		result.append(id);
		result.append(", name: ");
		result.append(name);
		result.append(')');
		return result.toString();
	}

	/**
	 * Creates the suspect info.
	 *
	 * @param suspect
	 *            the suspect
	 * @return the y suspect info
	 * @generated NOT
	 */
	@Override
	public YSuspectInfo createSuspectInfo(YSuspect suspect) {
		YSuspectInfo result = YECviewFactory.eINSTANCE.createYSuspectInfo();
		result.setSuspect(suspect);
		return result;
	}
	
	/**
	 * Gets the view.
	 *
	 * @return the view
	 * @generated NOT
	 */
	public YView getView() {
		return findViewGeneric(getLayout());
	}
	
	/**
	 * Find view generic.
	 *
	 * @param container
	 *            the container
	 * @return the y view
	 * @generated NOT
	 */
	protected YView findViewGeneric(EObject container) {
		if (container == null) {
			return null;
		}
		if (container instanceof YView) {
			return (YView) container;
		} else if (container instanceof YLayout) {
			return ((YLayout) container).getView();
		} else {
			EObject parent = container.eContainer();
			return findViewGeneric(parent);
		}
	}

}
