// Feuerwerk

import java.awt.*;
import java.applet.*;
import java.lang.*;
import java.util.*;
import java.net.*;
public class FireWork extends Applet implements Runnable
{
public int AnimationSpeed,           RocketStyleVariability,           MaxRocketNumber,           MaxRocketExplosionEnergy,           MaxRocketPatchNumber,           MaxRocketPatchLength,           Gravity;

public String RocketSoundtrack;
private int mx,my;
private Thread thread=null;
private Rocket rocket[];

public void init()  
   {
   int i;   
   String p;   
   p=getParameter("AnimationSpeed");   
   AnimationSpeed=(p==null)?100:Integer.valueOf(p).intValue();   
   RocketSoundtrack=getParameter("RocketSoundtrack");
   p=getParameter("RocketStyleVariability");
   RocketStyleVariability=(p==null)?20:Integer.valueOf(p).intValue();
   p=getParameter("MaxRocketNumber");
   MaxRocketNumber=(p==null)?5:Integer.valueOf(p).intValue();
   p=getParameter("MaxRocketExplosionEnergy");
   MaxRocketExplosionEnergy=(p==null)?500:Integer.valueOf(p).intValue();
   p=getParameter("MaxRocketPatchNumber");
   MaxRocketPatchNumber=(p==null)?50:Integer.valueOf(p).intValue();
   p=getParameter("MaxRocketPatchLength");
   MaxRocketPatchLength=(p==null)?100:Integer.valueOf(p).intValue();
   p=getParameter("Gravity");
   Gravity=(p==null)?20:Integer.valueOf(p).intValue();
   mx=size().width-1;   my=size().height-1;
   rocket=new Rocket[MaxRocketNumber];
   for(i=0;i<MaxRocketNumber;i++)
         rocket[i]=new Rocket(mx,my,Gravity);
    }

public void start()
   {
   if(thread==null)
      {
      thread=new Thread(this);
      thread.start();
      }
   }

public void stop()
   {
   if(thread!=null)
      {
      thread.stop();
      thread=null;
      }
   }

public void run()
   {
   int i,
   e=(int)(Math.random()*MaxRocketExplosionEnergy*3/4)+
         MaxRocketExplosionEnergy/4+1,
       p=(int)(Math.random()*MaxRocketPatchNumber*3/4)+
         MaxRocketPatchNumber/4+1,
       l=(int)(Math.random()*MaxRocketPatchLength*3/4)+
         MaxRocketPatchLength/4+1;
   long s=(long)(Math.random()*10000);
   boolean sleep;
   Graphics g=getGraphics();
   URL u=null;   while(true)
      {
      try
          {
          thread.sleep(100/AnimationSpeed);
          }
      catch(InterruptedException x)
	{}
      sleep=true;
      for(i=0;i<MaxRocketNumber;i++)
         sleep=sleep&&rocket[i].sleep;
      if(sleep&&Math.random()*100<RocketStyleVariability)
         {
         e=(int)(Math.random()*MaxRocketExplosionEnergy*3/4)+
           MaxRocketExplosionEnergy/4+1;
         p=(int)(Math.random()*MaxRocketPatchNumber*3/4)+
           MaxRocketPatchNumber/4+1;
         l=(int)(Math.random()*MaxRocketPatchLength*3/4)+
           MaxRocketPatchLength/4+1;
         s=(long)(Math.random()*10000);
         }
      for(i=0;i<MaxRocketNumber;i++)
         {
         if(rocket[i].sleep&&Math.random()*MaxRocketNumber*l<1)
            {
            try 
	   {
                u=new URL(getDocumentBase(),RocketSoundtrack);
                }
            catch(MalformedURLException x)
	{}
            play(u);
            rocket[i].init(e,p,l,s);
            rocket[i].start();
            }
         rocket[i].show(g);
         }
      }
   }

public void paint(Graphics g)
   {
   g.setColor(Color.black);
   g.fillRect(0,0,mx+1,my+1);
   }
}

class Rocket
{
public boolean sleep=true;
private int energy,
patch,length,
            mx,my,
            gravity,
            ox,oy,
            vx[],vy[],
            x,y,
            red,blue,green,
            t;

private Random random;
public Rocket(int a,int b,int g)
   {
   mx=a;
   my=b;
   gravity=g;
   }public void init(int e,int p,int l,long seed)
   {
   int i;
   energy=e;
   patch=p;
   length=l;
   random=new Random(seed);
   vx=new int[patch];
   vy=new int[patch];
   red=(int)(random.nextDouble()*128)+128;
   blue=(int)(random.nextDouble()*128)+128;
   green=(int)(random.nextDouble()*128)+128;
   ox=(int)(Math.random()*mx/2)+mx/4;
   oy=(int)(Math.random()*my/2)+my/4;
   for(i=0;i<patch;i++)
      {
      vx[i]=(int)(Math.random()*energy)-energy/2;
      vy[i]=(int)(Math.random()*energy*7/8)-energy/8;
      }
   }

public void start()
   {
   t=0;
   sleep=false;
   }

public void show(Graphics g)
   {
   if(!sleep)
      if(t<length)
         {
         int i,c;
         double s;
         Color color;
         c=(int)(random.nextDouble()*64)-32+red;
         if(c>=0&&c<256)red=c;
         c=(int)(random.nextDouble()*64)-32+blue;
         if(c>=0&&c<256)blue=c;
         c=(int)(random.nextDouble()*64)-32+green;
         if(c>=0&&c<256)green=c;
         color=new Color(red,blue,green);
         for(i=0;i<patch;i++)
            {
            s=(double)t/100;
            x=(int)(vx[i]*s);
            y=(int)(vy[i]*s-gravity*s*s);
            g.setColor(color);
            g.drawLine(ox+x,oy-y,ox+x,oy-y);
            if(t>=length/2)
               {
               int j;
               for(j=0;j<2;j++)
                  {
                  s=(double)((t-length/2)*2+j)/100;
                  x=(int)(vx[i]*s);
                  y=(int)(vy[i]*s-gravity*s*s);
                  g.setColor(Color.black);
                  g.drawLine(ox+x,oy-y,ox+x,oy-y);
                  }
               }
            }
         t++;
         }
      else
         {
         sleep=true;
         }
   }
}