//////////////////////////////////////////////////////////////////////////
// Fire			:	Realtime Flames in your Browser !!!					//
//					Applet Version (DOS/DirectX version avialiable, too)//
// Version		:	1.0													//
// Extra info	:   Not avialiable at this time ...						//
//																		//
// Creator		:	aBn0rMaL '97 (c) (Benjamin Nitschke, exDreamGames)	//
// Created for	:	my HTML/JAVA Homepage for Informatik by Mr. Schr.	//
// Created at	:	18:13 at the 13. October 1997						//
// Modificated  :	23:30 at the 13. October 1997						//
//																		//
// Found bugs	:   None at this time ...								//
// Fixed bugs	:   Well, none ...										//
//																		//
// TODO			:	text in the flames									//
//////////////////////////////////////////////////////////////////////////

// import the essential classes for this applet
import java.awt.*;
import java.awt.image.ImageProducer;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.MemoryImageSource;
import java.applet.Applet;


// the Fire class
public class Fire extends java.applet.Applet implements Runnable
{
	// the resolution of the applet
	int xRes, yRes;
	Image offScrImage;

	// use for faster graphics the index color model
	IndexColorModel myColorModel = null;

	// the timer
	Thread timer = null;
	int timerSpeed = 5;

	// the flames pixel array
	byte fire[];
	int thisFire, oldFire, newPix;
	String fireText;

	// global variables i, j, k, l
	int i, j, k, l;


	public void initColorModel()
	{
		// create the palette for flames
		byte red[] = new byte[256];
		byte green[] = new byte[256];
		byte blue[] = new byte[256];
		byte alpha[] = new byte[256];

		// first clear all entries
		for( int i = 0; i < 256; i++ )
		{
			red[i] = blue[i] = green[i] = (byte) 0;
			alpha[i] = (byte) 0xFF;
		} // of for

		// a bit of blue over the flames !
		for( int i = 0; i < 8; i++ )
		{
			blue[i] = (byte) (i*8);      // increase a bit blue
			blue[i+8] = (byte) (64-(i*8)); // decrease a bit blue
		} // of for

		// increase red
		for( int i = 8; i < 32; i++ )
		{
			red[i] = (byte) (((i-8)*255)/23);
		} // of for

		// increase green, hold red
		for( int i = 32; i < 56; i++ )
		{
			red[i] = (byte) 0xFF;
			green[i] = (byte) (((i-32)*255)/23);
		} // of for

		// increase blue, hold red and green (=yellow)
		for( int i = 56; i < 80; i++ )
		{
			red[i] = green[i] = (byte) 0xFF;
			blue[i] = (byte) (((i-56)*255)/23);
		} // of for

		// rest white !
		for( int i = 80; i < 256; i++ )
		{
			red[i] = green[i] = blue[i] = (byte) 0xFF;
		} // of for

		myColorModel = new IndexColorModel( 8, 256, red, green, blue, alpha );

	} // of initColorModel

	public void init()
	{
		xRes = size().width;
		yRes = size().height;

		fire = new byte[ 2 * xRes * yRes ];
		thisFire = 0;
		oldFire = xRes * yRes;

		String param = getParameter( "TIMERSPEED" );
		if ( param != null )
		{
			timerSpeed = Integer.parseInt( param );
		} // of if ( param ... )

		fireText = getParameter( "FIRETEXT" );
		if ( fireText == null )
		{
			fireText = "Hi Freaks";
		}

		if( myColorModel == null )
		{
			initColorModel();
		}
	} // of init

	public void start()
	{
		if ( timer == null )
		{
			timer = new Thread( this );
			timer.start();
		} // of if ( timer ... )
	} // of start

	public void stop()
	{
		timer = null;
	} // of stop

	public void makeFire()
	{
		int nFire = thisFire;
		thisFire = oldFire;
		oldFire = nFire;

		// create a new line (at the bottom of the fire)
		for ( j = yRes-3; j < yRes; j++ )
		{
			for ( i = 0; i < xRes; i++)
			{
				fire[ thisFire + i + xRes*j ] = (byte) (Math.random()*64+64);
			} // of for
		} // of for
		for( i = 0; i < (int) (Math.random()*(xRes/3)); i++ )
		{
			l = (int) (Math.random()*(xRes-3));
			for( j = 0; j < 3; j++ )
			{
				for( k = 0; k < 3; k++ )
				{
					fire[ thisFire + l + j + (yRes-3+k)*xRes ] = (byte) 0x8F;
				} // of for
			} // of for
		} // of for

		// scroll every line a line up, (TODO:mix) and decrement the colors
		for( i=0; i<yRes-1; i++ )
		{
			// every line
			for( j=0; j<xRes; j++ )
			{
				newPix =  (// fire[ oldFire + i*xRes+j ]+
							fire[ oldFire +(i+2)*xRes+j ]+
							fire[ oldFire +(i+1)*xRes+(j-1) ]+
							fire[ oldFire +(i+1)*xRes+(j+1) ]+
							fire[ oldFire +(i+1)*xRes+(j+0) ] ) >> 2;
				if( newPix < 1 ) newPix = 0; else newPix--;
				fire[ thisFire + i*xRes+j ] = (byte) newPix;
			} // of for
		} // of for
	} // of makeFire()

	public void run()
	{
		while ( timer != null )
		{
			try
			{
				Thread.sleep( timerSpeed );
			} // of try
			catch ( InterruptedException e )
			{
				// dummy
			} // of catch

			// repaint the hole scene
			repaint();
		} // of while
		timer = null;
	} // of run

	public void update( Graphics g )
	{
		// create the new fire scene
		makeFire();

		paint( g );
	} // of update

	public void paint( Graphics g )
	{
		offScrImage = createImage( new MemoryImageSource( xRes, yRes-2,
										myColorModel,
										fire, thisFire, xRes) );
		g.drawImage( offScrImage, 0, 0, xRes, yRes, this );
	} // of paint
} // of class Fire

// that's it: Just enjoy the JAVA-Coding !
