package metab;
import metab.*;
import java.io.*;


/**
 * The <code>Stomach</code> class simulates the Stomach compartment in the
 * Compartmental model.  The stomach's job is two-fold in that it both metabolizes
 * and delays the transport of ethanol through the body.  Gastric Alcohol
 * Dehydrogenase (GADH) is responsible for the metabolism of some of the ethanol present
 * in the stomach.  At the same time, ethanol is exiting the stomach through the
 * pyloric sphincter at a rate determined by the current ethanol concentration
 * in the stomach.  The ethanol being metabolized should be removed from the system
 * by the user, just as in the <code>LeanBodyMass</code> class.  Ethanol exiting
 * through the pyloric sphincter should be transfered to an <code>Intestine</code>
 * class by the user.  Transfer and removal of ethanol and liquid should be handled
 * by the user using the addLiquid and addContents methods of the class.  To implement,
 * the amount of ethanol (g) and the total liquid voluem (L) must be present.  An optional
 * description (label) can also be used to better differentiate the compartment.
 * @author Levi Blackstone, Matthew Woller
 * @version 1.40
 * @see metab.Intestine
 * @see metab.LeanBodyMass
 * @see metab.NMSubject
 */
public class Stomach implements Serializable{

    /**
     * Amount of ethanol (grams).
     */
    private double amount;
    /**
     * Amount of total liquid in the stomach (L).
     */
    private double liquid;
	/**
     * Maximum reaction rate for Gastric Alcohol Dehydrogenase (GADH) in
     * mmol ethanol/min/L mucosa.
     */
    private static final double Vmax = 1.544;// 1.544 orig
    /**
     * Michaelis-Menton constant for GADH (mM).
     */
    private static final double Km = 497.834;// 497.834 orig
    /**
     * Ethanol transport rate constant from stomach to intestine (L/min).
     */
    private static final double ks = 0.083333;
    /**
     * Optional label for compartment.
     */
    private String label;

	/**
	 * Constructor for stomach compartment.
	 * @param amount Amount of ethanol (g).
	 * @param liquid Amount of liquid including beverages and gastric fluid (L).
	 * @see metab.Stomach#Stomach(double , double , String)
	 */
    Stomach(double amount, double liquid) {

        this.amount = amount;
        this.liquid = liquid;

    }

   	/**
	 * Constructor for stomach compartment.
	 * @param amount Amount of ethanol (g).
	 * @param liquid Amount of liquid including beverages and gastric fluid (L).
	 * @param label Optional description for compartment.
	 * @see metab.Stomach#Stomach(double , double)
	 */
    Stomach(double amount, double liquid, String label) {

        this.amount = amount;
        this.liquid = liquid;
        this.label = label;

    }

	/**
	 * Adds ethanol to the intestine compartment (can be a negative value).
	 * @param newContents Amount of ethanol being transfered (g).
	 */
    public void addContents(double newContents) {

        if (amount + newContents < 0.00) {
        	amount = 0.00;
        } else {
			amount += newContents;
		}

    }

	/**
	 * Adds liquid from the beverage(s) and gastric fluid.
	 * @param newLiquid Amount of liquid being transfered (L).
	 */
    public void addLiquid(double newLiquid){

    	if (this.liquid + newLiquid < 0.00) {
    		this.liquid = 0.00;
    	} else {
			this.liquid += newLiquid; // L
		}

    }

	/**
	 * Resets compartment.
	 */
    public void clear() {

        amount = 0.0;

    }

	/**
	 * Computes amount of ethanol metabolized in stomach by GADH.
	 * @return <Code>double</Code> representing amount of metabolized ethanol (mM).
	 */
    public double computeMMMetab() {

        if (liquid <= 0.0){
            return 0;
        } else {
            double concentration = amount/liquid; //g/L
            return (Vmax * concentration)/(Km + concentration); // mM
        }

    }

	/**
	 * Computes amount of ethanol being released into intestine.
	 * @return <Code>double</Code> representing rate of release (g/min).
	 */
    public double computeEthanolRelease() {

        // Emptying rate continues to slow as ethanol decreases, but this
        // prevents the model from running indefinitely.
        if (amount < .6) {
            return .05;
        } else {
            if (liquid <= 0.00) {
                return .25;
            }
            double concentration = amount/liquid; //g/L
            return (ks * concentration); // g/min
        }
	}

	/**
	 * Retrieves amount of ethanol remaining in intestine.
	 * @return <Code>double</Code> representing amount of ethanol (g).
	 */
    public double getContents() {

        return amount;

    }

	/**
	 * Retrieves the optional label.
	 * @return <Code>String</Code> representing label.
	 */
    public String getLabel() {

        return label;

    }

	/**
	 * Retrieves amount of liquid remaining in intestine.
	 * @return <Code>double</Code> representing amount of liquid (L).
	 */
    public double getLiquid() {

    	return liquid;

    }

	/**
	 * Checks to see if any ethanol remains in intestine.
	 * @return <Code>boolean</Code> specifying if intestine is empty.
	 */
    public boolean isEmpty() {

        return (amount <= 0.0);

    }

	/**
	 * Sets optional label.
	 * @param newLabel String representing new label.
	 */
    public void setLabel(String newLabel) {

        label = newLabel;

    }

}