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

package org.apache.xalan.xsltc.runtime.output;

import java.util.Stack;

import org.apache.xalan.xsltc.*;
import org.apache.xalan.xsltc.runtime.*;
import org.apache.xalan.xsltc.runtime.Hashtable;

import org.apache.xalan.xsltc.TransletException;
import org.apache.xalan.xsltc.TransletOutputHandler;
import org.apache.xalan.xsltc.runtime.Hashtable;

public abstract class OutputBase implements TransletOutputHandler, Constants {

    /**
     * Document system identifier
     */
    protected String  _doctypeSystem = null;

    /**
     * Document public identifier
     */
    protected String  _doctypePublic = null;

    /**
     * Holds the current tree depth.
     */
    protected int _depth = 0;

    /**
     * Each entry (prefix) in this hashtable points to a Stack of URIs
     */
    protected 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
     */
    protected Stack _nodeStack;

    /** 
     * The top of this stack is the prefix that was last mapped to an URI
     */
    protected Stack _prefixStack;

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

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

    /**
     * Set to true when a CDATA section is being output.
     */
    protected boolean _cdataTagOpen = false;

    /**
     * Set to true when a start tag is being output.
     */
    protected boolean _startTagOpen  = false;
 
    /**
     * Set to false after processing first element.
     */
    protected boolean _firstElement = true;

    /**
     * Initialize global variables
     */
    protected void initCDATA() {
	// CDATA stack
	_cdataStack = new Stack();
	_cdataStack.push(new Integer(-1)); 	// push dummy value
    }

    protected void initNamespaces() {
	// Namespaces
	_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;
    }

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

    }

    public void setCdataElements(Hashtable elements) { 
	_cdata = elements;
    }

 
   /**
     * 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". In addition, this method 
     * ignores prefixes bound to the empty string "".
     */ 
    protected String patchName(String qname) throws TransletException {
        final int lastColon = qname.lastIndexOf(':');

        if (lastColon > 0) {
            final int firstColon = qname.indexOf(':');
            final String prefix = qname.substring(0, firstColon);
            final String localName = qname.substring(lastColon + 1);

	    // If uri is "" then ignore prefix
            final String uri = lookupNamespace(prefix);
            if (uri != null && uri.length() == 0) {
                return localName;
            }
            else if (firstColon != lastColon) {
                return prefix + ':' + localName;
            }
        }
        return qname;
    }

    /**
     * Declare a prefix to point to a namespace URI
     */
    protected boolean pushNamespace(String prefix, String uri) {
	// Prefixes "xml" and "xmlns" cannot be redefined
	if (prefix.startsWith(XML_PREFIX)) {
	    return false;
	}
	
	Stack stack;
	// Get the stack that contains URIs for the specified prefix
	if ((stack = (Stack)_namespaces.get(prefix)) == null) {
	    _namespaces.put(prefix, stack = new Stack());
	}

	if (!stack.empty() && uri.equals(stack.peek())) {
	    return false;
	}

	stack.push(uri);
	_prefixStack.push(prefix);
	_nodeStack.push(new Integer(_depth));
	return true;
    }

    /**
     * Undeclare the namespace that is currently pointed to by a given prefix
     */
    protected boolean popNamespace(String prefix) {
	// Prefixes "xml" and "xmlns" cannot be redefined
	if (prefix.startsWith(XML_PREFIX)) {
	    return false;
	}

	Stack stack;
	if ((stack = (Stack)_namespaces.get(prefix)) != null) {
	    stack.pop();
	    return true;
	}
	return false;
    }

    /**
     * Pop all namespace definitions that were delcared by the current element
     */
    protected void popNamespaces() {
	while (true) {
	    if (_nodeStack.isEmpty()) return;
	    Integer i = (Integer)(_nodeStack.peek());
	    if (i.intValue() != _depth) return;
	    _nodeStack.pop();
	    popNamespace((String)_prefixStack.pop());
	}
    }

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

    /**
     * Returns the local name of a qualified name. If the name has 
     * no prefix, then it works as the identity (SAX2).
     */
    protected static String getLocalName(String qname) {
        final int col = qname.lastIndexOf(':');
        return (col > 0) ? qname.substring(col + 1) : qname;
    }

    /**
     * Returns the URI of an element or attribute. Note that default namespaces
     * do not apply directly to attributes.
     */
    protected 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;
    }

    public void startCDATA() throws TransletException { }
    public void endCDATA() throws TransletException { }
    public void namespace(String prefix, String uri) throws TransletException { }
    public void setType(int type) { }
    public void setIndent(boolean indent) { }
    public void omitHeader(boolean value) { }
    public boolean setEscaping(boolean escape) throws TransletException { return true; }
    public void setMediaType(String mediaType) { }
    public void setStandalone(String standalone) { }
    public void setVersion(String version) { }
    public void close() { }

}
