/* DefaultTreeCellRenderer.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.tree;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;

import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JTree;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.plaf.UIResource;

/**
 * A default implementation of the {@link TreeCellRenderer} interface.
 *
 * @author Andrew Selkirk
 */
public class DefaultTreeCellRenderer
  extends JLabel
  implements TreeCellRenderer
{

  /**
   * A flag indicating the current selection status.
   */
  protected boolean selected;

  /**
   * A flag indicating the current focus status.
   */
  protected boolean hasFocus;

  /**
   * Indicates if the focus border is also drawn around the icon.
   */
  private boolean drawsFocusBorderAroundIcon;

  /**
   * The icon used to represent non-leaf nodes that are closed.
   *
   * @see #setClosedIcon(Icon)
   */
  protected transient Icon closedIcon;

  /**
   * The icon used to represent leaf nodes.
   *
   * @see #setLeafIcon(Icon)
   */
  protected transient Icon leafIcon;

  /**
   * The icon used to represent non-leaf nodes that are open.
   *
   * @see #setOpenIcon(Icon)
   */
  protected transient Icon openIcon;

  /**
   * The color used for text in selected cells.
   *
   * @see #setTextSelectionColor(Color)
   */
  protected Color textSelectionColor;

  /**
   * The color used for text in non-selected cells.
   *
   * @see #setTextNonSelectionColor(Color)
   */
  protected Color textNonSelectionColor;

  /**
   * The background color for selected cells.
   *
   * @see #setBackgroundSelectionColor(Color)
   */
  protected Color backgroundSelectionColor;

  /**
   * The background color for non-selected cells.
   *
   * @see #setBackgroundNonSelectionColor(Color)
   */
  protected Color backgroundNonSelectionColor;

  /**
   * The border color for selected tree cells.
   *
   * @see #setBorderSelectionColor(Color)
   */
  protected Color borderSelectionColor;

  /**
   * Creates a new tree cell renderer with defaults appropriate for the
   * current {@link LookAndFeel}.
   */
  public DefaultTreeCellRenderer()
  {
    setLeafIcon(getDefaultLeafIcon());
    setOpenIcon(getDefaultOpenIcon());
    setClosedIcon(getDefaultClosedIcon());

    setTextNonSelectionColor(UIManager.getColor("Tree.textForeground"));
    setTextSelectionColor(UIManager.getColor("Tree.selectionForeground"));
    setBackgroundNonSelectionColor(UIManager.getColor("Tree.textBackground"));
    setBackgroundSelectionColor(UIManager.getColor("Tree.selectionBackground"));
    setBorderSelectionColor(UIManager.getColor("Tree.selectionBorderColor"));
    Object val = UIManager.get("Tree.drawsFocusBorderAroundIcon");
    drawsFocusBorderAroundIcon = val != null && ((Boolean) val).booleanValue();
  }

  /**
   * Returns the default icon for non-leaf tree cells that are open (expanded).
   * The icon is fetched from the defaults table for the current
   * {@link LookAndFeel} using the key <code>Tree.openIcon</code>.
   *
   * @return The default icon.
   */
  public Icon getDefaultOpenIcon()
  {
    return UIManager.getIcon("Tree.openIcon");
  }

  /**
   * Returns the default icon for non-leaf tree cells that are closed (not
   * expanded).  The icon is fetched from the defaults table for the current
   * {@link LookAndFeel} using the key <code>Tree.closedIcon</code>.
   *
   * @return The default icon.
   */
  public Icon getDefaultClosedIcon()
  {
    return UIManager.getIcon("Tree.closedIcon");
  }

  /**
   * Returns the default icon for leaf tree cells.  The icon is fetched from
   * the defaults table for the current {@link LookAndFeel} using the key
   * <code>Tree.leafIcon</code>.
   *
   * @return The default icon.
   */
  public Icon getDefaultLeafIcon()
  {
    return UIManager.getIcon("Tree.leafIcon");
  }

  /**
   * Sets the icon to be displayed for non-leaf nodes that are open (expanded).
   * Set this to <code>null</code> if no icon is required.
   *
   * @param icon  the icon (<code>null</code> permitted).
   *
   * @see #getOpenIcon()
   */
  public void setOpenIcon(Icon icon)
  {
    openIcon = icon;
  }

  /**
   * Returns the icon displayed for non-leaf nodes that are open (expanded).
   * The default value is initialised from the {@link LookAndFeel}.
   *
   * @return The open icon (possibly <code>null</code>).
   *
   * @see #setOpenIcon(Icon)
   */
  public Icon getOpenIcon()
  {
    return openIcon;
  }

  /**
   * Sets the icon to be displayed for non-leaf nodes that are closed.  Set
   * this to <code>null</code> if no icon is required.
   *
   * @param icon  the icon (<code>null</code> permitted).
   *
   * @see #getClosedIcon()
   */
  public void setClosedIcon(Icon icon)
  {
    closedIcon = icon;
  }

  /**
   * Returns the icon displayed for non-leaf nodes that are closed.  The
   * default value is initialised from the {@link LookAndFeel}.
   *
   * @return The closed icon (possibly <code>null</code>).
   *
   * @see #setClosedIcon(Icon)
   */
  public Icon getClosedIcon()
  {
    return closedIcon;
  }

  /**
   * Sets the icon to be displayed for leaf nodes.  Set this to
   * <code>null</code> if no icon is required.
   *
   * @param icon  the icon (<code>null</code> permitted).
   *
   * @see #getLeafIcon()
   */
  public void setLeafIcon(Icon icon)
  {
    leafIcon = icon;
  }

  /**
   * Returns the icon displayed for leaf nodes.  The default value is
   * initialised from the {@link LookAndFeel}.
   *
   * @return The leaf icon (possibly <code>null</code>).
   *
   * @see #setLeafIcon(Icon)
   */
  public Icon getLeafIcon()
  {
    return leafIcon;
  }

  /**
   * Sets the text color for tree cells that are selected.
   *
   * @param c  the color (<code>null</code> permitted).
   *
   * @see #getTextSelectionColor()
   */
  public void setTextSelectionColor(Color c)
  {
    textSelectionColor = c;
  }

  /**
   * Returns the text color for tree cells that are selected.
   * The default value is obtained from the {@link LookAndFeel} defaults
   * table using the key <code>Tree.selectionForeground</code>.
   *
   * @return The text color for tree cells that are selected.
   *
   * @see #setTextSelectionColor(Color)
   */
  public Color getTextSelectionColor()
  {
    return textSelectionColor;
  }

  /**
   * Sets the text color for tree cells that are not selected.
   *
   * @param c  the color (<code>null</code> permitted).
   *
   * @see #getTextNonSelectionColor()
   */
  public void setTextNonSelectionColor(Color c)
  {
    textNonSelectionColor = c;
  }

  /**
   * Returns the text color for tree cells that are not selected.
   * The default value is obtained from the {@link LookAndFeel} defaults
   * table using the key <code>Tree.selectionForeground</code>.
   *
   * @return The background color for tree cells that are not selected.
   *
   * @see #setTextgroundNonSelectionColor(Color)
   */
  public Color getTextNonSelectionColor()
  {
    return textNonSelectionColor;
  }

  /**
   * Sets the background color for tree cells that are selected.
   *
   * @param c  the color (<code>null</code> permitted).
   *
   * @see #getBackgroundSelectionColor()
   */
  public void setBackgroundSelectionColor(Color c)
  {
    backgroundSelectionColor = c;
  }

  /**
   * Returns the background color for tree cells that are selected.
   * The default value is obtained from the {@link LookAndFeel} defaults
   * table using the key <code>Tree.selectionBackground</code>.
   *
   * @return The background color for tree cells that are selected.
   *
   * @see #setBackgroundSelectionColor(Color)
   */
  public Color getBackgroundSelectionColor()
  {
    return backgroundSelectionColor;
  }

  /**
   * Sets the background color for tree cells that are not selected.
   *
   * @param c  the color (<code>null</code> permitted).
   *
   * @see #getBackgroundNonSelectionColor()
   */
  public void setBackgroundNonSelectionColor(Color c)
  {
    backgroundNonSelectionColor = c;
  }

  /**
   * Returns the background color for tree cells that are not selected.
   * The default value is obtained from the {@link LookAndFeel} defaults
   * table using the key <code>Tree.textBackground</code>.
   *
   * @return The background color for tree cells that are not selected.
   *
   * @see #setBackgroundNonSelectionColor(Color)
   */
  public Color getBackgroundNonSelectionColor()
  {
    return backgroundNonSelectionColor;
  }

  /**
   * Sets the border color for tree cells that are selected.
   *
   * @param c  the color (<code>null</code> permitted).
   *
   * @see #getBorderSelectionColor()
   */
  public void setBorderSelectionColor(Color c)
  {
    borderSelectionColor = c;
  }

  /**
   * Returns the border color for tree cells that are selected.
   * The default value is obtained from the {@link LookAndFeel} defaults
   * table using the key <code>Tree.selectionBorderColor</code>.
   *
   * @return The border color for tree cells that are selected.
   *
   * @see #setBorderSelectionColor(Color)
   */
  public Color getBorderSelectionColor()
  {
    return borderSelectionColor;
  }

  /**
   * Sets the font.
   *
   * @param f the font.
   *
   * @see #getFont()
   */
  public void setFont(Font f)
  {
    if (f != null && f instanceof UIResource)
      f = null;
    super.setFont(f);
  }

  /**
   * Sets the background color.
   *
   * @param c the color.
   */
  public void setBackground(Color c)
  {
    if (c != null && c instanceof UIResource)
      c = null;
    super.setBackground(c);
  }

  /**
   * Returns a component (in fact <code>this</code>) that can be used to
   * render a tree cell with the specified state.
   *
   * @param tree  the tree that the cell belongs to.
   * @param val  the cell value.
   * @param selected  indicates whether or not the cell is selected.
   * @param expanded  indicates whether or not the cell is expanded.
   * @param leaf  indicates whether or not the cell is a leaf in the tree.
   * @param row  the row index.
   * @param hasFocus  indicates whether or not the cell has the focus.
   *
   * @return <code>this</code>.
   */
  public Component getTreeCellRendererComponent(JTree tree, Object val,
                                                boolean selected,
                                                boolean expanded, boolean leaf,
                                                int row, boolean hasFocus)
  {
    if (leaf)
      setIcon(getLeafIcon());
    else if (expanded)
      setIcon(getOpenIcon());
    else
      setIcon(getClosedIcon());

    setText(val.toString());
    this.selected = selected;
    this.hasFocus = hasFocus;
    setHorizontalAlignment(LEFT);
    setOpaque(false);
    setVerticalAlignment(CENTER);
    setEnabled(true);
    super.setFont(UIManager.getFont("Tree.font"));

    if (selected)
      {
        super.setBackground(getBackgroundSelectionColor());
        setForeground(getTextSelectionColor());

        if (hasFocus)
          setBorderSelectionColor(UIManager.getLookAndFeelDefaults().
                                  getColor("Tree.selectionBorderColor"));
        else
          setBorderSelectionColor(null);
      }
    else
      {
        super.setBackground(getBackgroundNonSelectionColor());
        setForeground(getTextNonSelectionColor());
        setBorderSelectionColor(null);
      }

    return this;
  }

  /**
   * Returns the current font.
   *
   * @return The current font.
   *
   * @see #setFont(Font)
   */
  public Font getFont()
  {
    return super.getFont();
  }

  /**
   * Paints the value. The background is filled based on selected.
   *
   * @param g the graphics device.
   */
  public void paint(Graphics g)
  {
    // Determine background color.
    Color bgColor;
    if (selected)
      bgColor = getBackgroundSelectionColor();
    else
      {
        bgColor = getBackgroundNonSelectionColor();
        if (bgColor == null)
          bgColor = getBackground();
      }
    // Paint background.
    int xOffset = -1;
    if (bgColor != null)
      {
        xOffset = getXOffset();
        g.setColor(bgColor);
        g.fillRect(xOffset, 0, getWidth() - xOffset, getHeight());
      }

    if (hasFocus)
      {
        if (drawsFocusBorderAroundIcon)
          xOffset = 0;
        else if (xOffset == -1)
          xOffset = getXOffset();
        paintFocus(g, xOffset, 0, getWidth() - xOffset, getHeight());
      }
    super.paint(g);
  }

  /**
   * Paints the focus indicator.
   */
  private void paintFocus(Graphics g, int x, int y, int w, int h)
  {
    Color col = getBorderSelectionColor();
    if (col != null)
      {
        g.setColor(col);
        g.drawRect(x, y, w - 1, h - 1);
      }
  }

  /**
   * Determines the X offset of the label that is caused by
   * the icon.
   *
   * @return the X offset of the label
   */
  private int getXOffset()
  {
    Icon i = getIcon();
    int offs = 0;
    if (i != null && getText() != null)
      offs = i.getIconWidth() + Math.max(0, getIconTextGap() - 1);
    return offs;
  }

  /**
   * Returns the preferred size of the cell.
   *
   * @return The preferred size of the cell.
   */
  public Dimension getPreferredSize()
  {
    Dimension size = super.getPreferredSize();
    size.width += 3;
    return size;
  }

  /**
   * For performance reasons, this method is overridden to do nothing.
   */
  public void validate()
  {
    // Overridden for performance reasons.
  }

  /**
   * For performance reasons, this method is overridden to do nothing.
   */
  public void revalidate()
  {
    // Overridden for performance reasons.
  }

  /**
   * For performance reasons, this method is overridden to do nothing.
   *
   * @param tm ignored
   * @param x coordinate of the region to mark as dirty
   * @param y coordinate of the region to mark as dirty
   * @param width dimension of the region to mark as dirty
   * @param height dimension of the region to mark as dirty
   */
  public void repaint(long tm, int x, int y, int width, int height)
  {
    // Overridden for performance reasons.
  }

  /**
   * For performance reasons, this method is overridden to do nothing.
   *
   * @param area  the area to repaint.
   */
  public void repaint(Rectangle area)
  {
    // Overridden for performance reasons.
  }

  /**
   * For performance reasons, this method is overridden to do nothing.
   *
   * @param name  the property name.
   * @param oldValue  the old value.
   * @param newValue  the new value.
   */
  protected void firePropertyChange(String name, Object oldValue,
                                    Object newValue)
  {
    // Overridden for performance reasons.
  }

  /**
   * For performance reasons, this method is overridden to do nothing.
   *
   * @param name  the property name.
   * @param oldValue  the old value.
   * @param newValue  the new value.
   */
  public void firePropertyChange(String name, byte oldValue, byte newValue)
  {
    // Overridden for performance reasons.
  }

  /**
   * For performance reasons, this method is overridden to do nothing.
   *
   * @param name  the property name.
   * @param oldValue  the old value.
   * @param newValue  the new value.
   */
  public void firePropertyChange(String name, char oldValue, char newValue)
  {
    // Overridden for performance reasons.
  }

  /**
   * For performance reasons, this method is overridden to do nothing.
   *
   * @param name  the property name.
   * @param oldValue  the old value.
   * @param newValue  the new value.
   */
  public void firePropertyChange(String name, short oldValue, short newValue)
  {
    // Overridden for performance reasons.
  }

  /**
   * For performance reasons, this method is overridden to do nothing.
   *
   * @param name  the property name.
   * @param oldValue  the old value.
   * @param newValue  the new value.
   */
  public void firePropertyChange(String name, int oldValue, int newValue)
  {
    // Overridden for performance reasons.
  }

  /**
   * For performance reasons, this method is overridden to do nothing.
   *
   * @param name  the property name.
   * @param oldValue  the old value.
   * @param newValue  the new value.
   */
  public void firePropertyChange(String name, long oldValue, long newValue)
  {
    // Overridden for performance reasons.
  }

  /**
   * For performance reasons, this method is overridden to do nothing.
   *
   * @param name  the property name.
   * @param oldValue  the old value.
   * @param newValue  the new value.
   */
  public void firePropertyChange(String name, float oldValue, float newValue)
  {
    // Overridden for performance reasons.
  }

  /**
   * For performance reasons, this method is overridden to do nothing.
   *
   * @param name  the property name.
   * @param oldValue  the old value.
   * @param newValue  the new value.
   */
  public void firePropertyChange(String name, double oldValue, double newValue)
  {
    //  Overridden for performance reasons.
  }

  /**
   * For performance reasons, this method is overridden to do nothing.
   *
   * @param name  the property name.
   * @param oldValue  the old value.
   * @param newValue  the new value.
   */
  public void firePropertyChange(String name, boolean oldValue,
                                 boolean newValue)
  {
    //  Overridden for performance reasons.
  }

}
