/*
 * 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(MUTABLENODEREFLIST_HEADER_GUARD_1357924680)
#define MUTABLENODEREFLIST_HEADER_GUARD_1357924680



// Base include file.  Must be first.
#include <xalanc/XPath/XPathDefinitions.hpp>



#include <xalanc/XPath/NodeRefList.hpp>



namespace XALAN_CPP_NAMESPACE {



class XPathExecutionContext;
class XalanDocument;
class XalanNodeList;



/**
 * Local implementation of MutableNodeRefList.  This class is for internal use
 * only.
 */
class XALAN_XPATH_EXPORT MutableNodeRefList : public NodeRefList
{
public:

    /**
     * Construct an empty mutable node list.
     */
    explicit
    MutableNodeRefList(MemoryManager& theManager);

    static MutableNodeRefList*
    create(MemoryManager& theManager);
    /**
     * Construct a mutable node list from another list.
     * 
     * @param theSource source list
     */
    MutableNodeRefList(const MutableNodeRefList&    theSource,
                        MemoryManager& theManager);

    /**
     * Construct a mutable node list from another list.
     * 
     * @param theSource  source list
     */
    explicit
    MutableNodeRefList(const NodeRefListBase&   theSource,
                        MemoryManager& theManager);

    virtual
    ~MutableNodeRefList();

    MutableNodeRefList&
    operator=(const MutableNodeRefList&     theRHS);

    MutableNodeRefList&
    operator=(const NodeRefList&        theRHS);

    MutableNodeRefList&
    operator=(const NodeRefListBase&    theRHS);

    MutableNodeRefList&
    operator=(const XalanNodeList*  theRHS);

    /**
     * Add a node at to the list.
     * 
     * @param n node to add
     */
    void
    addNode(XalanNode*  n);

    /**
     * Insert a node at a given position.
     * 
     * @param n   node to insert
     * @param pos position of insertion
     */
    void
    insertNode(
            XalanNode*  n,
            size_type   pos);

    /**
     * Remove a node from the list.
     * 
     * @param n   node to insert
     */
    void
    removeNode(const XalanNode*     n);

    /**
     * Remove a node from the list.
     * 
     * @param pos position of node in list
     */
    void
    removeNode(size_type    pos);

    /**
     * Remove all nodes.
     */
    void
    clear();

    /**
     * Set a item.
     * 
     * @param pos position of node to modify
     * @param n   node to insert, default is empty node
     */
    void
    setNode(
            size_type   pos,
            XalanNode*  n = 0);

    /**
     * Copy NodeList members into this nodelist, adding in document order.  If
     * a node is null, don't add it.
     * 
     * @param nodelist node list to add
     */
    void
    addNodes(const XalanNodeList&   nodelist);

    /**
     * Copy NodeList members into this nodelist, adding in document order.  If
     * a node is null, don't add it.
     * 
     * @param nodelist node list to add
     */
    void
    addNodes(const NodeRefListBase&     nodelist);

    /**
     * Copy NodeList members into this nodelist, adding in document order.
     * 
     * @param nodelist node list to add
     * @param executionContext the current execution context
     */
    void
    addNodesInDocOrder(
            const XalanNodeList&    nodelist,
            XPathExecutionContext&  executionContext);
  
    /**
     * Copy NodeList members into this nodelist, adding in document order.
     * 
     * @param nodelist node list to add
     * @param executionContext the current execution context
     */
    void
    addNodesInDocOrder(
            const NodeRefListBase&  nodelist,
            XPathExecutionContext&  executionContext);

    /**
     * Copy NodeList members into this nodelist, adding in document order.
     * 
     * @param nodelist node list to add
     * @param executionContext the current execution context
     */
    void
    addNodesInDocOrder(
            const MutableNodeRefList&   nodelist,
            XPathExecutionContext&      executionContext);
  
    /**
     * Add a node into list where it should occur in document order.
     *
     * @param node node object to add
     * @param executionContext the current execution context
     */
    void
    addNodeInDocOrder(
            XalanNode*              node,
            XPathExecutionContext&  executionContext);

    /**
     * Clear any null entries in the node list.
     */
    void
    clearNulls();

    /**
     * Reverse the nodes in the list.
     */
    void
    reverse();

    /**
     * Reserve space for the supplied number of nodes.
     * This is taken as an optimization, and may be
     * ignored.  You might want to call this when you
     * know the number of nodes you're about to add to
     * this list.
     *
     * Remember to take into account the current size of
     * the list when calling this.  That means you will
     * probably want to add the result of getLength() to
     * the number of nodes you're planning to add.
     *
     * @param theCount the number of nodes to reserve space for
     */
    void
    reserve(size_type   theCount)
    {
        m_nodeList.reserve(theCount);
    }

    /**
     * See if the order of the nodes is an unknown order.
     */
    bool
    getUnknownOrder() const
    {
        return m_order == eUnknownOrder ? true : false;
    }

    void
    setUnknownOrder()
    {
        m_order = eUnknownOrder;
    }

    /**
     * See if the order of the nodes is document order.
     */
    bool
    getDocumentOrder() const
    {
        return m_order == eDocumentOrder ? true : false;
    }

    /**
     * Set the known order of the nodes.  This should
     * only be done when the order is known. Otherwise,
     * disaster will ensue.
     */
    void
    setDocumentOrder()
    {
        m_order = eDocumentOrder;
    }

    /**
     * See if the order of the nodes is reverse document order.
     */
    bool
    getReverseDocumentOrder() const
    {
        return m_order == eReverseDocumentOrder ? true : false;
    }

    /**
     * Set the known order of the nodes.  This should
     * only be done when the order is known. Otherwise,
     * disaster will ensue.
     */
    void
    setReverseDocumentOrder()
    {
        m_order = eReverseDocumentOrder;
    }

    typedef NodeListVectorType::iterator    NodeListIteratorType;

    class addNodeInDocOrderFunctor
    {
    public:

        addNodeInDocOrderFunctor(
                MutableNodeRefList&     theList,
                XPathExecutionContext&  theExecutionContext) :
            m_list(theList),
            m_executionContext(theExecutionContext)
        {
        }

        void
        operator()(XalanNode*   theNode) const
        {
            m_list.addNodeInDocOrder(theNode, m_executionContext);
        }

    private:

        MutableNodeRefList&     m_list;

        XPathExecutionContext&  m_executionContext;
    };

    void
    swap(MutableNodeRefList&    theOther)
    {
        NodeRefList::swap(theOther);

        const eOrder    temp = m_order;

        m_order = theOther.m_order;

        theOther.m_order = temp;
    }

private:
    //not defined
    MutableNodeRefList(const MutableNodeRefList&    theSource);

    // An enum to determine what the order of the nodes is...
    enum eOrder { eUnknownOrder, eDocumentOrder, eReverseDocumentOrder };

    eOrder  m_order;
};

XALAN_USES_MEMORY_MANAGER(MutableNodeRefList)

}



#endif  // MUTABLENODEREFLIST_HEADER_GUARD_1357924680
