import java.awt.*;

// This appears in Core Web Programming from
// Prentice Hall Publishers, and may be freely used
// or adapted. 1997 Marty Hall, hall@apl.jhu.edu.

/** A Panel that reports mouse, keyboard and focus
 *  events to a TextArea (if available) or to
 *  standard output (if no TextArea is available).
 */

public class EventPanel extends Panel {

  /** The TextArea messages can be reported in. */
 
  protected TextArea reportArea = null;

  /** Build EventPanel; reports get sent to TextArea. */
  
  public EventPanel(TextArea reportArea) {
    this.reportArea = reportArea;
  }

  /** Build EventPanel; reports get printed. */
  
  public EventPanel() {}

  /** Report that mouse was pressed. */
  
  public boolean mouseDown(Event event, int x, int y) {
    return(mouseClick("mouseDown", event, x, y));
  }

  /** Report that mouse was released. */
  
  public boolean mouseUp(Event event, int x, int y) {
    return(mouseClick("mouseUp", event, x, y));
  }

  /** Determine button and number of clicks. */
  
  protected boolean mouseClick(String type, Event event,
                             int x, int y) {
    String description = type + "[";
    if ((event.modifiers & Event.ALT_MASK) != 0)
      description = description + "middle, ";
    else if ((event.modifiers & Event.META_MASK) != 0)
      description = description + "right, ";
    else
      description = description + "left, ";
    if (event.clickCount > 1)
      description = description + event.clickCount + "]";
    else
      description = description + "single]";
    return(report(description, x, y));
  }

  /** Report that mouse was moved (no buttons down). */
  
  public boolean mouseMove(Event event, int x, int y) {
    return(report("mouseMove", x, y));
  }

  /** Report that mouse was moved (with button down). */
  
  public boolean mouseDrag(Event event, int x, int y) {
    return(report("mouseDrag", x, y));
  }

  /** Report that mouse entered panel. */
  
  public boolean mouseEnter(Event event, int x, int y) {
    return(report("mouseEnter", x, y));
  }

  /** Report that mouse left panel. */
  
  public boolean mouseExit(Event event, int x, int y) {
    return(report("mouseExit", x, y));
  }

  /** Report that panel got input focus. */
  
  public boolean gotFocus(Event event, Object ignore) {
    return(report("gotFocus", event.x, event.y));
  }

  /** Report that panel lost input focus. */
  
  public boolean lostFocus(Event event, Object ignore) {
    return(report("lostFocus", event.x, event.y));
  }

  /** Report that a key was pressed. */
  
  public boolean keyDown(Event event, int key) {
    return(keyStroke("keyDown", event, key));
  }

  /** Report that a key was released. */
  
  public boolean keyUp(Event event, int key) {
    return(keyStroke("keyUp", event, key));
  }

  /** Separate regular keys from function keys. */
  
  protected boolean keyStroke(String type,
                              Event event, int key) {
    String description = ": " + type;
    if (event.id == Event.KEY_ACTION ||
        event.id == Event.KEY_ACTION_RELEASE)
      description = functionKeyName(key) + description;
    else
      description = keyName(key) + description;
    return(report(description, event.x, event.y));
  }

  /** Give name of function-key code. */
  
  protected String functionKeyName(int key) {
    switch(key) {
      case Event.DOWN: return("Down Arrow");
      case Event.END: return("END");
      case Event.F1: return("F1");
      case Event.F2: return("F2");
      case Event.F3: return("F3");
      case Event.F4: return("F4");
      case Event.F5: return("F5");
      case Event.F6: return("F6");
      case Event.F7: return("F7");
      case Event.F8: return("F8");
      case Event.F9: return("F9");
      case Event.HOME: return("HOME");
      case Event.LEFT: return("Left Arrow");
      case Event.PGDN: return("Page Down");
      case Event.PGUP: return("Page Up");
      case Event.RIGHT: return("Right Arrow");
      case Event.UP: return("Up Arrow");
      default: return("Unknown Function Key");
    }
  }

  /** Give name of normal-key code. */
  
  protected String keyName(int key) {
    switch(key) {
      case 8: return("BACKSPACE");
      case 9: return("TAB");
      case 10: return("LF");
      case 13: return("CR");
      case 27: return("ESCAPE");
      case 32: return("SPACE");
      case 127: return("DELETE");
    }
    if (key<33)
      return("Control-" +
             String.valueOf((char)(64+key)));
    else
      return(String.valueOf((char)key));
  }

  /** Report on event and return true. */
  
  protected boolean report(String methodName,
                           int x, int y) {
    String message = methodName + "("
                    + x + "," + y + ").\n";
    if (reportArea != null)
      reportArea.appendText(message);
    else
      System.out.print(message);
    return(true);
  }
}

