/*
 * $Id$
 *
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000 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 "Crimson" 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, Sun Microsystems, Inc., 
 * http://www.sun.com.  For more information on the Apache Software 
 * Foundation, please see <http://www.apache.org/>.
 */

package org.apache.xerces.tree;


import java.io.OutputStreamWriter;
import java.io.OutputStream;
import java.io.Writer;
import java.io.IOException;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;

import org.w3c.dom.*;

import org.xml.sax.SAXException;

//Don't need this looks like.
//import org.apache.crimson.parser.Parser;


/**
 * Class representing a DTD in DOM Level 1; this class exists purely
 * for editor support, and is of dubious interest otherwise.
 *
 * @author David Brownell
 * @version $Revision$
 */
final class Doctype extends NodeBase implements DocumentType
{
    // Stuff generated during parsing ...
    private String	name;
    private Nodemap	entities;
    private Nodemap	notations;

    // ... stuff assigned by apps separately
    private String	publicId;
    private String	systemId;
    private String	internalSubset;


    // package private
    Doctype (String n)
    {
	name = n;
	entities = new Nodemap ();
	notations = new Nodemap ();
    }

    // package private
    Doctype (String pub, String sys, String subset)
    {
	publicId = pub;
	systemId = sys;
	internalSubset = subset;
    }

    // package private
    Doctype(String name, String publicId, String systemId,
            String internalSubset)
    {
        this.name = name;
        this.publicId = publicId;
	this.systemId = systemId;
	this.internalSubset = internalSubset;
    }

    // package private
    void setPrintInfo (String pub, String sys, String subset)
    {
	publicId = pub;
	systemId = sys;
	internalSubset = subset;
    }


    /**
     * Writes out a textual DTD, trusting that any internal subset text
     * is in fact well formed XML.
     */
    public void writeXml (XmlWriteContext context) throws IOException
    {
	Writer	out = context.getWriter ();
	Element	root = getOwnerDocument ().getDocumentElement ();

	out.write ("<!DOCTYPE ");
	out.write (root == null ? "UNKNOWN-ROOT" : root.getNodeName ());

	if (systemId != null) {
	    if (publicId != null) {
		out.write (" PUBLIC '");
		out.write (publicId);
		out.write ("' '");
	    } else
		out.write (" SYSTEM '");
	    out.write (systemId);
	    out.write ("'");
	}
	if (internalSubset != null) {
	    out.write (XmlDocument.eol);
	    out.write ("[");
	    out.write (internalSubset);
	    out.write ("]");
	}
	out.write (">");
	out.write (XmlDocument.eol);
    }

    /** DOM: Returns DOCUMENT_TYPE_NODE */
    public short getNodeType ()
	{ return DOCUMENT_TYPE_NODE; }
    
    /** DOM:  Returns the name declared for the document root node. */
    public String getName ()
	{ return name; }
    
    /** DOM:  Returns the name declared for the document root node. */
    public String getNodeName ()
	{ return name; }
    
    /** DOM: NYI
     * @deprecated Not yet implemented.
     */
    public Node cloneNode (boolean deep)
    {
// XXX
	throw new RuntimeException (getMessage ("DT-000"));
    }

    /**
     * DOM: Returns the internal, external, and unparsed entities
     * declared in this DTD.
     */
    public NamedNodeMap getEntities ()
	{ return entities; }

    /** DOM: Returns the notations declared in this DTD.  */
    public NamedNodeMap getNotations ()
	{ return notations; }
    
    /**
     * The public identifier of the external subset.
     * @since DOM Level 2
     */
    public String getPublicId() {
        return publicId;
    }

    /**
     * The system identifier of the external subset.
     * @since DOM Level 2
     */
    public String getSystemId() {
        return systemId;
    }

    /**
     * The internal subset as a string.
     * @since DOM Level 2
     */
    public String getInternalSubset() {
        return internalSubset;
    }

    // package private
    void setOwnerDocument (XmlDocument doc)
    {
	super.setOwnerDocument (doc);
	if (entities != null)
	    for (int i = 0; entities.item (i) != null; i++)
		((NodeBase)entities.item (i)).setOwnerDocument (doc);
	if (notations != null)
	    for (int i = 0; notations.item (i) != null; i++)
		((NodeBase)notations.item (i)).setOwnerDocument (doc);
    }


    /** Adds a notation node. */
    // package private
    void addNotation (String name, String pub, String sys)
    {
	NotationNode node = new NotationNode (name, pub, sys);
	node.setOwnerDocument ((XmlDocument)getOwnerDocument ());
	notations.setNamedItem (node);
    }

    /**
     * Adds an entity node for an external entity, which
     * could be parsed or unparsed.
     */
    // package private
    void addEntityNode (String name, String pub, String sys, String not)
    {
	EntityNode node = new EntityNode (name, pub, sys, not);
	node.setOwnerDocument ((XmlDocument)getOwnerDocument ());
	entities.setNamedItem (node);
    }

    /** Adds an entity node for an  internal parsed entity. */
    // package private
    void addEntityNode (String name, String value)
    {
	if ("lt".equals (name) || "gt".equals (name)
		|| "apos".equals (name) || "quot".equals (name)
		|| "amp".equals (name))
	    return;	// predeclared, immutable

	EntityNode node = new EntityNode (name, value);
	node.setOwnerDocument ((XmlDocument)getOwnerDocument ());
	entities.setNamedItem (node);
    }

    /** Marks the sets of entities and notations as readonly. */
    // package private
    void setReadonly ()
    {
	entities.readonly = true;
	notations.readonly = true;
    }


    static class NotationNode extends NodeBase implements Notation
    {
	private String	notation;
	private String	publicId;
	private String	systemId;

	NotationNode (String name, String pub, String sys)
	{
	    notation = name;
	    publicId = pub;
	    systemId = sys;
	}

	public String getPublicId ()
	    { return publicId; }

	public String getSystemId ()
	    { return systemId; }
	
	public short getNodeType ()
	    { return NOTATION_NODE; }
	
	public String getNodeName ()
	    { return notation; }
	
	public Node cloneNode (boolean ignored)
	{
	    NotationNode retval;

	    retval = new NotationNode (notation, publicId, systemId);
	    retval.setOwnerDocument ((XmlDocument)getOwnerDocument ());
	    return retval;
	}

	public void writeXml (XmlWriteContext context) throws IOException
	{
	    Writer out = context.getWriter ();
	    out.write ("<!NOTATION ");
	    out.write (notation);
	    if (publicId != null) {
		out.write (" PUBLIC '");
		out.write (publicId);
		if (systemId != null) {
		    out.write ("' '");
		    out.write (systemId);
		}
	    } else {
		out.write (" SYSTEM '");
		out.write (systemId);
	    }
	    out.write ("'>");
	}
    }


    // DOM permits the children to be null ... we do that consistently
    static class EntityNode extends NodeBase implements Entity
    {
	private String	entityName;

	private String	publicId;
	private String	systemId;
	private String	notation;

	private String	value;

	EntityNode (String name, String pub, String sys, String not)
	{
	    entityName = name;
	    publicId = pub;
	    systemId = sys;
	    notation = not;
	}

	EntityNode (String name, String value)
	{
	    entityName = name;
	    this.value = value;
	}

	public String getNodeName ()
	    { return entityName; }
	
	public short getNodeType ()
	    { return ENTITY_NODE; }

	public String getPublicId ()
	    { return publicId; }

	public String getSystemId ()
	    { return systemId; }

	public String getNotationName ()
	    { return notation; }
	
	public Node cloneNode (boolean ignored)
	{
	    EntityNode retval;

	    retval = new EntityNode (entityName, publicId, systemId,
			    notation);
	    retval.setOwnerDocument ((XmlDocument)getOwnerDocument ());
	    return retval;
	}

	public void writeXml (XmlWriteContext context) throws IOException
	{
	    Writer out = context.getWriter ();
	    out.write ("<!ENTITY ");
	    out.write (entityName);

	    if (value == null) {
		if (publicId != null) {
		    out.write (" PUBLIC '");
		    out.write (publicId);
		    out.write ("' '");
		} else
		    out.write (" SYSTEM '");
		out.write (systemId);
		out.write ("'");
		if (notation != null) {
		    out.write (" NDATA ");
		    out.write (notation);
		}
	    } else {
		out.write (" \"");
		int length = value.length ();
		for (int i = 0; i < length; i++) {
		    char c = value.charAt (i);
		    if (c == '"')
			out.write ("&quot;");
		    else
			out.write (c);
		}
		out.write ('"');
	    }
	    out.write (">");
	}
    }

    static class Nodemap implements NamedNodeMap
    {
	// package private
	boolean	readonly;

	// package private
	java.util.Vector	list = new java.util.Vector ();

	// XXX copied from AttributeSet; share implementation!
	public Node getNamedItem (String name)
	{
	    int	length = list.size ();
	    Node	value;

	    for (int i = 0; i < length; i++) {
		value = item (i);
		if (value.getNodeName ().equals (name))
		    return value;
	    }
	    return null;
	}

        /**
         * <b>DOM2:</b>
         */
        public Node getNamedItemNS(String namespaceURI, String localName) {
            return null;
        }
        
	// XXX copied from AttributeSet; share implementation!
	public int getLength ()
	{
	    return list.size ();
	}

	// XXX copied from AttributeSet; share implementation!
	public Node item (int index)
	{
	    if (index < 0 || index >= list.size ())
		return null;
	    return (Node) list.elementAt (index);
	}


	public Node removeNamedItem (String name)
	throws DOMException
	{
	    throw new DomEx (DOMException.NO_MODIFICATION_ALLOWED_ERR);
	}

        /**
         * <b>DOM2:</b>
         */
        public Node removeNamedItemNS(String namespaceURI, String localName)
            throws DOMException
        {
	    throw new DomEx(DOMException.NO_MODIFICATION_ALLOWED_ERR);
        }

	// caller guarantees (e.g. from parser) uniqueness
	public Node setNamedItem (Node item) throws DOMException
	{
	    if (readonly)
		throw new DomEx (DOMException.NO_MODIFICATION_ALLOWED_ERR);
	    list.addElement (item);
	    return null;
	}

        /**
         * <b>DOM2:</b>
         */
        public Node setNamedItemNS(Node arg) throws DOMException {
            if (readonly) {
                throw new DomEx(DomEx.NO_MODIFICATION_ALLOWED_ERR);
            }

            list.addElement(arg);
            return null;
        }

    }
}
