package simulate;
import java.awt.*;
import java.awt.event.*;
import java.util.Observer;
import java.util.Observable;

public abstract class Display extends Panel implements Simulation.GraphicalElement, Integrator.IntervalListener {

    int updateInterval;
    int iieCount;
    protected Phase phase;  //consider eliminating phase and put in subclasses as needed
    
    // Constructor
    public Display () {
	    setUpdateInterval(1);
	    Simulation.register(this);
        Simulation.integratorManager.addObserver(makeIntegratorObserver());
        Simulation.phaseManager.addObserver(makePhaseObserver());
    }
    
    //Override this to have respond in a different way when component is added
    //not good if multiple integrators are involved
    protected Observer makeIntegratorObserver() {    
        return new Observer() {
            public void update(Observable mgr, Object obj) {
                Integrator integrator = (Integrator)obj;
                integrator.addIntervalListener(Display.this);
            }
        };
    }
    //Override this to have respond in a different way when component is added
    protected Observer makePhaseObserver() {    
        return new Observer() {
            public void update(Observable mgr, Object obj) {
                Phase phase = (Phase)obj;
                setPhase(phase);
            }
        };
    }

    public Component graphic(Object obj) {return this;}
    
    /**
     * Method called to update the display.  
     * This method is called after the display receives 
     * an integrationIntervalEvent updateInterval times.
     * After completing this method the Display does a repaint.
     */
    public abstract void doUpdate();
        
    public void intervalAction(Integrator.IntervalEvent evt) {
	    if(--iieCount == 0) {
	        iieCount = updateInterval;
	        doUpdate();
            repaint();
	    }
    }

    public final int getUpdateInterval() {return updateInterval;}
    public final void setUpdateInterval(int i) {
        if(i > 0) {
            updateInterval = i;
            iieCount = updateInterval;
        }
    }
    
    public void setPhase(Phase p) {phase = p;}  //2D needed to manipulate dimensions array directly
    public Phase phase() {return phase;}
    
}
