/*
 * Copyright 2014 Piotr Caban for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define COBJMACROS

#include "oleacc_private.h"

#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(oleacc);

typedef struct {
    IAccessible IAccessible_iface;
    IOleWindow IOleWindow_iface;
    IEnumVARIANT IEnumVARIANT_iface;

    LONG ref;

    HWND hwnd;
    HWND enum_pos;
} Client;

static inline Client* impl_from_Client(IAccessible *iface)
{
    return CONTAINING_RECORD(iface, Client, IAccessible_iface);
}

static HRESULT WINAPI Client_QueryInterface(IAccessible *iface, REFIID riid, void **ppv)
{
    Client *This = impl_from_Client(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);

    if(IsEqualIID(riid, &IID_IAccessible) ||
            IsEqualIID(riid, &IID_IDispatch) ||
            IsEqualIID(riid, &IID_IUnknown)) {
        *ppv = iface;
    }else if(IsEqualIID(riid, &IID_IOleWindow)) {
        *ppv = &This->IOleWindow_iface;
    }else if(IsEqualIID(riid, &IID_IEnumVARIANT)) {
        *ppv = &This->IEnumVARIANT_iface;
    }else {
        WARN("no interface: %s\n", debugstr_guid(riid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IAccessible_AddRef(iface);
    return S_OK;
}

static ULONG WINAPI Client_AddRef(IAccessible *iface)
{
    Client *This = impl_from_Client(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref = %u\n", This, ref);
    return ref;
}

static ULONG WINAPI Client_Release(IAccessible *iface)
{
    Client *This = impl_from_Client(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref = %u\n", This, ref);

    if(!ref)
        heap_free(This);
    return ref;
}

static HRESULT WINAPI Client_GetTypeInfoCount(IAccessible *iface, UINT *pctinfo)
{
    Client *This = impl_from_Client(iface);
    FIXME("(%p)->(%p)\n", This, pctinfo);
    return E_NOTIMPL;
}

static HRESULT WINAPI Client_GetTypeInfo(IAccessible *iface,
        UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
    Client *This = impl_from_Client(iface);
    FIXME("(%p)->(%u %x %p)\n", This, iTInfo, lcid, ppTInfo);
    return E_NOTIMPL;
}

static HRESULT WINAPI Client_GetIDsOfNames(IAccessible *iface, REFIID riid,
        LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
    Client *This = impl_from_Client(iface);
    FIXME("(%p)->(%s %p %u %x %p)\n", This, debugstr_guid(riid),
            rgszNames, cNames, lcid, rgDispId);
    return E_NOTIMPL;
}

static HRESULT WINAPI Client_Invoke(IAccessible *iface, DISPID dispIdMember,
        REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
        VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    Client *This = impl_from_Client(iface);
    FIXME("(%p)->(%x %s %x %x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
            lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
    return E_NOTIMPL;
}

static HRESULT WINAPI Client_get_accParent(IAccessible *iface, IDispatch **ppdispParent)
{
    Client *This = impl_from_Client(iface);

    TRACE("(%p)->(%p)\n", This, ppdispParent);

    return AccessibleObjectFromWindow(This->hwnd, OBJID_WINDOW,
            &IID_IDispatch, (void**)ppdispParent);
}

static HRESULT WINAPI Client_get_accChildCount(IAccessible *iface, LONG *pcountChildren)
{
    Client *This = impl_from_Client(iface);
    HWND cur;

    TRACE("(%p)->(%p)\n", This, pcountChildren);

    *pcountChildren = 0;
    for(cur = GetWindow(This->hwnd, GW_CHILD); cur; cur = GetWindow(cur, GW_HWNDNEXT))
        (*pcountChildren)++;

    return S_OK;
}

static HRESULT WINAPI Client_get_accChild(IAccessible *iface,
        VARIANT varChildID, IDispatch **ppdispChild)
{
    Client *This = impl_from_Client(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varChildID), ppdispChild);

    *ppdispChild = NULL;
    return E_INVALIDARG;
}

static HRESULT WINAPI Client_get_accName(IAccessible *iface, VARIANT varID, BSTR *pszName)
{
    Client *This = impl_from_Client(iface);
    WCHAR name[1024];
    UINT i, len;

    TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszName);

    *pszName = NULL;
    if(convert_child_id(&varID) != CHILDID_SELF || !IsWindow(This->hwnd))
        return E_INVALIDARG;

    len = SendMessageW(This->hwnd, WM_GETTEXT, sizeof(name)/sizeof(WCHAR), (LPARAM)name);
    if(!len)
        return S_FALSE;

    for(i=0; i<len; i++) {
        if(name[i] == '&') {
            len--;
            memmove(name+i, name+i+1, (len-i)*sizeof(WCHAR));
            break;
        }
    }

    *pszName = SysAllocStringLen(name, len);
    return *pszName ? S_OK : E_OUTOFMEMORY;
}

static HRESULT WINAPI Client_get_accValue(IAccessible *iface, VARIANT varID, BSTR *pszValue)
{
    Client *This = impl_from_Client(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszValue);

    *pszValue = NULL;
    if(convert_child_id(&varID) != CHILDID_SELF)
        return E_INVALIDARG;
    return S_FALSE;
}

static HRESULT WINAPI Client_get_accDescription(IAccessible *iface,
        VARIANT varID, BSTR *pszDescription)
{
    Client *This = impl_from_Client(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszDescription);

    *pszDescription = NULL;
    if(convert_child_id(&varID) != CHILDID_SELF)
        return E_INVALIDARG;
    return S_FALSE;
}

static HRESULT WINAPI Client_get_accRole(IAccessible *iface, VARIANT varID, VARIANT *pvarRole)
{
    Client *This = impl_from_Client(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pvarRole);

    if(convert_child_id(&varID) != CHILDID_SELF) {
        V_VT(pvarRole) = VT_EMPTY;
        return E_INVALIDARG;
    }

    V_VT(pvarRole) = VT_I4;
    V_I4(pvarRole) = ROLE_SYSTEM_CLIENT;
    return S_OK;
}

static HRESULT WINAPI Client_get_accState(IAccessible *iface, VARIANT varID, VARIANT *pvarState)
{
    Client *This = impl_from_Client(iface);
    LONG style;

    TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pvarState);

    if(convert_child_id(&varID) != CHILDID_SELF) {
        V_VT(pvarState) = VT_EMPTY;
        return E_INVALIDARG;
    }

    V_VT(pvarState) = VT_I4;
    V_I4(pvarState) = 0;

    style = GetWindowLongW(This->hwnd, GWL_STYLE);
    if(style & WS_DISABLED)
        V_I4(pvarState) |= STATE_SYSTEM_UNAVAILABLE;
    else if(IsWindow(This->hwnd))
        V_I4(pvarState) |= STATE_SYSTEM_FOCUSABLE;
    if(GetFocus() == This->hwnd)
        V_I4(pvarState) |= STATE_SYSTEM_FOCUSED;
    if(!(style & WS_VISIBLE))
        V_I4(pvarState) |= STATE_SYSTEM_INVISIBLE;
    return S_OK;
}

static HRESULT WINAPI Client_get_accHelp(IAccessible *iface, VARIANT varID, BSTR *pszHelp)
{
    Client *This = impl_from_Client(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszHelp);

    *pszHelp = NULL;
    if(convert_child_id(&varID) != CHILDID_SELF)
        return E_INVALIDARG;
    return S_FALSE;
}

static HRESULT WINAPI Client_get_accHelpTopic(IAccessible *iface,
        BSTR *pszHelpFile, VARIANT varID, LONG *pidTopic)
{
    Client *This = impl_from_Client(iface);
    FIXME("(%p)->(%p %s %p)\n", This, pszHelpFile, debugstr_variant(&varID), pidTopic);
    return E_NOTIMPL;
}

static HRESULT WINAPI Client_get_accKeyboardShortcut(IAccessible *iface,
        VARIANT varID, BSTR *pszKeyboardShortcut)
{
    static const WCHAR shortcut_fmt[] = {'A','l','t','+','!',0};
    Client *This = impl_from_Client(iface);
    WCHAR name[1024];
    UINT i, len;

    TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszKeyboardShortcut);

    *pszKeyboardShortcut = NULL;
    if(convert_child_id(&varID) != CHILDID_SELF)
        return E_INVALIDARG;

    len = SendMessageW(This->hwnd, WM_GETTEXT, sizeof(name)/sizeof(WCHAR), (LPARAM)name);
    for(i=0; i<len; i++) {
        if(name[i] == '&')
            break;
    }
    if(i+1 >= len)
        return S_FALSE;

    *pszKeyboardShortcut = SysAllocString(shortcut_fmt);
    if(!*pszKeyboardShortcut)
        return E_OUTOFMEMORY;

    (*pszKeyboardShortcut)[4] = name[i+1];
    return S_OK;
}

static HRESULT WINAPI Client_get_accFocus(IAccessible *iface, VARIANT *pvarID)
{
    Client *This = impl_from_Client(iface);
    FIXME("(%p)->(%p)\n", This, pvarID);
    return E_NOTIMPL;
}

static HRESULT WINAPI Client_get_accSelection(IAccessible *iface, VARIANT *pvarID)
{
    Client *This = impl_from_Client(iface);
    FIXME("(%p)->(%p)\n", This, pvarID);
    return E_NOTIMPL;
}

static HRESULT WINAPI Client_get_accDefaultAction(IAccessible *iface,
        VARIANT varID, BSTR *pszDefaultAction)
{
    Client *This = impl_from_Client(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszDefaultAction);

    *pszDefaultAction = NULL;
    if(convert_child_id(&varID) != CHILDID_SELF)
        return E_INVALIDARG;
    return S_FALSE;
}

static HRESULT WINAPI Client_accSelect(IAccessible *iface, LONG flagsSelect, VARIANT varID)
{
    Client *This = impl_from_Client(iface);
    FIXME("(%p)->(%x %s)\n", This, flagsSelect, debugstr_variant(&varID));
    return E_NOTIMPL;
}

static HRESULT WINAPI Client_accLocation(IAccessible *iface, LONG *pxLeft,
        LONG *pyTop, LONG *pcxWidth, LONG *pcyHeight, VARIANT varID)
{
    Client *This = impl_from_Client(iface);
    RECT rect;
    POINT pt;

    TRACE("(%p)->(%p %p %p %p %s)\n", This, pxLeft, pyTop,
            pcxWidth, pcyHeight, debugstr_variant(&varID));

    *pxLeft = *pyTop = *pcxWidth = *pcyHeight = 0;
    if(convert_child_id(&varID) != CHILDID_SELF)
        return E_INVALIDARG;

    if(!GetClientRect(This->hwnd, &rect))
        return S_OK;

    pt.x = rect.left,
    pt.y = rect.top;
    MapWindowPoints(This->hwnd, NULL, &pt, 1);
    *pxLeft = pt.x;
    *pyTop = pt.y;

    pt.x = rect.right;
    pt.y = rect.bottom;
    MapWindowPoints(This->hwnd, NULL, &pt, 1);
    *pcxWidth = pt.x - *pxLeft;
    *pcyHeight = pt.y - *pyTop;
    return S_OK;
}

static HRESULT WINAPI Client_accNavigate(IAccessible *iface,
        LONG navDir, VARIANT varStart, VARIANT *pvarEnd)
{
    Client *This = impl_from_Client(iface);
    FIXME("(%p)->(%d %s %p)\n", This, navDir, debugstr_variant(&varStart), pvarEnd);
    return E_NOTIMPL;
}

static HRESULT WINAPI Client_accHitTest(IAccessible *iface,
        LONG xLeft, LONG yTop, VARIANT *pvarID)
{
    Client *This = impl_from_Client(iface);
    HWND child;
    POINT pt;

    TRACE("(%p)->(%d %d %p)\n", This, xLeft, yTop, pvarID);

    V_VT(pvarID) = VT_I4;
    V_I4(pvarID) = 0;

    pt.x = xLeft;
    pt.y = yTop;
    if(!IsWindowVisible(This->hwnd) || !ScreenToClient(This->hwnd, &pt))
        return S_OK;

    child = ChildWindowFromPointEx(This->hwnd, pt, CWP_SKIPINVISIBLE);
    if(!child || child==This->hwnd)
        return S_OK;

    V_VT(pvarID) = VT_DISPATCH;
    return AccessibleObjectFromWindow(child, OBJID_WINDOW,
            &IID_IDispatch, (void**)&V_DISPATCH(pvarID));
}

static HRESULT WINAPI Client_accDoDefaultAction(IAccessible *iface, VARIANT varID)
{
    Client *This = impl_from_Client(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_variant(&varID));
    return E_NOTIMPL;
}

static HRESULT WINAPI Client_put_accName(IAccessible *iface, VARIANT varID, BSTR pszName)
{
    Client *This = impl_from_Client(iface);
    FIXME("(%p)->(%s %s)\n", This, debugstr_variant(&varID), debugstr_w(pszName));
    return E_NOTIMPL;
}

static HRESULT WINAPI Client_put_accValue(IAccessible *iface, VARIANT varID, BSTR pszValue)
{
    Client *This = impl_from_Client(iface);
    FIXME("(%p)->(%s %s)\n", This, debugstr_variant(&varID), debugstr_w(pszValue));
    return E_NOTIMPL;
}

static const IAccessibleVtbl ClientVtbl = {
    Client_QueryInterface,
    Client_AddRef,
    Client_Release,
    Client_GetTypeInfoCount,
    Client_GetTypeInfo,
    Client_GetIDsOfNames,
    Client_Invoke,
    Client_get_accParent,
    Client_get_accChildCount,
    Client_get_accChild,
    Client_get_accName,
    Client_get_accValue,
    Client_get_accDescription,
    Client_get_accRole,
    Client_get_accState,
    Client_get_accHelp,
    Client_get_accHelpTopic,
    Client_get_accKeyboardShortcut,
    Client_get_accFocus,
    Client_get_accSelection,
    Client_get_accDefaultAction,
    Client_accSelect,
    Client_accLocation,
    Client_accNavigate,
    Client_accHitTest,
    Client_accDoDefaultAction,
    Client_put_accName,
    Client_put_accValue
};

static inline Client* impl_from_Client_OleWindow(IOleWindow *iface)
{
    return CONTAINING_RECORD(iface, Client, IOleWindow_iface);
}

static HRESULT WINAPI Client_OleWindow_QueryInterface(IOleWindow *iface, REFIID riid, void **ppv)
{
    Client *This = impl_from_Client_OleWindow(iface);
    return IAccessible_QueryInterface(&This->IAccessible_iface, riid, ppv);
}

static ULONG WINAPI Client_OleWindow_AddRef(IOleWindow *iface)
{
    Client *This = impl_from_Client_OleWindow(iface);
    return IAccessible_AddRef(&This->IAccessible_iface);
}

static ULONG WINAPI Client_OleWindow_Release(IOleWindow *iface)
{
    Client *This = impl_from_Client_OleWindow(iface);
    return IAccessible_Release(&This->IAccessible_iface);
}

static HRESULT WINAPI Client_OleWindow_GetWindow(IOleWindow *iface, HWND *phwnd)
{
    Client *This = impl_from_Client_OleWindow(iface);

    TRACE("(%p)->(%p)\n", This, phwnd);

    *phwnd = This->hwnd;
    return S_OK;
}

static HRESULT WINAPI Client_OleWindow_ContextSensitiveHelp(IOleWindow *iface, BOOL fEnterMode)
{
    Client *This = impl_from_Client_OleWindow(iface);
    FIXME("(%p)->(%x)\n", This, fEnterMode);
    return E_NOTIMPL;
}

static const IOleWindowVtbl ClientOleWindowVtbl = {
    Client_OleWindow_QueryInterface,
    Client_OleWindow_AddRef,
    Client_OleWindow_Release,
    Client_OleWindow_GetWindow,
    Client_OleWindow_ContextSensitiveHelp
};

static inline Client* impl_from_Client_EnumVARIANT(IEnumVARIANT *iface)
{
    return CONTAINING_RECORD(iface, Client, IEnumVARIANT_iface);
}

static HRESULT WINAPI Client_EnumVARIANT_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
{
    Client *This = impl_from_Client_EnumVARIANT(iface);
    return IAccessible_QueryInterface(&This->IAccessible_iface, riid, ppv);
}

static ULONG WINAPI Client_EnumVARIANT_AddRef(IEnumVARIANT *iface)
{
    Client *This = impl_from_Client_EnumVARIANT(iface);
    return IAccessible_AddRef(&This->IAccessible_iface);
}

static ULONG WINAPI Client_EnumVARIANT_Release(IEnumVARIANT *iface)
{
    Client *This = impl_from_Client_EnumVARIANT(iface);
    return IAccessible_Release(&This->IAccessible_iface);
}

static HRESULT WINAPI Client_EnumVARIANT_Next(IEnumVARIANT *iface,
        ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
{
    Client *This = impl_from_Client_EnumVARIANT(iface);
    HWND cur = This->enum_pos, next;
    ULONG fetched = 0;
    HRESULT hr;

    TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);

    if(!celt) {
        if(pCeltFetched)
            *pCeltFetched = 0;
        return S_OK;
    }

    if(!This->enum_pos)
        next = GetWindow(This->hwnd, GW_CHILD);
    else
        next = GetWindow(This->enum_pos, GW_HWNDNEXT);

    while(next) {
        cur = next;

        V_VT(rgVar+fetched) = VT_DISPATCH;
        hr = AccessibleObjectFromWindow(cur, OBJID_WINDOW,
                &IID_IDispatch, (void**)&V_DISPATCH(rgVar+fetched));
        if(FAILED(hr)) {
            V_VT(rgVar+fetched) = VT_EMPTY;
            while(fetched > 0) {
                VariantClear(rgVar+fetched-1);
                fetched--;
            }
            if(pCeltFetched)
                *pCeltFetched = 0;
            return hr;
        }
        fetched++;
        if(fetched == celt)
            break;

        next = GetWindow(cur, GW_HWNDNEXT);
    }

    This->enum_pos = cur;
    if(pCeltFetched)
        *pCeltFetched = fetched;
    return celt == fetched ? S_OK : S_FALSE;
}

static HRESULT WINAPI Client_EnumVARIANT_Skip(IEnumVARIANT *iface, ULONG celt)
{
    Client *This = impl_from_Client_EnumVARIANT(iface);
    HWND next;

    TRACE("(%p)->(%u)\n", This, celt);

    while(celt) {
        if(!This->enum_pos)
            next = GetWindow(This->hwnd, GW_CHILD);
        else
            next = GetWindow(This->enum_pos, GW_HWNDNEXT);
        if(!next)
            return S_FALSE;

        This->enum_pos = next;
        celt--;
    }

    return S_OK;
}

static HRESULT WINAPI Client_EnumVARIANT_Reset(IEnumVARIANT *iface)
{
    Client *This = impl_from_Client_EnumVARIANT(iface);

    TRACE("(%p)\n", This);

    This->enum_pos = 0;
    return S_OK;
}

static HRESULT WINAPI Client_EnumVARIANT_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
{
    Client *This = impl_from_Client_EnumVARIANT(iface);
    FIXME("(%p)->(%p)\n", This, ppEnum);
    return E_NOTIMPL;
}

static const IEnumVARIANTVtbl ClientEnumVARIANTVtbl = {
    Client_EnumVARIANT_QueryInterface,
    Client_EnumVARIANT_AddRef,
    Client_EnumVARIANT_Release,
    Client_EnumVARIANT_Next,
    Client_EnumVARIANT_Skip,
    Client_EnumVARIANT_Reset,
    Client_EnumVARIANT_Clone
};

HRESULT create_client_object(HWND hwnd, const IID *iid, void **obj)
{
    Client *client;
    HRESULT hres;

    if(!IsWindow(hwnd))
        return E_FAIL;

    client = heap_alloc_zero(sizeof(Client));
    if(!client)
        return E_OUTOFMEMORY;

    client->IAccessible_iface.lpVtbl = &ClientVtbl;
    client->IOleWindow_iface.lpVtbl = &ClientOleWindowVtbl;
    client->IEnumVARIANT_iface.lpVtbl = &ClientEnumVARIANTVtbl;
    client->ref = 1;
    client->hwnd = hwnd;
    client->enum_pos = 0;

    hres = IAccessible_QueryInterface(&client->IAccessible_iface, iid, obj);
    IAccessible_Release(&client->IAccessible_iface);
    return hres;
}
