// TrafficLight
// burton rosenberg
// July 8, 1997

import java.awt.* ;
import java.applet.* ;

public class TrafficLight 
extends Applet 
implements Runnable, TrafficLightState  {

    Button goButton = new Button("Go") ;
    TrafficLightCanvas tlc ;
    Thread tlcThread ;

    public void init() {
        
        setLayout(new BorderLayout()) ;
        Panel buttonPanel = new Panel() ;
        add( "North", buttonPanel ) ;
        goButton.setFont( new Font( "TimesRoman", Font.PLAIN, 20 ) ) ;
        buttonPanel.add(goButton) ;
        tlc = new TrafficLightCanvas() ;
        add( "Center", tlc ) ;
        validate() ;

    }

    public boolean action( Event e, Object o ) {
       if ( e.target==goButton ) {
           if ( tlcThread == null ) {
              tlcThread = new Thread(this) ;
              tlcThread.start() ;
           }
           return true ;
       }
       return false ;
    }
 
    public void run() {
       tlc.setState( GREEN ) ;
       tlc.repaint() ;
       try {
          Thread.sleep(3000) ;
       }
       catch ( InterruptedException e ) { }
       tlc.setState( YELLOW ) ;
       tlc.repaint() ;
       try {
          Thread.sleep(3000) ;
       }
       catch ( InterruptedException e ) { }
       tlc.setState( RED ) ;
       tlc.repaint() ;
       tlcThread = null ;
    }

    public String getAppletInfo() {
       return( "Traffic Light, by Burton Rosenberg, 8 July 1997" ) ;
    }
}


class TrafficLightCanvas 
extends Canvas 
implements TrafficLightState {

    int state = RED ;

    void setState ( int state ) { 
       // System.out.println("TrafficLightCanvas.setState: " + state ) ;
       this.state = state ; 
    }

    final static int WIDTH = 50 ;
    final static int HEIGHT = 3*WIDTH ;
    final static int INSET = 5 ;

    public void paint( Graphics gc ) {
        Dimension d = size() ; // what's the current canvas size?
        // (xo,yo) = upper left corner of traffic light
        int xo = (d.width-WIDTH) / 2 ;
        int yo = (d.height-HEIGHT) / 2 ;

        gc.setColor( Color.black ) ;
        gc.fillRect( xo, yo, WIDTH, HEIGHT ) ;
    
        int w = WIDTH - 2 * INSET ;
        gc.setColor( makeColor( RED ) ) ;
        gc.fillOval( xo+=INSET, yo+=INSET, w, w ) ;
        gc.setColor( makeColor( YELLOW ) ) ;
        gc.fillOval( xo, yo+=WIDTH, w, w ) ;
        gc.setColor( makeColor( GREEN ) ) ;
        gc.fillOval( xo, yo+=WIDTH, w, w ) ;
    }

    private Color makeColor( int colorIndex ) {
        Color c ;
        switch ( colorIndex ) {
        case RED: 
            c = Color.red ; 
            break ;
        case YELLOW: 
            c = Color.yellow ; 
            break ;
        case GREEN: 
            c = Color.green ; 
            break ;
        default:
            c = Color.black ;
        }
        if ( colorIndex == state ) 
            return c.brighter().brighter().brighter() ;
        else
            return c.darker().darker().darker() ;
    } 
}

interface TrafficLightState {

    int RED = 0 ;
    int YELLOW = 1 ;
    int GREEN = 2 ;

}
