/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#if !defined(XALAN_RESULTNAMESPACESSTACK_HEADER_GUARD)
#define XALAN_RESULTNAMESPACESSTACK_HEADER_GUARD



// Base include file.  Must be first.
#include <xalanc/XSLT/XSLTDefinitions.hpp>



#include <xalanc/Include/XalanVector.hpp>



#include <xalanc/XalanDOM/XalanDOMString.hpp>



#include <xalanc/XPath/XalanQName.hpp>



namespace XALAN_CPP_NAMESPACE {



class XALAN_XSLT_EXPORT ResultNamespacesStack
{
public:


#if defined(XALAN_USE_DEQUE_FOR_VECTOR_BOOL)
    typedef std::deque<bool>    BoolVectorType;
#else
    typedef XalanVector<bool>       BoolVectorType;
#endif

    typedef XalanQName::NamespaceVectorType     NamespaceVectorType;
    typedef XalanQName::NamespacesStackType     NamespacesStackType;

    typedef NamespacesStackType::size_type      size_type;


    explicit
    ResultNamespacesStack(MemoryManager& theManager);

    ~ResultNamespacesStack();

    void
    addDeclaration(
            const XalanDOMString&   thePrefix,
            const XalanDOMString&   theNamespaceURI)
    {
        addDeclaration(
            thePrefix,
            theNamespaceURI.c_str(),
            theNamespaceURI.length());
    }

    void
    addDeclaration(
            const XalanDOMString&   thePrefix,
            const XalanDOMChar*     theNamespaceURI)
    {
        addDeclaration(
            thePrefix,
            theNamespaceURI,
            length(theNamespaceURI));
    }

    void
    addDeclaration(
            const XalanDOMString&       thePrefix,
            const XalanDOMChar*         theNamespaceURI,
            XalanDOMString::size_type   theLength);

    void
    pushContext();

    void
    popContext();

    const XalanDOMString*
    getNamespaceForPrefix(const XalanDOMString&     thePrefix) const;

    const XalanDOMString*
    getPrefixForNamespace(const XalanDOMString&     theNamespaceURI) const;

    /**
     * See if the prefix has been mapped to a namespace in the current
     * context, without looking down the stack of namespaces.
     */
    bool
    prefixIsPresentLocal(const XalanDOMString&  thePrefix);

    void
    clear();

    size_type
    size() const
    {
        return m_resultNamespaces.size() - 1;
    }

    bool
    empty() const
    {
        return NamespacesStackType::const_iterator(m_stackPosition) == m_resultNamespaces.begin() ? true : false;
    }

private:

    // not implemented
    ResultNamespacesStack(const ResultNamespacesStack&);

    bool
    operator==(const ResultNamespacesStack&) const;

    ResultNamespacesStack&
    operator=(const ResultNamespacesStack&);

    enum { eDefaultCreateNewContextStackSize = 25 };

    /**
     * A stack to keep track of the result tree namespaces.
     */
    NamespacesStackType             m_resultNamespaces;

    NamespacesStackType::iterator   m_stackBegin;

    NamespacesStackType::iterator   m_stackPosition;

    BoolVectorType                  m_createNewContextStack;
};



}



#endif  // XALAN_RESULTNAMESPACESSTACK_HEADER_GUARD
