/*
 * 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.
 */

/*
 * $Id: DOMNodeIteratorImpl.cpp 568078 2007-08-21 11:43:25Z amassari $
 */

//////////////////////////////////////////////////////////////////////
// DOMNodeIteratorImpl.cpp: implementation of the DOMNodeIteratorImpl class.
//
//////////////////////////////////////////////////////////////////////

#include "DOMNodeIteratorImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMException.hpp>

XERCES_CPP_NAMESPACE_BEGIN

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

DOMNodeIteratorImpl::DOMNodeIteratorImpl (DOMDocument* doc,
                                    DOMNode* root,
                                    unsigned long whatToShow,
                                    DOMNodeFilter* nodeFilter,
                                    bool expandEntityRef)
:   fRoot(root),
    fDocument(doc),
    fWhatToShow(whatToShow),
    fNodeFilter(nodeFilter),
    fExpandEntityReferences(expandEntityRef),
    fDetached(false),
    fCurrentNode(0),
    fForward(true)    
{
	
}


DOMNodeIteratorImpl::DOMNodeIteratorImpl ( const DOMNodeIteratorImpl& toCopy)
    : DOMNodeIterator(toCopy),
    fRoot(toCopy.fRoot),
    fDocument(toCopy.fDocument),
    fWhatToShow(toCopy.fWhatToShow),
    fNodeFilter(toCopy.fNodeFilter),
    fExpandEntityReferences(toCopy.fExpandEntityReferences),
    fDetached(toCopy.fDetached),
    fCurrentNode(toCopy.fCurrentNode),
    fForward(toCopy.fForward)
{
}


DOMNodeIteratorImpl& DOMNodeIteratorImpl::operator= (const DOMNodeIteratorImpl& other) {
    fRoot                   = other.fRoot;
    fCurrentNode            = other.fRoot;
    fWhatToShow             = other.fWhatToShow;
    fNodeFilter             = other.fNodeFilter;
    fForward                = other.fForward;
    fDetached               = other.fDetached;
    fExpandEntityReferences = other.fExpandEntityReferences;
    fDocument               = other.fDocument;
    return *this;
}

DOMNodeIteratorImpl::~DOMNodeIteratorImpl ()
{
	fDetached = false;
}


void DOMNodeIteratorImpl::detach ()
{
	fDetached = true;
   ((DOMDocumentImpl *)fDocument)->removeNodeIterator(this);
}


DOMNode* DOMNodeIteratorImpl::getRoot() {
    return fRoot;
}


// Implementation Note: Note that the iterator looks at whatToShow
// and filter values at each call, and therefore one _could_ add
// setters for these values and alter them while iterating!

/** Return the whatToShow value */

unsigned long DOMNodeIteratorImpl::getWhatToShow () {
    return fWhatToShow;
}


/** Return the filter */

DOMNodeFilter* DOMNodeIteratorImpl::getFilter () {
    return fNodeFilter;
}

/** Get the expandEntity reference flag. */
bool DOMNodeIteratorImpl::getExpandEntityReferences()
{
    return fExpandEntityReferences;
}

/** Return the next DOMNode* in the Iterator. The node is the next node in
 *  depth-first order which also passes the filter, and whatToShow.
 *  A 0 return means either that
 */

DOMNode* DOMNodeIteratorImpl::nextNode () {
	if (fDetached)
		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);

    // if root is 0 there is no next node->
    if (!fRoot)
			return 0;

    DOMNode* aNextNode = fCurrentNode;
    bool accepted = false; // the next node has not been accepted.

    while (!accepted) {

        // if last direction is not forward, repeat node->
        if (!fForward && (aNextNode != 0)) {
            //System.out.println("nextNode():!fForward:"+fCurrentNode.getNodeName());
            aNextNode = fCurrentNode;
        } else {
        // else get the next node via depth-first
            aNextNode = nextNode(aNextNode, true);
        }

        fForward = true; //REVIST: should direction be set forward before 0 check?

        // nothing in the list. return 0.
        if (!aNextNode) return 0;

        // does node pass the filters and whatToShow?
        accepted = acceptNode(aNextNode);
        if (accepted) {
            // if so, then the node is the current node->
            fCurrentNode = aNextNode;
            return fCurrentNode;
        }
    }

    // no nodes, or no accepted nodes.
    return 0;
}


/** Return the previous Node in the Iterator. The node is the next node in
 *  _backwards_ depth-first order which also passes the filter, and whatToShow.
 */

DOMNode* DOMNodeIteratorImpl::previousNode () {
	if (fDetached)
		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);
		
    // if the root is 0, or the current node is 0, return 0.
    if (!fRoot || !fCurrentNode) return 0;

    DOMNode* aPreviousNode = fCurrentNode;
    bool accepted = false;

    while (!accepted) {

        if (fForward && (aPreviousNode != 0)) {
            //repeat last node->
            aPreviousNode = fCurrentNode;
        } else {
            // get previous node in backwards depth first order.
            aPreviousNode = previousNode(aPreviousNode);
        }

        // we are going backwards
        fForward = false;

        // if the new previous node is 0, we're at head or past the root,
        // so return 0.
        if (!aPreviousNode) return 0;

        // check if node passes filters and whatToShow.
        accepted = acceptNode(aPreviousNode);
        if (accepted) {
            // if accepted, update the current node, and return it.
            fCurrentNode = aPreviousNode;
            return fCurrentNode;
        }
    }
    // there are no nodes?
    return 0;
}


/** The node is accepted if it passes the whatToShow and the filter. */
bool DOMNodeIteratorImpl::acceptNode (DOMNode* node) {
	if (fDetached)
		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);

    if (fNodeFilter == 0) {
        return ((fWhatToShow & (1 << (node->getNodeType() - 1))) != 0);
    } else {
        return ((fWhatToShow & (1 << (node->getNodeType() - 1))) != 0)
            && fNodeFilter->acceptNode(node) == DOMNodeFilter::FILTER_ACCEPT;
    }
}


/** Return node, if matches or any parent if matches. */
DOMNode* DOMNodeIteratorImpl::matchNodeOrParent (DOMNode* node) {

    for (DOMNode* n = fCurrentNode; n != fRoot; n = n->getParentNode()) {
        if (node == n) return n;
    }

    return 0;
}


/** The method nextNode(DOMNode, bool) returns the next node
 *  from the actual DOM tree.
 *
 *  The bool visitChildren determines whether to visit the children.
 *  The result is the nextNode.
 */

DOMNode* DOMNodeIteratorImpl::nextNode (DOMNode* node, bool visitChildren) {
	if (fDetached)
		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);

    if (!node) return fRoot;

    DOMNode* result = 0;
    // only check children if we visit children.
    if (visitChildren) {
        //if hasChildren, return 1st child.
        if ((fExpandEntityReferences || node->getNodeType()!=DOMNode::ENTITY_REFERENCE_NODE) && 
            node->hasChildNodes()) {
            result = node->getFirstChild();
            return result;
        }
    }

    // if hasSibling, return sibling
    if (node != fRoot) {
        result = node->getNextSibling();
        if (result != 0) return result;


        // return parent's 1st sibling.
        DOMNode* parent = node->getParentNode();
        while ((parent != 0) && parent != fRoot) {
            result = parent->getNextSibling();
            if (result != 0) {
                return result;
            } else {
                parent = parent->getParentNode();
            }

        } // while (parent != 0 && parent != fRoot) {
    }
    // end of list, return 0
    return 0;
}


/** The method previousNode(DOMNode) returns the previous node
 *  from the actual DOM tree.
 */

DOMNode* DOMNodeIteratorImpl::previousNode (DOMNode* node) {
	if (fDetached)
		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);

    DOMNode* result = 0;

    // if we're at the root, return 0.
    if (node == fRoot)
			return 0;

    // get sibling
    result = node->getPreviousSibling();
    if (!result) {
        //if 1st sibling, return parent
        result = node->getParentNode();
        return result;
    }

    // if sibling has children, keep getting last child of child.
    if (result->hasChildNodes()) {
        while ((fExpandEntityReferences || result->getNodeType()!=DOMNode::ENTITY_REFERENCE_NODE) && 
               result->hasChildNodes()) {
            result = result->getLastChild();
        }
    }

    return result;
}


/** Fix-up the iterator on a remove. Called by DOM or otherwise,
 *  before an actual DOM remove.
 */

void DOMNodeIteratorImpl::removeNode (DOMNode* node) {
	if (fDetached)
		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);

    // Implementation note: Fix-up means setting the current node properly
    // after a remove.

    if (!node) return;

    DOMNode* deleted = matchNodeOrParent(node);

    if (!deleted) return;

    if (fForward) {
        fCurrentNode = previousNode(deleted);
    } else
    // if (!fForward)
    {
        DOMNode* next = nextNode(deleted, false);
        if (next != 0) {
            // normal case: there _are_ nodes following this in the iterator.
            fCurrentNode = next;
        } else {
            // the last node in the iterator is to be removed,
            // so we set the current node to be the previous one.
            fCurrentNode = previousNode(deleted);
            fForward = true;
        }

    }

}


void DOMNodeIteratorImpl::release()
{
    detach();

    // for performance reason, do not recycle pointer
    // chance that this is allocated again and again is not usual
}

XERCES_CPP_NAMESPACE_END

