package simulate;

import simulate.units.*;

public abstract class IntegratorMD extends Integrator {
    
    protected double timeStep;
    protected double elapsedTime;
    protected Unit.Time timeStepUnit;
//    protected MeterTemperature thermometer;
    
    public IntegratorMD() {
        setTimeStep(Default.TIME_STEP, Default.TIME_STEP_UNIT);
        intervalEvent = new IntervalEvent();
    }
    
    public double elapsedTime() {return stepCount*timeStep;}
        
    // Time step and its units
    public final void setTimeStep(double t, Unit.Time u) {
        timeStepUnit = u;
        setTimeStep(t);
    }
    public void setTimeStep(double t) {timeStep = timeStepUnit.toSim(t);}
    public final double getTimeStep() {return timeStepUnit.fromSim(timeStep);}
    public final double timeStep() {return timeStep;}
    public final void setTimeStepUnit(Unit.Time u) {timeStepUnit = u;}
    public Unit.Time getTimeStepUnit() {return timeStepUnit;}
    
    public ChronoMeter chronoMeter() {
        ChronoMeter c = new ChronoMeter();
        this.addIntervalListener(c);
        return c;
    }
    
    /**
     * Class for measuring elapsed simulation time
     */
    class ChronoMeter extends Meter {
        
        double t0;
        
        ChronoMeter() {
            super();
            reset();
            setLabel("Elapsed time");
        }
        
        public void reset() {t0 = elapsedTime();}
        public void intervalAction(Integrator.IntervalEvent evt) {}
        public double currentValue() {return elapsedTime() - t0;}
    }
    
    // DisplayBox to present the elapsed time
    public static class Timer extends DisplayBox {
    
        public Timer(ChronoMeter meter) {
            super();
            this.setMeter(meter);
            this.setUnit(Simulation.unitSystem().time());
            this.setPrecision(7);
            setSize(100,60);
        }
    }
}
    