package org.lucci.madhoc.simulation;



import java.sql.Date;

import org.lucci.config.TypedConfiguration;

import sun.security.action.GetLongAction;


public class Simulation implements Configurable
{
    // a negative value means that the number of threads will be the number of processors
    // detected on the host machine
    private int numberOfThreads = -1;
    
    // the name of the simulation
    private String name = new Date(System.currentTimeMillis()).toLocaleString();

    // the current iteration of the simulation process
    private int iteration = 0;

    // the number of iteration per second
    private double resolution = 4;

    // the effective frequency of the simulation process
    // this is used to find out the time acceleration
    // until the first iterations, it cannot be defined
    private double iterationFrequency = -1;

    private long startDate;
    

    // the date from which iteration are counted
    long iterationCountStartDate = System.currentTimeMillis();
    
    // the number of iterations counted since iterationCountStartDate 
    int iterationCounter = 0;
    
    private org.lucci.madhoc.simulation.random.RandomNumberGenerator randomNumberGenerator;

    

    
    private TypedConfiguration configuration;
    
    /**
     * @return Returns the logicalIterationFrequency.
     */
    public double getResolution()
    {
        return resolution;
    }

    /**
     * @param step The logicalIterationFrequency to set.
     */
    public void setResolution(double step)
    {
        this.resolution = step;
    }

    /**
     * @return Returns the effectiveIterationFrequency.
     */
    public double getIterationFrequency()
    {
        return iterationFrequency;
    }

    protected void setIterationFrequency(double f)
    {
        this.iterationFrequency = f;
    }
    
    public int getIteration()
    {
        return iteration;
    }
    
    protected void setIteration(int i)
    {
        this.iteration = i;
    }

    public double getSimulatedTime()
    {
        return getIteration() * getResolution();
    }

    public double getAcceleration()
    {
        return iterationFrequency / getResolution();
    }



    public String getName()
    {
        return name;
    }

    public void setName(String string)
    {
        name = string;
    }

    public String toString()
    {
        return getName();
    }


    /* (non-Javadoc)
     * @see org.lucci.madhoc.util.Configurable#configure(org.lucci.madhoc.util.Configuration)
     */
    public void configure() throws Throwable
    {
        setName(getConfiguration().getString("simulation_name"));
        randomNumberGenerator = new org.lucci.madhoc.simulation.random.RandomNumberGenerator();
        randomNumberGenerator.setSimulation(this);
        randomNumberGenerator.configure();
        setResolution(getConfiguration().getDouble("simulation_resolution"));

        this.numberOfThreads = getConfiguration().getInteger("number_of_threads");
    }

    public org.lucci.madhoc.simulation.random.RandomNumberGenerator getRandomNumberGenerator()
    {
        return randomNumberGenerator;
    }

    public TypedConfiguration getConfiguration()
    {
        return configuration;
    }
    public void setConfiguration(TypedConfiguration configuration)
    {
        if (configuration == null)
            throw new IllegalArgumentException("null configuration");

        this.configuration = configuration;
    }

    public long getStartDate()
    {
        return startDate;
    }
    public void setStartDate(long startDate)
    {
        this.startDate = startDate;
    }

    public int getNumberOfThreads()
    {
        if (this.numberOfThreads > 0)
        {
            return this.numberOfThreads;
        }
        else
        {
            return Runtime.getRuntime().availableProcessors();
        }
    }
}