/*
 * (c) 1998-2000 The Brookings Institution, All Rights Reserved
 *
 * Permission to use this software and its documentation for non-commercial
 * purposes and without fee is hereby granted, provided this copyright statement
 * is included. Please contact us for permission for redistribution and other uses.
 * 
 * BROOKINGS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, 
 * OR NON-INFRINGEMENT. BROOKINGS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
 * LICENSEE AS A RESULT OF USING THIS SOFTWARE OR ITS DERIVATIVES.
 *
 * _Sugarscape_
 * See _Growing Artificial Societies: Social Science from the Ground Up_
 * Brookings Institution Press, The MIT Press
 * Joshua Epstein
 * jepstein@brook.edu
 * Robert Axtell
 * raxtell@brook.edu
 *
 * Miles Parker
 * mparker@brook.edu

 * http://www.brook.edu/es/dynamics/models/ascape
 * The Brookings Institution
 * Washington, D.C.
 */

package edu.brook.sugarscape;

import java.lang.*;
import java.awt.*;
import java.applet.*;

import edu.brook.ascape.model.*;
import edu.brook.ascape.rule.*;
import edu.brook.ascape.view.*;
import edu.brook.ascape.util.*;

public class GAS_Base extends ScapeVector {

    //Parameters
    protected int minVision = 1;
    protected int maxVision = 6;
    protected int minSugarMetabolism = 1;
    protected int maxSugarMetabolism = 4;
    protected int minInitialSugar = 0;
    protected int maxInitialSugar = 30;
    protected int minDeathAge = 60;
    protected int maxDeathAge = 100;
    protected float sugarMoundness = .004f;

    protected ScapeGraph sugarscape;
    
    protected ScapeVector agents;
    
    protected Overhead2DView sugarView;
	
    /**
     * Returns the topology parameter for sugar peaks
     */
    public float getSugarMoundness() {
	    return sugarMoundness;
    }

    /**
     * Sets the topology parameter for sugar peaks
     */
    public void setSugarMoundness (float moundness) {
        sugarMoundness = moundness;
    }

    /**
     * Returns the minimum vision that an agent may be given on initialization.
     * Model parameter.
     */
    public int getMinVision() {
        return minVision;
    }
    
    /**
     * Sets the minimum vision that an agent may be given on initialization.
     * Model parameter.
     */
    public void setMinVision(int _minVision) {
        minVision = _minVision;
    }
    
    /**
     * Returns the maximum vision that an agent may be given on initialization.
     * Model parameter.
     */
    public int getMaxVision() {
        return maxVision;
    }
    
    /**
     * Sets the maximum vision that an agent may be given on initialization.
     * Model parameter.
     */
    public void setMaxVision(int _maxVision) {
        maxVision = _maxVision;
    }
    
    /**
     * Returns the minimum sugar metabolism that an agent may be given on initialization.
     * Model parameter.
     */
    public int getMinSugarMetabolism() {
        return minSugarMetabolism;
    }
    
    /**
     * Sets the minimum sugar metabolism that an agent may be given on initialization.
     * Model parameter.
     */
    public void setMinSugarMetabolism(int _minMetabolism) {
        minSugarMetabolism = _minMetabolism;
    }
    
    /**
     * Returns the maximum sugar metabolism that an agent may be given on initialization.
     * Model parameter.
     */
    public int getMaxSugarMetabolism() {
        return maxSugarMetabolism;
    }
    
    /**
     * Sets the maximum Sugar metabolism that an agent may be given on initialization.
     * Model parameter.
     */
    public void setMaxSugarMetabolism(int _maxMetabolism) {
        maxSugarMetabolism = _maxMetabolism;
    }
    
    /**
     * Returns the minimum age that an agent may be given on initialization.
     * Model parameter.
     */
    public int getMinDeathAge() {
        return minDeathAge;
    }
    
    /**
     * Sets the minimum age that an agent may be given on initialization.
     * Model parameter.
     */
    public void setMinDeathAge(int _minDeathAge) {
        minDeathAge = _minDeathAge;
    }
    
    /**
     * Returns the maximum age that an agent may be given on initialization.
     * Model parameter.
     */
    public int getMaxDeathAge() {
        return maxDeathAge;
    }
    
    /**
     * Sets the maximum age that an agent may be given on initialization.
     * Model parameter.
     */
    public void setMaxDeathAge(int _maxDeathAge) {
        maxDeathAge = _maxDeathAge;
    }
    
    /**
     * Returns the minimum sugar that an agent may be given on initialization.
     * Model parameter.
     */
    public int getMinInitialSugar() {
        return minInitialSugar;
    }
    
    /**
     * Sets the minimum sugar that an agent may be given on initialization.
     * Model parameter.
     */
    public void setMinInitialSugar(int _minInitialSugar) {
        minInitialSugar = _minInitialSugar;
    }
    
    /**
     * Returns the maximum sugar that an agent may be given on initialization.
     * Model parameter.
     */
    public int getMaxInitialSugar() {
        return maxInitialSugar;
    }
    
    /**
     * Sets the maximum sugar that an agent may be given on initialization.
     * Model parameter.
     */
    public void setMaxInitialSugar(int _maxInitialSugar) {
        maxInitialSugar = _maxInitialSugar;
    }
    
    public void createScape() {
        setName("Sugarscape Model");
        setPrototypeAgent(new ScapeVector());
	    sugarscape = new ScapeArray2DVonNeumann();
	    sugarscape.setName("Sugar Cells");
	    sugarscape.setPrototypeAgent(new SugarCell());
	    sugarscape.setExtent(new Coordinate2DDiscrete(50, 50));
        SugarAgent agent = new SugarAgent();
        agent.setHostScape(sugarscape);
	    agents = new ScapeVector();
	    agents.setName("Sugar Agents");
	    agents.setPrototypeAgent(agent);
        sugarscape.setExecutionOrder(Scape.RULE_ORDER);
        sugarscape.setCellsRequestUpdates(true);
        addAgent(sugarscape);
        addAgent(agents);
    }

    public void onSetup () {
	    agents.setExtent(new Coordinate1DDiscrete(400));
    }

    public void createViews() {
        super.createViews();
	    sugarView = new Overhead2DView();
	    final ColorFeatureGradiated colorCellForSugar = new ColorFeatureGradiated("Sugar");
	    colorCellForSugar.setDataPoint(new UnitIntervalDataPoint() {
            public double getValue(Object object) {
                return ((double) (double) ((SugarCell) object).getSugar().getQuantity() / (double) SugarCell.MAX_SUGAR);
            }
	    });
	    colorCellForSugar.setMaximumColor(Color.yellow);
	    sugarView.setCellColorFeature(colorCellForSugar);
	    sugarView.setAgentColorFeature(ColorFeatureFixed.red);
	    sugarView.setCellSize(8);
	    sugarscape.addView(sugarView);
	    if (ViewFrameBridge.isInApplet()) {
	        ViewFrameBridge.getAppletModelPanel().add("Center", sugarView);
	    }
    }
}
