/* WaveDisplay.java */

package distributedwave;

import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Graphics;
import java.awt.Dimension;
import java.awt.image.ImageObserver;
import javax.swing.JComponent;
import java.util.Observable;
import java.util.Observer;

/** Display a wave on the screen
 *
 * @author Russell C. Bjork
 */
public class WaveDisplay extends JComponent implements Observer
{
    /** Constructor
     *
     *  @param wave the object that actually does the wave
     */
    public WaveDisplay(DistributedWave wave)
    {
        wave.addObserver(this);

        // Prepare the images
        
        images = new Image[DistributedWave.NUMBER_OF_STEPS];
        int height = -1;
        for (int i = 0; i < DistributedWave.NUMBER_OF_STEPS; i ++)
        {
            images[i] = Toolkit.getDefaultToolkit().getImage(
                    getClass().getClassLoader().getResource(
                    "images/wave" + i + ".png")).
                    getScaledInstance(PREFERRED_WIDTH, -1, Image.SCALE_DEFAULT);
            height = images[i].getHeight(this);
            while (height < 0)
                synchronized(this)
                {
                    try
                    {
                        wait();
                        height = images[i].getHeight(this);
                    }
                    catch(InterruptedException e)
                    { }
                }
        }
        currentImage = images[0];
        
        // Set the size.  This assumes all images scale to the same height
        
        setPreferredSize(new Dimension(PREFERRED_WIDTH, height));
    }
    
    /** Override of inherited paint() - paint this component, showing the 
     *  current image
     *
     *  @param graphics the graphics object
     */
    public void paint(Graphics graphics)
    {
        graphics.drawImage(currentImage, 0, 0, this);
    }

    /** Method required by the Observer interface
     *
     *  @param observable the observable that changed
     *  @param arg - the argument - will be an integer representing the
     *         number of the image to draw
     */
    public void update(Observable observable, Object arg)
    {
        currentImage = images[((Integer) arg).intValue()];
        repaint();
    }

    /** Method required by the inherited ImageObserver interface - override of
     *  default
     */
    public boolean imageUpdate(Image img,
                    int infoflags,
                    int x,
                    int y,
                    int width,
                    int height)
    {
        if ((infoflags & ImageObserver.ALLBITS) != 0)
        {
            synchronized(this)
            {
                notify();
                return false;
            }
        }
        else
            return true;
    }

    private Image [] images;
    private Image currentImage;
    
    private static final int PREFERRED_WIDTH = 800;
}
