/*
 * Implementation of the OLEACC dll
 *
 * Copyright 2003 Mike McCormack 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 <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "ole2.h"
#include "commctrl.h"
#include "rpcproxy.h"

#include "initguid.h"
#include "oleacc_private.h"
#include "resource.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(oleacc);

static const WCHAR lresult_atom_prefix[] = {'w','i','n','e','_','o','l','e','a','c','c',':'};

static const WCHAR menuW[] = {'#','3','2','7','6','8',0};
static const WCHAR desktopW[] = {'#','3','2','7','6','9',0};
static const WCHAR dialogW[] = {'#','3','2','7','7','0',0};
static const WCHAR winswitchW[] = {'#','3','2','7','7','1',0};
static const WCHAR mdi_clientW[] = {'M','D','I','C','l','i','e','n','t',0};
static const WCHAR richeditW[] = {'R','I','C','H','E','D','I','T',0};
static const WCHAR richedit20aW[] = {'R','i','c','h','E','d','i','t','2','0','A',0};
static const WCHAR richedit20wW[] = {'R','i','c','h','E','d','i','t','2','0','W',0};

typedef HRESULT (WINAPI *accessible_create)(HWND, const IID*, void**);

extern HRESULT WINAPI OLEACC_DllGetClassObject(REFCLSID, REFIID, void**) DECLSPEC_HIDDEN;
extern BOOL WINAPI OLEACC_DllMain(HINSTANCE, DWORD, void*) DECLSPEC_HIDDEN;
extern HRESULT WINAPI OLEACC_DllRegisterServer(void) DECLSPEC_HIDDEN;
extern HRESULT WINAPI OLEACC_DllUnregisterServer(void) DECLSPEC_HIDDEN;

static struct {
    const WCHAR *name;
    DWORD idx;
    accessible_create create_client;
    accessible_create create_window;
} builtin_classes[] = {
    {WC_LISTBOXW,           0x10000, NULL, NULL},
    {menuW,                 0x10001, NULL, NULL},
    {WC_BUTTONW,            0x10002, NULL, NULL},
    {WC_STATICW,            0x10003, NULL, NULL},
    {WC_EDITW,              0x10004, NULL, NULL},
    {WC_COMBOBOXW,          0x10005, NULL, NULL},
    {dialogW,               0x10006, NULL, NULL},
    {winswitchW,            0x10007, NULL, NULL},
    {mdi_clientW,           0x10008, NULL, NULL},
    {desktopW,              0x10009, NULL, NULL},
    {WC_SCROLLBARW,         0x1000a, NULL, NULL},
    {STATUSCLASSNAMEW,      0x1000b, NULL, NULL},
    {TOOLBARCLASSNAMEW,     0x1000c, NULL, NULL},
    {PROGRESS_CLASSW,       0x1000d, NULL, NULL},
    {ANIMATE_CLASSW,        0x1000e, NULL, NULL},
    {WC_TABCONTROLW,        0x1000f, NULL, NULL},
    {HOTKEY_CLASSW,         0x10010, NULL, NULL},
    {WC_HEADERW,            0x10011, NULL, NULL},
    {TRACKBAR_CLASSW,       0x10012, NULL, NULL},
    {WC_LISTVIEWW,          0x10013, NULL, NULL},
    {UPDOWN_CLASSW,         0x10016, NULL, NULL},
    {TOOLTIPS_CLASSW,       0x10018, NULL, NULL},
    {WC_TREEVIEWW,          0x10019, NULL, NULL},
    {MONTHCAL_CLASSW,       0,       NULL, NULL},
    {DATETIMEPICK_CLASSW,   0,       NULL, NULL},
    {WC_IPADDRESSW,         0,       NULL, NULL},
    {richeditW,             0x1001c, NULL, NULL},
    {richedit20aW,          0,       NULL, NULL},
    {richedit20wW,          0,       NULL, NULL},
};

static HINSTANCE oleacc_handle = 0;

int convert_child_id(VARIANT *v)
{
    switch(V_VT(v)) {
    case VT_I4:
        return V_I4(v);
    default:
        FIXME("unhandled child ID variant type: %d\n", V_VT(v));
        return -1;
    }
}

static accessible_create get_builtin_accessible_obj(HWND hwnd, LONG objid)
{
    WCHAR class_name[64];
    int i, idx;

    if(!RealGetWindowClassW(hwnd, class_name, sizeof(class_name)/sizeof(WCHAR)))
        return NULL;
    TRACE("got window class: %s\n", debugstr_w(class_name));

    for(i=0; i<sizeof(builtin_classes)/sizeof(builtin_classes[0]); i++) {
        if(!strcmpiW(class_name, builtin_classes[i].name)) {
            accessible_create ret;

            ret = (objid==OBJID_CLIENT ?
                    builtin_classes[i].create_client :
                    builtin_classes[i].create_window);
            if(!ret)
                FIXME("unhandled window class: %s\n", debugstr_w(class_name));
            return ret;
        }
    }

    idx = SendMessageW(hwnd, WM_GETOBJECT, 0, OBJID_QUERYCLASSNAMEIDX);
    if(idx) {
        for(i=0; i<sizeof(builtin_classes)/sizeof(builtin_classes[0]); i++) {
            if(idx == builtin_classes[i].idx) {
                accessible_create ret;

                ret = (objid==OBJID_CLIENT ?
                        builtin_classes[i].create_client :
                        builtin_classes[i].create_window);
                if(!ret)
                    FIXME("unhandled class name idx: %x\n", idx);
                return ret;
            }
        }

        WARN("unhandled class name idx: %x\n", idx);
    }

    return NULL;
}

HRESULT WINAPI CreateStdAccessibleObject( HWND hwnd, LONG idObject,
        REFIID riidInterface, void** ppvObject )
{
    accessible_create create;

    TRACE("%p %d %s %p\n", hwnd, idObject,
          debugstr_guid( riidInterface ), ppvObject );

    switch(idObject) {
    case OBJID_CLIENT:
        create = get_builtin_accessible_obj(hwnd, idObject);
        if(create) return create(hwnd, riidInterface, ppvObject);
        return create_client_object(hwnd, riidInterface, ppvObject);
    case OBJID_WINDOW:
        create = get_builtin_accessible_obj(hwnd, idObject);
        if(create) return create(hwnd, riidInterface, ppvObject);
        return create_window_object(hwnd, riidInterface, ppvObject);
    default:
        FIXME("unhandled object id: %d\n", idObject);
        return E_NOTIMPL;
    }
}

HRESULT WINAPI ObjectFromLresult( LRESULT result, REFIID riid, WPARAM wParam, void **ppObject )
{
    WCHAR atom_str[sizeof(lresult_atom_prefix)/sizeof(WCHAR)+3*8+3];
    HANDLE server_proc, server_mapping, mapping;
    DWORD proc_id, size;
    IStream *stream;
    HGLOBAL data;
    void *view;
    HRESULT hr;
    WCHAR *p;

    TRACE("%ld %s %ld %p\n", result, debugstr_guid(riid), wParam, ppObject );

    if(wParam)
        FIXME("unsupported wParam = %lx\n", wParam);

    if(!ppObject)
        return E_INVALIDARG;
    *ppObject = NULL;

    if(result != (ATOM)result)
        return E_FAIL;

    if(!GlobalGetAtomNameW(result, atom_str, sizeof(atom_str)/sizeof(WCHAR)))
        return E_FAIL;
    if(memcmp(atom_str, lresult_atom_prefix, sizeof(lresult_atom_prefix)))
        return E_FAIL;
    p = atom_str + sizeof(lresult_atom_prefix)/sizeof(WCHAR);
    proc_id = strtoulW(p, &p, 16);
    if(*p != ':')
        return E_FAIL;
    server_mapping = ULongToHandle( strtoulW(p+1, &p, 16) );
    if(*p != ':')
        return E_FAIL;
    size = strtoulW(p+1, &p, 16);
    if(*p != 0)
        return E_FAIL;

    server_proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, proc_id);
    if(!server_proc)
        return E_FAIL;

    if(!DuplicateHandle(server_proc, server_mapping, GetCurrentProcess(), &mapping,
                0, FALSE, DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS))
        return E_FAIL;
    CloseHandle(server_proc);
    GlobalDeleteAtom(result);

    view = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
    CloseHandle(mapping);
    if(!view)
        return E_FAIL;

    data = GlobalAlloc(GMEM_FIXED, size);
    if(!data) {
        UnmapViewOfFile(view);
        return E_OUTOFMEMORY;
    }
    memcpy(data, view, size);
    UnmapViewOfFile(view);

    hr = CreateStreamOnHGlobal(data, TRUE, &stream);
    if(FAILED(hr)) {
        GlobalFree(data);
        return hr;
    }

    hr = CoUnmarshalInterface(stream, riid, ppObject);
    IStream_Release(stream);
    return hr;
}

LRESULT WINAPI LresultFromObject( REFIID riid, WPARAM wParam, LPUNKNOWN pAcc )
{
    static const WCHAR atom_fmt[] = {'%','0','8','x',':','%','0','8','x',':','%','0','8','x',0};
    static const LARGE_INTEGER seek_zero = {{0}};

    WCHAR atom_str[sizeof(lresult_atom_prefix)/sizeof(WCHAR)+3*8+3];
    IStream *stream;
    HANDLE mapping;
    STATSTG stat;
    HRESULT hr;
    ATOM atom;
    void *view;

    TRACE("%s %ld %p\n", debugstr_guid(riid), wParam, pAcc);

    if(wParam)
        FIXME("unsupported wParam = %lx\n", wParam);

    if(!pAcc)
        return E_INVALIDARG;

    hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
    if(FAILED(hr))
        return hr;

    hr = CoMarshalInterface(stream, riid, pAcc, MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL);
    if(FAILED(hr)) {
        IStream_Release(stream);
        return hr;
    }

    hr = IStream_Seek(stream, seek_zero, STREAM_SEEK_SET, NULL);
    if(FAILED(hr)) {
        IStream_Release(stream);
        return hr;
    }

    hr = IStream_Stat(stream, &stat, STATFLAG_NONAME);
    if(FAILED(hr)) {
        CoReleaseMarshalData(stream);
        IStream_Release(stream);
        return hr;
    }else if(stat.cbSize.u.HighPart) {
        FIXME("stream size to big\n");
        CoReleaseMarshalData(stream);
        IStream_Release(stream);
        return E_NOTIMPL;
    }

    mapping = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
            stat.cbSize.u.HighPart, stat.cbSize.u.LowPart, NULL);
    if(!mapping) {
        CoReleaseMarshalData(stream);
        IStream_Release(stream);
        return hr;
    }

    view = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0);
    if(!view) {
        CloseHandle(mapping);
        CoReleaseMarshalData(stream);
        IStream_Release(stream);
        return E_FAIL;
    }

    hr = IStream_Read(stream, view, stat.cbSize.u.LowPart, NULL);
    UnmapViewOfFile(view);
    if(FAILED(hr)) {
        CloseHandle(mapping);
        hr = IStream_Seek(stream, seek_zero, STREAM_SEEK_SET, NULL);
        if(SUCCEEDED(hr))
            CoReleaseMarshalData(stream);
        IStream_Release(stream);
        return hr;

    }

    memcpy(atom_str, lresult_atom_prefix, sizeof(lresult_atom_prefix));
    sprintfW(atom_str+sizeof(lresult_atom_prefix)/sizeof(WCHAR),
             atom_fmt, GetCurrentProcessId(), HandleToUlong(mapping), stat.cbSize.u.LowPart);
    atom = GlobalAddAtomW(atom_str);
    if(!atom) {
        CloseHandle(mapping);
        hr = IStream_Seek(stream, seek_zero, STREAM_SEEK_SET, NULL);
        if(SUCCEEDED(hr))
            CoReleaseMarshalData(stream);
        IStream_Release(stream);
        return E_FAIL;
    }

    IStream_Release(stream);
    return atom;
}

HRESULT WINAPI AccessibleObjectFromPoint( POINT ptScreen, IAccessible** ppacc, VARIANT* pvarChild )
{
    FIXME("{%d,%d} %p %p: stub\n", ptScreen.x, ptScreen.y, ppacc, pvarChild );
    return E_NOTIMPL;
}

HRESULT WINAPI AccessibleObjectFromWindow( HWND hwnd, DWORD dwObjectID,
                             REFIID riid, void** ppvObject )
{
    TRACE("%p %d %s %p\n", hwnd, dwObjectID,
          debugstr_guid( riid ), ppvObject );

    if(!ppvObject)
        return E_INVALIDARG;
    *ppvObject = NULL;

    if(IsWindow(hwnd)) {
        LRESULT lres;

        lres = SendMessageW(hwnd, WM_GETOBJECT, 0xffffffff, dwObjectID);
        if(FAILED(lres))
            return lres;
        else if(lres)
            return ObjectFromLresult(lres, riid, 0, ppvObject);
    }

    return CreateStdAccessibleObject(hwnd, dwObjectID, riid, ppvObject);
}

HRESULT WINAPI WindowFromAccessibleObject(IAccessible *acc, HWND *phwnd)
{
    IDispatch *parent;
    IOleWindow *ow;
    HRESULT hres;

    TRACE("%p %p\n", acc, phwnd);

    IAccessible_AddRef(acc);
    while(1) {
        hres = IAccessible_QueryInterface(acc, &IID_IOleWindow, (void**)&ow);
        if(SUCCEEDED(hres)) {
            hres = IOleWindow_GetWindow(ow, phwnd);
            IOleWindow_Release(ow);
            IAccessible_Release(acc);
            return hres;
        }

        hres = IAccessible_get_accParent(acc, &parent);
        IAccessible_Release(acc);
        if(FAILED(hres))
            return hres;
        if(hres!=S_OK || !parent) {
            *phwnd = NULL;
            return hres;
        }

        hres = IDispatch_QueryInterface(parent, &IID_IAccessible, (void**)&acc);
        IDispatch_Release(parent);
        if(FAILED(hres))
            return hres;
    }
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
                    LPVOID lpvReserved)
{
    TRACE("%p, %d, %p\n", hinstDLL, fdwReason, lpvReserved);

    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            oleacc_handle = hinstDLL;
            DisableThreadLibraryCalls(hinstDLL);
            break;
    }

    return OLEACC_DllMain(hinstDLL, fdwReason, lpvReserved);
}

HRESULT WINAPI DllRegisterServer(void)
{
    return OLEACC_DllRegisterServer();
}

HRESULT WINAPI DllUnregisterServer(void)
{
    return OLEACC_DllUnregisterServer();
}

HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, void **ppv)
{
    if(IsEqualGUID(&CLSID_CAccPropServices, rclsid)) {
        TRACE("(CLSID_CAccPropServices %s %p)\n", debugstr_guid(iid), ppv);
        return get_accpropservices_factory(iid, ppv);
    }

    if(IsEqualGUID(&CLSID_PSFactoryBuffer, rclsid)) {
        TRACE("(CLSID_PSFactoryBuffer %s %p)\n", debugstr_guid(iid), ppv);
        return OLEACC_DllGetClassObject(rclsid, iid, ppv);
    }

    FIXME("%s %s %p: stub\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
    return E_NOTIMPL;
}

void WINAPI GetOleaccVersionInfo(DWORD* pVersion, DWORD* pBuild)
{
    *pVersion = MAKELONG(0,7); /* Windows 7 version of oleacc: 7.0.0.0 */
    *pBuild = MAKELONG(0,0);
}

HANDLE WINAPI GetProcessHandleFromHwnd(HWND hwnd)
{
    DWORD proc_id;

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

    if(!GetWindowThreadProcessId(hwnd, &proc_id))
        return NULL;
    return OpenProcess(PROCESS_DUP_HANDLE | PROCESS_VM_OPERATION |
            PROCESS_VM_READ | PROCESS_VM_WRITE | SYNCHRONIZE, TRUE, proc_id);
}

UINT WINAPI GetRoleTextW(DWORD role, LPWSTR lpRole, UINT rolemax)
{
    INT ret;
    WCHAR *resptr;

    TRACE("%u %p %u\n", role, lpRole, rolemax);

    /* return role text length */
    if(!lpRole)
        return LoadStringW(oleacc_handle, role, (LPWSTR)&resptr, 0);

    ret = LoadStringW(oleacc_handle, role, lpRole, rolemax);
    if(!(ret > 0)){
        if(rolemax > 0) lpRole[0] = '\0';
        return 0;
    }

    return ret;
}

UINT WINAPI GetRoleTextA(DWORD role, LPSTR lpRole, UINT rolemax)
{
    UINT length;
    WCHAR *roletextW;

    TRACE("%u %p %u\n", role, lpRole, rolemax);

    if(lpRole && !rolemax)
        return 0;

    length = GetRoleTextW(role, NULL, 0);
    if(!length) {
        if(lpRole && rolemax)
            lpRole[0] = 0;
        return 0;
    }

    roletextW = HeapAlloc(GetProcessHeap(), 0, (length + 1)*sizeof(WCHAR));
    if(!roletextW)
        return 0;

    GetRoleTextW(role, roletextW, length + 1);

    length = WideCharToMultiByte( CP_ACP, 0, roletextW, -1, NULL, 0, NULL, NULL );

    if(!lpRole){
        HeapFree(GetProcessHeap(), 0, roletextW);
        return length - 1;
    }

    if(rolemax < length) {
        HeapFree(GetProcessHeap(), 0, roletextW);
        lpRole[0] = 0;
        return 0;
    }

    WideCharToMultiByte( CP_ACP, 0, roletextW, -1, lpRole, rolemax, NULL, NULL );

    if(rolemax < length){
        lpRole[rolemax-1] = '\0';
        length = rolemax;
    }

    HeapFree(GetProcessHeap(), 0, roletextW);

    return length - 1;
}

UINT WINAPI GetStateTextW(DWORD state_bit, WCHAR *state_str, UINT state_str_len)
{
    DWORD state_id;

    TRACE("%x %p %u\n", state_bit, state_str, state_str_len);

    if(state_bit & ~(STATE_SYSTEM_VALID | STATE_SYSTEM_HASPOPUP)) {
        if(state_str && state_str_len)
            state_str[0] = 0;
        return 0;
    }

    state_id = IDS_STATE_NORMAL;
    while(state_bit) {
        state_id++;
        state_bit /= 2;
    }

    if(state_str) {
        UINT ret = LoadStringW(oleacc_handle, state_id, state_str, state_str_len);
        if(!ret && state_str_len)
            state_str[0] = 0;
        return ret;
    }else {
        WCHAR *tmp;
        return LoadStringW(oleacc_handle, state_id, (WCHAR*)&tmp, 0);
    }

}

UINT WINAPI GetStateTextA(DWORD state_bit, CHAR *state_str, UINT state_str_len)
{
    DWORD state_id;

    TRACE("%x %p %u\n", state_bit, state_str, state_str_len);

    if(state_str && !state_str_len)
        return 0;

    if(state_bit & ~(STATE_SYSTEM_VALID | STATE_SYSTEM_HASPOPUP)) {
        if(state_str && state_str_len)
            state_str[0] = 0;
        return 0;
    }

    state_id = IDS_STATE_NORMAL;
    while(state_bit) {
        state_id++;
        state_bit /= 2;
    }

    if(state_str) {
        UINT ret = LoadStringA(oleacc_handle, state_id, state_str, state_str_len);
        if(!ret && state_str_len)
            state_str[0] = 0;
        return ret;
    }else {
        CHAR tmp[256];
        return LoadStringA(oleacc_handle, state_id, tmp, sizeof(tmp));
    }
}

HRESULT WINAPI AccessibleChildren(IAccessible *container,
        LONG start, LONG count, VARIANT *children, LONG *children_cnt)
{
    IEnumVARIANT *ev;
    LONG i, child_no;
    HRESULT hr;

    TRACE("%p %d %d %p %p\n", container, start, count, children, children_cnt);

    if(!container || !children || !children_cnt)
        return E_INVALIDARG;

    for(i=0; i<count; i++)
        VariantInit(children+i);

    hr = IAccessible_QueryInterface(container, &IID_IEnumVARIANT, (void**)&ev);
    if(SUCCEEDED(hr)) {
        hr = IEnumVARIANT_Reset(ev);
        if(SUCCEEDED(hr))
            hr = IEnumVARIANT_Skip(ev, start);
        if(SUCCEEDED(hr))
            hr = IEnumVARIANT_Next(ev, count, children, (ULONG*)children_cnt);
        IEnumVARIANT_Release(ev);
        return hr;
    }

    hr = IAccessible_get_accChildCount(container, &child_no);
    if(FAILED(hr))
        return hr;

    for(i=0; i<count && start+i+1<=child_no; i++) {
        IDispatch *disp;

        V_VT(children+i) = VT_I4;
        V_I4(children+i) = start+i+1;

        hr = IAccessible_get_accChild(container, children[i], &disp);
        if(SUCCEEDED(hr) && disp) {
            V_VT(children+i) = VT_DISPATCH;
            V_DISPATCH(children+i) = disp;
        }
    }

    *children_cnt = i;
    return i==count ? S_OK : S_FALSE;
}
