/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2003 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 "Xalan" 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, Lotus
 * Development Corporation., http://www.lotus.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.apache.xalan.serialize;

import java.util.Stack;

import java.io.Writer;
import java.io.IOException;

import java.util.Hashtable;
import java.util.Vector;
import java.util.Properties;
import java.util.BitSet;

import org.xml.sax.*;

import org.apache.xml.utils.BoolStack;
import org.apache.xml.utils.Trie;
import org.apache.xml.utils.FastStringBuffer;
import org.apache.xalan.res.XSLMessages;
import org.apache.xpath.res.XPATHErrorResources;
import org.apache.xml.utils.StringToIntTable;
import org.apache.xalan.templates.OutputProperties;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;

/**
 * <meta name="usage" content="general"/>
 * SerializerToHTML formats SAX-style events into XML.
 */
public class SerializerToHTML extends SerializerToXML
{

  /** State stack to keep track of if the current element has output 
   *  escaping disabled. */
  protected BoolStack m_isRawStack = new BoolStack();

  /** True if the current element is a block element.  (seems like 
   *  this needs to be a stack. -sb). */
  private boolean m_inBlockElem = false;

  /**
   * Map that tells which XML characters should have special treatment, and it
   *  provides character to entity name lookup.
   */
  protected static CharInfo m_htmlcharInfo =
    new CharInfo(CharInfo.HTML_ENTITIES_RESOURCE);

  /** A digital search trie for fast, case insensitive lookup of ElemDesc objects. */
  static Trie m_elementFlags = new Trie();

  static
  {

    // HTML 4.0 loose DTD
    m_elementFlags.put("BASEFONT", new ElemDesc(0 | ElemDesc.EMPTY));
    m_elementFlags.put("FRAME",
                       new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
    m_elementFlags.put("FRAMESET", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("NOFRAMES", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("ISINDEX",
                       new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
    m_elementFlags.put("APPLET",
                       new ElemDesc(0 | ElemDesc.WHITESPACESENSITIVE));
    m_elementFlags.put("CENTER", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("DIR", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("MENU", new ElemDesc(0 | ElemDesc.BLOCK));

    // HTML 4.0 strict DTD
    m_elementFlags.put("TT", new ElemDesc(0 | ElemDesc.FONTSTYLE));
    m_elementFlags.put("I", new ElemDesc(0 | ElemDesc.FONTSTYLE));
    m_elementFlags.put("B", new ElemDesc(0 | ElemDesc.FONTSTYLE));
    m_elementFlags.put("BIG", new ElemDesc(0 | ElemDesc.FONTSTYLE));
    m_elementFlags.put("SMALL", new ElemDesc(0 | ElemDesc.FONTSTYLE));
    m_elementFlags.put("EM", new ElemDesc(0 | ElemDesc.PHRASE));
    m_elementFlags.put("STRONG", new ElemDesc(0 | ElemDesc.PHRASE));
    m_elementFlags.put("DFN", new ElemDesc(0 | ElemDesc.PHRASE));
    m_elementFlags.put("CODE", new ElemDesc(0 | ElemDesc.PHRASE));
    m_elementFlags.put("SAMP", new ElemDesc(0 | ElemDesc.PHRASE));
    m_elementFlags.put("KBD", new ElemDesc(0 | ElemDesc.PHRASE));
    m_elementFlags.put("VAR", new ElemDesc(0 | ElemDesc.PHRASE));
    m_elementFlags.put("CITE", new ElemDesc(0 | ElemDesc.PHRASE));
    m_elementFlags.put("ABBR", new ElemDesc(0 | ElemDesc.PHRASE));
    m_elementFlags.put("ACRONYM", new ElemDesc(0 | ElemDesc.PHRASE));
    m_elementFlags.put("SUP",
                       new ElemDesc(0 | ElemDesc.SPECIAL
                                    | ElemDesc.ASPECIAL));
    m_elementFlags.put("SUB",
                       new ElemDesc(0 | ElemDesc.SPECIAL
                                    | ElemDesc.ASPECIAL));
    m_elementFlags.put("SPAN",
                       new ElemDesc(0 | ElemDesc.SPECIAL
                                    | ElemDesc.ASPECIAL));
    m_elementFlags.put("BDO",
                       new ElemDesc(0 | ElemDesc.SPECIAL
                                    | ElemDesc.ASPECIAL));
    m_elementFlags.put("BR",
                       new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL
                                    | ElemDesc.EMPTY | ElemDesc.BLOCK));
    m_elementFlags.put("BODY", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("ADDRESS",
                       new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.BLOCKFORM
                                    | ElemDesc.BLOCKFORMFIELDSET));
    m_elementFlags.put("DIV",
                       new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.BLOCKFORM
                                    | ElemDesc.BLOCKFORMFIELDSET));
    m_elementFlags.put("A", new ElemDesc(0 | ElemDesc.SPECIAL));
    m_elementFlags.put("MAP",
                       new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL
                                    | ElemDesc.BLOCK));
    m_elementFlags.put("AREA",
                       new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
    m_elementFlags.put("LINK",
                       new ElemDesc(0 | ElemDesc.HEADMISC | ElemDesc.EMPTY
                                    | ElemDesc.BLOCK));
    m_elementFlags.put("IMG",
                       new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL
                                    | ElemDesc.EMPTY
                                    | ElemDesc.WHITESPACESENSITIVE));
    m_elementFlags.put("OBJECT",
                       new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL
                                    | ElemDesc.HEADMISC
                                    | ElemDesc.WHITESPACESENSITIVE));
    m_elementFlags.put("PARAM", new ElemDesc(0 | ElemDesc.EMPTY));
    m_elementFlags.put("HR",
                       new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.BLOCKFORM
                                    | ElemDesc.BLOCKFORMFIELDSET
                                    | ElemDesc.EMPTY));
    m_elementFlags.put("P",
                       new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.BLOCKFORM
                                    | ElemDesc.BLOCKFORMFIELDSET));
    m_elementFlags.put("H1",
                       new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
    m_elementFlags.put("H2",
                       new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
    m_elementFlags.put("H3",
                       new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
    m_elementFlags.put("H4",
                       new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
    m_elementFlags.put("H5",
                       new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
    m_elementFlags.put("H6",
                       new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
    m_elementFlags.put("PRE",
                       new ElemDesc(0 | ElemDesc.PREFORMATTED
                                    | ElemDesc.BLOCK));
    m_elementFlags.put("Q",
                       new ElemDesc(0 | ElemDesc.SPECIAL
                                    | ElemDesc.ASPECIAL));
    m_elementFlags.put("BLOCKQUOTE",
                       new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.BLOCKFORM
                                    | ElemDesc.BLOCKFORMFIELDSET));
    m_elementFlags.put("INS", new ElemDesc(0));
    m_elementFlags.put("DEL", new ElemDesc(0));
    m_elementFlags.put("DL",
                       new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.BLOCKFORM
                                    | ElemDesc.BLOCKFORMFIELDSET));
    m_elementFlags.put("DT", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("DD", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("OL",
                       new ElemDesc(0 | ElemDesc.LIST | ElemDesc.BLOCK));
    m_elementFlags.put("UL",
                       new ElemDesc(0 | ElemDesc.LIST | ElemDesc.BLOCK));
    m_elementFlags.put("LI", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("FORM", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("LABEL", new ElemDesc(0 | ElemDesc.FORMCTRL));
    m_elementFlags.put("INPUT",
                       new ElemDesc(0 | ElemDesc.FORMCTRL
                                    | ElemDesc.INLINELABEL | ElemDesc.EMPTY));
    m_elementFlags.put("SELECT",
                       new ElemDesc(0 | ElemDesc.FORMCTRL
                                    | ElemDesc.INLINELABEL));
    m_elementFlags.put("OPTGROUP", new ElemDesc(0));
    m_elementFlags.put("OPTION", new ElemDesc(0));
    m_elementFlags.put("TEXTAREA",
                       new ElemDesc(0 | ElemDesc.FORMCTRL
                                    | ElemDesc.INLINELABEL));
    m_elementFlags.put("FIELDSET",
                       new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.BLOCKFORM));
    m_elementFlags.put("LEGEND", new ElemDesc(0));
    m_elementFlags.put("BUTTON",
                       new ElemDesc(0 | ElemDesc.FORMCTRL
                                    | ElemDesc.INLINELABEL));
    m_elementFlags.put("TABLE",
                       new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.BLOCKFORM
                                    | ElemDesc.BLOCKFORMFIELDSET));
    m_elementFlags.put("CAPTION", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("THEAD", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("TFOOT", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("TBODY", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("COLGROUP", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("COL",
                       new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
    m_elementFlags.put("TR", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("TH", new ElemDesc(0));
    m_elementFlags.put("TD", new ElemDesc(0));
    m_elementFlags.put("HEAD",
                       new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.HEADELEM));
    m_elementFlags.put("TITLE", new ElemDesc(0 | ElemDesc.BLOCK));
    m_elementFlags.put("BASE",
                       new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
    m_elementFlags.put("META",
                       new ElemDesc(0 | ElemDesc.HEADMISC | ElemDesc.EMPTY
                                    | ElemDesc.BLOCK));
    m_elementFlags.put("STYLE",
                       new ElemDesc(0 | ElemDesc.HEADMISC | ElemDesc.RAW
                                    | ElemDesc.BLOCK));
    m_elementFlags.put("SCRIPT",
                       new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL
                                    | ElemDesc.HEADMISC | ElemDesc.RAW));
    m_elementFlags.put("NOSCRIPT",
                       new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.BLOCKFORM
                                    | ElemDesc.BLOCKFORMFIELDSET));
    m_elementFlags.put("HTML", new ElemDesc(0 | ElemDesc.BLOCK));

    // From "John Ky" <hand@syd.speednet.com.au
    // Transitional Document Type Definition ()
    // file:///C:/Documents%20and%20Settings/sboag.BOAG600E/My%20Documents/html/sgml/loosedtd.html#basefont
    m_elementFlags.put("FONT", new ElemDesc(0 | ElemDesc.FONTSTYLE));

    // file:///C:/Documents%20and%20Settings/sboag.BOAG600E/My%20Documents/html/present/graphics.html#edef-STRIKE
    m_elementFlags.put("S", new ElemDesc(0 | ElemDesc.FONTSTYLE));
    m_elementFlags.put("STRIKE", new ElemDesc(0 | ElemDesc.FONTSTYLE));

    // file:///C:/Documents%20and%20Settings/sboag.BOAG600E/My%20Documents/html/present/graphics.html#edef-U
    m_elementFlags.put("U", new ElemDesc(0 | ElemDesc.FONTSTYLE));

    // From "John Ky" <hand@syd.speednet.com.au
    m_elementFlags.put("NOBR", new ElemDesc(0 | ElemDesc.FONTSTYLE));
    
     // HTML 4.0, section 16.5
     m_elementFlags.put("IFRAME",
                                        new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.BLOCKFORM
                                                                     | ElemDesc.BLOCKFORMFIELDSET));
     // NS4 extensions
     m_elementFlags.put("LAYER",
                                        new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.BLOCKFORM
                                                                     | ElemDesc.BLOCKFORMFIELDSET));
     m_elementFlags.put("ILAYER",
                                        new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.BLOCKFORM
                                                                     | ElemDesc.BLOCKFORMFIELDSET));
  
    ElemDesc elemDesc;

    elemDesc = (ElemDesc) m_elementFlags.get("AREA");

    elemDesc.setAttr("HREF", ElemDesc.ATTRURL);
    elemDesc.setAttr("NOHREF", ElemDesc.ATTREMPTY);

    elemDesc = (ElemDesc) m_elementFlags.get("BASE");

    elemDesc.setAttr("HREF", ElemDesc.ATTRURL);

    elemDesc = (ElemDesc) m_elementFlags.get("BLOCKQUOTE");

    elemDesc.setAttr("CITE", ElemDesc.ATTRURL);

    elemDesc = (ElemDesc) m_elementFlags.get("Q");

    elemDesc.setAttr("CITE", ElemDesc.ATTRURL);

    elemDesc = (ElemDesc) m_elementFlags.get("INS");

    elemDesc.setAttr("CITE", ElemDesc.ATTRURL);

    elemDesc = (ElemDesc) m_elementFlags.get("DEL");

    elemDesc.setAttr("CITE", ElemDesc.ATTRURL);

    elemDesc = (ElemDesc) m_elementFlags.get("A");

    elemDesc.setAttr("HREF", ElemDesc.ATTRURL);
    elemDesc.setAttr("NAME", ElemDesc.ATTRURL);
    
    elemDesc = (ElemDesc) m_elementFlags.get("LINK");
    elemDesc.setAttr("HREF", ElemDesc.ATTRURL);

    elemDesc = (ElemDesc) m_elementFlags.get("INPUT");

    elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
    elemDesc.setAttr("USEMAP", ElemDesc.ATTRURL);
    elemDesc.setAttr("CHECKED", ElemDesc.ATTREMPTY);
    elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
    elemDesc.setAttr("ISMAP", ElemDesc.ATTREMPTY);
    elemDesc.setAttr("READONLY", ElemDesc.ATTREMPTY);

    elemDesc = (ElemDesc) m_elementFlags.get("SELECT");

    elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
    elemDesc.setAttr("MULTIPLE", ElemDesc.ATTREMPTY);

    elemDesc = (ElemDesc) m_elementFlags.get("OPTGROUP");

    elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);

    elemDesc = (ElemDesc) m_elementFlags.get("OPTION");

    elemDesc.setAttr("SELECTED", ElemDesc.ATTREMPTY);
    elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);

    elemDesc = (ElemDesc) m_elementFlags.get("TEXTAREA");

    elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
    elemDesc.setAttr("READONLY", ElemDesc.ATTREMPTY);

    elemDesc = (ElemDesc) m_elementFlags.get("BUTTON");

    elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);

    elemDesc = (ElemDesc) m_elementFlags.get("SCRIPT");

    elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
    elemDesc.setAttr("FOR", ElemDesc.ATTRURL);
    elemDesc.setAttr("DEFER", ElemDesc.ATTREMPTY);

    elemDesc = (ElemDesc) m_elementFlags.get("IMG");

    elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
    elemDesc.setAttr("LONGDESC", ElemDesc.ATTRURL);
    elemDesc.setAttr("USEMAP", ElemDesc.ATTRURL);
    elemDesc.setAttr("ISMAP", ElemDesc.ATTREMPTY);

    elemDesc = (ElemDesc) m_elementFlags.get("OBJECT");

    elemDesc.setAttr("CLASSID", ElemDesc.ATTRURL);
    elemDesc.setAttr("CODEBASE", ElemDesc.ATTRURL);
    elemDesc.setAttr("DATA", ElemDesc.ATTRURL);
    elemDesc.setAttr("ARCHIVE", ElemDesc.ATTRURL);
    elemDesc.setAttr("USEMAP", ElemDesc.ATTRURL);
    elemDesc.setAttr("DECLARE", ElemDesc.ATTREMPTY);

    elemDesc = (ElemDesc) m_elementFlags.get("FORM");

    elemDesc.setAttr("ACTION", ElemDesc.ATTRURL);

    elemDesc = (ElemDesc) m_elementFlags.get("HEAD");

    elemDesc.setAttr("PROFILE", ElemDesc.ATTRURL);

    // Attribution to: "Voytenko, Dimitry" <DVoytenko@SECTORBASE.COM>
    elemDesc = (ElemDesc) m_elementFlags.get("FRAME");

    elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
    elemDesc.setAttr("LONGDESC", ElemDesc.ATTRURL);
 
    // HTML 4.0, section 16.5
    elemDesc = (ElemDesc) m_elementFlags.get("IFRAME");
 
    elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
    elemDesc.setAttr("LONGDESC", ElemDesc.ATTRURL);
 
    // NS4 extensions
    elemDesc = (ElemDesc) m_elementFlags.get("LAYER");
 
    elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
 
    elemDesc = (ElemDesc) m_elementFlags.get("ILAYER");
 
    elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
 
    elemDesc = (ElemDesc) m_elementFlags.get("DIV");

    elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
  }

  /**
   * Dummy element for elements not found.
   */
  static private ElemDesc m_dummy = new ElemDesc(0 | ElemDesc.BLOCK);

  /** True if URLs should be specially escaped with the %xx form. */
  private boolean m_specialEscapeURLs = true;

  /** True if the META tag should be omitted. */
  private boolean m_omitMetaTag = false;

  /**
   * Tells if the formatter should use special URL escaping.
   *
   * @param bool True if URLs should be specially escaped with the %xx form.
   */
  public void setSpecialEscapeURLs(boolean bool)
  {
    m_specialEscapeURLs = bool;
  }

  /**
   * Tells if the formatter should omit the META tag.
   *
   * @param bool True if the META tag should be omitted.
   */
  public void setOmitMetaTag(boolean bool)
  {
    m_omitMetaTag = bool;
  }

  /**
   * Specifies an output format for this serializer. It the
   * serializer has already been associated with an output format,
   * it will switch to the new format. This method should not be
   * called while the serializer is in the process of serializing
   * a document.
   *
   * @param format The output format to use
   */
  public void setOutputFormat(Properties format)
  {

    m_specialEscapeURLs =
      OutputProperties.getBooleanProperty(OutputProperties.S_USE_URL_ESCAPING,
                                          format);

    m_omitMetaTag =
      OutputProperties.getBooleanProperty(OutputProperties.S_OMIT_META_TAG,
                                          format);
                            
    super.setOutputFormat(format);
  }

  /**
   * Tells if the formatter should use special URL escaping.
   *
   * @return True if URLs should be specially escaped with the %xx form.
   */
  public boolean getSpecialEscapeURLs()
  {
    return m_specialEscapeURLs;
  }

  /**
   * Tells if the formatter should omit the META tag.
   *
   * @return True if the META tag should be omitted.
   */
  public boolean getOmitMetaTag()
  {
    return m_omitMetaTag;
  }

  /**
   * Get a description of the given element.
   *
   * @param name non-null name of element, case insensitive.
   *
   * @return non-null reference to ElemDesc, which may be m_dummy if no 
   *         element description matches the given name.
   */
  ElemDesc getElemDesc(String name)
  {

    if (null != name)
    {
      Object obj = m_elementFlags.get(name);

      if (null != obj)
        return (ElemDesc) obj;
    }

    return m_dummy;
  }

  /**
   * Default constructor.
   */
  public SerializerToHTML()
  {

    super();
    m_charInfo = m_htmlcharInfo;
  }

  /** The name of the current element. */
  private String m_currentElementName = null;

  /**
   * Receive notification of the beginning of a document.
   *
   * @throws org.xml.sax.SAXException Any SAX exception, possibly
   *            wrapping another exception.
   *
   * @throws org.xml.sax.SAXException
   */
  public void startDocument() throws org.xml.sax.SAXException
  {

    m_needToOutputDocTypeDecl = true;
    m_startNewLine = false;
    m_shouldNotWriteXMLHeader = true;

    if (true == m_needToOutputDocTypeDecl)
    {
      if ((null != m_doctypeSystem) || (null != m_doctypePublic))
      {
        accum("<!DOCTYPE HTML");

        if (null != m_doctypePublic)
        {
          accum(" PUBLIC \"");
          accum(m_doctypePublic);
          accum("\"");
        }

        if (null != m_doctypeSystem)
        {
          if (null == m_doctypePublic)
            accum(" SYSTEM \"");
          else
            accum(" \"");

          accum(m_doctypeSystem);
          accum("\"");
        }

        accum(">");
        outputLineSep();
      }
    }

    m_needToOutputDocTypeDecl = false;
  }

  /**
   *  Receive notification of the beginning of an element.
   *
   *
   *  @param namespaceURI
   *  @param localName
   *  @param name The element type name.
   *  @param atts The attributes attached to the element, if any.
   *  @throws org.xml.sax.SAXException Any SAX exception, possibly
   *             wrapping another exception.
   *  @see #endElement
   *  @see org.xml.sax.AttributeList
   */
  public void startElement(
          String namespaceURI, String localName, String name, Attributes atts)
            throws org.xml.sax.SAXException
  {
    // System.out.println("SerializerToHTML#startElement("+namespaceURI+", "+localName+", "+name+", ...);");

    if (null != namespaceURI && namespaceURI.length() > 0)
    {
      super.startElement(namespaceURI, localName, name, atts);

      return;
    }

    boolean savedDoIndent = m_doIndent;
    boolean noLineBreak;

    writeParentTagEnd();
    pushState(
      namespaceURI, localName,
      m_cdataSectionNames, m_cdataSectionStates);

    // pushState(namespaceURI, localName, m_format.getNonEscapingElements(),
    //          m_disableOutputEscapingStates);
    ElemDesc elemDesc = getElemDesc(name);

    // ElemDesc parentElemDesc = getElemDesc(m_currentElementName);
    boolean isBlockElement = elemDesc.is(ElemDesc.BLOCK);
    boolean isHeadElement = elemDesc.is(ElemDesc.HEADELEM);

    // boolean isWhiteSpaceSensitive = elemDesc.is(ElemDesc.WHITESPACESENSITIVE);
    if (m_ispreserve)
      m_ispreserve = false;
    else if (m_doIndent && (null != m_currentElementName)
             && (!m_inBlockElem || isBlockElement)

    /* && !isWhiteSpaceSensitive */
    )
    {
      m_startNewLine = true;

      indent(m_currentIndent);
    }

    m_inBlockElem = !isBlockElement;

    m_isRawStack.push(elemDesc.is(ElemDesc.RAW));

    m_currentElementName = name;

    // m_parents.push(m_currentElementName);
    this.accum('<');
    this.accum(name);

    int nAttrs = atts.getLength();

    for (int i = 0; i < nAttrs; i++)
    {
      processAttribute(atts.getQName(i), elemDesc, atts.getValue(i));
    }

    // Flag the current element as not yet having any children.
    openElementForChildren();

    m_currentIndent += this.m_indentAmount;
    m_isprevtext = false;
    m_doIndent = savedDoIndent;

    if (isHeadElement)
    {
      writeParentTagEnd();

      if (!m_omitMetaTag)
      {
        if (m_doIndent)
          indent(m_currentIndent);

        accum(
          "<META http-equiv=\"Content-Type\" content=\"text/html; charset=");

        // String encoding = Encodings.getMimeEncoding(m_encoding).toLowerCase();
        String encoding = Encodings.getMimeEncoding(m_encoding);

        accum(encoding);
        accum('"');
        accum('>');
      }
    }
  }

  /**
   *  Receive notification of the end of an element.
   *
   *
   *  @param namespaceURI
   *  @param localName
   *  @param name The element type name
   *  @throws org.xml.sax.SAXException Any SAX exception, possibly
   *             wrapping another exception.
   */
  public void endElement(String namespaceURI, String localName, String name)
          throws org.xml.sax.SAXException
  {
    // System.out.println("SerializerToHTML#endElement("+namespaceURI+", "+localName+", "+name+");");
    if (null != namespaceURI && namespaceURI.length() > 0)
    {
      super.endElement(namespaceURI, localName, name);

      return;
    }

    m_currentIndent -= this.m_indentAmount;

    boolean hasChildNodes = childNodesWereAdded();

    // System.out.println(m_currentElementName);
    // m_parents.pop();
    m_isRawStack.pop();

    ElemDesc elemDesc = getElemDesc(name);

    // ElemDesc parentElemDesc = getElemDesc(m_currentElementName);
    boolean isBlockElement = elemDesc.is(ElemDesc.BLOCK);
    boolean shouldIndent = false;

    if (m_ispreserve)
    {
      m_ispreserve = false;
    }
    else if (m_doIndent && (!m_inBlockElem || isBlockElement))
    {
      m_startNewLine = true;
      shouldIndent = true;

      // indent(m_currentIndent);
    }

    m_inBlockElem = !isBlockElement;

    if (hasChildNodes)
    {
      if (shouldIndent)
        indent(m_currentIndent);

      this.accum("</");
      this.accum(name);
      this.accum('>');

      m_currentElementName = name;
    }
    else
    {
      if (!elemDesc.is(ElemDesc.EMPTY))
      {
        this.accum('>');

        // As per Dave/Paul recommendation 12/06/2000
        // if (shouldIndent)
        //  indent(m_currentIndent);

        this.accum('<');
        this.accum('/');
        this.accum(name);
        this.accum('>');
      }
      else
      {
        this.accum('>');
      }
    }

    if (elemDesc.is(ElemDesc.WHITESPACESENSITIVE))
      m_ispreserve = true;

    if (hasChildNodes)
    {
      if (!m_preserves.isEmpty())
        m_preserves.pop();
    }

    m_isprevtext = false;

    // m_disableOutputEscapingStates.pop();
    m_cdataSectionStates.pop();
  }

  /**
   * Process an attribute.
   * @param   name   The name of the attribute.
   * @param elemDesc non-null reference to the owning element description.
   * @param   value   The value of the attribute.
   *
   * @throws org.xml.sax.SAXException
   */
  protected void processAttribute(
          String name, ElemDesc elemDesc, String value)
            throws org.xml.sax.SAXException
  {

    this.accum(' ');

    if (((value.length() == 0) || value.equalsIgnoreCase(name))
            && elemDesc.isAttrFlagSet(name, ElemDesc.ATTREMPTY))
    {
      this.accum(name);
    }
    else
    {
      this.accum(name);
      this.accum('=');

      this.accum('\"');
      if (elemDesc.isAttrFlagSet(name, ElemDesc.ATTRURL))
        writeAttrURI(value, m_specialEscapeURLs);
      else
        writeAttrString(value, this.m_encoding);
      this.accum('\"');

    }
  }
  
  /**
   * Tell if a character is an ASCII digit.
   */
   private boolean isASCIIDigit(char c)
   {
      return (c >= '0' && c <= '9');
   }
   
 /**
  * Make an integer into an HH hex value.
  * Does no checking on the size of the input, since this 
  * is only meant to be used locally by writeAttrURI.
  * 
  * @param i must be a value less than 255.
  * 
  * @return should be a two character string.
  */
  private String makeHHString(int i)
  {
    String s = Integer.toHexString(i).toUpperCase();
    if(s.length() == 1)
    {
      s = "0"+s;
    }
    return s;
  }
    
  /**
  * Dmitri Ilyin: Makes sure if the String is HH encoded sign.
  * @param str must be 2 characters long
  *
  * @return true or false
  */
  private boolean isHHSign(String str) 
  {
    boolean sign = true;  
    try {
      char r = (char)Integer.parseInt(str,16);
    } catch (NumberFormatException e) {
      sign = false;  
    }
    return sign;
  }
  
  /**
   * Write the specified <var>string</var> after substituting non ASCII characters,
   * with <CODE>%HH</CODE>, where HH is the hex of the byte value.
   *
   * @param   string      String to convert to XML format.
   * @param doURLEscaping True if we should try to encode as 
   *                      per http://www.ietf.org/rfc/rfc2396.txt.
   *
   * @throws org.xml.sax.SAXException if a bad surrogate pair is detected.
   */
  public void writeAttrURI(String string, boolean doURLEscaping)
          throws org.xml.sax.SAXException
  {
    // http://www.ietf.org/rfc/rfc2396.txt says:
    // A URI is always in an "escaped" form, since escaping or unescaping a
    // completed URI might change its semantics.  Normally, the only time
    // escape encodings can safely be made is when the URI is being created
    // from its component parts; each component may have its own set of
    // characters that are reserved, so only the mechanism responsible for
    // generating or interpreting that component can determine whether or
    // not escaping a character will change its semantics. Likewise, a URI
    // must be separated into its components before the escaped characters
    // within those components can be safely decoded.
    //
    // ...So we do our best to do limited escaping of the URL, without 
    // causing damage.  If the URL is already properly escaped, in theory, this 
    // function should not change the string value.

    char[] stringArray = string.toCharArray();
    int len = stringArray.length;
        
    for (int i = 0; i < len; i++)
    {
      char ch = stringArray[i];

      if ((ch < 32) || (ch > 126))
      {
        if (doURLEscaping)
        {
          // Encode UTF16 to UTF8.
          // Reference is Unicode, A Primer, by Tony Graham.
          // Page 92.
          
          // Note that Kay doesn't escape 0x20...
          //  if(ch == 0x20) // Not sure about this... -sb
          //  {
          //    accum(ch);
          //  }
          //  else 
          if(ch <= 0x7F)
          {
            accum('%');
            accum(makeHHString(ch));          
          }
          else if(ch <= 0x7FF)
          {
            // Clear low 6 bits before rotate, put high 4 bits in low byte, 
            // and set two high bits.
            int high = (ch >> 6) | 0xC0;  
            int low = (ch & 0x3F) | 0x80; // First 6 bits, + high bit
            accum('%');
            accum(makeHHString(high));
            accum('%');
            accum(makeHHString(low));
          }
          else if( isUTF16Surrogate(ch) ) // high surrogate
          {
            // I'm sure this can be done in 3 instructions, but I choose 
            // to try and do it exactly like it is done in the book, at least 
            // until we are sure this is totally clean.  I don't think performance 
            // is a big issue with this particular function, though I could be 
            // wrong.  Also, the stuff below clearly does more masking than 
            // it needs to do.
            
            // Clear high 6 bits.
            int highSurrogate = ((int) ch) & 0x03FF;
            
            // Middle 4 bits (wwww) + 1
            // "Note that the value of wwww from the high surrogate bit pattern
            // is incremented to make the uuuuu bit pattern in the scalar value 
            // so the surrogate pair don't address the BMP."
            int wwww = ((highSurrogate & 0x03C0) >> 6);
            int uuuuu = wwww+1;  
            
            // next 4 bits
            int zzzz = (highSurrogate & 0x003C) >> 2;
            
            // low 2 bits
            int yyyyyy = ((highSurrogate & 0x0003) << 4) & 0x30;
            
            // Get low surrogate character.
            ch = stringArray[++i];
            
            // Clear high 6 bits.
            int lowSurrogate = ((int) ch) & 0x03FF;
            
            // put the middle 4 bits into the bottom of yyyyyy (byte 3)
            yyyyyy = yyyyyy | ((lowSurrogate & 0x03C0) >> 6);
            
            // bottom 6 bits.
            int xxxxxx = (lowSurrogate & 0x003F);
            
            int byte1 = 0xF0 | (uuuuu >> 2); // top 3 bits of uuuuu
            int byte2 = 0x80 | (((uuuuu & 0x03) << 4) & 0x30) | zzzz;
            int byte3 = 0x80 | yyyyyy;
            int byte4 = 0x80 | xxxxxx;
            
            accum('%');
            accum(makeHHString(byte1));
            accum('%');
            accum(makeHHString(byte2));
            accum('%');
            accum(makeHHString(byte3));
            accum('%');
            accum(makeHHString(byte4));
          }
          else 
          {
            int high = (ch >> 12) | 0xE0; // top 4 bits
            int middle = ((ch & 0x0FC0) >> 6) | 0x80; // middle 6 bits
            int low = (ch & 0x3F) | 0x80; // First 6 bits, + high bit
            accum('%');
            accum(makeHHString(high));
            accum('%');
            accum(makeHHString(middle));
            accum('%');
            accum(makeHHString(low));
          }

        }
        else if (canConvert(ch))
        {
          accum(ch);
        }
        else
        {
          accum("&#");
          accum(Integer.toString(ch));
          accum(';');
        }
      }
      else if('%' == ch)
      {
        // If the character is a '%' number number, try to avoid double-escaping.
        // There is a question if this is legal behavior.
          
// Dmitri Ilyin: to check if '%' number number is invalid. It must be checked if %xx is a sign, that would be encoded
// The encoded signes are in Hex form. So %xx my be in form %3C that is "<" sign. I will try to change here a little.
          
//        if( ((i+2) < len) && isASCIIDigit(stringArray[i+1]) && isASCIIDigit(stringArray[i+2]) )
        
// We are no longer escaping '%'
       /* if ( ((i+2) < len) && isHHSign(new String(stringArray,i+1,2)) )
        {
          accum(ch);
        }
        else
        {
          if (doURLEscaping)
          {
           accum('%');
           accum(makeHHString(ch));
          }
          else*/
            accum(ch);
       // }   
               
      } 
      // Since http://www.ietf.org/rfc/rfc2396.txt refers to the URI grammar as
      // not allowing quotes in the URI proper syntax, nor in the fragment 
      // identifier, we believe that it's OK to double escape quotes.
      else if (ch == '"')
      {
        // Mike Kay encodes this as &#34;, so he may know something I don't?
        if (doURLEscaping)
          accum("%22");
        else
          accum("&quot;"); // we have to escape this, I guess.
      }
      else
      {
        accum(ch);
      }
    }
              
  }

  /**
   * Writes the specified <var>string</var> after substituting <VAR>specials</VAR>,
   * and UTF-16 surrogates for character references <CODE>&amp;#xnn</CODE>.
   *
   * @param   string      String to convert to XML format.
   * @param   encoding    CURRENTLY NOT IMPLEMENTED.
   *
   * @throws org.xml.sax.SAXException
   */
  public void writeAttrString(String string, String encoding)
          throws org.xml.sax.SAXException
  {

    final char chars[] = string.toCharArray();
    final int strLen = chars.length;

    for (int i = 0; i < strLen; i++)
    {
      char ch = chars[i];

      // System.out.println("SPECIALSSIZE: "+SPECIALSSIZE);
      // System.out.println("ch: "+(int)ch);
      // System.out.println("m_maxCharacter: "+(int)m_maxCharacter);
      // System.out.println("m_attrCharsMap[ch]: "+(int)m_attrCharsMap[ch]);
      if (canConvert(ch) && (!m_charInfo.isSpecial(ch)))
      {
        accum(ch);
      }
      else if ('<' == ch || '>' == ch)
      {
        accum(ch);  // no escaping in this case, as specified in 15.2
      }
      else if (('&' == ch) && ((i + 1) < strLen) && ('{' == chars[i + 1]))
      {
        accum(ch);  // no escaping in this case, as specified in 15.2
      }
      else
      {
        int pos = accumDefaultEntity(ch, i, chars, strLen, false);

        if (i != pos)
        {
          i = pos - 1;
        }
        else
        {
          if (isUTF16Surrogate(ch))
          {
            try
            {
              i = writeUTF16Surrogate(ch, chars, i, strLen);
            }
            catch(IOException ioe)
            {
              throw new SAXException(ioe);
            }
          }

          // The next is kind of a hack to keep from escaping in the case 
          // of Shift_JIS and the like.

          /*
          else if ((ch < m_maxCharacter) && (m_maxCharacter == 0xFFFF)
          && (ch != 160))
          {
          accum(ch);  // no escaping in this case
          }
          else
          */
          String entityName = m_charInfo.getEntityNameForChar(ch);

          if (null != entityName)
          {
            accum('&');
            accum(entityName);
            accum(';');
          }
          else if (canConvert(ch))
          {
            accum(ch);  // no escaping in this case
          }
          else
          {
            accum("&#");
            accum(Integer.toString(ch));
            accum(';');
          }
        }
      }
    }
  }

  /**
   * Copy an entity into the accumulation buffer.
   *
   * @param s The name of the entity.
   * @param pos unused.
   *
   * @return The pos argument.
   *
   * @throws org.xml.sax.SAXException
   */
  private int copyEntityIntoBuf(String s, int pos)
          throws org.xml.sax.SAXException
  {

    int l = s.length();

    accum('&');

    for (int i = 0; i < l; i++)
    {
      accum(s.charAt(i));
    }

    accum(';');

    return pos;
  }

  /**
   * Receive notification of character data.
   *
   * <p>The Parser will call this method to report each chunk of
   * character data.  SAX parsers may return all contiguous character
   * data in a single chunk, or they may split it into several
   * chunks; however, all of the characters in any single event
   * must come from the same external entity, so that the Locator
   * provides useful information.</p>
   *
   * <p>The application must not attempt to read from the array
   * outside of the specified range.</p>
   *
   * <p>Note that some parsers will report whitespace using the
   * ignorableWhitespace() method rather than this one (validating
   * parsers must do so).</p>
   *
   * @param chars The characters from the XML document.
   * @param start The start position in the array.
   * @param length The number of characters to read from the array.
   * @throws org.xml.sax.SAXException Any SAX exception, possibly
   *            wrapping another exception.
   * @see #ignorableWhitespace
   * @see org.xml.sax.Locator
   *
   * @throws org.xml.sax.SAXException
   */
  public void characters(char chars[], int start, int length)
          throws org.xml.sax.SAXException
  {

    if (m_isRawStack.peekOrFalse())
    {
      try
      {
        writeParentTagEnd();

        m_ispreserve = true;

        if (shouldIndent())
          indent(m_currentIndent);

        // this.accum("<![CDATA[");
        // this.accum(chars, start, length);
        writeNormalizedChars(chars, start, length, false);

        // this.accum("]]>");
        return;
      }
      catch (IOException ioe)
      {
        throw new org.xml.sax.SAXException(
          XSLMessages.createXPATHMessage(
          XPATHErrorResources.ER_OIERROR, null), ioe);  //"IO error", ioe);
      }
    }
    else
    {
      super.characters(chars, start, length);
    }
  }

  /**
   *  Receive notification of cdata.
   *
   *  <p>The Parser will call this method to report each chunk of
   *  character data.  SAX parsers may return all contiguous character
   *  data in a single chunk, or they may split it into several
   *  chunks; however, all of the characters in any single event
   *  must come from the same external entity, so that the Locator
   *  provides useful information.</p>
   *
   *  <p>The application must not attempt to read from the array
   *  outside of the specified range.</p>
   *
   *  <p>Note that some parsers will report whitespace using the
   *  ignorableWhitespace() method rather than this one (validating
   *  parsers must do so).</p>
   *
   *  @param ch The characters from the XML document.
   *  @param start The start position in the array.
   *  @param length The number of characters to read from the array.
   *  @throws org.xml.sax.SAXException Any SAX exception, possibly
   *             wrapping another exception.
   *  @see #ignorableWhitespace
   *  @see org.xml.sax.Locator
   *
   * @throws org.xml.sax.SAXException
   */
  public void cdata(char ch[], int start, int length)
          throws org.xml.sax.SAXException
  {

    if ((null != m_currentElementName)
            && (m_currentElementName.equalsIgnoreCase("SCRIPT")
                || m_currentElementName.equalsIgnoreCase("STYLE")))
    {
      try
      {
        writeParentTagEnd();

        m_ispreserve = true;

        if (shouldIndent())
          indent(m_currentIndent);

        // this.accum(ch, start, length);
        writeNormalizedChars(ch, start, length, true);
      }
      catch (IOException ioe)
      {
        throw new org.xml.sax.SAXException(
          XSLMessages.createXPATHMessage(
          XPATHErrorResources.ER_OIERROR, null), ioe);  //"IO error", ioe);
      }
    }

    /*
    else if(m_stripCData) // should normally always be false
    {
      try
      {
        writeParentTagEnd();
        m_ispreserve = true;
        if (shouldIndent())
          indent(m_currentIndent);
        // this.accum("<![CDATA[");
        this.accum(ch, start, length);
        // this.accum("]]>");
      }
      catch(IOException ioe)
      {
        throw new org.xml.sax.SAXException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_OIERROR, null),ioe); //"IO error", ioe);
      }
    }
    */
    else
    {
      super.cdata(ch, start, length);
    }
  }

  /**
   *  Receive notification of a processing instruction.
   *
   *  @param target The processing instruction target.
   *  @param data The processing instruction data, or null if
   *         none was supplied.
   *  @throws org.xml.sax.SAXException Any SAX exception, possibly
   *             wrapping another exception.
   *
   * @throws org.xml.sax.SAXException
   */
  public void processingInstruction(String target, String data)
          throws org.xml.sax.SAXException
  {

    // Use a fairly nasty hack to tell if the next node is supposed to be 
    // unescaped text.
    if (target.equals(Result.PI_DISABLE_OUTPUT_ESCAPING))
    {
      startNonEscaping();
    }
    else if (target.equals(Result.PI_ENABLE_OUTPUT_ESCAPING))
    {
      endNonEscaping();
    }
    else
    {
      writeParentTagEnd();

      if (shouldIndent())
        indent(m_currentIndent);

      this.accum("<?" + target);

      if (data.length() > 0 &&!Character.isSpaceChar(data.charAt(0)))
        this.accum(" ");

      this.accum(data + ">");  // different from XML
      
      // Always output a newline char if not inside of an 
      // element. The whitespace is not significant in that
      // case.
      if (m_elemStack.isEmpty())
         outputLineSep();

      m_startNewLine = true;
    }
  }

  /**
   * Receive notivication of a entityReference.
   *
   * @param name non-null reference to entity name string.
   *
   * @throws org.xml.sax.SAXException
   */
  public void entityReference(String name) throws org.xml.sax.SAXException
  {

    this.accum("&");
    this.accum(name);
    this.accum(";");
  }
}

