/* CellRendererPane.java --
   Copyright (C) 2002, 2004, 2006, 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 java.awt.Component;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Rectangle;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;

/**
 * Paints the cells of JList, JTable and JTree.
 * It intercepts the usual paint tree, so that we don't walk up and
 * repaint everything.
 *
 * @author Andrew Selkirk
 */
public class CellRendererPane extends Container implements Accessible
{
  private static final long serialVersionUID = -7642183829532984273L;

  /**
   * Provides accessibility support for CellRendererPanes.
   */
  protected class AccessibleCellRendererPane extends AccessibleAWTContainer
  {
    private static final long serialVersionUID = -8981090083147391074L;

    /**
     * Constructor AccessibleCellRendererPane
     */
    protected AccessibleCellRendererPane()
    {
      // Nothing to do here.
    }

    /**
     * getAccessibleRole
     * @return AccessibleRole
     */
    public AccessibleRole getAccessibleRole()
    {
      return AccessibleRole.PANEL;
    }
  }

  /**
   * accessibleContext
   */
  protected AccessibleContext accessibleContext = null;

  /**
   * Constructs a new CellRendererPane.
   */
  public CellRendererPane()
  {
    setVisible(false);
  }

  /**
   * Should not be called.
   *
   * @param graphics not used here
   */
  public void update(Graphics graphics)
  {
    //Nothing to do here.
  }

  /**
   * Despite normal behaviour this does <em>not</em> cause the container
   * to be invalidated. This prevents propagating up the paint tree.
   */
  public void invalidate()
  {
    // Overridden to do nothing.
  }

  /**
   * Should not be called.
   *
   * @param graphics not used here
   */
  public void paint(Graphics graphics)
  {
    // Overridden to do nothing.
  }

  /**
   * Overridden to check if a component is already a child of this Container.
   * If it's already a child, nothing is done. Otherwise we pass this to
   * <code>super.addImpl()</code>.
   *
   * @param c the component to add
   * @param constraints not used here
   * @param index not used here
   */
  protected void addImpl(Component c, Object constraints, int index)
  {
    if (!isAncestorOf(c))
      {
        super.addImpl(c, constraints, index);
      }
  }

  /**
   * Paints the specified component <code>c</code> on the {@link Graphics}
   * context <code>graphics</code>. The Graphics context is tranlated to
   * (x,y) and the components bounds are set to (w,h). If
   * <code>shouldValidate</code>
   * is set to true, then the component is validated before painting.
   *
   * @param graphics the graphics context to paint on
   * @param c the component to be painted
   * @param p the parent of the component
   * @param x the X coordinate of the upper left corner where c should
            be painted
   * @param y the Y coordinate of the upper left corner where c should
            be painted
   * @param w the width of the components drawing area
   * @param h the height of the components drawing area
   * @param shouldValidate if <code>c</code> should be validated before
   *        painting
   */
  public void paintComponent(Graphics graphics, Component c,
                             Container p, int x, int y, int w, int h,
                             boolean shouldValidate)
  {
    // reparent c
    addImpl(c, null, 0);

    Rectangle oldClip = graphics.getClipBounds();
    boolean translated = false;
    try
      {
        // translate to (x,y)
        graphics.translate(x, y);
        translated = true;
        graphics.clipRect(0, 0, w, h);
        // set bounds of c
        c.setBounds(0, 0, w, h);

        // validate if necessary
        if (shouldValidate)
          {
            c.validate();
          }

        // paint component
        c.paint(graphics);
      }
    finally
      {
        // untranslate g
        if (translated)
          graphics.translate(-x, -y);
        graphics.setClip(oldClip);
      }
  }

  /**
   * Paints the specified component <code>c</code> on the {@link Graphics}
   * context <code>graphics</code>. The Graphics context is tranlated to (x,y)
   * and the components bounds are set to (w,h). The component is <em>not</em>
   * validated before painting.
   *
   * @param graphics the graphics context to paint on
   * @param c the component to be painted
   * @param p the parent of the component
   * @param x the X coordinate of the upper left corner where c should
            be painted
   * @param y the Y coordinate of the upper left corner where c should
            be painted
   * @param w the width of the components drawing area
   * @param h the height of the components drawing area
   */
  public void paintComponent(Graphics graphics, Component c,
                             Container p, int x, int y, int w, int h)
  {
    paintComponent(graphics, c, p, x, y, w, h, false);
  }

  /**
   * Paints the specified component <code>c</code> on the {@link Graphics}
   * context <code>g</code>. The Graphics context is tranlated to (r.x,r.y) and
   * the components bounds are set to (r.width,r.height).
   * The component is <em>not</em>
   * validated before painting.
   *
   * @param graphics the graphics context to paint on
   * @param c the component to be painted
   * @param p the component on which we paint
   * @param r the bounding rectangle of c
   */
  public void paintComponent(Graphics graphics, Component c,
                             Container p, Rectangle r)
  {
    paintComponent(graphics, c, p, r.x, r.y, r.width, r.height);
  }

  /**
   * getAccessibleContext <em>TODO</em>
   * @return AccessibleContext
   */
  public AccessibleContext getAccessibleContext()
  {
    if (accessibleContext == null)
      accessibleContext = new AccessibleCellRendererPane();

    return accessibleContext;
  }
}
