/* CVS: $Id: LandResource.java,v 1.7 2001/03/18 19:16:33 gvijf Exp $ */

package evolution.lands;

/**
 * A land resource.
 */
abstract public class LandResource {

    /**
     * Create a new land resource with the given value.
     * @param value The value for this land resource.
     * @param min The minimal value this resource can be at.
     * @param max The maximum value this resource can be at.
     * @param visible Is this land resource visible?
     * @param determination How should the value of this resource be
     * presented to the player. One of "boolean", "numeric".
     */
    public LandResource(double value, double min, double max, boolean visible, String determination) {
        setBounds(min, max);
        setValue(value);
        setVisible(visible);
        setDetermination(determination);
    }

    /**
     * Is this land resource visible?
     */
    public boolean isVisible() {
        return visible;
    }

    /**
     * Set the visibility of this land resource.
     */
    public void setVisible(boolean visible) {
        this.visible = visible;
    }

    /**
     * How should the value of this resource be presented to the player.
     * @returns One of "boolean", "numeric".
     */
    public String getDetermination() {
        return determination;
    }

    /**
     * Set how the value of this resource should be presented to the player.
     * @param determination One of "boolean", "numeric".
     */
    protected void setDetermination(String determination) {
        if(determination.equals("numeric") || determination.equals("boolean"))
	        this.determination = determination;
        else
            throw new IllegalArgumentException("The type of land determination must be one of 'numeric', 'boolean'");
    }

    /**
     * The value of this land resource.
     */
    public double getValue() {
        return value;
    }

    /**
     * Set the bounds for this landresource.
     */
    protected void setBounds(double min, double max) {
        if(max < min)
            throw new RuntimeException("The minimum for a landresource must be less then the maximum");
        this.min = min;
        this.max = max;
    }

    /**
     * Set the value of this land resource.
     */
    protected void setValue(double value) {
        if(value < min) value = min;
        if(value > max) value = max;
        this.value = value;
    }

    /**
     * Get the visible value of this land resource.
     */
    public String getVisibleValueAsString() {
        if(isVisible()) {
            if(getDetermination().equals("boolean"))
                return (getValue() > 0) ? "yes" : "no";
            return getValue() + "";
        }
        return "Unknown";
    }

    /**
     * Get the visible value of this land resource.
     * If the value is 'Unknown', 0 is returned.
     */
    public double getVisibleValue() {
        return Double.parseDouble(getVisibleValueAsString());
    }

    /**
     * Extract the given amount from this land resource.
     * @exception NotEnoughLandResourcesException If the amount extracted is
	 * greater than the available amount.
     */
    public double extract(double amount) {
        if(amount > value) amount = value;
        setValue(getValue() - amount);
        return amount;
    }

    /**
     * Check whether the value of the landresources is still within the bounds.
     */
    public boolean isBoundary() {
        return (getValue() <= min) || (getValue() >= max);
    }

    /**
     * Get the state of this land resource.
     */
    public String getState() {
        return getVisibleValueAsString();
    }

    /**
     * Get the name of this land resource.
     */
    public String getName() {
        return LandKnowledgeCatalog.getInst().stripPathFromClassName(this);
    }

    /**
     * The value of this landresource.
     */
    private double value;
    
    /**
     * The minimum bound of this landresource.
     */
    private double min;
    
    /**
     * The maximum bound of this landresource.
     */
    private double max;

    /**
     * A boolean that indicates whether this resource is visible or not.
     */
    private boolean visible = true;

    /**
     * A string that indicates whether the value of this resource is shown 
     * as an exact amount (="numeric"), or whether only is indication if there 
     * are landresources or not ("boolean") .
     */
    private String determination = "numeric";

}