import java.applet.*;
import java.awt.*;
import java.net.*;
import java.util.*;

public class Lab3Map extends Applet {
    Image image;
    Vector rects;
    ImagemapRectangle lastrect; // ImagemapRectangle is defined below, and extends Rectangle.
    boolean done_loading = false;

    public void init() 
    {
	// Get the image from the "image" parameter.
	image = getImage(getCodeBase(), getParameter("image"));

	// create the vector. It will hold the rectangles ("hot spots").
	rects = new Vector();

	ImagemapRectangle r;
	int i=0;

	// get the rectangle parameters until there are no more.
	// The getRectangleParameter function is provided below and
	// parses the string (i.e. value of the rect parameter).
	while ((r = getRectangleParameter("rect" + i)) != null) 
	{
		// add the rect to the vector.
		rects.addElement(r);
		i++;
	}

	// draw the image offscreen for less flickering.
        Image offscreen = createImage(318, 191);
        Graphics myGC = offscreen.getGraphics();
        myGC.drawImage(image, 0, 0, this);
    }

    public boolean imageUpdate(Image img, int flag, int x, int y, int w, int h) {
	// this routine is just to check if the whole image has been loaded.
	// Must look familiar by now.
        if (flag == ALLBITS) {
                done_loading = true;
                repaint();
                return false;
        }
        else
                return true;
    }

    public void paint(Graphics g) 
    {
	// draw the image if loaded.
        if (done_loading)
		g.drawImage(image, 0, 0, this);
    }

    private ImagemapRectangle findrect(int x, int y) 
    {
	// Checks if the location of the click falls inside a "hot spot".
	int i;
	ImagemapRectangle r = null;

	// loops through the rectangles in vector and sees if the location is in one of them.
	for (i=0; i< rects.size(); i++) 
	{
		r = (ImagemapRectangle) rects.elementAt(i);
		if (r.inside(x,y)) 
		{
			break;
		}
	}
	if (i<rects.size()) return r;
	else return null;
    }

    public boolean mouseDown(Event event, int x, int y) 
    {
	// if user clicked, then find the associated rectangle.
	ImagemapRectangle r = findrect(x,y);

	// if click fell outside all rectangles, return false.
	if (r == null) return false;

	// get the Graphics context, set the XOR mode to red, and draw a rectangle
	// around the "hot spot" in question.
	Graphics g = getGraphics();
	g.setXORMode(Color.red);
	g.drawRect(r.x, r.y, r.width, r.height);

	// save the rectangle that was just drawn, so that it can be erased on a mouse up.
	lastrect = r;

	// show the "goto" location in the statusbar.
	showStatus("This takes you to:" + r.url);

        return true;
    }

    public boolean mouseUp(Event event, int x, int y) 
    {
	// if mouseUp followed a valid mouseDown (i.e. inside a "hot spot".
	if (lastrect != null) 
	{
		// Get the graphics context and set the XOR mode again.
		// Setting the XOR mode and then drawing the rectangle again will 
		// effectively result in an erase operation.
		Graphics g = getGraphics();
		g.setXORMode(Color.red);
		g.drawRect(lastrect.x, lastrect.y, lastrect.width, lastrect.height);

		// Erase the statusbar.
		showStatus("");

		// find the rectangle for the mouse position.
		ImagemapRectangle r = findrect(x, y);

		// if mouseUp is in a "hot spot" and if it is in the same hot spot
		// as the mouseDown occured, then go to the URL specified for that Hot spot.
		if ((r != null) && (r == lastrect)) 
		{
			getAppletContext().showDocument(r.url);
		}

		// reset the lastrect;
		lastrect = null;
	}
        return true;
    }

    protected ImagemapRectangle getRectangleParameter(String name) 
    {
	// this function parses the value of a rectangle from the HTML file.
	int x,y,w,h;
	URL url;

	// get the value for the parameter.
	String value = getParameter(name);
	if (value == null) return null;

	// The value consists of several fields: the rectangle's (x,y) coordinates
	// and it's width and height, along with the "goto" URL the browser should load
	// upon selecting the rectangle.
	try {
		// Set the StringTokenizer to be the comma (",") since this is what separates
		// the entries in the string.
		StringTokenizer st = new StringTokenizer(value, ",");

		// now you can easily get the various values, by doing a "nextToken" to get
		// the next field, and then parsing it to an integer.
		x = Integer.parseInt(st.nextToken());
		y = Integer.parseInt(st.nextToken());
		w = Integer.parseInt(st.nextToken());
		h = Integer.parseInt(st.nextToken());

		// The last field in the string is nont an integer but a URL
		// location. Create the URL and save it in "url".
		url = new URL(getDocumentBase(), st.nextToken());
	}
	catch(NoSuchElementException e) return null;
	catch(NumberFormatException e) return null;
	catch(MalformedURLException e) return null;

	// now, create a rectangle and pass the various variables to its constructor.
	// This will create the rectangle and initialize the fields in it.
	return new ImagemapRectangle(x, y, w, h, url);
    }

}

// Define a new class ImageRectangle to extend the Rectangle class. Only override the
// Rectangle constructor to also take a URL.

class ImagemapRectangle extends Rectangle {
	URL url;
	
	public ImagemapRectangle(int x, int y, int w, int h, URL theUrl) {
		// call the superclass (i.e. Rectangle) constructor and initialize
		// the rectangle.
		super(x,y,w,h);

		// set the extra URL field for our rectangle.
		url = theUrl;
	}
}

