/*
 *  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 {
    const ITfCategoryMgrVtbl *CategoryMgrVtbl;
    LONG refCount;
} CategoryMgr;

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 = (CategoryMgr *)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 = (CategoryMgr *)iface;
    return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI CategoryMgr_Release(ITfCategoryMgr *iface)
{
    CategoryMgr *This = (CategoryMgr *)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 = (CategoryMgr*)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)
{
    CategoryMgr *This = (CategoryMgr*)iface;
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

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

static HRESULT WINAPI CategoryMgr_EnumItemsInCategory ( ITfCategoryMgr *iface,
        REFGUID rcatid, IEnumGUID **ppEnum)
{
    CategoryMgr *This = (CategoryMgr*)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 = (CategoryMgr*)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 = (CategoryMgr*)iface;
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

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

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

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

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

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

static HRESULT WINAPI CategoryMgr_RegisterGUID ( ITfCategoryMgr *iface,
        REFGUID rguid, TfGuidAtom *pguidatom
)
{
    CategoryMgr *This = (CategoryMgr*)iface;
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI CategoryMgr_GetGUID ( ITfCategoryMgr *iface,
        TfGuidAtom guidatom, GUID *pguid)
{
    CategoryMgr *This = (CategoryMgr*)iface;
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI CategoryMgr_IsEqualTfGuidAtom ( ITfCategoryMgr *iface,
        TfGuidAtom guidatom, REFGUID rguid, BOOL *pfEqual)
{
    CategoryMgr *This = (CategoryMgr*)iface;
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}


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->CategoryMgrVtbl= &CategoryMgr_CategoryMgrVtbl;
    This->refCount = 1;

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