/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.apache.org.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package ui;                    
                    

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.net.URL;
import java.net.MalformedURLException;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;
import org.xml.sax.ErrorHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.apache.xerces.parsers.DOMParser;
import ui.DOMParserSaveEncoding;



/**
 * A sample DOM Tree Viewer. This sample program illustrates how to
 * traverse a DOM tree and display it in a Swing JTree View.
 *
 * @version
 */
public class TreeView extends JFrame implements ActionListener, TextListener {

    //
    // Constants
    //

    static final boolean DEBUG = true;
  
    /** Default parser name. */
    static final String 
        DEFAULT_PARSER_NAME = "org.apache.xerces.parsers.DOMParser";
    static int WARNING = 0;
    static int ERROR=1;
    static int FATAL_ERROR=2;
        

    static final String title = "TreeViewer";
    static final String openString = "Open";
    static final String quitString = "Quit";
    static final String reloadString = "Reload current XML file";
    static final String expandString = "Expand Tree";
    static final String collapseString = "Collapse Tree";

    //
    // Data
    //

    ErrorStorer ef;
    String fname;
    DOMTree m_tree;
    JTextArea sourceText, messageText;
    Vector textLine;
    FileNameInput fni;
    DOMParserSaveEncoding parser;
    Image openFolder;
    Image closedFolder;
    Image leafImage;

    /**
     *  Constructor
     */
    public TreeView() {
        this(null);
    }

    /**
     *  Constructor
     */
    public TreeView(String uri) {
        super(uri);
        openFolder = DefaultImages.createOpenFolderImage();
        closedFolder = DefaultImages.createClosedFolderImage();
        leafImage = DefaultImages.createLeafImage();
        parser = new DOMParserSaveEncoding();
        ef = new ErrorStorer();
        fname = uri;
        JMenuBar jmb = new JMenuBar();
        JMenu fileMenu = new JMenu("File");
        JMenuItem item;

        item = new JMenuItem(openString);
        fileMenu.add(item);
        item.addActionListener(this);

        item = new JMenuItem(quitString);
        fileMenu.add(item);
        item.addActionListener(this);

        JMenu shortcutMenu = new JMenu("Shortcuts");

        item = new JMenuItem(expandString);
        shortcutMenu.add(item);
        item.addActionListener(this);

        item = new JMenuItem(collapseString);
        shortcutMenu.add(item);
        item.addActionListener(this);

        item = new JMenuItem(reloadString);
        shortcutMenu.add(item);
        item.addActionListener(this);

        jmb.add(fileMenu);
        jmb.add(shortcutMenu);
        setJMenuBar(jmb);

        getContentPane().add(createUI(fname));
        
    }

    /** create and return the entire UI from the root TreeNode
     */
    JComponent createUI(String filename) {
        if (DEBUG) System.out.println("START createUI:"+filename);

        // create the message panel first so we can send messages to it...
        messageText = new JTextArea(3,40);
        messageText.setFont(new Font("dialog", Font.PLAIN, 12));
        JPanel messagePanel = new JPanel(new BorderLayout());
        messagePanel.add(new JScrollPane(messageText) {
            public Dimension getPreferredSize(){
                Dimension size = TreeView.this.getSize();
                return new Dimension(size.width, size.height / 4);
                }
            public Dimension getMinimumSize(){
                return new Dimension(100, 100);
                }
            },
            BorderLayout.CENTER);
        messagePanel.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("Messages"),
            BorderFactory.createEmptyBorder(4, 4, 4, 4)
            ));

        // create the TextArea for XML source
        sourceText = new JTextArea();
        sourceText.setFont(new Font("monospaced", Font.PLAIN, 12));
        sourceText.setBackground(Color.white);
        sourceText.setForeground(Color.black);
        sourceText.setSelectedTextColor(Color.black);
        sourceText.setSelectionColor(Color.red);
        sourceText.setEditable(false);
        JPanel sourcePanel = new JPanel(new BorderLayout());
        sourcePanel.add(new JScrollPane(sourceText){
            public Dimension getPreferredSize(){
                Dimension size = TreeView.this.getSize();
                return new Dimension(size.width / 2, size.height * 3 / 5);
                }
            public Dimension getMinimumSize(){
                return new Dimension(100, 100);
                }
            },
            BorderLayout.CENTER);
        sourcePanel.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("Source View"),
            BorderFactory.createEmptyBorder(4, 4, 4, 4)
            ));

        // create the JTree and scroll pane.
        JPanel treePanel = new JPanel(new BorderLayout());
        m_tree = new DOMTree();
        m_tree.setCellRenderer(new XMLTreeCellRenderer());
        m_tree.getSelectionModel().setSelectionMode
            (TreeSelectionModel.SINGLE_TREE_SELECTION);

        // Listen for when the selection changes, call nodeSelected(node)
        m_tree.addTreeSelectionListener(
            new TreeSelectionListener() {
                public void valueChanged(TreeSelectionEvent e) {
                    TreeNode node = (TreeNode)
                        (e.getPath().getLastPathComponent());

                    nodeSelected(node);
                }
            }
        );
        m_tree.setRowHeight(18);
        m_tree.setFont(new Font("dialog", Font.PLAIN, 12));

        treePanel.add(new JScrollPane(m_tree) {
            public Dimension getPreferredSize(){
                Dimension size = TreeView.this.getSize();
                return new Dimension(size.width / 2, size.height * 3 / 5);
                }
            public Dimension getMinimumSize(){
                return new Dimension(100, 100);
                }
            },
            BorderLayout.CENTER);

        treePanel.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("Tree View"),
            BorderFactory.createEmptyBorder(4, 4, 4, 4)
            ));

        // refreshUI loads everthything!
        refreshUI(filename);

        // use the new JSplitPane to dynamically resize...
        JComponent split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
            true, treePanel, sourcePanel);

        JComponent mainSplitPane =
            new JSplitPane(JSplitPane.VERTICAL_SPLIT,
                           true, split, messagePanel);

        if (DEBUG) System.out.println("END createUI:"+filename);
        return mainSplitPane;
    }

    /** refreshUI is called when we have a new filename to parse.
     */
    void refreshUI(String filename) {
        if (DEBUG) System.out.println("START refreshUI:"+filename);

        messageText.selectAll();
        messageText.cut();

        if (filename == null || filename.equals("")) {
            messageText.setForeground(Color.red);
            messageText.append("No input XML filename specified:"+filename+"\n");
            return;
        }

        fname = filename;
        Document newRoot = getRoot(filename);
        if (newRoot == null) {
            messageText.setForeground(Color.red);
            messageText.append("Unable to get new DOM Tree for:"+filename+"\n");
            return;
        }
        m_tree.setDocument(newRoot);

        // new Source
        sourceText.selectAll();
        sourceText.cut();
        readXMLFile(fname, sourceText);

        setTitle(title+": "+filename);

        if (m_tree!= null)
            expandTree();


        if (ef != null && ef.getErrorNodes()!=null       
                    && ef.getErrorNodes().size() > 0 ) {
            messageText.setForeground(Color.red);
            messageText.append("XML source, "+fname+" has errors.\n");
            messageText.append("Please click on red Tree View items for details.\n");
            /***/
            Hashtable errors = ef.getErrorNodes();
            Enumeration keys = errors.keys();
            while (keys.hasMoreElements()) {
                Node node = (Node)keys.nextElement();
                messageText.append("node="+node.getNodeName()
                +", error="+((ParseError)errors.get(node)).getMsg()+"\n");
            }
        }
        if (DEBUG) System.out.println("END refreshUI:"+filename);
    }

    /**
     *  Invoke the Parser on fname and return the root TreeNode.
     */
    public Document getRoot(String filename) {
        if (DEBUG) System.out.println("START getRoot:"+filename);

        if (filename == null || filename.equals(""))
        return null;

        try {
            //
            // Reset the Error Storage and handling
            //
     
            ef.resetErrors();
            parser.setErrorHandler(ef);
            parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false); // otherwise parser.getCurrentNode() == null
            parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
            parser.setFeature("http://apache.org/xml/features/allow-java-encodings", true);
            parser.parse(filename);
            Document document = parser.getDocument();
            /***/
            return document;
        } catch (Exception e) {
             System.err.println( "Error: Invalid XML document could not get ROOT" );
             System.exit( 1 );
            //e.printStackTrace(System.err);
        }
        return null;
    }

    /** read the xml file from filename and append it to the JTextArea
     */
    synchronized void readXMLFile(String filename, JTextArea ta) {

        if (DEBUG) System.out.println("START readXMLFile"+filename);
        if (filename == null || filename.equals(""))
            return;
        InputStream fis = null;
        BufferedReader dis = null;
        try {
            java.net.URL file = createURL(filename);
            fis = file.openStream();

            String javaEncoding = parser.getJavaEncoding(); // get saved java encoding
            try
            {
            dis = new BufferedReader(new InputStreamReader(fis, javaEncoding ));
            }
            catch( UnsupportedEncodingException ex )
            {
            dis = new BufferedReader(new InputStreamReader(fis ));
            }
        } catch (Exception ex) {
            System.err.println("ERROR: Xerces.readXMLFile: "+ex);
            return;
        }

        String line;
        int i = 0;

        int len = 0;
        textLine = new Vector();
        String nl = "\n";
        int nllen = nl.length();
        StringBuffer sb = new StringBuffer();

        try{
            readline: while ((line = dis.readLine()) != null) {
                sb.append(line+nl);
                textLine.addElement(new Integer(len));
                len += line.length()+nllen;
            }
            ta.append(sb.toString());
        } catch (IOException io) {
            System.err.println(io);
            return;
        }

        // relayout because contents have changed
        //ta.revalidate();

        if (DEBUG) System.out.println("END readXMLFile"+filename);
        return;

    }

    /** called when our JTree's nodes are selected.
     */
    void nodeSelected(TreeNode treeNode) {

        Node node = m_tree.getNode(treeNode);

        if( node == null )     // It is possible to get a null node
            return;

        StringBuffer sb = new StringBuffer();
        messageText.selectAll();
        messageText.cut();


        //fix

       //JTextArea sourceText = sourceText;
       Object errorObject = ef == null ? null : ef.getError(node);
       if (errorObject != null) {
           // There *is* an error in this node.
           messageText.setForeground(Color.red);
           ParseError eip = (ParseError)errorObject;
           sb.append("Error: "+eip.getMsg()+"\n");
           int lineNo = eip.getLineNo();
           int pos  = 0;
           int next = 0;                       
           int sizeOfTextLine = textLine.size();

           if( lineNo < sizeOfTextLine )
              {
              pos = ((Integer)textLine.elementAt(lineNo-1)).intValue();
              next = (lineNo == sizeOfTextLine ) ?
               pos :
               (((Integer)textLine.elementAt(lineNo)).intValue());
              }
           else
              {
              pos  = (( Integer) textLine.elementAt( sizeOfTextLine - 1 )).intValue();
              next = pos + 2;
              }

           sourceText.select(pos, next );
           //m_textScrollPane.repaint();
       } else {
           messageText.setForeground(Color.black);
           sourceText.select(0, 0 );
       }
        
        //fix

        
        if (node.getNodeType() == Node.ELEMENT_NODE
                    || node.getNodeType() == Node.TEXT_NODE 
                || node.getNodeType() == Node.CDATA_SECTION_NODE )
                 {
                    sb.append(node.toString());
            }
       
        messageText.append(sb.toString());
    }

    /** called when a the text value has changed in the FileNameInput.
     *  read in new XML file.
     */
    public void textValueChanged(TextEvent e) {
        try {
            if (fni != null)
                fni.setVisible(false);
            fname = ((JTextField)e.getSource()).getText();
            if (DEBUG) System.out.println("textValueChanged:"+fname);
            refreshUI(fname);

        } catch (Exception ex) {
           System.err.println( "Error: while trying to refresh gui" );
           System.exit( 1 );
        //    ex.printStackTrace();
        }
    }

    /** called to handle menu actions.
     */
    public void actionPerformed(java.awt.event.ActionEvent e) {
        if (DEBUG) System.err.println("ACTION: "+e.getActionCommand()+", "+e.paramString());

        if (e.getActionCommand().equals(quitString)) {
          System.exit(0);
        }
        else if (e.getActionCommand().equals(openString)) {

            fni = new FileNameInput("Open File");
            fni.addTextListener(this);
            fni.setVisible(true);
        }
        else if (e.getActionCommand().equals(expandString)) {
            expandTree();
        }
        else if (e.getActionCommand().equals(collapseString)) {
            int rows = m_tree.getRowCount();
            for (int i = 0; i < rows; i++) {
                m_tree.collapseRow(i);
            }
        }
        else
        //if (e.getActionCommand().equals(reloadString)) {
            refreshUI(fname);
        //}
    }

    void expandTree() {
        int rows = 0;
        for (int levels=0; levels <= 4; levels++) {
            rows=m_tree.getRowCount();
            for (int i = 0; i < rows; i++) {
                m_tree.expandRow(i);
            }
        }
    }

    /*
     * The XMLTreeCellRenderer is an inner class which enables the
     * highlighting of errors in the tree and shows the gender values
     * as different icons.
     */
    class XMLTreeCellRenderer extends DefaultTreeCellRenderer
    {

        public Component getTreeCellRendererComponent(JTree tree, Object value,
                          boolean selected, boolean expanded,
                          boolean leaf, int row,
                              boolean hasFocus)
        {
            Node node = ((DOMTree)tree).getNode(value);
            Component comp = super.getTreeCellRendererComponent(tree, value,
                           selected,  expanded, leaf,  row, hasFocus);
            if (selected) {
                comp.setBackground(Color.blue);
            }
            if (ef != null
            && ef.getErrorNodes() != null
            && value != null
            && node != null
            && ef.getErrorNodes().containsKey( node )) {
                comp.setForeground(Color.red);
            }

            if (node != null) {
                if (leaf) {
                    setIcon(new ImageIcon(leafImage));
                } else if (expanded) {
                    setIcon(new ImageIcon(openFolder));
                } else {
                    setIcon(new ImageIcon(closedFolder));
                }
            }
            if (node != null && node instanceof Element) {
                
                Element txNode = (Element)node;
                Attr txAtt = (Attr)txNode.getAttributeNode("gender");
                if (txAtt != null) {
                    if (txAtt.getValue().equals("male")) {
                        setIcon(new ImageIcon("male.gif"));
                    } else
                    if (txAtt.getValue().equals("female")) {
                        setIcon(new ImageIcon("female.gif"));
                    }
                }
            }

            return comp;
        }
    }

    /*
     * The FileNameInput is an inner class which allows the user
     * to enter a filename. It exists due to a Swing bug which
     * has problems with the real file input panel.
     */
    class FileNameInput extends JFrame implements ActionListener {


        JLabel fileLabel;
        JTextField textField;
        JButton ok;
        JButton cancel;
        Vector textListeners;

        public FileNameInput() {
            this("");
        }

        public FileNameInput(String title) {

            super(title);

            fileLabel = new JLabel("Enter XML file name:");
            textField = new JTextField();
            textField.addActionListener(this);
            ok = new JButton("ok");
            cancel = new JButton("cancel");
            JPanel buttonPanel = new JPanel();
            buttonPanel.add(ok);
            buttonPanel.add(cancel);
            ok.addActionListener(this);
            cancel.addActionListener(this);
            getContentPane().add(fileLabel, BorderLayout.NORTH);
            getContentPane().add(textField, BorderLayout.CENTER);
            getContentPane().add(buttonPanel, BorderLayout.SOUTH);
            setSize(400,100);
        }

        public void actionPerformed(ActionEvent e) {

            if (e.getSource() == ok || e.getSource() == textField) {
                System.out.println("FileNameInput: pressed OK");
                    TextEvent event = new TextEvent(textField, TextEvent.TEXT_VALUE_CHANGED);
                    deliverEvent(event);
                    setVisible(false);
            } else
            if (e.getSource() == cancel) {
                System.out.println("FileNameInput: pressed cancel");
                    setVisible(false);
            }
        }

        /**
         * Adds a TextListener event listener.
         *
         * @param listener  The listener to add.
         *
         * @see #removeTextListener
         */
        public void addTextListener(TextListener listener) {

            // is there anything to do?
            if (listener == null)
                return;

            if (textListeners == null)
               textListeners = new Vector();

            // add listener
            textListeners.addElement(listener);
            }

        /**
         * Removes a TextListener event listener.
         *
         * @param listener  The listener to remove.
         *
         * @see #addTextListener
         */
        public void removeTextListener(TextListener listener) {

            // is there anything to do?
            if (listener == null || textListeners == null)
                return;

            // add listener
            textListeners.removeElement(listener);
            }


        /**
         * This function delivers TextListener events, when the ok
         * button is clicked.
         *
         * @param evt The event to deliver.
         */
        protected void deliverEvent(EventObject evt) {

            if (evt instanceof TextEvent) {
                TextEvent event = (TextEvent)evt;

                Vector l;
                synchronized (textListeners) { l = (Vector)textListeners.clone(); }

                int size = l.size();
                for (int i = 0; i < size; i++)
                    ((TextListener)l.elementAt(i)).textValueChanged(event);
                }
            }
    }

    //
    // Create a URL object from either a URL string or a plain file name.
    //
    static URL createURL(String name) throws Exception {
        try {
                URL u = new URL(name);
                return u;
        } catch (MalformedURLException ex) {
        }
        URL u = new URL("file:" + new File(name).getAbsolutePath());
        return u;
    }    
    
    /**
     * The ErrorStorer maps Nodes to errors. It receives a reference
     * to the ErrorTreeFactory in the Constructor.
     *
     * When error is called, it asks the
     * ErrorTreeFactory for the current node, and uses this as the
     * "key" of a Hashtable, with the error as a value. The error
     * value is wrapped up nicely in an ParseError object.
     *
     * It is used in the XML Tutorial to illustrate how to implement
     * the ErrorListener to provide error storage for later reference.
     *
     */
    class ErrorStorer 
        implements ErrorHandler
        
    {

        //
        // Data
        //
        Hashtable errorNodes = null;
        
        /**
         * Constructor
         */
        public ErrorStorer() {
        }

        /**
         * The client is is allowed to get a reference to the Hashtable,
         * and so could corrupt it, or add to it...
         */
        public Hashtable getErrorNodes() {
            return errorNodes;
        }

        /**
         * The ParseError object for the node key is returned.
         * If the node doesn't have errors, null is returned.
         */
        public Object getError(Node node) {
            if (errorNodes == null)
                return null;
            return errorNodes.get(node);
        }
        
        /**
         * Reset the error storage.
         */
        public void resetErrors() {
            if (errorNodes != null)
            errorNodes.clear();
        }
        
        /***/
        public void warning(SAXParseException ex) {
            handleError(ex, WARNING);
        }

        public void error(SAXParseException ex) {
            handleError(ex, ERROR);
        }

        public void fatalError(SAXParseException ex) throws SAXException {
            handleError(ex, FATAL_ERROR);
        }
        
        private void handleError(SAXParseException ex, int type) {
            System.out.println("!!! handleError: "+ex.getMessage());

            StringBuffer errorString = new StringBuffer();
            errorString.append("at line number, ");
            errorString.append(ex.getLineNumber());
            errorString.append(": ");
            errorString.append(ex.getMessage());

            // Node current = parser.getCurrentNode();

            Node current = null ;

            try
              {
              current = ( Node ) parser.getProperty( "http://apache.org/xml/properties/dom/current-element-node" );
              
              }
            catch( SAXException exception  )
              {
               ;
              }

            if (current == null) {
                System.err.println("Error in handleError. getCurrentNode()==null!");
                return;
            }
            
            if (errorNodes == null)
                errorNodes = new Hashtable();
            ParseError previous = (ParseError) errorNodes.get(current);
            ParseError eip  = null;
            // if a Node already has an error, we accumulate the text here...
            if (previous != null) {
                eip = previous;
                errorString = new StringBuffer(previous.getMsg()+"\n"+errorString.toString());
                eip.setMsg(errorString.toString());
            } else {
                eip = new
                    ParseError(
                        ex.getSystemId(), 
                        ex.getLineNumber(), 
                        ex.getColumnNumber(),
                        "",  
                        errorString.toString());
            }

            // put it in the Hashtable.
            errorNodes.put(current, eip);
        }
        
    }
    
    /**
     * The ParseError class wraps up all the error info from
     * the ErrorStorer's error method.
     *
     * @see ErrorStorer
     */
    class ParseError extends Object {

        //
        // Data
        //

        String fileName;
        int lineNo;
        int charOffset;
        Object key;
        String msg;

        /**
         * Constructor
         */
        public ParseError(String fileName, int lineNo, int charOffset,
                           Object key, 
                           String msg)
        {
            this. fileName=fileName;
            this. lineNo=lineNo;
            this. charOffset=charOffset;
            this. key=key;
            this. msg=msg;
        }

        //
        // Getters...
        //
        public String getFileName() { return fileName; }
        public int getLineNo() { return lineNo; }
        public int getCharOffset() { return charOffset;}
        public Object getKey() { return key; }
        public String getMsg() { return msg; }
        public void setMsg(String s) { msg = s; }
    }


    //
    // Main
    //
    
    /** Main program entry point. */
    public static void main(String argv[]) {
        
        // vars
        int parserNameIndex = -1;
        String parserName = DEFAULT_PARSER_NAME;

        // check parameters
        for (int i = 0; i < argv.length; i++) {
            String arg = argv[i];

            // options
            if (arg.startsWith("-")) {
                if (arg.equals("-p")) {
                    if (i == argv.length - 1) {
                        System.err.println("error: missing parser class");
                        System.exit(1);
                    }
                    parserName = argv[++i];
                    parserNameIndex = i;
                    continue;
                }

                if (arg.equals("-h")) {
                    printUsage();
                    System.exit(1);
                }
            }

            // print uri
            System.err.println(arg+':');
   
            JFrame frame = null;
            if (parserNameIndex == argv.length-1) {
                // null behaviour is blank screen - eg no JTree, or file dispalyed
                frame = new TreeView("");
            } else {
                frame = new TreeView(arg);
            }
            frame.addWindowListener(new java.awt.event.WindowAdapter() {
             public void windowClosing(java.awt.event.WindowEvent e) {
                 System.exit(0);
             }
            });
            frame.setSize(790, 590);
            frame.setVisible(true);
        }
    } // main(String[])

    /** Prints the usage. */
    private static void printUsage() {

        System.err.println("usage: java ui.TreeViewer (options) uri ...");
        System.err.println();
        System.err.println("options:");
        System.err.println("  -p name  Specify DOM parser class by name.");
        System.err.println("           Default parser: "+DEFAULT_PARSER_NAME);
        System.err.println("  -h       This help screen.");

    } // printUsage()

} // class TreeViewer
