/* JViewport.java --
   Copyright (C) 2002, 2004, 2005  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 javax.swing;

import gnu.classpath.SystemProperties;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.Serializable;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ViewportUI;

/**
 *
 * <pre>
 *                                                     _
 *   +-------------------------------+    ...........Y1 \
 *   |  view                         |                .  \
 *   |  (this component's child)     |                .   > VY
 *   |                               |                .  / = Y2-Y1
 *   |         +------------------------------+  ....Y2_/
 *   |         | viewport            |        |       .
 *   |         | (this component)    |        |       .
 *   |         |                     |        |       .
 *   |         |                     |        |       .
 *   |         |                     |        |       .
 *   |         |                     |        |       .
 *   |         +------------------------------+  ....Y3
 *   |                               |                .
 *   |         .                     |        .       .
 *   |         .                     |        .       .
 *   +---------.---------------------+    ...........Y4
 *   .         .                     .        .
 *   .         .                     .        .
 *   .         .                     .        .
 *   X1.......X2.....................X3.......X4
 *   \____  ___/
 *        \/
 *        VX = X2-X1
 *</pre>
 *
 * <p>A viewport is, like all swing components, located at some position in
 * the swing component tree; that location is exactly the same as any other
 * components: the viewport's "bounds".</p>
 *
 * <p>But in terms of drawing its child, the viewport thinks of itself as
 * covering a particular position <em>of the view's coordinate space</em>.
 * For example, the {@link #getViewPosition} method returns
 * the position <code>(VX,VY)</code> shown above, which is an position in
 * "view space", even though this is <em>implemented</em> by positioning
 * the underlying child at position <code>(-VX,-VY)</code></p>
 *
 */
public class JViewport extends JComponent implements Accessible
{
  /**
   * Provides accessibility support for <code>JViewport</code>.
   *
   * @author Roman Kennke (roman@kennke.org)
   */
  protected class AccessibleJViewport extends AccessibleJComponent
  {
    /**
     * Creates a new instance of <code>AccessibleJViewport</code>.
     */
    protected AccessibleJViewport()
    {
      // Nothing to do here.
    }

    /**
     * Returns the accessible role of <code>JViewport</code>, which is
     * {@link AccessibleRole#VIEWPORT}.
     *
     * @return the accessible role of <code>JViewport</code>
     */
    public AccessibleRole getAccessibleRole()
    {
      return AccessibleRole.VIEWPORT;
    }
  }

  /**
   * A {@link java.awt.event.ComponentListener} that listens for
   * changes of the view's size. This triggers a revalidate() call on the
   * viewport.
   */
  protected class ViewListener extends ComponentAdapter implements Serializable
  {
    private static final long serialVersionUID = -2812489404285958070L;

    /**
     * Creates a new instance of ViewListener.
     */
    protected ViewListener()
    {
      // Nothing to do here.
    }

    /**
     * Receives notification when a component (in this case: the view
     * component) changes it's size. This simply triggers a revalidate() on the
     * viewport.
     *
     * @param ev the ComponentEvent describing the change
     */
    public void componentResized(ComponentEvent ev)
    {
      // Fire state change, because resizing the view means changing the
      // extentSize.
      fireStateChanged();
      revalidate();
    }
  }

  public static final int SIMPLE_SCROLL_MODE = 0;
  public static final int BLIT_SCROLL_MODE = 1;
  public static final int BACKINGSTORE_SCROLL_MODE = 2;

  private static final long serialVersionUID = -6925142919680527970L;

  /**
   * The default scrollmode to be used by all JViewports as determined by
   * the system property gnu.javax.swing.JViewport.scrollMode.
   */
  private static final int defaultScrollMode;

  protected boolean scrollUnderway;
  protected boolean isViewSizeSet;

  /**
   * This flag indicates whether we use a backing store for drawing.
   *
   * @deprecated since JDK 1.3
   */
  protected boolean backingStore;

  /**
   * The backingstore image used for the backingstore and blit scroll methods.
   */
  protected Image backingStoreImage;

  /**
   * The position at which the view has been drawn the last time. This is used
   * to determine the bittable area.
   */
  protected Point lastPaintPosition;

  ChangeEvent changeEvent = new ChangeEvent(this);

  int scrollMode;

  /**
   * The ViewListener instance.
   */
  ViewListener viewListener;

  /**
   * Stores the location from where to blit. This is a cached Point object used
   * in blitting calculations.
   */
  Point cachedBlitFrom;

  /**
   * Stores the location where to blit to. This is a cached Point object used
   * in blitting calculations.
   */
  Point cachedBlitTo;

  /**
   * Stores the width of the blitted area. This is a cached Dimension object
   * used in blitting calculations.
   */
  Dimension cachedBlitSize;

  /**
   * Stores the bounds of the area that needs to be repainted. This is a cached
   * Rectangle object used in blitting calculations.
   */
  Rectangle cachedBlitPaint;

  boolean damaged = true;

  /**
   * A flag indicating if the size of the viewport has changed since the
   * last repaint. This is used in double buffered painting to check if we
   * need a new double buffer, or can reuse the old one.
   */
  boolean sizeChanged = true;

  /**
   * Indicates if this JViewport is the paint root or not. If it is not, then
   * we may not assume that the offscreen buffer still has the right content
   * because parent components may have cleared the background already.
   */
  private boolean isPaintRoot = false;

  /**
   * Initializes the default setting for the scrollMode property.
   */
  static
  {
    String scrollModeProp =
      SystemProperties.getProperty("gnu.swing.scrollmode", "BACKINGSTORE");
    if (scrollModeProp.equalsIgnoreCase("simple"))
      defaultScrollMode = SIMPLE_SCROLL_MODE;
    else if (scrollModeProp.equalsIgnoreCase("backingstore"))
      defaultScrollMode = BACKINGSTORE_SCROLL_MODE;
    else
      defaultScrollMode = BLIT_SCROLL_MODE;
  }

  public JViewport()
  {
    setOpaque(true);
    setScrollMode(defaultScrollMode);
    updateUI();
    setLayout(createLayoutManager());
    lastPaintPosition = new Point();
    cachedBlitFrom = new Point();
    cachedBlitTo = new Point();
    cachedBlitSize = new Dimension();
    cachedBlitPaint = new Rectangle();
  }

  public Dimension getExtentSize()
  {
    return getSize();
  }

  public Dimension toViewCoordinates(Dimension size)
  {
    return size;
  }

  public Point toViewCoordinates(Point p)
  {
    Point pos = getViewPosition();
    return new Point(p.x + pos.x,
                     p.y + pos.y);
  }

  public void setExtentSize(Dimension newSize)
  {
    Dimension oldExtent = getExtentSize();
    if (! newSize.equals(oldExtent))
      {
        setSize(newSize);
        fireStateChanged();
      }
  }

  /**
   * Returns the viewSize when set, or the preferred size of the set
   * Component view.  If no viewSize and no Component view is set an
   * empty Dimension is returned.
   */
  public Dimension getViewSize()
  {
    Dimension size;
    Component view = getView();
    if (view != null)
      {
        if (isViewSizeSet)
          size = view.getSize();
        else
          size = view.getPreferredSize();
      }
    else
      size = new Dimension(0, 0);
    return size;
  }


  public void setViewSize(Dimension newSize)
  {
    Component view = getView();
    if (view != null)
      {
        if (! newSize.equals(view.getSize()))
          {
            scrollUnderway = false;
            view.setSize(newSize);
            isViewSizeSet = true;
            fireStateChanged();
          }
      }
  }

  /**
   * Get the viewport's position in view space. Despite confusing name,
   * this really does return the viewport's (0,0) position in view space,
   * not the view's position.
   */

  public Point getViewPosition()
  {
    Component view = getView();
    if (view == null)
      return new Point(0,0);
    else
      {
        Point p = view.getLocation();
        p.x = -p.x;
        p.y = -p.y;
        return p;
      }
  }

  public void setViewPosition(Point p)
  {
    Component view = getView();
    if (view != null && ! p.equals(getViewPosition()))
      {
        scrollUnderway = true;
        view.setLocation(-p.x, -p.y);
        fireStateChanged();
      }
  }

  public Rectangle getViewRect()
  {
    return new Rectangle(getViewPosition(), getExtentSize());
  }

  /**
   * @deprecated 1.4
   */
  public boolean isBackingStoreEnabled()
  {
    return scrollMode == BACKINGSTORE_SCROLL_MODE;
  }

  /**
   * @deprecated 1.4
   */
  public void setBackingStoreEnabled(boolean b)
  {
    if (b && scrollMode != BACKINGSTORE_SCROLL_MODE)
      {
        scrollMode = BACKINGSTORE_SCROLL_MODE;
        fireStateChanged();
      }
  }

  public void setScrollMode(int mode)
  {
    scrollMode = mode;
    fireStateChanged();
  }

  public int getScrollMode()
  {
    return scrollMode;
  }

  public Component getView()
  {
    if (getComponentCount() == 0)
      return null;

    return getComponents()[0];
  }

  public void setView(Component v)
  {
    Component currView = getView();
    if (viewListener != null && currView != null)
      currView.removeComponentListener(viewListener);

    if (v != null)
      {
        if (viewListener == null)
          viewListener = createViewListener();
        v.addComponentListener(viewListener);
        add(v);
        fireStateChanged();
      }
    revalidate();
    repaint();
  }

  public void reshape(int x, int y, int w, int h)
  {
    if (w != getWidth() || h != getHeight())
      sizeChanged = true;
    super.reshape(x, y, w, h);
    if (sizeChanged)
      {
        damaged = true;
        fireStateChanged();
      }
  }

  public final Insets getInsets()
  {
    return new Insets(0, 0, 0, 0);
  }

  public final Insets getInsets(Insets insets)
  {
    if (insets == null)
      return getInsets();
    insets.top = 0;
    insets.bottom = 0;
    insets.left = 0;
    insets.right = 0;
    return insets;
  }


  /**
   * Overridden to return <code>false</code>, so the JViewport's paint method
   * gets called instead of directly calling the children. This is necessary
   * in order to get a useful clipping and translation on the children.
   *
   * @return <code>false</code>
   */
  public boolean isOptimizedDrawingEnabled()
  {
    return false;
  }

  public void paint(Graphics g)
  {
    Component view = getView();

    if (view == null)
      return;

    Rectangle viewBounds = view.getBounds();
    Rectangle portBounds = getBounds();

    if (viewBounds.width == 0
        || viewBounds.height == 0
        || portBounds.width == 0
        || portBounds.height == 0)
      return;

    switch (getScrollMode())
      {

      case JViewport.BACKINGSTORE_SCROLL_MODE:
        paintBackingStore(g);
        break;
      case JViewport.BLIT_SCROLL_MODE:
        paintBlit(g);
        break;
      case JViewport.SIMPLE_SCROLL_MODE:
      default:
        paintSimple(g);
        break;
      }
    damaged = false;
  }

  public void addChangeListener(ChangeListener listener)
  {
    listenerList.add(ChangeListener.class, listener);
  }

  public void removeChangeListener(ChangeListener listener)
  {
    listenerList.remove(ChangeListener.class, listener);
  }

  public ChangeListener[] getChangeListeners()
  {
    return (ChangeListener[]) getListeners(ChangeListener.class);
  }

  /**
   * This method returns the String ID of the UI class of  Separator.
   *
   * @return The UI class' String ID.
   */
  public String getUIClassID()
  {
    return "ViewportUI";
  }

  /**
   * This method resets the UI used to the Look and Feel defaults..
   */
  public void updateUI()
  {
    setUI((ViewportUI) UIManager.getUI(this));
  }

  /**
   * This method returns the viewport's UI delegate.
   *
   * @return The viewport's UI delegate.
   */
  public ViewportUI getUI()
  {
    return (ViewportUI) ui;
  }

  /**
   * This method sets the viewport's UI delegate.
   *
   * @param ui The viewport's UI delegate.
   */
  public void setUI(ViewportUI ui)
  {
    super.setUI(ui);
  }

  public final void setBorder(Border border)
  {
    if (border != null)
      throw new IllegalArgumentException();
  }

  /**
   * Scrolls the view so that contentRect becomes visible.
   *
   * @param contentRect the rectangle to make visible within the view
   */
  public void scrollRectToVisible(Rectangle contentRect)
  {
    Component view = getView();
    if (view == null)
      return;

    Point pos = getViewPosition();
    // We get the contentRect in the viewport coordinates. But we want to
    // calculate with view coordinates.
    int contentX = contentRect.x + pos.x;
    int contentY = contentRect.y + pos.y;
    Rectangle viewBounds = getView().getBounds();
    Rectangle portBounds = getBounds();

    if (isShowing())
      getView().validate();

    // If the bottom boundary of contentRect is below the port
    // boundaries, scroll up as necessary.
    if (contentY + contentRect.height + viewBounds.y > portBounds.height)
      pos.y = contentY + contentRect.height - portBounds.height;
    // If contentY is above the port boundaries, scroll down to
    // contentY.
    if (contentY + viewBounds.y < 0)
      pos.y = contentY;
    // If the right boundary of contentRect is right from the port
    // boundaries, scroll left as necessary.
    if (contentX + contentRect.width + viewBounds.x > portBounds.width)
      pos.x = contentX + contentRect.width - portBounds.width;
    // If contentX is left from the port boundaries, scroll right to
    // contentRect.x.
    if (contentX + viewBounds.x < 0)
      pos.x = contentX;
    setViewPosition(pos);
  }

  /**
   * Returns the accessible context for this <code>JViewport</code>. This
   * will be an instance of {@link AccessibleJViewport}.
   *
   * @return the accessible context for this <code>JViewport</code>
   */
  public AccessibleContext getAccessibleContext()
  {
    if (accessibleContext == null)
      accessibleContext = new AccessibleJViewport();
    return accessibleContext;
  }

  /**
   * Forward repaint to parent to make sure only one paint is performed by the
   * RepaintManager.
   *
   * @param tm number of milliseconds to defer the repaint request
   * @param x the X coordinate of the upper left corner of the dirty area
   * @param y the Y coordinate of the upper left corner of the dirty area
   * @param w the width of the dirty area
   * @param h the height of the dirty area
   */
  public void repaint(long tm, int x, int y, int w, int h)
  {
    Component parent = getParent();
    if (parent != null)
      parent.repaint(tm, x + getX(), y + getY(), w, h);
    else
      super.repaint(tm, x, y, w, h);
  }

  protected void addImpl(Component comp, Object constraints, int index)
  {
    if (getComponentCount() > 0)
      remove(getComponents()[0]);

    super.addImpl(comp, constraints, index);
  }

  protected void fireStateChanged()
  {
    ChangeListener[] listeners = getChangeListeners();
    for (int i = 0; i < listeners.length; ++i)
      listeners[i].stateChanged(changeEvent);
  }

  /**
   * Creates a {@link ViewListener} that is supposed to listen for
   * size changes on the view component.
   *
   * @return a ViewListener instance
   */
  protected ViewListener createViewListener()
  {
    return new ViewListener();
  }

  /**
   * Creates the LayoutManager that is used for this viewport. Override
   * this method if you want to use a custom LayoutManager.
   *
   * @return a LayoutManager to use for this viewport
   */
  protected LayoutManager createLayoutManager()
  {
    return new ViewportLayout();
  }

  /**
   * Computes the parameters for the blitting scroll method. <code>dx</code>
   * and <code>dy</code> specifiy the X and Y offset by which the viewport
   * is scrolled. All other arguments are output parameters and are filled by
   * this method.
   *
   * <code>blitFrom</code> holds the position of the blit rectangle in the
   * viewport rectangle before scrolling, <code>blitTo</code> where the blitArea
   * is copied to.
   *
   * <code>blitSize</code> holds the size of the blit area and
   * <code>blitPaint</code> is the area of the view that needs to be painted.
   *
   * This method returns <code>true</code> if blitting is possible and
   * <code>false</code> if the viewport has to be repainted completetly without
   * blitting.
   *
   * @param dx the horizontal delta
   * @param dy the vertical delta
   * @param blitFrom the position from where to blit; set by this method
   * @param blitTo the position where to blit area is copied to; set by this
   *        method
   * @param blitSize the size of the blitted area; set by this method
   * @param blitPaint the area that needs repainting; set by this method
   *
   * @return <code>true</code> if blitting is possible,
   *         <code>false</code> otherwise
   */
  protected boolean computeBlit(int dx, int dy, Point blitFrom, Point blitTo,
                                Dimension blitSize, Rectangle blitPaint)
  {
    if ((dx != 0 && dy != 0) || (dy == 0 && dy == 0) || damaged)
      // We cannot blit if the viewport is scrolled in both directions at
      // once. Also, we do not want to blit if the viewport is not scrolled at
      // all, because that probably means the view component repaints itself
      // and the buffer needs updating.
      return false;

    Rectangle portBounds = SwingUtilities.calculateInnerArea(this, getBounds());

    // Compute the blitFrom and blitTo parameters.
    blitFrom.x = portBounds.x;
    blitFrom.y = portBounds.y;
    blitTo.x = portBounds.x;
    blitTo.y = portBounds.y;

    if (dy > 0)
      {
        blitFrom.y = portBounds.y + dy;
      }
    else if (dy < 0)
      {
        blitTo.y = portBounds.y - dy;
      }
    else if (dx > 0)
      {
        blitFrom.x = portBounds.x + dx;
      }
    else if (dx < 0)
      {
        blitTo.x = portBounds.x - dx;
      }

    // Compute size of the blit area.
    if (dx != 0)
      {
        blitSize.width = portBounds.width - Math.abs(dx);
        blitSize.height = portBounds.height;
      }
    else if (dy != 0)
      {
        blitSize.width = portBounds.width;
        blitSize.height = portBounds.height - Math.abs(dy);
      }

    // Compute the blitPaint parameter.
    blitPaint.setBounds(portBounds);
    if (dy > 0)
      {
        blitPaint.y = portBounds.y + portBounds.height - dy;
        blitPaint.height = dy;
      }
    else if (dy < 0)
      {
        blitPaint.height = -dy;
      }
    if (dx > 0)
      {
        blitPaint.x = portBounds.x + portBounds.width - dx;
        blitPaint.width = dx;
      }
    else if (dx < 0)
      {
        blitPaint.width = -dx;
      }

    return true;
  }

  /**
   * Paints the viewport in case we have a scrollmode of
   * {@link #SIMPLE_SCROLL_MODE}.
   *
   * This simply paints the view directly on the surface of the viewport.
   *
   * @param g the graphics context to use
   */
  void paintSimple(Graphics g)
  {
    // We need to call this to properly clear the background.
    paintComponent(g);

    Point pos = getViewPosition();
    Component view = getView();
    Shape oldClip = g.getClip();
    g.clipRect(0, 0, getWidth(), getHeight());
    boolean translated = false;
    try
      {
        g.translate(-pos.x, -pos.y);
        translated = true;
        view.paint(g);
      }
    finally
      {
        if (translated)
          g.translate (pos.x, pos.y);
        g.setClip(oldClip);
      }
  }

  /**
   * Paints the viewport in case we have a scroll mode of
   * {@link #BACKINGSTORE_SCROLL_MODE}.
   *
   * This method uses a backing store image to paint the view to, which is then
   * subsequently painted on the screen. This should make scrolling more
   * smooth.
   *
   * @param g the graphics context to use
   */
  void paintBackingStore(Graphics g)
  {
    // If we have no backing store image yet or the size of the component has
    // changed, we need to rebuild the backing store.
    if (backingStoreImage == null || sizeChanged)
      {
        backingStoreImage = createImage(getWidth(), getHeight());
        sizeChanged = false;
        Graphics g2 = backingStoreImage.getGraphics();
        paintSimple(g2);
        g2.dispose();
      }
    // Otherwise we can perform the blitting on the backing store image:
    // First we move the part that remains visible after scrolling, then
    // we only need to paint the bit that becomes newly visible.
    else
      {
        Graphics g2 = backingStoreImage.getGraphics();
        Point viewPosition = getViewPosition();
        int dx = viewPosition.x - lastPaintPosition.x;
        int dy = viewPosition.y - lastPaintPosition.y;
        boolean canBlit = computeBlit(dx, dy, cachedBlitFrom, cachedBlitTo,
                                      cachedBlitSize, cachedBlitPaint);
        if (canBlit && isPaintRoot)
          {
            // Copy the part that remains visible during scrolling.
            if (cachedBlitSize.width > 0 && cachedBlitSize.height > 0)
              {
                g2.copyArea(cachedBlitFrom.x, cachedBlitFrom.y,
                            cachedBlitSize.width, cachedBlitSize.height,
                            cachedBlitTo.x - cachedBlitFrom.x,
                            cachedBlitTo.y - cachedBlitFrom.y);
              }
            // Now paint the part that becomes newly visible.
            g2.setClip(cachedBlitPaint.x, cachedBlitPaint.y,
                       cachedBlitPaint.width, cachedBlitPaint.height);
            paintSimple(g2);
          }
        // If blitting is not possible for some reason, fall back to repainting
        // everything.
        else
          {
            // If the image has not been scrolled at all, only the changed
            // clip must be updated in the buffer.
            if (dx == 0 && dy == 0)
              g2.setClip(g.getClip());

            paintSimple(g2);
          }
        g2.dispose();
      }
    // Actually draw the backingstore image to the graphics context.
    g.drawImage(backingStoreImage, 0, 0, this);
    // Update the lastPaintPosition so that we know what is already drawn when
    // we paint the next time.
    lastPaintPosition.setLocation(getViewPosition());
  }

  /**
   * Paints the viewport in case we have a scrollmode of
   * {@link #BLIT_SCROLL_MODE}.
   *
   * This paints the viewport using a backingstore and a blitting algorithm.
   * Only the newly exposed area of the view is painted from the view painting
   * methods, the remainder is copied from the backing store.
   *
   * @param g the graphics context to use
   */
  void paintBlit(Graphics g)
  {
    // First we move the part that remains visible after scrolling, then
    // we only need to paint the bit that becomes newly visible.
    Point viewPosition = getViewPosition();
    int dx = viewPosition.x - lastPaintPosition.x;
    int dy = viewPosition.y - lastPaintPosition.y;
    boolean canBlit = computeBlit(dx, dy, cachedBlitFrom, cachedBlitTo,
                                  cachedBlitSize, cachedBlitPaint);
    if (canBlit && isPaintRoot)
      {
        // Copy the part that remains visible during scrolling.
        if (cachedBlitSize.width > 0 && cachedBlitSize.width > 0)
          {
            g.copyArea(cachedBlitFrom.x, cachedBlitFrom.y,
                       cachedBlitSize.width, cachedBlitSize.height,
                       cachedBlitTo.x - cachedBlitFrom.x,
                       cachedBlitTo.y - cachedBlitFrom.y);
          }
        // Now paint the part that becomes newly visible.
        Shape oldClip = g.getClip();
        g.clipRect(cachedBlitPaint.x, cachedBlitPaint.y,
                  cachedBlitPaint.width, cachedBlitPaint.height);
        try
          {
            paintSimple(g);
          }
        finally
          {
            g.setClip(oldClip);
          }
      }
    // If blitting is not possible for some reason, fall back to repainting
    // everything.
    else
      paintSimple(g);
    lastPaintPosition.setLocation(getViewPosition());
  }

  /**
   * Overridden from JComponent to set the {@link #isPaintRoot} flag.
   *
   * @param x the rectangle to paint, X coordinate
   * @param y the rectangle to paint, Y coordinate
   * @param w the rectangle to paint, width
   * @param h the rectangle to paint, height
   */
  void paintImmediately2(int x, int y, int w, int h)
  {
    isPaintRoot = true;
    super.paintImmediately2(x, y, w, h);
    isPaintRoot = false;
  }

  /**
   * Returns true when the JViewport is using a backbuffer, so that we
   * can update our backbuffer correctly.
   */
  boolean isPaintRoot()
  {
    return scrollMode == BACKINGSTORE_SCROLL_MODE;
  }
}
