//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.diagram.model.impl;

import java.util.Collection;
import java.util.Iterator;

import org.eclipse.draw2d.geometry.Point;
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.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.epf.diagram.model.ModelPackage;
import org.eclipse.epf.diagram.model.Node;
import org.eclipse.epf.diagram.model.NodeContainer;


/**
 * <!-- begin-user-doc --> An implementation of the model object '<em><b>Node Container</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 * <li>{@link org.eclipse.epf.diagram.model.impl.NodeContainerImpl#getNodes <em>Nodes</em>}</li>
 * </ul>
 * </p>
 * 
 * @generated
 */
public abstract class NodeContainerImpl extends NodeImpl implements
		NodeContainer {
	/**
	 * The cached value of the '{@link #getNodes() <em>Nodes</em>}'
	 * containment reference list. <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @see #getNodes()
	 * @generated
	 * @ordered
	 */
	protected EList nodes = null;

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected EClass eStaticClass() {
		return ModelPackage.eINSTANCE.getNodeContainer();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	public EList getNodes() {
		if (nodes == null) {
			nodes = new EObjectContainmentEList(Node.class, this,
					ModelPackage.NODE_CONTAINER__NODES);
		}
		return nodes;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	public NotificationChain eInverseAdd(InternalEObject otherEnd,
			int featureID, Class baseClass, NotificationChain msgs) {
		if (featureID >= 0) {
			switch (eDerivedStructuralFeatureID(featureID, baseClass)) {
			case ModelPackage.NODE_CONTAINER__INCOMING_CONNECTIONS:
				return ((InternalEList) getIncomingConnections()).basicAdd(
						otherEnd, msgs);
			case ModelPackage.NODE_CONTAINER__OUTGOING_CONNECTIONS:
				return ((InternalEList) getOutgoingConnections()).basicAdd(
						otherEnd, msgs);
			default:
				return eDynamicInverseAdd(otherEnd, featureID, baseClass, msgs);
			}
		}
		if (eContainer != null)
			msgs = eBasicRemoveFromContainer(msgs);
		return eBasicSetContainer(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	public NotificationChain eInverseRemove(InternalEObject otherEnd,
			int featureID, Class baseClass, NotificationChain msgs) {
		if (featureID >= 0) {
			switch (eDerivedStructuralFeatureID(featureID, baseClass)) {
			case ModelPackage.NODE_CONTAINER__INCOMING_CONNECTIONS:
				return ((InternalEList) getIncomingConnections()).basicRemove(
						otherEnd, msgs);
			case ModelPackage.NODE_CONTAINER__OUTGOING_CONNECTIONS:
				return ((InternalEList) getOutgoingConnections()).basicRemove(
						otherEnd, msgs);
			case ModelPackage.NODE_CONTAINER__NODES:
				return ((InternalEList) getNodes()).basicRemove(otherEnd, msgs);
			default:
				return eDynamicInverseRemove(otherEnd, featureID, baseClass,
						msgs);
			}
		}
		return eBasicSetContainer(null, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	public Object eGet(EStructuralFeature eFeature, boolean resolve) {
		switch (eDerivedStructuralFeatureID(eFeature)) {
		case ModelPackage.NODE_CONTAINER__OBJECT:
			return getObject();
		case ModelPackage.NODE_CONTAINER__LOCATION:
			return getLocation();
		case ModelPackage.NODE_CONTAINER__WIDTH:
			return new Integer(getWidth());
		case ModelPackage.NODE_CONTAINER__HEIGHT:
			return new Integer(getHeight());
		case ModelPackage.NODE_CONTAINER__INCOMING_CONNECTIONS:
			return getIncomingConnections();
		case ModelPackage.NODE_CONTAINER__OUTGOING_CONNECTIONS:
			return getOutgoingConnections();
		case ModelPackage.NODE_CONTAINER__READ_ONLY:
			return isReadOnly() ? Boolean.TRUE : Boolean.FALSE;
		case ModelPackage.NODE_CONTAINER__NODES:
			return getNodes();
		}
		return eDynamicGet(eFeature, resolve);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	public void eSet(EStructuralFeature eFeature, Object newValue) {
		switch (eDerivedStructuralFeatureID(eFeature)) {
		case ModelPackage.NODE_CONTAINER__OBJECT:
			setObject((Object) newValue);
			return;
		case ModelPackage.NODE_CONTAINER__LOCATION:
			setLocation((Point) newValue);
			return;
		case ModelPackage.NODE_CONTAINER__WIDTH:
			setWidth(((Integer) newValue).intValue());
			return;
		case ModelPackage.NODE_CONTAINER__HEIGHT:
			setHeight(((Integer) newValue).intValue());
			return;
		case ModelPackage.NODE_CONTAINER__INCOMING_CONNECTIONS:
			getIncomingConnections().clear();
			getIncomingConnections().addAll((Collection) newValue);
			return;
		case ModelPackage.NODE_CONTAINER__OUTGOING_CONNECTIONS:
			getOutgoingConnections().clear();
			getOutgoingConnections().addAll((Collection) newValue);
			return;
		case ModelPackage.NODE_CONTAINER__READ_ONLY:
			setReadOnly(((Boolean) newValue).booleanValue());
			return;
		case ModelPackage.NODE_CONTAINER__NODES:
			getNodes().clear();
			getNodes().addAll((Collection) newValue);
			return;
		}
		eDynamicSet(eFeature, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	public void eUnset(EStructuralFeature eFeature) {
		switch (eDerivedStructuralFeatureID(eFeature)) {
		case ModelPackage.NODE_CONTAINER__OBJECT:
			setObject(OBJECT_EDEFAULT);
			return;
		case ModelPackage.NODE_CONTAINER__LOCATION:
			setLocation(LOCATION_EDEFAULT);
			return;
		case ModelPackage.NODE_CONTAINER__WIDTH:
			setWidth(WIDTH_EDEFAULT);
			return;
		case ModelPackage.NODE_CONTAINER__HEIGHT:
			setHeight(HEIGHT_EDEFAULT);
			return;
		case ModelPackage.NODE_CONTAINER__INCOMING_CONNECTIONS:
			getIncomingConnections().clear();
			return;
		case ModelPackage.NODE_CONTAINER__OUTGOING_CONNECTIONS:
			getOutgoingConnections().clear();
			return;
		case ModelPackage.NODE_CONTAINER__READ_ONLY:
			setReadOnly(READ_ONLY_EDEFAULT);
			return;
		case ModelPackage.NODE_CONTAINER__NODES:
			getNodes().clear();
			return;
		}
		eDynamicUnset(eFeature);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	public boolean eIsSet(EStructuralFeature eFeature) {
		switch (eDerivedStructuralFeatureID(eFeature)) {
		case ModelPackage.NODE_CONTAINER__OBJECT:
			return OBJECT_EDEFAULT == null ? object != null : !OBJECT_EDEFAULT
					.equals(object);
		case ModelPackage.NODE_CONTAINER__LOCATION:
			return LOCATION_EDEFAULT == null ? location != null
					: !LOCATION_EDEFAULT.equals(location);
		case ModelPackage.NODE_CONTAINER__WIDTH:
			return width != WIDTH_EDEFAULT;
		case ModelPackage.NODE_CONTAINER__HEIGHT:
			return height != HEIGHT_EDEFAULT;
		case ModelPackage.NODE_CONTAINER__INCOMING_CONNECTIONS:
			return incomingConnections != null
					&& !incomingConnections.isEmpty();
		case ModelPackage.NODE_CONTAINER__OUTGOING_CONNECTIONS:
			return outgoingConnections != null
					&& !outgoingConnections.isEmpty();
		case ModelPackage.NODE_CONTAINER__READ_ONLY:
			return readOnly != READ_ONLY_EDEFAULT;
		case ModelPackage.NODE_CONTAINER__NODES:
			return nodes != null && !nodes.isEmpty();
		}
		return eDynamicIsSet(eFeature);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.NodeImpl#setReadOnly(boolean)
	 */
	public void setReadOnly(boolean newReadOnly) {
		super.setReadOnly(newReadOnly);
		if (newReadOnly) {
			for (Iterator iter = getNodes().iterator(); iter.hasNext();) {
				Node child = (Node) iter.next();
				child.setReadOnly(newReadOnly);
			}
		}
	}

	/**
	 * @param removedNodes
	 */
	protected void pushBackToDiagram(Collection removedNodes) {
		ActivityDetailDiagramImpl diagram = (ActivityDetailDiagramImpl) getDiagram();
		Collection breakdownElements = diagram.getAllBreakdownElements();
		for (Iterator iter = removedNodes.iterator(); iter.hasNext();) {
			Node node = (Node) iter.next();
			if (!breakdownElements.contains(node.getObject())) {
				iter.remove();
			}
		}
		// for (Iterator iter = diagram.getNodes().iterator(); iter.hasNext();)
		// {
		// Object node = iter.next();
		// if(node instanceof RoleTaskComposite){
		// List list = ((RoleTaskComposite)node).getNodes();
		// boolean destroy = true;
		// for(Iterator iterator = list.iterator(); iterator.hasNext();){
		// Object obj = iterator.next();
		// if(obj instanceof TaskNode) destroy = false;
		// }
		// if(destroy) iter.remove();
		// }
		// }
		if (!removedNodes.isEmpty()) {
			diagram.getNodes().addAll(removedNodes);
		}
	}
} // NodeContainerImpl
