package org.eclipse.stem.diseasemodels.standard.impl;

/*******************************************************************************
 * Copyright (c) 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 API and implementation
 *******************************************************************************/

import java.util.Iterator;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.stem.core.graph.DynamicLabel;
import org.eclipse.stem.core.graph.Edge;
import org.eclipse.stem.core.graph.IntegrationLabel;
import org.eclipse.stem.core.graph.Node;
import org.eclipse.stem.core.graph.NodeLabel;
import org.eclipse.stem.core.graph.SimpleDataExchangeLabelValue;
import org.eclipse.stem.core.model.STEMTime;
import org.eclipse.stem.definitions.edges.MigrationEdgeLabel;
import org.eclipse.stem.definitions.edges.impl.MigrationEdgeLabelImpl;
import org.eclipse.stem.diseasemodels.standard.DiseaseModelLabel;
import org.eclipse.stem.diseasemodels.standard.DiseaseModelLabelValue;
//import org.eclipse.stem.diseasemodels.standard.SEIRLabelValue;
//import org.eclipse.stem.diseasemodels.standard.SILabelValue;
import org.eclipse.stem.diseasemodels.standard.SEIRLabel;
import org.eclipse.stem.diseasemodels.standard.SEIRLabelValue;
import org.eclipse.stem.diseasemodels.standard.SILabelValue;
import org.eclipse.stem.diseasemodels.standard.SIR;
import org.eclipse.stem.diseasemodels.standard.SIRLabel;
import org.eclipse.stem.diseasemodels.standard.SIRLabelValue;
import org.eclipse.stem.diseasemodels.standard.StandardDiseaseModelLabel;
import org.eclipse.stem.diseasemodels.standard.StandardDiseaseModelLabelValue;
import org.eclipse.stem.diseasemodels.standard.StandardFactory;
import org.eclipse.stem.diseasemodels.standard.StandardPackage;

/**
 * <!-- begin-user-doc --> An implementation of the model object '<em><b>SIR</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.stem.diseasemodels.standard.impl.SIRImpl#getImmunityLossRate <em>Immunity Loss Rate</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public abstract class SIRImpl extends SIImpl implements SIR {
	/**
	 * The default value of the '{@link #getImmunityLossRate() <em>Immunity Loss Rate</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getImmunityLossRate()
	 * @generated
	 * @ordered
	 */
	protected static final double IMMUNITY_LOSS_RATE_EDEFAULT = 0.0;

	/**
	 * The cached value of the '{@link #getImmunityLossRate() <em>Immunity Loss Rate</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getImmunityLossRate()
	 * @generated
	 * @ordered
	 */
	protected double immunityLossRate = IMMUNITY_LOSS_RATE_EDEFAULT;

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

	/**
	 * @param sirDiseaseModel
	 *            the SIR disease model to be initialized
	 * @param diseaseModelName
	 * @param backgroundMortalityRate
	 * @param infectiousMortality
	 * @param infectiousMortalityRate
	 *            the rate at which fatally infectious population members die
	 * @param transmissionRate
	 * @param recoveryRate
	 * @param immunityLossRate
	 * @param incubationRate
	 * @param nonLinearityCoefficient
	 * @param timePeriod
	 * @param populationIdentifier
	 */
	protected static SIR initializeSIRDiseaseModel(final SIR sirDiseaseModel,
			final String diseaseModelName,
			final double backgroundMortalityRate,
			final double infectiousMortalityRate,
			final double transmissionRate, final double recoveryRate,
			final double immunityLossRate,
			final double nonLinearityCoefficient, final long timePeriod,
			final String populationIdentifier) {
		SIImpl.initializeSIDiseaseModel(sirDiseaseModel, diseaseModelName,
				backgroundMortalityRate,
				infectiousMortalityRate, transmissionRate, recoveryRate,
				nonLinearityCoefficient, timePeriod, populationIdentifier);
		sirDiseaseModel.setImmunityLossRate(immunityLossRate);
		return sirDiseaseModel;
	} // initializeSIRDiseaseModel

	/**
	 * @see org.eclipse.stem.diseasemodels.standard.impl.DiseaseModelImpl#createDiseaseModelLabel()
	 */
	@Override
	public DiseaseModelLabel createDiseaseModelLabel() {
		return StandardFactory.eINSTANCE.createSIRLabel();
	} // createDiseaseModelLabel
	
	@Override
	public DiseaseModelLabelValue createDiseaseModelLabelValue() {
		return StandardFactory.eINSTANCE.createSIRLabelValue();
	} // createDiseaseModelLabelValue
	

	/**
	 * @see org.eclipse.stem.diseasemodels.standard.impl.SIImpl#computeDeaths(org.eclipse.stem.diseasemodels.standard.StandardDiseaseModelLabelValue,
	 *      long)
	 */
	@Override
	public StandardDiseaseModelLabelValue computeDiseaseDeathsDeltas(
			final STEMTime time, final StandardDiseaseModelLabelValue currentLabelValue, final long timeDelta, DiseaseModelLabelValue returnValue) {


		final SIRLabelValue currentSIR = (SIRLabelValue) currentLabelValue;
		
		final double adjustedInfectiousMortalityRate = getAdjustedInfectiousMortalityRate(timeDelta);
		final double diseaseDeaths = adjustedInfectiousMortalityRate
				* currentSIR.getI();

		SIRLabelValueImpl ret = (SIRLabelValueImpl)returnValue;
		ret.setS(0.0);
		ret.setI(-diseaseDeaths);
		ret.setIncidence(0.0);
		ret.setR(0.0);
		ret.setDiseaseDeaths(diseaseDeaths);
		return ret;
	} // computeDeaths

	/**
	 * @see org.eclipse.stem.diseasemodels.standard.impl.SIImpl#computeTransitions(StandardDiseaseModelLabelValue,
	 *      StandardDiseaseModelLabel, long)
	 */
	@Override
	public StandardDiseaseModelLabelValue computeDiseaseDeltas(
			final STEMTime time, 
			final StandardDiseaseModelLabelValue currentState,
			final StandardDiseaseModelLabel diseaseLabel, final long timeDelta, DiseaseModelLabelValue returnValue) {
		final SIRLabelValue currentSIR = (SIRLabelValue) currentState;
		
		// This is beta*
		double transmissionRate = getAdjustedTransmissionRate(timeDelta);
				
		if(!this.isFrequencyDependent()) transmissionRate *= getTransmissionRateScaleFactor(diseaseLabel);

		// The effective Infectious population  is a dimensionles number normalize by total
		// population used in teh computation of bets*S*i where i = Ieffective/Pop.
		// This includes a correction to the current
		// infectious population (Ieffective) based on the conserved exchange of people (circulation)
		// between regions. Note that this is no the "arrivals" and "departures" which are
		// a different process.
		final double effectiveInfectious = getNormalizedEffectiveInfectious(diseaseLabel.getNode(), diseaseLabel, currentSIR.getI());

		/*
		 * Compute state transitions
		 * 
		 * Regarding computing the number of transitions from Susceptible to Exposed:
		 * In a linear model the "effective" number of infectious people is just
		 * the number of infectious people In a nonlinear model we have a
		 * nonLinearity exponent that is > 1 this models the effect of immune
		 * system saturation when Susceptible people are exposed to large
		 * numbers of infectious people. then the "effective" number of
		 * infectious people is I^nonLinearity exponent to allow for either
		 * linear or nonlinear models we always calculate I^nonLinearity
		 * exponent and allow nonLinearity exponent >= 1.0
		 */
		double numberOfInfectedToRecovered = getAdjustedRecoveryRate(timeDelta)
		* currentSIR.getI();
		double numberOfRecoveredToSusceptible = getAdjustedImmunityLossRate(timeDelta)
		* currentSIR.getR();
		// Need to checked what do do here. If non linear coefficient is not 1 and
		// the effective infectious is negative (which is possible), what do do? 
		// Let's fall back on the linear method for now.
		double numberOfSusceptibleToInfected = 0.0;
		if(getNonLinearityCoefficient() != 1.0 && effectiveInfectious >= 0.0)
			numberOfSusceptibleToInfected = transmissionRate
			* currentSIR.getS()* Math.pow(effectiveInfectious, getNonLinearityCoefficient());
		else
			numberOfSusceptibleToInfected = transmissionRate
			* currentSIR.getS()* effectiveInfectious;
		
		
		// Determine delta S
		final double deltaS = numberOfRecoveredToSusceptible - numberOfSusceptibleToInfected;
			// Determine delta I
		final double deltaI = numberOfSusceptibleToInfected- numberOfInfectedToRecovered;
		// Determine delta R
		final double deltaR = numberOfInfectedToRecovered - numberOfRecoveredToSusceptible;
		
		SIRLabelValueImpl ret = (SIRLabelValueImpl)returnValue;
		ret.setS(deltaS);
		ret.setI(deltaI);
		ret.setIncidence(numberOfInfectedToRecovered);
		ret.setR(deltaR);
		ret.setDiseaseDeaths(0);
		return ret;
		
	} // computeTransitions

	

	/**
	 * @see org.eclipse.stem.diseasemodels.standard.impl.StandardDiseaseModelImpl#getMigrationDeltas(org.eclipse.stem.diseasemodels.standard.StandardDiseaseModelLabel,
	 *      org.eclipse.stem.core.model.STEMTime)
	 */
	@Override
	protected StandardDiseaseModelLabelValue getMigrationDeltas(final StandardDiseaseModelLabel diseaseLabel, final STEMTime time, DiseaseModelLabelValue returnValue) {
		final StandardDiseaseModelLabelValue retValue = (StandardDiseaseModelLabelValue) createDiseaseModelLabelValue();
		
		double deltaS = 0.0;
		double deltaI = 0.0;
		double deltaR = 0.0;

		// DO MIGRATION THROUGH MIGRATION EDGES
	    // to/from THIS node
		Node node = diseaseLabel.getNode();
		for (final Iterator<Edge> migrationEdgeIter = MigrationEdgeLabelImpl.getMigrationEdgesFromNode(node).iterator(); migrationEdgeIter.hasNext();) {
			//every edge is an A=>B Edge. For each node there might be two edges
			//where THIS node can act as type A or type B (origin or destination)
			final Edge migrationEdge = migrationEdgeIter.next();
			MigrationEdgeLabel migrationLabel = (MigrationEdgeLabel) migrationEdge.getLabel();
			double migrationRate = migrationLabel.getCurrentValue().getMigrationRate();
			// get the other node
			final Node otherNode = migrationEdge.getOtherNode(node);
			// do a test to find out if this edge is an incoming or outgoing edge
			// by getting the edges' destination node (which could be THIS node)
			boolean incomming = (migrationEdge.getB().equals(node));
			// is this incoming
			if (incomming) {
				// edge is incoming
				for (final Iterator<NodeLabel> labelIter = otherNode.getLabels().iterator(); labelIter.hasNext();) {
					final NodeLabel nodeLabel = labelIter.next();
					// Is this a disease label?
					if (nodeLabel instanceof StandardDiseaseModelLabel) {
						final SIRLabel otherSIRLabel = (SIRLabel) nodeLabel;
						// Yes
						// Is it updated by this disease model?
						if (this == otherSIRLabel.getDecorator()) {
							deltaS  += migrationRate*otherSIRLabel.getCurrentSIRValue().getS();
							deltaI += migrationRate*otherSIRLabel.getCurrentSIRValue().getI();
							deltaR  += migrationRate*otherSIRLabel.getCurrentSIRValue().getR();
							break;
						} // if
					}
				} // for
			} else {
				// edge is outgoing
				// edge is incoming
				for (final Iterator<NodeLabel> labelIter = node.getLabels().iterator(); labelIter.hasNext();) {
					final NodeLabel nodeLabel = labelIter.next();
					// Is this a disease label?
					if (nodeLabel instanceof StandardDiseaseModelLabel) {
						final SIRLabel thisSIRLabel = (SIRLabel) nodeLabel;
						// Yes
						// Is it updated by this disease model?
						if (this == thisSIRLabel.getDecorator()) {
							deltaS  -= migrationRate*thisSIRLabel.getCurrentSIRValue().getS();
							deltaI -= migrationRate*thisSIRLabel.getCurrentSIRValue().getI();
							deltaR  -= migrationRate*thisSIRLabel.getCurrentSIRValue().getR();
							break;
						} // if
					}
				} // for
			}
		} // for each migration edge

		SIRLabelValueImpl ret = (SIRLabelValueImpl)returnValue;
		ret.setS(deltaS);
		ret.setI(deltaI);
		ret.setIncidence(0);
		ret.setR(deltaR);
		ret.setDiseaseDeaths(0);
		return ret;
	} // getMigrationDeltas

	
	
	
	/**
	 * @param fractionToDepart
	 * @param nextState
	 * @return
	 */
	@Override
	protected StandardDiseaseModelLabelValue computeDepartures(
			final 	double fractionToDepart,final  StandardDiseaseModelLabelValue nextState) {
		final SIRLabelValue departees = StandardFactory.eINSTANCE
				.createSIRLabelValue();
		final SIRLabelValue siState = (SIRLabelValue) nextState;
		departees.setS(fractionToDepart * siState.getS());
		departees.setI(fractionToDepart * siState.getI());
		departees.setR(fractionToDepart * siState.getR());
		return departees;
	} // computeDepartures

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

	/**
	 * <!-- begin-user-doc -->
	 * 
	 * @return
	 * 
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public double getImmunityLossRate() {
		return immunityLossRate;
	}

	/**
	 * <!-- begin-user-doc -->
	 * 
	 * @param newImmunityLossRate
	 * 
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setImmunityLossRate(double newImmunityLossRate) {
		double oldImmunityLossRate = immunityLossRate;
		immunityLossRate = newImmunityLossRate;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StandardPackage.SIR__IMMUNITY_LOSS_RATE, oldImmunityLossRate, immunityLossRate));
	}

	/**
	 * <!-- begin-user-doc -->
	 * 
	 * @param timeDelta
	 * @return
	 * 
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public double getAdjustedImmunityLossRate(long timeDelta) {
		return getImmunityLossRate()
				* ((double) timeDelta / (double) getTimePeriod());
	} // getAdjustedImmunityRate

	
	
	/**
	 * <!-- begin-user-doc -->
	 * 
	 * @param featureID
	 * @param resolve
	 * @param coreType
	 * @return
	 * 
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case StandardPackage.SIR__IMMUNITY_LOSS_RATE:
				return getImmunityLossRate();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * 
	 * @param featureID
	 * @param newValue
	 * 
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case StandardPackage.SIR__IMMUNITY_LOSS_RATE:
				setImmunityLossRate((Double)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * 
	 * @param featureID
	 * 
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case StandardPackage.SIR__IMMUNITY_LOSS_RATE:
				setImmunityLossRate(IMMUNITY_LOSS_RATE_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * 
	 * @param featureID
	 * @return
	 * 
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case StandardPackage.SIR__IMMUNITY_LOSS_RATE:
				return immunityLossRate != IMMUNITY_LOSS_RATE_EDEFAULT;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * 
	 * @return
	 * 
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (immunityLossRate: "); //$NON-NLS-1$
		result.append(immunityLossRate);
		result.append(')');
		return result.toString();
	}

	/**
	 * @see org.eclipse.stem.diseasemodels.standard.impl.SIImpl#sane()
	 */
	@Override
	public boolean sane() {
		boolean retValue = super.sane();

		retValue = retValue && immunityLossRate >= IMMUNITY_LOSS_RATE_EDEFAULT;
		assert retValue;

		retValue = retValue && !Double.isInfinite(immunityLossRate);
		assert retValue;
		
		retValue = retValue && !Double.isNaN(immunityLossRate);
		assert retValue;
		
		return retValue;
	} // sane

} // SIRImpl
