/*
 * Copyright (C) 2008-2010, 2013, 2015 Apple Inc. All Rights Reserved.
 * Copyright (C) 2012 Serotek Corporation. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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 "WebKitDLL.h"
#include "AccessibleBase.h"

#include "AccessibleImage.h"
#include "AccessibleTextImpl.h"
#include "WebView.h"
#include <WebCore/AccessibilityListBox.h>
#include <WebCore/AccessibilityMenuListPopup.h>
#include <WebCore/AccessibilityObject.h>
#include <WebCore/AXObjectCache.h>
#include <WebCore/BString.h>
#include <WebCore/Element.h>
#include <WebCore/EventHandler.h>
#include <WebCore/FrameView.h>
#include <WebCore/HostWindow.h>
#include <WebCore/HTMLNames.h>
#include <WebCore/HTMLFrameElementBase.h>
#include <WebCore/HTMLInputElement.h>
#include <WebCore/IntRect.h>
#include <WebCore/NotImplemented.h>
#include <WebCore/PlatformEvent.h>
#include <WebCore/RenderFrame.h>
#include <WebCore/RenderObject.h>
#include <WebCore/RenderView.h>
#include <comutil.h>
#include <oleacc.h>
#include <wtf/RefPtr.h>
#include <wtf/text/StringBuilder.h>

using namespace WebCore;

AccessibleBase::AccessibleBase(AccessibilityObject* obj, HWND window)
    : AccessibilityObjectWrapper(obj)
    , m_window(window)
{
    ASSERT_ARG(obj, obj);
    m_object->setWrapper(this);
    ++gClassCount;
    gClassNameCount().add("AccessibleBase");
}

AccessibleBase::~AccessibleBase()
{
    --gClassCount;
    gClassNameCount().remove("AccessibleBase");
}

AccessibleBase* AccessibleBase::createInstance(AccessibilityObject* obj, HWND window)
{
    ASSERT_ARG(obj, obj);

    if (obj->isImage())
        return new AccessibleImage(obj, window);
    else if (obj->isStaticText() || obj->isTextControl() || (obj->node() && obj->node()->isTextNode()))
        return new AccessibleText(obj, window);

    return new AccessibleBase(obj, window);
}

HRESULT AccessibleBase::QueryService(_In_ REFGUID guidService, _In_ REFIID riid, _COM_Outptr_ void **ppvObject)
{
    if (!IsEqualGUID(guidService, SID_AccessibleComparable)
        && !IsEqualGUID(guidService, IID_IAccessible2_2)
        && !IsEqualGUID(guidService, IID_IAccessible2)
        && !IsEqualGUID(guidService, IID_IAccessibleApplication)
        && !IsEqualGUID(guidService, IID_IAccessible)
        && !IsEqualGUID(guidService, IID_IAccessibleText)
        && !IsEqualGUID(guidService, IID_IAccessibleText2)
        && !IsEqualGUID(guidService, IID_IAccessibleEditableText)) {
        *ppvObject = nullptr;
        return E_INVALIDARG;
    }
    return QueryInterface(riid, ppvObject);
}

// IUnknown
HRESULT AccessibleBase::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    if (IsEqualGUID(riid, __uuidof(IAccessible)))
        *ppvObject = static_cast<IAccessible*>(this);
    else if (IsEqualGUID(riid, __uuidof(IDispatch)))
        *ppvObject = static_cast<IAccessible*>(this);
    else if (IsEqualGUID(riid, __uuidof(IUnknown)))
        *ppvObject = static_cast<IAccessible*>(this);
    else if (IsEqualGUID(riid, __uuidof(IAccessible2_2)))
        *ppvObject = static_cast<IAccessible2_2*>(this);
    else if (IsEqualGUID(riid, __uuidof(IAccessible2)))
        *ppvObject = static_cast<IAccessible2*>(this);
    else if (IsEqualGUID(riid, __uuidof(IAccessibleComparable)))
        *ppvObject = static_cast<IAccessibleComparable*>(this);
    else if (IsEqualGUID(riid, __uuidof(IServiceProvider)))
        *ppvObject = static_cast<IServiceProvider*>(this);
    else if (IsEqualGUID(riid, __uuidof(AccessibleBase)))
        *ppvObject = static_cast<AccessibleBase*>(this);
    else {
        *ppvObject = nullptr;
        return E_NOINTERFACE;
    }
    AddRef();
    return S_OK;
}

ULONG AccessibleBase::Release()
{
    ASSERT(m_refCount > 0);
    if (--m_refCount)
        return m_refCount;
    delete this;
    return 0;
}

// IAccessible2_2
HRESULT AccessibleBase::get_attribute(_In_ BSTR key, _Out_ VARIANT* value)
{
    if (!value)
        return E_POINTER;

    AtomString keyAtom(key, ::SysStringLen(key));

    accessibilityAttributeValue(keyAtom, value);

    return S_OK;
}

HRESULT AccessibleBase::get_accessibleWithCaret(_COM_Outptr_opt_ IUnknown** accessible, _Out_ long* caretOffset)
{
    if (!accessible || !caretOffset)
        return E_POINTER;
    *accessible = nullptr;
    *caretOffset = 0;
    notImplemented();
    return E_NOTIMPL;
}

HRESULT AccessibleBase::get_relationTargetsOfType(_In_ BSTR type, long maxTargets, __deref_out_ecount_full_opt(*nTargets) IUnknown*** targets, _Out_ long* nTargets)
{
    notImplemented();
    return E_NOTIMPL;
}

// IAccessible2
HRESULT AccessibleBase::get_nRelations(_Out_ long* nRelations)
{
    if (!nRelations)
        return E_POINTER;

    if (!m_object)
        return E_FAIL;
    notImplemented();
    *nRelations = 0;
    return S_OK;
}

HRESULT AccessibleBase::get_relation(long relationIndex, _COM_Outptr_opt_ IAccessibleRelation** relation)
{
    if (!relation)
        return E_POINTER;

    *relation = nullptr;

    notImplemented();
    return E_NOTIMPL;
}

HRESULT AccessibleBase::get_relations(long maxRelations, __out_ecount_part(maxRelations, *nRelations)  IAccessibleRelation** relations, _Out_ long* nRelations)
{
    if (!relations || !nRelations)
        return E_POINTER;

    *relations = nullptr;

    notImplemented();
    return E_NOTIMPL;
}

HRESULT AccessibleBase::role(_Out_ long* role)
{
    if (!role)
        return E_POINTER;
    *role = 0;
    if (!m_object)
        return E_FAIL;

    *role = wrapper(m_object)->role();
    return S_OK;
}

HRESULT AccessibleBase::scrollTo(IA2ScrollType scrollType)
{
    if (!m_object)
        return E_FAIL;
    return S_FALSE;
}

HRESULT AccessibleBase::scrollToPoint(IA2CoordinateType coordinateType, long x, long y)
{
    if (!m_object)
        return E_FAIL;
    return S_FALSE;
}

HRESULT AccessibleBase::get_groupPosition(_Out_ long* groupLevel, _Out_ long* similarItemsInGroup, _Out_ long* positionInGroup)
{
    notImplemented();
    return E_NOTIMPL;
}

HRESULT AccessibleBase::get_states(_Out_ AccessibleStates* states)
{
    if (!states)
        return E_POINTER;

    if (!m_object)
        return E_FAIL;

    *states = 0;
    notImplemented();
    return S_OK;
}

HRESULT AccessibleBase::get_extendedRole(__deref_opt_out BSTR* extendedRole)
{
    if (!extendedRole)
        return E_POINTER;
    *extendedRole = nullptr;
    if (!m_object)
        return E_FAIL;

    notImplemented();
    return S_FALSE;
}

HRESULT AccessibleBase::get_localizedExtendedRole(__deref_opt_out BSTR* localizedExtendedRole)
{
    if (!localizedExtendedRole)
        return E_POINTER;
    *localizedExtendedRole = nullptr;
    if (!m_object)
        return E_FAIL;

    notImplemented();
    return S_FALSE;
}

HRESULT AccessibleBase::get_nExtendedStates(_Out_ long* nExtendedStates)
{
    if (!nExtendedStates)
        return E_POINTER;

    if (!m_object)
        return E_FAIL;

    notImplemented();
    *nExtendedStates = 0;
    return S_OK;
}

HRESULT AccessibleBase::get_extendedStates(long maxExtendedStates, __deref_out_ecount_part_opt(maxExtendedStates, *nExtendedStates) BSTR** extendedStates, _Out_ long* nExtendedStates)
{
    notImplemented();
    return E_NOTIMPL;
}

HRESULT AccessibleBase::get_localizedExtendedStates(long maxLocalizedExtendedStates, __deref_out_ecount_part_opt(maxLocalizedExtendedStates, *nLocalizedExtendedStates) BSTR** localizedExtendedStates, _Out_ long* nLocalizedExtendedStates)
{
    notImplemented();
    return E_NOTIMPL;
}

HRESULT AccessibleBase::get_uniqueID(_Out_ long* uniqueID)
{
    if (!uniqueID)
        return E_POINTER;

    if (!m_object)
        return E_FAIL;

    *uniqueID = static_cast<long>(m_object->objectID().toUInt64());
    return S_OK;
}

HRESULT AccessibleBase::get_windowHandle(_Out_ HWND* windowHandle)
{
    *windowHandle = m_window;
    return S_OK;
}

HRESULT AccessibleBase::get_indexInParent(_Out_ long* indexInParent)
{
    return E_NOTIMPL;
}

HRESULT AccessibleBase::get_locale(_Out_ IA2Locale* locale)
{
    if (!locale)
        return E_POINTER;

    if (!m_object)
        return E_FAIL;

#if USE(CF)
    locale->language = BString(m_object->language().createCFString().get()).release();
#else
    locale->language = BString(m_object->language()).release();
#endif

    return S_OK;
}

HRESULT AccessibleBase::get_attributes(__deref_opt_out BSTR* attributes)
{
    if (!attributes)
        return E_POINTER;
    *attributes = nullptr;
    if (!m_object)
        return E_FAIL;

    notImplemented();
    return S_FALSE;
}

// IAccessible
HRESULT AccessibleBase::get_accParent(_COM_Outptr_opt_ IDispatch** parent)
{
    if (!parent)
        return E_POINTER;

    *parent = nullptr;

    if (!m_object)
        return E_FAIL;

    AccessibilityObject* parentObject = static_cast<AccessibilityObject*>(m_object->parentObjectUnignored());
    if (parentObject) {
        *parent = wrapper(parentObject);
        (*parent)->AddRef();
        return S_OK;
    }

    if (!m_window)
        return E_FAIL;

    return WebView::AccessibleObjectFromWindow(m_window,
        OBJID_WINDOW, __uuidof(IAccessible), reinterpret_cast<void**>(parent));
}

HRESULT AccessibleBase::get_accChildCount(_Out_ long* count)
{
    if (!m_object)
        return E_FAIL;
    if (!count)
        return E_POINTER;
    *count = static_cast<long>(m_object->children().size());
    return S_OK;
}

HRESULT AccessibleBase::get_accChild(VARIANT vChild, _COM_Outptr_opt_ IDispatch** ppChild)
{
    if (!ppChild)
        return E_POINTER;

    *ppChild = nullptr;

    AccessibilityObject* childObj;

    HRESULT hr = getAccessibilityObjectForChild(vChild, childObj);
    if (FAILED(hr))
        return hr;

    *ppChild = static_cast<IDispatch*>(wrapper(childObj));
    (*ppChild)->AddRef();
    return S_OK;
}

HRESULT AccessibleBase::get_accName(VARIANT vChild, __deref_opt_out BSTR* name)
{
    if (!name)
        return E_POINTER;

    *name = nullptr;

    AccessibilityObject* childObj;
    HRESULT hr = getAccessibilityObjectForChild(vChild, childObj);

    if (FAILED(hr))
        return hr;

    if (*name = BString(wrapper(childObj)->name()).release())
        return S_OK;
    return S_FALSE;
}

HRESULT AccessibleBase::get_accValue(VARIANT vChild, __deref_opt_out BSTR* value)
{
    if (!value)
        return E_POINTER;

    *value = nullptr;

    AccessibilityObject* childObj;
    HRESULT hr = getAccessibilityObjectForChild(vChild, childObj);

    if (FAILED(hr))
        return hr;

    if (*value = BString(wrapper(childObj)->value()).release())
        return S_OK;
    return S_FALSE;
}

HRESULT AccessibleBase::get_accDescription(VARIANT vChild, __deref_opt_out BSTR* description)
{
    if (!description)
        return E_POINTER;

    *description = nullptr;

    AccessibilityObject* childObj;
    HRESULT hr = getAccessibilityObjectForChild(vChild, childObj);

    if (FAILED(hr))
        return hr;

    if (*description = BString(childObj->descriptionForMSAA()).release())
        return S_OK;

    return S_FALSE;
}

HRESULT AccessibleBase::get_accRole(VARIANT vChild, _Out_ VARIANT* pvRole)
{
    if (!pvRole)
        return E_POINTER;

    ::VariantInit(pvRole);

    AccessibilityObject* childObj;
    HRESULT hr = getAccessibilityObjectForChild(vChild, childObj);

    if (FAILED(hr))
        return hr;

    String roleString = childObj->stringRoleForMSAA();
    if (!roleString.isEmpty()) {
        V_VT(pvRole) = VT_BSTR;
        V_BSTR(pvRole) = BString(roleString).release();
        return S_OK;
    }

    pvRole->vt = VT_I4;
    pvRole->lVal = wrapper(childObj)->role();
    return S_OK;
}

long AccessibleBase::state() const
{
    long state = 0;
    if (m_object->isLinked())
        state |= STATE_SYSTEM_LINKED;

    if (m_object->isHovered())
        state |= STATE_SYSTEM_HOTTRACKED;

    if (!m_object->isEnabled())
        state |= STATE_SYSTEM_UNAVAILABLE;

    if (!m_object->canSetValueAttribute())
        state |= STATE_SYSTEM_READONLY;

    if (m_object->isOffScreen())
        state |= STATE_SYSTEM_OFFSCREEN;

    if (m_object->isPasswordField())
        state |= STATE_SYSTEM_PROTECTED;

    if (m_object->isIndeterminate())
        state |= STATE_SYSTEM_INDETERMINATE;

    if (m_object->isChecked())
        state |= STATE_SYSTEM_CHECKED;

    if (m_object->isPressed())
        state |= STATE_SYSTEM_PRESSED;

    if (m_object->isFocused())
        state |= STATE_SYSTEM_FOCUSED;

    if (m_object->isVisited())
        state |= STATE_SYSTEM_TRAVERSED;

    if (m_object->canSetFocusAttribute())
        state |= STATE_SYSTEM_FOCUSABLE;

    if (m_object->isSelected())
        state |= STATE_SYSTEM_SELECTED;

    if (m_object->canSetSelectedAttribute())
        state |= STATE_SYSTEM_SELECTABLE;

    if (m_object->isMultiSelectable())
        state |= STATE_SYSTEM_EXTSELECTABLE | STATE_SYSTEM_MULTISELECTABLE;

    if (!m_object->isVisible())
        state |= STATE_SYSTEM_INVISIBLE;

    if (m_object->isCollapsed())
        state |= STATE_SYSTEM_COLLAPSED;

    if (m_object->roleValue() == AccessibilityRole::PopUpButton) {
        state |= STATE_SYSTEM_HASPOPUP;

        if (!m_object->isCollapsed())
            state |= STATE_SYSTEM_EXPANDED;
    }

    return state;
}

HRESULT AccessibleBase::get_accState(VARIANT vChild, _Out_ VARIANT* pvState)
{
    if (!pvState)
        return E_POINTER;

    ::VariantInit(pvState);

    AccessibilityObject* childObj;
    HRESULT hr = getAccessibilityObjectForChild(vChild, childObj);

    if (FAILED(hr))
        return hr;

    pvState->vt = VT_I4;
    pvState->lVal = wrapper(childObj)->state();

    return S_OK;
}

HRESULT AccessibleBase::get_accHelp(VARIANT vChild, __deref_opt_out BSTR* helpText)
{
    if (!helpText)
        return E_POINTER;

    *helpText = nullptr;

    AccessibilityObject* childObj;
    HRESULT hr = getAccessibilityObjectForChild(vChild, childObj);

    if (FAILED(hr))
        return hr;

    if (*helpText = BString(childObj->helpText()).release())
        return S_OK;
    return S_FALSE;
}

HRESULT AccessibleBase::get_accKeyboardShortcut(VARIANT vChild, __deref_opt_out BSTR* shortcut)
{
    if (!shortcut)
        return E_POINTER;

    *shortcut = nullptr;

    AccessibilityObject* childObj;
    HRESULT hr = getAccessibilityObjectForChild(vChild, childObj);

    if (FAILED(hr))
        return hr;

    String accessKey = childObj->accessKey();
    if (accessKey.isNull())
        return S_FALSE;

    static String accessKeyModifiers;
    if (accessKeyModifiers.isNull()) {
        StringBuilder accessKeyModifiersBuilder;
        auto modifiers = EventHandler::accessKeyModifiers();
        // Follow the same order as Mozilla MSAA implementation:
        // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings
        // should not be localized and defines the separator as "+".
        if (modifiers.contains(PlatformEvent::Modifier::ControlKey))
            accessKeyModifiersBuilder.append("Ctrl+");
        if (modifiers.contains(PlatformEvent::Modifier::AltKey))
            accessKeyModifiersBuilder.append("Alt+");
        if (modifiers.contains(PlatformEvent::Modifier::ShiftKey))
            accessKeyModifiersBuilder.append("Shift+");
        if (modifiers.contains(PlatformEvent::Modifier::MetaKey))
            accessKeyModifiersBuilder.append("Win+");
        accessKeyModifiers = accessKeyModifiersBuilder.toString();
    }
    *shortcut = BString(String(accessKeyModifiers + accessKey)).release();
    return S_OK;
}

HRESULT AccessibleBase::accSelect(long selectionFlags, VARIANT vChild)
{
    // According to MSDN, these combinations are invalid.
    if (((selectionFlags & (SELFLAG_ADDSELECTION | SELFLAG_REMOVESELECTION)) == (SELFLAG_ADDSELECTION | SELFLAG_REMOVESELECTION))
        || ((selectionFlags & (SELFLAG_ADDSELECTION | SELFLAG_TAKESELECTION)) == (SELFLAG_ADDSELECTION | SELFLAG_TAKESELECTION))
        || ((selectionFlags & (SELFLAG_REMOVESELECTION | SELFLAG_TAKESELECTION)) == (SELFLAG_REMOVESELECTION | SELFLAG_TAKESELECTION))
        || ((selectionFlags & (SELFLAG_EXTENDSELECTION | SELFLAG_TAKESELECTION)) == (SELFLAG_EXTENDSELECTION | SELFLAG_TAKESELECTION)))
        return E_INVALIDARG;

    AccessibilityObject* childObject;
    HRESULT hr = getAccessibilityObjectForChild(vChild, childObject);

    if (FAILED(hr))
        return hr;

    if (selectionFlags & SELFLAG_TAKEFOCUS)
        childObject->setFocused(true);

    AccessibilityObject* parentObject = childObject->parentObject();
    if (!parentObject)
        return E_INVALIDARG;

    if (selectionFlags & SELFLAG_TAKESELECTION) {
        if (is<AccessibilityListBox>(*parentObject)) {
            Vector<RefPtr<AXCoreObject> > selectedChildren(1);
            selectedChildren[0] = childObject;
            downcast<AccessibilityListBox>(*parentObject).setSelectedChildren(selectedChildren);
        } else { // any element may be selectable by virtue of it having the aria-selected property
            ASSERT(!parentObject->isMultiSelectable());
            childObject->setSelected(true);
        }
    }

    // MSDN says that ADD, REMOVE, and EXTENDSELECTION with no other flags are invalid for
    // single-select.
    const long allSELFLAGs = SELFLAG_TAKEFOCUS | SELFLAG_TAKESELECTION | SELFLAG_EXTENDSELECTION | SELFLAG_ADDSELECTION | SELFLAG_REMOVESELECTION;
    if (!parentObject->isMultiSelectable()
        && (((selectionFlags & allSELFLAGs) == SELFLAG_ADDSELECTION)
        || ((selectionFlags & allSELFLAGs) == SELFLAG_REMOVESELECTION)
        || ((selectionFlags & allSELFLAGs) == SELFLAG_EXTENDSELECTION)))
        return E_INVALIDARG;

    if (selectionFlags & SELFLAG_ADDSELECTION)
        childObject->setSelected(true);

    if (selectionFlags & SELFLAG_REMOVESELECTION)
        childObject->setSelected(false);

    // FIXME: Should implement SELFLAG_EXTENDSELECTION. For now, we just return
    // S_OK, matching Firefox.

    return S_OK;
}

HRESULT AccessibleBase::get_accSelection(_Out_ VARIANT*)
{
    return E_NOTIMPL;
}

HRESULT AccessibleBase::get_accFocus(_Out_ VARIANT* pvFocusedChild)
{
    if (!pvFocusedChild)
        return E_POINTER;

    ::VariantInit(pvFocusedChild);

    if (!m_object)
        return E_FAIL;

    auto focusedObject = downcast<AccessibilityObject>(m_object->focusedUIElement());
    if (!focusedObject)
        return S_FALSE;

    if (focusedObject == m_object) {
        V_VT(pvFocusedChild) = VT_I4;
        V_I4(pvFocusedChild) = CHILDID_SELF;
        return S_OK;
    }

    V_VT(pvFocusedChild) = VT_DISPATCH;
    V_DISPATCH(pvFocusedChild) = wrapper(focusedObject);
    V_DISPATCH(pvFocusedChild)->AddRef();
    return S_OK;
}

HRESULT AccessibleBase::get_accDefaultAction(VARIANT vChild, __deref_opt_out BSTR* action)
{
    if (!action)
        return E_POINTER;

    *action = nullptr;

    AccessibilityObject* childObj;
    HRESULT hr = getAccessibilityObjectForChild(vChild, childObj);

    if (FAILED(hr))
        return hr;

    if (*action = BString(childObj->localizedActionVerb()).release())
        return S_OK;
    return S_FALSE;
}

HRESULT AccessibleBase::accLocation(_Out_ long* left, _Out_ long* top, _Out_ long* width, _Out_ long* height, VARIANT vChild)
{
    if (!left || !top || !width || !height)
        return E_POINTER;

    *left = *top = *width = *height = 0;

    AccessibilityObject* childObj;
    HRESULT hr = getAccessibilityObjectForChild(vChild, childObj);

    if (FAILED(hr))
        return hr;

    if (!childObj->documentFrameView())
        return E_FAIL;

    IntRect screenRect(childObj->documentFrameView()->contentsToScreen(snappedIntRect(childObj->elementRect())));
    *left = screenRect.x();
    *top = screenRect.y();
    *width = screenRect.width();
    *height = screenRect.height();
    return S_OK;
}

HRESULT AccessibleBase::accNavigate(long direction, VARIANT vFromChild, _Out_ VARIANT* pvNavigatedTo)
{
    if (!pvNavigatedTo)
        return E_POINTER;

    ::VariantInit(pvNavigatedTo);

    AccessibilityObject* childObj = nullptr;

    switch (direction) {
        case NAVDIR_DOWN:
        case NAVDIR_UP:
        case NAVDIR_LEFT:
        case NAVDIR_RIGHT:
            // These directions are not implemented, matching Mozilla and IE.
            return E_NOTIMPL;
        case NAVDIR_LASTCHILD:
        case NAVDIR_FIRSTCHILD:
            // MSDN states that navigating to first/last child can only be from self.
            if (vFromChild.lVal != CHILDID_SELF)
                return E_INVALIDARG;

            if (!m_object)
                return E_FAIL;

            if (direction == NAVDIR_FIRSTCHILD)
                childObj = m_object->firstChild();
            else
                childObj = m_object->lastChild();
            break;
        case NAVDIR_NEXT:
        case NAVDIR_PREVIOUS: {
            // Navigating to next and previous is allowed from self or any of our children.
            HRESULT hr = getAccessibilityObjectForChild(vFromChild, childObj);
            if (FAILED(hr))
                return hr;

            if (direction == NAVDIR_NEXT)
                childObj = childObj->nextSibling();
            else
                childObj = childObj->previousSibling();
            break;
        }
        default:
            ASSERT_NOT_REACHED();
            return E_INVALIDARG;
    }

    if (!childObj)
        return S_FALSE;

    V_VT(pvNavigatedTo) = VT_DISPATCH;
    V_DISPATCH(pvNavigatedTo) = wrapper(childObj);
    V_DISPATCH(pvNavigatedTo)->AddRef();
    return S_OK;
}

HRESULT AccessibleBase::accHitTest(long x, long y, _Out_ VARIANT* pvChildAtPoint)
{
    if (!pvChildAtPoint)
        return E_POINTER;

    ::VariantInit(pvChildAtPoint);

    if (!m_object || !m_object->documentFrameView())
        return E_FAIL;

    IntPoint point = m_object->documentFrameView()->screenToContents(IntPoint(x, y));
    auto childObject = downcast<AccessibilityObject>(m_object->accessibilityHitTest(point));

    if (!childObject) {
        // If we did not hit any child objects, test whether the point hit us, and
        // report that.
        if (!m_object->boundingBoxRect().contains(point))
            return S_FALSE;
        childObject = m_object;
    }

    if (childObject == m_object) {
        V_VT(pvChildAtPoint) = VT_I4;
        V_I4(pvChildAtPoint) = CHILDID_SELF;
    } else {
        V_VT(pvChildAtPoint) = VT_DISPATCH;
        V_DISPATCH(pvChildAtPoint) = static_cast<IDispatch*>(wrapper(childObject));
        V_DISPATCH(pvChildAtPoint)->AddRef();
    }
    return S_OK;
}

HRESULT AccessibleBase::accDoDefaultAction(VARIANT vChild)
{
    AccessibilityObject* childObj;
    HRESULT hr = getAccessibilityObjectForChild(vChild, childObj);

    if (FAILED(hr))
        return hr;

    if (!childObj->performDefaultAction())
        return S_FALSE;

    return S_OK;
}

// AccessibleBase
String AccessibleBase::name() const
{
    return m_object->nameForMSAA();
}

String AccessibleBase::value() const
{
    return m_object->stringValueForMSAA();
}

static long MSAARole(AccessibilityRole role)
{
    switch (role) {
    case AccessibilityRole::Button:
        return ROLE_SYSTEM_PUSHBUTTON;
    case AccessibilityRole::RadioButton:
        return ROLE_SYSTEM_RADIOBUTTON;
    case AccessibilityRole::CheckBox:
    case AccessibilityRole::ToggleButton:
    case AccessibilityRole::Switch:
        return ROLE_SYSTEM_CHECKBUTTON;
    case AccessibilityRole::Slider:
        return ROLE_SYSTEM_SLIDER;
    case AccessibilityRole::TabGroup:
    case AccessibilityRole::TabList:
        return ROLE_SYSTEM_PAGETABLIST;
    case AccessibilityRole::TextField:
    case AccessibilityRole::TextArea:
    case AccessibilityRole::EditableText:
        return ROLE_SYSTEM_TEXT;
    case AccessibilityRole::Heading:
    case AccessibilityRole::ListMarker:
    case AccessibilityRole::StaticText:
    case AccessibilityRole::Label:
        return ROLE_SYSTEM_STATICTEXT;
    case AccessibilityRole::Outline:
        return ROLE_SYSTEM_OUTLINE;
    case AccessibilityRole::Column:
        return ROLE_SYSTEM_COLUMN;
    case AccessibilityRole::Row:
        return ROLE_SYSTEM_ROW;
    case AccessibilityRole::ApplicationGroup:
    case AccessibilityRole::Group:
    case AccessibilityRole::RadioGroup:
        return ROLE_SYSTEM_GROUPING;
    case AccessibilityRole::DescriptionList:
    case AccessibilityRole::Directory:
    case AccessibilityRole::List:
    case AccessibilityRole::ListBox:
    case AccessibilityRole::MenuListPopup:
        return ROLE_SYSTEM_LIST;
    case AccessibilityRole::Grid:
    case AccessibilityRole::Table:
        return ROLE_SYSTEM_TABLE;
    case AccessibilityRole::ImageMapLink:
    case AccessibilityRole::Link:
    case AccessibilityRole::WebCoreLink:
        return ROLE_SYSTEM_LINK;
    case AccessibilityRole::Canvas:
    case AccessibilityRole::ImageMap:
    case AccessibilityRole::Image:
        return ROLE_SYSTEM_GRAPHIC;
    case AccessibilityRole::ListItem:
        return ROLE_SYSTEM_LISTITEM;
    case AccessibilityRole::ListBoxOption:
    case AccessibilityRole::MenuListOption:
        return ROLE_SYSTEM_STATICTEXT;
    case AccessibilityRole::ComboBox:
    case AccessibilityRole::PopUpButton:
        return ROLE_SYSTEM_COMBOBOX;
    case AccessibilityRole::Div:
    case AccessibilityRole::Footer:
    case AccessibilityRole::Form:
    case AccessibilityRole::Paragraph:
        return ROLE_SYSTEM_GROUPING;
    case AccessibilityRole::HorizontalRule:
    case AccessibilityRole::Splitter:
        return ROLE_SYSTEM_SEPARATOR;
    case AccessibilityRole::ApplicationAlert:
    case AccessibilityRole::ApplicationAlertDialog:
        return ROLE_SYSTEM_ALERT;
    case AccessibilityRole::DisclosureTriangle:
        return ROLE_SYSTEM_BUTTONDROPDOWN;
    case AccessibilityRole::Incrementor:
    case AccessibilityRole::SpinButton:
        return ROLE_SYSTEM_SPINBUTTON;
    case AccessibilityRole::SpinButtonPart:
        return ROLE_SYSTEM_PUSHBUTTON;
    case AccessibilityRole::Toolbar:
        return ROLE_SYSTEM_TOOLBAR;
    case AccessibilityRole::UserInterfaceTooltip:
        return ROLE_SYSTEM_TOOLTIP;
    case AccessibilityRole::Tree:
    case AccessibilityRole::TreeGrid:
        return ROLE_SYSTEM_OUTLINE;
    case AccessibilityRole::TreeItem:
        return ROLE_SYSTEM_OUTLINEITEM;
    case AccessibilityRole::TabPanel:
        return ROLE_SYSTEM_GROUPING;
    case AccessibilityRole::Tab:
        return ROLE_SYSTEM_PAGETAB;
    case AccessibilityRole::Application:
        return ROLE_SYSTEM_APPLICATION;
    case AccessibilityRole::ApplicationDialog:
        return ROLE_SYSTEM_DIALOG;
    case AccessibilityRole::ApplicationLog:
    case AccessibilityRole::ApplicationMarquee:
        return ROLE_SYSTEM_GROUPING;
    case AccessibilityRole::ApplicationStatus:
        return ROLE_SYSTEM_STATUSBAR;
    case AccessibilityRole::ApplicationTimer:
        return ROLE_SYSTEM_CLOCK;
    case AccessibilityRole::Cell:
        return ROLE_SYSTEM_CELL;
    case AccessibilityRole::ColumnHeader:
        return ROLE_SYSTEM_COLUMNHEADER;
    case AccessibilityRole::Definition:
    case AccessibilityRole::DescriptionListDetail:
    case AccessibilityRole::DescriptionListTerm:
    case AccessibilityRole::Document:
    case AccessibilityRole::DocumentArticle:
    case AccessibilityRole::DocumentNote:
        return ROLE_SYSTEM_GROUPING;
    case AccessibilityRole::DocumentMath:
    case AccessibilityRole::MathElement:
        return ROLE_SYSTEM_EQUATION;
    case AccessibilityRole::HelpTag:
        return ROLE_SYSTEM_HELPBALLOON;
    case AccessibilityRole::WebApplication:
    case AccessibilityRole::LandmarkBanner:
    case AccessibilityRole::LandmarkComplementary:
    case AccessibilityRole::LandmarkContentInfo:
    case AccessibilityRole::LandmarkMain:
    case AccessibilityRole::LandmarkNavigation:
    case AccessibilityRole::LandmarkRegion:
    case AccessibilityRole::LandmarkSearch:
    case AccessibilityRole::Legend:
        return ROLE_SYSTEM_GROUPING;
    case AccessibilityRole::Menu:
        return ROLE_SYSTEM_MENUPOPUP;
    case AccessibilityRole::MenuItem:
    case AccessibilityRole::MenuButton:
        return ROLE_SYSTEM_MENUITEM;
    case AccessibilityRole::MenuBar:
        return ROLE_SYSTEM_MENUBAR;
    case AccessibilityRole::ProgressIndicator:
        return ROLE_SYSTEM_PROGRESSBAR;
    case AccessibilityRole::RowHeader:
        return ROLE_SYSTEM_ROWHEADER;
    case AccessibilityRole::ScrollBar:
        return ROLE_SYSTEM_SCROLLBAR;
    case AccessibilityRole::SVGRoot:
        return ROLE_SYSTEM_GROUPING;
    case AccessibilityRole::TableHeaderContainer:
        return ROLE_SYSTEM_GROUPING;
    case AccessibilityRole::Window:
        return ROLE_SYSTEM_WINDOW;
    default:
        // This is the default role for MSAA.
        return ROLE_SYSTEM_CLIENT;
    }
}

long AccessibleBase::role() const
{
    return MSAARole(m_object->roleValueForMSAA());
}

HRESULT AccessibleBase::getAccessibilityObjectForChild(VARIANT vChild, AccessibilityObject*& childObj) const
{
    childObj = 0;

    if (!m_object)
        return E_FAIL;

    m_object->updateBackingStore();

    if (vChild.vt != VT_I4)
        return E_INVALIDARG;

    if (vChild.lVal == CHILDID_SELF)
        childObj = m_object;
    else if (vChild.lVal < 0) {
        // When broadcasting MSAA events, we negate the AXID and pass it as the
        // child ID.
        Document* document = m_object->document();
        if (!document)
            return E_FAIL;

        childObj = document->axObjectCache()->objectFromAXID(makeObjectIdentifier<AXIDType>(-vChild.lVal));
    } else {
        size_t childIndex = static_cast<size_t>(vChild.lVal - 1);

        if (childIndex >= m_object->children().size())
            return E_FAIL;
        childObj = static_cast<AccessibilityObject*>(m_object->children().at(childIndex).get());
    }

    if (!childObj)
        return E_FAIL;

    return S_OK;
}

AccessibleBase* AccessibleBase::wrapper(AccessibilityObject* obj) const
{
    AccessibleBase* result = static_cast<AccessibleBase*>(obj->wrapper());
    if (!result)
        result = createInstance(obj, m_window);
    return result;
}

HRESULT AccessibleBase::isSameObject(_In_opt_ IAccessibleComparable* other, _Out_ BOOL* result)
{
    if (!result || !other)
        return E_POINTER;

    COMPtr<AccessibleBase> otherAccessibleBase(Query, other);
    *result = (otherAccessibleBase == this || otherAccessibleBase->m_object == m_object);
    return S_OK;
}
