/** ShapeFramework.java -- standalone application demonstrating Frameworks */

import java.awt.*;
import java.util.*;

abstract class Shape
{
	protected int centerX;
	protected int centerY;
	
	Shape(int x, int y)
	{
		centerX = x;
		centerY = y;
	}
	
	abstract void draw(Graphics g);
	abstract boolean inside(int x, int y);
}

class Rect extends Shape
{
	protected int width;
	protected int height;

	Rect(int x, int y, int w, int h)
	{
		super(x, y);
		width = w;
		height = h;
	}

	public void draw(Graphics g)
	{
		g.drawRect(centerX-width/2, centerY-height/2, width, height);
	}

	public boolean inside(int x, int y)
	{
		return (x > centerX-width/2 && x < centerX+width/2 &&
					y > centerY-height/2 && y < centerY+width/2);
	}
}

class Circle extends Shape
{
	protected int radius;

	Circle(int x, int y, int r)
	{
		super(x, y);
		radius = r;
	}

	public void draw(Graphics g)
	{
		g.drawOval(centerX-radius, centerY-radius, 2*radius, 2*radius);
	}

	public boolean inside(int x, int y)
	{
		float xdist = x - centerX;
		float ydist = y - centerY;

		return Math.sqrt(xdist*xdist + ydist*ydist) < radius;
	}
}

class ShapeCanvas extends Canvas
{
	private ShapeFramework parent;

	public ShapeCanvas(ShapeFramework p)
	{
		parent = p;
	}

	public boolean mouseDown(Event e, int x, int y)
	{
		parent.mousePressed(x, y);
		return true;
	}
}



abstract class ShapeFramework extends Frame
{
    private Canvas canvas;
    private Vector shapes;	// list of Shapes
	
    public ShapeFramework()
    { 
        // create the Frame with title.
        super("Shape Demo"); 
        
        // Add a menubar, with a File menu, with a Quit button.
        MenuBar menubar = new MenuBar();
        Menu file = new Menu("File", true);
        menubar.add(file);
        file.add("Quit");
        file.add("Draw");
        setMenuBar(menubar);
        
        //  make the Canvas and shape list
        canvas = new ShapeCanvas(this);
        shapes = new Vector();
        add("Center", canvas);
        resize(300, 300);
        
        startup();
   
        // pop up window
        show();
    }
        
    void draw()
    {
        for (int i=0; i<shapes.size(); i++)
        {
            Shape shape = (Shape)shapes.elementAt(i);
            shape.draw(canvas.getGraphics());
        }
    }

    void addShape(Shape shape)
    {
         shapes.addElement(shape);
    }
    
    // Handle the  menu buttons.
    public boolean action(Event e, Object arg)
    {
        if (e.target instanceof MenuItem)
        {
            String label = (String) arg;
            if (label.equals("Quit"))
                System.exit(0);
            else if (label.equals("Draw"))
                draw();
        }
        return false;
    }

	public void mousePressed(int x, int y)
	{
		for (int i=0; i<shapes.size(); i++)
		{
			Shape shape = (Shape)shapes.elementAt(i);
			if (shape.inside(x, y))
				hit(shape, x, y);
		}
	}

	abstract void startup();
	abstract void hit(Shape s, int x, int y);
    
}


class ShapeApplication extends ShapeFramework
{
	public void startup()
	{
		// create the shapes
		addShape(new Rect(100, 100, 40, 60));
		addShape(new Circle(200, 200, 30));
	}

	public void hit(Shape s, int x, int y)
	{
		System.out.println("hit! "+s.getClass().getName()+" "+x+" "+y);
	}

	public static void main(String args[])
	{
		new ShapeApplication();
	}
}
