/*
 * Copyright (C) 2012 Alistair Leslie-Hughes
 * Copyright 2015 Nikolay Sivov 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 "config.h"
#include "wine/port.h"

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "ole2.h"
#include "olectl.h"
#include "dispex.h"
#include "scrrun.h"
#include "scrrun_private.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(scrrun);

#define BUCKET_COUNT  509
#define DICT_HASH_MOD 1201

/* Implementation details

   Dictionary contains one list that links all pairs, this way
   order in which they were added is preserved. Each bucket has
   its own list to hold all pairs in this bucket. Initially all
   bucket lists are zeroed and we init them once we about to add
   first pair.

   When pair is removed it's unlinked from both lists; if it was
   a last pair in a bucket list it stays empty in initialized state.

   Preserving pair order is important for enumeration, so far testing
   indicates that pairs are not reordered basing on hash value.
 */

struct keyitem_pair {
    struct  list entry;
    struct  list bucket;
    DWORD   hash;
    VARIANT key;
    VARIANT item;
};

typedef struct
{
    struct provideclassinfo classinfo;
    IDictionary IDictionary_iface;
    LONG ref;

    CompareMethod method;
    LONG count;
    struct list pairs;
    struct list buckets[BUCKET_COUNT];
    struct list notifier;
} dictionary;

struct dictionary_enum {
    IEnumVARIANT IEnumVARIANT_iface;
    LONG ref;

    dictionary *dict;
    struct list *cur;
    struct list notify;
};

static inline dictionary *impl_from_IDictionary(IDictionary *iface)
{
    return CONTAINING_RECORD(iface, dictionary, IDictionary_iface);
}

static inline struct dictionary_enum *impl_from_IEnumVARIANT(IEnumVARIANT *iface)
{
    return CONTAINING_RECORD(iface, struct dictionary_enum, IEnumVARIANT_iface);
}

static inline struct list *get_bucket_head(dictionary *dict, DWORD hash)
{
    return &dict->buckets[hash % BUCKET_COUNT];
}

static inline BOOL is_string_key(const VARIANT *key)
{
    return V_VT(key) == VT_BSTR || V_VT(key) == (VT_BSTR|VT_BYREF);
}

/* Only for VT_BSTR or VT_BSTR|VT_BYREF types */
static inline WCHAR *get_key_strptr(const VARIANT *key)
{
    if (V_VT(key) == VT_BSTR)
        return V_BSTR(key);

    if (V_BSTRREF(key))
        return *V_BSTRREF(key);

    return NULL;
}

/* should be used only when both keys are of string type, it's not checked */
static inline int strcmp_key(const dictionary *dict, const VARIANT *key1, const VARIANT *key2)
{
    const WCHAR *str1, *str2;

    str1 = get_key_strptr(key1);
    str2 = get_key_strptr(key2);
    return dict->method == BinaryCompare ? strcmpW(str1, str2) : strcmpiW(str1, str2);
}

static BOOL is_matching_key(const dictionary *dict, const struct keyitem_pair *pair, const VARIANT *key, DWORD hash)
{
    if (is_string_key(key) && is_string_key(&pair->key)) {
        if (hash != pair->hash)
            return FALSE;

        return strcmp_key(dict, key, &pair->key) == 0;
    }

    if ((is_string_key(key) && !is_string_key(&pair->key)) ||
        (!is_string_key(key) && is_string_key(&pair->key)))
        return FALSE;

    /* for numeric keys only check hash */
    return hash == pair->hash;
}

static struct keyitem_pair *get_keyitem_pair(dictionary *dict, VARIANT *key)
{
    struct keyitem_pair *pair;
    struct list *head, *entry;
    VARIANT hash;
    HRESULT hr;

    hr = IDictionary_get_HashVal(&dict->IDictionary_iface, key, &hash);
    if (FAILED(hr))
        return NULL;

    head = get_bucket_head(dict, V_I4(&hash));
    if (!head->next || list_empty(head))
        return NULL;

    entry = list_head(head);
    do {
        pair = LIST_ENTRY(entry, struct keyitem_pair, bucket);
        if (is_matching_key(dict, pair, key, V_I4(&hash))) return pair;
    } while ((entry = list_next(head, entry)));

    return NULL;
}

static HRESULT add_keyitem_pair(dictionary *dict, VARIANT *key, VARIANT *item)
{
    struct keyitem_pair *pair;
    struct list *head;
    VARIANT hash;
    HRESULT hr;

    hr = IDictionary_get_HashVal(&dict->IDictionary_iface, key, &hash);
    if (FAILED(hr))
        return hr;

    pair = heap_alloc(sizeof(*pair));
    if (!pair)
        return E_OUTOFMEMORY;

    pair->hash = V_I4(&hash);
    VariantInit(&pair->key);
    VariantInit(&pair->item);

    hr = VariantCopyInd(&pair->key, key);
    if (FAILED(hr))
        goto failed;

    hr = VariantCopyInd(&pair->item, item);
    if (FAILED(hr))
        goto failed;

    head = get_bucket_head(dict, pair->hash);
    if (!head->next)
        /* this only happens once per bucket */
        list_init(head);

    /* link to bucket list and to full list */
    list_add_tail(head, &pair->bucket);
    list_add_tail(&dict->pairs, &pair->entry);
    dict->count++;
    return S_OK;

failed:
    VariantClear(&pair->key);
    VariantClear(&pair->item);
    heap_free(pair);
    return hr;
}

static void free_keyitem_pair(struct keyitem_pair *pair)
{
    VariantClear(&pair->key);
    VariantClear(&pair->item);
    heap_free(pair);
}

static HRESULT WINAPI dict_enum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **obj)
{
    struct dictionary_enum *This = impl_from_IEnumVARIANT(iface);

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

    if (IsEqualIID(riid, &IID_IEnumVARIANT) || IsEqualIID(riid, &IID_IUnknown)) {
        *obj = iface;
        IEnumVARIANT_AddRef(iface);
        return S_OK;
    }
    else {
        WARN("interface not supported %s\n", debugstr_guid(riid));
        *obj = NULL;
        return E_NOINTERFACE;
    }
}

static ULONG WINAPI dict_enum_AddRef(IEnumVARIANT *iface)
{
    struct dictionary_enum *This = impl_from_IEnumVARIANT(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p)->(%u)\n", This, ref);
    return ref;
}

static ULONG WINAPI dict_enum_Release(IEnumVARIANT *iface)
{
    struct dictionary_enum *This = impl_from_IEnumVARIANT(iface);
    LONG ref = InterlockedDecrement(&This->ref);

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

    if (!ref) {
        list_remove(&This->notify);
        IDictionary_Release(&This->dict->IDictionary_iface);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI dict_enum_Next(IEnumVARIANT *iface, ULONG count, VARIANT *keys, ULONG *fetched)
{
    struct dictionary_enum *This = impl_from_IEnumVARIANT(iface);
    struct keyitem_pair *pair;
    ULONG i = 0;

    TRACE("(%p)->(%u %p %p)\n", This, count, keys, fetched);

    if (fetched)
        *fetched = 0;

    if (!count)
        return S_OK;

    while (This->cur && i < count) {
        pair = LIST_ENTRY(This->cur, struct keyitem_pair, entry);
        VariantCopy(&keys[i], &pair->key);
        This->cur = list_next(&This->dict->pairs, This->cur);
        i++;
    }

    if (fetched)
        *fetched = i;

    return i < count ? S_FALSE : S_OK;
}

static HRESULT WINAPI dict_enum_Skip(IEnumVARIANT *iface, ULONG count)
{
    struct dictionary_enum *This = impl_from_IEnumVARIANT(iface);

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

    if (!count)
        return S_OK;

    if (!This->cur)
        return S_FALSE;

    while (count--) {
        This->cur = list_next(&This->dict->pairs, This->cur);
        if (!This->cur) break;
    }

    return count == 0 ? S_OK : S_FALSE;
}

static HRESULT WINAPI dict_enum_Reset(IEnumVARIANT *iface)
{
    struct dictionary_enum *This = impl_from_IEnumVARIANT(iface);

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

    This->cur = list_head(&This->dict->pairs);
    return S_OK;
}

static HRESULT create_dict_enum(dictionary*, IUnknown**);

static HRESULT WINAPI dict_enum_Clone(IEnumVARIANT *iface, IEnumVARIANT **cloned)
{
    struct dictionary_enum *This = impl_from_IEnumVARIANT(iface);
    TRACE("(%p)->(%p)\n", This, cloned);
    return create_dict_enum(This->dict, (IUnknown**)cloned);
}

static const IEnumVARIANTVtbl dictenumvtbl = {
    dict_enum_QueryInterface,
    dict_enum_AddRef,
    dict_enum_Release,
    dict_enum_Next,
    dict_enum_Skip,
    dict_enum_Reset,
    dict_enum_Clone
};

static HRESULT create_dict_enum(dictionary *dict, IUnknown **ret)
{
    struct dictionary_enum *This;

    *ret = NULL;

    This = heap_alloc(sizeof(*This));
    if (!This)
        return E_OUTOFMEMORY;

    This->IEnumVARIANT_iface.lpVtbl = &dictenumvtbl;
    This->ref = 1;
    This->cur = list_head(&dict->pairs);
    list_add_tail(&dict->notifier, &This->notify);
    This->dict = dict;
    IDictionary_AddRef(&dict->IDictionary_iface);

    *ret = (IUnknown*)&This->IEnumVARIANT_iface;
    return S_OK;
}

static void notify_remove_pair(struct list *notifier, struct list *pair)
{
    struct dictionary_enum *dict_enum;
    struct list *cur;

    LIST_FOR_EACH(cur, notifier) {
        dict_enum = LIST_ENTRY(cur, struct dictionary_enum, notify);
        if (!pair)
            dict_enum->cur = list_head(&dict_enum->dict->pairs);
        else if (dict_enum->cur == pair) {
            dict_enum->cur = list_next(&dict_enum->dict->pairs, dict_enum->cur);
        }
    }
}

static HRESULT WINAPI dictionary_QueryInterface(IDictionary *iface, REFIID riid, void **obj)
{
    dictionary *This = impl_from_IDictionary(iface);
    TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);

    *obj = NULL;

    if(IsEqualIID(riid, &IID_IUnknown) ||
       IsEqualIID(riid, &IID_IDispatch) ||
       IsEqualIID(riid, &IID_IDictionary))
    {
        *obj = &This->IDictionary_iface;
    }
    else if (IsEqualIID(riid, &IID_IProvideClassInfo))
    {
        *obj = &This->classinfo.IProvideClassInfo_iface;
    }
    else if ( IsEqualGUID( riid, &IID_IDispatchEx ))
    {
        TRACE("Interface IDispatchEx not supported - returning NULL\n");
        *obj = NULL;
        return E_NOINTERFACE;
    }
    else if ( IsEqualGUID( riid, &IID_IObjectWithSite ))
    {
        TRACE("Interface IObjectWithSite not supported - returning NULL\n");
        *obj = NULL;
        return E_NOINTERFACE;
    }
    else
    {
        WARN("interface %s not implemented\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*obj);
    return S_OK;
}

static ULONG WINAPI dictionary_AddRef(IDictionary *iface)
{
    dictionary *This = impl_from_IDictionary(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI dictionary_Release(IDictionary *iface)
{
    dictionary *This = impl_from_IDictionary(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if (!ref) {
        IDictionary_RemoveAll(iface);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI dictionary_GetTypeInfoCount(IDictionary *iface, UINT *pctinfo)
{
    dictionary *This = impl_from_IDictionary(iface);

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

    *pctinfo = 1;
    return S_OK;
}

static HRESULT WINAPI dictionary_GetTypeInfo(IDictionary *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
    dictionary *This = impl_from_IDictionary(iface);

    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
    return get_typeinfo(IDictionary_tid, ppTInfo);
}

static HRESULT WINAPI dictionary_GetIDsOfNames(IDictionary *iface, REFIID riid, LPOLESTR *rgszNames,
                UINT cNames, LCID lcid, DISPID *rgDispId)
{
    dictionary *This = impl_from_IDictionary(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);

    hr = get_typeinfo(IDictionary_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI dictionary_Invoke(IDictionary *iface, DISPID dispIdMember, REFIID riid,
                LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
                EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    dictionary *This = impl_from_IDictionary(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    hr = get_typeinfo(IDictionary_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke(typeinfo, &This->IDictionary_iface, dispIdMember, wFlags,
                pDispParams, pVarResult, pExcepInfo, puArgErr);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI dictionary_putref_Item(IDictionary *iface, VARIANT *Key, VARIANT *pRetItem)
{
    dictionary *This = impl_from_IDictionary(iface);

    FIXME("(%p)->(%p %p)\n", This, Key, pRetItem);

    return E_NOTIMPL;
}

static HRESULT WINAPI dictionary_put_Item(IDictionary *iface, VARIANT *key, VARIANT *item)
{
    dictionary *This = impl_from_IDictionary(iface);
    struct keyitem_pair *pair;

    TRACE("(%p)->(%s %s)\n", This, debugstr_variant(key), debugstr_variant(item));

    if ((pair = get_keyitem_pair(This, key)))
        return VariantCopyInd(&pair->item, item);

    return IDictionary_Add(iface, key, item);
}

static HRESULT WINAPI dictionary_get_Item(IDictionary *iface, VARIANT *key, VARIANT *item)
{
    dictionary *This = impl_from_IDictionary(iface);
    struct keyitem_pair *pair;

    TRACE("(%p)->(%s %p)\n", This, debugstr_variant(key), item);

    if ((pair = get_keyitem_pair(This, key)))
        VariantCopy(item, &pair->item);
    else {
        VariantInit(item);
        return IDictionary_Add(iface, key, item);
    }

    return S_OK;
}

static HRESULT WINAPI dictionary_Add(IDictionary *iface, VARIANT *key, VARIANT *item)
{
    dictionary *This = impl_from_IDictionary(iface);

    TRACE("(%p)->(%s %s)\n", This, debugstr_variant(key), debugstr_variant(item));

    if (get_keyitem_pair(This, key))
        return CTL_E_KEY_ALREADY_EXISTS;

    return add_keyitem_pair(This, key, item);
}

static HRESULT WINAPI dictionary_get_Count(IDictionary *iface, LONG *count)
{
    dictionary *This = impl_from_IDictionary(iface);

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

    *count = This->count;
    return S_OK;
}

static HRESULT WINAPI dictionary_Exists(IDictionary *iface, VARIANT *key, VARIANT_BOOL *exists)
{
    dictionary *This = impl_from_IDictionary(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_variant(key), exists);

    if (!exists)
        return CTL_E_ILLEGALFUNCTIONCALL;

    *exists = get_keyitem_pair(This, key) != NULL ? VARIANT_TRUE : VARIANT_FALSE;
    return S_OK;
}

static HRESULT WINAPI dictionary_Items(IDictionary *iface, VARIANT *items)
{
    dictionary *This = impl_from_IDictionary(iface);
    struct keyitem_pair *pair;
    SAFEARRAYBOUND bound;
    SAFEARRAY *sa;
    VARIANT *v;
    HRESULT hr;
    LONG i;

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

    if (!items)
        return S_OK;

    bound.lLbound = 0;
    bound.cElements = This->count;
    sa = SafeArrayCreate(VT_VARIANT, 1, &bound);
    if (!sa)
        return E_OUTOFMEMORY;

    hr = SafeArrayAccessData(sa, (void**)&v);
    if (FAILED(hr)) {
        SafeArrayDestroy(sa);
        return hr;
    }

    i = 0;
    LIST_FOR_EACH_ENTRY(pair, &This->pairs, struct keyitem_pair, entry) {
        VariantCopy(&v[i], &pair->item);
        i++;
    }
    SafeArrayUnaccessData(sa);

    V_VT(items) = VT_ARRAY|VT_VARIANT;
    V_ARRAY(items) = sa;
    return S_OK;
}

static HRESULT WINAPI dictionary_put_Key(IDictionary *iface, VARIANT *key, VARIANT *newkey)
{
    dictionary *This = impl_from_IDictionary(iface);
    struct keyitem_pair *pair;
    VARIANT empty;
    HRESULT hr;

    TRACE("(%p)->(%s %s)\n", This, debugstr_variant(key), debugstr_variant(newkey));

    if ((pair = get_keyitem_pair(This, key))) {
        /* found existing pair for a key, add new pair with new key
           and old item and remove old pair after that */

        hr = IDictionary_Add(iface, newkey, &pair->item);
        if (FAILED(hr))
            return hr;

        return IDictionary_Remove(iface, key);
    }

    VariantInit(&empty);
    return IDictionary_Add(iface, newkey, &empty);
}

static HRESULT WINAPI dictionary_Keys(IDictionary *iface, VARIANT *keys)
{
    dictionary *This = impl_from_IDictionary(iface);
    struct keyitem_pair *pair;
    SAFEARRAYBOUND bound;
    SAFEARRAY *sa;
    VARIANT *v;
    HRESULT hr;
    LONG i;

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

    if (!keys)
        return S_OK;

    bound.lLbound = 0;
    bound.cElements = This->count;
    sa = SafeArrayCreate(VT_VARIANT, 1, &bound);
    if (!sa)
        return E_OUTOFMEMORY;

    hr = SafeArrayAccessData(sa, (void**)&v);
    if (FAILED(hr)) {
        SafeArrayDestroy(sa);
        return hr;
    }

    i = 0;
    LIST_FOR_EACH_ENTRY(pair, &This->pairs, struct keyitem_pair, entry) {
        VariantCopy(&v[i], &pair->key);
        i++;
    }
    SafeArrayUnaccessData(sa);

    V_VT(keys) = VT_ARRAY|VT_VARIANT;
    V_ARRAY(keys) = sa;
    return S_OK;
}

static HRESULT WINAPI dictionary_Remove(IDictionary *iface, VARIANT *key)
{
    dictionary *This = impl_from_IDictionary(iface);
    struct keyitem_pair *pair;

    TRACE("(%p)->(%s)\n", This, debugstr_variant(key));

    if (!(pair = get_keyitem_pair(This, key)))
        return CTL_E_ELEMENT_NOT_FOUND;

    notify_remove_pair(&This->notifier, &pair->entry);
    list_remove(&pair->entry);
    list_remove(&pair->bucket);
    This->count--;

    free_keyitem_pair(pair);
    return S_OK;
}

static HRESULT WINAPI dictionary_RemoveAll(IDictionary *iface)
{
    dictionary *This = impl_from_IDictionary(iface);
    struct keyitem_pair *pair, *pair2;

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

    if (This->count == 0)
        return S_OK;

    notify_remove_pair(&This->notifier, NULL);
    LIST_FOR_EACH_ENTRY_SAFE(pair, pair2, &This->pairs, struct keyitem_pair, entry) {
        list_remove(&pair->entry);
        list_remove(&pair->bucket);
        free_keyitem_pair(pair);
    }
    This->count = 0;

    return S_OK;
}

static HRESULT WINAPI dictionary_put_CompareMode(IDictionary *iface, CompareMethod method)
{
    dictionary *This = impl_from_IDictionary(iface);

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

    if (This->count)
        return CTL_E_ILLEGALFUNCTIONCALL;

    This->method = method;
    return S_OK;
}

static HRESULT WINAPI dictionary_get_CompareMode(IDictionary *iface, CompareMethod *method)
{
    dictionary *This = impl_from_IDictionary(iface);

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

    *method = This->method;
    return S_OK;
}

static HRESULT WINAPI dictionary__NewEnum(IDictionary *iface, IUnknown **ret)
{
    dictionary *This = impl_from_IDictionary(iface);

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

    return create_dict_enum(This, ret);
}

static DWORD get_str_hash(const WCHAR *str, CompareMethod method)
{
    DWORD hash = 0;

    if (str) {
        while (*str) {
            WCHAR ch;

            ch = (method == TextCompare || method == DatabaseCompare) ? tolowerW(*str) : *str;

            hash += (hash << 4) + ch;
            str++;
        }
    }

    return hash % DICT_HASH_MOD;
}

static DWORD get_num_hash(FLOAT num)
{
    return (*((DWORD*)&num)) % DICT_HASH_MOD;
}

static HRESULT get_flt_hash(FLOAT flt, LONG *hash)
{
    if (isinf(flt)) {
        *hash = 0;
        return S_OK;
    }
    else if (!isnan(flt)) {
        *hash = get_num_hash(flt);
        return S_OK;
    }

    /* NaN case */
    *hash = ~0u;
    return CTL_E_ILLEGALFUNCTIONCALL;
}

static DWORD get_ptr_hash(void *ptr)
{
    return PtrToUlong(ptr) % DICT_HASH_MOD;
}

static HRESULT WINAPI dictionary_get_HashVal(IDictionary *iface, VARIANT *key, VARIANT *hash)
{
    dictionary *This = impl_from_IDictionary(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_variant(key), hash);

    V_VT(hash) = VT_I4;
    switch (V_VT(key))
    {
    case VT_BSTR|VT_BYREF:
    case VT_BSTR:
        V_I4(hash) = get_str_hash(get_key_strptr(key), This->method);
        break;
    case VT_UI1|VT_BYREF:
    case VT_UI1:
        V_I4(hash) = get_num_hash(V_VT(key) & VT_BYREF ? *V_UI1REF(key) : V_UI1(key));
        break;
    case VT_I2|VT_BYREF:
    case VT_I2:
        V_I4(hash) = get_num_hash(V_VT(key) & VT_BYREF ? *V_I2REF(key) : V_I2(key));
        break;
    case VT_I4|VT_BYREF:
    case VT_I4:
        V_I4(hash) = get_num_hash(V_VT(key) & VT_BYREF ? *V_I4REF(key) : V_I4(key));
        break;
    case VT_UNKNOWN|VT_BYREF:
    case VT_DISPATCH|VT_BYREF:
    case VT_UNKNOWN:
    case VT_DISPATCH:
    {
        IUnknown *src = (V_VT(key) & VT_BYREF) ? *V_UNKNOWNREF(key) : V_UNKNOWN(key);
        IUnknown *unk = NULL;

        if (!src) {
            V_I4(hash) = 0;
            return S_OK;
        }

        IUnknown_QueryInterface(src, &IID_IUnknown, (void**)&unk);
        if (!unk) {
            V_I4(hash) = ~0u;
            return CTL_E_ILLEGALFUNCTIONCALL;
        }
        V_I4(hash) = get_ptr_hash(unk);
        IUnknown_Release(unk);
        break;
    }
    case VT_DATE|VT_BYREF:
    case VT_DATE:
        return get_flt_hash(V_VT(key) & VT_BYREF ? *V_DATEREF(key) : V_DATE(key), &V_I4(hash));
    case VT_R4|VT_BYREF:
    case VT_R4:
        return get_flt_hash(V_VT(key) & VT_BYREF ? *V_R4REF(key) : V_R4(key), &V_I4(hash));
    case VT_R8|VT_BYREF:
    case VT_R8:
        return get_flt_hash(V_VT(key) & VT_BYREF ? *V_R8REF(key) : V_R8(key), &V_I4(hash));
    case VT_INT:
    case VT_UINT:
    case VT_I1:
    case VT_I8:
    case VT_UI2:
    case VT_UI4:
        V_I4(hash) = ~0u;
        return CTL_E_ILLEGALFUNCTIONCALL;
    default:
        FIXME("not implemented for type %d\n", V_VT(key));
        return E_NOTIMPL;
    }

    return S_OK;
}

static const struct IDictionaryVtbl dictionary_vtbl =
{
    dictionary_QueryInterface,
    dictionary_AddRef,
    dictionary_Release,
    dictionary_GetTypeInfoCount,
    dictionary_GetTypeInfo,
    dictionary_GetIDsOfNames,
    dictionary_Invoke,
    dictionary_putref_Item,
    dictionary_put_Item,
    dictionary_get_Item,
    dictionary_Add,
    dictionary_get_Count,
    dictionary_Exists,
    dictionary_Items,
    dictionary_put_Key,
    dictionary_Keys,
    dictionary_Remove,
    dictionary_RemoveAll,
    dictionary_put_CompareMode,
    dictionary_get_CompareMode,
    dictionary__NewEnum,
    dictionary_get_HashVal
};

HRESULT WINAPI Dictionary_CreateInstance(IClassFactory *factory,IUnknown *outer,REFIID riid, void **obj)
{
    dictionary *This;

    TRACE("(%p, %p, %s, %p)\n", factory, outer, debugstr_guid(riid), obj);

    *obj = NULL;

    This = heap_alloc(sizeof(*This));
    if(!This) return E_OUTOFMEMORY;

    This->IDictionary_iface.lpVtbl = &dictionary_vtbl;
    This->ref = 1;
    This->method = BinaryCompare;
    This->count = 0;
    list_init(&This->pairs);
    list_init(&This->notifier);
    memset(This->buckets, 0, sizeof(This->buckets));

    init_classinfo(&CLSID_Dictionary, (IUnknown *)&This->IDictionary_iface, &This->classinfo);
    *obj = &This->IDictionary_iface;

    return S_OK;
}
