/*
 *  This program sets up a race between four threads, each trying to fill a
 *  line on the screen with its color before the other threads manage to do
 *  so.  
 *
 *  Copyright (c) 2000, 2002, 2003, 2005, 2010 - Russell C. Bjork
 */
 
import java.awt.*;
import javax.swing.*;

class Racer extends JPanel implements Runnable
{
    /** Main program - create four racers, place them in a frame,
     *  set up a thread for each, and then start each thread.
     */ 
    public static void main(String [] args) throws InterruptedException
    {
        // Create the frame for displaying the racers
        
        JFrame frame = new JFrame("Racers");
        frame.getContentPane().setLayout(new GridLayout(0, 1));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        // Create the racers, add them to the frame
        
        Racer [] racer = new Racer[RACER_COUNT];
        for (int i = 0; i < RACER_COUNT; i ++)
        {
            racer[i] = new Racer(RACER_COLOR[i]);
            frame.getContentPane().add(racer[i]);
        }
        
        frame.setSize(WIDTH, RACER_COUNT * HEIGHT);
        frame.show();
        
        // Create the threads for the racers
        
        Thread [] racerThread = new Thread[RACER_COUNT];
        for (int i = 0; i < RACER_COUNT; i ++)
            racerThread[i] = new Thread(racer[i]);
            
        // Start the racers
        
        for (int i = 0; i < RACER_COUNT; i ++)
            racerThread[i].start();

        // Wait for all the racers to finish, then report done
        
        for (int i = 0; i < RACER_COUNT; i ++)
            racerThread[i].join();
            
        System.out.println("All racers are done");
    }

    /** Constructor for object representing a single racer
     *
     *  @param color the color for this racer
     */
    private Racer(Color color)
    {
        super();
        this.color = color;
        position = 0;
    }
    
    /** Draw this racer 
     */
    public void paint(Graphics g)
    {
        g.setColor(color);
        g.fillRect(0, 0, getSize().width * position / 100, getSize().height);
    }
    
    /** run() method required by Runnable interface.  This code is executed
     *  by the thread associated with this racer 
     */
    public void run()
    {
        while (position < 100)
        {
            // Kill some time
            
            try
            { 
                Thread.sleep((int) (200 * Math.random()));
            }
            catch(InterruptedException e)
            { }
            
            position ++;
            repaint();
        }
    }   

    // Instance variables for a racer object
    
    private Color color;
    private int position;
    
    // Constants to control appearance and number and color of racers
    
    private static final int WIDTH = 300;
    private static final int HEIGHT = 50;
    private static final int RACER_COUNT = 4;
    private static final Color [] RACER_COLOR = 
        { Color.red, Color.green, Color.yellow, Color.blue };
}
    
