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


/**
 * The <code>LeanBodyMass</code> class simulates the Lean Body Mass compartment
 * in the Compartmental model.  The Lean Body Mass handles the majority of the
 * actual metabolism of ethanol in the human body, mainly through the liver.
 * Once the ethanol has been metabolized, the user should remove it from the system
 * using the addContents method.  No addLiquid method is necessary for this class
 * because the liquid is the aqueous portion of the subject's body.  This Total Body
 * Water is a required argument during class construction.  The TBW must be calculated
 * or measured outside of the class (externally).  Also required during construction
 * is the amount of ethanol (g), the subject's previous drinking history (an integer
 * value consisting of one of the constants defined in <code>NMSubject</code>,
 * and, optionally, a description (label) of the compartment.
 * @author Levi Blackstone, Matthew Woller
 * @version 1.61
 * @see metab.Stomach
 * @see metab.Intestine
 * @see metab.NMSubject
 */
public class LeanBodyMass implements Serializable{

    /**
     * Amount of ethanol (grams).
     */
    private double amount;
    /**
     * Total Body Water (TBW) present in individual.
     */
    private double TBW;
    /**
     * Liver Alcohol Dehydrogenase (LADH) maximum reaction rate (mmol ethanol/min
     * /L Body Water).
     */
    private static final double Vmax = 4.518;// 4.518 orig
    /**
     * Michaelis-Menton constant for LADH (mM).
     */
    private static final double Km = 1.752;// 1.752 orig
    /**
     * Standard representation of the subject's drinking history.
     */
    private int drinkingHistory;
    /**
     * Optional label for compartment.
     */
    private String label;

	/**
	 * Constructor for lean body mass compartment.
	 * @param amount Amount of ethanol (g).
	 * @param TBW Total water in body mass (L).
	 * @param drinkingHistory Previous drinking habits of the subject.
	 * @see metab.LeanBodyMass#LeanBodyMass(double , double , int, String)
	 */
    LeanBodyMass(double amount, double TBW, int drinkingHistory) {

        this.amount = amount;
        this.TBW = TBW;
        this.drinkingHistory = drinkingHistory;

    }

    /**
	 * Constructor for lean body mass compartment.
	 * @param amount Amount of ethanol (g).
	 * @param TBW Total water in body mass (L).
	 * @param drinkingHistory Previous drinking habits of the subject.
	 * @param label Optional description for compartment.
	 * @see metab.LeanBodyMass#LeanBodyMass(double, double, int)
	 */
    LeanBodyMass(double amount, double TBW, int drinkingHistory, String label) {

        this.amount = amount;
        this.TBW = TBW;
        this.drinkingHistory = drinkingHistory;
        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;
		}

    }

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

        amount = 0.0;

    }

	/**
	 * Computes amount of ethanol metabolized in lean body mass by LADH.
	 * @return <Code>double</Code> representing amount of metabolized ethanol (mM).
	 */
    public double computeMMMetab() {

        // Accelerates, retards, or leaves alone the rate of metabolism.
        double concentration = amount/TBW;
        return (((drinkingHistory == NMSubject._LIGHT_DRINKER) ? Vmax * .8 :
                 (drinkingHistory == NMSubject._MODERATE_DRINKER) ? Vmax :
                 (drinkingHistory == NMSubject._HEAVY_DRINKER) ? Vmax * 1.2 : Vmax)
                  * concentration) / (Km + concentration);

    }

	/**
	 * 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;

    }

	/**
	 * 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;

    }

}