/*
 * 1.0 code.
 */

import java.awt.*;
import java.applet.Applet;

/* 
 * This displays a framed area.  When the user drags within
 * the area, this program displays a rectangle extending from
 * where the user first pressed the mouse button to the current
 * cursor location.
 */

public class RectangleDemo extends Applet {
    RFramedArea framedArea;
    Label label;

    public void init() {
        GridBagLayout gridBag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();

        setLayout(gridBag);

        framedArea = new RFramedArea(this);
        c.fill = GridBagConstraints.BOTH;
        c.weighty = 1.0;
        c.gridwidth = GridBagConstraints.REMAINDER; //end row
        gridBag.setConstraints(framedArea, c);
        add(framedArea);

        label = new Label("Drag within the framed area.");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 1.0;
        c.weighty = 0.0;
        gridBag.setConstraints(label, c);
        add(label);

        validate();
    }

    public void rectChanged(Rectangle rect) {
        label.setText("Rectangle goes from ("
                      + rect.x + ", " + rect.y + ") to ("
                      + (rect.x + rect.width - 1) + ", "
                      + (rect.y + rect.height - 1) + ").");
        repaint();
    }
}

/* This class exists solely to put a frame around the coordinate area. */
class RFramedArea extends Panel {
    public RFramedArea(RectangleDemo controller) {
        super();

        //Set layout to one that makes its contents as big as possible.
        setLayout(new GridLayout(1,0));

        add(new SelectionArea(controller));
        validate();
    }

    public Insets insets() {
        return new Insets(4,4,5,5);
    }

    public void paint(Graphics g) {
        Dimension d = size();
        Color bg = getBackground();
 
        g.setColor(bg);
        g.draw3DRect(0, 0, d.width - 1, d.height - 1, true);
        g.draw3DRect(3, 3, d.width - 7, d.height - 7, false);
    }
}

class SelectionArea extends Canvas {
    Rectangle currentRect;
    RectangleDemo controller;

    public SelectionArea(RectangleDemo controller) {
        super();
        this.controller = controller;
    }

    public boolean mouseDown(Event event, int x, int y) {
        currentRect = new Rectangle(x, y, 0, 0);
        repaint();
        return false;
    }

    public boolean mouseDrag(Event event, int x, int y) {
        currentRect.resize(x - currentRect.x, y - currentRect.y);
        repaint();
        return false;
    }

    public boolean mouseUp(Event event, int x, int y) {
        currentRect.resize(x - currentRect.x, y - currentRect.y);
        repaint();
        return false;
    }

    public void paint(Graphics g) {
        Dimension d = size();

        //If currentRect exists, paint a rectangle on top.
        if (currentRect != null) {
            Rectangle box = getDrawableRect(currentRect, d);
            controller.rectChanged(box);
    
            //Draw the box outline.
            g.drawRect(box.x, box.y, box.width - 1, box.height - 1);
        }
    }

    Rectangle getDrawableRect(Rectangle originalRect, Dimension drawingArea) {
        int x = originalRect.x;
        int y = originalRect.y;
        int width = originalRect.width;
        int height = originalRect.height;

        //Make sure rectangle width and height are positive.
        if (width < 0) {
            width = 0 - width;
            x = x - width + 1;
            if (x < 0) {
                width += x;
                x = 0;
            }
        }
        if (height < 0) {
            height = 0 - height;
            y = y - height + 1;
            if (y < 0) {
                height += y;
                y = 0;
            }
        }

        //The rectangle shouldn't extend past the drawing area.
        if ((x + width) > drawingArea.width) {
            width = drawingArea.width - x;
        }
        if ((y + height) > drawingArea.height) {
            height = drawingArea.height - y;
        }

        return new Rectangle(x, y, width, height);
    }
}
