/* Miata.java - Miata.net Mazda Miata animation. */

/* 
 * Copyright (C) 1996 Mark Boyns <boyns@sdsu.edu>
 *
 * Centipedo <URL:http://www.sdsu.edu/~boyns/java/miata/>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/**
 * @version 1.0 06 May 1996
 * @author Mark Boyns
 */

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Event;

public class Miata extends java.applet.Applet implements Runnable
{
    final int screen_width = 500;
    final int screen_height = 100;

    MediaTracker tracker;
    Image miata;
    Image logo;
    Image buffer;
    AudioClip skid_sound = null;

    int miata_width = 230; /* pixels */
    int miata_height = 95; /* pixels */
    int miata_speed = 20; /* pixels */
    int restart_delay = 30000; /* 30 seconds */
    int index = 0; /* miata frame index */
    int x = 0; /* miata x location */

    boolean paint_logo = true;
    boolean paint_miata = false;
    
    Thread thread = null;

    public void init ()
    {
	/* Load the images with MediaTracker. */
	tracker = new MediaTracker (this);

	logo = getImage (getCodeBase (), "miatanet.gif");
	tracker.addImage (logo, 0);
	
	miata = getImage (getCodeBase (), "miata.gif");
	tracker.addImage (miata, 1);

	skid_sound = getAudioClip (getCodeBase (), "skid.au");

	/* double buffer */
	buffer = createImage (screen_width, screen_height);
	
	resize (screen_width, screen_height);

	thread = new Thread (this);
	thread.start ();
    }

    public void start ()
    {
	if (thread == null)
	{
	    thread = new Thread (this);
	    thread.start ();
	}
    }
    
    public void stop ()
    {
	if (thread != null && thread.isAlive ())
	{
	    thread.stop ();
	    thread = null;
	}

    }

    void sleep (long ms)
    {
	try
	{
	    Thread.sleep (ms);
	}
	catch (Exception e)
	{
	}
    }

    public void run ()
    {
	tracker.checkAll (true);

	for (;;)
	{
	    if (tracker.checkID (0) == false)
	    {
		showStatus ("Loading Miata.net logo...");
		try
		{
			tracker.waitForID (0);
		}
		catch (Exception e)
		{
			return;
		}
		repaint ();
		showStatus ("");
	    }

	    if (tracker.checkID (1) == false)
	    {
		showStatus ("Loading 28K image...");
		try
		{
		    tracker.waitForID (1);
		}
		catch (Exception e)
		{
		    return;
		}
		showStatus ("");
	    }

	    paint_miata = true;

	    /* Move the miata to the center of the screen. */
	    index = 0;
	    x = screen_width;
	    while (x >= (screen_width/2 - miata_width/4))
	    {
		index = index == 0 ? 1 : 0;
		repaint ();
		sleep (100);
		x -= miata_speed;
	    }

	    /* Turn towards the viewer. */
	    if (skid_sound != null)
	    {
		skid_sound.play ();
	    }
	    for (index = 2; index <= 8; index++)
	    {
		repaint ();
		sleep (50);
	    }

	    /* Flash the headlights. */
	    int flash_frames[] = { 8, 9, 10, 9 };
	    for (int flashes = 0; flashes < 3; flashes++)

	    {
		for (int f = 0; f < flash_frames.length; f++)
		{
		    index = flash_frames[f];
		    repaint ();
		    sleep (200);
		}
	    }

	    for (index = 8; index >= 2; index--)
	    {
		repaint ();
		sleep (50);
	    }

	    /* Drive off the screen. */
	    index = 0;
	    while (x > -miata_width)
	    {
		index = index == 0 ? 1 : 0;
		repaint ();
		sleep (100);
		x -= miata_speed;
	    }

	    /* Paint the logo and sleep. */
	    paint_miata = false;
	    repaint ();
	    sleep (restart_delay);
	}
    }

    /* Handle mouse events. */
    public boolean mouseDown (Event e, int x, int y)
    {
	if (thread != null && thread.isAlive ())
	{
	    thread.stop ();
	    thread = null;
	}
	else
	{
	    thread = new Thread (this);
	    thread.start ();
	}
	return true;
    }
    
    /* Don't clear the screen; just call paint. */
    public void update (Graphics g)
    {
	paint (g);
    }

    /* Paint the screen. */
    public void paint (Graphics g)
    {
	/* Use double buffering. */
	Graphics b = buffer.getGraphics ();
	b.setColor (Color.white);
	b.fillRect (0, 0, screen_width, screen_height);

	if (paint_logo)
	{
	    int w = logo.getWidth (this);
	    int h = logo.getHeight (this);
	    b.drawImage (logo, screen_width/2 - w/2, screen_height/2 - h/2, w, h, this);
	}

	if (paint_miata)
	{
	    Graphics gc = b.create (x, 0, miata_width, miata_height);
	    gc.drawImage (miata, 0, -(index * miata_height), this);
	    gc.dispose ();
	}

	b.dispose ();
	g.drawImage (buffer, 0, 0, this);
    }
}

/*
Local variables:
eval: (progn (make-local-variable 'compile-command) (setq compile-command (concat "javac " buffer-file-name)))
End:
*/
