/*
 * @(#)$Id$
 *
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001 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) 2001, Sun
 * Microsystems., http://www.sun.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * @author Jacek Ambroziak
 * @author Santiago Pericas-Geertsen
 * @author Morten Jorgensen
 * @author Seth Ford <seth.ford@fmr.com> 
 *
 */

package org.apache.xalan.xsltc.runtime;

import java.io.*;
import java.util.Stack;
import java.util.Enumeration;

import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.AttributesImpl;

import org.apache.xalan.xsltc.*;

public final class TextOutput implements TransletOutputHandler, Constants {

    // These are the various output types we handle
    public static final int UNKNOWN = 0; // determine type from output contents
    public static final int XML     = 1;
    public static final int HTML    = 2;
    public static final int TEXT    = 3;
    public static final int QNAME   = 4;  // no special handling

    // These parameters are set by the <xsl:output> element, or by the
    // get/setOutputProperty() methods in TrAX
    private int	   _outputType = UNKNOWN;
    private String _encoding;
    private String _mediaType = "text/html";
    private String _doctypeSystem = null;
    private String _doctypePublic = null;

    private boolean   _escapeChars = false;
    private boolean   _startTagOpen = false;
    private boolean   _headTagOpen = false;
    private boolean   _cdataTagOpen = false;
    private boolean   _is8859Encoded = false;

    // Contains all elements that should be output as CDATA sections
    private Hashtable _cdata = null;

    private static final char[] AMP      = "&amp;".toCharArray();
    private static final char[] LT       = "&lt;".toCharArray();
    private static final char[] GT       = "&gt;".toCharArray();
    private static final char[] CRLF     = "&#xA;".toCharArray();
    private static final char[] QUOTE    = "&quot;".toCharArray();
    private static final char[] NBSP     = "&nbsp;".toCharArray();

    private static final char[] BEGCDATA = "<![CDATA[".toCharArray();
    private static final char[] ENDCDATA = "]]>".toCharArray();
    private static final char[] CNTCDATA = "]]]]><![CDATA[>".toCharArray();
    private static final char[] BEGCOMM  = "<!--".toCharArray();
    private static final char[] ENDCOMM  = "-->".toCharArray();

    private static final int AMP_length   = AMP.length;
    private static final int LT_length    = LT.length;
    private static final int GT_length    = GT.length;
    private static final int CRLF_length  = CRLF.length;
    private static final int QUOTE_length = QUOTE.length;
    private static final int NBSP_length  = NBSP.length;
    private static final int BEGCOMM_length = BEGCOMM.length;
    private static final int ENDCOMM_length = ENDCOMM.length;

    private static final String HREF_STR        = "href";
    private static final String CITE_STR        = "cite";
    private static final String SRC_STR         = "src";
    private static final String CHAR_ESC_START  = "&#";
    private static final String CDATA_ESC_START = "]]>&#";
    private static final String CDATA_ESC_END   = ";<![CDATA[";

    private AttributesImpl _attributes = new AttributesImpl();
    private String         _elementName = null;

    // Each entry (prefix) in this hashtable points to a Stack of URIs
    private Hashtable _namespaces;
    // The top of this stack contains an id of the element that last declared
    // a namespace. Used to ensure prefix/uri map scopes are closed correctly
    private Stack     _nodeStack;
    // The top of this stack is the prefix that was last mapped to an URI
    private Stack     _prefixStack;

    // The top of this stack contains the QName of the currently open element
    private Stack     _qnameStack;

    // The top of this stack contains the element id of the last element whose
    // contents should be output as CDATA sections.
    private Stack     _cdataStack;

    // Holds the current tree depth (see startElement() and endElement()).
    private int _depth = 0;

    // Reference to the SAX2 handlers that consume this handler's output
    private ContentHandler _saxHandler;
    private LexicalHandler _lexHandler;

    /**
     * Creates a new translet output post-processor
     *
     * @param handler A SAX2 handler to consume the generated SAX events 
     * @throws IOException
     */
    public TextOutput(ContentHandler handler) throws IOException {
        _saxHandler = handler;
        init();
    }

    /**
     * Creates a new translet output post-processor
     *
     * @param handler A SAX2 handler to consume the generated SAX events 
     * @param encoding The default encoding to use (set in <xsl:output>)
     * @throws IOException
     */
    public TextOutput(ContentHandler handler, String encoding)
	throws IOException {
        _saxHandler = handler;
        init();
	_encoding = encoding;
	_is8859Encoded = _encoding.equalsIgnoreCase("iso-8859-1");	
    }

    /**
     * Creates a new translet output post-processor
     *
     * @param handler A SAX2 handler to consume the generated SAX events 
     * @param encoding The default encoding to use (set in <xsl:output>)
     * @throws IOException
     */
    public TextOutput(ContentHandler sax, LexicalHandler lex, String encoding)
	throws IOException {
        _saxHandler = sax;
	_lexHandler = lex;
        init();
	_encoding = encoding;
	_is8859Encoded = _encoding.equalsIgnoreCase("iso-8859-1");	
    }

    /**
     * Initialise global variables
     */
    private void init() throws IOException {
	// Reset all output configuration from <xsl:output>
	_outputType = UNKNOWN;
	_encoding = "UTF-8";
	_mediaType = "text/html";

	// Reset all internal variables and tables
	_escapeChars  = false;
	_startTagOpen = false;
	_cdataTagOpen = false;
	_qnameStack = new Stack();
	_cdataStack = new Stack();
	_cdataStack.push(new Integer(-1)); // push dummy value

	// Reset our internal namespace handling
	initNamespaces();
    }

    /**
     * Closes the output stream
     */
    public void close() {
	if ((_saxHandler != null) &&
	    (_saxHandler instanceof DefaultSAXOutputHandler)) {
	    ((DefaultSAXOutputHandler)_saxHandler).close();
	}
    }

    /**
     * This method is used internally when the output type was initially
     * undefined and the type is set (by this handler) based on the contents
     * of the output. Set the default values for some output paramters.
     */
    private void setTypeInternal(int type) {
	if (type == XML) {
	    _escapeChars = true;
	}
	else if (type == HTML) {
	    setIndent(true);
	    _escapeChars = true;
	}
	setType(type);
    }

    /**
     * Emit header through the SAX handler
     */
    private void emitHeader() throws SAXException {
	// Output HTML header as META element
	if (_outputType == HTML) {
	    AttributeList attrs = new AttributeList();
	    attrs.add("http-equiv", "Content-Type");
	    attrs.add("content", _mediaType+"; charset="+_encoding);
	    _saxHandler.startElement(EMPTYSTRING, EMPTYSTRING, "meta", attrs);
	    _saxHandler.endElement(EMPTYSTRING, EMPTYSTRING, "meta");
	}
    }

    /**
     * This method is called when all the data needed for a call to the
     * SAX handler's startElement() method has been gathered.
     */
    public void closeStartTag() throws TransletException {
	try {
	    _startTagOpen = false;

	    // Now is time to send the startElement event
	    _saxHandler.startElement(getNamespaceURI(_elementName, true),
		getLocalName(_elementName), _elementName, _attributes);

	    // Insert <META> tag directly after <HEAD> element in HTML output
	    if (_headTagOpen) {
		emitHeader();
		_headTagOpen = false;
	    }
	}
	catch (SAXException e) {
	    throw new TransletException(e);
	}
    } 

    /**
     * Turns special character escaping on/off. Note that characters will
     * never, even if this option is set to 'true', be escaped within
     * CDATA sections in output XML documents.
     */
    public boolean setEscaping(boolean escape) throws TransletException {

	// Set output type to XML (the default) if still unknown.
	if (_outputType == UNKNOWN) setTypeInternal(XML);

	// Save old escaping setting (for the return value) and set new value
	boolean oldSetting = _escapeChars;
	_escapeChars = escape;

	// Characters are never escaped in output mode 'text'
	if (_outputType == TEXT) _escapeChars = false; 

	return(oldSetting);
    }

    /**
     * Starts the output document. Outputs the document header if the
     * output type is set to XML.
     */
    public void startDocument() throws TransletException {
        try {
            _saxHandler.startDocument();
	    // Output escaping is _ALWAYS_ enabled for XML output
            if (_outputType == XML) _escapeChars = true;
        } catch (SAXException e) {
            throw new TransletException(e);
        }
    }

    /**
     * Ends the document output.
     */
    public void endDocument() throws TransletException {
        try {
            // Set output type to XML (the default) if still unknown.
            if (_outputType == UNKNOWN) setTypeInternal(XML);

	    // Close any open start tag
	    if (_startTagOpen) closeStartTag();
	    if (_cdataTagOpen) closeCDATA();

	    // Close output document
            _saxHandler.endDocument();
        } catch (SAXException e) {
            throw new TransletException(e);
        }
    }

    /**
     * Utility method - pass a string to the SAX handler's characters() method
     */
    private void characters(String str) throws SAXException {
	final char[] ch = str.toCharArray();
	characters(ch, 0, ch.length);
    }

    /**
     * Utility method - pass a whole character array to the SAX handler
     */
    private void characters(char[] ch) throws SAXException {
	characters(ch, 0, ch.length);
    }

    /**
     * Utility method - pass a whole charactes as CDATA to SAX handler
     */
    private void startCDATA(char[] ch, int off, int len) throws SAXException {
	
	final int limit = off + len;
	int offset = off;

	// Output start bracket - "<![CDATA["
	_saxHandler.characters(BEGCDATA, 0, BEGCDATA.length);

	// Detect any occurence of "]]>" in the character array
	for (int i = offset; i < limit-2; i++) {
	    if (ch[i] == ']' && ch[i+1] == ']' && ch[i+2] == '>') {
		_saxHandler.characters(ch, offset, i - offset);
		_saxHandler.characters(CNTCDATA, 0, CNTCDATA.length);
		offset = i+3;
		i=i+2; // Skip next chars ']' and '>'.
	    }
	}

	// Output the remaining characters
	if (offset < limit) _saxHandler.characters(ch, offset, limit - offset);

	_cdataTagOpen = true;
    }

    private void closeCDATA() throws SAXException {
	// Output closing bracket - "]]>"
	_saxHandler.characters(ENDCDATA, 0, ENDCDATA.length);
	_cdataTagOpen = false;
    }

    /**
     * Send characters to the output document
     */
    public void characters(char[] ch, int off, int len)	
	throws TransletException {
        try {
	    switch(_outputType) {
	    case UNKNOWN: // Set type to XML and fall through
		setTypeInternal(XML);
	    case XML:
		// Close any open start tag
		if (_startTagOpen) closeStartTag();

		// Take special precautions if within a CDATA section. If we
		// encounter the sequence ']]>' within the CDATA, we need to
		// break the section in two and leave the ']]' at the end of
		// the first CDATA and '>' at the beginning of the next. Other
		// special characters/sequences are _NOT_ escaped within CDATA.
		Integer I = (Integer)_cdataStack.peek();
		if ((I.intValue() == _depth) && (!_cdataTagOpen)) {
		    startCDATA(ch, off, len);
		} 
		else if (_escapeChars) {
		    if (_cdataTagOpen) {
			escapeCDATA(ch, off, len);
		    } else {
			escapeCharacters(ch, off, len);
		    }
		} 
		else {
		    _saxHandler.characters(ch, off, len);
		}
		return;

	    case HTML:
		// Close any open start tag
		if (_startTagOpen) closeStartTag();

		// Output escaped characters if required. Non-ASCII characters
		// within HTML attributes should _NOT_ be escaped.
		if (_escapeChars) {
		    if (!_qnameStack.isEmpty()) {
			String qname = (String)_qnameStack.peek();
			qname = qname.toLowerCase();
			if ((qname.equals("style"))||(qname.equals("script"))) {
			    _saxHandler.characters(ch, off, len);
			    return;
			}
		    }
		    escapeCharacters(ch, off, len);
		}
		// Output the chracters as the are
		else {
		    _saxHandler.characters(ch, off, len);
		}
		return;

	    case TEXT:
		_saxHandler.characters(ch, off, len);
		return;
	    }
        }
	catch (SAXException e) {
            throw new TransletException(e);
        }
    }

    /**
     * Start an element in the output document. This might be an XML
     * element (<elem>data</elem> type) or a CDATA section.
     */
    public void startElement(String elementName) throws TransletException {
	try {
	    switch(_outputType) {

	    case UNKNOWN:
		// If we don't know the output type yet we need to examine
		// the very first element to see if it is "html".
		if (elementName.toLowerCase().equals("html"))
		    setTypeInternal(HTML);
		else
		    setTypeInternal(XML);
		startElement(elementName);
		return;

	    case XML:
		// Close any open start tag
		if (_startTagOpen) closeStartTag();
		if (_cdataTagOpen) closeCDATA();

		// Handle document type declaration (for first element only)
		if (_lexHandler != null) {
		    if (_doctypeSystem != null)
			_lexHandler.startDTD(elementName,
					     _doctypePublic,_doctypeSystem);
		    _lexHandler = null;
		}

		_depth++;
		_elementName = elementName;
		_attributes.clear();
		_startTagOpen = true;
		_qnameStack.push(elementName);
		
		if ((_cdata != null) && (_cdata.get(elementName) != null))
		    _cdataStack.push(new Integer(_depth));
		
		return;

	    case HTML:
		// Close any open start tag
		if (_startTagOpen) closeStartTag();

		// Handle document type declaration (for first element only)
		if (_lexHandler != null) {
		    if ((_doctypeSystem != null) || (_doctypePublic != null))
			_lexHandler.startDTD(elementName,
					     _doctypePublic,_doctypeSystem);
		    _lexHandler = null;
		}

		_depth++;
		_elementName = elementName;
		_attributes.clear();
		_startTagOpen = true;
		_qnameStack.push(elementName);

		// Insert <META> tag directly after <HEAD> element in HTML doc
		if (elementName.toLowerCase().equals("head"))
		    _headTagOpen = true;
		return;

	    case TEXT:
		// Do not output element tags if output mode is 'text'
		return;
		
	    }
	}
	catch (SAXException e) {
            throw new TransletException(e);
        }
    }

    /**
     * Utility method - escape special characters and pass to SAX handler
     */
    private void escapeCharacters(char[] ch, int off, int len)
	throws SAXException {

	int limit = off + len;
	int offset = off;

	if (limit > ch.length) limit = ch.length;;


	// Step through characters and escape all special characters
	for (int i = off; i < limit; i++) {
	    char current = ch[i];
	    switch (current) {
	    case '&':
		_saxHandler.characters(ch, offset, i - offset);
		_saxHandler.characters(AMP, 0, AMP_length);
		offset = i + 1;
		break;
	    case '<':
		_saxHandler.characters(ch, offset, i - offset);
		_saxHandler.characters(LT, 0, LT_length);
		offset = i + 1;
		break;
	    case '>':
		_saxHandler.characters(ch, offset, i - offset);
		_saxHandler.characters(GT, 0, GT_length);
		offset = i + 1;
		break;
	    case '\u00a0':
		_saxHandler.characters(ch, offset, i - offset);
		_saxHandler.characters(NBSP, 0, NBSP_length);
		offset = i + 1;
		break;
	    default:
		if ( (current >= '\u007F' && current < '\u00A0') ||
		     (_is8859Encoded && (current > '\u00FF')) )
		{
		    StringBuffer buf = new StringBuffer(CHAR_ESC_START);
		    buf.append(Integer.toString((int)ch[i]));
		    buf.append(';');
		    final String esc = buf.toString();
		    final char[] chars = esc.toCharArray();
		    final int    strlen = esc.length();
		    _saxHandler.characters(ch, offset, i - offset);
		    _saxHandler.characters(chars, 0, strlen);
		    offset = i + 1;
		}
	    }
	}
	// Output remaining characters (that do not need escaping).
	if (offset < limit) _saxHandler.characters(ch, offset, limit - offset);
    }

    /**
     * Utility method - escape special characters and pass to SAX handler
     */
    private void escapeCDATA(char[] ch, int off, int len)
	throws SAXException {

	int limit = off + len;
	int offset = off;

	if (limit > ch.length) limit = ch.length;;

	// Step through characters and escape all special characters
	for (int i = off; i < limit; i++) {
	    if (ch[i] > '\u00ff') {
		StringBuffer buf = new StringBuffer(CDATA_ESC_START);
		buf.append(Integer.toString((int)ch[i]));
		buf.append(CDATA_ESC_END);
		final String esc = buf.toString();
		final char[] chars = esc.toCharArray();
		final int    strlen = esc.length();
		_saxHandler.characters(ch, offset, i - offset);
		_saxHandler.characters(chars, 0, strlen);
		offset = i + 1;
	    }
	}
	// Output remaining characters (that do not need escaping).
	if (offset < limit) _saxHandler.characters(ch, offset, limit - offset);
    }

    /**
     * This method escapes special characters used in attribute values
     */
    private String escapeString(String value) {

	int i;
	char[] ch = value.toCharArray();
	int limit = ch.length;
	int offset = 0;
	StringBuffer buf = new StringBuffer();
	
	for (i = 0; i < limit; i++) {
	    switch (ch[i]) {
	    case '&':
		buf.append(ch, offset, i - offset);
		buf.append(AMP);
		offset = i + 1;
		break;
	    case '"':
		buf.append(ch, offset, i - offset);
		buf.append(QUOTE);
		offset = i + 1;
		break;
	    case '<':
		buf.append(ch, offset, i - offset);
		buf.append(LT);
		offset = i + 1;
		break;
	    case '>':
		buf.append(ch, offset, i - offset);
		buf.append(GT);
		offset = i + 1;
		break;
	    case '\n':
		buf.append(ch, offset, i - offset);
		buf.append(CRLF);
		offset = i + 1;
		break;
	    }
	}
	if (offset < limit) {
	    buf.append(ch, offset, limit - offset);
	}
	return(buf.toString());
    }

    private String makeHHString(int i) {
	String s = Integer.toHexString(i).toUpperCase();
	if (s.length() == 1) {
	    s = "0"+s;
	}
	return s;
    }

    /**
     * This method escapes special characters used in HTML attribute values
     */
    private String escapeAttr(String base) {
	final int len = base.length() - 1;
	final String str = "&quot;";
	int pos;

	char[] ch = base.toCharArray();
	StringBuffer buf = new StringBuffer();
        for(int i=0; i<base.length(); i++){
	    if (ch[i] <= 0x20) {
		buf.append('%');
		buf.append(makeHHString(ch[i]));
	    } 
	    else if (ch[i] > '\u007F') {
		int high = (ch[i] >> 6) | 0xC0;
		int low  = (ch[i] & 0x3F) | 0x80;  // First 6 bits + high bit
		buf.append('%');
		buf.append(makeHHString(high));
		buf.append('%');
		buf.append(makeHHString(low));
	    }
	    else {
		// These chars are reserved or unsafe in URLs
		// pg 196, 'HTML, The Definitive Guide" C. Musciano, et. al
	        switch (ch[i]) {
		    case '\u007F' :
		    case '\u0022' :
		    case '\u007B' :
		    case '\u007D' :
		    case '\u007C' :
		    case '\\'     :
		    case '\t'     :
		    case '\u005E' :
		    case '\u007E' :
		    case '\u005B' :
		    case '\u005D' :
		    case '\u0060' :
		        buf.append('%');
		        buf.append(Integer.toHexString((int)ch[i]));
		        break;
		    case '\u0026' :
			//bug fix for customer/murphy3: buf.append("&amp;");
			buf.append("&");
			break;
		    default:	
		        buf.append(ch[i]); break;
	        }
	    } 
  	}
	base = buf.toString();

	while ((pos = base.indexOf('"')) > -1) {
	    if (pos == 0) {
		final String after = base.substring(1);
		base = str + after;
	    }
	    else if (pos == len) {
		final String before = base.substring(0, pos);
		base = before + str;
	    }
	    else {
		final String before = base.substring(0, pos);
		final String after = base.substring(pos+1);
		base = before + str + after;
	    }
	}
	return base;
    }

    /**
     * Replaces whitespaces in a URL with '%20'
     */
    private String quickAndDirtyUrlEncode(String base) {
	final String pst20 = "%20";
	final int len = base.length() - 1;
	int pos;
	// Slow, very slow indeed
	while ((pos = base.indexOf(' ')) > -1) {
	    if (pos == 0) {
		final String after = base.substring(1);
		base = pst20 + after;
	    }
	    else if (pos == len) {
		final String before = base.substring(0, pos);
		base = before + pst20;
	    }
	    else {
		final String before = base.substring(0, pos);
		final String after = base.substring(pos+1);
		base = before + pst20 + after;
	    }
	}
	return base;
    }

    /**
     * Returns the URI of an element or attribute. Note that default namespaces 
     * do not apply directly to attributes.
     */
    private String getNamespaceURI(String qname, boolean isElement) 
	throws TransletException 
    {
	String uri = EMPTYSTRING;
	int col = qname.lastIndexOf(':');
	final String prefix = (col > 0) ? qname.substring(0, col) : EMPTYSTRING;

	if (prefix != EMPTYSTRING || isElement) { 
	    uri = lookupNamespace(prefix);
	    if (uri == null && !prefix.equals(XMLNS_PREFIX)) {
		BasisLibrary.runTimeError(BasisLibrary.NAMESPACE_PREFIX_ERR,
					  qname.substring(0, col));
	    }
	}
	return uri;
    }

    /**
     * Returns the local name of a qualified name. If the name has no prefix
     * then return null. 
     */
    private static String getLocalName(String qname) throws TransletException {
	final int col = qname.lastIndexOf(':');
	return (col > 0) ? qname.substring(col + 1) : null;
    }

    /**
     * TODO: This method is a HACK! Since XSLTC does not have access to the
     * XML file, it sometimes generates a NS prefix of the form "ns?" for
     * an attribute. If at runtime, when the qname of the attribute is
     * known, another prefix is specified for the attribute, then we can get 
     * a qname of the form "ns?:otherprefix:name". This function patches the 
     * qname by simply ignoring "otherprefix".
     */
    private static String patchQName(String qname) throws TransletException {
	final int lastColon = qname.lastIndexOf(':');
	if (lastColon > 0) {
	    final int firstColon = qname.indexOf(':');
	    if (firstColon != lastColon) {
		return qname.substring(0, firstColon) + qname.substring(lastColon);
	    }
	}
	return qname;
    }

    /**
     * Put an attribute and its value in the start tag of an element.
     * Signal an exception if this is attempted done outside a start tag.
     */
    public void attribute(String name, final String value)
	throws TransletException {

	if (_outputType == TEXT) return;

	final String patchedName = patchQName(name);
	final String localName = getLocalName(patchedName);
	final String uri = getNamespaceURI(patchedName, false);
	final int index = (localName == null) ?
				_attributes.getIndex(name) :	/* don't use patchedName */
				_attributes.getIndex(uri, localName);

	switch(_outputType) {
	case XML:
	    if (!_startTagOpen) {
		BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR, patchedName);
	    }

/*
System.err.println("TextOutput.attribute() uri = " + uri
    + " localname = " + localName
    + " qname = " + name 
    + "\n value = " + value
    + " escapeString(value) = " + escapeString(value));
*/

	    // Output as namespace declaration
	    if (name.startsWith(XMLNS_PREFIX)) {
		namespace(name.length() > 6 ? name.substring(6) : EMPTYSTRING, value);
	    }
	    else {
		if (index >= 0) {	// Duplicate attribute?
		    _attributes.setAttribute(index, uri, localName, patchedName, "CDATA", 
			escapeString(value));	
		}
		else {
		    _attributes.addAttribute(uri, localName, patchedName, "CDATA", 
			escapeString(value));
		}
	    }
	    break;
	case HTML:
	    if (!_startTagOpen) {
		BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR,name);
	    }

	    /* 
	     * The following is an attempt to escape an URL stored in a href
	     * attribute of HTML output. Normally URLs should be encoded at
	     * the time they are created, since escaping or unescaping a
	     * completed URI might change its semantics. We limit or escaping
	     * to include space characters only - and nothing else. This is for
	     * two reasons: (1) performance and (2) we want to make sure that
	     * we do not change the meaning of the URL.
	     */
	    final String tmp = name.toLowerCase();
	    if (tmp.equals(HREF_STR) || tmp.equals(SRC_STR) || tmp.equals(CITE_STR)) {
		if (index >= 0) {
		    _attributes.setAttribute(index, EMPTYSTRING, EMPTYSTRING, name, 
			"CDATA", quickAndDirtyUrlEncode(escapeAttr(value)));
		}
		else {
		    _attributes.addAttribute(EMPTYSTRING, EMPTYSTRING, name, "CDATA",
			quickAndDirtyUrlEncode(escapeAttr(value)));
		}
	    }
	    else {
		if (index >= 0) {
		    _attributes.setAttribute(index, EMPTYSTRING, EMPTYSTRING, 
			name, "CDATA", escapeNonURLAttr(value));
		}
		else {
		    _attributes.addAttribute(EMPTYSTRING, EMPTYSTRING, 
			name, "CDATA", escapeNonURLAttr(value));
		}
	    }
	    break;
	}
    }

    /**
     * Escape non ASCII characters (> u007F) as &#XXX; entities.
     */
    private String escapeNonURLAttr(String base) {
	final int len = base.length() - 1;

	char[] ch = base.toCharArray();
	StringBuffer buf = new StringBuffer();
        for(int i=0; i<base.length(); i++){
	    if (ch[i] > '\u007F') {
	        buf.append(CHAR_ESC_START);
		buf.append(Integer.toString((int)ch[i]));
	        buf.append(';');
	    }
	    else {
	        buf.append(ch[i]); 
	    } 
  	}
	base = buf.toString();
	return base;
    }


    /**
     * End an element or CDATA section in the output document
     */
    public void endElement(String elementName) throws TransletException {
	try {
	    switch(_outputType) {
	    case TEXT:
		// Do not output element tags if output mode is 'text'
		return;
	    case XML:
		// Close any open element
		if (_startTagOpen) closeStartTag();
		if (_cdataTagOpen) closeCDATA();

		final String qname = (String) _qnameStack.pop();
		_saxHandler.endElement(getNamespaceURI(qname, true), 
		    getLocalName(qname), qname);

		popNamespaces();
		if (((Integer)_cdataStack.peek()).intValue() == _depth)
		    _cdataStack.pop();
		_depth--;
		return;
	    case HTML:
		// Close any open element
		if (_startTagOpen) closeStartTag();
		_saxHandler.endElement(EMPTYSTRING, EMPTYSTRING, 
		    (String)(_qnameStack.pop()));
		popNamespaces();
		_depth--;		
		return;
	    }

        } catch (SAXException e) {
            throw new TransletException(e);
        }
    }

    /**
     * Send a HTML-style comment to the output document
     */
    public void comment(String comment) throws TransletException {
	try {
	    // Close any open element before emitting comment
            if (_startTagOpen) closeStartTag();
	    if (_cdataTagOpen) closeCDATA();

            // Set output type to XML (the default) if still unknown.
            if (_outputType == UNKNOWN) setTypeInternal(XML);

            // ...and then output the comment.
            _saxHandler.characters(BEGCOMM, 0, BEGCOMM_length);
            characters(comment);
            _saxHandler.characters(ENDCOMM, 0, ENDCOMM_length);
	}
	catch (SAXException e) {
	    throw new TransletException(e);
	}
    }
    
    /**
     * Send a processing instruction to the output document
     */
    public void processingInstruction(String target, String data)
	throws TransletException {
        try {
	    // Close any open element
	    if (_startTagOpen) closeStartTag();
	    if (_cdataTagOpen) closeCDATA();

	    // Handle document type declaration (only HTML at this point)
	    if ((_lexHandler != null) && (_outputType == HTML)) {
		if ((_doctypeSystem != null) || (_doctypePublic != null))
		    _lexHandler.startDTD("HTML",_doctypePublic,_doctypeSystem);
		_lexHandler = null;
	    }

	    // Pass the processing instruction to the SAX handler
            _saxHandler.processingInstruction(target, data);
        }
	catch (SAXException e) {
            throw new TransletException(e);
        }
    }

    /**
     * Initialize namespace stacks
     */
    private void initNamespaces() {
	_namespaces = new Hashtable();
	_nodeStack = new Stack();
	_prefixStack = new Stack();

	// Define the default namespace (initially maps to "" uri)
	Stack stack;
	_namespaces.put(EMPTYSTRING, stack = new Stack());
	stack.push(EMPTYSTRING);
	_prefixStack.push(EMPTYSTRING);

	_namespaces.put(XML_PREFIX, stack = new Stack());
	stack.push("http://www.w3.org/XML/1998/namespace");
	_prefixStack.push(XML_PREFIX);

	_nodeStack.push(new Integer(-1));
	_depth = 0;
    }

    /**
     * Declare a prefix to point to a namespace URI
     */
    private void pushNamespace(String prefix, String uri) throws SAXException {
	// Prefixes "xml" and "xmlns" cannot be redefined
	if (prefix.equals(XML_PREFIX)) return;
	
	Stack stack;
	// Get the stack that contains URIs for the specified prefix
	if ((stack = (Stack)_namespaces.get(prefix)) == null) {
	    stack = new Stack();
	    _namespaces.put(prefix, stack);
	}
	// Quit now if the URI the prefix currently maps to is the same as this
	if (!stack.empty() && uri.equals(stack.peek())) return;
	// Put this URI on top of the stack for this prefix
	stack.push(uri);

	_prefixStack.push(prefix);
	_nodeStack.push(new Integer(_depth));

	// Inform the SAX handler
	_saxHandler.startPrefixMapping(prefix, escapeString(uri));
    }

    /**
     * Undeclare the namespace that is currently pointed to by a given prefix
     */
    private void popNamespace(String prefix) throws SAXException {
	// Prefixes "xml" and "xmlns" cannot be redefined
	if (prefix.equals(XML_PREFIX)) return;

	Stack stack;
	if ((stack = (Stack)_namespaces.get(prefix)) != null) {
	    stack.pop();
	    _saxHandler.endPrefixMapping(prefix);
	}
    }

    /**
     * Pop all namespace definitions that were delcared by the current element
     */
    private void popNamespaces() throws TransletException {
	try {
	    while (true) {
		if (_nodeStack.isEmpty()) return;
		Integer i = (Integer)(_nodeStack.peek());
		if (i.intValue() != _depth) return;
		_nodeStack.pop();
		popNamespace((String)_prefixStack.pop());
	    }
	}
	catch (SAXException e) {
	    throw new TransletException(e);
	}
    }

    /**
     * Use a namespace prefix to lookup a namespace URI
     */
    private String lookupNamespace(String prefix) {
	final Stack stack = (Stack)_namespaces.get(prefix);
	return stack != null && !stack.isEmpty() ? (String)stack.peek() : null;
    }

    /**
     * Send a namespace declaration in the output document. The namespace
     * declaration will not be include if the namespace is already in scope
     * with the same prefix.
     */
    public void namespace(final String prefix, final String uri)
	throws TransletException {
	try {
	    if (_startTagOpen)
		pushNamespace(prefix, uri);
	    else {
		if ((prefix == EMPTYSTRING) && (uri == EMPTYSTRING)) return;
		BasisLibrary.runTimeError(BasisLibrary.STRAY_NAMESPACE_ERR,
					  prefix, uri);
	    }
	}
	catch (SAXException e) {
	    throw new TransletException(e);
	}
    }

    /************************************************************************
     * The following are all methods for configuring the output settings
     ************************************************************************/
    /**
     * Set the output type. The type must be wither TEXT, XML or HTML.
     */
    public void setType(int type)  {
	try {
	    _outputType = type;
	    if ((_outputType == HTML) || (_outputType == XML))
		_escapeChars = true;
	    if (_encoding == null)
	    	_encoding = "UTF-8";
	    if (_saxHandler instanceof DefaultSAXOutputHandler)
		((DefaultSAXOutputHandler)_saxHandler).setOutputType(type);
	}
	catch (SAXException e) { }
    }

    /**
     * Turns output indentation on/off. Should only be set to on
     * if the output type is XML or HTML.
     */
    public void setIndent(boolean indent) {
	if (_saxHandler instanceof DefaultSAXOutputHandler) {
            ((DefaultSAXOutputHandler)_saxHandler).setIndent(indent);
	}
    } 

    /**
     * Directive to turn xml header declaration  on/off. 
     */
    public void omitHeader(boolean value) {
	if (_saxHandler instanceof DefaultSAXOutputHandler) {
            ((DefaultSAXOutputHandler)_saxHandler).omitHeader(value);
	}
    }

    /**
     * Set the XML output document version - should be 1.0
     */
    public void setVersion(String version) {
	if (_saxHandler instanceof DefaultSAXOutputHandler) {
            ((DefaultSAXOutputHandler)_saxHandler).setVersion(version);
	}
    }

    /**
     * Set the XML standalone attribute - must be "yes" or "no"
     */
    public void setStandalone(String standalone) {
	if (_saxHandler instanceof DefaultSAXOutputHandler) {
            ((DefaultSAXOutputHandler)_saxHandler).setStandalone(standalone);
	}
    }

    /**
     * Set the output document system/public identifiers
     */
    public void setDoctype(String system, String pub) {
	_doctypeSystem = system;
	_doctypePublic = pub;
    }

    /**
     * Set the output media type - only relevant for HTML output
     */
    public void setMediaType(String mediaType) {
	// This value does not have to be passed to the SAX handler. This
	// handler creates the HTML <meta> tag in which the media-type
	// (MIME-type) will be used.
	_mediaType = mediaType;
    }

    /**
     * The <xsl:output method="xml"/> instruction can specify that certain
     * XML elements should be output as CDATA sections. This methods allows
     * the translet to insert these elements into a hashtable of strings.
     * Every output element is looked up in this hashtable before it is
     * output.
     */ 
    public void setCdataElements(Hashtable elements) {
	_cdata = elements;
    }

}
