/**
 *                                                                            
 *  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:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 */
 package org.eclipse.osbp.ecview.core.extension.model.extension.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.ecview.core.common.model.core.YEmbeddable;
import org.eclipse.osbp.ecview.core.common.model.core.impl.YLayoutImpl;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelFactory;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YAbsoluteLayout;
import org.eclipse.osbp.ecview.core.extension.model.extension.YAbsoluteLayoutCellStyle;

/**
 * <!-- begin-user-doc --> An implementation of the model object '
 * <em><b>YAbsolute Layout</b></em>'. <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YAbsoluteLayoutImpl#getCellStyles <em>Cell Styles</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YAbsoluteLayoutImpl#isChildResizeEnabled <em>Child Resize Enabled</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YAbsoluteLayoutImpl#isChildMoveEnabled <em>Child Move Enabled</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class YAbsoluteLayoutImpl extends YLayoutImpl implements YAbsoluteLayout {
	/**
	 * The cached value of the '{@link #getCellStyles() <em>Cell Styles</em>}' containment reference list.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getCellStyles()
	 * @generated
	 * @ordered
	 */
	protected EList<YAbsoluteLayoutCellStyle> cellStyles;

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

	/**
	 * The cached value of the '{@link #isChildResizeEnabled() <em>Child Resize Enabled</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #isChildResizeEnabled()
	 * @generated
	 * @ordered
	 */
	protected boolean childResizeEnabled = CHILD_RESIZE_ENABLED_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #isChildMoveEnabled() <em>Child Move Enabled</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #isChildMoveEnabled()
	 * @generated
	 * @ordered
	 */
	protected boolean childMoveEnabled = CHILD_MOVE_ENABLED_EDEFAULT;

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

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public EList<YAbsoluteLayoutCellStyle> getCellStyles() {
		if (cellStyles == null) {
			cellStyles = new EObjectContainmentEList.Resolving<YAbsoluteLayoutCellStyle>(YAbsoluteLayoutCellStyle.class, this, ExtensionModelPackage.YABSOLUTE_LAYOUT__CELL_STYLES);
		}
		return cellStyles;
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setChildResizeEnabled(boolean newChildResizeEnabled) {
		boolean oldChildResizeEnabled = childResizeEnabled;
		childResizeEnabled = newChildResizeEnabled;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YABSOLUTE_LAYOUT__CHILD_RESIZE_ENABLED, oldChildResizeEnabled, childResizeEnabled));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setChildMoveEnabled(boolean newChildMoveEnabled) {
		boolean oldChildMoveEnabled = childMoveEnabled;
		childMoveEnabled = newChildMoveEnabled;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YABSOLUTE_LAYOUT__CHILD_MOVE_ENABLED, oldChildMoveEnabled, childMoveEnabled));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ExtensionModelPackage.YABSOLUTE_LAYOUT__CELL_STYLES:
				return ((InternalEList<?>)getCellStyles()).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 ExtensionModelPackage.YABSOLUTE_LAYOUT__CELL_STYLES:
				return getCellStyles();
			case ExtensionModelPackage.YABSOLUTE_LAYOUT__CHILD_RESIZE_ENABLED:
				return isChildResizeEnabled();
			case ExtensionModelPackage.YABSOLUTE_LAYOUT__CHILD_MOVE_ENABLED:
				return isChildMoveEnabled();
		}
		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 ExtensionModelPackage.YABSOLUTE_LAYOUT__CELL_STYLES:
				getCellStyles().clear();
				getCellStyles().addAll((Collection<? extends YAbsoluteLayoutCellStyle>)newValue);
				return;
			case ExtensionModelPackage.YABSOLUTE_LAYOUT__CHILD_RESIZE_ENABLED:
				setChildResizeEnabled((Boolean)newValue);
				return;
			case ExtensionModelPackage.YABSOLUTE_LAYOUT__CHILD_MOVE_ENABLED:
				setChildMoveEnabled((Boolean)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ExtensionModelPackage.YABSOLUTE_LAYOUT__CELL_STYLES:
				getCellStyles().clear();
				return;
			case ExtensionModelPackage.YABSOLUTE_LAYOUT__CHILD_RESIZE_ENABLED:
				setChildResizeEnabled(CHILD_RESIZE_ENABLED_EDEFAULT);
				return;
			case ExtensionModelPackage.YABSOLUTE_LAYOUT__CHILD_MOVE_ENABLED:
				setChildMoveEnabled(CHILD_MOVE_ENABLED_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ExtensionModelPackage.YABSOLUTE_LAYOUT__CELL_STYLES:
				return cellStyles != null && !cellStyles.isEmpty();
			case ExtensionModelPackage.YABSOLUTE_LAYOUT__CHILD_RESIZE_ENABLED:
				return childResizeEnabled != CHILD_RESIZE_ENABLED_EDEFAULT;
			case ExtensionModelPackage.YABSOLUTE_LAYOUT__CHILD_MOVE_ENABLED:
				return childMoveEnabled != CHILD_MOVE_ENABLED_EDEFAULT;
		}
		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(" (childResizeEnabled: ");
		result.append(childResizeEnabled);
		result.append(", childMoveEnabled: ");
		result.append(childMoveEnabled);
		result.append(')');
		return result.toString();
	}

	public YAbsoluteLayoutCellStyle getCellStyle(YEmbeddable element) {
		for (YAbsoluteLayoutCellStyle style : getCellStyles()) {
			if (element == style.getTarget()) {
				return style;
			}
		}
		
		YAbsoluteLayoutCellStyle yStyle = ExtensionModelFactory.eINSTANCE
				.createYAbsoluteLayoutCellStyle();
		yStyle.setTarget(element);
		getCellStyles().add(yStyle);
		return yStyle;
	}

} // YAbsoluteLayoutImpl
