import java.awt.image.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class VolatileImageTest3 extends JApplet implements Runnable {

    private MediaTracker tracker;

    private Image image;
    private int width;
    private int height;
    private boolean volatileFlag = true;

    private java.util.List sprites;
    private static final int SPRITE_NUMBER = 8;
    private static final String SPRITE_FILENAME = "javacup";
    private static final String SPRITE_FILESUFFIX = "gif";
    private int x;

    private volatile int index;
    private volatile double time = 0.0;

    Thread thread;

    public void init(){
        tracker = new MediaTracker(this);

        sprites = new java.util.ArrayList(8);
        for(int i = 0 ; i < SPRITE_NUMBER ; i++){
            Image tempImage = getImage(getDocumentBase(), SPRITE_FILENAME + i + "." + SPRITE_FILESUFFIX);
            sprites.add(tempImage);
            tracker.addImage(tempImage, 0);
        }

        String volatileParameter = getParameter("Volatile");
        if(volatileParameter.equalsIgnoreCase("TRUE")){
            volatileFlag = true;
        }else{
            volatileFlag = false;
        }
    }

    public void start(){
        thread = new Thread(this);
        thread.start();
    }

    public void stop(){
        thread = null;
    }

    private void initVolatileImage(){
        if (image == null || width != getWidth() || height != getHeight()) {
            width = getWidth();
            height = getHeight();
            if(volatileFlag){
                image = createVolatileImage(width, height);
            }else{
                image = createImage(width, height);
            }
        }
    }

    private void validateVolatileImage() {
        GraphicsConfiguration gc = this.getGraphicsConfiguration();

        if (volatileFlag && ((VolatileImage)image).validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE) {
            image = createVolatileImage(width, height);
        }
    }

    private void move(){
        x += 10;
        if(x > width){
            x = - ((Image)sprites.get(0)).getWidth(this);
        }
    }

    public void paint(Graphics g){
        initVolatileImage();
        if(tracker.statusAll(false) != MediaTracker.COMPLETE){
            return;
        }

        try{
            do {
                validateVolatileImage();
                Graphics gImage = image.getGraphics();
                gImage.setColor(Color.yellow);
                gImage.fillRect(0, 0, width, height);
                gImage.setColor(Color.black);
                gImage.drawString(time + " draw/second", 0, height - 10);
                gImage.drawImage((Image)sprites.get(index), x, 0, this);
                gImage.dispose();
                g.drawImage(image, 0, 0, this);
            } while (volatileFlag && ((VolatileImage)image).contentsLost());
        }catch(NullPointerException ex){}
    }

    public void run(){
        try{
            tracker.waitForID(0);
        }catch(InterruptedException e){
            return;
        }

        Thread currentThread = Thread.currentThread();
        while(currentThread == thread){
            long startTime = System.currentTimeMillis();
            for(int i = 0 ; i < 100 ; i++){
                for(index = 0 ; index < SPRITE_NUMBER ; index++){
                    move();
                    Graphics g = getGraphics();
                    update(g);
                }
            }
            long endTime = System.currentTimeMillis();
            time = (double)SPRITE_NUMBER / (endTime - startTime) * 100000.0;
        }
    }
}
