/**
 * <copyright>
 * </copyright>
 *
 * $Id$
 */
package org.eclipse.stem.diseasemodels.standard.impl;

import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EDataTypeEList;
import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;
import org.eclipse.osgi.util.NLS;
import org.eclipse.stem.core.graph.Graph;
import org.eclipse.stem.core.graph.Node;
import org.eclipse.stem.core.graph.NodeLabel;
import org.eclipse.stem.core.model.Decorator;
import org.eclipse.stem.core.model.STEMTime;
import org.eclipse.stem.core.model.impl.NodeDecoratorImpl;
import org.eclipse.stem.core.scenario.ScenarioInitializationException;
import org.eclipse.stem.definitions.LocationUtility;
import org.eclipse.stem.definitions.nodes.impl.RegionImpl;
import org.eclipse.stem.diseasemodels.Activator;
import org.eclipse.stem.diseasemodels.standard.DiseaseModel;
import org.eclipse.stem.diseasemodels.standard.DiseaseModelLabel;
import org.eclipse.stem.diseasemodels.standard.DiseaseModelLabelValue;
import org.eclipse.stem.diseasemodels.standard.Initializer;
import org.eclipse.stem.diseasemodels.standard.StandardDiseaseModel;
import org.eclipse.stem.diseasemodels.standard.StandardPackage;

/**
 * <!-- begin-user-doc --> An implementation of the model object '
 * <em><b>Initializer</b></em>'. <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.stem.diseasemodels.standard.impl.InitializerImpl#getDiseaseName <em>Disease Name</em>}</li>
 *   <li>{@link org.eclipse.stem.diseasemodels.standard.impl.InitializerImpl#getTargetISOKey <em>Target ISO Key</em>}</li>
 *   <li>{@link org.eclipse.stem.diseasemodels.standard.impl.InitializerImpl#getTargetURI <em>Target URI</em>}</li>
 *   <li>{@link org.eclipse.stem.diseasemodels.standard.impl.InitializerImpl#getPopulationIdentifier <em>Population Identifier</em>}</li>
 *   <li>{@link org.eclipse.stem.diseasemodels.standard.impl.InitializerImpl#getCompartments <em>Compartments</em>}</li>
 *   <li>{@link org.eclipse.stem.diseasemodels.standard.impl.InitializerImpl#getCompartmentValues <em>Compartment Values</em>}</li>
 *   <li>{@link org.eclipse.stem.diseasemodels.standard.impl.InitializerImpl#isUseFractions <em>Use Fractions</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class InitializerImpl extends NodeDecoratorImpl implements Initializer {

	/**
	 * All {@link DiseaseModelLabel}s that are initialized by this
	 * {@link Initializer}.
	 */
	private EList<DiseaseModelLabel> labelsToInitialize;

	/**
	 * The default value of the '{@link #getDiseaseName() <em>Disease Name</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getDiseaseName()
	 * @generated
	 * @ordered
	 */
	protected static final String DISEASE_NAME_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getDiseaseName() <em>Disease Name</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getDiseaseName()
	 * @generated
	 * @ordered
	 */
	protected String diseaseName = DISEASE_NAME_EDEFAULT;

	/**
	 * The default value of the '{@link #getTargetISOKey() <em>Target ISO Key</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getTargetISOKey()
	 * @generated
	 * @ordered
	 */
	protected static final String TARGET_ISO_KEY_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getTargetISOKey() <em>Target ISO Key</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getTargetISOKey()
	 * @generated
	 * @ordered
	 */
	protected String targetISOKey = TARGET_ISO_KEY_EDEFAULT;

	/**
	 * The default value of the '{@link #getTargetURI() <em>Target URI</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getTargetURI()
	 * @generated
	 * @ordered
	 */
	protected static final URI TARGET_URI_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getTargetURI() <em>Target URI</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getTargetURI()
	 * @generated
	 * @ordered
	 */
	protected URI targetURI = TARGET_URI_EDEFAULT;

	/**
	 * The default value of the '{@link #getPopulationIdentifier() <em>Population Identifier</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getPopulationIdentifier()
	 * @generated
	 * @ordered
	 */
	protected static final String POPULATION_IDENTIFIER_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getPopulationIdentifier() <em>Population Identifier</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getPopulationIdentifier()
	 * @generated
	 * @ordered
	 */
	protected String populationIdentifier = POPULATION_IDENTIFIER_EDEFAULT;

	/**
	 * The cached value of the '{@link #getCompartments() <em>Compartments</em>}' attribute list.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getCompartments()
	 * @generated
	 * @ordered
	 */
	protected EList<String> compartments;

	/**
	 * The cached value of the '{@link #getCompartmentValues() <em>Compartment Values</em>}' attribute list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCompartmentValues()
	 * @generated
	 * @ordered
	 */
	protected EList<Double> compartmentValues;

	/**
	 * The default value of the '{@link #isUseFractions() <em>Use Fractions</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #isUseFractions()
	 * @generated
	 * @ordered
	 */
	protected static final boolean USE_FRACTIONS_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isUseFractions() <em>Use Fractions</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #isUseFractions()
	 * @generated
	 * @ordered
	 */
	protected boolean useFractions = USE_FRACTIONS_EDEFAULT;

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	protected InitializerImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return StandardPackage.Literals.INITIALIZER;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public String getDiseaseName() {
		return diseaseName;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setDiseaseName(String newDiseaseName) {
		String oldDiseaseName = diseaseName;
		diseaseName = newDiseaseName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StandardPackage.INITIALIZER__DISEASE_NAME, oldDiseaseName, diseaseName));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public String getTargetISOKey() {
		return targetISOKey;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setTargetISOKey(String newTargetISOKey) {
		String oldTargetISOKey = targetISOKey;
		targetISOKey = newTargetISOKey;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StandardPackage.INITIALIZER__TARGET_ISO_KEY, oldTargetISOKey, targetISOKey));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public URI getTargetURI() {
		return targetURI;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setTargetURI(URI newTargetURI) {
		URI oldTargetURI = targetURI;
		targetURI = newTargetURI;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StandardPackage.INITIALIZER__TARGET_URI, oldTargetURI, targetURI));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public String getPopulationIdentifier() {
		return populationIdentifier;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setPopulationIdentifier(String newPopulationIdentifier) {
		String oldPopulationIdentifier = populationIdentifier;
		populationIdentifier = newPopulationIdentifier;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StandardPackage.INITIALIZER__POPULATION_IDENTIFIER, oldPopulationIdentifier, populationIdentifier));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public EList<String> getCompartments() {
		if (compartments == null) {
			compartments = new EDataTypeUniqueEList<String>(String.class, this, StandardPackage.INITIALIZER__COMPARTMENTS);
		}
		return compartments;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public EList<Double> getCompartmentValues() {
		if (compartmentValues == null) {
			compartmentValues = new EDataTypeEList<Double>(Double.class, this, StandardPackage.INITIALIZER__COMPARTMENT_VALUES);
		}
		return compartmentValues;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isUseFractions() {
		return useFractions;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setUseFractions(boolean newUseFractions) {
		boolean oldUseFractions = useFractions;
		useFractions = newUseFractions;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StandardPackage.INITIALIZER__USE_FRACTIONS, oldUseFractions, useFractions));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case StandardPackage.INITIALIZER__DISEASE_NAME:
				return getDiseaseName();
			case StandardPackage.INITIALIZER__TARGET_ISO_KEY:
				return getTargetISOKey();
			case StandardPackage.INITIALIZER__TARGET_URI:
				return getTargetURI();
			case StandardPackage.INITIALIZER__POPULATION_IDENTIFIER:
				return getPopulationIdentifier();
			case StandardPackage.INITIALIZER__COMPARTMENTS:
				return getCompartments();
			case StandardPackage.INITIALIZER__COMPARTMENT_VALUES:
				return getCompartmentValues();
			case StandardPackage.INITIALIZER__USE_FRACTIONS:
				return isUseFractions();
		}
		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 StandardPackage.INITIALIZER__DISEASE_NAME:
				setDiseaseName((String)newValue);
				return;
			case StandardPackage.INITIALIZER__TARGET_ISO_KEY:
				setTargetISOKey((String)newValue);
				return;
			case StandardPackage.INITIALIZER__TARGET_URI:
				setTargetURI((URI)newValue);
				return;
			case StandardPackage.INITIALIZER__POPULATION_IDENTIFIER:
				setPopulationIdentifier((String)newValue);
				return;
			case StandardPackage.INITIALIZER__COMPARTMENTS:
				getCompartments().clear();
				getCompartments().addAll((Collection<? extends String>)newValue);
				return;
			case StandardPackage.INITIALIZER__COMPARTMENT_VALUES:
				getCompartmentValues().clear();
				getCompartmentValues().addAll((Collection<? extends Double>)newValue);
				return;
			case StandardPackage.INITIALIZER__USE_FRACTIONS:
				setUseFractions((Boolean)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case StandardPackage.INITIALIZER__DISEASE_NAME:
				setDiseaseName(DISEASE_NAME_EDEFAULT);
				return;
			case StandardPackage.INITIALIZER__TARGET_ISO_KEY:
				setTargetISOKey(TARGET_ISO_KEY_EDEFAULT);
				return;
			case StandardPackage.INITIALIZER__TARGET_URI:
				setTargetURI(TARGET_URI_EDEFAULT);
				return;
			case StandardPackage.INITIALIZER__POPULATION_IDENTIFIER:
				setPopulationIdentifier(POPULATION_IDENTIFIER_EDEFAULT);
				return;
			case StandardPackage.INITIALIZER__COMPARTMENTS:
				getCompartments().clear();
				return;
			case StandardPackage.INITIALIZER__COMPARTMENT_VALUES:
				getCompartmentValues().clear();
				return;
			case StandardPackage.INITIALIZER__USE_FRACTIONS:
				setUseFractions(USE_FRACTIONS_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case StandardPackage.INITIALIZER__DISEASE_NAME:
				return DISEASE_NAME_EDEFAULT == null ? diseaseName != null : !DISEASE_NAME_EDEFAULT.equals(diseaseName);
			case StandardPackage.INITIALIZER__TARGET_ISO_KEY:
				return TARGET_ISO_KEY_EDEFAULT == null ? targetISOKey != null : !TARGET_ISO_KEY_EDEFAULT.equals(targetISOKey);
			case StandardPackage.INITIALIZER__TARGET_URI:
				return TARGET_URI_EDEFAULT == null ? targetURI != null : !TARGET_URI_EDEFAULT.equals(targetURI);
			case StandardPackage.INITIALIZER__POPULATION_IDENTIFIER:
				return POPULATION_IDENTIFIER_EDEFAULT == null ? populationIdentifier != null : !POPULATION_IDENTIFIER_EDEFAULT.equals(populationIdentifier);
			case StandardPackage.INITIALIZER__COMPARTMENTS:
				return compartments != null && !compartments.isEmpty();
			case StandardPackage.INITIALIZER__COMPARTMENT_VALUES:
				return compartmentValues != null && !compartmentValues.isEmpty();
			case StandardPackage.INITIALIZER__USE_FRACTIONS:
				return useFractions != USE_FRACTIONS_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(" (diseaseName: "); //$NON-NLS-1$
		result.append(diseaseName);
		result.append(", targetISOKey: "); //$NON-NLS-1$
		result.append(targetISOKey);
		result.append(", targetURI: "); //$NON-NLS-1$
		result.append(targetURI);
		result.append(", populationIdentifier: "); //$NON-NLS-1$
		result.append(populationIdentifier);
		result.append(", compartments: "); //$NON-NLS-1$
		result.append(compartments);
		result.append(", compartmentValues: "); //$NON-NLS-1$
		result.append(compartmentValues);
		result.append(", useFractions: "); //$NON-NLS-1$
		result.append(useFractions);
		result.append(')');
		return result.toString();
	}

	@Override
	public void decorateGraph(STEMTime time) throws ScenarioInitializationException  {
		if (isGraphDecorated()) {
			return;
		}

		Graph graph = getGraph();
		DiseaseModel diseaseModel = null;
		labelsToInitialize = new BasicEList<DiseaseModelLabel>();

		// Try to find disease model
		for (Decorator decorator : graph.getDecorators()) {
			if (decorator instanceof StandardDiseaseModel) {
				StandardDiseaseModel model = (StandardDiseaseModel) decorator;

				if (model.getDiseaseName().equals(getDiseaseName())) {
					diseaseModel = model;
					break;
				}
			}
		}

		if (diseaseModel == null) {
			throw new ScenarioInitializationException(NLS.bind(Messages.INITIALIZER_DISEASE_NOT_FOUND, new Object[] {getDiseaseName(), this.getURI().toString()}), this, new Exception());
		}

		URI target = null;

		if (getTargetURI() != null) {
			target = getTargetURI();
		} else {
			target = RegionImpl.createRegionNodeURI(getTargetISOKey());
		}

		Node parent = graph.getNode(target);
		Set<Node> allNodes = LocationUtility.getAllChildren(parent);
		allNodes.add(parent);

		for (Node node : allNodes) {
			if (node == null) {
				throw new ScenarioInitializationException(NLS.bind(Messages.INITIALIZER_NODE_NOT_FOUND, new Object[] {target, this.getURI().toString()}), this, new Exception());
			}

			// Try to find disease label
			for (NodeLabel nodeLabel : node.getLabels()) {
				if (nodeLabel instanceof DiseaseModelLabel) {
					DiseaseModelLabel diseaseModelLabel = (DiseaseModelLabel) nodeLabel;

					if (diseaseModelLabel.getDecorator() == diseaseModel
							&& diseaseModelLabel.getPopulationModelLabel()
									.getPopulationIdentifier()
									.equals(this.getPopulationIdentifier())) {
						doInitialization(diseaseModelLabel);
						labelsToInitialize.add(diseaseModelLabel);
						break;
					}
				}
			}
		}

		setProgress(1.0);
		return;
	}

	@Override
	public void resetLabels() throws ScenarioInitializationException {
		for (DiseaseModelLabel label : labelsToInitialize) {
			doInitialization(label);
		}
	}

	@SuppressWarnings("boxing")
	private void doInitialization(DiseaseModelLabel label) throws ScenarioInitializationException {
		DiseaseModelLabelValue current = (DiseaseModelLabelValue) label
				.getCurrentValue();
		double populationCount = current.getPopulationCount();
		EList<EAttribute> attributes = current.eClass().getEAllAttributes();
		double populationToInitialize = 0.0;

		if (!isUseFractions()) {
			for (double v : getCompartmentValues()) {
				populationToInitialize += v;
			}
		}

		if (populationToInitialize > populationCount) {
			throw new ScenarioInitializationException(NLS.bind(Messages.INITIALIZER_INVALID_POPULATION_COUNT, new Object[] {populationToInitialize, populationCount, this.getURI().toString()}), this, new Exception());
		}

		for (EAttribute attribute : attributes) {
			for (int i = 0; i < getCompartments().size(); i++) {
				if (attribute.getName().equals(getCompartments().get(i))) {
					if (isUseFractions()) {
						current.eSet(attribute, getCompartmentValues().get(i)
								* populationCount);
					} else {
						if (getCompartments().get(i).equals("s")) { //$NON-NLS-1$
							current.eSet(attribute, populationCount
									- populationToInitialize);
						} else {
							current.eSet(attribute,
									getCompartmentValues().get(i));
						}
					}
				}
			}
		}
	}

} // InitializerImpl
