/*
 * (C) Copyright IBM Corp. 1997-1998  All rights reserved.
 *
 * US Government Users Restricted Rights Use, duplication or
 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 *
 * The program is provided "as is" without any warranty express or
 * implied, including the warranty of non-infringement and the implied
 * warranties of merchantibility and fitness for a particular purpose.
 * IBM will not be liable for any damages suffered by you as a result
 * of using the Program. In no event will IBM be liable for any
 * special, indirect or consequential damages or lost profits even if
 * IBM has been advised of the possibility of their occurrence. IBM
 * will not be liable for any third party claims against you.
 */

package com.ibm.xml.parser.util;

import com.ibm.xml.parser.AttDef;
import com.ibm.xml.parser.Attlist;
import com.ibm.xml.parser.Child;
import com.ibm.xml.parser.ContentModel;
import com.ibm.xml.parser.DTD;
import com.ibm.xml.parser.DefaultElementFactory;
import com.ibm.xml.parser.ElementDecl;
import com.ibm.xml.parser.Entity;
import com.ibm.xml.parser.ExternalID;
import com.ibm.xml.parser.NamespacePI;
import com.ibm.xml.parser.StylesheetPI;
import com.ibm.xml.parser.TXAttribute;
import com.ibm.xml.parser.TXCDATASection;
import com.ibm.xml.parser.TXComment;
import com.ibm.xml.parser.TXDocument;
import com.ibm.xml.parser.TXElement;
import com.ibm.xml.parser.TXNotation;
import com.ibm.xml.parser.TXPI;
import com.ibm.xml.parser.TXText;
import com.sun.java.swing.tree.TreeNode;
import java.util.Enumeration;
import org.w3c.dom.Comment;
import org.w3c.dom.PI;
import org.w3c.dom.Text;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Node;
import org.w3c.dom.NodeIterator;

/**
 * <P>A factory for Swing <CODE>JTree</CODE> class.</P>
 * <PRE>
 *   Parser p = new Parser(...);
 *   p.setElementFactory(new TreeFactory());
 *   TXDocument doc = p.readStream(...);
 *   tree = new JTree((TreeNode)doc);
 * </PRE>
 *
 * @version 1.1
 * @author TAMURA Kent &lt;kent@trl.ibm.co.jp&gt;
 * @see com.ibm.xml.parser.Parser#setElementFactory(com.ibm.xml.parser.ElementFactory)
 * @see com.sun.java.swing.JTree
 * @see com.sun.java.swing.tree.TreeNode
 */
public class TreeFactory extends DefaultElementFactory {
    public String toStringAttDef(AttDef ad, String encoding) {
        return ad.getName();
    }
    public String toStringAttlist(Attlist al, String encoding) {
        return "!ATTLIST "+al.getName();
    }
    public String toStringDTD(DTD dtd, String encoding) {
        return "!DOCTYPE "+dtd.getName();
    }
    public String toStringElementDecl(ElementDecl ed, String encoding) {
        return "!ELEMENT "+ed.getName();
    }
    public String toStringEntity(Entity ent, String encoding) {
        return "!ENTITY "+(ent.isParameter() ? "% " : "")+ent.getName();
    }
    public String toStringComment(Comment com, String encoding) {
        return "<!--"+com.getData()+"-->";
    }
    public String toStringDocument(TXDocument doc, String encoding) {
        return "[DOCUMENT]";
    }
    public String toStringElement(TXElement el, String encoding) {
        StringBuffer sb = new StringBuffer();
        sb.append("<");
        sb.append(el.getName());
        java.util.Enumeration en = el.attributeElements();
        while (en.hasMoreElements()) {
            sb.append(" ");
            sb.append(((TXAttribute)en.nextElement()).toXMLString(encoding));
        }
        sb.append(">");
        return sb.toString();
    }
    public String toStringNotation(TXNotation no, String encoding) {
        return "!NOTATION "+no.getName();
    }
    public String toStringPI(PI pi, String encoding) {
        return "<?"+pi.getName()+pi.getData()+"?>";
    }
    public String toStringText(Text text, String encoding) {
        String ret;
        if (text instanceof CDATASection) {
            ret = "<![CDATA["+text.getData()+"]]>";
        } else {
            ret = "\""+TXText.makePrintable(text.getData())+"\"";
        }
        return ret;
    }

    public TXDocument createDocument() {
        TXDocument doc = new TreeDocument();
        doc.setFactory(this);
        return doc;
    }

    public TXElement createElement(String name) {
        TXElement el = new TreeElement(name);
        el.setFactory(this);
        return el;
    }

    public TXText createText(String data, boolean ignorable) {
        TXText te = new TreeText(data);
        te.setFactory(this);
        te.setIsIgnorableWhitespace(ignorable);
        return te;
    }
    public TXText createText(char[] ac, int offset, int length, boolean ignorable) {
        TXText te = new TreeText(new String(ac, offset, length));
        te.setFactory(this);
        te.setIsIgnorableWhitespace(ignorable);
        return te;
    }

    public TXCDATASection createCDATA(String data) {
        TXCDATASection cd = new TreeCDATASection(data);
        cd.setFactory(this);
        return cd;
    }

    public TXComment createComment(String data) {
        TXComment comm = new TreeComment(data);
        comm.setFactory(this);
        return comm;
    }

    public TXPI createPI(String name, String data) {
        TXPI pi = new TreePI(name, data);
        pi.setFactory(this);
        return pi;
    }

    public NamespacePI createNamespacePI(String name, String data, String ns,
                                         String prefix, String src) {
        NamespacePI pi = new TreeNamespacePI(name, data, ns, prefix, src);
        pi.setFactory(this);
        return pi;
    }

    public StylesheetPI createStylesheetPI(String name, String data,
                                           String type, String href, String title) {
        StylesheetPI pi = new TreeStylesheetPI(name, data, type, href, title);
        pi.setFactory(this);
        return pi;
    }

    public DTD createDTD() {
        DTD d = new TreeDTD();
        d.setFactory(this);
        return d;
    }
    public DTD createDTD(String rootname, ExternalID eid) {
        DTD d = new TreeDTD(rootname, eid);
        d.setFactory(this);
        return d;
    }
    public ElementDecl createElementDecl(String elementname, ContentModel cs) {
        ElementDecl ed = new TreeElementDecl(elementname, cs);
        ed.setFactory(this);
        return ed;
    }

    public Attlist createAttlist(String elementname) {
        Attlist al = new TreeAttlist(elementname);
        al.setFactory(this);
        return al;
    }
    public AttDef createAttDef(String attributename) {
        AttDef ad = new TreeAttDef(attributename);
        ad.setFactory(this);
        return ad;
    }
    public Entity createEntity(String name, String value, boolean parameter) {
        Entity en = new TreeEntity(name, value, parameter);
        en.setFactory(this);
        return en;
    }
    public Entity createEntity(String name, ExternalID eid, boolean isParameter, String ndata) {
        Entity en = new TreeEntity(name, eid, isParameter, ndata);
        en.setFactory(this);
        return en;
    }
    public TXNotation createNotation(String name, ExternalID eid) {
        TXNotation no = new TreeNotation(name, eid);
        no.setFactory(this);
        return no;
    }

    // ================================================

    public static class TreeDocument extends TXDocument implements TreeNode {
        public Enumeration children() {
            return elements();
        }
        public boolean getAllowsChildren() {
            return true;
        }
        public TreeNode getChildAt(int childIndex) {
            return (TreeNode)getChildNodes().moveTo(childIndex);
        }
        public int getChildCount() {
            return getChildNodes().getLength();
        }
        public int getIndex(TreeNode node) {
            NodeIterator ni = getChildNodes();
            Node n;
            int ret = 0;
            while (null != (n = ni.toNextNode())) {
                if (n == node)  return ret;
                ret ++;
            }
            return -1;
        }
        public TreeNode getParent() {
            return (TreeNode)getParentNode();
        }
        public boolean isLeaf() {
            return false;
        }
    }

    // ================================================

    public static class TreeElement extends TXElement implements TreeNode {
        public TreeElement(String qname) {
            super(qname);
        }
        public Enumeration children() {
            return elements();
        }
        public boolean getAllowsChildren() {
            return true;
        }
        public TreeNode getChildAt(int childIndex) {
            return (TreeNode)getChildNodes().moveTo(childIndex);
        }
        public int getChildCount() {
            return getChildNodes().getLength();
        }
        public int getIndex(TreeNode node) {
            NodeIterator ni = getChildNodes();
            Node n;
            int ret = 0;
            while (null != (n = ni.toNextNode())) {
                if (n == node)  return ret;
                ret ++;
            }
            return -1;
        }
        public TreeNode getParent() {
            return (TreeNode)getParentNode();
        }
        public boolean isLeaf() {
            return !hasChildNodes();
        }
    }

    // ================================================

    public static class TreeDTD extends DTD implements TreeNode {
        public TreeDTD() {
            super();
        }
        public TreeDTD(String root, ExternalID eid) {
            super(root, eid);
        }
        public Enumeration children() {
            return elements();
        }
        public boolean getAllowsChildren() {
            return true;
        }
        public TreeNode getChildAt(int childIndex) {
            return (TreeNode)getChildNodes().moveTo(childIndex);
        }
        public int getChildCount() {
            return getChildNodes().getLength();
        }
        public int getIndex(TreeNode node) {
            NodeIterator ni = getChildNodes();
            Node n;
            int ret = 0;
            while (null != (n = ni.toNextNode())) {
                if (n == node)  return ret;
                ret ++;
            }
            return -1;
        }
        public TreeNode getParent() {
            return (TreeNode)getParentNode();
        }
        public boolean isLeaf() {
            return !hasChildNodes();
        }
    }
    
    // ================================================

    public static class TreeText extends TXText implements TreeNode {
        public TreeText(String data) {
            super(data);
        }
        public Enumeration children() {
            return null;
        }
        public boolean getAllowsChildren() {
            return false;
        }
        public TreeNode getChildAt(int childIndex) {
            return null;
        }
        public int getChildCount() {
            return 0;
        }
        public int getIndex(TreeNode node) {
            return -1;
        }
        public TreeNode getParent() {
            return (TreeNode)getParentNode();
        }
        public boolean isLeaf() {
            return true;
        }
    }

    // ================================================

    public static class TreeCDATASection extends TXCDATASection implements TreeNode {
        public TreeCDATASection(String data) {
            super(data);
        }
        public Enumeration children() {
            return null;
        }
        public boolean getAllowsChildren() {
            return false;
        }
        public TreeNode getChildAt(int childIndex) {
            return null;
        }
        public int getChildCount() {
            return 0;
        }
        public int getIndex(TreeNode node) {
            return -1;
        }
        public TreeNode getParent() {
            return (TreeNode)getParentNode();
        }
        public boolean isLeaf() {
            return true;
        }
    }

    // ================================================

    public static class TreeComment extends TXComment implements TreeNode {
        public TreeComment(String data) {
            super(data);
        }
        public Enumeration children() {
            return null;
        }
        public boolean getAllowsChildren() {
            return false;
        }
        public TreeNode getChildAt(int childIndex) {
            return null;
        }
        public int getChildCount() {
            return 0;
        }
        public int getIndex(TreeNode node) {
            return -1;
        }
        public TreeNode getParent() {
            return (TreeNode)getParentNode();
        }
        public boolean isLeaf() {
            return true;
        }
    }

    // ================================================

    public static class TreePI extends TXPI implements TreeNode {
        public TreePI(String name, String data) {
            super(name, data);
        }
        public Enumeration children() {
            return null;
        }
        public boolean getAllowsChildren() {
            return false;
        }
        public TreeNode getChildAt(int childIndex) {
            return null;
        }
        public int getChildCount() {
            return 0;
        }
        public int getIndex(TreeNode node) {
            return -1;
        }
        public TreeNode getParent() {
            return (TreeNode)getParentNode();
        }
        public boolean isLeaf() {
            return true;
        }
    }

    // ================================================

    public static class TreeNamespacePI extends NamespacePI implements TreeNode {
        public TreeNamespacePI(String n, String d, String ns, String p, String s) {
            super(n, d, ns, p, s);
        }
        public Enumeration children() {
            return null;
        }
        public boolean getAllowsChildren() {
            return false;
        }
        public TreeNode getChildAt(int childIndex) {
            return null;
        }
        public int getChildCount() {
            return 0;
        }
        public int getIndex(TreeNode node) {
            return -1;
        }
        public TreeNode getParent() {
            return (TreeNode)getParentNode();
        }
        public boolean isLeaf() {
            return true;
        }
    }

    // ================================================

    public static class TreeStylesheetPI extends StylesheetPI implements TreeNode {
        public TreeStylesheetPI(String n, String d, String t, String h, String tit) {
            super(n, d, t, h, tit);
        }
        public Enumeration children() {
            return null;
        }
        public boolean getAllowsChildren() {
            return false;
        }
        public TreeNode getChildAt(int childIndex) {
            return null;
        }
        public int getChildCount() {
            return 0;
        }
        public int getIndex(TreeNode node) {
            return -1;
        }
        public TreeNode getParent() {
            return (TreeNode)getParentNode();
        }
        public boolean isLeaf() {
            return true;
        }
    }

    // ================================================

    public static class TreeElementDecl extends ElementDecl implements TreeNode {
        public TreeElementDecl(String n, ContentModel cm) {
            super(n, cm);
        }
        public Enumeration children() {
            return null;
        }
        public boolean getAllowsChildren() {
            return false;
        }
        public TreeNode getChildAt(int childIndex) {
            return null;
        }
        public int getChildCount() {
            return 0;
        }
        public int getIndex(TreeNode node) {
            return -1;
        }
        public TreeNode getParent() {
            return (TreeNode)getParentNode();
        }
        public boolean isLeaf() {
            return true;
        }
    }

    // ================================================

    public static class TreeAttlist extends Attlist implements TreeNode {
        public TreeAttlist(String n) {
            super(n);
        }
        public Enumeration children() {
            return elements();
        }
        public boolean getAllowsChildren() {
            return true;
        }
        public TreeNode getChildAt(int childIndex) {
            return (TreeNode)elementAt(childIndex);
        }
        public int getChildCount() {
            return size();
        }
        public int getIndex(TreeNode node) {
            Enumeration en = elements();
            int ret = 0;
            while (en.hasMoreElements()) {
                if (node == en.nextElement())  return ret;
                ret ++;
            }
            return -1;
        }
        public TreeNode getParent() {
            return (TreeNode)getParentNode();
        }
        public boolean isLeaf() {
            return 0 == size();
        }
    }

    // ================================================

    public static class TreeAttDef extends AttDef implements TreeNode {
        public TreeAttDef(String n) {
            super(n);
        }
        public Enumeration children() {
            return null;
        }
        public boolean getAllowsChildren() {
            return false;
        }
        public TreeNode getChildAt(int childIndex) {
            return null;
        }
        public int getChildCount() {
            return 0;
        }
        public int getIndex(TreeNode node) {
            return -1;
        }
        public TreeNode getParent() {
            return (TreeNode)getParentNode();
        }
        public boolean isLeaf() {
            return true;
        }
    }

    // ================================================

    public static class TreeEntity extends Entity implements TreeNode {
        public TreeEntity(String n, String v, boolean p) {
            super(n, v, p);
        }
        public TreeEntity(String n, ExternalID eid, boolean p, String nd) {
            super(n, eid, p, nd);
        }
        public Enumeration children() {
            return null;
        }
        public boolean getAllowsChildren() {
            return false;
        }
        public TreeNode getChildAt(int childIndex) {
            return null;
        }
        public int getChildCount() {
            return 0;
        }
        public int getIndex(TreeNode node) {
            return -1;
        }
        public TreeNode getParent() {
            return (TreeNode)getParentNode();
        }
        public boolean isLeaf() {
            return true;
        }
    }

    // ================================================

    public static class TreeNotation extends TXNotation implements TreeNode {
        public TreeNotation(String n, ExternalID eid) {
            super(n, eid);
        }
        public Enumeration children() {
            return null;
        }
        public boolean getAllowsChildren() {
            return false;
        }
        public TreeNode getChildAt(int childIndex) {
            return null;
        }
        public int getChildCount() {
            return 0;
        }
        public int getIndex(TreeNode node) {
            return -1;
        }
        public TreeNode getParent() {
            return (TreeNode)getParentNode();
        }
        public boolean isLeaf() {
            return true;
        }
    }
}

