/*
 * 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 "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**);

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;

const char *debugstr_variant(const VARIANT *v)
{
    if(!v)
        return "(null)";

    if(V_ISBYREF(v))
        return wine_dbg_sprintf("{V_BYREF -> %s}", debugstr_variant(V_BYREF(v)));

    switch(V_VT(v)) {
        case VT_EMPTY:
            return "{VT_EMPTY}";
        case VT_NULL:
            return "{VT_NULL}";
        case VT_I2:
            return wine_dbg_sprintf("{VT_I2: %d}", V_I2(v));
        case VT_I4:
            return wine_dbg_sprintf("{VT_I4: %d}", V_I4(v));
        case VT_UI4:
            return wine_dbg_sprintf("{VT_UI4: %u}", V_UI4(v));
        case VT_R8:
            return wine_dbg_sprintf("{VT_R8: %lf}", V_R8(v));
        case VT_BSTR:
            return wine_dbg_sprintf("{VT_BSTR: %s}", debugstr_w(V_BSTR(v)));
        case VT_DISPATCH:
            return wine_dbg_sprintf("{VT_DISPATCH: %p}", V_DISPATCH(v));
        case VT_BOOL:
            return wine_dbg_sprintf("{VT_BOOL: %x}", V_BOOL(v));
        default:
            return wine_dbg_sprintf("{vt %d}", V_VT(v));
    }
}

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);
    memcpy(data, view, size);
    UnmapViewOfFile(view);
    if(!data)
        return E_OUTOFMEMORY;

    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 TRUE;
}

HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, void **ppv)
{
    FIXME("%s %s %p: stub\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
    return E_NOTIMPL;
}

HRESULT WINAPI DllRegisterServer(void)
{
    FIXME("\n");
    return S_OK;
}

HRESULT WINAPI DllUnregisterServer(void)
{
    FIXME("\n");
    return S_OK;
}

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));
    }
}
