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

package evolution.actions;

import java.util.*;

import evolution.*;
import evolution.resources.*;
import evolution.lands.*;

/**
 * Investigate a land for coals.
 */
public class GeoInvestigation extends Action {

    /**
     * Checks if tha action "geo-investigation" can be performed by the human on the selected square of land.
     * If not, some exception will be thrown.
     */
    protected void doChecks(Human human) throws NotEnoughResourcesException, IllegalLandTypeException, NotEnoughLandResourcesException {
        if(isRevealed(human.getSquareOfLand())) {
            revealed = new HashMap();
            throw new IllegalLandTypeException("This one's done");
        }
        super.doChecks(human);
    }

    /**
     * Extra things which should be done when this action's perform
     * method is called.
     * Template method.
     */
    protected void _perform(Human human) throws NotEnoughResourcesException, IllegalLandTypeException, NotEnoughLandResourcesException {
        Map m = ActionKnowledgeCatalog.getInst().makeStringDoubleMap("GeoInvestigation.reveals", "");
        Iterator it = m.keySet().iterator();
        while(it.hasNext()) {
            String resourceName = (String) it.next();
            int inc = ((Double) m.get(resourceName)).intValue();
            if(setRevealed(resourceName, getRevealed(resourceName) + inc)) {
                LandResource r = human.getSquareOfLand().getLandResource(resourceName);
                r.setVisible(true);
            }
        }
    }

    /**
     * Checks whether this action can be performed on the given square of land.
     */
    protected boolean canBePerformedOn(SquareOfLand square) {
        return !isRevealed(square) && super.canBePerformedOn(square);
    }

    /**
     * Checks whether this square of land has already revealed 
     * if there are coals under the ground or not.
     */
    protected boolean isRevealed(SquareOfLand square) {
        Map m = square.getLandResources();
        Iterator it = m.keySet().iterator();
        while(it.hasNext()) {
            String resName = (String) it.next();
            LandResource r = square.getLandResource(resName);
            if(ActionKnowledgeCatalog.getInst().makeStringDoubleMap("GeoInvestigation.reveals", "").keySet().contains(resName))
                if(!r.isVisible()) return false;
        }
        return true;
    }

    /**
     * Return the percentage of how much the given resource is revealed
     */
    protected int getRevealed(String resourceName) {
        try {
            return ((Integer) revealed.get(resourceName)).intValue();
        } catch(NullPointerException e) {
            return 0;
        }
    }

    /**
     * Set the percentage of how much the given resource is revealed
     */
    protected boolean setRevealed(String resourceName, int rev) {
        Integer v = new Integer((rev <= 0) ? 0 : ((rev >= 100) ? 100 : rev));
        revealed.put(resourceName, v);
        return v.intValue() == 100;
    }

    /**
     * A map that contains as key the name of a landresource 
     * and as value a percentage of how much that resource is revealed.
     */
    private Map revealed = new HashMap();
}