/*
 * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.java2d.pipe;

import java.awt.BasicStroke;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.awt.geom.IllegalPathStateException;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import sun.java2d.SunGraphics2D;
import sun.java2d.loops.ProcessPath;
import static sun.java2d.pipe.BufferedOpCodes.*;

/**
 * Base class for enqueuing rendering operations in a single-threaded
 * rendering environment.  Instead of each operation being rendered
 * immediately by the underlying graphics library, the operation will be
 * added to the provided RenderQueue, which will be processed at a later
 * time by a single thread.
 *
 * This class provides implementations of drawLine(), drawRect(), drawPoly(),
 * fillRect(), draw(Shape), and fill(Shape), which are useful for a
 * hardware-accelerated renderer.  The other draw*() and fill*() methods
 * simply delegate to draw(Shape) and fill(Shape), respectively.
 */
public abstract class BufferedRenderPipe
    implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe, ParallelogramPipe
{
    ParallelogramPipe aapgrampipe = new AAParallelogramPipe();

    static final int BYTES_PER_POLY_POINT = 8;
    static final int BYTES_PER_SCANLINE = 12;
    static final int BYTES_PER_SPAN = 16;

    protected RenderQueue rq;
    protected RenderBuffer buf;
    private BufferedDrawHandler drawHandler;

    public BufferedRenderPipe(RenderQueue rq) {
        this.rq = rq;
        this.buf = rq.getBuffer();
        this.drawHandler = new BufferedDrawHandler();
    }

    public ParallelogramPipe getAAParallelogramPipe() {
        return aapgrampipe;
    }

    /**
     * Validates the state in the provided SunGraphics2D object and sets up
     * any special resources for this operation (e.g. enabling gradient
     * shading).
     */
    protected abstract void validateContext(SunGraphics2D sg2d);
    protected abstract void validateContextAA(SunGraphics2D sg2d);

    public void drawLine(SunGraphics2D sg2d,
                         int x1, int y1, int x2, int y2)
    {
        int transx = sg2d.transX;
        int transy = sg2d.transY;
        rq.lock();
        try {
            validateContext(sg2d);
            rq.ensureCapacity(20);
            buf.putInt(DRAW_LINE);
            buf.putInt(x1 + transx);
            buf.putInt(y1 + transy);
            buf.putInt(x2 + transx);
            buf.putInt(y2 + transy);
        } finally {
            rq.unlock();
        }
    }

    public void drawRect(SunGraphics2D sg2d,
                         int x, int y, int width, int height)
    {
        rq.lock();
        try {
            validateContext(sg2d);
            rq.ensureCapacity(20);
            buf.putInt(DRAW_RECT);
            buf.putInt(x + sg2d.transX);
            buf.putInt(y + sg2d.transY);
            buf.putInt(width);
            buf.putInt(height);
        } finally {
            rq.unlock();
        }
    }

    public void fillRect(SunGraphics2D sg2d,
                         int x, int y, int width, int height)
    {
        rq.lock();
        try {
            validateContext(sg2d);
            rq.ensureCapacity(20);
            buf.putInt(FILL_RECT);
            buf.putInt(x + sg2d.transX);
            buf.putInt(y + sg2d.transY);
            buf.putInt(width);
            buf.putInt(height);
        } finally {
            rq.unlock();
        }
    }

    public void drawRoundRect(SunGraphics2D sg2d,
                              int x, int y, int width, int height,
                              int arcWidth, int arcHeight)
    {
        draw(sg2d, new RoundRectangle2D.Float(x, y, width, height,
                                              arcWidth, arcHeight));
    }

    public void fillRoundRect(SunGraphics2D sg2d,
                              int x, int y, int width, int height,
                              int arcWidth, int arcHeight)
    {
        fill(sg2d, new RoundRectangle2D.Float(x, y, width, height,
                                              arcWidth, arcHeight));
    }

    public void drawOval(SunGraphics2D sg2d,
                         int x, int y, int width, int height)
    {
        draw(sg2d, new Ellipse2D.Float(x, y, width, height));
    }

    public void fillOval(SunGraphics2D sg2d,
                         int x, int y, int width, int height)
    {
        fill(sg2d, new Ellipse2D.Float(x, y, width, height));
    }

    public void drawArc(SunGraphics2D sg2d,
                        int x, int y, int width, int height,
                        int startAngle, int arcAngle)
    {
        draw(sg2d, new Arc2D.Float(x, y, width, height,
                                   startAngle, arcAngle,
                                   Arc2D.OPEN));
    }

    public void fillArc(SunGraphics2D sg2d,
                        int x, int y, int width, int height,
                        int startAngle, int arcAngle)
    {
        fill(sg2d, new Arc2D.Float(x, y, width, height,
                                   startAngle, arcAngle,
                                   Arc2D.PIE));
    }

    protected void drawPoly(final SunGraphics2D sg2d,
                            final int[] xPoints, final int[] yPoints,
                            final int nPoints, final boolean isClosed)
    {
        if (xPoints == null || yPoints == null) {
            throw new NullPointerException("coordinate array");
        }
        if (xPoints.length < nPoints || yPoints.length < nPoints) {
            throw new ArrayIndexOutOfBoundsException("coordinate array");
        }

        if (nPoints < 2) {
            // render nothing
            return;
        } else if (nPoints == 2 && !isClosed) {
            // render a simple line
            drawLine(sg2d, xPoints[0], yPoints[0], xPoints[1], yPoints[1]);
            return;
        }

        rq.lock();
        try {
            validateContext(sg2d);

            int pointBytesRequired = nPoints * BYTES_PER_POLY_POINT;
            int totalBytesRequired = 20 + pointBytesRequired;

            if (totalBytesRequired <= buf.capacity()) {
                if (totalBytesRequired > buf.remaining()) {
                    // process the queue first and then enqueue the points
                    rq.flushNow();
                }
                buf.putInt(DRAW_POLY);
                // enqueue parameters
                buf.putInt(nPoints);
                buf.putInt(isClosed ? 1 : 0);
                buf.putInt(sg2d.transX);
                buf.putInt(sg2d.transY);
                // enqueue the points
                buf.put(xPoints, 0, nPoints);
                buf.put(yPoints, 0, nPoints);
            } else {
                // queue is too small to accomodate all points; perform the
                // operation directly on the queue flushing thread
                rq.flushAndInvokeNow(new Runnable() {
                    public void run() {
                        drawPoly(xPoints, yPoints,
                                 nPoints, isClosed,
                                 sg2d.transX, sg2d.transY);
                    }
                });
            }
        } finally {
            rq.unlock();
        }
    }

    protected abstract void drawPoly(int[] xPoints, int[] yPoints,
                                     int nPoints, boolean isClosed,
                                     int transX, int transY);

    public void drawPolyline(SunGraphics2D sg2d,
                             int[] xPoints, int[] yPoints,
                             int nPoints)
    {
        drawPoly(sg2d, xPoints, yPoints, nPoints, false);
    }

    public void drawPolygon(SunGraphics2D sg2d,
                            int[] xPoints, int[] yPoints,
                            int nPoints)
    {
        drawPoly(sg2d, xPoints, yPoints, nPoints, true);
    }

    public void fillPolygon(SunGraphics2D sg2d,
                            int[] xPoints, int[] yPoints,
                            int nPoints)
    {
        fill(sg2d, new Polygon(xPoints, yPoints, nPoints));
    }

    private class BufferedDrawHandler
        extends ProcessPath.DrawHandler
    {
        BufferedDrawHandler() {
            // these are bogus values; the caller will use validate()
            // to ensure that they are set properly prior to each usage
            super(0, 0, 0, 0);
        }

        /**
         * This method needs to be called prior to each draw/fillPath()
         * operation to ensure the clip bounds are up to date.
         */
        void validate(SunGraphics2D sg2d) {
            Region clip = sg2d.getCompClip();
            setBounds(clip.getLoX(), clip.getLoY(),
                      clip.getHiX(), clip.getHiY(),
                      sg2d.strokeHint);
        }

        /**
         * drawPath() support...
         */

        public void drawLine(int x1, int y1, int x2, int y2) {
            // assert rq.lock.isHeldByCurrentThread();
            rq.ensureCapacity(20);
            buf.putInt(DRAW_LINE);
            buf.putInt(x1);
            buf.putInt(y1);
            buf.putInt(x2);
            buf.putInt(y2);
        }

        public void drawPixel(int x, int y) {
            // assert rq.lock.isHeldByCurrentThread();
            rq.ensureCapacity(12);
            buf.putInt(DRAW_PIXEL);
            buf.putInt(x);
            buf.putInt(y);
        }

        /**
         * fillPath() support...
         */

        private int scanlineCount;
        private int scanlineCountIndex;
        private int remainingScanlines;

        private void resetFillPath() {
            buf.putInt(DRAW_SCANLINES);
            scanlineCountIndex = buf.position();
            buf.putInt(0);
            scanlineCount = 0;
            remainingScanlines = buf.remaining() / BYTES_PER_SCANLINE;
        }

        private void updateScanlineCount() {
            buf.putInt(scanlineCountIndex, scanlineCount);
        }

        /**
         * Called from fillPath() to indicate that we are about to
         * start issuing drawScanline() calls.
         */
        public void startFillPath() {
            rq.ensureCapacity(20); // to ensure room for at least a scanline
            resetFillPath();
        }

        public void drawScanline(int x1, int x2, int y) {
            if (remainingScanlines == 0) {
                updateScanlineCount();
                rq.flushNow();
                resetFillPath();
            }
            buf.putInt(x1);
            buf.putInt(x2);
            buf.putInt(y);
            scanlineCount++;
            remainingScanlines--;
        }

        /**
         * Called from fillPath() to indicate that we are done
         * issuing drawScanline() calls.
         */
        public void endFillPath() {
            updateScanlineCount();
        }
    }

    protected void drawPath(SunGraphics2D sg2d,
                            Path2D.Float p2df, int transx, int transy)
    {
        rq.lock();
        try {
            validateContext(sg2d);
            drawHandler.validate(sg2d);
            ProcessPath.drawPath(drawHandler, p2df, transx, transy);
        } finally {
            rq.unlock();
        }
    }

    protected void fillPath(SunGraphics2D sg2d,
                            Path2D.Float p2df, int transx, int transy)
    {
        rq.lock();
        try {
            validateContext(sg2d);
            drawHandler.validate(sg2d);
            drawHandler.startFillPath();
            ProcessPath.fillPath(drawHandler, p2df, transx, transy);
            drawHandler.endFillPath();
        } finally {
            rq.unlock();
        }
    }

    private native int fillSpans(RenderQueue rq, long buf,
                                 int pos, int limit,
                                 SpanIterator si, long iterator,
                                 int transx, int transy);

    protected void fillSpans(SunGraphics2D sg2d, SpanIterator si,
                             int transx, int transy)
    {
        rq.lock();
        try {
            validateContext(sg2d);
            rq.ensureCapacity(24); // so that we have room for at least a span
            int newpos = fillSpans(rq, buf.getAddress(),
                                   buf.position(), buf.capacity(),
                                   si, si.getNativeIterator(),
                                   transx, transy);
            buf.position(newpos);
        } finally {
            rq.unlock();
        }
    }

    public void fillParallelogram(SunGraphics2D sg2d,
                                  double x, double y,
                                  double dx1, double dy1,
                                  double dx2, double dy2)
    {
        rq.lock();
        try {
            validateContext(sg2d);
            rq.ensureCapacity(28);
            buf.putInt(FILL_PARALLELOGRAM);
            buf.putFloat((float) x);
            buf.putFloat((float) y);
            buf.putFloat((float) dx1);
            buf.putFloat((float) dy1);
            buf.putFloat((float) dx2);
            buf.putFloat((float) dy2);
        } finally {
            rq.unlock();
        }
    }

    public void drawParallelogram(SunGraphics2D sg2d,
                                  double x, double y,
                                  double dx1, double dy1,
                                  double dx2, double dy2,
                                  double lw1, double lw2)
    {
        rq.lock();
        try {
            validateContext(sg2d);
            rq.ensureCapacity(36);
            buf.putInt(DRAW_PARALLELOGRAM);
            buf.putFloat((float) x);
            buf.putFloat((float) y);
            buf.putFloat((float) dx1);
            buf.putFloat((float) dy1);
            buf.putFloat((float) dx2);
            buf.putFloat((float) dy2);
            buf.putFloat((float) lw1);
            buf.putFloat((float) lw2);
        } finally {
            rq.unlock();
        }
    }

    private class AAParallelogramPipe implements ParallelogramPipe {
        public void fillParallelogram(SunGraphics2D sg2d,
                                      double x, double y,
                                      double dx1, double dy1,
                                      double dx2, double dy2)
        {
            rq.lock();
            try {
                validateContextAA(sg2d);
                rq.ensureCapacity(28);
                buf.putInt(FILL_AAPARALLELOGRAM);
                buf.putFloat((float) x);
                buf.putFloat((float) y);
                buf.putFloat((float) dx1);
                buf.putFloat((float) dy1);
                buf.putFloat((float) dx2);
                buf.putFloat((float) dy2);
            } finally {
                rq.unlock();
            }
        }

        public void drawParallelogram(SunGraphics2D sg2d,
                                      double x, double y,
                                      double dx1, double dy1,
                                      double dx2, double dy2,
                                      double lw1, double lw2)
        {
            rq.lock();
            try {
                validateContextAA(sg2d);
                rq.ensureCapacity(36);
                buf.putInt(DRAW_AAPARALLELOGRAM);
                buf.putFloat((float) x);
                buf.putFloat((float) y);
                buf.putFloat((float) dx1);
                buf.putFloat((float) dy1);
                buf.putFloat((float) dx2);
                buf.putFloat((float) dy2);
                buf.putFloat((float) lw1);
                buf.putFloat((float) lw2);
            } finally {
                rq.unlock();
            }
        }
    }

    public void draw(SunGraphics2D sg2d, Shape s) {
        if (sg2d.strokeState == sg2d.STROKE_THIN) {
            if (s instanceof Polygon) {
                if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE) {
                    Polygon p = (Polygon)s;
                    drawPolygon(sg2d, p.xpoints, p.ypoints, p.npoints);
                    return;
                }
            }
            Path2D.Float p2df;
            int transx, transy;
            if (sg2d.transformState <= sg2d.TRANSFORM_INT_TRANSLATE) {
                if (s instanceof Path2D.Float) {
                    p2df = (Path2D.Float)s;
                } else {
                    p2df = new Path2D.Float(s);
                }
                transx = sg2d.transX;
                transy = sg2d.transY;
            } else {
                p2df = new Path2D.Float(s, sg2d.transform);
                transx = 0;
                transy = 0;
            }
            drawPath(sg2d, p2df, transx, transy);
        } else if (sg2d.strokeState < sg2d.STROKE_CUSTOM) {
            ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s);
            try {
                fillSpans(sg2d, si, 0, 0);
            } finally {
                si.dispose();
            }
        } else {
            fill(sg2d, sg2d.stroke.createStrokedShape(s));
        }
    }

    public void fill(SunGraphics2D sg2d, Shape s) {
        int transx, transy;

        if (sg2d.strokeState == sg2d.STROKE_THIN) {
            // Here we are able to use fillPath() for
            // high-quality fills.
            Path2D.Float p2df;
            if (sg2d.transformState <= sg2d.TRANSFORM_INT_TRANSLATE) {
                if (s instanceof Path2D.Float) {
                    p2df = (Path2D.Float)s;
                } else {
                    p2df = new Path2D.Float(s);
                }
                transx = sg2d.transX;
                transy = sg2d.transY;
            } else {
                p2df = new Path2D.Float(s, sg2d.transform);
                transx = 0;
                transy = 0;
            }
            fillPath(sg2d, p2df, transx, transy);
            return;
        }

        AffineTransform at;
        if (sg2d.transformState <= sg2d.TRANSFORM_INT_TRANSLATE) {
            // Transform (translation) will be done by FillSpans (we could
            // delegate to fillPolygon() here, but most hardware accelerated
            // libraries cannot handle non-convex polygons, so we will use
            // the FillSpans approach by default)
            at = null;
            transx = sg2d.transX;
            transy = sg2d.transY;
        } else {
            // Transform will be done by the PathIterator
            at = sg2d.transform;
            transx = transy = 0;
        }

        ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);
        try {
            // Subtract transx/y from the SSI clip to match the
            // (potentially untranslated) geometry fed to it
            Region clip = sg2d.getCompClip();
            ssi.setOutputAreaXYXY(clip.getLoX() - transx,
                                  clip.getLoY() - transy,
                                  clip.getHiX() - transx,
                                  clip.getHiY() - transy);
            ssi.appendPath(s.getPathIterator(at));
            fillSpans(sg2d, ssi, transx, transy);
        } finally {
            ssi.dispose();
        }
    }
}
