/*
 * Copyright (C) 2009 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.
 *     * 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.z
 *     * 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.
 */

#ifndef SKY_ENGINE_PUBLIC_WEB_WEBNODE_H_
#define SKY_ENGINE_PUBLIC_WEB_WEBNODE_H_

#include "../platform/WebCommon.h"
#include "../platform/WebPrivatePtr.h"
#include "../platform/WebString.h"
#include "sky/engine/public/web/WebExceptionCode.h"

namespace blink {

class Node;
class WebDocument;
class WebElement;

// Provides access to some properties of a DOM node.
// Note that the class design requires that neither this class nor any of its subclasses have any virtual
// methods (other than the destructor), so that it is possible to safely static_cast an instance of one
// class to the appropriate subclass based on the actual type of the wrapped blink::Node. For the same
// reason, subclasses must not add any additional data members.
class WebNode {
public:
    virtual ~WebNode() { reset(); }

    WebNode() { }
    WebNode(const WebNode& n) { assign(n); }
    WebNode& operator=(const WebNode& n)
    {
        assign(n);
        return *this;
    }

    BLINK_EXPORT void reset();
    BLINK_EXPORT void assign(const WebNode&);

    BLINK_EXPORT bool equals(const WebNode&) const;
    // Required for using WebNodes in std maps.  Note the order used is
    // arbitrary and should not be expected to have any specific meaning.
    BLINK_EXPORT bool lessThan(const WebNode&) const;

    bool isNull() const { return m_private.isNull(); }

    enum NodeType {
        ElementNode = 1,
        TextNode = 3,
        CDataSectionNode = 4,
        // EntityReferenceNodes are impossible to create in Blink.
        // EntityNodes are impossible to create in Blink.
        ProcessingInstructionsNode = 7,
        CommentNode = 8,
        DocumentNode = 9,
        DocumentTypeNode = 10,
        DocumentFragmentNode = 11,
        // NotationNodes are impossible to create in Blink.
        // XPathNamespaceNodes are impossible to create in Blink.
        ShadowRootNode = 14
    };

    BLINK_EXPORT NodeType nodeType() const;
    BLINK_EXPORT WebNode parentNode() const;
    BLINK_EXPORT WebString nodeName() const;
    BLINK_EXPORT WebDocument document() const;
    BLINK_EXPORT WebNode firstChild() const;
    BLINK_EXPORT WebNode lastChild() const;
    BLINK_EXPORT WebNode previousSibling() const;
    BLINK_EXPORT WebNode nextSibling() const;
    BLINK_EXPORT bool hasChildNodes() const;
    BLINK_EXPORT bool isLink() const;
    BLINK_EXPORT bool isTextNode() const;
    BLINK_EXPORT bool isFocusable() const;
    BLINK_EXPORT bool isContentEditable() const;
    BLINK_EXPORT bool isElementNode() const;
    BLINK_EXPORT void simulateClick();
    BLINK_EXPORT WebElement querySelector(const WebString&, WebExceptionCode&) const;
    BLINK_EXPORT WebElement rootEditableElement() const;
    BLINK_EXPORT bool focused() const;
    BLINK_EXPORT bool remove();

    // Returns true if the node has a non-empty bounding box in layout.
    // This does not 100% guarantee the user can see it, but is pretty close.
    // Note: This method only works properly after layout has occurred.
    BLINK_EXPORT bool hasNonEmptyBoundingBox() const;

    BLINK_EXPORT bool containsIncludingShadowDOM(const WebNode&) const;
    BLINK_EXPORT WebElement shadowHost() const;

    template<typename T> T to()
    {
        T res;
        res.WebNode::assign(*this);
        return res;
    }

    template<typename T> const T toConst() const
    {
        T res;
        res.WebNode::assign(*this);
        return res;
    }

#if BLINK_IMPLEMENTATION
    WebNode(const PassRefPtr<Node>&);
    WebNode& operator=(const PassRefPtr<Node>&);
    operator PassRefPtr<Node>() const;
#endif

#if BLINK_IMPLEMENTATION
    template<typename T> T* unwrap()
    {
        return static_cast<T*>(m_private.get());
    }

    template<typename T> const T* constUnwrap() const
    {
        return static_cast<const T*>(m_private.get());
    }
#endif

protected:
    WebPrivatePtr<Node> m_private;
};

inline bool operator==(const WebNode& a, const WebNode& b)
{
    return a.equals(b);
}

inline bool operator!=(const WebNode& a, const WebNode& b)
{
    return !(a == b);
}

inline bool operator<(const WebNode& a, const WebNode& b)
{
    return a.lessThan(b);
}

} // namespace blink

#endif  // SKY_ENGINE_PUBLIC_WEB_WEBNODE_H_
