/*

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 */
package org.apache.batik.apps.svgbrowser;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import org.apache.batik.anim.dom.SVGOMDocument;
import org.apache.batik.anim.dom.XBLOMContentElement;
import org.apache.batik.apps.svgbrowser.DOMDocumentTree.DOMDocumentTreeAdapter;
import org.apache.batik.apps.svgbrowser.DOMDocumentTree.DOMDocumentTreeEvent;
import org.apache.batik.apps.svgbrowser.DOMDocumentTree.DropCompletedInfo;
import org.apache.batik.apps.svgbrowser.DropDownHistoryModel.RedoPopUpMenuModel;
import org.apache.batik.apps.svgbrowser.DropDownHistoryModel.UndoPopUpMenuModel;
import org.apache.batik.apps.svgbrowser.HistoryBrowser.DocumentCommandController;
import org.apache.batik.apps.svgbrowser.NodePickerPanel.NameEditorDialog;
import org.apache.batik.apps.svgbrowser.NodePickerPanel.NodePickerAdapter;
import org.apache.batik.apps.svgbrowser.NodePickerPanel.NodePickerEvent;
import org.apache.batik.apps.svgbrowser.NodeTemplates.NodeTemplateDescriptor;
import org.apache.batik.bridge.svg12.ContentManager;
import org.apache.batik.bridge.svg12.DefaultXBLManager;
import org.apache.batik.dom.AbstractDocument;
import org.apache.batik.dom.util.DOMUtilities;
import org.apache.batik.dom.util.SAXDocumentFactory;
import org.apache.batik.dom.xbl.NodeXBL;
import org.apache.batik.dom.xbl.XBLManager;
import org.apache.batik.util.SVGConstants;
import org.apache.batik.util.XMLResourceDescriptor;
import org.apache.batik.util.gui.DropDownComponent;
import org.apache.batik.util.gui.resource.ActionMap;
import org.apache.batik.util.gui.resource.ButtonFactory;
import org.apache.batik.util.gui.resource.MissingListenerException;
import org.apache.batik.util.resources.ResourceManager;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.css.CSSStyleDeclaration;
import org.w3c.dom.css.ViewCSS;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.events.MutationEvent;

/**
 * The components of this class are used to view a DOM tree.
 *
 * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
 * @version $Id$
 */
public class DOMViewer extends JFrame implements ActionMap {

    /**
     * The resource file name
     */
    protected static final String RESOURCE =
        "org.apache.batik.apps.svgbrowser.resources.DOMViewerMessages";

    /**
     * The resource bundle
     */
    protected static ResourceBundle bundle;

    /**
     * The resource manager
     */
    protected static ResourceManager resources;

    static {
        bundle = ResourceBundle.getBundle(RESOURCE, Locale.getDefault());
        resources = new ResourceManager(bundle);
    }

    /**
     * The map that contains the listeners
     */
    protected Map listeners = new HashMap();

    /**
     * The button factory.
     */
    protected ButtonFactory buttonFactory;

    /**
     * The panel.
     */
    protected Panel panel;

    /**
     * Whether to show text nodes that contain only whitespace in the tree.
     */
    protected boolean showWhitespace = true;

    /**
     * Whether "capturing click" tool is enabled. If enabled, the element being
     * clicked on is found and selected in the DOMViewer's document tree
     */
    protected boolean isCapturingClickEnabled;

    /**
     * The DOMViewer controller.
     */
    protected DOMViewerController domViewerController;

    /**
     * Manages the element selection on the canvas.
     */
    protected ElementOverlayManager elementOverlayManager;

    /**
     * Whether painting the overlay on the canvas is enabled.
     */
    protected boolean isElementOverlayEnabled;

    /**
     * The history browsing manager. Manages undo / redo.
     */
    protected HistoryBrowserInterface historyBrowserInterface;

    /**
     * Whether the DOMViewer can be used for editing the document.
     */
    protected boolean canEdit = true;

    /**
     * The button for enabling and disabling the overlay.
     */
    protected JToggleButton overlayButton;

    /**
     * Creates a new DOMViewer panel.
     */
    public DOMViewer(DOMViewerController controller) {
        super(resources.getString("Frame.title"));
        setSize(resources.getInteger("Frame.width"),
                resources.getInteger("Frame.height"));

        domViewerController = controller;

        elementOverlayManager = domViewerController.createSelectionManager();
        if (elementOverlayManager != null) {
            elementOverlayManager
                    .setController(new DOMViewerElementOverlayController());
        }
        historyBrowserInterface =
            new HistoryBrowserInterface
                (new DocumentCommandController(controller));

        listeners.put("CloseButtonAction", new CloseButtonAction());
        listeners.put("UndoButtonAction", new UndoButtonAction());
        listeners.put("RedoButtonAction", new RedoButtonAction());
        listeners.put("CapturingClickButtonAction",
                      new CapturingClickButtonAction());
        listeners.put("OverlayButtonAction", new OverlayButtonAction());

        // Create the main panel
        panel = new Panel();
        getContentPane().add(panel);

        JPanel p = new JPanel(new BorderLayout());
        JCheckBox cb =
            new JCheckBox(resources.getString("ShowWhitespaceCheckbox.text"));
        cb.setSelected(showWhitespace);
        cb.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent ie) {
                setShowWhitespace(ie.getStateChange() == ItemEvent.SELECTED);
            }
        });
        p.add(cb, BorderLayout.WEST);
        p.add(getButtonFactory().createJButton("CloseButton"),
              BorderLayout.EAST);
        getContentPane().add(p, BorderLayout.SOUTH);

        // Set the document
        Document document = domViewerController.getDocument();
        if (document != null) {
//            panel
//                    .setDocument(document, (ViewCSS) document
//                            .getDocumentElement());
            panel.setDocument(document, null);
        }
    }

    /**
     * Sets whether to show text nodes that contain only whitespace in the tree.
     */
    public void setShowWhitespace(boolean state) {
        showWhitespace = state;
        if (panel.document != null)
            panel.setDocument(panel.document);
    }

    /**
     * Sets the document to display.
     */
    public void setDocument(Document doc) {
        panel.setDocument(doc);
    }

    /**
     * Sets the document to display and its ViewCSS.
     */
    public void setDocument(Document doc, ViewCSS view) {
        panel.setDocument(doc, view);
    }

    /**
     * Whether the document can be edited using the DOMViewer.
     *
     * @return True if the document can be edited throught the DOMViewer
     */
    public boolean canEdit() {
        return domViewerController.canEdit() && canEdit;
    }

    /**
     * Enables / disables the DOMViewer to be used to edit the documents.
     *
     * @param canEdit
     *            True - The DOMViewer can be used to edit the documents
     */
    public void setEditable(boolean canEdit) {
        this.canEdit = canEdit;
    }

    /**
     * Selects and scrolls to the given node in the document tree.
     *
     * @param node
     *            The node to be selected
     */
    public void selectNode(Node node) {
        panel.selectNode(node);
    }

    /**
     * Resets the history.
     */
    public void resetHistory() {
        historyBrowserInterface.getHistoryBrowser().resetHistory();
    }

    /**
     * Gets buttonFactory.
     */
    private ButtonFactory getButtonFactory() {
        if (buttonFactory == null) {
            buttonFactory = new ButtonFactory(bundle, this);
        }
        return buttonFactory;
    }

    // ActionMap

    /**
     * Returns the action associated with the given string or null on error
     *
     * @param key
     *            the key mapped with the action to get
     * @throws MissingListenerException
     *             if the action is not found
     */
    public Action getAction(String key) throws MissingListenerException {
        return (Action)listeners.get(key);
    }

    /**
     * Groups the document changes that were made out of the document into a
     * single change and adds this change to the history browser.
     */
    private void addChangesToHistory() {
        historyBrowserInterface.performCurrentCompoundCommand();
    }

    /**
     * The action associated with the 'Close' button of the viewer panel
     */
    protected class CloseButtonAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            if (panel.attributePanel.panelHiding()) {
                panel.tree.setSelectionRow(0);
                DOMViewer.this.dispose();
            }
        }
    }

    /**
     * The action associated with the 'Undo' dropdown button of the viewer panel
     */
    protected class UndoButtonAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            addChangesToHistory();
            historyBrowserInterface.getHistoryBrowser().undo();
        }
    }

    /**
     * The action associated with the 'Redo' dropdown button of the viewer panel
     */
    protected class RedoButtonAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            addChangesToHistory();
            historyBrowserInterface.getHistoryBrowser().redo();
        }
    }

    /**
     * The action associated with the 'Capturing-click' toggle button of the
     * viewer panel.
     */
    protected class CapturingClickButtonAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            JToggleButton btn = (JToggleButton) e.getSource();
            isCapturingClickEnabled = btn.isSelected();
            if (!isCapturingClickEnabled) {
                btn.setToolTipText
                    (resources.getString("CapturingClickButton.tooltip"));
            } else {
                btn.setToolTipText
                    (resources.getString("CapturingClickButton.disableText"));
            }
        }
    }

    /**
     * Toggles the element highlighting overlay.
     */
    protected void toggleOverlay() {
        isElementOverlayEnabled = overlayButton.isSelected();
        if (!isElementOverlayEnabled) {
            overlayButton.setToolTipText
                (resources.getString("OverlayButton.tooltip"));
        } else {
            overlayButton.setToolTipText
                (resources.getString("OverlayButton.disableText"));
        }
        // Refresh overlay
        if (elementOverlayManager != null) {
            elementOverlayManager.setOverlayEnabled(isElementOverlayEnabled);
            elementOverlayManager.repaint();
        }
    }

    /**
     * The action associated with the 'overlay' toggle button of the viewer
     * panel.
     */
    protected class OverlayButtonAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            toggleOverlay();
        }
    }

    /**
     * NodePickerController implementation.
     */
    protected class DOMViewerNodePickerController
            implements NodePickerController {

        public boolean isEditable() {
            return DOMViewer.this.canEdit();
        }

        public boolean canEdit(Element el) {
//            if (panel == null || panel.document == null || true
//                    /*|| panel.document.getDocumentElement() != el*/) {
                return true;
//            }
//            return false;
        }
    }

    /**
     * DOMDocumentTreeController implementation.
     */
    protected class DOMViewerDOMDocumentTreeController
            implements DOMDocumentTreeController {

        public boolean isDNDSupported() {
            return canEdit();
        }
    }

    /**
     * ElementOverlayController implementation.
     */
    protected class DOMViewerElementOverlayController
            implements ElementOverlayController {

        public boolean isOverlayEnabled() {
            return canEdit() && isElementOverlayEnabled;
        }
    }

    /**
     * The panel that contains the viewer.
     */
    public class Panel extends JPanel {

        // DOM Mutation event names.
        public static final String NODE_INSERTED = "DOMNodeInserted";
        public static final String NODE_REMOVED = "DOMNodeRemoved";
        public static final String ATTRIBUTE_MODIFIED = "DOMAttrModified";
        public static final String CHAR_DATA_MODIFIED = "DOMCharacterDataModified";

        /**
         * The DOM document.
         */
        protected Document document;

        /**
         * "Node inserted" DOM Mutation Listener.
         */
        protected EventListener nodeInsertion;

        /**
         * "Node removed" DOM Mutation Listener.
         */
        protected EventListener nodeRemoval;

        /**
         * "Attribute modified" DOM Mutation Listener.
         */
        protected EventListener attrModification;

        /**
         * "Character data modified" DOM Mutation Listener.
         */
        protected EventListener charDataModification;

        /**
         * Capturing "click" event type listener. Allows the "capturing click"
         * option
         */
        protected EventListener capturingListener;

        /**
         * The ViewCSS object associated with the document.
         */
        protected ViewCSS viewCSS;

        /**
         * The tree.
         */
        protected DOMDocumentTree tree;

        /**
         * The split pane.
         */
        protected JSplitPane splitPane;

        /**
         * The right panel.
         */
        protected JPanel rightPanel = new JPanel(new BorderLayout());

        /**
         * The properties table.
         */
        protected JTable propertiesTable = new JTable();

        /**
         * The panel to show the nodes attributes.
         */
        protected NodePickerPanel attributePanel =
            new NodePickerPanel(new DOMViewerNodePickerController());
        {
            attributePanel.addListener(new NodePickerAdapter() {

                public void updateElement(NodePickerEvent event) {
                    String result = event.getResult();
                    Element targetElement = (Element) event.getContextNode();
                    Element newElem = wrapAndParse(result, targetElement);

                    addChangesToHistory();

                    AbstractCompoundCommand cmd = historyBrowserInterface
                            .createNodeChangedCommand(newElem);
                    Node parent = targetElement.getParentNode();
                    Node nextSibling = targetElement.getNextSibling();
                    cmd.addCommand(historyBrowserInterface
                            .createRemoveChildCommand(parent, targetElement));
                    cmd.addCommand(historyBrowserInterface
                            .createInsertChildCommand(parent, nextSibling,
                                    newElem));
                    historyBrowserInterface.performCompoundUpdateCommand(cmd);

                    attributePanel.setPreviewElement(newElem);
                    //selectNewNode(newElem);
                }

                public void addNewElement(NodePickerEvent event) {
                    String result = event.getResult();
                    Element targetElement = (Element) event.getContextNode();
                    Element newElem = wrapAndParse(result, targetElement);

                    addChangesToHistory();

                    historyBrowserInterface.appendChild(targetElement,
                            newElem);

                    attributePanel.setPreviewElement(newElem);
                    //selectNewNode(newElem);
                }

                /**
                 * Parses the given string into an element after editing, or
                 * adding new element. The element that should be parsed has to
                 * have all the active prefixes set, so it has to be wrapped
                 * with the wrapper element that has all the mentioned prefixes
                 * bound to the appopriate namespaces. Wrapper element string
                 * has all the active prefixes set using the parentNode.
                 *
                 * @param toParse
                 *            The string that should be parsed into svg element
                 * @param startingNode
                 *            The node from where to start looking the prefixes
                 * @return The parsed element
                 */
                private Element wrapAndParse(String toParse, Node startingNode) {
                    // Fill the prefix map
                    Map prefixMap = new HashMap();
                    int j = 0;
                    for (Node currentNode = startingNode;
                         currentNode != null;
                         currentNode = currentNode.getParentNode()) {
                        NamedNodeMap nMap = currentNode.getAttributes();
                        for (int i = 0; nMap != null && i < nMap.getLength(); i++) {
                            Attr atr = (Attr) nMap.item(i);
                            String prefix = atr.getPrefix();
                            String localName = atr.getLocalName();
                            String namespaceURI = atr.getValue();
                            if (prefix != null
                                    && prefix.equals(SVGConstants.XMLNS_PREFIX)) {
                                String attrName = SVGConstants.XMLNS_PREFIX
                                        + ":" + localName;
                                if (!prefixMap.containsKey(attrName)) {
                                    prefixMap.put(attrName, namespaceURI);
                                }
                            }
                            // Start from parentNode searching for the xmlns
                            if ((j != 0 || currentNode == document
                                    .getDocumentElement())
                                    && atr.getNodeName().equals(
                                            SVGConstants.XMLNS_PREFIX)
                                    && !prefixMap
                                            .containsKey(SVGConstants.XMLNS_PREFIX)) {
                                prefixMap.put(SVGConstants.XMLNS_PREFIX, atr
                                        .getNodeValue());
                            }
                        }
                        j++;
                    }
                    Document doc = panel.document;
                    SAXDocumentFactory df = new SAXDocumentFactory(
                            doc.getImplementation(),
                            XMLResourceDescriptor.getXMLParserClassName());
                    URL urlObj = null;
                    if (doc instanceof SVGOMDocument) {
                        urlObj = ((SVGOMDocument) doc).getURLObject();
                    }
                    String uri = (urlObj == null) ? "" : urlObj.toString();
                    Node node = DOMUtilities.parseXML(toParse, doc, uri,
                            prefixMap, SVGConstants.SVG_SVG_TAG, df);
                    return (Element) node.getFirstChild();
                }

                /**
                 * Selects the given element. Needs to be wrapped with the
                 * UpdateManager to wait for the previous command to be executed
                 * by HistoryBrowser
                 *
                 * @param elem
                 *            The element to select
                 */
                private void selectNewNode(final Element elem) {
                    domViewerController.performUpdate(new Runnable() {
                        public void run() {
                            selectNode(elem);
                        }
                    });
                }
            });
        }

        /**
         * The layout for the attribute panel.
         */
        protected GridBagConstraints attributePanelLayout =
            new GridBagConstraints();
        {
            attributePanelLayout.gridx = 1;
            attributePanelLayout.gridy = 1;
            attributePanelLayout.gridheight = 2;
            attributePanelLayout.weightx = 1.0;
            attributePanelLayout.weighty = 1.0;
            attributePanelLayout.fill = GridBagConstraints.BOTH;
        }

        /**
         * The layout for the properties table.
         */
        protected GridBagConstraints propertiesTableLayout =
            new GridBagConstraints();
        {
            propertiesTableLayout.gridx = 1;
            propertiesTableLayout.gridy = 3;
            propertiesTableLayout.weightx = 1.0;
            propertiesTableLayout.weighty = 1.0;
            propertiesTableLayout.fill = GridBagConstraints.BOTH;
        }

        /**
         * The element panel.
         */
        protected JPanel elementPanel = new JPanel(new GridBagLayout());
        {
            JScrollPane pane2 = new JScrollPane();
            pane2.setBorder(BorderFactory.createCompoundBorder(BorderFactory
                    .createEmptyBorder(2, 0, 2, 2), BorderFactory
                    .createCompoundBorder(BorderFactory.createTitledBorder(
                            BorderFactory.createEmptyBorder(), resources
                                    .getString("CSSValuesPanel.title")),
                            BorderFactory.createLoweredBevelBorder())));
            pane2.getViewport().add(propertiesTable);

            // 2/3 attributePanel, 1/3 propertiesTable
            elementPanel.add(attributePanel, attributePanelLayout);
            elementPanel.add(pane2, propertiesTableLayout);
        }

        /**
         * The CharacterData panel text area.
         */
        protected class CharacterPanel extends JPanel {

            /**
             * Associated node.
             */
            protected Node node;

            /**
             * The text area.
             */
            protected JTextArea textArea = new JTextArea();

            /**
             * Constructor.
             * @param layout    The LayoutManager
             */
            public CharacterPanel(BorderLayout layout) {
                super(layout);
            }

            /**
             * Gets the textArea.
             *
             * @return textArea
             */
            public JTextArea getTextArea() {
                return textArea;
            }

            /**
             * Sets the textArea.
             *
             * @param textArea
             *            the text area to set
             */
            public void setTextArea(JTextArea textArea) {
                this.textArea = textArea;
            }

            /**
             * Gets the node.
             *
             * @return node
             */
            public Node getNode() {
                return node;
            }

            /**
             * Sets the node.
             *
             * @param node
             *            the node to set
             */
            public void setNode(Node node) {
                this.node = node;
            }
        }

        /**
         * The CharacterData node panel.
         */
        protected CharacterPanel characterDataPanel = new CharacterPanel(new BorderLayout());
        {
            characterDataPanel.setBorder
                (BorderFactory.createCompoundBorder
                 (BorderFactory.createEmptyBorder(2, 0, 2, 2),
                  BorderFactory.createCompoundBorder
                  (BorderFactory.createTitledBorder
                   (BorderFactory.createEmptyBorder(),
                    resources.getString("CDataPanel.title")),
                   BorderFactory.createLoweredBevelBorder())));
            JScrollPane pane = new JScrollPane();
            JTextArea textArea = new JTextArea();
            characterDataPanel.setTextArea(textArea);
            pane.getViewport().add(textArea);
            characterDataPanel.add(pane);

            textArea.setEditable(true);
            textArea.addFocusListener(new FocusAdapter() {
                public void focusLost(FocusEvent e) {
                    if (canEdit()) {
                        Node contextNode = characterDataPanel.getNode();
                        String newValue = characterDataPanel.getTextArea()
                                .getText();
                        switch (contextNode.getNodeType()) {
                        case Node.COMMENT_NODE:
                        case Node.TEXT_NODE:
                        case Node.CDATA_SECTION_NODE:
                            addChangesToHistory();
                            historyBrowserInterface.setNodeValue(contextNode,
                                    newValue);
                            break;
                        }
                    }
                }
            });
        }

        /**
         * The documentInfo panel text area.
         */
        protected JTextArea documentInfo = new JTextArea();

        /**
         * The documentInfo node panel.
         */
        protected JPanel documentInfoPanel = new JPanel(new BorderLayout());
        {
            documentInfoPanel.setBorder
                (BorderFactory.createCompoundBorder
                 (BorderFactory.createEmptyBorder(2, 0, 2, 2),
                  BorderFactory.createCompoundBorder
                  (BorderFactory.createTitledBorder
                   (BorderFactory.createEmptyBorder(),
                    resources.getString("DocumentInfoPanel.title")),
                   BorderFactory.createLoweredBevelBorder())));
            JScrollPane pane = new JScrollPane();
            pane.getViewport().add(documentInfo);
            documentInfoPanel.add(pane);
            documentInfo.setEditable(false);
        }

        /**
         * Creates a new Panel object.
         */
        public Panel() {
            super(new BorderLayout());
            setBorder(BorderFactory.createTitledBorder
                      (BorderFactory.createEmptyBorder(),
                       resources.getString("DOMViewerPanel.title")));

            JToolBar tb =
                new JToolBar(resources.getString("DOMViewerToolbar.name"));
            tb.setFloatable(false);

            // Undo
            JButton undoButton = getButtonFactory().createJToolbarButton("UndoButton");
            undoButton.setDisabledIcon
                (new ImageIcon
                    (getClass().getResource(resources.getString("UndoButton.disabledIcon"))));
            DropDownComponent undoDD = new DropDownComponent(undoButton);
            undoDD.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2));
            undoDD.setMaximumSize(new Dimension(44, 25));
            undoDD.setPreferredSize(new Dimension(44, 25));
            tb.add(undoDD);
            UndoPopUpMenuModel undoModel = new UndoPopUpMenuModel(undoDD
                    .getPopupMenu(), historyBrowserInterface);
            undoDD.getPopupMenu().setModel(undoModel);

            // Redo
            JButton redoButton = getButtonFactory().createJToolbarButton("RedoButton");
            redoButton.setDisabledIcon
                (new ImageIcon
                    (getClass().getResource(resources.getString("RedoButton.disabledIcon"))));
            DropDownComponent redoDD = new DropDownComponent(redoButton);
            redoDD.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2));
            redoDD.setMaximumSize(new Dimension(44, 25));
            redoDD.setPreferredSize(new Dimension(44, 25));
            tb.add(redoDD);
            RedoPopUpMenuModel redoModel = new RedoPopUpMenuModel(redoDD
                    .getPopupMenu(), historyBrowserInterface);
            redoDD.getPopupMenu().setModel(redoModel);

            // Capturing click toggle button
            JToggleButton capturingClickButton = getButtonFactory()
                    .createJToolbarToggleButton("CapturingClickButton");
            capturingClickButton.setEnabled(true);
            capturingClickButton.setPreferredSize(new Dimension(32, 25));
            tb.add(capturingClickButton);

            // Overlay toggle button
            overlayButton =
                getButtonFactory().createJToolbarToggleButton("OverlayButton");
            overlayButton.setEnabled(true);
            overlayButton.setPreferredSize(new Dimension(32, 25));
            tb.add(overlayButton);

            // Add toolbar
            add(tb, BorderLayout.NORTH);

            // DOMDocumentTree
            TreeNode root;
            root = new DefaultMutableTreeNode
                (resources.getString("EmptyDocument.text"));
            tree = new DOMDocumentTree
                (root, new DOMViewerDOMDocumentTreeController());
            tree.setCellRenderer(new NodeRenderer());
            tree.putClientProperty("JTree.lineStyle", "Angled");
            // Add the listeners to DOMDocumentTree
            tree.addListener(new DOMDocumentTreeAdapter() {

                public void dropCompleted(DOMDocumentTreeEvent event) {
                    DropCompletedInfo info = (DropCompletedInfo) event
                            .getSource();

                    addChangesToHistory();

                    AbstractCompoundCommand cmd = historyBrowserInterface
                            .createNodesDroppedCommand(info.getChildren());

                    int n = info.getChildren().size();
                    for (int i = 0; i < n; i++) {
                        Node node = (Node) info.getChildren().get(i);
                        // If the node has its ancestor in selected nodes,
                        // it should stay as it's child
                        if (!DOMUtilities.isAnyNodeAncestorOf(info
                                .getChildren(), node)) {
                            cmd.addCommand(historyBrowserInterface
                                    .createInsertChildCommand(info.getParent(),
                                            info.getSibling(), node));
                        }
                    }
                    historyBrowserInterface.performCompoundUpdateCommand(cmd);
                }
            });
            tree.addTreeSelectionListener(new DOMTreeSelectionListener());
            tree.addMouseListener(new TreePopUpListener());
            JScrollPane treePane = new JScrollPane();
            treePane.setBorder(BorderFactory.createCompoundBorder
                               (BorderFactory.createEmptyBorder(2, 2, 2, 0),
                                BorderFactory.createCompoundBorder
                                (BorderFactory.createTitledBorder
                                 (BorderFactory.createEmptyBorder(),
                                  resources.getString("DOMViewer.title")),
                                 BorderFactory.createLoweredBevelBorder())));
            treePane.getViewport().add(tree);
            splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                                       true, // Continuous layout
                                       treePane,
                                       rightPanel);
            int loc = resources.getInteger("SplitPane.dividerLocation");
            splitPane.setDividerLocation(loc);
            add(splitPane);
        }

        /**
         * Sets the document to display.
         */
        public void setDocument(Document doc) {
            setDocument(doc, null);
        }

        /**
         * Sets the document to display and its ViewCSS.
         */
        public void setDocument(Document doc, ViewCSS view) {
            if (document != null) {
                if (document != doc) {
                    removeDomMutationListeners(document);
                    addDomMutationListeners(doc);
                    removeCapturingListener(document);
                    addCapturingListener(doc);
                }
            }
            else {
                addDomMutationListeners(doc);
                addCapturingListener(doc);
            }
            resetHistory();
            document = doc;
            viewCSS = view;
            TreeNode root = createTree(doc, showWhitespace);
            ((DefaultTreeModel) tree.getModel()).setRoot(root);
            if (rightPanel.getComponentCount() != 0) {
                rightPanel.remove(0);
                splitPane.revalidate();
                splitPane.repaint();
            }
        }

        /**
         * Registers DOM Mutation Listener on the given document.
         *
         * @param doc
         *            The given document
         */
        protected void addDomMutationListeners(Document doc) {
            EventTarget target = (EventTarget) doc;
            nodeInsertion = new NodeInsertionHandler();
            target.addEventListener(NODE_INSERTED, nodeInsertion, true);
            nodeRemoval = new NodeRemovalHandler();
            target.addEventListener(NODE_REMOVED, nodeRemoval, true);
            attrModification = new AttributeModificationHandler();
            target.addEventListener(ATTRIBUTE_MODIFIED, attrModification,
                    true);
            charDataModification = new CharDataModificationHandler();
            target.addEventListener(CHAR_DATA_MODIFIED,
                    charDataModification, true);
        }

        /**
         * Removes previously registered mutation listeners from the document.
         *
         * @param doc
         *            The document
         */
        protected void removeDomMutationListeners(Document doc) {
            if (doc != null) {
                EventTarget target = (EventTarget) doc;
                target.removeEventListener(NODE_INSERTED, nodeInsertion, true);
                target.removeEventListener(NODE_REMOVED, nodeRemoval, true);
                target.removeEventListener(ATTRIBUTE_MODIFIED,
                        attrModification, true);
                target.removeEventListener(CHAR_DATA_MODIFIED,
                        charDataModification, true);
            }
        }

        /**
         * Registers capturing "click" listener on the document element of the
         * given document.
         *
         * @param doc
         *            The given document
         */
        protected void addCapturingListener(Document doc) {
            EventTarget target = (EventTarget) doc.getDocumentElement();
            capturingListener = new CapturingClickHandler();
            target.addEventListener(SVGConstants.SVG_CLICK_EVENT_TYPE,
                    capturingListener, true);
        }

        /**
         * Removes previously registered capturing "click" event listener from
         * the document element of the given document.
         *
         * @param doc
         *            The given document
         */
        protected void removeCapturingListener(Document doc) {
            if (doc != null) {
                EventTarget target = (EventTarget) doc.getDocumentElement();
                target.removeEventListener(SVGConstants.SVG_CLICK_EVENT_TYPE,
                        capturingListener, true);
            }
        }

        /**
         * Handles "DOMNodeInserted" event.
         */
        protected class NodeInsertionHandler implements EventListener {

            public void handleEvent(final Event evt) {
                Runnable runnable = new Runnable() {
                    public void run() {
                        MutationEvent mevt = (MutationEvent) evt;
                        Node targetNode = (Node) mevt.getTarget();
                        DefaultMutableTreeNode parentNode = findNode(tree,
                                targetNode.getParentNode());
                        DefaultMutableTreeNode insertedNode =
                            (DefaultMutableTreeNode)
                            createTree(targetNode, showWhitespace);
                        DefaultTreeModel model =
                            (DefaultTreeModel) tree.getModel();
                        DefaultMutableTreeNode newParentNode =
                            (DefaultMutableTreeNode)
                            createTree(targetNode.getParentNode(),
                                       showWhitespace);
                        // Finds where to insert the node in the tree
                        int index = findIndexToInsert(parentNode, newParentNode);
                        if (index != -1) {
                            model.insertNodeInto
                                (insertedNode, parentNode, index);
                        }
                        attributePanel.updateOnDocumentChange(mevt.getType(),
                                                              targetNode);
                    }
                };
                refreshGUI(runnable);
                registerDocumentChange((MutationEvent)evt);
            }

            /**
             * Compares the children of the two tree nodes and returns the index
             * of the first difference.
             *
             * @param parentNode
             *            The old tree node
             * @param newParentNode
             *            The new tree node
             * @return first child that differs
             */
            protected int findIndexToInsert
                    (DefaultMutableTreeNode parentNode,
                     DefaultMutableTreeNode newParentNode) {
                int index = -1;
                if (parentNode == null || newParentNode == null) {
                    return index;
                }
                // Finds the index where to insert new node
                Enumeration oldChildren = parentNode.children();
                Enumeration newChildren = newParentNode.children();
                int count = 0;
                while (oldChildren.hasMoreElements()) {
                    // Current DefaultMutableTreeNode node being processed
                    DefaultMutableTreeNode currentOldChild =
                        (DefaultMutableTreeNode) oldChildren.nextElement();
                    DefaultMutableTreeNode currentNewChild =
                        (DefaultMutableTreeNode) newChildren.nextElement();
                    Node oldChild =
                        ((NodeInfo) currentOldChild.getUserObject()).getNode();
                    Node newChild =
                        ((NodeInfo) currentNewChild.getUserObject()).getNode();
                    if (oldChild != newChild) {
                        return count;
                    }
                    count++;
                }
                return count;
            }
        }

        /**
         * Handles "DOMNodeRemoved" event.
         */
        protected class NodeRemovalHandler implements EventListener {

            public void handleEvent(final Event evt) {
                Runnable runnable = new Runnable() {
                    public void run() {
                        MutationEvent mevt = (MutationEvent) evt;
                        Node targetNode = (Node) mevt.getTarget();
                        DefaultMutableTreeNode treeNode = findNode(tree,
                                targetNode);
                        DefaultTreeModel model = (DefaultTreeModel) tree
                                .getModel();
                        if (treeNode != null) {
                            model.removeNodeFromParent(treeNode);
                        }
                        attributePanel.updateOnDocumentChange(mevt.getType(),
                                targetNode);
                    }
                };
                refreshGUI(runnable);
                registerDocumentChange((MutationEvent)evt);
            }
        }

        /**
         * Handles "DOMAttrModified" event.
         */
        protected class AttributeModificationHandler implements EventListener {

            public void handleEvent(final Event evt) {
                Runnable runnable = new Runnable() {
                    public void run() {
                        MutationEvent mevt = (MutationEvent) evt;
                        Element targetElement = (Element) mevt.getTarget();
                        // Repaint the target node
                        DefaultTreeModel model = (DefaultTreeModel) tree
                                .getModel();

                        model.nodeChanged(findNode(tree, targetElement));
                        attributePanel.updateOnDocumentChange(mevt.getType(),
                                targetElement);
                    }
                };
                refreshGUI(runnable);
                registerDocumentChange((MutationEvent) evt);
            }
        }

        /**
         * Handles "DOMCharacterDataModified" event.
         */
        protected class CharDataModificationHandler implements EventListener {
            public void handleEvent(final Event evt) {
                Runnable runnable = new Runnable() {
                    public void run() {
                        MutationEvent mevt = (MutationEvent) evt;
                        Node targetNode = (Node) mevt.getTarget();
                        if (characterDataPanel.getNode() == targetNode) {
                            characterDataPanel.getTextArea().setText(
                                    targetNode.getNodeValue());
                            attributePanel.updateOnDocumentChange(mevt
                                    .getType(), targetNode);
                        }
                    }
                };
                refreshGUI(runnable);
                if (characterDataPanel.getNode() == evt.getTarget()) {
                    registerDocumentChange((MutationEvent) evt);
                }
            }
        }

        /**
         * Checks whether the DOMViewer can be used to edit the document and if
         * true refreshes the DOMViewer after the DOM Mutation event occured.
         *
         * @param runnable
         *            The runnable to invoke for refresh
         */
        protected void refreshGUI(Runnable runnable) {
            if (canEdit()) {
                try {
                    SwingUtilities.invokeAndWait(runnable);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }

        /**
         * Adds the "DOMNodeInserted" Mutation event to current history
         * browser's interface compound command
         *
         * @param mevt
         *            The Mutation Event
         */
        protected void registerNodeInserted(MutationEvent mevt) {
            Node targetNode = (Node) mevt.getTarget();
            historyBrowserInterface.addToCurrentCompoundCommand
                (historyBrowserInterface.createNodeInsertedCommand
                    (targetNode.getParentNode(),
                     targetNode.getNextSibling(),
                     targetNode));
        }

        /**
         * Adds the "DOMNodeRemoved" Mutation event to current history browser's
         * interface compound command
         *
         * @param mevt
         *            The Mutation Event
         */
        protected void registerNodeRemoved(MutationEvent mevt) {
            Node targetNode = (Node) mevt.getTarget();
            historyBrowserInterface.addToCurrentCompoundCommand
                (historyBrowserInterface.createNodeRemovedCommand
                    (mevt.getRelatedNode(),
                     targetNode.getNextSibling(),
                     targetNode));
        }

        /**
         * Adds the "DOMAttrModified" Mutation event, of the
         * MutationEvent.ADDITION type to current history browser's
         * interface compound command
         *
         * @param mevt
         *            The Mutation Event
         */
        protected void registerAttributeAdded(MutationEvent mevt) {
            Element targetElement = (Element) mevt.getTarget();
            historyBrowserInterface.addToCurrentCompoundCommand
                (historyBrowserInterface.createAttributeAddedCommand
                    (targetElement,
                     mevt.getAttrName(),
                     mevt.getNewValue(),
                     null));
        }

        /**
         * Adds the "DOMAttrModified" Mutation event, of the
         * MutationEvent.REMOVAL type to current history browser's
         * interface compound command
         *
         * @param mevt
         *            The Mutation Event
         */

        protected void registerAttributeRemoved(MutationEvent mevt) {
            Element targetElement = (Element) mevt.getTarget();
            historyBrowserInterface.addToCurrentCompoundCommand
                (historyBrowserInterface.createAttributeRemovedCommand
                    (targetElement,
                     mevt.getAttrName(),
                     mevt.getPrevValue(),
                     null));
        }

        /**
         * Adds the "DOMAttrModified" Mutation event, of the
         * MutationEvent.MODIFICATION type to current history browser's
         * interface compound command
         *
         * @param mevt
         *            The Mutation Event
         */
        protected void registerAttributeModified(MutationEvent mevt) {
            Element targetElement = (Element) mevt.getTarget();
            historyBrowserInterface.addToCurrentCompoundCommand
                (historyBrowserInterface.createAttributeModifiedCommand
                    (targetElement,
                     mevt.getAttrName(),
                     mevt.getPrevValue(),
                     mevt.getNewValue(),
                     null));
        }

        /**
         * Checks what type of the "DOMAttrModified" mutation event occured, and
         * invokes the appropriate method to register the change.
         *
         * @param mevt
         *            The Mutation Event
         */
        protected void registerAttributeChanged(MutationEvent mevt) {
            switch (mevt.getAttrChange()) {
                case MutationEvent.ADDITION:
                    registerAttributeAdded(mevt);
                    break;
                case MutationEvent.REMOVAL:
                    registerAttributeRemoved(mevt);
                    break;
                case MutationEvent.MODIFICATION:
                    registerAttributeModified(mevt);
                    break;
                default:
                    registerAttributeModified(mevt);
                    break;
            }
        }

        /**
         * Adds the "DOMCharDataModified" Mutation event to current history
         * browser's interface compound command
         *
         * @param mevt
         *            The Mutation Event
         */
        protected void registerCharDataModified(MutationEvent mevt) {
            Node targetNode = (Node) mevt.getTarget();
            historyBrowserInterface.addToCurrentCompoundCommand
                (historyBrowserInterface.createCharDataModifiedCommand
                    (targetNode,
                     mevt.getPrevValue(),
                     mevt.getNewValue()));
        }

        /**
         * Checks if the document change that occured should be registered. If
         * the document change has occured out of the DOMViewer, the state of
         * the history browser should be HistoryBrowserState.IDLE. Otherwise, if
         * the DOMViewer caused the change, one of the following states is
         * active: HistoryBrowserState.EXECUTING, HistoryBrowserState.UNDOING,
         * HistoryBrowserState.REDOING. This method should be invoked while the
         * document change is occuring (in mutation event handlers), otherwise,
         * if put in another thread, the state flag becomes invalid. Also checks
         * if the DOMViewer can be used to edit the document. If not, then the
         * change shouldn't be registered by the HistoryBrowser
         *
         * @return True if the DOMViewer can edit the document and the history
         *         browser state is IDLE at the moment
         */
        protected boolean shouldRegisterDocumentChange() {
            return canEdit() &&
                historyBrowserInterface.getHistoryBrowser().getState()
                    == HistoryBrowser.IDLE;
        }

        /**
         * Puts the document change in the current history browser's interface
         * compound command if the document change occured outside of the
         * DOMViewer.
         *
         * @param mevt
         *            The info on the event. Use to describe the document change
         *            to the history browser
         */
        protected void registerDocumentChange(MutationEvent mevt) {
            if (shouldRegisterDocumentChange()) {
                String type = mevt.getType();
                if (type.equals(NODE_INSERTED)) {
                    registerNodeInserted(mevt);
                } else if (type.equals(NODE_REMOVED)) {
                    registerNodeRemoved(mevt);
                } else if (type.equals(ATTRIBUTE_MODIFIED)) {
                    registerAttributeChanged(mevt);
                } else if (type.equals(CHAR_DATA_MODIFIED)) {
                    registerCharDataModified(mevt);
                }
            }
        }

        /**
         * Handles the capturing "mouseclick" event.
         */
        protected class CapturingClickHandler implements EventListener {
            public void handleEvent(Event evt) {
                if (isCapturingClickEnabled) {
                    Element targetElement = (Element) evt.getTarget();
                    selectNode(targetElement);
                }
            }
        }

        /**
         * Creates a swing tree from a DOM document.
         */
        protected MutableTreeNode createTree(Node node,
                                             boolean showWhitespace) {
            DefaultMutableTreeNode result;
            result = new DefaultMutableTreeNode(new NodeInfo(node));
            for (Node n = node.getFirstChild();
                 n != null;
                 n = n.getNextSibling()) {
                if (!showWhitespace && (n instanceof org.w3c.dom.Text)) {
                    String txt = n.getNodeValue();
                    if (txt.trim().length() == 0)
                        continue;
                }
                result.add(createTree(n, showWhitespace));
            }
            if (node instanceof NodeXBL) {
                Element shadowTree = ((NodeXBL) node).getXblShadowTree();
                if (shadowTree != null) {
                    DefaultMutableTreeNode shadowNode
                        = new DefaultMutableTreeNode
                            (new ShadowNodeInfo(shadowTree));
                    shadowNode.add(createTree(shadowTree, showWhitespace));
                    result.add(shadowNode);
                }
            }
            if (node instanceof XBLOMContentElement) {
                AbstractDocument doc
                    = (AbstractDocument) node.getOwnerDocument();
                XBLManager xm = doc.getXBLManager();
                if (xm instanceof DefaultXBLManager) {
                    DefaultMutableTreeNode selectedContentNode
                        = new DefaultMutableTreeNode(new ContentNodeInfo(node));
                    DefaultXBLManager dxm = (DefaultXBLManager) xm;
                    ContentManager cm = dxm.getContentManager(node);
                    if (cm != null) {
                        NodeList nl
                            = cm.getSelectedContent((XBLOMContentElement) node);
                        for (int i = 0; i < nl.getLength(); i++) {
                            selectedContentNode.add(createTree(nl.item(i),
                                                               showWhitespace));
                        }
                        result.add(selectedContentNode);
                    }
                }
            }
            return result;
        }

        /**
         * Finds and returns the node in the tree that represents the given node
         * in the document.
         *
         * @param theTree
         *            The given JTree
         * @param node
         *            The given org.w3c.dom.Node
         * @return Node or null if not found
         */
        protected DefaultMutableTreeNode findNode(JTree theTree, Node node) {
            DefaultMutableTreeNode root = (DefaultMutableTreeNode) theTree
                    .getModel().getRoot();
            Enumeration treeNodes = root.breadthFirstEnumeration();
            while (treeNodes.hasMoreElements()) {
                DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode) treeNodes
                        .nextElement();
                NodeInfo userObject = (NodeInfo) currentNode.getUserObject();
                if (userObject.getNode() == node) {
                    return currentNode;
                }
            }
            return null;
        }

        /**
         * Finds and selects the given node in the document tree.
         *
         * @param targetNode
         *            The node to be selected
         */
        public void selectNode(final Node targetNode) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    DefaultMutableTreeNode node = findNode(tree, targetNode);
                    if (node != null) {
                        TreeNode[] path = node.getPath();
                        TreePath tp = new TreePath(path);
                        // Changes the selection
                        tree.setSelectionPath(tp);
                        // Expands and scrolls the TreePath to visible if
                        // needed
                        tree.scrollPathToVisible(tp);
                    }
                }
            });
        }

        /**
         * Tree popup listener.
         */
        protected class TreePopUpListener extends MouseAdapter {

            /**
             * The actual pop-up menu.
             */
            protected JPopupMenu treePopupMenu;

            /**
             * Creates new pop up listener.
             */
            public TreePopUpListener() {
                treePopupMenu = new JPopupMenu();

                // "Insert new node" menu
                treePopupMenu.add(createTemplatesMenu(resources
                        .getString("ContextMenuItem.insertNewNode")));

                // "Create new element..." item
                JMenuItem item = new JMenuItem(resources
                        .getString("ContextMenuItem.createNewElement"));
                treePopupMenu.add(item);
                item.addActionListener(new TreeNodeAdder());

                // "Remove selection" item
                item = new JMenuItem(resources
                        .getString("ContextMenuItem.removeSelection"));
                item.addActionListener(new TreeNodeRemover());
                treePopupMenu.add(item);
            }

            public void mouseReleased(MouseEvent e) {
                // Show the pop-up component
                if (e.isPopupTrigger() && e.getClickCount() == 1) {
                    if (tree.getSelectionPaths() != null) {
                        showPopUp(e);
                    }
                }
            }

            // Handles selection on the tree
            public void mousePressed(MouseEvent e) {
                JTree sourceTree = (JTree) e.getSource();
                TreePath targetPath = sourceTree.getPathForLocation(e.getX(), e
                        .getY());
                if (!e.isControlDown() && !e.isShiftDown()) {
                    sourceTree.setSelectionPath(targetPath);
                } else {
                    sourceTree.addSelectionPath(targetPath);
                }
                // Show the pop-up component
                if (e.isPopupTrigger() && e.getClickCount() == 1) {
                    showPopUp(e);
                }
            }

            /**
             * Shows this popup menu if the DOMViewer can be used to edti the
             * document.
             */
            private void showPopUp(MouseEvent e) {
                if (canEdit()) {
                    TreePath path = tree.getPathForLocation(e.getX(), e.getY());
                    // Don't show the pop up menu for the root element
                    if (path != null && path.getPathCount() > 1) {
                        treePopupMenu.show((Component) e.getSource(), e.getX(),
                                e.getY());
                    }
                }
            }
        }

        /**
         * Handles tree pop-up menu action for adding new node.
         */
        protected class TreeNodeAdder implements ActionListener {

            public void actionPerformed(ActionEvent e) {
                // Prompt for the node name
                NameEditorDialog nameEditorDialog = new NameEditorDialog(
                        DOMViewer.this);
                nameEditorDialog.setLocationRelativeTo(DOMViewer.this);
                int results = nameEditorDialog.showDialog();
                if (results == NameEditorDialog.OK_OPTION) {
                    Element elementToAdd = document.createElementNS(
                            SVGConstants.SVG_NAMESPACE_URI, nameEditorDialog
                                    .getResults());
                    if (rightPanel.getComponentCount() != 0) {
                        rightPanel.remove(0);
                    }
                    rightPanel.add(elementPanel);

                    // Pass the parent node as the selected one
                    TreePath[] treePaths = tree.getSelectionPaths();
                    if (treePaths != null) {
                        TreePath treePath = treePaths[treePaths.length - 1];
                        DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath
                                .getLastPathComponent();
                        NodeInfo nodeInfo = (NodeInfo) node.getUserObject();
                        // Enter the attributePanel 'add new element' mode
                        attributePanel.enterAddNewElementMode(elementToAdd,
                                nodeInfo.getNode());
                    }
                }
            }
        }

        /**
         * Parser for the Element template.
         */
        protected class NodeTemplateParser implements ActionListener {

            /**
             * The string to parse.
             */
            protected String toParse;

            /**
             * The node type.
             */
            protected short nodeType;

            /**
             * Constructor.
             *
             * @param toParse
             *            The string to parse
             */
            public NodeTemplateParser(String toParse, short nodeType) {
                this.toParse = toParse;
                this.nodeType = nodeType;
            }

            public void actionPerformed(ActionEvent e) {
                Node nodeToAdd = null;
                switch (nodeType) {
                case Node.ELEMENT_NODE:
                    URL urlObj = null;
                    if (document instanceof SVGOMDocument) {
                        urlObj = ((SVGOMDocument) document).getURLObject();
                    }
                    String uri = (urlObj == null) ? "" : urlObj.toString();
                    Map prefixes = new HashMap();
                    prefixes.put(SVGConstants.XMLNS_PREFIX,
                            SVGConstants.SVG_NAMESPACE_URI);
                    prefixes.put(SVGConstants.XMLNS_PREFIX + ":"
                            + SVGConstants.XLINK_PREFIX,
                            SVGConstants.XLINK_NAMESPACE_URI);
                    SAXDocumentFactory df = new SAXDocumentFactory(document
                            .getImplementation(), XMLResourceDescriptor
                            .getXMLParserClassName());
                    DocumentFragment documentFragment = (DocumentFragment) DOMUtilities
                            .parseXML(toParse, document, uri, prefixes,
                                    SVGConstants.SVG_SVG_TAG, df);
                    nodeToAdd = documentFragment.getFirstChild();
                    break;
                case Node.TEXT_NODE:
                    nodeToAdd = document.createTextNode(toParse);
                    break;
                case Node.COMMENT_NODE:
                    nodeToAdd = document.createComment(toParse);
                    break;
                case Node.CDATA_SECTION_NODE:
                    nodeToAdd = document.createCDATASection(toParse);
                }

                // Append the new node to the parentNode
                TreePath[] treePaths = tree.getSelectionPaths();
                if (treePaths != null) {
                    TreePath treePath = treePaths[treePaths.length - 1];
                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath
                            .getLastPathComponent();
                    NodeInfo nodeInfo = (NodeInfo) node.getUserObject();

                    addChangesToHistory();

                    historyBrowserInterface.appendChild(nodeInfo.getNode(),
                            nodeToAdd);
                }
            }
        }

        /**
         * Creates JMenu menu using {@link NodeTemplates}.
         *
         * @param name
         *            The name of the submenu
         * @return The JMenu submenu
         */
        protected JMenu createTemplatesMenu(String name) {
            NodeTemplates templates = new NodeTemplates();
            JMenu submenu = new JMenu(name);

            // Create submenus
            HashMap menuMap = new HashMap();
            ArrayList categoriesList = templates.getCategories();
            int n = categoriesList.size();
            for (Object aCategoriesList : categoriesList) {
                String category = aCategoriesList.toString();
                JMenu currentMenu = new JMenu(category);
                submenu.add(currentMenu);
                // Add submenus to the map
                menuMap.put(category, currentMenu);
            }

            // Sort the value list and then iterate through node templates
            ArrayList values =
                new ArrayList(templates.getNodeTemplatesMap().values());
            Collections.sort(values, new Comparator() {
                public int compare(Object o1, Object o2) {
                    NodeTemplateDescriptor n1 = (NodeTemplateDescriptor) o1;
                    NodeTemplateDescriptor n2 = (NodeTemplateDescriptor) o2;
                    return n1.getName().compareTo(n2.getName());
                }
            });
            for (Object value : values) {
                NodeTemplateDescriptor desc =
                        (NodeTemplateDescriptor) value;
                String toParse = desc.getXmlValue();
                short nodeType = desc.getType();
                String nodeCategory = desc.getCategory();
                JMenuItem currentItem = new JMenuItem(desc.getName());
                currentItem.addActionListener
                        (new NodeTemplateParser(toParse, nodeType));
                JMenu currentSubmenu = (JMenu) menuMap.get(nodeCategory);
                currentSubmenu.add(currentItem);
            }
            return submenu;
        }

        /**
         * Handles tree pop-up menu action for removing nodes.
         */
        protected class TreeNodeRemover implements ActionListener {

            public void actionPerformed(ActionEvent e) {
                addChangesToHistory();

                AbstractCompoundCommand cmd = historyBrowserInterface
                        .createRemoveSelectedTreeNodesCommand(null);
                TreePath[] treePaths = tree.getSelectionPaths();
                for (int i = 0; treePaths != null && i < treePaths.length; i++) {
                    TreePath treePath = treePaths[i];
                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath
                            .getLastPathComponent();
                    NodeInfo nodeInfo = (NodeInfo) node.getUserObject();
                    if (DOMUtilities.isParentOf(nodeInfo.getNode(),
                            nodeInfo.getNode().getParentNode())) {
                        cmd.addCommand(historyBrowserInterface
                                .createRemoveChildCommand(nodeInfo.getNode()
                                        .getParentNode(), nodeInfo.getNode()));
                    }
                }
                historyBrowserInterface.performCompoundUpdateCommand(cmd);
            }
        }

        /**
         * To listen to the tree selection.
         */
        protected class DOMTreeSelectionListener
                implements TreeSelectionListener {

            /**
             * Called when the selection changes.
             */
            public void valueChanged(TreeSelectionEvent ev) {
                // Manages the selection overlay
                if (elementOverlayManager != null) {
                    handleElementSelection(ev);
                }

                DefaultMutableTreeNode mtn;
                mtn = (DefaultMutableTreeNode)
                    tree.getLastSelectedPathComponent();

                if (mtn == null) {
                    return;
                }

                if (rightPanel.getComponentCount() != 0) {
                    rightPanel.remove(0);
                }

                Object nodeInfo = mtn.getUserObject();
                if (nodeInfo instanceof NodeInfo) {
                    Node node = ((NodeInfo) nodeInfo).getNode();
                    switch (node.getNodeType()) {
                    case Node.DOCUMENT_NODE:
                        documentInfo.setText
                            (createDocumentText((Document) node));
                        rightPanel.add(documentInfoPanel);
                        break;
                    case Node.ELEMENT_NODE:
                        propertiesTable.setModel(new NodeCSSValuesModel(node));
                        attributePanel.promptForChanges();
                        attributePanel.setPreviewElement((Element) node);
                        rightPanel.add(elementPanel);
                        break;
                    case Node.COMMENT_NODE:
                    case Node.TEXT_NODE:
                    case Node.CDATA_SECTION_NODE:
                        characterDataPanel.setNode(node);
                        characterDataPanel.getTextArea().setText
                            (node.getNodeValue());
                        rightPanel.add(characterDataPanel);
                    }
                }

                splitPane.revalidate();
                splitPane.repaint();
            }

            protected String createDocumentText(Document doc) {
                StringBuffer sb = new StringBuffer();
                sb.append("Nodes: ");
                sb.append(nodeCount(doc));
                return sb.toString();
            }

            protected int nodeCount(Node node) {
                int result = 1;
                for (Node n = node.getFirstChild();
                     n != null;
                     n = n.getNextSibling()) {
                    result += nodeCount(n);
                }
                return result;
            }

            /**
             * Processes element selection overlay.
             *
             * @param ev
             *            Tree selection event
             */
            protected void handleElementSelection(TreeSelectionEvent ev) {
                TreePath[] paths = ev.getPaths();
                for (TreePath path : paths) {
                    DefaultMutableTreeNode mtn =
                            (DefaultMutableTreeNode) path.getLastPathComponent();
                    Object nodeInfo = mtn.getUserObject();
                    if (nodeInfo instanceof NodeInfo) {
                        Node node = ((NodeInfo) nodeInfo).getNode();
                        if (node.getNodeType() == Node.ELEMENT_NODE) {
                            if (ev.isAddedPath(path)) {
                                elementOverlayManager.addElement
                                        ((Element) node);
                            } else {
                                elementOverlayManager.removeElement
                                        ((Element) node);
                            }
                        }
                    }
                }
                elementOverlayManager.repaint();
            }
        }

        /**
         * To render the tree nodes.
         */
        protected class NodeRenderer extends DefaultTreeCellRenderer {

            /**
             * The icon used to represent elements.
             */
            protected ImageIcon elementIcon;

            /**
             * The icon used to represent comments.
             */
            protected ImageIcon commentIcon;

            /**
             * The icon used to represent processing instructions.
             */
            protected ImageIcon piIcon;

            /**
             * The icon used to represent text.
             */
            protected ImageIcon textIcon;

            /**
             * Creates a new NodeRenderer object.
             */
            public NodeRenderer() {
                String s;
                s = resources.getString("Element.icon");
                elementIcon = new ImageIcon(getClass().getResource(s));
                s = resources.getString("Comment.icon");
                commentIcon = new ImageIcon(getClass().getResource(s));
                s = resources.getString("PI.icon");
                piIcon = new ImageIcon(getClass().getResource(s));
                s = resources.getString("Text.icon");
                textIcon = new ImageIcon(getClass().getResource(s));
            }

            /**
             * Sets the value of the current tree cell.
             */
            public Component getTreeCellRendererComponent(JTree tree,
                                                          Object value,
                                                          boolean sel,
                                                          boolean expanded,
                                                          boolean leaf,
                                                          int row,
                                                          boolean hasFocus) {
                super.getTreeCellRendererComponent(tree, value, sel, expanded,
                                                   leaf, row, hasFocus);
                switch (getNodeType(value)) {
                case Node.ELEMENT_NODE:
                    setIcon(elementIcon);
                    break;
                case Node.COMMENT_NODE:
                    setIcon(commentIcon);
                    break;
                case Node.PROCESSING_INSTRUCTION_NODE:
                    setIcon(piIcon);
                    break;
                case Node.TEXT_NODE:
                case Node.CDATA_SECTION_NODE:
                    setIcon(textIcon);
                    break;
                }
                return this;
            }

            /**
             * Returns the DOM type of the given object.
             * @return the type or -1.
             */
            protected short getNodeType(Object value) {
                DefaultMutableTreeNode mtn = (DefaultMutableTreeNode)value;
                Object obj = mtn.getUserObject();
                if (obj instanceof NodeInfo) {
                    Node node = ((NodeInfo)obj).getNode();
                    return node.getNodeType();
                }
                return -1;
            }
        }

        /**
         * To display the CSS properties of a DOM node in a table.
         */
        protected class NodeCSSValuesModel extends AbstractTableModel {

            /**
             * The node.
             */
            protected Node node;

            /**
             * The computed style.
             */
            protected CSSStyleDeclaration style;

            /**
             * The property names.
             */
            protected List propertyNames;

            /**
             * Creates a new NodeAttributesModel object.
             */
            public NodeCSSValuesModel(Node n) {
                node = n;
                if (viewCSS != null) {
                    style = viewCSS.getComputedStyle((Element)n, null);
                    propertyNames = new ArrayList();
                    if (style != null) {
                        for (int i = 0; i < style.getLength(); i++) {
                            propertyNames.add(style.item(i));
                        }
                        Collections.sort(propertyNames);
                    }
                }
            }

            /**
             * Returns the name to give to a column.
             */
            public String getColumnName(int col) {
                if (col == 0) {
                    return resources.getString("CSSValuesTable.column1");
                } else {
                    return resources.getString("CSSValuesTable.column2");
                }
            }

            /**
             * Returns the number of columns in the table.
             */
            public int getColumnCount() {
                return 2;
            }

            /**
             * Returns the number of rows in the table.
             */
            public int getRowCount() {
                if (style == null) {
                    return 0;
                }
                return style.getLength();
            }

            /**
             * Whether the given cell is editable.
             */
            public boolean isCellEditable(int row, int col) {
                return false;
            }

            /**
             * Returns the value of the given cell.
             */
            public Object getValueAt(int row, int col) {
                String prop = (String)propertyNames.get(row);
                if (col == 0) {
                    return prop;
                } else {
                    return style.getPropertyValue(prop);
                }
            }
        }

    } // class Panel

    /**
     * To store the nodes informations
     */
    protected static class NodeInfo {
        /**
         * The DOM node.
         */
        protected Node node;

        /**
         * Creates a new NodeInfo object.
         */
        public NodeInfo(Node n) {
            node = n;
        }

        /**
         * Returns the DOM Node associated with this node info.
         */
        public Node getNode() {
            return node;
        }

        /**
         * Returns a printable representation of the object.
         */
        public String toString() {
            if (node instanceof Element) {
                Element e = (Element) node;
                String id = e.getAttribute(SVGConstants.SVG_ID_ATTRIBUTE);
                if (id.length() != 0) {
                    return node.getNodeName() + " \"" + id + "\"";
                }
            }
            return node.getNodeName();
        }
    }

    /**
     * To store the node information for a shadow tree.
     */
    protected static class ShadowNodeInfo extends NodeInfo {

        /**
         * Creates a new ShadowNodeInfo object.
         */
        public ShadowNodeInfo(Node n) {
            super(n);
        }

        /**
         * Returns a printable representation of the object.
         */
        public String toString() {
            return "shadow tree";
        }
    }

    /**
     * To store the node information for an xbl:content node's
     * selected content.
     */
    protected static class ContentNodeInfo extends NodeInfo {

        /**
         * Creates a new ContentNodeInfo object.
         */
        public ContentNodeInfo(Node n) {
            super(n);
        }

        /**
         * Returns a printable representation of the object.
         */
        public String toString() {
            return "selected content";
        }
    }
}
