/*
 * Copyright 1998-2000 Sun Microsystems, Inc.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 */

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.tree.*;
import javax.swing.undo.*;
import java.awt.*;
import java.beans.*;
import java.util.*;

/**
 * Displays a tree showing all the elements in a text Document. Selecting
 * a node will result in reseting the selection of the JTextComponent.
 * This also becomes a CaretListener to know when the selection has changed
 * in the text to update the selected item in the tree.
 *
 * @author Scott Violet
 */
public class ElementTreePanel extends JPanel implements CaretListener, DocumentListener, PropertyChangeListener, TreeSelectionListener {
    /** Tree showing the documents element structure. */
    protected JTree             tree;
    /** Text component showing elemenst for. */
    protected JTextComponent    editor;
    /** Model for the tree. */
    protected ElementTreeModel  treeModel;
    /** Set to true when updatin the selection. */
    protected boolean           updatingSelection;

    public ElementTreePanel(JTextComponent editor) {
        this.editor = editor;

        Document document = editor.getDocument();

        // Create the tree.
        treeModel = new ElementTreeModel(document);
        tree = new JTree(treeModel) {
            public String convertValueToText(Object value, boolean selected,
                                             boolean expanded, boolean leaf,
                                             int row, boolean hasFocus) {
                // Should only happen for the root
                if(!(value instanceof Element))
                    return value.toString();

                Element        e = (Element)value;
                AttributeSet   as = e.getAttributes().copyAttributes();
                String         asString;

                if(as != null) {
                    StringBuffer       retBuffer = new StringBuffer("[");
                    Enumeration        names = as.getAttributeNames();

                    while(names.hasMoreElements()) {
                        Object        nextName = names.nextElement();

                        if(nextName != StyleConstants.ResolveAttribute) {
                            retBuffer.append(" ");
                            retBuffer.append(nextName);
                            retBuffer.append("=");
                            retBuffer.append(as.getAttribute(nextName));
                        }
                    }
                    retBuffer.append(" ]");
                    asString = retBuffer.toString();
                }
                else
                    asString = "[ ]";

                if(e.isLeaf())
                    return e.getName() + " [" + e.getStartOffset() +
                        ", " + e.getEndOffset() +"] Attributes: " + asString;
                return e.getName() + " [" + e.getStartOffset() +
                    ", " + e.getEndOffset() + "] Attributes: " +
                        asString;
            }
        };
        tree.addTreeSelectionListener(this);
        tree.setDragEnabled(true);
        // Don't show the root, it is fake.
        tree.setRootVisible(false);
        // Since the display value of every node after the insertion point
        // changes every time the text changes and we don't generate a change
        // event for all those nodes the display value can become off.
        // This can be seen as '...' instead of the complete string value.
        // This is a temporary workaround, increase the needed size by 15,
        // hoping that will be enough.
        tree.setCellRenderer(new DefaultTreeCellRenderer() {
            public Dimension getPreferredSize() {
                Dimension retValue = super.getPreferredSize();
                if(retValue != null)
                    retValue.width += 15;
                return retValue;
            }
        });
        // become a listener on the document to update the tree.
        document.addDocumentListener(this);

        // become a PropertyChangeListener to know when the Document has
        // changed.
        editor.addPropertyChangeListener(this);

        // Become a CaretListener
        editor.addCaretListener(this);

        // configure the panel and frame containing it.
        setLayout(new BorderLayout());
        add(new JScrollPane(tree), BorderLayout.CENTER);

        // Add a label above tree to describe what is being shown
        JLabel     label = new JLabel("Elements that make up the current document", SwingConstants.CENTER);

        label.setFont(new Font("Dialog", Font.BOLD, 14));
        add(label, BorderLayout.NORTH);

        setPreferredSize(new Dimension(400, 400));
    }

    /**
     * Resets the JTextComponent to <code>editor</code>. This will update
     * the tree accordingly.
     */
    public void setEditor(JTextComponent editor) {
        if (this.editor == editor) {
            return;
        }

        if (this.editor != null) {
            Document      oldDoc = this.editor.getDocument();

            oldDoc.removeDocumentListener(this);
            this.editor.removePropertyChangeListener(this);
            this.editor.removeCaretListener(this);
        }
        this.editor = editor;
        if (editor == null) {
            treeModel = null;
            tree.setModel(null);
        }
        else {
            Document   newDoc = editor.getDocument();

            newDoc.addDocumentListener(this);
            editor.addPropertyChangeListener(this);
            editor.addCaretListener(this);
            treeModel = new ElementTreeModel(newDoc);
            tree.setModel(treeModel);
        }
    }

    // PropertyChangeListener

    /**
     * Invoked when a property changes. We are only interested in when the
     * Document changes to reset the DocumentListener.
     */
    public void propertyChange(PropertyChangeEvent e) {
        if (e.getSource() == getEditor() &&
            e.getPropertyName().equals("document")) {
            JTextComponent      editor = getEditor();
            Document            oldDoc = (Document)e.getOldValue();
            Document            newDoc = (Document)e.getNewValue();

            // Reset the DocumentListener
            oldDoc.removeDocumentListener(this);
            newDoc.addDocumentListener(this);

            // Recreate the TreeModel.
            treeModel = new ElementTreeModel(newDoc);
            tree.setModel(treeModel);
        }
    }


    // DocumentListener

    /**
     * Gives notification that there was an insert into the document.  The
     * given range bounds the freshly inserted region.
     *
     * @param e the document event
     */
    public void insertUpdate(DocumentEvent e) {
        updateTree(e);
    }

    /**
     * Gives notification that a portion of the document has been
     * removed.  The range is given in terms of what the view last
     * saw (that is, before updating sticky positions).
     *
     * @param e the document event
     */
    public void removeUpdate(DocumentEvent e) {
        updateTree(e);
    }

    /**
     * Gives notification that an attribute or set of attributes changed.
     *
     * @param e the document event
     */
    public void changedUpdate(DocumentEvent e) {
        updateTree(e);
    }

    // CaretListener

    /**
     * Messaged when the selection in the editor has changed. Will update
     * the selection in the tree.
     */
    public void caretUpdate(CaretEvent e) {
        if(!updatingSelection) {
            JTextComponent     editor = getEditor();
            int                selBegin = Math.min(e.getDot(), e.getMark());
            int                end = Math.max(e.getDot(), e.getMark());
            Vector             paths = new Vector();
            TreeModel          model = getTreeModel();
            Object             root = model.getRoot();
            int                rootCount = model.getChildCount(root);

            // Build an array of all the paths to all the character elements
            // in the selection.
            for(int counter = 0; counter < rootCount; counter++) {
                int            start = selBegin;

                while(start <= end) {
                    TreePath    path = getPathForIndex(start, root,
                                       (Element)model.getChild(root, counter));
                    Element     charElement = (Element)path.
                                               getLastPathComponent();

                    paths.addElement(path);
                    if(start >= charElement.getEndOffset())
                        start++;
                    else
                        start = charElement.getEndOffset();
                }
            }

            // If a path was found, select it (them).
            int               numPaths = paths.size();

            if(numPaths > 0) {
                TreePath[]    pathArray = new TreePath[numPaths];

                paths.copyInto(pathArray);
                updatingSelection = true;
                try {
                    getTree().setSelectionPaths(pathArray);
                    getTree().scrollPathToVisible(pathArray[0]);
                }
                finally {
                    updatingSelection = false;
                }
            }
        }
    }

    // TreeSelectionListener

    /**
      * Called whenever the value of the selection changes.
      * @param e the event that characterizes the change.
      */
    public void valueChanged(TreeSelectionEvent e) {
        JTree       tree = getTree();

        if(!updatingSelection && tree.getSelectionCount() == 1) {
            TreePath      selPath = tree.getSelectionPath();
            Object        lastPathComponent = selPath.getLastPathComponent();

            if(!(lastPathComponent instanceof DefaultMutableTreeNode)) {
                Element       selElement = (Element)lastPathComponent;

                updatingSelection = true;
                try {
                    getEditor().select(selElement.getStartOffset(),
                                       selElement.getEndOffset());
                }
                finally {
                    updatingSelection = false;
                }
            }
        }
    }

    // Local methods

    /**
     * @return tree showing elements.
     */
    protected JTree getTree() {
        return tree;
    }

    /**
     * @return JTextComponent showing elements for.
     */
    protected JTextComponent getEditor() {
        return editor;
    }

    /**
     * @return TreeModel implementation used to represent the elements.
     */
    public DefaultTreeModel getTreeModel() {
        return treeModel;
    }

    /**
     * Updates the tree based on the event type. This will invoke either
     * updateTree with the root element, or handleChange.
     */
    protected void updateTree(DocumentEvent event) {
        updatingSelection = true;
        try {
            TreeModel        model = getTreeModel();
            Object           root = model.getRoot();

            for(int counter = model.getChildCount(root) - 1; counter >= 0;
                counter--) {
                updateTree(event, (Element)model.getChild(root, counter));
            }
        }
        finally {
            updatingSelection = false;
        }
    }

    /**
     * Creates TreeModelEvents based on the DocumentEvent and messages
     * the treemodel. This recursively invokes this method with children
     * elements.
     * @param event indicates what elements in the tree hierarchy have
     * changed.
     * @param element Current element to check for changes against.
     */
    protected void updateTree(DocumentEvent event, Element element) {
        DocumentEvent.ElementChange ec = event.getChange(element);

        if (ec != null) {
            Element[]       removed = ec.getChildrenRemoved();
            Element[]       added = ec.getChildrenAdded();
            int             startIndex = ec.getIndex();

            // Check for removed.
            if(removed != null && removed.length > 0) {
                int[]            indices = new int[removed.length];

                for(int counter = 0; counter < removed.length; counter++) {
                    indices[counter] = startIndex + counter;
                }
                getTreeModel().nodesWereRemoved((TreeNode)element, indices,
                                                removed);
            }
            // check for added
            if(added != null && added.length > 0) {
                int[]            indices = new int[added.length];

                for(int counter = 0; counter < added.length; counter++) {
                    indices[counter] = startIndex + counter;
                }
                getTreeModel().nodesWereInserted((TreeNode)element, indices);
            }
        }
        if(!element.isLeaf()) {
            int        startIndex = element.getElementIndex
                                       (event.getOffset());
            int        elementCount = element.getElementCount();
            int        endIndex = Math.min(elementCount - 1,
                                           element.getElementIndex
                                     (event.getOffset() + event.getLength()));

            if(startIndex > 0 && startIndex < elementCount &&
               element.getElement(startIndex).getStartOffset() ==
               event.getOffset()) {
                // Force checking the previous element.
                startIndex--;
            }
            if(startIndex != -1 && endIndex != -1) {
                for(int counter = startIndex; counter <= endIndex; counter++) {
                    updateTree(event, element.getElement(counter));
                }
            }
        }
        else {
            // Element is a leaf, assume it changed
            getTreeModel().nodeChanged((TreeNode)element);
        }
    }

    /**
     * Returns a TreePath to the element at <code>position</code>.
     */
    protected TreePath getPathForIndex(int position, Object root,
                                       Element rootElement) {
        TreePath         path = new TreePath(root);
        Element          child = rootElement.getElement
                                    (rootElement.getElementIndex(position));

        path = path.pathByAddingChild(rootElement);
        path = path.pathByAddingChild(child);
        while(!child.isLeaf()) {
            child = child.getElement(child.getElementIndex(position));
            path = path.pathByAddingChild(child);
        }
        return path;
    }


    /**
     * ElementTreeModel is an implementation of TreeModel to handle displaying
     * the Elements from a Document. AbstractDocument.AbstractElement is
     * the default implementation used by the swing text package to implement
     * Element, and it implements TreeNode. This makes it trivial to create
     * a DefaultTreeModel rooted at a particular Element from the Document.
     * Unfortunately each Document can have more than one root Element.
     * Implying that to display all the root elements as a child of another
     * root a fake node has be created. This class creates a fake node as
     * the root with the children being the root elements of the Document
     * (getRootElements).
     * <p>This subclasses DefaultTreeModel. The majority of the TreeModel
     * methods have been subclassed, primarily to special case the root.
     */
    public static class ElementTreeModel extends DefaultTreeModel {
        protected Element[]         rootElements;

        public ElementTreeModel(Document document) {
            super(new DefaultMutableTreeNode("root"), false);
            rootElements = document.getRootElements();
        }

        /**
         * Returns the child of <I>parent</I> at index <I>index</I> in
         * the parent's child array.  <I>parent</I> must be a node
         * previously obtained from this data source. This should
         * not return null if <i>index</i> is a valid index for
         * <i>parent</i> (that is <i>index</i> >= 0 && <i>index</i>
         * < getChildCount(<i>parent</i>)).
         *
         * @param   parent  a node in the tree, obtained from this data source
         * @return  the child of <I>parent</I> at index <I>index</I>
         */
        public Object getChild(Object parent, int index) {
            if(parent == root)
                return rootElements[index];
            return super.getChild(parent, index);
        }


        /**
         * Returns the number of children of <I>parent</I>.  Returns 0
         * if the node is a leaf or if it has no children.
         * <I>parent</I> must be a node previously obtained from this
         * data source.
         *
         * @param   parent  a node in the tree, obtained from this data source
         * @return  the number of children of the node <I>parent</I>
         */
        public int getChildCount(Object parent) {
            if(parent == root)
                return rootElements.length;
            return super.getChildCount(parent);
        }


        /**
         * Returns true if <I>node</I> is a leaf.  It is possible for
         * this method to return false even if <I>node</I> has no
         * children.  A directory in a filesystem, for example, may
         * contain no files; the node representing the directory is
         * not a leaf, but it also has no children.
         *
         * @param   node    a node in the tree, obtained from this data source
         * @return  true if <I>node</I> is a leaf
         */
        public boolean isLeaf(Object node) {
            if(node == root)
                return false;
            return super.isLeaf(node);
        }

        /**
         * Returns the index of child in parent.
         */
        public int getIndexOfChild(Object parent, Object child) {
            if(parent == root) {
                for(int counter = rootElements.length - 1; counter >= 0;
                    counter--) {
                    if(rootElements[counter] == child)
                        return counter;
                }
                return -1;
            }
            return super.getIndexOfChild(parent, child);
        }

        /**
         * Invoke this method after you've changed how node is to be
         * represented in the tree.
         */
        public void nodeChanged(TreeNode node) {
            if(listenerList != null && node != null) {
                TreeNode         parent = node.getParent();

                if(parent == null && node != root) {
                    parent = root;
                }
                if(parent != null) {
                    int        anIndex = getIndexOfChild(parent, node);

                    if(anIndex != -1) {
                        int[]        cIndexs = new int[1];

                        cIndexs[0] = anIndex;
                        nodesChanged(parent, cIndexs);
                    }
                }
            }
        }

        /**
         * Returns the path to a particluar node. This is recursive.
         */
        protected TreeNode[] getPathToRoot(TreeNode aNode, int depth) {
            TreeNode[]              retNodes;

            /* Check for null, in case someone passed in a null node, or
               they passed in an element that isn't rooted at root. */
            if(aNode == null) {
                if(depth == 0)
                    return null;
                else
                    retNodes = new TreeNode[depth];
            }
            else {
                depth++;
                if(aNode == root)
                    retNodes = new TreeNode[depth];
                else {
                    TreeNode parent = aNode.getParent();

                    if(parent == null)
                        parent = root;
                    retNodes = getPathToRoot(parent, depth);
                }
                retNodes[retNodes.length - depth] = aNode;
            }
            return retNodes;
        }
    }
}
