/* RepaintManager.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 gnu.java.awt.LowPriorityEvent;

import java.applet.Applet;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.InvocationEvent;
import java.awt.image.VolatileImage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.WeakHashMap;

/**
 * <p>The repaint manager holds a set of dirty regions, invalid components,
 * and a double buffer surface.  The dirty regions and invalid components
 * are used to coalesce multiple revalidate() and repaint() calls in the
 * component tree into larger groups to be refreshed "all at once"; the
 * double buffer surface is used by root components to paint
 * themselves.</p>
 *
 * <p>See <a
 * href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">this
 * document</a> for more details.</p>
 * document</a> for more details.</p>
 *
 * @author Roman Kennke (kennke@aicas.com)
 * @author Graydon Hoare (graydon@redhat.com)
 * @author Audrius Meskauskas (audriusa@bioinformatics.org)
 */
public class RepaintManager
{
  /**
   * An InvocationEvent subclass that implements LowPriorityEvent. This is used
   * to defer the execution of RepaintManager requests as long as possible on
   * the event queue. This way we make sure that all available input is
   * processed before getting active with the RepaintManager. This allows
   * for better optimization (more validate and repaint requests can be
   * coalesced) and thus has a positive effect on performance for GUI
   * applications under heavy load.
   */
  private static class RepaintWorkerEvent
    extends InvocationEvent
    implements LowPriorityEvent
  {

    /**
     * Creates a new RepaintManager event.
     *
     * @param source the source
     * @param runnable the runnable to execute
     */
    public RepaintWorkerEvent(Object source, Runnable runnable,
                              Object notifier, boolean catchEx)
    {
      super(source, runnable, notifier, catchEx);
    }

    /**
     * An application that I met implements its own event dispatching and
     * calls dispatch() via reflection, and only checks declared methods,
     * that is, it expects this method to be in the event's class, not
     * in a superclass. So I put this in here... sigh.
     */
    public void dispatch()
    {
      super.dispatch();
    }
  }

  /**
   * The current repaint managers, indexed by their ThreadGroups.
   */
  static WeakHashMap currentRepaintManagers;

  /**
   * A rectangle object to be reused in damaged regions calculation.
   */
  private static Rectangle rectCache = new Rectangle();

  /**
   * <p>A helper class which is placed into the system event queue at
   * various times in order to facilitate repainting and layout. There is
   * typically only one of these objects active at any time. When the
   * {@link RepaintManager} is told to queue a repaint, it checks to see if
   * a {@link RepaintWorker} is "live" in the system event queue, and if
   * not it inserts one using {@link SwingUtilities#invokeLater}.</p>
   *
   * <p>When the {@link RepaintWorker} comes to the head of the system
   * event queue, its {@link RepaintWorker#run} method is executed by the
   * swing paint thread, which revalidates all invalid components and
   * repaints any damage in the swing scene.</p>
   */
  private class RepaintWorker
    implements Runnable
  {

    boolean live;

    public RepaintWorker()
    {
      live = false;
    }

    public synchronized void setLive(boolean b)
    {
      live = b;
    }

    public synchronized boolean isLive()
    {
      return live;
    }

    public void run()
    {
      try
        {
          ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
          RepaintManager rm =
            (RepaintManager) currentRepaintManagers.get(threadGroup);
          rm.validateInvalidComponents();
          rm.paintDirtyRegions();
        }
      finally
        {
          setLive(false);
        }
    }

  }

  /**
   * A table storing the dirty regions of components.  The keys of this
   * table are components, the values are rectangles. Each component maps
   * to exactly one rectangle.  When more regions are marked as dirty on a
   * component, they are union'ed with the existing rectangle.
   *
   * This is package private to avoid a synthetic accessor method in inner
   * class.
   *
   * @see #addDirtyRegion
   * @see #getDirtyRegion
   * @see #isCompletelyDirty
   * @see #markCompletelyClean
   * @see #markCompletelyDirty
   */
  private HashMap dirtyComponents;

  /**
   * The dirtyComponents which is used in paintDiryRegions to avoid unnecessary
   * locking.
   */
  private HashMap dirtyComponentsWork;

  /**
   * A single, shared instance of the helper class. Any methods which mark
   * components as invalid or dirty eventually activate this instance. It
   * is added to the event queue if it is not already active, otherwise
   * reused.
   *
   * @see #addDirtyRegion
   * @see #addInvalidComponent
   */
  private RepaintWorker repaintWorker;

  /**
   * The set of components which need revalidation, in the "layout" sense.
   * There is no additional information about "what kind of layout" they
   * need (as there is with dirty regions), so it is just a vector rather
   * than a table.
   *
   * @see #addInvalidComponent
   * @see #removeInvalidComponent
   * @see #validateInvalidComponents
   */
  private ArrayList invalidComponents;

  /**
   * Whether or not double buffering is enabled on this repaint
   * manager. This is merely a hint to clients; the RepaintManager will
   * always return an offscreen buffer when one is requested.
   *
   * @see #isDoubleBufferingEnabled
   * @see #setDoubleBufferingEnabled
   */
  private boolean doubleBufferingEnabled;

  /**
   * The offscreen buffers. This map holds one offscreen buffer per
   * Window/Applet and releases them as soon as the Window/Applet gets garbage
   * collected.
   */
  private WeakHashMap offscreenBuffers;

  /**
   * The maximum width and height to allocate as a double buffer. Requests
   * beyond this size are ignored.
   *
   * @see #paintDirtyRegions
   * @see #getDoubleBufferMaximumSize
   * @see #setDoubleBufferMaximumSize
   */
  private Dimension doubleBufferMaximumSize;


  /**
   * Create a new RepaintManager object.
   */
  public RepaintManager()
  {
    dirtyComponents = new HashMap();
    dirtyComponentsWork = new HashMap();
    invalidComponents = new ArrayList();
    repaintWorker = new RepaintWorker();
    doubleBufferMaximumSize = new Dimension(2000,2000);
    doubleBufferingEnabled =
      SystemProperties.getProperty("gnu.swing.doublebuffering", "true")
                      .equals("true");
    offscreenBuffers = new WeakHashMap();
  }

  /**
   * Returns the <code>RepaintManager</code> for the current thread's
   * thread group. The default implementation ignores the
   * <code>component</code> parameter and returns the same repaint manager
   * for all components.
   *
   * @param component a component to look up the manager of
   *
   * @return the current repaint manager for the calling thread's thread group
   *         and the specified component
   *
   * @see #setCurrentManager
   */
  public static RepaintManager currentManager(Component component)
  {
    if (currentRepaintManagers == null)
      currentRepaintManagers = new WeakHashMap();
    ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
    RepaintManager currentManager =
      (RepaintManager) currentRepaintManagers.get(threadGroup);
    if (currentManager == null)
      {
        currentManager = new RepaintManager();
        currentRepaintManagers.put(threadGroup, currentManager);
      }
    return currentManager;
  }

  /**
   * Returns the <code>RepaintManager</code> for the current thread's
   * thread group. The default implementation ignores the
   * <code>component</code> parameter and returns the same repaint manager
   * for all components.
   *
   * This method is only here for backwards compatibility with older versions
   * of Swing and simply forwards to {@link #currentManager(Component)}.
   *
   * @param component a component to look up the manager of
   *
   * @return the current repaint manager for the calling thread's thread group
   *         and the specified component
   *
   * @see #setCurrentManager
   */
  public static RepaintManager currentManager(JComponent component)
  {
    return currentManager((Component)component);
  }

  /**
   * Sets the repaint manager for the calling thread's thread group.
   *
   * @param manager the repaint manager to set for the current thread's thread
   *        group
   *
   * @see #currentManager(Component)
   */
  public static void setCurrentManager(RepaintManager manager)
  {
    if (currentRepaintManagers == null)
      currentRepaintManagers = new WeakHashMap();

    ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
    currentRepaintManagers.put(threadGroup, manager);
  }

  /**
   * Add a component to the {@link #invalidComponents} vector. If the
   * {@link #repaintWorker} class is not active, insert it in the system
   * event queue.
   *
   * @param component The component to add
   *
   * @see #removeInvalidComponent
   */
  public void addInvalidComponent(JComponent component)
  {
    Component validateRoot = null;
    Component c = component;
    while (c != null)
      {
        // Special cases we don't bother validating are when the invalidated
        // component (or any of it's ancestors) is inside a CellRendererPane
        // or if it doesn't have a peer yet (== not displayable).
        if (c instanceof CellRendererPane || ! c.isDisplayable())
          return;
        if (c instanceof JComponent && ((JComponent) c).isValidateRoot())
          {
            validateRoot = c;
            break;
          }

        c = c.getParent();
      }

    // If we didn't find a validate root, then we don't validate.
    if (validateRoot == null)
      return;

    // Make sure the validate root and all of it's ancestors are visible.
    c = validateRoot;
    while (c != null)
      {
        if (! c.isVisible() || ! c.isDisplayable())
          return;
        c = c.getParent();
      }

    if (invalidComponents.contains(validateRoot))
      return;

    //synchronized (invalidComponents)
    //  {
        invalidComponents.add(validateRoot);
    //  }

    if (! repaintWorker.isLive())
      {
        repaintWorker.setLive(true);
        invokeLater(repaintWorker);
      }
  }

  /**
   * Remove a component from the {@link #invalidComponents} vector.
   *
   * @param component The component to remove
   *
   * @see #addInvalidComponent
   */
  public void removeInvalidComponent(JComponent component)
  {
    synchronized (invalidComponents)
      {
        invalidComponents.remove(component);
      }
  }

  /**
   * Add a region to the set of dirty regions for a specified component.
   * This involves union'ing the new region with any existing dirty region
   * associated with the component. If the {@link #repaintWorker} class
   * is not active, insert it in the system event queue.
   *
   * @param component The component to add a dirty region for
   * @param x The left x coordinate of the new dirty region
   * @param y The top y coordinate of the new dirty region
   * @param w The width of the new dirty region
   * @param h The height of the new dirty region
   *
   * @see #addDirtyRegion
   * @see #getDirtyRegion
   * @see #isCompletelyDirty
   * @see #markCompletelyClean
   * @see #markCompletelyDirty
   */
  public void addDirtyRegion(JComponent component, int x, int y,
                             int w, int h)
  {
    if (w <= 0 || h <= 0 || !component.isShowing())
      return;
    component.computeVisibleRect(rectCache);
    SwingUtilities.computeIntersection(x, y, w, h, rectCache);

    if (! rectCache.isEmpty())
      {
        synchronized (dirtyComponents)
          {
            Rectangle dirtyRect = (Rectangle)dirtyComponents.get(component);
            if (dirtyRect != null)
              {
                SwingUtilities.computeUnion(rectCache.x, rectCache.y,
                                            rectCache.width, rectCache.height,
                                            dirtyRect);
              }
            else
              {
                dirtyComponents.put(component, rectCache.getBounds());
              }
          }

        if (! repaintWorker.isLive())
          {
            repaintWorker.setLive(true);
            invokeLater(repaintWorker);
          }
      }
  }

  /**
   * Get the dirty region associated with a component, or <code>null</code>
   * if the component has no dirty region.
   *
   * @param component The component to get the dirty region of
   *
   * @return The dirty region of the component
   *
   * @see #dirtyComponents
   * @see #addDirtyRegion
   * @see #isCompletelyDirty
   * @see #markCompletelyClean
   * @see #markCompletelyDirty
   */
  public Rectangle getDirtyRegion(JComponent component)
  {
    Rectangle dirty = (Rectangle) dirtyComponents.get(component);
    if (dirty == null)
      dirty = new Rectangle();
    return dirty;
  }

  /**
   * Mark a component as dirty over its entire bounds.
   *
   * @param component The component to mark as dirty
   *
   * @see #dirtyComponents
   * @see #addDirtyRegion
   * @see #getDirtyRegion
   * @see #isCompletelyDirty
   * @see #markCompletelyClean
   */
  public void markCompletelyDirty(JComponent component)
  {
    addDirtyRegion(component, 0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
  }

  /**
   * Remove all dirty regions for a specified component
   *
   * @param component The component to mark as clean
   *
   * @see #dirtyComponents
   * @see #addDirtyRegion
   * @see #getDirtyRegion
   * @see #isCompletelyDirty
   * @see #markCompletelyDirty
   */
  public void markCompletelyClean(JComponent component)
  {
    synchronized (dirtyComponents)
      {
        dirtyComponents.remove(component);
      }
  }

  /**
   * Return <code>true</code> if the specified component is completely
   * contained within its dirty region, otherwise <code>false</code>
   *
   * @param component The component to check for complete dirtyness
   *
   * @return Whether the component is completely dirty
   *
   * @see #dirtyComponents
   * @see #addDirtyRegion
   * @see #getDirtyRegion
   * @see #isCompletelyDirty
   * @see #markCompletelyClean
   */
  public boolean isCompletelyDirty(JComponent component)
  {
    boolean dirty = false;
    Rectangle r = getDirtyRegion(component);
    if(r.width == Integer.MAX_VALUE && r.height == Integer.MAX_VALUE)
      dirty = true;
    return dirty;
  }

  /**
   * Validate all components which have been marked invalid in the {@link
   * #invalidComponents} vector.
   */
  public void validateInvalidComponents()
  {
    // We don't use an iterator here because that would fail when there are
    // components invalidated during the validation of others, which happens
    // quite frequently. Instead we synchronize the access a little more.
    while (invalidComponents.size() > 0)
      {
        Component comp;
        synchronized (invalidComponents)
          {
            comp = (Component) invalidComponents.remove(0);
          }
        // Validate the validate component.
        if (! (comp.isVisible() && comp.isShowing()))
          continue;
        comp.validate();
      }
  }

  /**
   * Repaint all regions of all components which have been marked dirty in the
   * {@link #dirtyComponents} table.
   */
  public void paintDirtyRegions()
  {
    // Short circuit if there is nothing to paint.
    if (dirtyComponents.size() == 0)
      return;

    // Swap dirtyRegions with dirtyRegionsWork to avoid locking.
    synchronized (dirtyComponents)
      {
        HashMap swap = dirtyComponents;
        dirtyComponents = dirtyComponentsWork;
        dirtyComponentsWork = swap;
      }

    // Compile a set of repaint roots.
    HashSet repaintRoots = new HashSet();
    Set components = dirtyComponentsWork.keySet();
    for (Iterator i = components.iterator(); i.hasNext();)
      {
        JComponent dirty = (JComponent) i.next();
        compileRepaintRoots(dirtyComponentsWork, dirty, repaintRoots);
      }

    for (Iterator i = repaintRoots.iterator(); i.hasNext();)
      {
        JComponent comp = (JComponent) i.next();
        Rectangle damaged = (Rectangle) dirtyComponentsWork.remove(comp);
        if (damaged == null || damaged.isEmpty())
          continue;
        comp.paintImmediately(damaged);
      }
    dirtyComponentsWork.clear();
  }

  /**
   * Compiles a list of components that really get repainted. This is called
   * once for each component in the dirtyRegions HashMap, each time with
   * another <code>dirty</code> parameter. This searches up the component
   * hierarchy of <code>dirty</code> to find the highest parent that is also
   * marked dirty and merges the dirty regions.
   *
   * @param dirtyRegions the dirty regions
   * @param dirty the component for which to find the repaint root
   * @param roots the list to which new repaint roots get appended
   */
  private void compileRepaintRoots(HashMap dirtyRegions, JComponent dirty,
                                   HashSet roots)
  {
    Component current = dirty;
    Component root = dirty;

    // This will contain the dirty region in the root coordinate system,
    // possibly clipped by ancestor's bounds.
    Rectangle originalDirtyRect = (Rectangle) dirtyRegions.get(dirty);
    rectCache.setBounds(originalDirtyRect);

    // The bounds of the current component.
    int x = dirty.getX();
    int y = dirty.getY();
    int w = dirty.getWidth();
    int h = dirty.getHeight();

    // Do nothing if dirty region is clipped away by the component's bounds.
    rectCache = SwingUtilities.computeIntersection(0, 0, w, h, rectCache);
    if (rectCache.isEmpty())
      return;

    // The cumulated offsets.
    int dx = 0;
    int dy = 0;
    // The actual offset for the found root.
    int rootDx = 0;
    int rootDy = 0;

    // Search the highest component that is also marked dirty.
    Component parent;
    while (true)
      {
        parent = current.getParent();
        if (parent == null || !(parent instanceof JComponent))
          break;

        current = parent;
        // Update the offset.
        dx += x;
        dy += y;
        rectCache.x += x;
        rectCache.y += y;

        x = current.getX();
        y = current.getY();
        w = current.getWidth();
        h = current.getHeight();
        rectCache = SwingUtilities.computeIntersection(0, 0, w, h, rectCache);

        // Don't paint if the dirty regions is clipped away by any of
        // its ancestors.
        if (rectCache.isEmpty())
          return;

        // We can skip to the next up when this parent is not dirty.
        if (dirtyRegions.containsKey(parent))
          {
            root = current;
            rootDx = dx;
            rootDy = dy;
          }
      }

    // Merge the rectangles of the root and the requested component if
    // the are different.
    if (root != dirty)
      {
        rectCache.x += rootDx - dx;
        rectCache.y += rootDy - dy;
        Rectangle dirtyRect = (Rectangle) dirtyRegions.get(root);
        SwingUtilities.computeUnion(rectCache.x, rectCache.y, rectCache.width,
                                    rectCache.height, dirtyRect);
      }

    // Adds the root to the roots set.
    if (! roots.contains(root))
      roots.add(root);
  }

  /**
   * Get an offscreen buffer for painting a component's image. This image
   * may be smaller than the proposed dimensions, depending on the value of
   * the {@link #doubleBufferMaximumSize} property.
   *
   * @param component The component to return an offscreen buffer for
   * @param proposedWidth The proposed width of the offscreen buffer
   * @param proposedHeight The proposed height of the offscreen buffer
   *
   * @return A shared offscreen buffer for painting
   */
  public Image getOffscreenBuffer(Component component, int proposedWidth,
                                  int proposedHeight)
  {
    Component root = SwingUtilities.getWindowAncestor(component);
    Image buffer = (Image) offscreenBuffers.get(root);
    if (buffer == null
        || buffer.getWidth(null) < proposedWidth
        || buffer.getHeight(null) < proposedHeight)
      {
        int width = Math.max(proposedWidth, root.getWidth());
        width = Math.min(doubleBufferMaximumSize.width, width);
        int height = Math.max(proposedHeight, root.getHeight());
        height = Math.min(doubleBufferMaximumSize.height, height);
        buffer = component.createImage(width, height);
        offscreenBuffers.put(root, buffer);
      }
    return buffer;
  }

  /**
   * Blits the back buffer of the specified root component to the screen.
   * This is package private because it must get called by JComponent.
   *
   * @param comp the component to be painted
   * @param x the area to paint on screen, in comp coordinates
   * @param y the area to paint on screen, in comp coordinates
   * @param w the area to paint on screen, in comp coordinates
   * @param h the area to paint on screen, in comp coordinates
   */
  void commitBuffer(Component comp, int x, int y, int w, int h)
  {
    Component root = comp;
    while (root != null
           && ! (root instanceof Window || root instanceof Applet))
      {
        x += root.getX();
        y += root.getY();
        root = root.getParent();
      }

    if (root != null)
      {
        Graphics g = root.getGraphics();
        Image buffer = (Image) offscreenBuffers.get(root);
        if (buffer != null)
          {
            // Make sure we have a sane clip at this point.
            g.clipRect(x, y, w, h);
            g.drawImage(buffer, 0, 0, root);
            g.dispose();
          }
      }
  }

  /**
   * Creates and returns a volatile offscreen buffer for the specified
   * component that can be used as a double buffer. The returned image
   * is a {@link VolatileImage}. Its size will be <code>(proposedWidth,
   * proposedHeight)</code> except when the maximum double buffer size
   * has been set in this RepaintManager.
   *
   * @param comp the Component for which to create a volatile buffer
   * @param proposedWidth the proposed width of the buffer
   * @param proposedHeight the proposed height of the buffer
   *
   * @since 1.4
   *
   * @see VolatileImage
   */
  public Image getVolatileOffscreenBuffer(Component comp, int proposedWidth,
                                          int proposedHeight)
  {
    Component root = SwingUtilities.getWindowAncestor(comp);
    Image buffer = (Image) offscreenBuffers.get(root);
    if (buffer == null
        || buffer.getWidth(null) < proposedWidth
        || buffer.getHeight(null) < proposedHeight
        || !(buffer instanceof VolatileImage))
      {
        int width = Math.max(proposedWidth, root.getWidth());
        width = Math.min(doubleBufferMaximumSize.width, width);
        int height = Math.max(proposedHeight, root.getHeight());
        height = Math.min(doubleBufferMaximumSize.height, height);
        buffer = root.createVolatileImage(width, height);
        if (buffer != null)
          offscreenBuffers.put(root, buffer);
      }
    return buffer;
  }


  /**
   * Get the value of the {@link #doubleBufferMaximumSize} property.
   *
   * @return The current value of the property
   *
   * @see #setDoubleBufferMaximumSize
   */
  public Dimension getDoubleBufferMaximumSize()
  {
    return doubleBufferMaximumSize;
  }

  /**
   * Set the value of the {@link #doubleBufferMaximumSize} property.
   *
   * @param size The new value of the property
   *
   * @see #getDoubleBufferMaximumSize
   */
  public void setDoubleBufferMaximumSize(Dimension size)
  {
    doubleBufferMaximumSize = size;
  }

  /**
   * Set the value of the {@link #doubleBufferingEnabled} property.
   *
   * @param buffer The new value of the property
   *
   * @see #isDoubleBufferingEnabled
   */
  public void setDoubleBufferingEnabled(boolean buffer)
  {
    doubleBufferingEnabled = buffer;
  }

  /**
   * Get the value of the {@link #doubleBufferingEnabled} property.
   *
   * @return The current value of the property
   *
   * @see #setDoubleBufferingEnabled
   */
  public boolean isDoubleBufferingEnabled()
  {
    return doubleBufferingEnabled;
  }

  public String toString()
  {
    return "RepaintManager";
  }

  /**
   * Sends an RepaintManagerEvent to the event queue with the specified
   * runnable. This is similar to SwingUtilities.invokeLater(), only that the
   * event is a low priority event in order to defer the execution a little
   * more.
   */
  private void invokeLater(Runnable runnable)
  {
    Toolkit tk = Toolkit.getDefaultToolkit();
    EventQueue evQueue = tk.getSystemEventQueue();
    InvocationEvent ev = new RepaintWorkerEvent(evQueue, runnable, null, false);
    evQueue.postEvent(ev);
  }
}
