/*
 * Author: Paul Koshevoy
 * MyCanvas.java  Fri 9 Oct 1997, 11:25:00 1997
 */

import java.awt.*;

public class MyCanvas extends Canvas implements Runnable
{
private int delay = 41;// delay between the redraws of the canvas in milliseconds
private int width;     // width of the canvas
private int height;    // height of the canvas
private SpaceShip UFO; // the space ship object

private SpaceShip misc[];// the rest of the clutter floating in the space
private int clutter;     // count of clutter in the space
    
private Image offImage;       // buffer for double buffering
public  Image NEBULA;         // background picture
private MediaTracker tracker; // this tracker will look out for the progress on the background load
private Graphics offGraphics; // buffer for double buffering
private Thread animatorThread;// thread for double buffering and rotaion
private int zoom_offset;
private int t_delay=0; // this variable kills missiles and debris before ship materializes
    
public MyCanvas(Image nebula) // constructor
    {
	NEBULA = nebula;
	tracker = new MediaTracker(this);
	tracker.addImage(NEBULA, 0);
	try
	    {
		tracker.waitForID(0);
	    }
	catch(InterruptedException e)
	    {}
	width  = NEBULA.getWidth(this);
	height = NEBULA.getHeight(this);
	setSize(width, height);
	misc = new SpaceShip[12];
	start();
    }
    
public void start()
    {
	if(animatorThread == null)
	    animatorThread = new Thread(this); // create a new thread for double buffering
	animatorThread.start();                // start the new thread
    }
    
public void stop()
    {
	if(animatorThread != null)
	    animatorThread.stop(); // stop the double buffer thread
	animatorThread = null;     // destroy the double buffer thread
	offGraphics = null;        // destroy offscreen buffer
	offImage = null;           // destroy offscreen buffer
    }
    
public void fire_missile(String bitmap, int w, int h, int r, int c)
    {
	if(t_delay == 0)
	    {
		if(clutter < 12 && UFO.dead==0)
		    {
			misc[clutter] = new SpaceShip(UFO, bitmap, w, h, width, height, r, c);
			misc[clutter].accelerate();
			clutter++;
		    }
	    }
    }

public void nuke_em_all()
    {
	for(int i=0; i<clutter; i++)
	    misc[i].explode();
    }

public void zoom_in()
    {
	if(SpaceShip.Scale < 11)
	    SpaceShip.Scale++;
    }
    
    
public void zoom_out()
    {
	if(SpaceShip.Scale > 1)
	    SpaceShip.Scale--;
    }
    
    
public void set(String bitmap, int w, int h, int r, int c)
    {
	UFO = null;
	UFO = new SpaceShip(bitmap, w, h, width, height, r, c);
    }


public void reset()
    {
	if(t_delay == 0)
	    {
		t_delay = 25;
		UFO.reassemble();
	    }
    }


public void remap_ship(String bitmap, int w, int h, int r, int c)
    {
//	stop();
	UFO.reset(bitmap, w, h, width, height, r, c);
//	start();
    }
    
public void ufo_accel()
    {
	UFO.accelerate();
    }

public void ufo_decel()
    {
	UFO.deaccelerate();
    }
    
public void ufo_rotate_ccw()
    {
	UFO.rotate_ccw();
    }
    
public void ufo_rotate_cw()
    {
	UFO.rotate_cw();
    }

public void dump()
    {
	UFO.dump();
    }
    
public void run()
    {
	Thread.currentThread().setPriority(Thread.MAX_PRIORITY); // maximize the priority of the thread
	long startTime = System.currentTimeMillis();             // start time

	while(Thread.currentThread() == animatorThread)          // double buffer thread
	    {
		try
		    {
			startTime += delay;
			Thread.sleep(Math.max(0, startTime - System.currentTimeMillis())); // put te thread to sleep for the delay
		    }
		catch(InterruptedException e)
		    {
			break;
		    }
		repaint(); // redraw
	    }
    }
    
    
public void update(Graphics g)
    {
	paint(g);
    }

    
public void paint(Graphics g)
    {
	// set up double buffer
	if((offGraphics == null))
	    {
		offImage = createImage(width, height);
		offGraphics = offImage.getGraphics();
	    }

	UFO.move();

// Set the background to be black
//        offGraphics.setColor(Color.black);
//        offGraphics.fillRect(0, 0, width, height);

	offGraphics.drawImage(NEBULA, 0, 0, this);
	
	zoom_offset = (int)(SpaceShip.Scale/2);
        // draw the SpaceShip
	if(SpaceShip.Scale==1)
	    for(int i=0; i<UFO.num; i++)
		{
		    offGraphics.setColor(UFO.pcolor[i]);
		    if(SpaceShip.Scale==1)
			offGraphics.drawLine(UFO.pixels[i].x_int(), UFO.pixels[i].y_int(),
					     UFO.pixels[i].x_int(), UFO.pixels[i].y_int());
		}
	else
	    for(int i=0; i<UFO.num; i++)
		{
		    offGraphics.setColor(UFO.pcolor[i]);
		    offGraphics.fillRect(UFO.pixels[i].x_int()-zoom_offset,
					 UFO.pixels[i].y_int()-zoom_offset,
					 (int)(SpaceShip.Scale), (int)(SpaceShip.Scale));
//		    offGraphics.fillOval(UFO.pixels[i].x_int()-zoom_offset,
//					 UFO.pixels[i].y_int()-zoom_offset,
//					 (int)(SpaceShip.Scale*2),
//					 (int)(SpaceShip.Scale*2));
		}
	

	if(SpaceShip.Scale==1)
	    for(int j=0; j<clutter; j++)
		{
		    misc[j].move();
		    for(int i=0; i<misc[j].num; i++)
			{
			    offGraphics.setColor(misc[j].pcolor[i]);
			    offGraphics.drawLine(misc[j].pixels[i].x_int(), misc[j].pixels[i].y_int(),
						 misc[j].pixels[i].x_int(), misc[j].pixels[i].y_int());
			}
		}
	else
	    for(int j=0; j<clutter; j++)
		{
		    misc[j].move();
		    for(int i=0; i<misc[j].num; i++)
			{
			    offGraphics.setColor(misc[j].pcolor[i]);
			    offGraphics.fillRect(misc[j].pixels[i].x_int()-zoom_offset,
						 misc[j].pixels[i].y_int()-zoom_offset,
						 (int)(SpaceShip.Scale), (int)(SpaceShip.Scale));
			}
		}
	// output the double buffer to the screen
	g.drawImage(offImage, 0, 0, this);

	// check for collisions
	for(int i=0; i<clutter; i++)
	    {
		if(UFO.collision(misc[i]))
		   {
		       UFO.explode();
		       misc[i].explode();
		   }
	    }
	for(int i=0; i<clutter; i++)
	    for(int j=0; j<clutter; j++)
		{
		    if(i!=j)
			if(misc[i].collision(misc[j]))
			    {
				misc[i].explode();
				misc[j].explode();
			    }
		}
	if(t_delay>0)
	    {
		if(clutter>0)
		    {
			if(t_delay%2==0)
			    {
				t_delay--;
				clutter--;
				misc[clutter]=null;
			    }
			else
			    t_delay--;
		    }
		else
		    t_delay = 0;
	    }
    }
}

