/*
 * 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 WebElement querySelector(const WebString&, WebExceptionCode&) const;
    BLINK_EXPORT WebElement rootEditableElement() const;
    BLINK_EXPORT bool focused() const;
    BLINK_EXPORT bool remove();

    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_
