/*
 * (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.Child;
import com.ibm.xml.parser.DTD;
import com.ibm.xml.parser.DefaultElementFactory;
import com.ibm.xml.parser.TXAttribute;
import com.ibm.xml.parser.TXCDATASection;
import com.ibm.xml.parser.TXDocument;
import com.ibm.xml.parser.TXElement;
import com.ibm.xml.parser.Util;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Hashtable;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Node;
import org.w3c.dom.NodeIterator;
import org.w3c.dom.Text;

/**
 * <P>A factory for HTML-like printing.
 * Nodes produced by this factory print no XML declaration,
 * no `<KBD>&lt;!DOCTYPE...&gt;</KBD>' and an internal DTD,
 * not `<KBD>/&gt;</KBD>' but `<KBD>&gt;</KBD>' for EMPTY elements
 * (i.e. `<KBD>&lt;BR&gt;</KBD>', `<KBD>&lt;HR&gt;</KBD>').
 * </P>
 * <UL>
 *  <LI>All element names are uppercased
 *  <LI>All attribute names are lowercased
 * </UL>
 *
 * @version 1.1
 * @author TAMURA Kent &lt;kent@trl.ibm.co.jp&gt;
 */
public class XHFactory extends DefaultElementFactory {
    public TXAttribute createAttribute(String name, String value) {
        TXAttribute a = new TXAttribute(name.toLowerCase(), value);
        a.setFactory(this);
        return a;
    }

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

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

    public void printDocument(TXDocument doc, PrintWriter pw, String encoding, int indent) {
        Enumeration en = doc.elements();
        while (en.hasMoreElements()) {
            Child ch = (Child)en.nextElement();
            if (!(ch instanceof DTD))
                ch.print(pw, encoding);
        }
        pw.flush();
    }

    static Hashtable s_empties;
    static {
        s_empties = new Hashtable();
                                // HTML 4.0 strict DTD
        s_empties.put("AREA", "AREA");
        s_empties.put("BASE", "BASE");
        s_empties.put("BR", "BR");
        s_empties.put("COL", "COL");
        s_empties.put("HR", "HR");
        s_empties.put("IMG", "IMG");
        s_empties.put("INPUT", "INPUT");
        s_empties.put("LINK", "LINK");
        s_empties.put("META", "META");
        s_empties.put("PARAM", "PARAM");
                                // HTML 4.0 loose DTD
        s_empties.put("BASEFONT", "BASEFONT");
        s_empties.put("FRAME", "FRAME");
        s_empties.put("ISINDEX", "ISINDEX");
    }
    public void printElement(TXElement el, PrintWriter pw, String encoding, int indent) {
        pw.print("<");
        pw.print(el.getName());
        Enumeration en = el.attributeElements();
        while (en.hasMoreElements()) {
            pw.print(" ");
            pw.print(((TXAttribute)en.nextElement()).toXMLString(encoding));
        }
        pw.print(">");

        if (null != s_empties.get(el.getName()))
            return;                             // This is EMPTY element.

        en = el.elements();
        while (en.hasMoreElements())
            ((Child)en.nextElement()).print(pw, encoding);

        pw.print("</");
        pw.print(el.getName());
        pw.print(">");
    }

    public void printText(Text text, PrintWriter pw, String encoding, int indent) {
        if (text instanceof CDATASection) {
            pw.print(text.getData());
        } else {
            pw.print(Util.backReference(text.getData(), encoding));
        }
    }
}

