/*
 *  ITfCategoryMgr implementation
 *
 *  Copyright 2009 Aric Stewart, 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
 */

#include "config.h"

#include <stdarg.h>

#define COBJMACROS

#include "wine/debug.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winuser.h"
#include "shlwapi.h"
#include "winerror.h"
#include "objbase.h"

#include "wine/unicode.h"

#include "msctf.h"
#include "msctf_internal.h"

WINE_DEFAULT_DEBUG_CHANNEL(msctf);

typedef struct tagCategoryMgr {
    ITfCategoryMgr ITfCategoryMgr_iface;
    LONG refCount;
} CategoryMgr;

static inline CategoryMgr *impl_from_ITfCategoryMgr(ITfCategoryMgr *iface)
{
    return CONTAINING_RECORD(iface, CategoryMgr, ITfCategoryMgr_iface);
}

static void CategoryMgr_Destructor(CategoryMgr *This)
{
    TRACE("destroying %p\n", This);
    HeapFree(GetProcessHeap(),0,This);
}

static HRESULT WINAPI CategoryMgr_QueryInterface(ITfCategoryMgr *iface, REFIID iid, LPVOID *ppvOut)
{
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);
    *ppvOut = NULL;

    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfCategoryMgr))
    {
        *ppvOut = This;
    }

    if (*ppvOut)
    {
        IUnknown_AddRef(iface);
        return S_OK;
    }

    WARN("unsupported interface: %s\n", debugstr_guid(iid));
    return E_NOINTERFACE;
}

static ULONG WINAPI CategoryMgr_AddRef(ITfCategoryMgr *iface)
{
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);
    return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI CategoryMgr_Release(ITfCategoryMgr *iface)
{
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);
    ULONG ret;

    ret = InterlockedDecrement(&This->refCount);
    if (ret == 0)
        CategoryMgr_Destructor(This);
    return ret;
}

/*****************************************************
 * ITfCategoryMgr functions
 *****************************************************/

static HRESULT WINAPI CategoryMgr_RegisterCategory ( ITfCategoryMgr *iface,
        REFCLSID rclsid, REFGUID rcatid, REFGUID rguid)
{
    WCHAR fullkey[110];
    WCHAR buf[39];
    WCHAR buf2[39];
    ULONG res;
    HKEY tipkey,catkey,itmkey;
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);

    static const WCHAR ctg[] = {'C','a','t','e','g','o','r','y',0};
    static const WCHAR itm[] = {'I','t','e','m',0};
    static const WCHAR fmt[] = {'%','s','\\','%','s',0};
    static const WCHAR fmt2[] = {'%','s','\\','%','s','\\','%','s','\\','%','s',0};

    TRACE("(%p) %s %s %s\n",This,debugstr_guid(rclsid), debugstr_guid(rcatid), debugstr_guid(rguid));

    StringFromGUID2(rclsid, buf, 39);
    sprintfW(fullkey,fmt,szwSystemTIPKey,buf);

    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ | KEY_WRITE,
                &tipkey ) != ERROR_SUCCESS)
        return E_FAIL;

    StringFromGUID2(rcatid, buf, 39);
    StringFromGUID2(rguid, buf2, 39);
    sprintfW(fullkey,fmt2,ctg,ctg,buf,buf2);

    res = RegCreateKeyExW(tipkey, fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
            NULL, &catkey, NULL);
    RegCloseKey(catkey);

    if (!res)
    {
        sprintfW(fullkey,fmt2,ctg,itm,buf2,buf);
        res = RegCreateKeyExW(tipkey, fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
                NULL, &itmkey, NULL);

        RegCloseKey(itmkey);
    }

    RegCloseKey(tipkey);

    if (!res)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI CategoryMgr_UnregisterCategory ( ITfCategoryMgr *iface,
        REFCLSID rclsid, REFGUID rcatid, REFGUID rguid)
{
    WCHAR fullkey[110];
    WCHAR buf[39];
    WCHAR buf2[39];
    HKEY tipkey;
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);

    static const WCHAR ctg[] = {'C','a','t','e','g','o','r','y',0};
    static const WCHAR itm[] = {'I','t','e','m',0};
    static const WCHAR fmt[] = {'%','s','\\','%','s',0};
    static const WCHAR fmt2[] = {'%','s','\\','%','s','\\','%','s','\\','%','s',0};

    TRACE("(%p) %s %s %s\n",This,debugstr_guid(rclsid), debugstr_guid(rcatid), debugstr_guid(rguid));

    StringFromGUID2(rclsid, buf, 39);
    sprintfW(fullkey,fmt,szwSystemTIPKey,buf);

    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ | KEY_WRITE,
                &tipkey ) != ERROR_SUCCESS)
        return E_FAIL;

    StringFromGUID2(rcatid, buf, 39);
    StringFromGUID2(rguid, buf2, 39);
    sprintfW(fullkey,fmt2,ctg,ctg,buf,buf2);

    sprintfW(fullkey,fmt2,ctg,itm,buf2,buf);
    RegDeleteTreeW(tipkey, fullkey);
    sprintfW(fullkey,fmt2,ctg,itm,buf2,buf);
    RegDeleteTreeW(tipkey, fullkey);

    RegCloseKey(tipkey);
    return S_OK;
}

static HRESULT WINAPI CategoryMgr_EnumCategoriesInItem ( ITfCategoryMgr *iface,
        REFGUID rguid, IEnumGUID **ppEnum)
{
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI CategoryMgr_EnumItemsInCategory ( ITfCategoryMgr *iface,
        REFGUID rcatid, IEnumGUID **ppEnum)
{
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI CategoryMgr_FindClosestCategory ( ITfCategoryMgr *iface,
        REFGUID rguid, GUID *pcatid, const GUID **ppcatidList, ULONG ulCount)
{
    static const WCHAR fmt[] = { '%','s','\\','%','s','\\','C','a','t','e','g','o','r','y','\\','I','t','e','m','\\','%','s',0};

    WCHAR fullkey[110];
    WCHAR buf[39];
    HKEY key;
    HRESULT hr = S_FALSE;
    INT index = 0;
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);

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

    if (!pcatid || (ulCount && ppcatidList == NULL))
        return E_INVALIDARG;

    StringFromGUID2(rguid, buf, 39);
    sprintfW(fullkey,fmt,szwSystemTIPKey,buf,buf);
    *pcatid = GUID_NULL;

    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ, &key ) !=
            ERROR_SUCCESS)
        return S_FALSE;

    while (1)
    {
        HRESULT hr2;
        ULONG res;
        GUID guid;
        WCHAR catid[39];
        DWORD cName;

        cName = 39;
        res = RegEnumKeyExW(key, index, catid, &cName, NULL, NULL, NULL, NULL);
        if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
        index ++;

        hr2 = CLSIDFromString(catid, &guid);
        if (FAILED(hr2)) continue;

        if (ulCount)
        {
            int j;
            BOOL found = FALSE;
            for (j = 0; j < ulCount; j++)
                if (IsEqualGUID(&guid, ppcatidList[j]))
                {
                    found = TRUE;
                    *pcatid = guid;
                    hr = S_OK;
                    break;
                }
            if (found) break;
        }
        else
        {
            *pcatid = guid;
            hr = S_OK;
            break;
        }
    }

    return hr;
}

static HRESULT WINAPI CategoryMgr_RegisterGUIDDescription (
        ITfCategoryMgr *iface, REFCLSID rclsid, REFGUID rguid,
        const WCHAR *pchDesc, ULONG cch)
{
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI CategoryMgr_UnregisterGUIDDescription (
        ITfCategoryMgr *iface, REFCLSID rclsid, REFGUID rguid)
{
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI CategoryMgr_GetGUIDDescription ( ITfCategoryMgr *iface,
        REFGUID rguid, BSTR *pbstrDesc)
{
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI CategoryMgr_RegisterGUIDDWORD ( ITfCategoryMgr *iface,
        REFCLSID rclsid, REFGUID rguid, DWORD dw)
{
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI CategoryMgr_UnregisterGUIDDWORD ( ITfCategoryMgr *iface,
        REFCLSID rclsid, REFGUID rguid)
{
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI CategoryMgr_GetGUIDDWORD ( ITfCategoryMgr *iface,
        REFGUID rguid, DWORD *pdw)
{
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI CategoryMgr_RegisterGUID ( ITfCategoryMgr *iface,
        REFGUID rguid, TfGuidAtom *pguidatom
)
{
    DWORD index;
    GUID *checkguid;
    DWORD id;
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);

    TRACE("(%p) %s %p\n",This,debugstr_guid(rguid),pguidatom);

    if (!pguidatom)
        return E_INVALIDARG;

    index = 0;
    do {
        id = enumerate_Cookie(COOKIE_MAGIC_GUIDATOM,&index);
        if (id && IsEqualGUID(rguid,get_Cookie_data(id)))
        {
            *pguidatom = id;
            return S_OK;
        }
    } while(id);

    checkguid = HeapAlloc(GetProcessHeap(),0,sizeof(GUID));
    *checkguid = *rguid;
    id = generate_Cookie(COOKIE_MAGIC_GUIDATOM,checkguid);

    if (!id)
    {
        HeapFree(GetProcessHeap(),0,checkguid);
        return E_FAIL;
    }

    *pguidatom = id;

    return S_OK;
}

static HRESULT WINAPI CategoryMgr_GetGUID ( ITfCategoryMgr *iface,
        TfGuidAtom guidatom, GUID *pguid)
{
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);

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

    if (!pguid)
        return E_INVALIDARG;

    *pguid = GUID_NULL;

    if (get_Cookie_magic(guidatom) == COOKIE_MAGIC_GUIDATOM)
        *pguid = *((REFGUID)get_Cookie_data(guidatom));

    return S_OK;
}

static HRESULT WINAPI CategoryMgr_IsEqualTfGuidAtom ( ITfCategoryMgr *iface,
        TfGuidAtom guidatom, REFGUID rguid, BOOL *pfEqual)
{
    CategoryMgr *This = impl_from_ITfCategoryMgr(iface);

    TRACE("(%p) %i %s %p\n",This,guidatom,debugstr_guid(rguid),pfEqual);

    if (!pfEqual)
        return E_INVALIDARG;

    *pfEqual = FALSE;
    if (get_Cookie_magic(guidatom) == COOKIE_MAGIC_GUIDATOM)
    {
        if (IsEqualGUID(rguid,get_Cookie_data(guidatom)))
            *pfEqual = TRUE;
    }

    return S_OK;
}


static const ITfCategoryMgrVtbl CategoryMgr_CategoryMgrVtbl =
{
    CategoryMgr_QueryInterface,
    CategoryMgr_AddRef,
    CategoryMgr_Release,

    CategoryMgr_RegisterCategory,
    CategoryMgr_UnregisterCategory,
    CategoryMgr_EnumCategoriesInItem,
    CategoryMgr_EnumItemsInCategory,
    CategoryMgr_FindClosestCategory,
    CategoryMgr_RegisterGUIDDescription,
    CategoryMgr_UnregisterGUIDDescription,
    CategoryMgr_GetGUIDDescription,
    CategoryMgr_RegisterGUIDDWORD,
    CategoryMgr_UnregisterGUIDDWORD,
    CategoryMgr_GetGUIDDWORD,
    CategoryMgr_RegisterGUID,
    CategoryMgr_GetGUID,
    CategoryMgr_IsEqualTfGuidAtom
};

HRESULT CategoryMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
{
    CategoryMgr *This;
    if (pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CategoryMgr));
    if (This == NULL)
        return E_OUTOFMEMORY;

    This->ITfCategoryMgr_iface.lpVtbl = &CategoryMgr_CategoryMgrVtbl;
    This->refCount = 1;

    TRACE("returning %p\n", This);
    *ppOut = (IUnknown *)This;
    return S_OK;
}
