/* Graphics.java -- Abstract Java drawing class
   Copyright (C) 1999, 2000, 2002, 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.awt;

import java.awt.image.ImageObserver;
import java.text.AttributedCharacterIterator;

/**
 * This is the abstract superclass of classes for drawing to graphics
 * devices such as the screen or printers.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Warren Levy (warrenl@cygnus.com)
 */
public abstract class Graphics
{

  /**
   * Default constructor for subclasses.
   */
  protected
  Graphics()
  {
  }

  /**
   * Returns a copy of this <code>Graphics</code> object.
   *
   * @return A copy of this object.
   */
  public abstract Graphics create();

  /**
   * Returns a copy of this <code>Graphics</code> object.  The origin point
   * will be translated to the point (x, y) and the cliping rectangle set
   * to the intersection of the clipping rectangle in this object and the
   * rectangle specified by the parameters to this method.
   *
   * @param x The new X coordinate of the clipping region rect.
   * @param y The new Y coordinate of the clipping region rect.
   * @param width The width of the clipping region intersect rectangle.
   * @param height The height of the clipping region intersect rectangle.
   *
   * @return A copy of this object, modified as specified.
   */
  public Graphics create(int x, int y, int width, int height)
  {
    Graphics g = create();

    g.translate(x, y);
    // FIXME: I'm not sure if this will work.  Are the old clip rect bounds
    // translated above?
    g.clipRect(0, 0, width, height);

    return(g);
  }

  /**
   * Translates this context so that its new origin point is the point
   * (x, y).
   *
   * @param x The new X coordinate of the origin.
   * @param y The new Y coordinate of the origin.
   */
  public abstract void translate(int x, int y);

  /**
   * Returns the current color for this object.
   *
   * @return The color for this object.
   */
  public abstract Color getColor();

  /**
   * Sets the current color for this object.
   *
   * @param color The new color.
   */
  public abstract void setColor(Color color);

  /**
   * Sets this context into "paint" mode, where the target pixels are
   * completely overwritten when drawn on.
   */
  public abstract void setPaintMode();

  /**
   * Sets this context info "XOR" mode, where the targe pixles are
   * XOR-ed when drawn on.
   *
   * @param color The color to XOR against.
   */
  public abstract void setXORMode(Color color);

  /**
   * Returns the current font for this graphics context.
   *
   * @return The current font.
   */
  public abstract Font getFont();

  /**
   * Sets the font for this graphics context to the specified value.
   *
   * @param font The new font.
   */
  public abstract void setFont(Font font);

  /**
   * Returns the font metrics for the current font.
   *
   * @return The font metrics for the current font.
   */
  public FontMetrics getFontMetrics()
  {
    return getFontMetrics(getFont());
  }

  /**
   * Returns the font metrics for the specified font.
   *
   * @param font The font to return metrics for.
   *
   * @return The requested font metrics.
   */
  public abstract FontMetrics getFontMetrics(Font font);

  /**
   * Returns the bounding rectangle of the clipping region for this
   * graphics context.
   *
   * @return The bounding rectangle for the clipping region.
   */
  public abstract Rectangle getClipBounds();

  /**
   * Returns the bounding rectangle of the clipping region for this
   * graphics context.
   *
   * @return The bounding rectangle for the clipping region.
   *
   * @deprecated This method is deprecated in favor of
   * <code>getClipBounds()</code>.
   */
  public Rectangle getClipRect()
  {
    return getClipBounds();
  }

  /**
   * Sets the clipping region to the intersection of the current clipping
   * region and the rectangle determined by the specified parameters.
   *
   * @param x The X coordinate of the upper left corner of the intersect rect.
   * @param y The Y coordinate of the upper left corner of the intersect rect.
   * @param width The width of the intersect rect.
   * @param height The height of the intersect rect.
   */
  public abstract void clipRect(int x, int y, int width, int height);

  /**
   * Sets the clipping region to the rectangle determined by the specified
   * parameters.
   *
   * @param x The X coordinate of the upper left corner of the rect.
   * @param y The Y coordinate of the upper left corner of the rect.
   * @param width The width of the rect.
   * @param height The height of the rect.
   */
  public abstract void setClip(int x, int y, int width, int height);

  /**
   * Returns the current clipping region as a <code>Shape</code> object.
   *
   * @return The clipping region as a <code>Shape</code>.
   */
  public abstract Shape getClip();

  /**
   * Sets the clipping region to the specified <code>Shape</code>.
   *
   * @param clip The new clipping region.
   */
  public abstract void setClip(Shape clip);

  /**
   * Copies the specified rectangle to the specified offset location.
   *
   * @param x The X coordinate of the upper left corner of the copy rect.
   * @param y The Y coordinate of the upper left corner of the copy rect.
   * @param width The width of the copy rect.
   * @param height The height of the copy rect.
   * @param dx The offset from the X value to start drawing.
   * @param dy The offset from the Y value to start drawing.
   */
  public abstract void copyArea(int x, int y, int width, int height, int dx,
                                int dy);

  /**
   * Draws a line between the two specified points.
   *
   * @param x1 The X coordinate of the first point.
   * @param y1 The Y coordinate of the first point.
   * @param x2 The X coordinate of the second point.
   * @param y2 The Y coordinate of the second point.
   */
  public abstract void drawLine(int x1, int y1, int x2, int y2);

  /**
   * Fills the area bounded by the specified rectangle.
   *
   * @param x The X coordinate of the upper left corner of the fill rect.
   * @param y The Y coordinate of the upper left corner of the fill rect.
   * @param width The width of the fill rect.
   * @param height The height of the fill rect.
   */
  public abstract void fillRect(int x, int y, int width, int height);

  /**
   * Draws the outline of the specified rectangle.
   *
   * @param x The X coordinate of the upper left corner of the draw rect.
   * @param y The Y coordinate of the upper left corner of the draw rect.
   * @param width The width of the draw rect.
   * @param height The height of the draw rect.
   */
  public void drawRect(int x, int y, int width, int height)
  {
    int x1 = x;
    int y1 = y;
    int x2 = x + width;
    int y2 = y + height;
    drawLine(x1, y1, x2, y1);
    drawLine(x2, y1, x2, y2);
    drawLine(x2, y2, x1, y2);
    drawLine(x1, y2, x1, y1);
  }

  /**
   * Clears the specified rectangle.
   *
   * @param x The X coordinate of the upper left corner of the clear rect.
   * @param y The Y coordinate of the upper left corner of the clear rect.
   * @param width The width of the clear rect.
   * @param height The height of the clear rect.
   */
  public abstract void clearRect(int x, int y, int width, int height);

  /**
   * Draws the outline of the specified rectangle with rounded cornders.
   *
   * @param x The X coordinate of the upper left corner of the draw rect.
   * @param y The Y coordinate of the upper left corner of the draw rect.
   * @param width The width of the draw rect.
   * @param height The height of the draw rect.
   * @param arcWidth The width of the corner arcs.
   * @param arcHeight The height of the corner arcs.
   */
  public abstract void drawRoundRect(int x, int y, int width, int height,
                                     int arcWidth, int arcHeight);

  /**
   * Fills the specified rectangle with rounded cornders.
   *
   * @param x The X coordinate of the upper left corner of the fill rect.
   * @param y The Y coordinate of the upper left corner of the fill rect.
   * @param width The width of the fill rect.
   * @param height The height of the fill rect.
   * @param arcWidth The width of the corner arcs.
   * @param arcHeight The height of the corner arcs.
   */
  public abstract void fillRoundRect(int x, int y, int width, int height,
                                     int arcWidth, int arcHeight);

  public void draw3DRect(int x, int y, int width, int height, boolean raised)
  {
    Color color = getColor();
    Color tl = color.brighter();
    Color br = color.darker();

    if (!raised)
      {
        Color tmp = tl;
        tl = br;
        br = tmp;
      }

    int x1 = x;
    int y1 = y;
    int x2 = x + width;
    int y2 = y + height;

    setColor(tl);
    drawLine(x1, y1, x2, y1);
    drawLine(x1, y2, x1, y1);
    setColor(br);
    drawLine(x2, y1, x2, y2);
    drawLine(x2, y2, x1, y2);
    setColor(color);
  }

  /**
   * Fills the specified rectangle with a 3D effect
   *
   * @param x The X coordinate of the upper left corner of the fill rect.
   * @param y The Y coordinate of the upper left corner of the fill rect.
   * @param width The width of the fill rect.
   * @param height The height of the fill rect.
   * @param raised <code>true</code> if the rectangle appears raised,
   * <code>false</code> if it should appear etched.
   */
  public void fill3DRect(int x, int y, int width, int height, boolean raised)
  {
    fillRect(x, y, width, height);
    draw3DRect(x, y, width-1, height-1, raised);
  }

  /**
   * Draws an oval that just fits within the specified rectangle.
   *
   * @param x The X coordinate of the upper left corner of the rect.
   * @param y The Y coordinate of the upper left corner of the rect.
   * @param width The width of the rect.
   * @param height The height of the rect.
   */
  public abstract void drawOval(int x, int y, int width, int height);

  /**
   * Fills an oval that just fits within the specified rectangle.
   *
   * @param x The X coordinate of the upper left corner of the rect.
   * @param y The Y coordinate of the upper left corner of the rect.
   * @param width The width of the rect.
   * @param height The height of the rect.
   */
  public abstract void fillOval(int x, int y, int width, int height);

  /**
   * Draws an arc using the specified bounding rectangle and the specified
   * angle parameter.  The arc is centered at the center of the rectangle.
   * The arc starts at the arcAngle position and extend for arcAngle
   * degrees.  The degree origin is at the 3 o'clock position.
   *
   * @param x The X coordinate of the upper left corner of the rect.
   * @param y The Y coordinate of the upper left corner of the rect.
   * @param width The width of the rect.
   * @param height The height of the rect.
   * @param arcStart The beginning angle of the arc.
   * @param arcAngle The extent of the arc.
   */
  public abstract void drawArc(int x, int y, int width, int height,
                               int arcStart, int arcAngle);

  /**
   * Fills the arc define by the specified bounding rectangle and the specified
   * angle parameter.  The arc is centered at the center of the rectangle.
   * The arc starts at the arcAngle position and extend for arcAngle
   * degrees.  The degree origin is at the 3 o'clock position.
   *
   * @param x The X coordinate of the upper left corner of the rect.
   * @param y The Y coordinate of the upper left corner of the rect.
   * @param width The width of the rect.
   * @param height The height of the rect.
   * @param arcStart The beginning angle of the arc.
   * @param arcAngle The extent of the arc.
   */
  public abstract void fillArc(int x, int y, int width, int height,
                               int arcStart, int arcAngle);

  /**
   * Draws a series of interconnected lines determined by the arrays
   * of corresponding x and y coordinates.
   *
   * @param xPoints The X coordinate array.
   * @param yPoints The Y coordinate array.
   * @param npoints The number of points to draw.
   */
  public abstract void drawPolyline(int xPoints[], int yPoints[], int npoints);

  /**
   * Draws a series of interconnected lines determined by the arrays
   * of corresponding x and y coordinates.  The figure is closed if necessary
   * by connecting the first and last points.
   *
   * @param xPoints The X coordinate array.
   * @param yPoints The Y coordinate array.
   * @param npoints The number of points to draw.
   */
  public abstract void drawPolygon(int xPoints[], int yPoints[], int npoints);

  /**
   * Draws the specified polygon.
   *
   * @param polygon The polygon to draw.
   */
  public void drawPolygon(Polygon polygon)
  {
    drawPolygon(polygon.xpoints, polygon.ypoints, polygon.npoints);
  }

  /**
   * Fills the polygon determined by the arrays
   * of corresponding x and y coordinates.
   *
   * @param xPoints The X coordinate array.
   * @param yPoints The Y coordinate array.
   * @param npoints The number of points to draw.
   */
  public abstract void fillPolygon(int xPoints[], int yPoints[], int npoints);

  /**
   * Fills the specified polygon
   *
   * @param polygon The polygon to fill.
   */
  public void fillPolygon(Polygon polygon)
  {
    fillPolygon(polygon.xpoints, polygon.ypoints, polygon.npoints);
  }

  /**
   * Draws the specified string starting at the specified point.
   *
   * @param string The string to draw.
   * @param x The X coordinate of the point to draw at.
   * @param y The Y coordinate of the point to draw at.
   */
  public abstract void drawString(String string, int x, int y);

  public abstract void drawString (AttributedCharacterIterator ci, int x,
                                   int y);

  /**
   * Draws the specified characters starting at the specified point.
   *
   * @param data The array of characters to draw.
   * @param offset The offset into the array to start drawing characters from.
   * @param length The number of characters to draw.
   * @param x The X coordinate of the point to draw at.
   * @param y The Y coordinate of the point to draw at.
   */
  public void drawChars(char data[], int offset, int length, int x, int y)
  {
    drawString(new String(data, offset, length), x, y);
  }

  public void drawBytes(byte[] data, int offset, int length, int x, int y)
  {
    String str = new String(data, offset, length);
    drawString(str, x, y);
  }

  /**
   * Draws all of the image that is available and returns.  If the image
   * is not completely loaded, <code>false</code> is returned and
   * the specified iamge observer is notified as more data becomes
   * available.
   *
   * @param image The image to draw.
   * @param x The X coordinate of the point to draw at.
   * @param y The Y coordinate of the point to draw at.
   * @param observer The image observer to notify as data becomes available.
   *
   * @return <code>true</code> if all the image data is available,
   * <code>false</code> otherwise.
   */
  public abstract boolean drawImage(Image image, int x, int y,
                                    ImageObserver observer);

  /**
   * Draws all of the image that is available and returns.  The image
   * is scaled to fit in the specified rectangle.  If the image
   * is not completely loaded, <code>false</code> is returned and
   * the specified iamge observer is notified as more data becomes
   * available.
   *
   * @param image The image to draw.
   * @param x The X coordinate of the point to draw at.
   * @param y The Y coordinate of the point to draw at.
   * @param width The width of the rectangle to draw in.
   * @param height The height of the rectangle to draw in.
   * @param observer The image observer to notify as data becomes available.
   *
   * @return <code>true</code> if all the image data is available,
   * <code>false</code> otherwise.
   */
  public abstract boolean drawImage(Image image, int x, int y, int width,
                                    int height, ImageObserver observer);

  /**
   * Draws all of the image that is available and returns.  If the image
   * is not completely loaded, <code>false</code> is returned and
   * the specified iamge observer is notified as more data becomes
   * available.
   *
   * @param image The image to draw.
   * @param x The X coordinate of the point to draw at.
   * @param y The Y coordinate of the point to draw at.
   * @param bgcolor The background color to use for the image.
   * @param observer The image observer to notify as data becomes available.
   *
   * @return <code>true</code> if all the image data is available,
   * <code>false</code> otherwise.
   */
  public abstract boolean drawImage(Image image, int x, int y, Color bgcolor,
                                    ImageObserver observer);

  /**
   * Draws all of the image that is available and returns.  The image
   * is scaled to fit in the specified rectangle.  If the image
   * is not completely loaded, <code>false</code> is returned and
   * the specified iamge observer is notified as more data becomes
   * available.
   *
   * @param image The image to draw.
   * @param x The X coordinate of the point to draw at.
   * @param y The Y coordinate of the point to draw at.
   * @param width The width of the rectangle to draw in.
   * @param height The height of the rectangle to draw in.
   * @param bgcolor The background color to use for the image.
   * @param observer The image observer to notify as data becomes available.
   *
   * @return <code>true</code> if all the image data is available,
   * <code>false</code> otherwise.
   */
  public abstract boolean drawImage(Image image, int x, int y, int width,
                                    int height, Color bgcolor,
                                    ImageObserver observer);

  /**
   * FIXME: Write Javadocs for this when you understand it.
   */
  public abstract boolean drawImage(Image image, int dx1, int dy1, int dx2,
                                    int dy2, int sx1, int sy1, int sx2,
                                    int sy2, ImageObserver observer);

  /**
   * FIXME: Write Javadocs for this when you understand it.
   */
  public abstract boolean drawImage(Image image, int dx1, int dy1, int dx2,
                                    int dy2, int sx1, int sy1, int sx2,
                                    int sy2, Color bgcolor,
                                    ImageObserver observer);

  /**
   * Free any resources held by this graphics context immediately instead
   * of waiting for the object to be garbage collected and finalized.
   */
  public abstract void dispose();

  /**
   * Frees the resources held by this graphics context when it is
   * garbage collected.
   */
  public void finalize()
  {
    dispose();
  }

  /**
   * Returns a string representation of this object.
   *
   * @return A string representation of this object.
   */
  public String toString()
  {
    return getClass ().getName () + "[font=" + getFont () + ",color="
           + getColor () + "]";
  }

  /**
   * Returns <code>true</code> if the specified rectangle intersects with the
   * current clip, <code>false</code> otherwise.
   *
   * @param x the X coordinate of the upper left corner of the test rectangle
   * @param y the Y coordinate of the upper left corner of the test rectangle
   * @param width the width of the upper left corner of the test rectangle
   * @param height the height of the upper left corner of the test rectangle
   * @return <code>true</code> if the specified rectangle intersects with the
   *         current clip, <code>false</code> otherwise
   */
  public boolean hitClip(int x, int y, int width, int height)
  {
    Shape clip = getClip();
    if (clip == null)
      return true;
    return getClip().intersects(x, y, width, height);
  }

  public Rectangle getClipBounds(Rectangle r)
  {
    Rectangle clipBounds = getClipBounds();

    if (r == null)
      return clipBounds;

    r.x      = clipBounds.x;
    r.y      = clipBounds.y;
    r.width  = clipBounds.width;
    r.height = clipBounds.height;
    return r;
  }
}
