/*
 * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package org.linotte.frame.cahier.sommaire;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.UIResource;
import javax.swing.tree.TreeCellRenderer;
import java.awt.*;

//import sun.swing.DefaultLookup;

/**
 * Displays an entry in a tree.
 * <code>DefaultTreeCellRenderer</code> is not opaque and
 * unless you subclass paint you should not change this.
 * See <a
 href="http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html">How to Use Trees</a>
 * in <em>The Java Tutorial</em>
 * for examples of customizing node display using this class.
 * <p>
 * The set of icons and colors used by {@code DefaultTreeCellRenderer}
 * can be configured using the various setter methods. The value for
 * each property is initialized from the defaults table. When the
 * look and feel changes ({@code updateUI} is invoked), any properties
 * that have a value of type {@code UIResource} are refreshed from the
 * defaults table. The following table lists the mapping between
 * {@code DefaultTreeCellRenderer} property and defaults table key:
 * <table border="1" cellpadding="1" cellspacing="0"
 *         valign="top" >
 *   <tr valign="top"  align="left">
 *     <th bgcolor="#CCCCFF" align="left">Property:
 *     <th bgcolor="#CCCCFF" align="left">Key:
 *   <tr><td>"leafIcon"<td>"Tree.leafIcon"
 *   <tr><td>"closedIcon"<td>"Tree.closedIcon"
 *   <tr><td>"openIcon"<td>"Tree.openIcon"
 *   <tr><td>"textSelectionColor"<td>"Tree.selectionForeground"
 *   <tr><td>"textNonSelectionColor"<td>"Tree.textForeground"
 *   <tr><td>"backgroundSelectionColor"<td>"Tree.selectionBackground"
 *   <tr><td>"backgroundNonSelectionColor"<td>"Tree.textBackground"
 *   <tr><td>"borderSelectionColor"<td>"Tree.selectionBorderColor"
 * </table>
 * <p>
 * <strong><a name="override">Implementation Note:</a></strong>
 * This class overrides
 * <code>invalidate</code>,
 * <code>validate</code>,
 * <code>revalidate</code>,
 * <code>repaint</code>,
 * and
 * <code>firePropertyChange</code>
 * solely to improve performance.
 * If not overridden, these frequently called methods would execute code paths
 * that are unnecessary for the default tree cell renderer.
 * If you write your own renderer,
 * take care to weigh the benefits and
 * drawbacks of overriding these methods.
 *
 * <p>
 * <strong>Warning:</strong>
 * Serialized objects of this class will not be compatible with
 * future Swing releases. The current serialization support is
 * appropriate for short term storage or RMI between applications running
 * the same version of Swing.  As of 1.4, support for long term storage
 * of all JavaBeans<sup><font size="-2">TM</font></sup>
 * has been added to the <code>java.beans</code> package.
 * Please see {@link java.beans.XMLEncoder}.
 *
 * @author Rob Davis
 * @author Ray Ryan
 * @author Scott Violet
 * @author Cpc6128 : ajout de l'attribut actif
 */
@SuppressWarnings("serial")
public class SommaireTreeCellRenderer extends JLabel implements TreeCellRenderer {

	/** Est-ce que le noeud est actif ?*/
	private boolean actif;
	private static final Color couleurActive = new Color(213, 211, 255);

	/** Last tree the renderer was painted in. */
	private JTree tree;

	/** Is the value currently selected. */
	protected boolean selected;
	/** True if has focus. */
	protected boolean hasFocus;
	/** True if draws focus border around icon as well. */
	private boolean drawsFocusBorderAroundIcon;
	/** If true, a dashed line is drawn as the focus indicator. */
	private boolean drawDashedFocusIndicator;

	// If drawDashedFocusIndicator is true, the following are used.
	/**
	 * Background color of the tree.
	 */
	private Color treeBGColor;

	// Icons
	/** Icon used to show non-leaf nodes that aren't expanded. */
	transient protected Icon closedIcon;

	/** Icon used to show leaf nodes. */
	transient protected Icon leafIcon;

	/** Icon used to show non-leaf nodes that are expanded. */
	transient protected Icon openIcon;

	// Colors
	/** Color to use for the foreground for selected nodes. */
	protected Color textSelectionColor;

	/** Color to use for the foreground for non-selected nodes. */
	protected Color textNonSelectionColor;

	/** Color to use for the background when a node is selected. */
	protected Color backgroundSelectionColor;

	/** Color to use for the background when the node isn't selected. */
	protected Color backgroundNonSelectionColor;

	/** Color to use for the focus indicator when the node has focus. */
	protected Color borderSelectionColor;

	private boolean isDropCell;
	private boolean fillBackground = true;

	/**
	 * Set to true after the constructor has run.
	 */
	private boolean inited;

	/**
	 * Creates a {@code DefaultTreeCellRenderer}. Icons and text color are
	 * determined from the {@code UIManager}.
	 */
	public SommaireTreeCellRenderer() {
		inited = true;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @since 1.7
	 */
	public void updateUI() {
		super.updateUI();
		// To avoid invoking new methods from the constructor, the
		// inited field is first checked. If inited is false, the constructor
		// has not run and there is no point in checking the value. As
		// all look and feels have a non-null value for these properties,
		// a null value means the developer has specifically set it to
		// null. As such, if the value is null, this does not reset the
		// value.
		if (!inited || (getLeafIcon() instanceof UIResource)) {
			setLeafIcon(UIManager.getIcon( "Tree.leafIcon"));
		}
		if (!inited || (getClosedIcon() instanceof UIResource)) {
			setClosedIcon(UIManager.getIcon("Tree.closedIcon"));
		}
		if (!inited || (getOpenIcon() instanceof UIManager)) {
			setOpenIcon(UIManager.getIcon("Tree.openIcon"));
		}
		if (!inited || (getTextSelectionColor() instanceof UIResource)) {
			setTextSelectionColor(UIManager.getColor("Tree.selectionForeground"));
		}
		if (!inited || (getTextNonSelectionColor() instanceof UIResource)) {
			setTextNonSelectionColor(UIManager.getColor("Tree.textForeground"));
		}
		if (!inited || (getBackgroundSelectionColor() instanceof UIResource)) {
			setBackgroundSelectionColor(UIManager.getColor("Tree.selectionBackground"));
		}
		if (!inited || (getBackgroundNonSelectionColor() instanceof UIResource)) {
			setBackgroundNonSelectionColor(UIManager.getColor("Tree.textBackground"));
		}
		if (!inited || (getBorderSelectionColor() instanceof UIResource)) {
			setBorderSelectionColor(UIManager.getColor( "Tree.selectionBorderColor"));
		}
		drawsFocusBorderAroundIcon = UIManager.getBoolean("Tree.drawsFocusBorderAroundIcon");
		drawDashedFocusIndicator = UIManager.getBoolean( "Tree.drawDashedFocusIndicator");

		fillBackground = UIManager.getBoolean( "Tree.rendererFillBackground");
		Insets margins = UIManager.getInsets( "Tree.rendererMargins");
		if (margins != null) {
			setBorder(new EmptyBorder(margins.top, margins.left, margins.bottom, margins.right));
		}

		setName("Tree.cellRenderer");
	}

	/**
	  * Returns the default icon, for the current laf, that is used to
	  * represent non-leaf nodes that are expanded.
	  */
	public Icon getDefaultOpenIcon() {
		return UIManager.getIcon("Tree.openIcon");
	}

	/**
	  * Returns the default icon, for the current laf, that is used to
	  * represent non-leaf nodes that are not expanded.
	  */
	public Icon getDefaultClosedIcon() {
		return UIManager.getIcon("Tree.closedIcon");
	}

	/**
	  * Returns the default icon, for the current laf, that is used to
	  * represent leaf nodes.
	  */
	public Icon getDefaultLeafIcon() {
		return UIManager.getIcon("Tree.leafIcon");
	}

	/**
	  * Sets the icon used to represent non-leaf nodes that are expanded.
	  */
	public void setOpenIcon(Icon newIcon) {
		openIcon = newIcon;
	}

	/**
	  * Returns the icon used to represent non-leaf nodes that are expanded.
	  */
	public Icon getOpenIcon() {
		return openIcon;
	}

	/**
	  * Sets the icon used to represent non-leaf nodes that are not expanded.
	  */
	public void setClosedIcon(Icon newIcon) {
		closedIcon = newIcon;
	}

	/**
	  * Returns the icon used to represent non-leaf nodes that are not
	  * expanded.
	  */
	public Icon getClosedIcon() {
		return closedIcon;
	}

	/**
	  * Sets the icon used to represent leaf nodes.
	  */
	public void setLeafIcon(Icon newIcon) {
		leafIcon = newIcon;
	}

	/**
	  * Returns the icon used to represent leaf nodes.
	  */
	public Icon getLeafIcon() {
		return leafIcon;
	}

	/**
	  * Sets the color the text is drawn with when the node is selected.
	  */
	public void setTextSelectionColor(Color newColor) {
		textSelectionColor = newColor;
	}

	/**
	  * Returns the color the text is drawn with when the node is selected.
	  */
	public Color getTextSelectionColor() {
		return textSelectionColor;
	}

	/**
	  * Sets the color the text is drawn with when the node isn't selected.
	  */
	public void setTextNonSelectionColor(Color newColor) {
		textNonSelectionColor = newColor;
	}

	/**
	  * Returns the color the text is drawn with when the node isn't selected.
	  */
	public Color getTextNonSelectionColor() {
		return textNonSelectionColor;
	}

	/**
	  * Sets the color to use for the background if node is selected.
	  */
	public void setBackgroundSelectionColor(Color newColor) {
		backgroundSelectionColor = newColor;
	}

	/**
	  * Returns the color to use for the background if node is selected.
	  */
	public Color getBackgroundSelectionColor() {
		return backgroundSelectionColor;
	}

	/**
	  * Sets the background color to be used for non selected nodes.
	  */
	public void setBackgroundNonSelectionColor(Color newColor) {
		backgroundNonSelectionColor = newColor;
	}

	/**
	  * Returns the background color to be used for non selected nodes.
	  */
	public Color getBackgroundNonSelectionColor() {
		return backgroundNonSelectionColor;
	}

	/**
	  * Sets the color to use for the border.
	  */
	public void setBorderSelectionColor(Color newColor) {
		borderSelectionColor = newColor;
	}

	/**
	  * Returns the color the border is drawn.
	  */
	public Color getBorderSelectionColor() {
		return borderSelectionColor;
	}

	/**
	 * Subclassed to map <code>FontUIResource</code>s to null. If
	 * <code>font</code> is null, or a <code>FontUIResource</code>, this
	 * has the effect of letting the font of the JTree show
	 * through. On the other hand, if <code>font</code> is non-null, and not
	 * a <code>FontUIResource</code>, the font becomes <code>font</code>.
	 */
	public void setFont(Font font) {
		if (font instanceof FontUIResource)
			font = null;
		super.setFont(font);
	}

	/**
	 * Gets the font of this component.
	 * @return this component's font; if a font has not been set
	 * for this component, the font of its parent is returned
	 */
	public Font getFont() {
		Font font = super.getFont();

		if (font == null && tree != null) {
			// Strive to return a non-null value, otherwise the html support
			// will typically pick up the wrong font in certain situations.
			font = tree.getFont();
		}
		return font;
	}

	/**
	 * Subclassed to map <code>ColorUIResource</code>s to null. If
	 * <code>color</code> is null, or a <code>ColorUIResource</code>, this
	 * has the effect of letting the background color of the JTree show
	 * through. On the other hand, if <code>color</code> is non-null, and not
	 * a <code>ColorUIResource</code>, the background becomes
	 * <code>color</code>.
	 */
	public void setBackground(Color color) {
		if (color instanceof ColorUIResource)
			color = null;
		super.setBackground(color);
	}

	/**
	  * Configures the renderer based on the passed in components.
	  * The value is set from messaging the tree with
	  * <code>convertValueToText</code>, which ultimately invokes
	  * <code>toString</code> on <code>value</code>.
	  * The foreground color is set based on the selection and the icon
	  * is set based on the <code>leaf</code> and <code>expanded</code>
	  * parameters.
	  */
	public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
		String stringValue = tree.convertValueToText(value, sel, expanded, leaf, row, hasFocus);

		this.tree = tree;
		this.hasFocus = hasFocus;
		setText(stringValue);

		Color fg = null;
		isDropCell = false;

		JTree.DropLocation dropLocation = tree.getDropLocation();
		if (dropLocation != null && dropLocation.getChildIndex() == -1 && tree.getRowForPath(dropLocation.getPath()) == row) {

			Color col = UIManager.getColor("Tree.dropCellForeground");
			if (col != null) {
				fg = col;
			} else {
				fg = getTextSelectionColor();
			}

			isDropCell = true;
		} else if (sel) {
			fg = getTextSelectionColor();
		} else {
			fg = getTextNonSelectionColor();
		}

		setForeground(fg);

		Icon icon = null;
		if (leaf) {
			icon = getLeafIcon();
		} else if (expanded) {
			icon = getOpenIcon();
		} else {
			icon = getClosedIcon();
		}

		if (!tree.isEnabled()) {
			setEnabled(false);
			LookAndFeel laf = UIManager.getLookAndFeel();
			Icon disabledIcon = laf.getDisabledIcon(tree, icon);
			if (disabledIcon != null)
				icon = disabledIcon;
			setDisabledIcon(icon);
		} else {
			setEnabled(true);
			setIcon(icon);
		}
		setComponentOrientation(tree.getComponentOrientation());

		selected = sel;

		return this;
	}

	/**
	  * Paints the value.  The background is filled based on selected.
	  */
	public void paint(Graphics g) {
		Color bColor;
		/** ça n'a pas de sens :*/
		selected = false;

		if (isDropCell) {
			bColor = UIManager.getColor( "Tree.dropCellBackground");
			if (bColor == null) {
				bColor = getBackgroundSelectionColor();
			}
		} else if (selected) {
			bColor = getBackgroundSelectionColor();
		} else {
			bColor = getBackgroundNonSelectionColor();
			if (bColor == null) {
				bColor = getBackground();
			}
		}

		int imageOffset = -1;
		if (bColor != null && fillBackground) {
			imageOffset = getLabelStart();
			g.setColor(bColor);
			//            if(getComponentOrientation().isLeftToRight()) {
			//                g.drawRect(imageOffset, 0, getWidth() - imageOffset,
			//                           getHeight());
			//            } else {
			//                g.drawRect(0, 0, getWidth() - imageOffset,
			//                           getHeight());
			//            }
		}

		if (isActif()) {
			if (drawsFocusBorderAroundIcon) {
				imageOffset = 0;
			} else if (imageOffset == -1) {
				imageOffset = getLabelStart();
			}
			if (getComponentOrientation().isLeftToRight()) {
				paintFocus(g, imageOffset, 0, getWidth() - imageOffset, getHeight(), bColor);
			} else {
				paintFocus(g, 0, 0, getWidth() - imageOffset, getHeight(), bColor);
			}
		}
		super.paint(g);
	}

	private void paintFocus(Graphics g, int x, int y, int w, int h, Color notColor) {
		Color bsColor = getBorderSelectionColor();

		if (bsColor != null && (selected || !drawDashedFocusIndicator)) {
			g.setColor(bsColor);
			g.drawRect(x, y, w - 1, h - 1);
		}
		if (drawDashedFocusIndicator && notColor != null) {
			if (treeBGColor != notColor) {
				treeBGColor = notColor;
			}
			g.setColor(couleurActive);
			g.fillRoundRect(x, y, w, h, 10, 10);
			//BasicGraphicsUtils.drawDashedRect(g, x, y, w, h);
		}
	}

	private int getLabelStart() {
		Icon currentI = getIcon();
		if (currentI != null && getText() != null) {
			return currentI.getIconWidth() + Math.max(0, getIconTextGap() - 1);
		}
		return 0;
	}

	/**
	 * Overrides <code>JComponent.getPreferredSize</code> to
	 * return slightly wider preferred size value.
	 */
	public Dimension getPreferredSize() {
		Dimension retDimension = super.getPreferredSize();

		if (retDimension != null)
			retDimension = new Dimension(retDimension.width + 3, retDimension.height);
		return retDimension;
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 */
	public void validate() {
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 *
	 * @since 1.5
	 */
	public void invalidate() {
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 */
	public void revalidate() {
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 */
	public void repaint(long tm, int x, int y, int width, int height) {
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 */
	public void repaint(Rectangle r) {
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 *
	 * @since 1.5
	 */
	public void repaint() {
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 */
	protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
		// Strings get interned...
		if (propertyName == "text"
				|| ((propertyName == "font" || propertyName == "foreground") && oldValue != newValue && getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey) != null)) {

			super.firePropertyChange(propertyName, oldValue, newValue);
		}
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 */
	public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 */
	public void firePropertyChange(String propertyName, char oldValue, char newValue) {
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 */
	public void firePropertyChange(String propertyName, short oldValue, short newValue) {
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 */
	public void firePropertyChange(String propertyName, int oldValue, int newValue) {
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 */
	public void firePropertyChange(String propertyName, long oldValue, long newValue) {
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 */
	public void firePropertyChange(String propertyName, float oldValue, float newValue) {
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 */
	public void firePropertyChange(String propertyName, double oldValue, double newValue) {
	}

	/**
	 * Overridden for performance reasons.
	 * See the <a href="#override">Implementation Note</a>
	 * for more information.
	 */
	public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
	}

	public boolean isActif() {
		return actif;
	}

	public void setActif(boolean actif) {
		this.actif = actif;
	}

}
