#ifndef TreeScopeEventContext_h
#define TreeScopeEventContext_h
#include "core/dom/Node.h"
#include "core/dom/NodeList.h"
#include "core/dom/TreeScope.h"
#include "core/events/EventTarget.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
namespace WebCore {
class EventPath;
class EventTarget;
class Node;
class TouchEventContext;
class TreeScope;
class TreeScopeEventContext : public RefCounted<TreeScopeEventContext> {
public:
    static PassRefPtr<TreeScopeEventContext> create(TreeScope&);
    ~TreeScopeEventContext();
    TreeScope& treeScope() const { return m_treeScope; }
    EventTarget* target() const { return m_target.get(); }
    void setTarget(PassRefPtr<EventTarget>);
    EventTarget* relatedTarget() const { return m_relatedTarget.get(); }
    void setRelatedTarget(PassRefPtr<EventTarget>);
    TouchEventContext* touchEventContext() const { return m_touchEventContext.get(); }
    TouchEventContext* ensureTouchEventContext();
    PassRefPtr<NodeList> ensureEventPath(EventPath&);
    bool isInclusiveAncestorOf(const TreeScopeEventContext&);
    void addChild(TreeScopeEventContext& child) { m_children.append(&child); }
    
    
    int calculatePrePostOrderNumber(int orderNumber);
private:
    TreeScopeEventContext(TreeScope&);
#ifndef NDEBUG
    bool isUnreachableNode(EventTarget&);
#endif
    TreeScope& m_treeScope;
    RefPtr<EventTarget> m_target;
    RefPtr<EventTarget> m_relatedTarget;
    RefPtr<NodeList> m_eventPath;
    RefPtrWillBePersistent<TouchEventContext> m_touchEventContext;
    Vector<TreeScopeEventContext*> m_children;
    int m_preOrder;
    int m_postOrder;
};
#ifndef NDEBUG
inline bool TreeScopeEventContext::isUnreachableNode(EventTarget& target)
{
    
    return target.toNode() && !target.toNode()->isSVGElement() && !target.toNode()->treeScope().isInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(m_treeScope);
}
#endif
inline void TreeScopeEventContext::setTarget(PassRefPtr<EventTarget> target)
{
    ASSERT(target);
    ASSERT(!isUnreachableNode(*target));
    m_target = target;
}
inline void TreeScopeEventContext::setRelatedTarget(PassRefPtr<EventTarget> relatedTarget)
{
    ASSERT(relatedTarget);
    ASSERT(!isUnreachableNode(*relatedTarget));
    m_relatedTarget = relatedTarget;
}
inline bool TreeScopeEventContext::isInclusiveAncestorOf(const TreeScopeEventContext& other)
{
    ASSERT(m_preOrder != -1 && m_postOrder != -1 && other.m_preOrder != -1 && other.m_postOrder != -1);
    return m_preOrder <= other.m_preOrder && other.m_postOrder <= m_postOrder;
}
}
#endif