/*
 * ParamDef.java
 *
 * Jim Frankenberger
 * USDA-ARS, West Lafayette IN
 * jrf@purdue.edu
 *
 * Created on August 25, 2004, 10:03 AM
 */
package ex1;

import java.util.*;

/**
 * This class is a generic parameter class, used for both the crops
 * and operations which holds all information about a parameter except the data value.
 *
 * @author  jrf
 */
public class ParamDef {

    /**
     * Parameter name
     */
    public String actualName;
    /**
     * key name of the parameter used for map in DefnFileParser
     * For UPGM and OPRN files name = actualName+id
     */
    public String name;

    /**
     * String the user sees as a logical name
     */
    public String prompt;

    /**
     * Units that the data is stored in
     */
    public String units;

    /**
     * Units that the user wants to see the data in
     */
    public String altUnits;
    
    /**
     * Type of the parameter: 0-float, 1-int/choicelist, 2-string
     */
    private ParamDef.ColumnType type;

    /**
     * Conversion factor to go from Units to AltUnits
     */
    public float factor;

    /**
     * Last add value in conversion process
     */
    public float addEnd;

    /**
     * For a int/choicelist list of options
     */
    public ArrayList<ChoiceParm> choices;
    
    public InputLimits il;
    
    private boolean decomp = false;

    /**
     *  Sets the decomposition flag, which determines whether this parameter
     * is in the crop subset of decomposition.
     */
    public void setDecomp(boolean input)
    {
        decomp = input;
    }
    
    /**
     *   Retrieves the decomposition flag, which determines whether this parameter
     * is in the crop subset of decomposition.
     */
    public boolean getDecomp()
    {
        return decomp;
    }
    
    /**
     * This function converts a base value into an alternate (English) unit representation
     * if the parameter has a factor field and an optional addEnd field. If the 
     * parameter does not have a factor field the original string is returned because
     * no conversion is required.
     *
     *  @param pstr String to convert to the alternate unit representation.
     * @return 
     */
    public String getAltValue(String pstr) {
        if (factor > -99990) {
            // need to apply the factor
            Float val;
            try {
                val = Float.valueOf(pstr);
            } catch (NumberFormatException nfe) {
                return pstr;
            }
            float val2 = val;
            val2 = val2 * factor;
            if (addEnd > -99990) // need to apply an addition after the factor
            {
                val2 += addEnd;
            }
            // return the alternate value
            return Float.toString(val2);
        } else {
            return pstr;  // no factor, just keep same value
        }
    }

    /**
     * This function converts a alternate value to its base value. This would be called if the 
     * user changed a cell while in alternate (English) units so that the value saved is converted 
     * first if the parameter has a factor and/or an addEnd field. The steps are
     * the reverse of those followed in getAltValue().
     *
     * @param pstr String to convert that may be in alternate units. If a parameter does not have an
     *       alternate unit representation setup the orginal string is returned (no conversion necessary).
     * @return the value in base units
     */
    public String getAltRevValue(String pstr) {
        if (factor > -99990) {
            // need to apply the factor
            Float val = Float.valueOf(pstr);
            float val2 = val;
            if (addEnd > -99990) // need to apply a subtraction first
            {
                val2 -= addEnd;
            }
            // return the alternate value
            val2 = val2 / factor;
            return Float.toString(val2);
        } else {
            return pstr;  // no factor, just keep same value
        }
    }

    /**
     * Construct a new ParamDef class
     */
    public ParamDef() {
        //strVals2 = new HashMap();
        //changes = new HashSet();
        factor = -99999;   // indicates no factor present
        addEnd = -99999;   // indicates no addEnd present
        type = ColumnType.FLOAT;
    }

    /**
     *  Set the type of the parameter
     *    @param val 0,1,2,3 for float, int , string, choice list
     */
    public void setType(ColumnType val) {
        type = val;
    }

    /**
     *   Get the type of the parameter.
     *     @return the type of the parameter
     */
    public ParamDef.ColumnType getType()
    {
        return type;
    }

    /**
     *   Get the value assigned to a specific choice list element
     *     @param ch the choice string to find
     *     @return the value of the choice string or -1 if not found
     */
    public int findChoiceVal(String ch) {
        for (ChoiceParm pc : choices) {
            if (pc.choice.equals(ch)) {
                return pc.val;
            }
        }
        return -2;
    }

    /**
     *   Get the choice string associated with a specific value
     *      @param ind value to search for
     *      @return the choice string that has the value
     */
    public String findChoiceString(int ind) {
        for (ChoiceParm pc : choices) {
            if (pc.val == ind) {
                return pc.choice;
            }
        }
        return null;
    }

    /**
     *   Get a very basic default value based on the field type
     *     @return a default string base don type
     */
    public String getPseudoVal() {
        if (type == ColumnType.FLOAT) {
            return "0.0";
        }
        if ((type == ColumnType.INTEGER) || (type == ColumnType.CHOICE)) {
            if (choices.size() > 0) {
                ChoiceParm pc = choices.get(0);
                return Integer.toString(pc.val);
            } else {
                return "0";
            }
        } else {
            return "???";   // string, but we have no idea what value should be
        }
    }
    
    public enum ColumnType
    {
        FLOAT, 
        INTEGER,
        STRING,
        CHOICE
    }
};
