/* Copyright (C) 2000  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.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.geom.AffineTransform;
import java.awt.image.ImageObserver;

/**
 * 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()
  {
    Graphics2DImpl gfxCopy = (Graphics2DImpl) super.clone();
    AbstractGraphicsState stateCopy =
      (AbstractGraphicsState) state.clone();
    gfxCopy.setState(stateCopy);
    
    return gfxCopy;
  }


  // -------- 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);
  }
}
