/* 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.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;

import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JTree;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
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;

  /**
   * drawsFocusBorderAroundIcon  // FIXME: is this used?
   */
  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"));
  }

  /**
   * 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)
  {
    // paint background
    Rectangle vr = new Rectangle();
    Rectangle ir = new Rectangle();
    Rectangle tr = new Rectangle();

    Insets insets = new Insets(0, 0, 0, 0);
    Border border = UIManager.getBorder("Tree.selectionBorder");
    if (border != null)
      insets = border.getBorderInsets(this);

    FontMetrics fm = getToolkit().getFontMetrics(getFont());
    SwingUtilities.layoutCompoundLabel((JLabel) this, fm, getText(),
                                       getIcon(), getVerticalAlignment(),
                                       getHorizontalAlignment(),
                                       getVerticalTextPosition(),
                                       getHorizontalTextPosition(), vr, ir, tr,
                                       getIconTextGap());

    // Reusing one rectangle.
    Rectangle bounds = getBounds(ir);
    
    bounds.x = tr.x - insets.left;
    bounds.width = tr.width + insets.left + insets.right;
    
    g.setColor(super.getBackground());
    g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);

    super.paint(g);
    
    // Paint the border of the focused element only (lead selection)
    if (hasFocus)
      {
        Color b = getBorderSelectionColor();
        if (b != null)
          {
            g.setColor(b);
            g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height - 1);
          }
      }
  }

  /**
   * Returns the preferred size of the cell.
   * 
   * @return The preferred size of the cell.
   */
  public Dimension getPreferredSize()
  {
    Rectangle vr = new Rectangle();
    Rectangle ir = new Rectangle();
    Rectangle tr = new Rectangle();

    FontMetrics fm = getToolkit().getFontMetrics(getFont());
    SwingUtilities.layoutCompoundLabel((JLabel) this, fm, getText(),
                                       getIcon(), getVerticalAlignment(),
                                       getHorizontalAlignment(),
                                       getVerticalTextPosition(),
                                       getHorizontalTextPosition(), vr, ir, tr,
                                       getIconTextGap());
    Rectangle cr = ir.union(tr);
    return new Dimension(cr.width, cr.height);
  } 

  /**
   * 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.
  } 

} 
