/************************************************}
{                                                }
{   JDK 1.1, 1.2, 1.3, 1.4                       }
{   Extensions graphiques compatibles QuickDraw  }
{   P.Chassignet, Ecole Polytechnique, 1998-2004 }
{                                                }
{   dernie`re mise a` jour:  30/4/03             }
{                                                }
{************************************************/

import java.awt.*;
import java.awt.peer.*;

/**
 * The class <code>MacLib</code> implements QuickDraw-like drawing and
 * event routines. 
 * It is mostly a static wrapper around a <code>GrafPort</code> object.
 *
 * @version  30 apr 2003
 * @author   Philippe Chassignet, Ecole Polytechnique
 * @see      GrafPort
 */
public class MacLib {

  /**
   * Used to specify the normal painting mode.
   *
   * @see      #penMode(int)
   */
  public static final int patCopy =  GrafPort.PAT_COPY;

  /**
   * Used to specify the XOR painting mode.
   *
   * @see      #penMode(int)
   */
  public static final int patXor  = GrafPort.PAT_XOR;

  /**
   * Used to specify one of the standard painting color.
   *
   * @see      #foreColor(int)
   * @see      #backColor(int)
   */
  public static final int blackColor = GrafPort.BLACK_COLOR;

  /**
   * Used to specify one of the standard painting color.
   *
   * @see      #foreColor(int)
   * @see      #backColor(int)
   */
  public static final int whiteColor = GrafPort.WHITE_COLOR;

  /**
   * Used to specify one of the standard painting color.
   *
   * @see      #foreColor(int)
   * @see      #backColor(int)
   */
  public static final int redColor = GrafPort.RED_COLOR;

  /**
   * Used to specify one of the standard painting color.
   *
   * @see      #foreColor(int)
   * @see      #backColor(int)
   */
  public static final int greenColor = GrafPort.GREEN_COLOR;

  /**
   * Used to specify one of the standard painting color.
   *
   * @see      #foreColor(int)
   * @see      #backColor(int)
   */
  public static final int blueColor = GrafPort.BLUE_COLOR;

  /**
   * Used to specify one of the standard painting color.
   *
   * @see      #foreColor(int)
   * @see      #backColor(int)
   */
  public static final int cyanColor = GrafPort.CYAN_COLOR;

  /**
   * Used to specify one of the standard painting color.
   *
   * @see      #foreColor(int)
   * @see      #backColor(int)
   */
  public static final int magentaColor = GrafPort.MAGENTA_COLOR;

  /**
   * Used to specify one of the standard painting color.
   *
   * @see      #foreColor(int)
   * @see      #backColor(int)
   */
  public static final int yellowColor = GrafPort.YELLOW_COLOR;

  /**
   * Used to specify one of the standard text font.
   *
   * @see      #textFont(String)
   */
  public static final String dialog        = GrafPort.DIALOG;

  /**
   * Used to specify one of the standard text font.
   *
   * @see      #textFont(String)
   */
  public static final String dialogInput   = GrafPort.DIALOG_INPUT;

  /**
   * Used to specify one of the standard text font.
   *
   * @see      #textFont(String)
   */
  public static final String sansSerif     = GrafPort.SANS_SERIF;

  /**
   * Used to specify one of the standard text font.
   *
   * @see      #textFont(String)
   */
  public static final String serif         = GrafPort.SERIF;

  /**
   * Used to specify one of the standard text font.
   *
   * @see      #textFont(String)
   */
  public static final String monospaced    = GrafPort.MONOSPACED;

  /**
   * Used to specify a text style.
   *
   * @see      #textFace(int)
   */
  public static final int plain	= GrafPort.PLAIN;

  /**
   * Used to specify a text style.
   *
   * @see      #textFace(int)
   */
  public static final int bold = GrafPort.BOLD;

  /**
   * Used to specify a text style.
   *
   * @see      #textFace(int)
   */
  public static final int italic = GrafPort.ITALIC;

  /**
   * Used to specify no modifier in the button state .
   *
   * @see      #buttonState()
   */
  public static final int none = GrafPort.NONE;

  /**
   * Used to encode the shift modifier in the button state.
   *
   * @see      #buttonState()
   */
  public static final int shift = GrafPort.SHIFT;

  /**
   * Used to encode the control modifier in the button state.
   *
   * @see      #buttonState()
   */
  public static final int control = GrafPort.CONTROL;

  /**
   * Used to encode the meta modifier in the button state.
   *
   * @see      #buttonState()
   */
  public static final int meta = GrafPort.META;

  /**
   * The seed value used by the <code>random()</code> generator. 
   * It is initialized to <code>1</code> and is reset by any call 
   * to <code>initQuickDraw</code>.
   * <p>
   * It may be set to a different value in order to start a different random 
   * sequence.
   *
   * @see         #random()
   * @see         #initQuickDraw
   */
  public static int randSeed = 1;
  
  /* interface with the DrawingFrame */
  private static GrafPort drawing = null;
  /* see below for class Dispatcher */
  private static Dispatcher dispatcher = null;

  /* interface with the external console */
  private static Frame text = null;

// procedural interface for Points

  /**
   * Sets the coordinates of the given point to the specified location.
   *
   * @param       p  the <code>Point</code> object to be modified
   * @param       h  the <em>h</em> coordinate of the new location
   * @param       v  the <em>v</em> coordinate of the new location
   */
  public static void setPt(Point p, int h, int v) {
    p.setPt(h, v);
  }
  /**
   * @see      #setPt(Point, int, int)
   */
  public static void SetPt(Point p, int h, int v) {
    setPt(p, h, v);
  }

  /**
   * Translates the second given point by the displacement vector specified 
   * as the first given point.
   * Adds the coordinates of point <code>src</code> 
   * to the coordinates of point <code>dst</code>.
   *
   * @param       src  the <code>Point</code> object used as a vector to 
   *                   specify the displacement
   * @param       dst  the <code>Point</code> object to be modified
   */
  public static void addPt(Point src, Point dst) {
    dst.addPt(src);
  }
  /**
   * @see      #addPt(Point, Point)
   */
  public static void AddPt(Point src, Point dst) {
    addPt(src, dst);
  }

  /**
   * Translates the second given point by the displacement vector specified 
   * as the inverse of the first given point.
   * Subtracts the coordinates of point <code>src</code> 
   * from the coordinates of point <code>dst</code>.
   *
   * @param       src  the <code>Point</code> object used as a vector to 
   *                   specify the displacement
   * @param       dst  the <code>Point</code> object to be modified
   */
  public static void subPt(Point src, Point dst) {
    dst.subPt(src);
  }
  /**
   * @see      #subPt(Point, Point)
   */
  public static void SubPt(Point src, Point dst) {
    subPt(src, dst);
  }

  /**
   * Determines whether the two given points have the same coordinates.
   *
   * @param       p1  the first <code>Point</code> object
   * @param       p2  the second <code>Point</code> object to compare with
   * @return      <code>true</code> if both points have same coordinates; 
   *              <code>false</code> otherwise
   */
  public static boolean equalPt(Point p1, Point p2) {
    return p1.equalPt(p2);
  }
  /**
   * @see      #equalPt(Point, Point)
   */
  public static boolean EqualPt(Point p1, Point p2) {
    return equalPt(p1, p2);
  }

// Points array allocation

  /**
   * Allocates an new array of also allocated Point objects, which is useful 
   * for specifying polygonal shapes. 
   *
   * @param       pCount  the number of wanted <code>Point</code> objects
   * @return      an new array of <code>pCount</code> new <code>Point</code> 
   *                objects
   * @see         #framePolygon(Point[], int)
   * @see         #paintPolygon(Point[], int)
   * @see         #erasePolygon(Point[], int)
   * @see         #invertPolygon(Point[], int)
   */
  public static Point[] newPointArray(int pCount) {
    Point[] points = new Point[pCount];
    for (int i = 0; i < pCount; i++)
      points[i] = new Point();
    return points;
  }

// procedural interface for Rects

  /**
   * Sets the coordinates of the given rectangle as specified.
   *
   * @param       r       the <code>Rect</code> object to be modified
   * @param       left    the new <em>left</em> coordinate
   * @param       top     the new <em>top</em> coordinate
   * @param       right   the new <em>right</em> coordinate
   * @param       bottom  the new <em>bottom</em> coordinate
   */
  public static void setRect(Rect r, int left, int top, int right, int bottom) {
    r.setRect(left, top, right, bottom);
  }
  /**
   * @see      #setRect(Rect, int, int, int, int)
   */
  public static void SetRect(Rect r, int left, int top, int right, int bottom) {
    setRect(r, left, top, right, bottom);
  }

  /**
   * Sets the coordinates of the given rectangle to the smallest one which 
   * encloses the two given points.
   *
   * @param       p1   the first <code>Point</code> object used to specify 
   *                   the coordinates
   * @param       p2   the second <code>Point</code> object used to specify 
   *                   the coordinates
   * @param       dst  the <code>Rect</code> object to be modified
   */
  public static void pt2Rect(Point p1, Point p2, Rect dst) {
    dst.pt2Rect(p1, p2);
  }
  /**
   * @see      #pt2Rect(Point, Point, Rect)
   */
  public static void Pt2Rect(Point p1, Point p2, Rect dst) {
    pt2Rect(p1, p2, dst);
  }

  /**
   * Translates the given rectangle by the specified displacement.
   * Adds <code>dh</code> to each horizontal coordinate and <code>dv</code> 
   * to each vertical coordinate.
   *
   * @param       r   the <code>Rect</code> object to be modified
   * @param       dh  the horizontal displacement
   * @param       dv  the vertical displacement
   */
  public static void offsetRect(Rect r, int dh, int dv) {
    r.offsetRect(dh, dv);
  }
  /**
   * @see      #offsetRect(Rect, int, int)
   */
  public static void OffsetRect(Rect r, int dh, int dv) {
    offsetRect(r, dh, dv);
  }

  /**
   * Shrinks or expands the given rectangle by the specified amounts.
   * Adds <code>dh</code> to the left coordinate and 
   * subtracts <code>dh</code> from the right coordinate.
   * Adds <code>dv</code> to the top coordinate and 
   * subtracts <code>dv</code> from the bottom coordinate.
   *
   * @param       r   the <code>Rect</code> object to be modified
   * @param       dh  the horizontal displacement
   * @param       dv  the vertical displacement
   */
  public static void insetRect(Rect r, int dh, int dv) {
    r.insetRect(dh, dv);
  }
  /**
   * @see      #insetRect(Rect, int, int)
   */
  public static void InsetRect(Rect r, int dh, int dv) {
    insetRect(r, dh, dv);
  }

  /**
   * Sets the coordinates of the third given rectangle to the smallest one 
   * which encloses the two first given rectangles.
   *
   * @param       src1  the first <code>Rect</code> object used to specify the 
   *                    coordinates
   * @param       src2  the second <code>Rect</code> object used to specify the 
   *                    coordinates
   * @param       dst   the <code>Rect</code> object to be modified
   */
  public static void unionRect(Rect src1, Rect src2, Rect dst) {
    dst.unionRect(src1, src2);
  }
  /**
   * @see      #unionRect(Rect, Rect, Rect)
   */
  public static void UnionRect(Rect src1, Rect src2, Rect dst) {
    unionRect(src1, src2, dst);
  }

  /**
   * Determines whether the two given rectangles have the same 
   * coordinates.
   *
   * @param       r1  the first <code>Rect</code> object
   * @param       r2  the second <code>Rect</code> object to compare with
   * @return      <code>true</code> if both rectangles have same coordinates; 
   *              <code>false</code> otherwise
   */
  public static boolean equalRect(Rect r1, Rect r2) {
    return r1.equalRect(r2);
  }
  /**
   * @see      #equalRect(Rect, Rect)
   */
  public static boolean EqualRect(Rect r1, Rect r2) {
    return EqualRect(r1, r2);
  }

  /**
   * Sets the coordinates of the third given rectangle to the rectangle 
   * that is the intersection of the two first given rectangles.
   * Determines also whether they indeed intersect. Rectangles that "touch" 
   * at a line or a point are not considered intersecting.
   * If the rectangles do not intersect, the third rectangle is set to 
   * <code>(0,0,0,0)</code>.
   *
   * @param       src1  the first <code>Rect</code> object used to specify the 
   *                    coordinates
   * @param       src2  the second <code>Rect</code> object used to specify the 
   *                    coordinates
   * @param       dst   the <code>Rect</code> object to be modified
   * @return      <code>true</code> if the two rectangles really intersect;
   *              <code>false</code> otherwise
   */
  public static boolean sectRect(Rect src1, Rect src2, Rect dst) {
    return dst.sectRect(src1, src2);
  }
  /**
   * @see      #sectRect(Rect, Rect, Rect)
   */
  public static boolean SectRect(Rect src1, Rect src2, Rect dst) {
    return sectRect(src1, src2, dst);
  }

  /**
   * Determines whether the pixel below and to the right of the given point 
   * is enclosed in the given rectangle.
   *
   * @param       pt  the <code>Point</code> object
   * @param       r   the <code>Rect</code> object to check with
   * @return      <code>true</code> if so; <code>false</code> otherwise
   */
  public static boolean ptInRect(Point pt, Rect r) {
    return r.ptInRect(pt);
  }
  /**
   * @see      #ptInRect(Point, Rect)
   */
  public static boolean PtInRect(Point pt, Rect r) {
    return PtInRect(pt, r);
  }

  /**
   * Determines whether the given rectangle is empty or not.
   * A rectangle is considered empty if the bottom coordinate is equal to 
   * or less than the top or the right coordinate is equal to or less 
   * than the left.
   *
   * @param       r  the <code>Rect</code> object
   * @return      <code>true</code> if so; <code>false</code> otherwise
   */
  public static boolean emptyRect(Rect r) {
    return r.emptyRect();
  }
  /**
   * @see      #emptyRect(Rect)
   */
  public static boolean EmptyRect(Rect r) {
    return emptyRect(r);
  }

// Init

  /**
   * Does nothing, MacLib is intented for static use.
   */
  MacLib() { System.err.println("new MacLib() !"); }

  /**
   * Initializes a MacLib session or reset the existing one.
   *
   * @see      #initQuickDraw(GrafPort)
   */
  public static void initQuickDraw() {
    if ( drawing == null )
      drawing = new GrafPort();
    else
      drawing.reset();
    randSeed = 1;
  }
  /**
   * @see      #initQuickDraw()
   */
  public static void InitQuickDraw() {
    initQuickDraw();
  }

  /**
   * Initializes or reset a MacLib session with the given GrafPort.
   *
   * @param    port  a <code>GrafPort</code> object
   * @see      #initQuickDraw()
   */
  public static void initQuickDraw(GrafPort port) {
    drawing = port;
    initQuickDraw();
  }

  /**
   * Launchs a concurrent thread for events dispatching in order to prevent 
   * dead-lock when the AWT EventDispatchThread is calling any of MacLib 
   * event routines.
   */

  /*
    It should be something like:
    
    EventDispatchThread dt = null;
    if ( Thread.currentThread() instanceof EventDispatchThread ) {
	  dt = new EventDispatchThread("AWT-Dispatch-Proxy", Toolkit.getEventQueue());
      dt.start();
    }
    
    as for modal dialog, but EventDispatchThread is private to java.awt.
  */
  /* see below for class Dispatcher */
  private synchronized static void checkEventDispatcher() {
    if ( Thread.currentThread().getName().indexOf("AWT") >= 0 )
      if ( dispatcher == null ) {
        dispatcher = new Dispatcher();
        dispatcher.start();
      }
  }

  /**
   * Disposes of the <code>GrafPort</code> and associated objects.
   */
  public synchronized static void dispose() {
    if ( dispatcher != null ) {
      dispatcher.running = false;
      dispatcher.interrupt();
      dispatcher = null;
    }
    drawing.dispose();
    drawing = null;
    text = null;
  }

// Windows

  /**
   * Defines the given <code>GrafPort</code> as the current Drawing window, 
   * but doesn't reset it.
   *
   * @param    port  a <code>GrafPort</code> object
   * @see      #initQuickDraw(GrafPort)
   * @see      #getPort()
   */
  public static void setPort(GrafPort port) {
    drawing = port;
  }
  /**
   * @see         #setPort(GrafPort)
   */
  public static void SetPort(GrafPort port) {
    drawing = port;
  }

  /**
   * Returns the <code>GrafPort</code> for the current Drawing window.
   *
   * @return      the <code>GrafPort</code> object
   * @see         #setPort(GrafPort)
   */
  public static GrafPort getPort() {
    return drawing;
  }
  /**
   * @see         #getPort()
   */
  public static GrafPort GetPort() {
    return drawing;
  }

  /**
   * Defines the given external frame as the current Text window.
   *
   * @param       frame  a Frame object
   */
  public static void setText(Frame frame) {
    text = frame;
  }

  /**
   * Sets the bounds of the Drawing window.
   *
   * @param       r  a <code>Rect</code> object that specifies the new 
   *                 screen coordinates
   */
  public static void setDrawingRect(Rect r) {
    drawing.setDrawingRect(r);
  }
  /**
   * @see         #setDrawingRect(Rect)
   */
  public static void SetDrawingRect(Rect r) {
    drawing.setDrawingRect(r);
  }

  /**
   * Sets the bounds of the Text window.
   *
   * @param       r  a <code>Rect</code> object that specifies the new 
   *                 screen coordinates
   */
  public static void setTextRect(Rect r) {
    if ( text != null ) {
      Insets in = text.getInsets();
      text.setBounds(r.left - in.left, r.top - in.top, 
                     r.right - r.left + in.left + in.right, 
                     r.bottom - r.top + in.bottom + in.top);
      text.validate();
    }
  }
  /**
   * @see         #setTextRect(Rect)
   */
  public static void SetTextRect(Rect r) {
    setTextRect(r);
  }


  /**
   * Gets the bounds of the Drawing window.
   *
   * @param       r  a <code>Rect</code> object filled with the screen 
   *                 coordinates
   */
  public static void getDrawingRect(Rect r) {
    r.setRect(drawing.getDrawingRect());
  }
  /**
   * @see         #getDrawingRect(Rect)
   */
  public static void GetDrawingRect(Rect r) {
    r.setRect(drawing.getDrawingRect());
  }

  /**
   * Gets the bounds of the Text window.
   *
   * @param       r  a <code>Rect</code> object filled with the screen 
   *                 coordinates
   */
  public static void getTextRect(Rect r) {
    if ( text != null ) {
      Rectangle b = text.getBounds();
      Insets in = text.getInsets();
      r.setRect(b.x + in.left, b.y + in.top, 
                b.x + b.width - in.right, 
                b.y + b.height - in.bottom);
    }
  }
  /**
   * @see         #getTextRect(Rect)
   */
  public static void GetTextRect(Rect r) {
    getTextRect(r);
  }

  /**
   * Makes the Drawing window visible and brings it to the front.
   */
  public static void showDrawing() {
    drawing.showDrawing();
  }
  /**
   * @see         #showDrawing()
   */
  public static void ShowDrawing() {
    drawing.showDrawing();
  }

  /**
   * Makes the Text window visible and brings it to the front.
   */
  public static void showText() {
    if ( text != null )
      text.setVisible(true);
  }
  /**
   * @see         #showText()
   */
  public static void ShowText() {
    showText();
  }

  /**
   * Hides both the Drawing and Text windows.
   */
  public static void hideAll() {
    drawing.hideDrawing();
    if ( text != null )
      text.setVisible(false);
  }
  /**
   * @see         #hideAll()
   */
  public static void HideAll() {
    hideAll();
  }

// Mouse

  /**
   * Returns the state of the mouse button.
   *
   * @return      <code>true</code> if the button is currently down after 
   *                being pressed in the Drawing window;
   *              <code>false</code> otherwise
   */
  public static boolean button() {
    return drawing.button();
  }
  /**
   * @see         #button()
   */
  public static boolean Button() {
    return drawing.button();
  }

  /**
   * Waits until the mouse button is pressed in the Drawing window.
   */
  public static void waitClickDown() {
    drawing.waitClickDown();
  }
  /**
   * @see         #waitClickDown()
   */
  public static void WaitClickDown() {
    drawing.waitClickDown();
  }

  /**
   * Waits until the mouse button is released after being pressed in the 
   * Drawing window.
   */
  public static void waitClickUp() {
    drawing.waitClickUp();
  }
  /**
   * @see         #waitClickUp()
   */
  public static void WaitClickUp() {
    drawing.waitClickUp();
  }

  /**
   * Stores the current mouse location (relative to the Drawing window) in 
   * the given <code>Point</code>Point object.
   *
   * @param       p  the <code>Point</code> object to be modified
   */
  public static void getMouse(Point p) {
    p.setPt(drawing.getMouse());
  }
  /**
   * @see         #getMouse(Point)
   */
  public static void GetMouse(Point p) {
    p.setPt(drawing.getMouse());
  }

  /**
   * Waits until the mouse button is pressed and then released in the Drawing 
   * window.
   * Stores the mouse location (relative to the Drawing window) at the 
   * release time in the given point.
   *
   * @param       p  the <code>Point</code> object to be modified
   */
  public static void getClick(Point p) {
    p.setPt(drawing.getClick());
  }
  /**
   * @see         #getClick(Point)
   */
  public static void GetClick(Point p) {
    p.setPt(drawing.getClick());
  }

  /**
   * Waits until the mouse button is released, after being pressed, or until 
   * the mouse location is dragged.
   * Stores the issued mouse location (relative to the Drawing window) in 
   * the given point.
   *
   * @param       p  the <code>Point</code> object to be modified
   */
  public static boolean trackMouse(Point p) {
    return drawing.trackMouse(p);
  }
  /**
   * @see         #trackMouse(Point)
   */
  public static boolean TrackMouse(Point p) {
    return drawing.trackMouse(p);
  }

  
  /**
   * Returns the <code>int</code> value that describes the modifier keys state 
   * at the time of the last mouse pressed event.
   * The returned value is either <code>none</code>, or a combination of 
   * the <code>shift</code>, <code>control</code> and <code>meta</code> 
   * (for the <em>Alt</em> key) constant flags.
   *
   * @return      the modifier keys state as an <code>int</code> value
   * @see         #none
   * @see         #shift
   * @see         #control
   * @see         #meta
   */
  public static int buttonState() {
    return drawing.buttonState();
  }
  /**
   * @see         #buttonState()
   */
  public static int ButtonState() {
    return drawing.buttonState();
  }

// KeyBoard

  /**
   * Checks whether the char, corresponding to the last keyboard event 
   * occured in the Drawing window, is still available.
   *
   * @return      <code>true</code> if any char available; 
   *              <code>false</code> otherwise
   */
  public static boolean keyPressed() {
    return drawing.keyPressed();
  }
  /**
   * @see         #keyPressed()
   */
  public static boolean KeyPressed() {
    return drawing.keyPressed();
  }
  
  /**
   * Returns the char corresponding to the last keyboard event in the 
   * Drawing window.
   * If no char is available, will block until a new keyboard event occurs.
   * The char is made unavailable for further calls.
   *
   * @return      the last key char
   */
  public static char getKey() {
    return drawing.getKey();
  }
  /**
   * @see         #getKey()
   */
  public static char GetKey() {
    return drawing.getKey();
  }

// Drawing context

  /**
   * Sets the current transfer mode, used for drawing lines and 
   * painting shapes, to be one of the two constant flags 
   * <code>patCopy</code> or <code>patXor</code>.
   * <p>
   * The initial pen mode is <code>patCopy</code>.
   *
   * @param       mode  the specified painting mode
   * @see         #patCopy
   * @see         #patXor
   */
  public static void penMode(int mode) {
    drawing.penMode(mode);
  }
  /**
   * @see         #penMode(int)
   */
  public static void PenMode(int mode) {
    drawing.penMode(mode);
  }

  /**
   * Sets the dimensions of the rectangular pen, used for drawing lines 
   * and framed shapes.
   * <p>
   * The initial pen size is <code>1x1</code>.
   *
   * @param       width    the new width for the pen
   * @param       height   the new height for the pen
   */
  public static void penSize(int width, int height) {
    drawing.penSize(width, height);
  }
  /**
   * @see         #penSize(int, int)
   */
  public static void PenSize(int width, int height) {
    drawing.penSize(width, height);
  }

  /**
   * Resets the initial state (mode and size) of the pen.
   * The pen location is not changed.
   *
   * @see         #penMode(int)
   * @see         #penSize(int, int)
   */
  public static void penNormal() {
    drawing.penNormal();
  }
  /**
   * @see         #penNormal()
   */
  public static void PenNormal() {
    drawing.penNormal();
  }

  /**
   * Sets the current pen color, used for drawing lines or text and painting 
   * shapes, as specified by the given <code>java.awt.Color</code> object.
   * <p>
   * The initial pen color is as specified by 
   * <code>java.awt.Color.black</code>.
   *
   * @param       color  the <code>Color</code> object
   */
  public static void foreColor(Color color) {
    drawing.foreColor(color);
  }

  /**
   * Sets the current pen color, used for drawing lines or text and painting 
   * shapes, as specified by one of the height constant flags :
   *    <code>blackColor</code>,
   *    <code>whiteColor</code>,
   *    <code>redColor</code>,
   *    <code>greenColor</code>,
   *    <code>blueColor</code>,
   *    <code>cyanColor</code>,
   *    <code>magentaColor</code> or
   *    <code>yellowColor</code>.
   * <p>
   * The initial pen color is as specified by <code>blackColor</code>.
   *
   * @param       color  the specified color flag
   * @see         #blackColor
   * @see         #whiteColor
   * @see         #redColor
   * @see         #greenColor
   * @see         #blueColor
   * @see         #cyanColor
   * @see         #magentaColor
   * @see         #yellowColor
   */
  public static void foreColor(int color) {
    drawing.foreColor(color);
  }
  /**
   * @see         #foreColor(int)
   */
  public static void ForeColor(int color) {
    drawing.foreColor(color);
  }
  
  /**
   * Sets the current pen color, used for drawing lines or text and painting 
   * shapes, as specified by the given <code>RGBColor</code> object.
   * <p>
   * The initial pen color is as specified by 
   * <code>new RGBColor(0,0,0)</code>.
   *
   * @param       color  the <code>RGBColor</code> object
   * @see         #foreColor(java.awt.Color)
   */
  public static void RGBForeColor(RGBColor color) {
    drawing.foreColor(color.getColor());
  }

  /**
   * Sets the current background color, used when erasing or inverting, 
   * as specified by the given <code>java.awt.Color</code> object.
   * <p>
   * The initial background color is as specified by 
   * <code>java.awt.Color.white</code>.
   *
   * @param       color  the <code>Color</code> object
   */
  public static void backColor(Color color) {
    drawing.backColor(color);
  }

  /**
   * Sets the current background color, used when erasing or inverting, 
   * as specified by one of the height constant flags :
   *    <code>blackColor</code>,
   *    <code>whiteColor</code>,
   *    <code>redColor</code>,
   *    <code>greenColor</code>,
   *    <code>blueColor</code>,
   *    <code>cyanColor</code>,
   *    <code>magentaColor</code> or
   *    <code>yellowColor</code>.
   * <p>
   * The initial background color is as specified by 
   * <code>whiteColor</code>.
   *
   * @param       color  the specified color flag
   * @see         #blackColor
   * @see         #whiteColor
   * @see         #redColor
   * @see         #greenColor
   * @see         #blueColor
   * @see         #cyanColor
   * @see         #magentaColor
   * @see         #yellowColor
   */
  public static void backColor(int color) {
    drawing.backColor(color);
  }
  /**
   * @see         #backColor(int)
   */
  public static void BackColor(int color) {
    drawing.backColor(color);
  }
  
  /**
   * Sets the current background color, used when erasing or inverting, 
   * as specified by the given <code>RGBColor</code> object.
   * <p>
   * The initial background color is as specified by 
   * <code>new RGBColor(255,255,255)</code>.
   *
   * @param       color  the <code>RGBColor</code> object
   * @see         #backColor(java.awt.Color)
   */
  public static void RGBBackColor(RGBColor color) {
    drawing.backColor(color.getColor());
  }

  /**
   * Stores the current pen location (relative to the Drawing window) in 
   * the given point.
   *
   * @param       p  the <code>Point</code> object to be modified
   */
  public static void getPen(Point p) {
    p.setPt(drawing.getPen());
  }
  /**
   * @see         #getPen(Point)
   */
  public static void GetPen(Point p) {
    p.setPt(drawing.getPen());
  }

  /**
   * Sets the coordinates of the pen (relative to the Drawing window) to the 
   * specified location.
   * <p>
   * No drawing is performed.
   *
   * @param       h  the horizontal coordinate of the new location
   * @param       v  the vertical coordinate of the new location
   */
  public static void moveTo(int h, int v) {
    drawing.moveTo(h, v);
  }
  /**
   * @see         #moveTo(int, int)
   */
  public static void MoveTo(int h, int v) {
    drawing.moveTo(h, v);
  }

  /**
   * Translates the coordinates of the pen by the specified displacement 
   * vector.
   * <p>
   * No drawing is performed.
   *
   * @param       dh  the horizontal displacement
   * @param       dv  the vertical displacement
   */
  public static void move(int dh, int dv) {
    drawing.move(dh, dv);
  }
  /**
   * @see         #move(int, int)
   */
  public static void Move(int dh, int dv) {
    drawing.move(dh, dv);
  }

  /**
   * Sets the name of the font used for drawing text. 
   * Some supported fonts are given by the followings constants :
   *    <code>dialog</code>,
   *    <code>dialogInput</code>,
   *    <code>sansSerif</code>,
   *    <code>serif</code> or
   *    <code>monospaced</code>.
   * <p>
   * The initial text font is as specified by <code>serif</code>.
   *
   * @param       the name of the new font used for drawing text
   * @see         #dialog
   * @see         #dialogInput
   * @see         #sansSerif
   * @see         #serif
   * @see         #monospaced
   */
  public void textFont(String name) {
    drawing.textFont(name);
  }
  /**
   * @see         #textFont(java.lang.String)
   */
  public void TextFont(String name) {
    drawing.textFont(name);
  }

  /**
   * Sets the size of the font used for drawing text. 
   * <p>
   * The initial text size is <code>12</code>.
   *
   * @param       the new size for drawing text
   */
  public void textSize(int size) {
    drawing.textSize(size);
  }
  /**
   * @see         #textSize(int)
   */
  public void TextSize(int size) {
    drawing.textSize(size);
  }

  /**
   * Sets the style of the font used for drawing text, 
   * it should be one of the followings constants :
   *    <code>plain</code>,
   *    <code>bold</code>,
   *    <code>italic</code> or
   *    <code>bold+italic</code>.
   * <p>
   * The initial text style is as specified by <code>plain</code>.
   *
   * @param       the code of the new style for drawing text
   * @see         #plain
   * @see         #bold
   * @see         #italic
   */
  public void textFace(int face) {
    drawing.textFace(face);
  }
  /**
   * @see         #textFace(int)
   */
  public void TextFace(int face) {
    drawing.textFace(face);
  }

  /**
   * Returns the metric informations about the current font as a 
   * <code>FontInfo</code> object.
   *
   * @return      the <code>FontInfo</code> object
   */
  public FontInfo getFontInfo() {
    return drawing.getFontInfo();
  }
  /**
   * @see         #getFontInfo()
   */
  public FontInfo GetFontInfo() {
    return drawing.getFontInfo();
  }

// Drawing lines

  /**
   * Draws a line from the current pen location to the location that is 
   * at distance of dh horizontally and dv vertically.
   * The pen location becomes this new location.
   *
   * @param       dh  the horizontal displacement
   * @param       dv  the vertical displacement
   * @see         #penMode(int)
   * @see         #penSize(int, int)
   * @see         #foreColor(java.awt.Color)
   */
  public static void line(int dh, int dv) {
    drawing.line(dh, dv);
  }
  /**
   * @see         #line(int, int)
   */
  public static void Line(int dh, int dv) {
    drawing.line(dh, dv);
  }

  /**
   * Draws a line from the current pen location to the location that is 
   * specified by h and v (in coordinates relative to the Drawing window).
   * The pen location becomes this new location.
   *
   * @param       h  the horizontal coordinate of the new location
   * @param       v  the vertical coordinate of the new location
   * @see         #penMode(int)
   * @see         #penSize(int, int)
   * @see         #foreColor(java.awt.Color)
   */
  public static void lineTo(int h, int v) {
    drawing.lineTo(h, v);
  }
  /**
   * @see         #lineTo(int, int)
   */
  public static void LineTo(int h, int v) {
    drawing.lineTo(h, v);
  }

  /**
   * Draws a line from the location that is specified by x1 and y1 to 
   * the location that is specified by x2 and y2 (in coordinates relative 
   * to the Drawing window).
   * The pen location becomes the second location.
   *
   * @param       x1  the horizontal coordinate of the first location
   * @param       y1  the vertical coordinate of the first location
   * @param       x2  the horizontal coordinate of the second location
   * @param       y2  the vertical coordinate of the second location
   * @see         #penMode(int)
   * @see         #penSize(int, int)
   * @see         #foreColor(java.awt.Color)
   */
  public static void drawLine(int x1, int y1, int x2, int y2) {
    drawing.drawLine(x1, y1, x2, y2);
  }
  /**
   * @see         #drawLine(int, int, int, int)
   */
  public static void DrawLine(int x1, int y1, int x2, int y2) {
    drawing.drawLine(x1, y1, x2, y2);
  }

// Shapes
  
  /**
   * Draws an outline just inside the specified rectangle.
   * The pen location is not changed.
   *
   * @param       r  a <code>Rect</code> object that specifies 
   *                 the rectangle to be framed
   * @see         #penMode(int)
   * @see         #penSize(int, int)
   * @see         #foreColor(java.awt.Color)
   */
  public static void frameRect(Rect r) {
    drawing.frameRect(r);
  }
  /**
   * @see         #frameRect(Rect)
   */
  public static void FrameRect(Rect r) {
    drawing.frameRect(r);
  }
  
  /**
   * Paints inside the specified rectangle.
   *
   * @param       r  a <code>Rect</code> object that specifies 
   *                 the rectangle to be painted
   * @see         #penMode(int)
   * @see         #foreColor(java.awt.Color)
   */
  public static void paintRect(Rect r) {
    drawing.paintRect(r);
  }
  /**
   * @see         #paintRect(Rect)
   */
  public static void PaintRect(Rect r){
    drawing.paintRect(r);
  }

  /**
   * Paints inside the specified rectangle, using the background color.
   *
   * @param       r  a <code>Rect</code> object that specifies 
   *                 the rectangle to be erased
   * @see         #backColor(java.awt.Color)
   */
  public static void eraseRect(Rect r) {
    drawing.eraseRect(r); 
  }
  /**
   * @see         #eraseRect(Rect)
   */
  public static void EraseRect(Rect r) {
    drawing.eraseRect(r); 
  }

  /**
   * Inverts pixels inside the specified rectangle.
   * Every white pixel becomes black and reciprocally.
   * Pixels of other colors are changed in an undefined but reversible 
   * manner.
   *
   * @param       r  a <code>Rect</code> object that specifies 
   *                 the rectangle to be inverted
   */
  public static void invertRect(Rect r) {
    drawing.invertRect(r); 
  }
  /**
   * @see         #invertRect(Rect)
   */
  public static void InvertRect(Rect r) {
    drawing.invertRect(r); 
  }

  /**
   * Draws an outline just inside the oval that fits inside the 
   * specified rectangle.
   * The pen location is not changed.
   *
   * @param       r  a <code>Rect</code> object that specifies 
   *                 the oval to be framed
   * @see         #penMode(int)
   * @see         #penSize(int, int)
   * @see         #foreColor(java.awt.Color)
   */
  public static void frameOval(Rect r) {
    drawing.frameOval(r);
  }
  /**
   * @see         #frameOval(Rect)
   */
  public static void FrameOval(Rect r) {
    drawing.frameOval(r);
  }
  
  /**
   * Paints inside the oval that fits inside the specified rectangle.
   *
   * @param       r  a <code>Rect</code> object that specifies 
   *                 the oval to be painted
   * @see         #penMode(int)
   * @see         #foreColor(java.awt.Color)
   */
  public static void paintOval(Rect r) {
    drawing.paintOval(r);
  }
  /**
   * @see         #paintOval(Rect)
   */
  public static void PaintOval(Rect r) {
    drawing.paintOval(r);
  }

  /**
   * Paints inside the oval that fits inside the specified rectangle, 
   * using the background color.
   *
   * @param       r  a <code>Rect</code> object that specifies 
   *                 the oval to be erased
   * @see         #backColor(java.awt.Color)
   */
  public static void eraseOval(Rect r) {
    drawing.eraseOval(r); 
  }
  /**
   * @see         #eraseOval(Rect)
   */
  public static void EraseOval(Rect r) {
    drawing.eraseOval(r); 
  }

  /**
   * Inverts pixels inside the oval that fits inside the specified rectangle.
   * Every white pixel becomes black and reciprocally.
   * Pixels of other colors are changed in an undefined but reversible 
   * manner.
   *
   * @param       r  a <code>Rect</code> object that specifies 
   *                 the oval to be inverted
   */
  public static void invertOval(Rect r) {
    drawing.invertOval(r); 
  }
  /**
   * @see         #invertOval(Rect)
   */
  public static void InvertOval(Rect r) {
    drawing.invertOval(r); 
  }

  /**
   * Paints inside the specified circle.
   *
   * @param       x  the <em>x</em> coordinate of the center of the circle
   * @param       y  the <em>y</em> coordinate of the center of the circle
   * @param       r  the radius of the circle
   * @see         #penMode(int)
   * @see         #foreColor(java.awt.Color)
   */
  public static void paintCircle(int x, int y, int r) {
    drawing.paintCircle(x, y, r);
  }
  /**
   * @see         #paintCircle(int, int, int)
   */
  public static void PaintCircle(int x, int y, int r) {
    drawing.paintCircle(x, y, r);
  }

  /**
   * Inverts pixels inside the specified circle.
   * Every white pixel becomes black and reciprocally.
   * Pixels of other colors are changed in an undefined but reversible 
   * manner.
   *
   * @param       x  the <em>x</em> coordinate of the center of the circle
   * @param       y  the <em>y</em> coordinate of the center of the circle
   * @param       r  the radius of the circle
   */
  public static void invertCircle(int x, int y, int r) {
    drawing.invertCircle(x, y, r);
  }
  /**
   * @see         #invertCircle(int, int, int)
   */
  public static void InvertCircle(int x, int y, int r) {
    drawing.invertCircle(x, y, r);
  }

  /**
   * Draws an outline just inside the specified rounded-corner rectangle.
   * The pen location is not changed.
   *
   * @param       r          a <code>Rect</code> object that specifies 
   *                         the shape to be framed
   * @param       arcWidth   the horizontal diameter of curvature for the 
                             corners arcs
   * @param       arcHeight  the vertical diameter of curvature for the 
                             corners arcs
   * @see         #penMode(int)
   * @see         #penSize(int, int)
   * @see         #foreColor(java.awt.Color)
   */
  public static void frameRoundRect(Rect r, int arcWidth, int arcHeight) {
    drawing.frameRoundRect(r, arcWidth, arcHeight);
  }
  /**
   * @see         #frameRoundRect(Rect, int, int)
   */
  public static void FrameRoundRect(Rect r, int arcWidth, int arcHeight) {
    drawing.frameRoundRect(r, arcWidth, arcHeight);
  }

  /**
   * Paints inside the specified rounded-corner rectangle.
   *
   * @param       r          a <code>Rect</code> object that specifies 
   *                         the shape to be painted
   * @param       arcWidth   the horizontal diameter of curvature for the 
                             corners arcs
   * @param       arcHeight  the vertical diameter of curvature for the 
                             corners arcs
   * @see         #penMode(int)
   * @see         #foreColor(java.awt.Color)
   */
  public static void paintRoundRect(Rect r, int arcWidth, int arcHeight) {
    drawing.paintRoundRect(r, arcWidth, arcHeight);
  }
  /**
   * @see         #paintRoundRect(Rect, int, int)
   */
  public static void PaintRoundRect(Rect r, int arcWidth, int arcHeight) {
    drawing.paintRoundRect(r, arcWidth, arcHeight);
  }

  /**
   * Paints inside the specified rounded-corner rectangle, 
   * using the background color.
   *
   * @param       r          a <code>Rect</code> object that specifies 
   *                         the shape to be erased
   * @param       arcWidth   the horizontal diameter of curvature for the 
                             corners arcs
   * @param       arcHeight  the vertical diameter of curvature for the 
                             corners arcs
   * @see         #backColor(java.awt.Color)
   */
  public static void eraseRoundRect(Rect r, int arcWidth, int arcHeight) {
    drawing.eraseRoundRect(r, arcWidth, arcHeight);
  }
  /**
   * @see         #eraseRoundRect(Rect, int, int)
   */
  public static void EraseRoundRect(Rect r, int arcWidth, int arcHeight) {
    drawing.eraseRoundRect(r, arcWidth, arcHeight);
  }

  /**
   * Inverts pixels inside the specified rounded-corner rectangle.
   * Every white pixel becomes black and reciprocally.
   * Pixels of other colors are changed in an undefined but reversible 
   * manner.
   *
   * @param       r          a <code>Rect</code> object that specifies 
   *                         the shape to be inverted
   * @param       arcWidth   the horizontal diameter of curvature for the 
                             corners arcs
   * @param       arcHeight  the vertical diameter of curvature for the 
                             corners arcs
   */
  public static void invertRoundRect(Rect r, int arcWidth, int arcHeight) {
    drawing.invertRoundRect(r, arcWidth, arcHeight);
  }
  /**
   * @see         #invertRoundRect(Rect, int, int)
   */
  public static void InvertRoundRect(Rect r, int arcWidth, int arcHeight) {
    drawing.invertRoundRect(r, arcWidth, arcHeight);
  }

  /**
   * Draws an arc of outline just inside the oval that fits inside the 
   * specified rectangle.
   * The startAngle parameter indicates where the arc begins and is 
   * treated mod 360.
   * The arcAngle parameters defines the extent of the arc.
   * The angles are given in degrees. A positive angle goes clockwise.
   * Zero degree is at l2 o'clock.
   * The pen location is not changed.
   *
   * @param       r           a <code>Rect</code> object that specifies 
   *                          the shape to be framed
   * @param       startAngle  indicates where the arc begins
   * @param       arcAngle    defines the extent of the arc
   * @see         #penMode(int)
   * @see         #penSize(int, int)
   * @see         #foreColor(java.awt.Color)
   */
  public static void frameArc(Rect r, int startAngle, int arcAngle) {
    drawing.frameArc(r, startAngle, arcAngle);
  }
  /**
   * @see         #frameArc(Rect, int, int)
   */
  public static void FrameArc(Rect r, int startAngle, int arcAngle) {
    drawing.frameArc(r, startAngle, arcAngle);
  }

  /**
   * Paints inside a wedge of the oval that fits inside the specified 
   * rectangle.
   * The startAngle parameter indicates where the arc begins and is 
   * treated mod 360.
   * The arcAngle parameters defines the extent of the arc.
   * The angles are given in degrees. A positive angle goes clockwise.
   * Zero degree is at l2 o'clock.
   *
   * @param       r           a <code>Rect</code> object that specifies 
   *                          the shape to be painted
   * @param       startAngle  indicates where the arc begins
   * @param       arcAngle    defines the extent of the arc
   * @see         #penMode(int)
   * @see         #foreColor(java.awt.Color)
   */
  public static void paintArc(Rect r, int startAngle, int arcAngle) {
    drawing.paintArc(r, startAngle, arcAngle);
  }
  /**
   * @see         #paintArc(Rect, int, int)
   */
  public static void PaintArc(Rect r, int startAngle, int arcAngle) {
    drawing.paintArc(r, startAngle, arcAngle);
  }

  /**
   * Paints inside a wedge of the oval that fits inside the specified 
   * rectangle, using the background color.
   * The startAngle parameter indicates where the arc begins and is 
   * treated mod 360.
   * The arcAngle parameters defines the extent of the arc.
   * The angles are given in degrees. A positive angle goes clockwise.
   * Zero degree is at l2 o'clock.
   *
   * @param       r           a <code>Rect</code> object that specifies 
   *                          the shape to be erased
   * @param       startAngle  indicates where the arc begins
   * @param       arcAngle    defines the extent of the arc
   * @see         #backColor(java.awt.Color)
   */
  public static void eraseArc(Rect r, int startAngle, int arcAngle) {
    drawing.eraseArc(r, startAngle, arcAngle);
  }
  /**
   * @see         #eraseArc(Rect, int, int)
   */
  public static void EraseArc(Rect r, int startAngle, int arcAngle) {
    drawing.eraseArc(r, startAngle, arcAngle);
  }

  /**
   * Inverts pixels inside a wedge of the oval that fits inside the specified 
   * rectangle.
   * Every white pixel becomes black and reciprocally.
   * Pixels of other colors are changed in an undefined but reversible 
   * manner.
   * The startAngle parameter indicates where the arc begins and is 
   * treated mod 360.
   * The arcAngle parameters defines the extent of the arc.
   * The angles are given in degrees. A positive angle goes clockwise.
   * Zero degree is at l2 o'clock.
   *
   * @param       r           a <code>Rect</code> object that specifies 
   *                          the shape to be inverted
   * @param       startAngle  indicates where the arc begins
   * @param       arcAngle    defines the extent of the arc
   */
  public static void invertArc(Rect r, int startAngle, int arcAngle) {
    drawing.invertArc(r, startAngle, arcAngle);
  }
  /**
   * @see         #invertArc(Rect, int, int)
   */
  public static void InvertArc(Rect r, int startAngle, int arcAngle) {
    drawing.invertArc(r, startAngle, arcAngle);
  }

  /**
   * Draws an outline of the specified polygon.
   *
   * @param       points  an array of the <code>Point</code> objects that 
                          specify the polygon to be framed
   * @param       pCount  the number of points
   * @see         #newPointArray(int)
   * @see         #penMode(int)
   * @see         #penSize(int, int)
   * @see         #foreColor(java.awt.Color)
   */
  public static void framePolygon(Point[] points, int pCount) {
    drawing.framePolygon(points, pCount);
  }
  /**
   * @see         #framePolygon(Point[], int)
   */
  public static void FramePolygon(Point[] points, int pCount) {
    drawing.framePolygon(points, pCount);
  }

  /**
   * Paints inside the specified polygon.
   * The area inside the polygon is defined using the even-odd fill rule.
   *
   * @param       points  an array of the <code>Point</code> objects that 
                          specify the polygon to be painted
   * @param       pCount  the number of points
   * @see         #newPointArray(int)
   * @see         #penMode(int)
   * @see         #foreColor(java.awt.Color)
   */
  public static void paintPolygon(Point[] points, int pCount) {
    drawing.paintPolygon(points, pCount);
  }
  /**
   * @see         #paintPolygon(Point[], int)
   */
  public static void PaintPolygon(Point[] points, int pCount) {
    drawing.paintPolygon(points, pCount);
  }

  /**
   * Paints inside the specified polygon, using the background color.
   * The area inside the polygon is defined using the even-odd fill rule.
   *
   * @param       points  an array of the <code>Point</code> objects that 
                          specify the polygon to be erased
   * @param       pCount  the number of points
   * @see         #newPointArray(int)
   * @see         #backColor(java.awt.Color)
   */
  public static void erasePolygon(Point[] points, int pCount) {
    drawing.erasePolygon(points, pCount);
  }
  /**
   * @see         #erasePolygon(Point[], int)
   */
  public static void ErasePolygon(Point[] points, int pCount) {
    drawing.erasePolygon(points, pCount);
  }

  /**
   * Inverts pixels inside the specified polygon.
   * The area inside the polygon is defined using the even-odd fill rule.
   * Every white pixel becomes black and reciprocally.
   * Pixels of other colors are changed in an undefined but reversible 
   * manner.
   *
   * @param       points  an array of the <code>Point</code> objects that 
                          specify the polygon to be inverted
   * @param       pCount  the number of points
   * @see         #newPointArray(int)
   */
  public static void invertPolygon(Point[] points, int pCount) {
    drawing.invertPolygon(points, pCount);
  }
  /**
   * @see         #invertPolygon(Point[], int)
   */
  public static void InvertPolygon(Point[] points, int pCount) {
    drawing.invertPolygon(points, pCount);
  }

// Text
  
  /**
   * Returns the width in pixels of the given text string.
   * This value is added to the pen horizontal coordinate when the 
   * string is drawn.
   *
   * @param       s  the string to be measured 
   * @return      the width of the given string 
   * @see         #drawString(java.lang.String)
   */
  public static int stringWidth(String s) {
    return drawing.stringWidth(s);
  }
  /**
   * @see         #stringWidth(java.lang.String)
   */
  public static int StringWidth(String s) {
    return drawing.stringWidth(s);
  }

  /**
   * Returns the width in pixels of the specified text.
   * This value is added to the pen horizontal coordinate when the 
   * specified text is drawn.
   *
   * @param       textBuf    the array of characters that stores the text
   * @param       firstByte  indicates where the measured text begins
   * @param       byteCount  indicates the number of characters to be measured
   * @return      the width of the specified text
   * @see         #drawText(char[], int, int)
   */
  public static int textWidth(char textBuf[], int firstByte, int byteCount) {
    return drawing.textWidth(textBuf, firstByte, byteCount);
  }
  /**
   * @see         #textWidth(char[], int, int)
   */
  public static int TextWidth(char textBuf[], int firstByte, int byteCount) {
    return drawing.textWidth(textBuf, firstByte, byteCount);
  }
  
  /**
   * Returns the width in pixels of the given character.
   * This value is added to the pen horizontal coordinate when the 
   * char is drawn.
   *
   * @param       c  the character to be measured
   * @return      the width of the given character
   * @see         #drawChar(char)
   */
  public static int charWidth(char c) {
    return drawing.charWidth(c);
  }
  /**
   * @see         #charWidth(char)
   */
  public static int CharWidth(char c) {
    return drawing.charWidth(c);
  }

  /**
   * Draws the given text string.
   * The string is placed beginning at the current pen location and 
   * extending to the right.
   * The pen location ends up to the right of the last character in the string.
   *
   * @param       s  the string to be drawn
   * @see         #moveTo(int, int)
   * @see         #foreColor(java.awt.Color)
   * @see         #textFont(java.lang.String)
   * @see         #textSize(int)
   * @see         #textFace(int)
   */
  public static void drawString(String s) {
    drawing.drawString(s);
  }
  /**
   * @see         #drawString(java.lang.String)
   */
  public static void DrawString(String s) {
    drawing.drawString(s);
  }

  /**
   * Draws the specified text.
   * The text is placed beginning at the current pen location and 
   * extending to the right.
   * The pen location ends up to the right of the last character in the string.
   *
   * @param       textBuf    the array of characters that stores the text
   * @param       firstByte  indicates where the drawn text begins
   * @param       byteCount  indicates the number of characters to be drawn
   * @see         #moveTo(int, int)
   * @see         #foreColor(java.awt.Color)
   * @see         #textFont(java.lang.String)
   * @see         #textSize(int)
   * @see         #textFace(int)
   */
  public static void drawText(char textBuf[], int firstByte, int byteCount) {
    drawing.drawText(textBuf, firstByte, byteCount);
  }
  /**
   * @see         #drawText(char[], int, int)
   */
  public static void DrawText(char textBuf[], int firstByte, int byteCount) {
    drawing.drawText(textBuf, firstByte, byteCount);
  }
  
  /**
   * Draws the given character.
   * The char is placed beginning at the current pen location and 
   * extending to the right.
   * The pen location ends up to the right of the character.
   *
   * @param       c  the character to be drawn
   * @see         #moveTo(int, int)
   * @see         #foreColor(java.awt.Color)
   * @see         #textFont(java.lang.String)
   * @see         #textSize(int)
   * @see         #textFace(int)
   */
  public static void drawChar(char c) {
    drawing.drawChar(c);
  }
  /**
   * @see         #drawChar(char)
   */
  public static void DrawChar(char c) {
    drawing.drawChar(c);
  }

// Image

  /**
   * Draws the given image,
   * starting at location <code>(x,y)</code> and scaled to fit 
   * a <code>width x height</code> rectangle.
   *
   * @param       img     the <code>Image</code> object to be drawn
   * @param       x       the <em>x</em> coordinate of the top-left corner
   * @param       y       the <em>y</em> coordinate of the top-left corner
   * @param       width   the width of the drawn image
   * @param       height  the height of the drawn image
   * @return      <code>true</code> if the image has been completely drawn.
   * @see         java.awt.Graphics#drawImage(Image, int, int, int, int, ImageObserver)
   */
  public boolean drawImage(Image img, int x, int y, int width, int height) {
    return drawing.drawImage(img, x, y, width, height);
  }

  /**
   * Draws the given image, starting at location <code>(x,y)</code>.
   *
   * @param       img     the <code>Image</code> object to be drawn
   * @param       x       the <em>x</em> coordinate of the top-left corner
   * @param       y       the <em>y</em> coordinate of the top-left corner
   * @return      <code>true</code> if the image has been completely drawn.
   * @see         java.awt.Graphics#drawImage(Image, int, int, ImageObserver)
   */
  public boolean drawImage(Image img, int x, int y) {
    return drawing.drawImage(img, x, y);
  }

// Divers
  
  /**
   * Returns the current number of ticks (sixtieths of a second) 
   * since midnight, January 1, 1970 UTC.
   *
   * @return      the number of ticks
   */
  public static long tickCount() {
	return System.currentTimeMillis()*60/1000;
  }
  /**
   * @see         #tickCount()
   */
  public static long TickCount() {
	return tickCount();
  }
  
  /**
   * Causes the system to beep
   *
   * @param       duration  actually without any effect
   */
  public static void sysBeep(int duration) {
	Toolkit.getDefaultToolkit().beep();
  }
  /**
   * @see         #sysBeep(int)
   */
  public static void SysBeep(int duration) {
	sysBeep(duration);
  }

  /**
   * Returns the <code>short</code> integer value corresponding to the 
   * 16 most significant bits of the given 32 bits integer.
   *
   * @param       value  the given 32 bits integer
   * @return      the 16 most significant bits, as a <code>short</code> value
   * @see         #loWord(int)
   */
  public static short hiWord(int value) {
    return (short)((value>>16) & 0xFFFF);
  }
  /**
   * @see         #hiWord(int)
   */
  public static short HiWord(int value) {
    return hiWord(value);
  }

  /**
   * Returns the <code>short</code> integer value corresponding to the 
   * 16 least significant bits of the given 32 bits integer.
   *
   * @param       value  the given 32 bits integer
   * @return      the 16 least significant bits, as a <code>short</code> value
   * @see         #hiWord(int)
   */
  public static short loWord(int value) {
    return (short)(value & 0xFFFF);
  }
  /**
   * @see         #loWord(int)
   */
  public static short LoWord(int value) {
    return loWord(value);
  }

  /**
   * Returns a pseudo-random, uniformly distributed, integer value 
   * in the range from <code>-32768</code> through <code>32767</code>.
   * <p>
   * The returned value depends on the global variable 
   * <code>randSeed</code>. Each call to <code>random()</code> updates 
   * this variable.
   *
   * @return      a pseudo-random <code>short</code> value
   * @see         #randSeed
   */
  public static short random() {
    int hiRand, loRand;

    hiRand = 16807 * ((randSeed >> 16) & 0xFFFF);
    loRand = 16807 * (randSeed & 0xFFFF);
    randSeed = (hiRand << 16) + 2 * ((hiRand >> 16) & 0xFFFF);
    if ( randSeed < 0 )
      randSeed = (randSeed & 0x7FFFFFFF) + 1;
    if ( randSeed >= 0x7FFFFFFF - loRand )
      randSeed -= 0x7FFFFFFF;
    randSeed += loRand;
    return (short)(randSeed & 0xFFFF);
  }
  /**
   * @see         #random()
   */
  public static short Random() {
    return random();
  }

}  // end class MacLib

/**
 * This class implements a concurrent thread running an events dispatcher 
 * in order to improve the responsiveness.
 * Inspired from EventDispatchThread, a private class of java.awt.
 * @version  13 sep 2002
 * @author   Philippe Chassignet, Ecole Polytechnique
 * @see      DrawingFrame
 * @see      MacLib
 * @see      EventDispatchThread
 */
class Dispatcher extends Thread {
  private EventQueue theQueue;
  boolean running = true;

  Dispatcher() {
    super("AWT-MacLib-Dispatcher");
    theQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
  }

  public void run() {
    while ( running ) {
      try {
        AWTEvent event = theQueue.getNextEvent();
        Object src = event.getSource();
        if ( src instanceof Component )
          ((Component)src).dispatchEvent(event);
        else if ( src instanceof MenuComponent )
          ((MenuComponent)src).dispatchEvent(event);
        else if ( event instanceof ActiveEvent )
          // This could become the sole method of dispatching in time, and 
          // moved to the event queue's dispatchEvent() method.
		  ((ActiveEvent)event).dispatch();
      } catch( ThreadDeath death ) {
        return;
      } catch( Throwable e ) {
        System.err.println("Exception occurred during event dispatching:");
        e.printStackTrace();
      }
    }
  }

}  // end class Dispatcher

