/* Copyright (C) 2000, 2002, 2003  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

package gnu.awt.j2d;

import java.awt.Color;
import java.awt.Composite;
import java.awt.Image;
import java.awt.Shape;
import java.awt.Rectangle;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.image.ImageObserver;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
import java.text.AttributedCharacterIterator;
import java.util.Map;

/**
 * Delegates almost all work to a state object, that allows us to
 * hot-swap rendering strategies based on state changes inflicted on
 * this Graphics object. This class keeps track of properties that are
 * not affected by the state, (such as clip shape,
 * foreground/background color, font, etc.).
 *
 * <p>The far front-end of the rendering pipeline consists of the
 * Graphics2D API. In the far back-end, lies the native graphics
 * libraries. In most cases the native graphics libraries only have
 * direct support for a subset of the properties of Graphics2D. To
 * make up missing features in the native graphics libraries, the
 * pipeline between the front-end and the back-end need to translate
 * drawing request to primitive operations that are supported by the
 * back-end. E.g. for X11, drawing a straight line will translate to
 * an XDrawLine, drawing a bezier curve will trigger flattening of the
 * curve and will result in a call to XDrawLines.
 *
 * <p>This is the basic strategy for the rendering pipeline: Whenever
 * a graphics property change occurs, that causes the current pipeline
 * to be insufficient, amend or replace parts of the pipeline so that
 * the pipeline will once again be able to translate requests to the
 * set of primitives supported by the native graphics library.
 *
 * <p>Most graphics libraries share common subsets of
 * functionality. To be able to reuse pieces of the rendering pipeline
 * for several backends, we define interfaces that describe subsets of
 * characteristics supported by the backends. A wrapper for the native
 * library can implement several interfaces to describe its range of
 * functionality.
 *
 * <p>Typically, most painting is done with a graphics object with
 * simple properties. Unless one is using a complex Look & Feel, the
 * painting of Swing components will never require affine transforms,
 * alpha blending, non-rectangular clipping, etc. When graphics
 * objects are created, they start off in a state where all the
 * properties are simple. Most graphics objects experience only
 * trivial property changes, and never leave this simple state. It is
 * therefore wise to ensure that the rendering pipeline for this
 * initial state is lean and as much as possible plugs directly into
 * the backend.
 *
 * <p>The initial state for graphics object of most raster displays
 * would call for two levels of indirection:
 *
 * <pre>
 * Graphics2D object ---> IntegerGraphicsState ---> DirectRasterGraphics
 * </pre>
 */
public class Graphics2DImpl extends Graphics2D implements Cloneable
{
  GraphicsConfiguration config;

  AbstractGraphicsState state;
    
  Color fg;
  Color bg;

  Font font;
  
  public Graphics2DImpl(GraphicsConfiguration config)
  {
    this.config = config;
  }
  
  public void setState(AbstractGraphicsState state)
  {
    this.state = state;
    this.state.setFrontend(this);
  }
    
  public Object clone()
  {
    try
      {
	Graphics2DImpl gfxCopy = (Graphics2DImpl) super.clone();
	AbstractGraphicsState stateCopy =
	  (AbstractGraphicsState) state.clone();
	gfxCopy.setState(stateCopy);
	
	return gfxCopy;
      }
    catch (CloneNotSupportedException ex)
      {
	// This should never happen.
	throw new InternalError ();
      }
  }


  // -------- Graphics methods:

  public Graphics create()
  {
    Graphics2DImpl gfxCopy = (Graphics2DImpl) clone();
    return gfxCopy;
  }

  public Color getColor()
  {
    return fg;
  }
  
  public void setColor(Color color)
  {
    fg = color;
    state.setColor(color);
  }

  public void setPaintMode()
  {
    state.setPaintMode();
  }

  public void setXORMode(Color altColor)
  {
    state.setXORMode(altColor);
  }

  public Font getFont()
  {
    return font;
  }

  public void setFont(Font font)
  {
    this.font = font;
    state.setFont(font);
  }
    
  public FontMetrics getFontMetrics(Font font)
  {
    return state.getFontMetrics(font);
  }

  public Rectangle getClipBounds()
  {
    return state.getClipBounds();
  }
    
  public void clipRect(int x, int y, int width, int height)
  {
    Shape clip = state.getClip();
    if (clip instanceof Rectangle)
      {
	Rectangle clipRect = (Rectangle) clip;
	clip = clipRect.intersection(new Rectangle(x, y, width, height));
	setClip(clip);
	return;
      }
	
    String msg =
      "intersecting current clip shape " + clip + " with new rectangle " +
      "has not been implemented yet";
    throw new UnsupportedOperationException(msg);
  }

  public void setClip(int x, int y, int width, int height)
  {
    Rectangle clip = new Rectangle(x, y, width, height);
    setClip(clip);
  }

  public Shape getClip()
  {
    return state.getClip();
  }

  public void setClip(Shape clip)
  {
    state.setClip(clip);
  }

  public void copyArea(int x, int y, int width, int height,
		       int dx, int dy)
  {
    state.copyArea(x, y, width, height, dx, dy);
  }

  public void drawLine(int x1, int y1, int x2, int y2)
  {
    state.drawLine(x1, y1, x2, y2);
  }
    
  public void fillRect(int x, int y, int width, int height)
  {
    state.fillRect(x, y, width, height);
  }
    
  public void clearRect(int x, int y, int width, int height)
  {
    state.clearRect(x, y, width, height);
  }
  
  public void drawRoundRect(int x, int y, int width, int height,
			    int arcWidth, int arcHeight)
  {
    state.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
  }
    
  public void fillRoundRect(int x, int y, int width, int height,
			    int arcWidth, int arcHeight)
  {
    state.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
  }

  public void drawOval(int x, int y, int width, int height)
  {
    state.drawOval(x, y, width, height);
  }

  public void fillOval(int x, int y, int width, int height)
  {
    state.fillOval(x, y, width, height);
  }

  public void drawArc(int x, int y, int width, int height,
		      int startAngle, int arcAngle)
  {
    state.drawArc(x, y, width, height, startAngle, arcAngle);
  }

  public void fillArc(int x, int y, int width, int height,
		      int startAngle, int arcAngle)
  {
    state.fillArc(x, y, width, height, startAngle, arcAngle);
  }

  public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
  {
    state.drawPolyline(xPoints, yPoints, nPoints);
  }
  
  public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
  {
    state.drawPolygon(xPoints, yPoints, nPoints);
  }
    
  public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
  {
    state.fillPolygon(xPoints, yPoints, nPoints);
  }
    
  public boolean drawImage(Image image, int x, int y,
			   ImageObserver observer)
  {
    return state.drawImage(image, x, y, observer);
  }

  public boolean drawImage(Image img, int x, int y,
			   int width, int height,
			   ImageObserver observer)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public boolean drawImage(Image img, int x, int y, Color bgcolor,
			   ImageObserver observer)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }
  
  public boolean drawImage(Image img, int x, int y,
			   int width, int height, Color bgcolor,
			   ImageObserver observer)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public boolean drawImage(Image img,
			   int dx1, int dy1, int dx2, int dy2,
			   int sx1, int sy1, int sx2, int sy2,
			   ImageObserver observer)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }
  
  public boolean drawImage(Image img,
			   int dx1, int dy1, int dx2, int dy2,
			   int sx1, int sy1, int sx2, int sy2,
			   Color bgcolor, ImageObserver observer)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }
  
  public void dispose()
  {
    AbstractGraphicsState lState = state;
    
    state = null;
    config = null;
    font = null;
    fg = null;
    bg = null;
    
    if (lState != null)
      lState.dispose();
  }
    


  // -------- Graphics2D methods:
    
  public void draw(Shape shape)
  {
    state.draw(shape);
  }
  
  public boolean drawImage(Image image, AffineTransform xform,
			   ImageObserver obs)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }


  public void drawString(String text, int x, int y)
  {
    state.drawString(text, x, y);
  }

  public void drawString(String text, float x, float y)
  {
    state.drawString(text, x, y);
  }

  public void fill(Shape shape)
  {
    state.fill(shape);
  }

  public boolean hit(Rectangle rect, Shape text, boolean onStroke)
  {
    return state.hit(rect, text, onStroke);
  }
    
  public GraphicsConfiguration getDeviceConfiguration()
  {
    return config;
  }

  public void setPaint(Paint paint)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public void setRenderingHint(RenderingHints.Key hintKey,
			       Object hintValue)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }
  
  public Object getRenderingHint(RenderingHints.Key hintKey)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public RenderingHints getRenderingHints()
  {
    throw new UnsupportedOperationException("not implemented yet");
  }
    
  public void translate(int x, int y)
  {
    state.translate(x, y);
  }
  
  public void translate(double tx, double ty)
  {
    state.translate(tx, ty);
  }
    
  public void rotate(double theta)
  {
    state.rotate(theta);
  }

  public void rotate(double theta, double x, double y)
  {
    state.rotate(theta, x, y);
  }
  
  public void scale(double scaleX, double scaleY)
  {
    state.scale(scaleX, scaleY);
  }
  
  public void shear(double shearX, double shearY)
  {
    state.shear(shearX, shearY);
  }

  public void transform(AffineTransform Tx)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public void setTransform(AffineTransform Tx)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }
    
  public AffineTransform getTransform()
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public Paint getPaint()
  {
    throw new UnsupportedOperationException("not implemented yet");
  }
    
  public void setBackground(Color color)
  {
    bg = color;
  }

  public Color getBackground()
  {
    return bg;
  }

  public void clip(Shape shape)
  {
    Shape clip = state.getClip();
    
    if ((shape instanceof Rectangle) && (clip instanceof Rectangle))
      {
	clip = ((Rectangle) clip).intersection((Rectangle) shape);
	state.setClip(clip);
	return;
      }
	
    String msg =
      "intersecting current clip shape " + clip + " with new shape " + shape +
      "has not been implemented yet";
    throw new UnsupportedOperationException(msg);
  }
  
  public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y)
  {
    throw new UnsupportedOperationException("not implemented yet");  
  }

  public void drawRenderedImage(RenderedImage image, AffineTransform xform)
  {
    throw new UnsupportedOperationException("not implemented yet");  
  }

  public void drawRenderableImage(RenderableImage image, AffineTransform xform)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public void drawString(AttributedCharacterIterator iterator,
                		  int x, int y)
  {
    throw new UnsupportedOperationException("not implemented yet");  
  }

  public void drawString(AttributedCharacterIterator iterator, float x, 
			 float y)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public void setComposite(Composite comp)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public void setStroke(Stroke stroke)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public void setRenderingHints(Map hints)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public void addRenderingHints(Map hints)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public Composite getComposite()
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public Stroke getStroke()
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public FontRenderContext getFontRenderContext ()
  {
    throw new UnsupportedOperationException("not implemented yet");
  }

  public void drawGlyphVector (GlyphVector g, float x, float y)
  {
    throw new UnsupportedOperationException("not implemented yet");
  }
}
