/*
 * Created on Nov 22, 2004
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package jone;
import java.awt.Color;
import java.awt.GraphicsConfiguration;
import java.awt.Rectangle;
import java.applet.Applet;
import java.awt.Graphics;
/**
 * @author brian
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class TestArena implements Runnable {

	
	private static TestArena defaultInstance;
	
	private Arena arena;
	private boolean cont;
	private int numWolves;
	private int numSheep; 
	private int numGrassPatches; 
	private double mutateRate; 
	private double selectedProp; 
	private double mutateFrac; 
	private int epochLength;
	private int numEpoches; 
	private int foodBonus; 
	private int birthCost; 
	private int overConsumptionPenalty;
	private int runSpeed = 50;
	private int displayEvery = 1;
	private Graphics graphics;
	private Thread thread;
	public static TestArena getInstance()
	{
		if(defaultInstance == null)
		{
			defaultInstance = new TestArena();
		}
		return defaultInstance;
	}
	public static void main(String[] args) {
		try 
		{	
			/* this need to be settable during the run */
			
			
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	public void paint(Graphics g)
	{
		
	}
	
	public void init(Graphics g) 
	{ 
		
		String [] args = {"0", "1000", "5",".01",".9",".3","100","1000"};
		 numWolves = Integer.parseInt(args[0]);
		 numSheep = Integer.parseInt(args[1]);
		 numGrassPatches = Integer.parseInt(args[2]);
		 mutateRate = Double.parseDouble(args[3]);
		 selectedProp = Double.parseDouble(args[4]);
		 mutateFrac = Double.parseDouble(args[5]);
		 epochLength = Integer.parseInt(args[6]);
		 numEpoches = Integer.parseInt(args[7]);
		 foodBonus = 10;
		 birthCost = -10;
		 overConsumptionPenalty = -4;
		this.graphics = g;
		this.cont = false;
	}
		
	public void run()
	{
		try {
		Arena arena = Arena.getInstance();
		ArenaPanel ap = ArenaPanel.getInstance();
		FitnessPlotPanel fpp = FitnessPlotPanel.getInstance();
		arena.initializeArena(numWolves,  numSheep, 
		 numGrassPatches,  mutateRate,  selectedProp,
		 epochLength,  birthCost,  overConsumptionPenalty, 
		 foodBonus, mutateFrac);
		
			 for(int epochcount = 1; epochcount <= numEpoches; epochcount++) {
			 	if(Arena.debug) {
					Arena.logger.debug("epoch is: " + epochcount);
				}
			 	for(int i = 0; i < epochLength; i++) {
					
					
					if(epochcount % this.displayEvery == 0 ) {
					arena.draw(this.graphics);
					Thread.sleep(100 - this.runSpeed);	
					ap.clearArea(this.graphics);
					}
					arena.run(1);
					
				} 
				FitnessGraphInfo fitness = arena.evolve();
				//fpp.nextTimeStep(fitness,new Color []{Color.blue, Color.red} , 2);
				
				fpp.nextTimeStepLine(fitness);
			 }
		}
		catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	
	}
	}
    public void start(int nSheep, int nWolves, int nGrass,
    		double mutaterate, double selectedprop,  double mutatefrac, 
			int epochlength, int numepoches, int  foodbonus, int  birthcost, 
			int overconsumptionpenalty, int speed, int percentToDisplay )
    {  
		this.numSheep = nSheep;
		this.numWolves = nWolves;
		this.numGrassPatches = nGrass;
    	this.mutateRate = mutaterate;
    	this.birthCost = birthcost;
    	this.mutateFrac = mutatefrac;
    	this.foodBonus = foodbonus;
		this.epochLength = epochlength;
		this.numEpoches = numepoches;
		this.overConsumptionPenalty = overconsumptionpenalty;
		this.selectedProp = selectedprop;
		this.runSpeed = speed;
		this.displayEvery = Math.max(1,(int) Math.round(100.0/(percentToDisplay)));
		FitnessPlotPanel.getInstance().clearArea(FitnessPlotPanel.getInstance().getGraphics());
		if(thread != null) {
			thread.stop();
		}
		
		thread = new Thread(this);
		thread.start();  
		this.cont = true;
    }
    public void stop(double mutaterate, double selectedprop,  double mutatefrac, 
			int epochlength, int numepoches, int  foodbonus, int  birthcost, 
			int overconsumptionpenalty, int speed, int percentToDisplay) 
    {  
    	this.mutateRate = mutaterate;
    	this.birthCost = birthcost;
    	this.mutateFrac = mutatefrac;
    	this.foodBonus = foodbonus;
		this.epochLength = epochlength;
		this.numEpoches = numepoches;
		this.overConsumptionPenalty = overconsumptionpenalty;
		this.selectedProp = selectedprop;
		this.runSpeed = speed;
		this.displayEvery = Math.max(1,(int) Math.round(100.0/(percentToDisplay)));
		
    	if(thread == null) {
    		return;
    	}
    	if(this.cont == true) {
    		this.cont = false;
    		thread.suspend(); // call destroy
    	}
    	else 
    	{
    		this.cont = true; 
    		thread.resume();
    	}
    }
    
    public void destroy() {  }

	
}
