// HTMLParser Library $Name: v1_6 $ - A java-based parser for HTML
// http://sourceforge.org/projects/htmlparser
// Copyright (C) 2005 Derrick Oswald
//
// Revision Control Information
//
// $Source: /cvsroot/htmlparser/htmlparser/src/org/htmlparser/parserapplications/filterbuilder/HtmlTreeCellRenderer.java,v $
// $Author: derrickoswald $
// $Date: 2005/04/12 11:27:42 $
// $Revision: 1.2 $
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
                                                                                                  
package org.htmlparser.parserapplications.filterbuilder;

import java.awt.Component;
import java.util.Vector;

import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellRenderer;

import org.htmlparser.Attribute;
import org.htmlparser.Node;
import org.htmlparser.lexer.Cursor;
import org.htmlparser.nodes.TagNode;
import org.htmlparser.nodes.TextNode;
import org.htmlparser.util.ParserException;
import org.htmlparser.util.Translate;

/**
 * Renderer for tree view of a NodeList.
 */
public class HtmlTreeCellRenderer
    extends
        DefaultTreeCellRenderer
    implements
        TreeCellRenderer
{
    /**
     * Create a new tree cell renderer for Nodes.
     */
    public HtmlTreeCellRenderer ()
    {
        setLeafIcon (null);
        setClosedIcon (null);
        setOpenIcon (null);
    }

    /**
     * Render the tag as HTML.
     * This is different from the tag's normal toHtml() method in that it
     * doesn't process children or end tags, just the initial tag, and
     * it also wraps the tag in html a label would expect.
     * @see org.htmlparser.Node#toHtml()
     * @param tag The tag to convert to HTML.
     * @return A string suitable for rendering the tag.
     */
    public String toHtml (TagNode tag)
    {
        int length;
        int size;
        Vector attributes;
        Attribute attribute;
        String s;
        boolean children;
        StringBuffer ret;

        length = 2;
        attributes = tag.getAttributesEx ();
        size = attributes.size ();
        for (int i = 0; i < size; i++)
        {
            attribute = (Attribute)attributes.elementAt (i);
            length += attribute.getLength ();
        }
        ret = new StringBuffer (length);
        ret.append ("<");
        for (int i = 0; i < size; i++)
        {
            attribute = (Attribute)attributes.elementAt (i);
            attribute.toString (ret);
        }
        ret.append (">");
        s = Translate.encode (ret.toString ());
        children = null != tag.getChildren ();
        ret = new StringBuffer (s.length () + 13 + (children ? 16 : 0));
        ret.append ("<html>");
        if (children)
            ret.append ("<font color=\"blue\">");
        ret.append (s);
        if (children)
            ret.append ("</font>");
        ret.append ("</html>");

        return (ret.toString ());
    }
    
    /**
     * Express this string node as a printable string
     * This is suitable for display in a debugger or output to a printout.
     * Control characters are replaced by their equivalent escape
     * sequence and contents is truncated to 80 characters.
     * @param node The node to render.
     * @return A string representation of the string node.
     */
    public String toText (TextNode node)
    {
        int startpos;
        int endpos;
        String s;
        char c;
        StringBuffer ret;

        startpos = node.getStartPosition ();
        endpos = node.getEndPosition ();
        ret = new StringBuffer (endpos - startpos + 20);
        s = node.toHtml ();
        for (int i = 0; i < s.length (); i++)
        {
            c = s.charAt (i);
            switch (c)
            {
                case '\t':
                    ret.append ("\\t");
                    break;
                case '\n':
                    ret.append ("\\n");
                    break;
                case '\r':
                    ret.append ("\\r");
                    break;
                default:
                    ret.append (c);
            }
            if (77 <= ret.length ())
            {
                ret.append ("...");
                break;
            }
        }

        return (ret.toString ());
    }

    /**
     * Render the node for the tree cell.
     * @see TreeCellRenderer#getTreeCellRendererComponent(JTree, Object, boolean, boolean, boolean, int, boolean)
     * @param tree {@inheritDoc}
     * @param value {@inheritDoc}
     * @param selected {@inheritDoc}
     * @param expanded {@inheritDoc}
     * @param leaf {@inheritDoc}
     * @param row {@inheritDoc}
     * @param hasFocus {@inheritDoc}
     * @return {@inheritDoc}
     */
    public Component getTreeCellRendererComponent (JTree tree, Object value,
            boolean selected, boolean expanded, boolean leaf, int row,
            boolean hasFocus)
    {
        Node node;

        super.getTreeCellRendererComponent (tree, value, selected, expanded, leaf, row, hasFocus);
        node = (Node)value;
        if (node instanceof TagNode)
            setText (toHtml ((TagNode)node));
        else if (node instanceof TextNode)
            setText (toText ((TextNode)node));
        else
            setText (node.toHtml ());

        return (this);
    }

}
