import java.applet.Applet;
import java.awt.*; // We're using just about everything
import java.util.Vector;

// A class for drawable rectangles
class DrawableRect extends Rectangle {
  Color color = Color.black; // What color am I?
  boolean filled = false; // Am I filled, or not?

  // constructs a drawable rectangle with the indicated dimensions and attributes
  DrawableRect(int x, int y, int width, int height, Color color, boolean filled) {
  super(x, y, width, height);
  this.color = color;
  this.filled = filled;
  }

  // draws a rectangle taking into account the specified offset
  void draw(Graphics g, int offset_x, int offset_y) {
    Color temp = g.getColor();
    g.setColor(color);
    if (filled) {
      g.fillRect(x - offset_x, y - offset_y, width, height);
    } else {
      g.drawRect(x - offset_x, y - offset_y, width, height);
    }
    g.setColor(temp);
    }
  }

  class CheckboxPanel extends Panel {
  // A CheckboxGroup enforces mutual exclusion
  CheckboxGroup myGroup;

  // Two checkboxes in the group
  Checkbox filledBox;
  Checkbox notFilledBox;

  CheckboxPanel() {
    // new java.awt.Panel()
    super();
    setLayout(new BorderLayout());
    myGroup = new CheckboxGroup();
    filledBox = new Checkbox("Filled", myGroup, false);
    notFilledBox = new Checkbox("Not Filled", myGroup, true);
    myGroup.setCurrent(notFilledBox);
    add("North", filledBox);
    add("South", notFilledBox);
  }

  // Return the state of our checkbox group
  boolean isFilled() {
    return (myGroup.getCurrent() == filledBox);
  }
}

class RectCanvas extends Canvas {
  // mouse down point
  int orig_x;
  int orig_y;

  // where the canvas has to be scrolled to
  public int offset_x = 0;
  public int offset_y = 0;

  // current settings for new rectangles
  boolean filled = false;
  Color rectColor = Color.black;

  // the collection of rectangles
  int numRects = 0;
  Vector rects = new Vector(100, 10);
  DrawableRect currentRect;  // just for convenience

  // create a drawable rectangle and add it to the list of rects
  DrawableRect addRect(int x, int y, int width, int height) {

    DrawableRect r = new DrawableRect(x, y, width, height, rectColor, filled);
    rects.addElement(r);
    numRects++;
    return r;
  }

  // disposes of all rectangles and starts a new list
  void clearRects() {
    numRects = 0;
    rects = new Vector(100, 10);
    repaint();
  }

  //  set the color for adding new rectangles
  void setRectColor(Color c) {
    rectColor = c;
  }

  // set the filled attribute for adding new rectangles
  void setFilled(boolean b) {
    filled = b;
  }

  // respond to mouseDown events ... called by inherited handleEvent()
  public boolean mouseDown(Event evt, int x, int y) {
    // set the mouse-down point
    orig_x = x;
    orig_y = y;

    // start a new rectangle
    currentRect = addRect(orig_x + offset_x, orig_y + offset_y, 0, 0);
    return true;
  }

  // respond to mouseDrag events ... called by inherited handleEvent()
  public boolean mouseDrag(Event evt, int x, int y) {
    // how far have we dragged in x and y?
    int x_diff = x - orig_x;
    int y_diff = y - orig_y;
    // Rectangles can't have negative height and width.
    // We want the Rectangle to follow the mouse.
    // Which is the top left corner?
    int x_val = (x_diff > 0)?
      orig_x + offset_x :
      x + offset_x;
    int y_val = (y_diff > 0)?
      orig_y + offset_y :
      y + offset_y;

  // Height and width determined by drag length.
  int width_val = Math.abs(x_diff);
  int height_val = Math.abs(y_diff);

  // Interactively reshape the rectangle
  currentRect.reshape(x_val, y_val, width_val, height_val);

  // Show the results as the user drags
  repaint();
  return true;
  }

  // Draw all rectangles on the canvas
  public void paint(Graphics g) {
    DrawableRect r;

    for ( int i = 0; i < numRects; i++) {
      r = (DrawableRect)rects.elementAt(i);
      // draw each rectangle, offset by the scroll amount
      r.draw(g, offset_x, offset_y);
    }
  }
}

public class GUIExample extends Applet {
  // the top panel and it's subitems
  Panel topPanel = new Panel();
  CheckboxPanel checkboxPanel = new CheckboxPanel();
  Label colorLabel = new Label("Color: ");
  Choice colorChoice = new Choice();

  // the middle panel and it's subitems
  Panel middlePanel = new Panel();
  RectCanvas rCanvas = new RectCanvas();
  Scrollbar x_scroll = new Scrollbar(Scrollbar.HORIZONTAL);
  Scrollbar y_scroll = new Scrollbar(Scrollbar.VERTICAL);

  // the bottom panel and it's subitem
  Panel bottomPanel = new Panel();
  Button clearButton = new Button("Clear");

public void init() {
  // create a layout manager and set our applet to use it
  this.setLayout(new BorderLayout());

  // SET UP THE TOP PANEL...

  topPanel.setLayout(new FlowLayout());
  // the color choice
  colorChoice.addItem("Black");
  colorChoice.addItem("Blue");
  colorChoice.addItem("Red");
  colorChoice.addItem("Green");
  colorChoice.addItem("Cyan");
  colorChoice.select("Black");

  // ... add all items to the top panel
  topPanel.add(checkboxPanel);
  topPanel.add(colorLabel);
  topPanel.add(colorChoice);

  // ... add the top panel to the applet
  this.add("North", topPanel);

  // THE MIDDLE PANEL...
  middlePanel.setLayout(new BorderLayout());

  // ...set up the middle panel's RectCanvas
  rCanvas.setFilled(checkboxPanel.isFilled());
  rCanvas.setRectColor(getSelectedColor());
  rCanvas.setBackground(Color.white);

  // ...add all items to the middle panel
  middlePanel.add("South", x_scroll);
  middlePanel.add("East", y_scroll);
  middlePanel.add("Center", rCanvas);

  // ...add the middle panel to the applet
  add("Center", middlePanel);

  // THE BOTTOM PANEL...
  bottomPanel.add(clearButton);
  // ...add the panel to the applet
  this.add("South", bottomPanel);

  resize(350, 350);
}

public void paint(Graphics g) {
  // make sure the canas ets repainted
  rCanvas.repaint();
}

  // Read the currently selected color from the Choice item
  Color getSelectedColor() {
    if (colorChoice.getSelectedItem().equals("Black")) {
      return Color.black;
    } else if (colorChoice.getSelectedItem().equals("Blue")) {
      return Color.blue;
    } else if (colorChoice.getSelectedItem().equals("Red")) {
      return Color.red;
    } else if (colorChoice.getSelectedItem().equals("Green")) {
      return Color.green;
    } else if (colorChoice.getSelectedItem().equals("Cyan")) {
      return Color.cyan;
    } else {
      return Color.black;
    }
  }

  // overrides java.awt.Component.handleEvent()
  public boolean handleEvent(Event evt) {
    if (evt.target == colorChoice) {
      rCanvas.setRectColor(getSelectedColor());

    } else if (evt.target instanceof Checkbox) {
      rCanvas.setFilled(checkboxPanel.isFilled());

    } else if (evt.target == x_scroll) {
      switch (evt.id) {
        case Event.SCROLL_LINE_UP:
        case Event.SCROLL_LINE_DOWN:
        case Event.SCROLL_PAGE_UP:
        case Event.SCROLL_PAGE_DOWN:
        case Event.SCROLL_ABSOLUTE:
          // evt.arg holds the value that the scrollbar has scrolled to
          rCanvas.offset_x = ((Integer)evt.arg).intValue();
        break;
        }

    } else if (evt.target == y_scroll) {
      switch (evt.id) {
        case Event.SCROLL_LINE_UP:
        case Event.SCROLL_LINE_DOWN:
        case Event.SCROLL_PAGE_UP:
        case Event.SCROLL_PAGE_DOWN:
        case Event.SCROLL_ABSOLUTE:
          // evt.arg holds the value that the scrollbar has scrolled to
          rCanvas.offset_y = ((Integer)evt.arg).intValue();
        break;
        }
      }

      // the canvas has been scrolled, so...
      rCanvas.repaint();

      // make sure other events are handled by the overridden event handler
      return super.handleEvent(evt);
    }

    // Respond to ACTION events called by java.awt.Component.handleEvent()
    public boolean action(Event evt, Object what) {
      if (evt.target.equals(clearButton)) {
        // clear the rectangles
        rCanvas.clearRects();
       }

       // ...just in case our parent needs the event
       return super.action(evt, what);
       }

       // Overrides java.awt.Component.reshape()
       // This method is called when the user resizes the applet

      public void reshape(int x, int y, int width, int height) {

        // allow java.awt.Component.reshape() to do the real work
        super.reshape(x, y, width, height);

        // Adjust the scrollbars: values, visible amounts, and ranges
        int canvasWidth = rCanvas.size().width;
        int canvasHeight = rCanvas.size().height;

        // ... use 1000 pixel "virtual" canvas
        x_scroll.setValues(rCanvas.offset_x, canvasWidth, 0, 1000 - canvasWidth);
        y_scroll.setValues(rCanvas.offset_y, canvasHeight, 0, 1000 - canvasHeight);

        // repaint the canvus
        rCanvas.repaint();
      }
    }