/*
 * Copyright 1999-2002 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.java2d.pipe;

/**
 * This class implements the ShapeIterator interface for a Region.
 * This is useful as the source iterator of a device clip region
 * (in its native guise), and also as the result of clipping a
 * Region to a rectangle.
 */
public class RegionSpanIterator implements SpanIterator {
    // The RegionIterator that we use to do the work
    RegionIterator ri;

    // Clipping bounds
    int lox, loy, hix, hiy;

    // Current Y band limits
    int curloy, curhiy;

    // Are we done?
    boolean done = false;

    // Is the associated Region rectangular?
    boolean isrect;

/*
    REMIND: For native implementation
    long pData;     // Private storage of rect info

    static {
        initIDs();
    }

    public static native void initIDs();
*/

    /**
     * Constructs an instance based on the given Region
     */
    public RegionSpanIterator(Region r) {
        int[] bounds = new int[4];

        r.getBounds(bounds);
        lox = bounds[0];
        loy = bounds[1];
        hix = bounds[2];
        hiy = bounds[3];
        isrect = r.isRectangular();

        ri = r.getIterator();
    }

    /**
     * Gets the bbox of the available region spans.
     */
    public void getPathBox(int pathbox[]) {
        pathbox[0] = lox;
        pathbox[1] = loy;
        pathbox[2] = hix;
        pathbox[3] = hiy;
    }

    /**
     * Intersect the box used for clipping the output spans with the
     * given box.
     */
    public void intersectClipBox(int clox, int cloy, int chix, int chiy) {
        if (clox > lox) {
            lox = clox;
        }
        if (cloy > loy) {
            loy = cloy;
        }
        if (chix < hix) {
            hix = chix;
        }
        if (chiy < hiy) {
            hiy = chiy;
        }
        done = lox >= hix || loy >= hiy;
    }

    /**
     * Fetches the next span that needs to be operated on.
     * If the return value is false then there are no more spans.
     */
    public boolean nextSpan(int spanbox[]) {

        // Quick test for end conditions
        if (done) {
            return false;
        }

        // If the Region is rectangular, we store our bounds (possibly
        // clipped via intersectClipBox()) in spanbox and return true
        // so that the caller will process the single span.  We set done
        // to true to ensure that this will be the last span processed.
        if (isrect) {
            getPathBox(spanbox);
            done = true;
            return true;
        }

        // Local cache of current span's bounds
        int curlox, curhix;
        int curloy = this.curloy;
        int curhiy = this.curhiy;

        while (true) {
            if (!ri.nextXBand(spanbox)) {
                if (!ri.nextYRange(spanbox)) {
                    done = true;
                    return false;
                }
                // Update the current y band and clip it
                curloy = spanbox[1];
                curhiy = spanbox[3];
                if (curloy < loy) {
                    curloy = loy;
                }
                if (curhiy > hiy) {
                    curhiy = hiy;
                }
                // Check for moving below the clip rect
                if (curloy >= hiy) {
                    done = true;
                    return false;
                }
                continue;
            }
            // Clip the x box
            curlox = spanbox[0];
            curhix = spanbox[2];
            if (curlox < lox) {
                curlox = lox;
            }
            if (curhix > hix) {
                curhix = hix;
            }
            // If it's non- box, we're done
            if (curlox < curhix && curloy < curhiy) {
                break;
            }
        }

        // Update the result and the store y range
        spanbox[0] = curlox;
        spanbox[1] = this.curloy = curloy;
        spanbox[2] = curhix;
        spanbox[3] = this.curhiy = curhiy;
        return true;
    }

    /**
     * This method tells the iterator that it may skip all spans
     * whose Y range is completely above the indicated Y coordinate.
     */
    public void skipDownTo(int y) {
        loy = y;
    }

    /**
     * This method returns a native pointer to a function block that
     * can be used by a native method to perform the same iteration
     * cycle that the above methods provide while avoiding upcalls to
     * the Java object.
     * The definition of the structure whose pointer is returned by
     * this method is defined in:
     * <pre>
     *     src/share/native/sun/java2d/pipe/SpanIterator.h
     * </pre>
     */
    public long getNativeIterator() {
        return 0;
    }

    /*
     * Cleans out all internal data structures.
     * REMIND: Native implementation
    public native void dispose();

    protected void finalize() {
        dispose();
    }
     */
}
