/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package org.apache.fop.afp;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.TexturePaint;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
import java.io.IOException;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
import org.apache.xmlgraphics.java2d.GraphicContext;
import org.apache.xmlgraphics.java2d.StrokingTextHandler;
import org.apache.xmlgraphics.java2d.TextHandler;
import org.apache.xmlgraphics.ps.ImageEncodingHelper;
import org.apache.xmlgraphics.util.MimeConstants;
import org.apache.xmlgraphics.util.UnitConv;

import org.apache.fop.afp.goca.GraphicsSetLineType;
import org.apache.fop.afp.modca.GraphicsObject;
import org.apache.fop.afp.svg.AFPGraphicsConfiguration;
import org.apache.fop.afp.util.CubicBezierApproximator;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.svg.NativeImageHandler;

/**
 * This is a concrete implementation of {@link AbstractGraphics2D} (and
 * therefore of {@link Graphics2D}) which is able to generate GOCA byte
 * codes.
 *
 * @see org.apache.xmlgraphics.java2d.AbstractGraphics2D
 */
public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHandler {

    private static final Log log = LogFactory.getLog(AFPGraphics2D.class);

    private static final int X = 0;

    private static final int Y = 1;

    private static final int X1 = 0;

    private static final int Y1 = 1;

    private static final int X2 = 2;

    private static final int Y2 = 3;

    private static final int X3 = 4;

    private static final int Y3 = 5;

    /** graphics object */
    private GraphicsObject graphicsObj = null;

    /** Fallback text handler */
    protected TextHandler fallbackTextHandler = new StrokingTextHandler();

    /** Custom text handler */
    protected TextHandler customTextHandler = null;

    /** AFP resource manager */
    private AFPResourceManager resourceManager = null;

    /** AFP resource info */
    private AFPResourceInfo resourceInfo = null;

    /** Current AFP state */
    private AFPPaintingState paintingState = null;

    /** AFP graphics configuration */
    private final AFPGraphicsConfiguration graphicsConfig = new AFPGraphicsConfiguration();

    /** The AFP FontInfo */
    private FontInfo fontInfo;

    /**
     * Main constructor
     *
     * @param textAsShapes
     *            if true, all text is turned into shapes in the convertion. No
     *            text is output.
     * @param paintingState painting state
     * @param resourceManager resource manager
     * @param resourceInfo resource info
     * @param fontInfo font info
     */
    public AFPGraphics2D(boolean textAsShapes, AFPPaintingState paintingState,
            AFPResourceManager resourceManager, AFPResourceInfo resourceInfo,
            FontInfo fontInfo) {
        super(textAsShapes);
        setPaintingState(paintingState);
        setResourceManager(resourceManager);
        setResourceInfo(resourceInfo);
        setFontInfo(fontInfo);
    }

    /**
     * Copy Constructor
     *
     * @param g2d
     *            a AFPGraphics2D whose properties should be copied
     */
    public AFPGraphics2D(AFPGraphics2D g2d) {
        super(g2d);
        this.paintingState = g2d.paintingState;
        this.resourceManager = g2d.resourceManager;
        this.resourceInfo = g2d.resourceInfo;
        this.fontInfo = g2d.fontInfo;

        this.graphicsObj = g2d.graphicsObj;
        this.fallbackTextHandler = g2d.fallbackTextHandler;
        this.customTextHandler = g2d.customTextHandler;
    }

    /**
     * Sets the AFP resource manager
     *
     * @param resourceManager the AFP resource manager
     */
    private void setResourceManager(AFPResourceManager resourceManager) {
        this.resourceManager = resourceManager;
    }

    /**
     * Sets the AFP resource info
     *
     * @param resourceInfo the AFP resource info
     */
    private void setResourceInfo(AFPResourceInfo resourceInfo) {
        this.resourceInfo = resourceInfo;
    }

    /**
     * Returns the GOCA graphics object
     *
     * @return the GOCA graphics object
     */
    public GraphicsObject getGraphicsObject() {
        return this.graphicsObj;
    }

    /**
     * Sets the GOCA graphics object
     *
     * @param obj the GOCA graphics object
     */
    public void setGraphicsObject(GraphicsObject obj) {
        this.graphicsObj = obj;
    }

    /**
     * Sets the AFP painting state
     *
     * @param paintingState the AFP painting state
     */
    private void setPaintingState(AFPPaintingState paintingState) {
        this.paintingState = paintingState;
    }

    /**
     * Returns the AFP painting state
     *
     * @return the AFP painting state
     */
    public AFPPaintingState getPaintingState() {
        return this.paintingState;
    }

    /**
     * Sets the FontInfo
     *
     * @param fontInfo the FontInfo
     */
    private void setFontInfo(FontInfo fontInfo) {
        this.fontInfo = fontInfo;
    }

    /**
     * Returns the FontInfo
     *
     * @return the FontInfo
     */
    public FontInfo getFontInfo() {
        return this.fontInfo;
    }

    /**
     * Sets the GraphicContext
     *
     * @param gc
     *            GraphicContext to use
     */
    public void setGraphicContext(GraphicContext gc) {
        this.gc = gc;
    }

    private int getResolution() {
        return this.paintingState.getResolution();
    }

    /**
     * Converts a length value to an absolute value.
     * Please note that this only uses the "ScaleY" factor, so this will result
     * in a bad value should "ScaleX" and "ScaleY" be different.
     * @param length the length
     * @return the absolute length
     */
    public double convertToAbsoluteLength(double length) {
        AffineTransform current = getTransform();
        double mult = getResolution() / (double)UnitConv.IN2PT;
        double factor = -current.getScaleY() / mult;
        return length * factor;
    }

    /** IBM's AFP Workbench paints lines that are wider than expected. We correct manually. */
    private static final double GUESSED_WIDTH_CORRECTION = 1.7;

    private static final double SPEC_NORMAL_LINE_WIDTH = UnitConv.in2pt(0.01); //"approx" 0.01 inch
    private static final double NORMAL_LINE_WIDTH
        = SPEC_NORMAL_LINE_WIDTH * GUESSED_WIDTH_CORRECTION;


    /**
     * Apply the stroke to the AFP graphics object.
     * This takes the java stroke and outputs the appropriate settings
     * to the AFP graphics object so that the stroke attributes are handled.
     *
     * @param stroke the java stroke
     */
    protected void applyStroke(Stroke stroke) {
        if (stroke instanceof BasicStroke) {
            BasicStroke basicStroke = (BasicStroke) stroke;

            // set line width
            float lineWidth = basicStroke.getLineWidth();
            if (false) {
                //Old approach. Retained until verified problems with 1440 resolution
                graphicsObj.setLineWidth(Math.round(lineWidth / 2));
            } else {
                double absoluteLineWidth = lineWidth * Math.abs(getTransform().getScaleY());
                double multiplier = absoluteLineWidth / NORMAL_LINE_WIDTH;
                graphicsObj.setLineWidth((int)Math.round(multiplier));
                //TODO Use GSFLW instead of GSLW for higher accuracy?
            }

            //No line join, miter limit and end cap support in GOCA. :-(

            // set line type/style (note: this is an approximation at best!)
            float[] dashArray = basicStroke.getDashArray();
            if (paintingState.setDashArray(dashArray)) {
                byte type = GraphicsSetLineType.DEFAULT; // normally SOLID
                if (dashArray != null) {
                    type = GraphicsSetLineType.DOTTED; // default to plain DOTTED if dashed line
                    // float offset = basicStroke.getDashPhase();
                    if (dashArray.length == 2) {
                        if (dashArray[0] < dashArray[1]) {
                            type = GraphicsSetLineType.SHORT_DASHED;
                        } else if (dashArray[0] > dashArray[1]) {
                            type = GraphicsSetLineType.LONG_DASHED;
                        }
                    } else if (dashArray.length == 4) {
                        if (dashArray[0] > dashArray[1]
                         && dashArray[2] < dashArray[3]) {
                            type = GraphicsSetLineType.DASH_DOT;
                        } else if (dashArray[0] < dashArray[1]
                                && dashArray[2] < dashArray[3]) {
                            type = GraphicsSetLineType.DOUBLE_DOTTED;
                        }
                    } else if (dashArray.length == 6) {
                        if (dashArray[0] > dashArray[1]
                         && dashArray[2] < dashArray[3]
                         && dashArray[4] < dashArray[5]) {
                            type = GraphicsSetLineType.DASH_DOUBLE_DOTTED;
                        }
                    }
                }
                graphicsObj.setLineType(type);
            }
        } else {
            log.warn("Unsupported Stroke: " + stroke.getClass().getName());
        }
    }

    /**
     * Apply the java paint to the AFP.
     * This takes the java paint sets up the appropriate AFP commands
     * for the drawing with that paint.
     * Currently this supports the gradients and patterns from batik.
     *
     * @param paint the paint to convert to AFP
     * @param fill true if the paint should be set for filling
     * @return true if the paint is handled natively, false if the paint should be rasterized
     */
    private boolean applyPaint(Paint paint, boolean fill) {
        if (paint instanceof Color) {
            return true;
        }
        log.debug("NYI: applyPaint() " + paint + " fill=" + fill);
        if (paint instanceof TexturePaint) {
//            TexturePaint texturePaint = (TexturePaint)paint;
//            BufferedImage bufferedImage = texturePaint.getImage();
//            AffineTransform at = paintingState.getTransform();
//            int x = (int)Math.round(at.getTranslateX());
//            int y = (int)Math.round(at.getTranslateY());
//            drawImage(bufferedImage, x, y, null);
        }
        return false;
    }


    /**
     * Handle the Batik drawing event
     *
     * @param shape
     *            the shape to draw
     * @param fill
     *            true if the shape is to be drawn filled
     */
    private void doDrawing(Shape shape, boolean fill) {
        if (!fill) {
            graphicsObj.newSegment();
        }

        graphicsObj.setColor(gc.getColor());

        applyPaint(gc.getPaint(), fill);

        if (fill) {
            graphicsObj.beginArea();
        } else {
            applyStroke(gc.getStroke());
        }

        AffineTransform trans = gc.getTransform();
        PathIterator iter = shape.getPathIterator(trans);
        if (shape instanceof Line2D) {
            double[] dstPts = new double[6];
            iter.currentSegment(dstPts);
            int[] coords = new int[4];
            coords[X1] = (int) Math.round(dstPts[X]);
            coords[Y1] = (int) Math.round(dstPts[Y]);
            iter.next();
            iter.currentSegment(dstPts);
            coords[X2] = (int) Math.round(dstPts[X]);
            coords[Y2] = (int) Math.round(dstPts[Y]);
            graphicsObj.addLine(coords);
        } else if (shape instanceof Rectangle2D) {
            double[] dstPts = new double[6];
            iter.currentSegment(dstPts);
            int[] coords = new int[4];
            coords[X2] = (int) Math.round(dstPts[X]);
            coords[Y2] = (int) Math.round(dstPts[Y]);
            iter.next();
            iter.next();
            iter.currentSegment(dstPts);
            coords[X1] = (int) Math.round(dstPts[X]);
            coords[Y1] = (int) Math.round(dstPts[Y]);
            graphicsObj.addBox(coords);
        } else if (shape instanceof Ellipse2D) {
            double[] dstPts = new double[6];
            Ellipse2D elip = (Ellipse2D) shape;
            double scale = trans.getScaleX();
            double radiusWidth = elip.getWidth() / 2;
            double radiusHeight = elip.getHeight() / 2;
            graphicsObj.setArcParams(
                    (int)Math.round(radiusWidth * scale),
                    (int)Math.round(radiusHeight * scale),
                    0,
                    0
            );
            double[] srcPts = new double[] {elip.getCenterX(), elip.getCenterY()};
            trans.transform(srcPts, 0, dstPts, 0, 1);
            final int mh = 1;
            final int mhr = 0;
            graphicsObj.addFullArc(
                    (int)Math.round(dstPts[X]),
                    (int)Math.round(dstPts[Y]),
                    mh,
                    mhr
            );
        } else {
            processPathIterator(iter);
        }

        if (fill) {
            graphicsObj.endArea();
        }
    }

    /**
     * Processes a path iterator generating the necessary painting operations.
     *
     * @param iter PathIterator to process
     */
    private void processPathIterator(PathIterator iter) {
        double[] dstPts = new double[6];
        double[] currentPosition = new double[2];
        for (int[] openingCoords = new int[2]; !iter.isDone(); iter.next()) {
            switch (iter.currentSegment(dstPts)) {
            case PathIterator.SEG_LINETO:
                graphicsObj.addLine(new int[] {
                        (int)Math.round(dstPts[X]),
                        (int)Math.round(dstPts[Y])
                     }, true);
                currentPosition = new double[]{dstPts[X], dstPts[Y]};
                break;
            case PathIterator.SEG_QUADTO:
                graphicsObj.addFillet(new int[] {
                        (int)Math.round(dstPts[X1]),
                        (int)Math.round(dstPts[Y1]),
                        (int)Math.round(dstPts[X2]),
                        (int)Math.round(dstPts[Y2])
                     }, true);
                currentPosition = new double[]{dstPts[X2], dstPts[Y2]};
                break;
            case PathIterator.SEG_CUBICTO:
                double[] cubicCoords = new double[] {currentPosition[0], currentPosition[1],
                    dstPts[X1], dstPts[Y1], dstPts[X2], dstPts[Y2], dstPts[X3], dstPts[Y3]};
                double[][] quadParts = CubicBezierApproximator.fixedMidPointApproximation(
                        cubicCoords);
                if (quadParts.length >= 4) {
                    for (int segIndex = 0; segIndex < quadParts.length; segIndex++) {
                        double[] quadPts = quadParts[segIndex];
                        if (quadPts != null && quadPts.length == 4) {
                            graphicsObj.addFillet(new int[]{
                                    (int) Math.round(quadPts[X1]),
                                    (int) Math.round(quadPts[Y1]),
                                    (int) Math.round(quadPts[X2]),
                                    (int) Math.round(quadPts[Y2])
                            }, true);
                            currentPosition = new double[]{quadPts[X2], quadPts[Y2]};
                        }
                    }
                }
                break;
            case PathIterator.SEG_MOVETO:
                openingCoords = new int[] {
                        (int)Math.round(dstPts[X]),
                        (int)Math.round(dstPts[Y])
                };
                currentPosition = new double[]{dstPts[X], dstPts[Y]};
                graphicsObj.setCurrentPosition(openingCoords);
                break;
            case PathIterator.SEG_CLOSE:
                graphicsObj.addLine(openingCoords, true);
                currentPosition = new double[]{openingCoords[0], openingCoords[1]};
                break;
            default:
                log.debug("Unrecognised path iterator type");
                break;
            }
        }
    }

    /** {@inheritDoc} */
    public void draw(Shape shape) {
        log.debug("draw() shape=" + shape);
        doDrawing(shape, false);
    }

    /** {@inheritDoc} */
    public void fill(Shape shape) {
        log.debug("fill() shape=" + shape);
        doDrawing(shape, true);
    }

    /**
     * Central handler for IOExceptions for this class.
     *
     * @param ioe
     *            IOException to handle
     */
    public void handleIOException(IOException ioe) {
        // TODO Surely, there's a better way to do this.
        log.error(ioe.getMessage());
        ioe.printStackTrace();
    }

    /** {@inheritDoc} */
    public void drawString(String str, float x, float y) {
        try {
            if (customTextHandler != null && !textAsShapes) {
                customTextHandler.drawString(this, str, x, y);
            } else {
                fallbackTextHandler.drawString(this, str, x, y);
            }
        } catch (IOException ioe) {
            handleIOException(ioe);
        }
    }

    /** {@inheritDoc} */
    public GraphicsConfiguration getDeviceConfiguration() {
        return graphicsConfig;
    }

    /** {@inheritDoc} */
    public Graphics create() {
        return new AFPGraphics2D(this);
    }

    /** {@inheritDoc} */
    public void dispose() {
        this.graphicsObj = null;
    }

    /** {@inheritDoc} */
    public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
        return drawImage(img, x, y, img.getWidth(observer), img.getHeight(observer), observer);
    }

    private BufferedImage buildBufferedImage(Dimension size) {
        return new BufferedImage(size.width, size.height,
                                 BufferedImage.TYPE_INT_ARGB);
    }

    private AFPImageObjectInfo createImageObjectInfo(
            RenderedImage img, int x, int y, int width, int height) throws IOException {
        ImageInfo imageInfo = new ImageInfo(null, "image/unknown");
        ImageSize size = new ImageSize(img.getWidth(), img.getHeight(), 72);
        imageInfo.setSize(size);

        ImageRendered imageRendered = new ImageRendered(imageInfo, img, null);
        RenderedImage renderedImage = imageRendered.getRenderedImage();

        // create image object info
        AFPImageObjectInfo imageObjectInfo = new AFPImageObjectInfo();

        imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS45);

        int bitsPerPixel = paintingState.getBitsPerPixel();
        imageObjectInfo.setBitsPerPixel(bitsPerPixel);

        imageObjectInfo.setResourceInfo(resourceInfo);

        int dataHeight = renderedImage.getHeight();
        imageObjectInfo.setDataHeight(dataHeight);

        int dataWidth = renderedImage.getWidth();
        imageObjectInfo.setDataWidth(dataWidth);

        boolean colorImages = paintingState.isColorImages();
        imageObjectInfo.setColor(colorImages);

        ByteArrayOutputStream boas = new ByteArrayOutputStream();
        ImageEncodingHelper.encodeRenderedImageAsRGB(renderedImage, boas);
        byte[] imageData = boas.toByteArray();

        // convert to grayscale
        if (!colorImages) {
            boas.reset();
            imageObjectInfo.setBitsPerPixel(bitsPerPixel);
            ImageEncodingHelper.encodeRGBAsGrayScale(
                  imageData, dataWidth, dataHeight, bitsPerPixel, boas);
            imageData = boas.toByteArray();
        }
        imageObjectInfo.setData(imageData);

        if (imageInfo != null) {
            imageObjectInfo.setUri(imageInfo.getOriginalURI());
        }

        // create object area info
        AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo();
        objectAreaInfo.setX(x);
        objectAreaInfo.setY(y);
        objectAreaInfo.setWidth(width);
        objectAreaInfo.setHeight(height);

        int resolution = paintingState.getResolution();
        objectAreaInfo.setWidthRes(resolution);
        objectAreaInfo.setHeightRes(resolution);

        imageObjectInfo.setObjectAreaInfo(objectAreaInfo);

        return imageObjectInfo;
    }

    /**
     * Draws an AWT image into a BufferedImage using an AWT Graphics2D implementation
     *
     * @param img the AWT image
     * @param bufferedImage the AWT buffered image
     * @param width the image width
     * @param height the image height
     * @param observer the image observer
     * @return true if the image was drawn
     */
    private boolean drawBufferedImage(Image img, BufferedImage bufferedImage,
            int width, int height, ImageObserver observer) {

        java.awt.Graphics2D g2d = bufferedImage.createGraphics();
        try {
            g2d.setComposite(AlphaComposite.SrcOver);

            Color color = new Color(1, 1, 1, 0);
            g2d.setBackground(color);
            g2d.setPaint(color);

            g2d.fillRect(0, 0, width, height);

            int imageWidth = bufferedImage.getWidth();
            int imageHeight = bufferedImage.getHeight();
            Rectangle clipRect = new Rectangle(0, 0, imageWidth, imageHeight);
            g2d.clip(clipRect);

            g2d.setComposite(gc.getComposite());

            return g2d.drawImage(img, 0, 0, imageWidth, imageHeight, observer);
        } finally {
            g2d.dispose(); //drawn so dispose immediately to free system resource
        }
    }

    /** {@inheritDoc} */
    public boolean drawImage(Image img, int x, int y, int width, int height,
            ImageObserver observer) {

        // draw with AWT Graphics2D
        Dimension imageSize = new Dimension(width, height);
        BufferedImage bufferedImage = buildBufferedImage(imageSize);

        boolean drawn = drawBufferedImage(img, bufferedImage, width, height, observer);
        if (drawn) {
            AffineTransform at = gc.getTransform();
            float[] srcPts = new float[] {x, y};
            float[] dstPts = new float[srcPts.length];
            at.transform(srcPts, 0, dstPts, 0, 1);
            x = Math.round(dstPts[X]);
            y = Math.round(dstPts[Y]);
            try {
                // get image object info
                AFPImageObjectInfo imageObjectInfo
                    = createImageObjectInfo(bufferedImage, x, y, width, height);

                // create image resource
                resourceManager.createObject(imageObjectInfo);
                return true;
            } catch (IOException ioe) {
                handleIOException(ioe);
            }
        }
        return false;
    }

    /** {@inheritDoc} */
    public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
        int imgWidth = img.getWidth();
        int imgHeight = img.getHeight();

        AffineTransform at = paintingState.getData().getTransform();
        AffineTransform gat = gc.getTransform();
        int graphicsObjectHeight
            = graphicsObj.getObjectEnvironmentGroup().getObjectAreaDescriptor().getHeight();
        int x = (int)Math.round(at.getTranslateX() + gat.getTranslateX());
        int y = (int)Math.round(at.getTranslateY() - (gat.getTranslateY() - graphicsObjectHeight));
        int width = (int)Math.round(imgWidth * gat.getScaleX());
        int height = (int)Math.round(imgHeight * -gat.getScaleY());
        try {
            // get image object info
            AFPImageObjectInfo imageObjectInfo
                = createImageObjectInfo(img, x, y, width, height);
            // create image resource
            resourceManager.createObject(imageObjectInfo);
        } catch (IOException ioe) {
            handleIOException(ioe);
        }
    }

    /**
     * Sets a custom TextHandler implementation that is responsible for painting
     * text. The default TextHandler paints all text as shapes. A custom
     * implementation can implement text painting using text painting operators.
     *
     * @param handler
     *            the custom TextHandler implementation
     */
    public void setCustomTextHandler(TextHandler handler) {
        this.customTextHandler = handler;
    }

    /** {@inheritDoc} */
    public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
        log.debug("drawRenderableImage() NYI: img=" + img + ", xform=" + xform);
    }

    /** {@inheritDoc} */
    public FontMetrics getFontMetrics(Font f) {
        log.debug("getFontMetrics() NYI: f=" + f);
        return null;
    }

    /** {@inheritDoc} */
    public void setXORMode(Color col) {
        log.debug("setXORMode() NYI: col=" + col);
    }

    /** {@inheritDoc} */
    public void addNativeImage(org.apache.xmlgraphics.image.loader.Image image,
            float x, float y, float width, float height) {
        log.debug("NYI: addNativeImage() " + "image=" + image
                + ",x=" + x + ",y=" + y + ",width=" + width + ",height=" + height);
    }

    /** {@inheritDoc} */
    public void copyArea(int x, int y, int width, int height, int dx, int dy) {
        log.debug("copyArea() NYI: ");
    }
}
