/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS 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 COPYRIGHT
 * OWNER OR 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.
 */

#include "config.h"
#include "core/dom/NodeRenderingTraversal.h"

#include "core/dom/shadow/ComposedTreeWalker.h"
#include "core/rendering/RenderObject.h"

namespace blink {

namespace NodeRenderingTraversal {

void ParentDetails::didTraverseInsertionPoint(const InsertionPoint* insertionPoint)
{
    if (!m_insertionPoint) {
        m_insertionPoint = insertionPoint;
    }
}

ContainerNode* parent(const Node* node, ParentDetails* details)
{
    ASSERT(node);
    ASSERT(!node->document().childNeedsDistributionRecalc());
    if (isActiveInsertionPoint(*node))
        return 0;
    ComposedTreeWalker walker(node, ComposedTreeWalker::CanStartFromShadowBoundary);
    return toContainerNode(walker.traverseParent(walker.get(), details));
}

bool contains(const ContainerNode* container, const Node* node)
{
    while (node) {
        if (node == container)
            return true;
        node = NodeRenderingTraversal::parent(node);
    }
    return false;
}

Node* nextSibling(const Node* node)
{
    ComposedTreeWalker walker(node);
    walker.nextSibling();
    return walker.get();
}

Node* previousSibling(const Node* node)
{
    ComposedTreeWalker walker(node);
    walker.previousSibling();
    return walker.get();
}

static Node* lastChild(const Node* node)
{
    ComposedTreeWalker walker(node);
    walker.lastChild();
    return walker.get();
}

static Node* firstChild(const Node* node)
{
    ComposedTreeWalker walker(node);
    walker.firstChild();
    return walker.get();
}

Node* previous(const Node* node, const Node* stayWithin)
{
    if (node == stayWithin)
        return 0;

    if (Node* previousNode = previousSibling(node)) {
        while (Node* previousLastChild = lastChild(previousNode))
            previousNode = previousLastChild;
        return previousNode;
    }
    return parent(node);
}

Node* next(const Node* node, const Node* stayWithin)
{
    if (Node* child = firstChild(node))
        return child;
    if (node == stayWithin)
        return 0;
    if (Node* nextNode = nextSibling(node))
        return nextNode;
    for (Node* parentNode = parent(node); parentNode; parentNode = parent(parentNode)) {
        if (parentNode == stayWithin)
            return 0;
        if (Node* nextNode = nextSibling(parentNode))
            return nextNode;
    }
    return 0;
}

RenderObject* nextSiblingRenderer(const Node* node)
{
    for (Node* sibling = NodeRenderingTraversal::nextSibling(node); sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) {
        if (RenderObject* renderer = sibling->renderer())
            return renderer;
    }
    return 0;
}

RenderObject* previousSiblingRenderer(const Node* node)
{
    for (Node* sibling = NodeRenderingTraversal::previousSibling(node); sibling; sibling = NodeRenderingTraversal::previousSibling(sibling)) {
        if (RenderObject* renderer = sibling->renderer())
            return renderer;
    }
    return 0;
}

}

} // namespace
