/* ScanlineCoverage.java -- Manages coverage information for a scanline
   Copyright (C) 2007 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package gnu.java.awt.java2d;

/**
 * Stores and handles the pixel converage for a scanline. The pixel coverage
 * is stored as sorted list of {@linke Covergage} entries, each of which holds
 * information about the coverage for the X and Y axis. This is utilized to
 * compute the actual coverage for each pixel on the scanline and finding
 * chunks of pixels with equal coverage quickly.
 */
public final class ScanlineCoverage
{

  /**
   * Iterates over the coverage list and calculates the actual coverage
   * ranges on a scanline.
   */
  public final class Iterator
  {
    /**
     * This instance is reused in the iteration.
     */
    private Range range;

    /**
     * The pointer to the current item in the iteration.
     */
    private Coverage currentItem;

    /**
     * The current coverage value.
     */
    private int currentCoverage;

    /**
     * True when the current pixel coverage has already been handled, false
     * otherwise.
     */
    private boolean handledPixelCoverage;

    /**
     * Creates a new CoverageIterator.
     */
    Iterator()
    {
      range = new Range();
    }

    /**
     * Returns the next coverage range on the scanline. The returned object
     * will always be the same object, but with different values. Keep that
     * in mind when dealing with this object.
     *
     * @return the next coverage range on the scanline
     */
    public Range next()
    {
      // TODO: Lump together the single-pixel coverage and the
      // between-pixel coverage when the pixel coverage delta is 0.
      if (handledPixelCoverage == false)
        {
          // Handle single pixel coverage.
          range.setXPos(currentItem.xPos);
          range.setLength(1);
          range.setCoverage(currentCoverage + currentItem.pixelCoverage);
          handledPixelCoverage = true;
        }
      else
        {
          // Handle pixel span coverage.
          currentCoverage += currentItem.covDelta;
          range.setCoverage(currentCoverage);
          range.setXPos(currentItem.xPos + 1);
          currentItem = currentItem.next;
          range.setLength(currentItem.xPos - range.xPos);
          handledPixelCoverage = false;
        }
      return range;
    }

    /**
     * Returns {@ true} when there are more coverage ranges to iterate,
     * {@ false} otherwise.
     *
     * @return {@ true} when there are more coverage ranges to iterate,
     *         {@ false} otherwise
     */
    public boolean hasNext()
    {
      boolean hasNext;
      if (currentItem != null && handledPixelCoverage == false)
        {
          // We have at least one more coverage item when there's a pixel
          // coverage piece left.
          hasNext = true;
        }
      else if (currentItem == null || currentItem.next == null
          || currentItem.next == last)
        {
          hasNext = false;
        }
      else
        {
          hasNext = true;
        }
      return hasNext;
    }

    /**
     * Resets this iterator to the start of the list.
     */
    void reset()
    {
      currentItem = head;
      currentCoverage = 0;
      handledPixelCoverage = false;
    }
  }

  /**
   * A data object that carries information about pixel coverage on a scanline.
   * The data consists of a starting X position on the scanline, the
   * length of the range in pixels and the actual coverage value.
   **/
  public static final class Range
  {
    /**
     * The X position on the scanline, in pixels.
     */
    private int xPos;

    /**
     * The length of the range, in pixels.
     */
    private int length;

    /**
     * The actual coverage. The relation depends on
     * {@link ScanlineCoverage#maxCoverage}.
     */
    private int coverage;

    /**
     * Creates a new CoverageRange object.
     */
    Range()
    {
      // Nothing to do. The values get initialized in the corresponding
      // setters.
    }

    /**
     * Sets the X start position (left) on the scanline. This value is
     * considered to be in pixels and device space.
     *
     * @param x the x position
     */
    void setXPos(int x)
    {
      xPos = x;
    }

    /**
     * Returns the X start position (left) on the scanline. This value
     * is considered to be in pixels and device space.
     *
     * @return the X position on the scanline
     */
    public int getXPos()
    {
      return xPos;
    }

    /**
     * Sets the length of the pixel range. This is in pixel units.
     *
     * @param l the length of the range
     */
    void setLength(int l)
    {
      length = l;
    }

    /**
     * Returns the length of the range in pixel units.
     *
     * @return the length of the range in pixel units
     */
    public int getLength()
    {
      return length;
    }

    /**
     * Returns the first X position after the range.
     *
     * @return the first X position after the range
     */
    public int getXPosEnd()
    {
      return xPos + length;
    }

    /**
     * Sets the coverage of the pixel range. The relation of that value
     * depends on {@link ScanlineCoverage#maxCoverage}.
     *
     * @param cov the coverage value for the pixel range
     */
    void setCoverage(int cov)
    {
      coverage = cov;
    }

    /**
     * Returns the coverage of the pixel range. The relation of this value
     * depends on {@link ScanlineCoverage#getMaxCoverage()}.
     *
     * @return the coverage of the pixel range
     */
    public int getCoverage()
    {
      return coverage;
    }

    /**
     * Returns a string representation.
     */
    public String toString()
    {
      return "Coverage range: xPos=" + xPos + ", length=" + length
             + ", coverage: " + coverage;
    }
  }

  /**
   * One bucket in the list.
   */
  private static final class Coverage
  {
    /**
     * The X coordinate on the scanline to which this bucket belongs.
     */
    int xPos;

    /**
     * The coverage delta from the pixel at xPos to xPos + 1.
     */
    int covDelta;

    /**
     * The delta for the pixel at xPos. This is added to the pixel at xPos,
     * but not to the following pixel.
     */
    int pixelCoverage;

    /**
     * Implements a linked list. This points to the next element of the list.
     */
    Coverage next;

    /**
     * Returns the X coordinate for this entry.
     *
     * @return the X coordinate for this entry
     */
    public int getXPos()
    {
      return xPos;
    }

    /**
     * Returns the coverage delta for this entry.
     *
     * @return the coverage delta for this entry
     */
    public int getCoverageDelta()
    {
      return covDelta;
    }

    /**
     * Returns a string representation.
     *
     * @return a string representation
     */
    public String toString()
    {
      return "Coverage: xPos: " + xPos + ", covDelta: " + covDelta;
    }

    /**
     * Returns a string representation of this entry and all the following
     * in the linked list.
     *
     * @return a string representation of this entry and all the following
     *         in the linked list
     */
    public String list()
    {
      String str = toString();
      if (next != null)
        str = str + " --> " + next.list();
      return str;
    }
  }

  /**
   * The head of the sorted list of buckets.
   */
  private Coverage head;

  /**
   * The current bucket. We make use of the fact that the scanline converter
   * always scans the scanline (and thus this list) from left to right to
   * quickly find buckets or insertion points.
   */
  private Coverage current;

  /**
   * The item that is before current in the list.
   */
  private Coverage currentPrev;

  /**
   * The bucket after the last valid bucket. Unused buckets are not thrown
   * away and garbage collected. Instead, we keep them at the tail of the list
   * and reuse them when necessary.
   */
  private Coverage last;

  /**
   * The last valid entry.
   */
  private Coverage lastPrev;

  /**
   * The minimum X coordinate of this scanline.
   */
  private int minX;

  /**
   * The maximum X coordinate of this scanline.
   */
  private int maxX;

  /**
   * The maximum coverage value.
   */
  private int maxCoverage;

  /**
   * The iterator over the ranges of this scanline.
   */
  private Iterator iterator;

  /**
   * Creates a new ScanlineCoverage instance.
   */
  public ScanlineCoverage()
  {
    iterator = new Iterator();
  }

  /**
   * Indicates the the next scan of the scanline begins and that the next
   * request will be at the beginning of this list. This makes searching and
   * sorting of this list very quick.
   */
  public void rewind()
  {
    current = head;
    currentPrev = null;
  }

  /**
   * Clears the list. This does not throw away the old buckets but only
   * resets the end-pointer of the list to the first element. All buckets are
   * then unused and are reused when the list is filled again.
   */
  public void clear()
  {
    last = head;
    lastPrev = null;
    current = head;
    currentPrev = null;
    minX = Integer.MAX_VALUE;
    maxX = Integer.MIN_VALUE;
  }

  /**
   * This adds the specified coverage to the pixel at the specified
   * X position.
   *
   * @param x the X position
   * @param xc the x coverage
   * @param yc the y coverage
   */
  public void add(int x, int xc, int yc)
  {
    Coverage bucket = findOrInsert(x);
    bucket.covDelta += xc;
    bucket.pixelCoverage += yc;
    minX = Math.min(minX, x);
    maxX = Math.max(maxX, x);
  }

  /**
   * Returns the maximum coverage value for the scanline.
   *
   * @return the maximum coverage value for the scanline
   */
  public int getMaxCoverage()
  {
    return maxCoverage;
  }

  /**
   * Sets the maximum coverage value for the scanline.
   *
   * @param maxCov the maximum coverage value for the scanline
   */
  void setMaxCoverage(int maxCov)
  {
    maxCoverage = maxCov;
  }

  /**
   * Returns the maximum X coordinate of the current scanline.
   *
   * @return the maximum X coordinate of the current scanline
   */
  public int getMaxX()
  {
    return maxX;
  }

  /**
   * Returns the minimum X coordinate of the current scanline.
   *
   * @return the minimum X coordinate of the current scanline
   */
  public int getMinX()
  {
    return minX;
  }

  /**
   * Finds the bucket in the list with the specified X coordinate.
   * If no such bucket is found, then a new one is fetched (either a cached
   * bucket from the end of the list or a newly allocated one) inserted at the
   * correct position and returned.
   *
   * @param x the X coordinate
   *
   * @return a bucket to hold the coverage data
   */
  private Coverage findOrInsert(int x)
  {
    // First search for a matching bucket.
    if (head == null)
      {
        // Special case: the list is still empty.
        // Testpoint 1.
        head = new Coverage();
        head.xPos = x;
        current = head;
        currentPrev = null;
        return head;
      }

    // This performs a linear search, starting from the current bucket.
    // This is reasonably efficient because access to this list is always done
    // in a linear fashion and we are usually not more then 1 or 2 buckets away
    // from the one we're looking for.
    Coverage match = current;
    Coverage prev = currentPrev;
    while (match != last && match.xPos < x)
      {
        prev = match;
        match = match.next;
      }

    // At this point we have either found an entry with xPos >= x, or reached
    // the end of the list (match == last || match == null).
    if (match == null)
      {
        // End of the list. No cached items to reuse.
        // Testpoint 2.
        match = new Coverage();
        match.xPos = x;
        if (prev != null)
          prev.next = match;
        current = match;
        currentPrev = prev;
        return match;
      }
    else if (match == last)
      {
        // End of the list. Reuse this item. Expand list.
        // Testpoint 3.
        last = match.next;
        lastPrev = match;
        match.xPos = x;
        match.covDelta = 0;
        match.pixelCoverage = 0;
        // Keep link to last element or null, indicating the end of the list.
        current = match;
        currentPrev = prev;
        return match;
      }

    if (x == match.xPos)
      {
        // Special case: We have another coverage entry at the same location
        // as an already existing entry. Return this.
        // Testpoint 4.
        current = match;
        currentPrev = prev;
        return match;
      }
    else // x <= match.xPos
      {
        assert (x <= match.xPos);
        assert (prev == null ||x > prev.xPos);

        // Create new entry, or reuse existing one.
        Coverage cov;
        if (last != null)
          {
            // Testpoint 5.
            cov = last;
            last = cov.next;
            lastPrev.next = last;
          }
        else
          {
            // Testpoint 6.
            cov = new Coverage();
          }

        cov.xPos = x;
        cov.covDelta = 0;
        cov.pixelCoverage = 0;

        // Insert this item in the list.
        if (prev != null)
          {
            // Testpoint 5 & 6.
            prev.next = cov;
            cov.next = match;
            current = cov;
            currentPrev = prev;
          }
        else
          {
            // Testpoint 7.
            assert (match == head);
            // Insert at head.
            head = cov;
            head.next = match;
            current = head;
            currentPrev = null;
          }
        return cov;
      }
  }

  /**
   * (Re-)Starts iterating the coverage values for the scanline.
   * Use the returned iterator to get the consecutive coverage ranges.
   *
   * @return the iterator
   */
  public Iterator iterate()
  {
    iterator.reset();
    return iterator;
  }

  /**
   * Returns {@ true} if this object has no entries for the current scanline,
   * {@ false} otherwise.
   *
   * @return {@ true} if this object has no entries for the current scanline,
   *         {@ false} otherwise
   */
  public boolean isEmpty()
  {
    return head == null || head == last
           || head.next == null || head.next == last;
  }

}
