package com.hatherly.Fireworks;

import java.applet.*;

import java.awt.*;

import java.awt.Graphics;

import java.lang.Thread;

import java.util.ArrayList;


/**
 * Applet to create a fireworks display consisting of
 * rockets with starbursts, rockets with spinning
 * starbursts and glitter rockets.
 * @author     Adam Hatherly
 */
public class Fireworks extends Applet implements Runnable {

	/**
	 * @uml.property  name="particle_set"
	 * @uml.associationEnd  multiplicity="(0 -1)" aggregation="composite" inverse="fireworks:com.hatherly.Fireworks.Particle"
	 * @uml.association  name="creates"
	 */
	private ArrayList particle_set = new ArrayList();
	private RocketLauncher rlaunch = RocketLauncher.getInstance();

	Thread display;
	int delay;
	int repaint_loop = 0;

	Dimension offDimension;
    Image offImage;
    Graphics offGraphics;

    static final long serialVersionUID = 1;

    /**
     * Initialises various variables at start-up
     */
    public void init() {
    	setBackground( Color.black );
    	String str = "260";
    	int fps = (str != null) ? Integer.parseInt(str) : 10;
    	delay = (fps > 0) ? (1000 / fps) : 100;
    }

    /**
     * This method is called when the applet becomes visible on
     * the screen. Create a thread and start it.
     */
    public void start() {
    	display = new Thread(this);
    	display.start();
	}

    public void stop() {
    }

    public void destroy() {
    }

    /**
     * This method draws all the particles on the graphics window
     * @param g Graphics object
     */
    public void paintFrame(Graphics g) {

    	g.setColor( Color.blue );
    	g.drawString( "Created by Adam Hatherly", getSize().height-150, getSize().height-10 );

    	// Draw all the particles

        int n;
        Particle p;

        if (particle_set.size()>0)
        {
        	for (n=0; n<particle_set.size(); n++)
        	{
        		p = (Particle)particle_set.get(n);
      			g.setColor( p.colour );
        		g.fillRect((int)p.x_pos,(int)p.y_pos,2,2);
        	}
        }
    }

    /**
     * Does double-buffering of the graphics to display - this
     * makes the animation smoother
     * @param g Graphics object
     */
    public void update(Graphics g) {
    	Dimension d = getSize();

    	// Create the offscreen graphics context

    	if ((offGraphics == null)
    	 || (d.width != offDimension.width)
    	 || (d.height != offDimension.height)) {
    	    offDimension = d;
    	    offImage = createImage(d.width, d.height);
    	    offGraphics = offImage.getGraphics();
    	}

    	// Erase the previous image

    	offGraphics.setColor(getBackground());
    	offGraphics.fillRect(0, 0, d.width, d.height);
    	offGraphics.setColor(Color.black);

    	// Paint the frame into the image

    	paintFrame(offGraphics);

    	// Paint the image onto the screen

    	g.drawImage(offImage, 0, 0, null);
    }

    /**
     * Paint the previous frame (if any).
     * @param g Graphics object
     */
    public void paint(Graphics g) {
		if (offImage != null && repaint_loop == 0) {
		    g.drawImage(offImage, 0, 0, null);
		}
		repaint_loop++;
		if (repaint_loop>2) repaint_loop = 0;
    }

    /**
     * This method is called by the thread that was created in
     * the start method. It does the main animation by looping
     * through all the particles calling their Move_Particle
     * method.
     */
    public void run()
    {
    	// Remember the starting time

    	try {
    		long tm = System.currentTimeMillis();
	    	while (Thread.currentThread() == display) {

	    		repaint();

	        	// Delay between frames

	        	tm += delay;
	    		Thread.sleep(Math.max(0, tm - System.currentTimeMillis()));

	    		// See if a new rocket is ready for launch

	    		rlaunch.launch(particle_set, getSize().width - 1, getSize().height - 1);


	        	// Move all the particles

	            int n;
	            boolean still_active = true;
	            Particle p;

	            if (particle_set.size()>0)
	            {
	            	for (n=0; n<particle_set.size(); n++)
	            	{
	            		p = (Particle)particle_set.get(n);
	            		still_active = p.Move_Particle(particle_set);
	            		if (!still_active)
	            		{
	            			particle_set.remove(n);
	            		}
	            	}
	            }
	        }
    	}
	    catch(Exception ex)
		{}
    }
}


syntax highlighted by Code2HTML, v. 0.9.1