/*
 *  ITfInputProcessorProfiles 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 "olectl.h"

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

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

WINE_DEFAULT_DEBUG_CHANNEL(msctf);

static const WCHAR szwLngp[] = {'L','a','n','g','u','a','g','e','P','r','o','f','i','l','e',0};
static const WCHAR szwEnable[] = {'E','n','a','b','l','e',0};
static const WCHAR szwTipfmt[] = {'%','s','\\','%','s',0};
static const WCHAR szwFullLangfmt[] = {'%','s','\\','%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};

static const WCHAR szwAssemblies[] = {'A','s','s','e','m','b','l','i','e','s',0};
static const WCHAR szwDefault[] = {'D','e','f','a','u','l','t',0};
static const WCHAR szwProfile[] = {'P','r','o','f','i','l','e',0};
static const WCHAR szwDefaultFmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};

typedef struct tagInputProcessorProfilesSink {
    struct list         entry;
    union {
        /* InputProcessorProfile Sinks */
        IUnknown            *pIUnknown;
        ITfLanguageProfileNotifySink *pITfLanguageProfileNotifySink;
    } interfaces;
} InputProcessorProfilesSink;

typedef struct tagInputProcessorProfiles {
    const ITfInputProcessorProfilesVtbl *InputProcessorProfilesVtbl;
    const ITfSourceVtbl *SourceVtbl;
    /* const ITfInputProcessorProfileMgrVtbl *InputProcessorProfileMgrVtbl; */
    /* const ITfInputProcessorProfilesExVtbl *InputProcessorProfilesExVtbl; */
    /* const ITfInputProcessorProfileSubstituteLayoutVtbl *InputProcessorProfileSubstituteLayoutVtbl; */
    LONG refCount;

    LANGID  currentLanguage;

    struct list     LanguageProfileNotifySink;
} InputProcessorProfiles;

typedef struct tagProfilesEnumGuid {
    const IEnumGUIDVtbl *Vtbl;
    LONG refCount;

    HKEY key;
    DWORD next_index;
} ProfilesEnumGuid;

typedef struct tagEnumTfLanguageProfiles {
    const IEnumTfLanguageProfilesVtbl *Vtbl;
    LONG refCount;

    HKEY    tipkey;
    DWORD   tip_index;
    WCHAR   szwCurrentClsid[39];

    HKEY    langkey;
    DWORD   lang_index;

    LANGID  langid;
    ITfCategoryMgr *catmgr;
} EnumTfLanguageProfiles;

static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut);
static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut);

static inline InputProcessorProfiles *impl_from_ITfSourceVtbl(ITfSource *iface)
{
    return (InputProcessorProfiles *)((char *)iface - FIELD_OFFSET(InputProcessorProfiles,SourceVtbl));
}

static void free_sink(InputProcessorProfilesSink *sink)
{
        IUnknown_Release(sink->interfaces.pIUnknown);
        HeapFree(GetProcessHeap(),0,sink);
}

static void InputProcessorProfiles_Destructor(InputProcessorProfiles *This)
{
    struct list *cursor, *cursor2;
    TRACE("destroying %p\n", This);

    /* free sinks */
    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->LanguageProfileNotifySink)
    {
        InputProcessorProfilesSink* sink = LIST_ENTRY(cursor,InputProcessorProfilesSink,entry);
        list_remove(cursor);
        free_sink(sink);
    }

    HeapFree(GetProcessHeap(),0,This);
}

static void add_userkey( REFCLSID rclsid, LANGID langid,
                                REFGUID guidProfile)
{
    HKEY key;
    WCHAR buf[39];
    WCHAR buf2[39];
    WCHAR fullkey[168];
    DWORD disposition = 0;
    ULONG res;

    TRACE("\n");

    StringFromGUID2(rclsid, buf, 39);
    StringFromGUID2(guidProfile, buf2, 39);
    sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);

    res = RegCreateKeyExW(HKEY_CURRENT_USER,fullkey, 0, NULL, 0,
                   KEY_READ | KEY_WRITE, NULL, &key, &disposition);

    if (!res && disposition == REG_CREATED_NEW_KEY)
    {
        DWORD zero = 0x0;
        RegSetValueExW(key, szwEnable, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
    }

    if (!res)
        RegCloseKey(key);
}

static HRESULT WINAPI InputProcessorProfiles_QueryInterface(ITfInputProcessorProfiles *iface, REFIID iid, LPVOID *ppvOut)
{
    InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
    *ppvOut = NULL;

    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfInputProcessorProfiles))
    {
        *ppvOut = This;
    }
    else if (IsEqualIID(iid, &IID_ITfSource))
    {
        *ppvOut = &This->SourceVtbl;
    }

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

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

static ULONG WINAPI InputProcessorProfiles_AddRef(ITfInputProcessorProfiles *iface)
{
    InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
    return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI InputProcessorProfiles_Release(ITfInputProcessorProfiles *iface)
{
    InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
    ULONG ret;

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

/*****************************************************
 * ITfInputProcessorProfiles functions
 *****************************************************/
static HRESULT WINAPI InputProcessorProfiles_Register(
        ITfInputProcessorProfiles *iface, REFCLSID rclsid)
{
    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
    HKEY tipkey;
    WCHAR buf[39];
    WCHAR fullkey[68];

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

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

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

    RegCloseKey(tipkey);

    return S_OK;
}

static HRESULT WINAPI InputProcessorProfiles_Unregister(
        ITfInputProcessorProfiles *iface, REFCLSID rclsid)
{
    WCHAR buf[39];
    WCHAR fullkey[68];
    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;

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

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

    RegDeleteTreeW(HKEY_LOCAL_MACHINE, fullkey);
    RegDeleteTreeW(HKEY_CURRENT_USER, fullkey);

    return S_OK;
}

static HRESULT WINAPI InputProcessorProfiles_AddLanguageProfile(
        ITfInputProcessorProfiles *iface, REFCLSID rclsid,
        LANGID langid, REFGUID guidProfile, const WCHAR *pchDesc,
        ULONG cchDesc, const WCHAR *pchIconFile, ULONG cchFile,
        ULONG uIconIndex)
{
    HKEY tipkey,fmtkey;
    WCHAR buf[39];
    WCHAR fullkey[100];
    ULONG res;
    DWORD disposition = 0;

    static const WCHAR fmt2[] = {'%','s','\\','0','x','%','0','8','x','\\','%','s',0};
    static const WCHAR desc[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
    static const WCHAR icnf[] = {'I','c','o','n','F','i','l','e',0};
    static const WCHAR icni[] = {'I','c','o','n','I','n','d','e','x',0};

    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;

    TRACE("(%p) %s %x %s %s %s %i\n",This,debugstr_guid(rclsid), langid,
            debugstr_guid(guidProfile), debugstr_wn(pchDesc,cchDesc),
            debugstr_wn(pchIconFile,cchFile),uIconIndex);

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

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

    StringFromGUID2(guidProfile, buf, 39);
    sprintfW(fullkey,fmt2,szwLngp,langid,buf);

    res = RegCreateKeyExW(tipkey,fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
            NULL, &fmtkey, &disposition);

    if (!res)
    {
        DWORD zero = 0x0;
        RegSetValueExW(fmtkey, desc, 0, REG_SZ, (const BYTE*)pchDesc, cchDesc * sizeof(WCHAR));
        RegSetValueExW(fmtkey, icnf, 0, REG_SZ, (const BYTE*)pchIconFile, cchFile * sizeof(WCHAR));
        RegSetValueExW(fmtkey, icni, 0, REG_DWORD, (LPBYTE)&uIconIndex, sizeof(DWORD));
        if (disposition == REG_CREATED_NEW_KEY)
            RegSetValueExW(fmtkey, szwEnable, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
        RegCloseKey(fmtkey);

        add_userkey(rclsid, langid, guidProfile);
    }
    RegCloseKey(tipkey);

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

static HRESULT WINAPI InputProcessorProfiles_RemoveLanguageProfile(
        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
        REFGUID guidProfile)
{
    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI InputProcessorProfiles_EnumInputProcessorInfo(
        ITfInputProcessorProfiles *iface, IEnumGUID **ppEnum)
{
    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
    TRACE("(%p) %p\n",This,ppEnum);
    return ProfilesEnumGuid_Constructor(ppEnum);
}

static HRESULT WINAPI InputProcessorProfiles_GetDefaultLanguageProfile(
        ITfInputProcessorProfiles *iface, LANGID langid, REFGUID catid,
        CLSID *pclsid, GUID *pguidProfile)
{
    WCHAR fullkey[168];
    WCHAR buf[39];
    HKEY hkey;
    DWORD count;
    ULONG res;
    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;

    TRACE("%p) %x %s %p %p\n",This, langid, debugstr_guid(catid),pclsid,pguidProfile);

    if (!catid || !pclsid || !pguidProfile)
        return E_INVALIDARG;

    StringFromGUID2(catid, buf, 39);
    sprintfW(fullkey, szwDefaultFmt, szwSystemCTFKey, szwAssemblies, langid, buf);

    if (RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE,
                &hkey ) != ERROR_SUCCESS)
        return S_FALSE;

    count = sizeof(buf);
    res = RegQueryValueExW(hkey, szwDefault, 0, NULL, (LPBYTE)buf, &count);
    if (res != ERROR_SUCCESS)
    {
        RegCloseKey(hkey);
        return S_FALSE;
    }
    CLSIDFromString(buf,pclsid);

    res = RegQueryValueExW(hkey, szwProfile, 0, NULL, (LPBYTE)buf, &count);
    if (res == ERROR_SUCCESS)
        CLSIDFromString(buf,pguidProfile);

    RegCloseKey(hkey);

    return S_OK;
}

static HRESULT WINAPI InputProcessorProfiles_SetDefaultLanguageProfile(
        ITfInputProcessorProfiles *iface, LANGID langid, REFCLSID rclsid,
        REFGUID guidProfiles)
{
    WCHAR fullkey[168];
    WCHAR buf[39];
    HKEY hkey;
    GUID catid;
    HRESULT hr;
    ITfCategoryMgr *catmgr;
    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
    static const GUID * tipcats[3] = { &GUID_TFCAT_TIP_KEYBOARD,
                                       &GUID_TFCAT_TIP_SPEECH,
                                       &GUID_TFCAT_TIP_HANDWRITING };

    TRACE("%p) %x %s %s\n",This, langid, debugstr_guid(rclsid),debugstr_guid(guidProfiles));

    if (!rclsid || !guidProfiles)
        return E_INVALIDARG;

    hr = CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);

    if (FAILED(hr))
        return hr;

    if (ITfCategoryMgr_FindClosestCategory(catmgr, rclsid,
            &catid, tipcats, 3) != S_OK)
        hr = ITfCategoryMgr_FindClosestCategory(catmgr, rclsid,
                &catid, NULL, 0);
    ITfCategoryMgr_Release(catmgr);

    if (FAILED(hr))
        return E_FAIL;

    StringFromGUID2(&catid, buf, 39);
    sprintfW(fullkey, szwDefaultFmt, szwSystemCTFKey, szwAssemblies, langid, buf);

    if (RegCreateKeyExW(HKEY_CURRENT_USER, fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
                NULL, &hkey, NULL ) != ERROR_SUCCESS)
        return E_FAIL;

    StringFromGUID2(rclsid, buf, 39);
    RegSetValueExW(hkey, szwDefault, 0, REG_SZ, (LPBYTE)buf, sizeof(buf));
    StringFromGUID2(guidProfiles, buf, 39);
    RegSetValueExW(hkey, szwProfile, 0, REG_SZ, (LPBYTE)buf, sizeof(buf));
    RegCloseKey(hkey);

    return S_OK;
}

static HRESULT WINAPI InputProcessorProfiles_ActivateLanguageProfile(
        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
        REFGUID guidProfiles)
{
    HRESULT hr;
    BOOL enabled;
    TF_LANGUAGEPROFILE LanguageProfile;
    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;

    TRACE("(%p) %s %x %s\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfiles));

    if (langid != This->currentLanguage) return E_INVALIDARG;

    if (get_active_textservice(rclsid,NULL))
    {
        TRACE("Already Active\n");
        return E_FAIL;
    }

    hr = ITfInputProcessorProfiles_IsEnabledLanguageProfile(iface, rclsid,
            langid, guidProfiles, &enabled);
    if (FAILED(hr) || !enabled)
    {
        TRACE("Not Enabled\n");
        return E_FAIL;
    }

    LanguageProfile.clsid = *rclsid;
    LanguageProfile.langid = langid;
    LanguageProfile.guidProfile = *guidProfiles;

    hr = add_active_textservice(&LanguageProfile);

    return hr;
}

static HRESULT WINAPI InputProcessorProfiles_GetActiveLanguageProfile(
        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID *plangid,
        GUID *pguidProfile)
{
    TF_LANGUAGEPROFILE profile;
    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;

    TRACE("(%p) %s %p %p\n",This,debugstr_guid(rclsid),plangid,pguidProfile);

    if (!rclsid || !plangid || !pguidProfile)
        return E_INVALIDARG;

    if (get_active_textservice(rclsid, &profile))
    {
        *plangid = profile.langid;
        *pguidProfile = profile.guidProfile;
        return S_OK;
    }
    else
    {
        *pguidProfile = GUID_NULL;
        return S_FALSE;
    }
}

static HRESULT WINAPI InputProcessorProfiles_GetLanguageProfileDescription(
        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
        REFGUID guidProfile, BSTR *pbstrProfile)
{
    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI InputProcessorProfiles_GetCurrentLanguage(
        ITfInputProcessorProfiles *iface, LANGID *plangid)
{
    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
    TRACE("(%p) 0x%x\n",This,This->currentLanguage);

    if (!plangid)
        return E_INVALIDARG;

    *plangid = This->currentLanguage;

    return S_OK;
}

static HRESULT WINAPI InputProcessorProfiles_ChangeCurrentLanguage(
        ITfInputProcessorProfiles *iface, LANGID langid)
{
    struct list *cursor;
    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
    BOOL accept;

    FIXME("STUB:(%p)\n",This);

    LIST_FOR_EACH(cursor, &This->LanguageProfileNotifySink)
    {
        InputProcessorProfilesSink* sink = LIST_ENTRY(cursor,InputProcessorProfilesSink,entry);
        accept = TRUE;
        ITfLanguageProfileNotifySink_OnLanguageChange(sink->interfaces.pITfLanguageProfileNotifySink, langid, &accept);
        if (!accept)
            return  E_FAIL;
    }

    /* TODO:  On successful language change call OnLanguageChanged sink */
    return E_NOTIMPL;
}

static HRESULT WINAPI InputProcessorProfiles_GetLanguageList(
        ITfInputProcessorProfiles *iface, LANGID **ppLangId, ULONG *pulCount)
{
    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
    FIXME("Semi-STUB:(%p)\n",This);
    *ppLangId = CoTaskMemAlloc(sizeof(LANGID));
    **ppLangId = This->currentLanguage;
    *pulCount = 1;
    return S_OK;
}

static HRESULT WINAPI InputProcessorProfiles_EnumLanguageProfiles(
        ITfInputProcessorProfiles *iface, LANGID langid,
        IEnumTfLanguageProfiles **ppEnum)
{
    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
    TRACE("(%p) %x %p\n",This,langid,ppEnum);
    return EnumTfLanguageProfiles_Constructor(langid, ppEnum);
}

static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfile(
        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
        REFGUID guidProfile, BOOL fEnable)
{
    HKEY key;
    WCHAR buf[39];
    WCHAR buf2[39];
    WCHAR fullkey[168];
    ULONG res;

    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
    TRACE("(%p) %s %x %s %i\n",This, debugstr_guid(rclsid), langid, debugstr_guid(guidProfile), fEnable);

    StringFromGUID2(rclsid, buf, 39);
    StringFromGUID2(guidProfile, buf2, 39);
    sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);

    res = RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, &key);

    if (!res)
    {
        RegSetValueExW(key, szwEnable, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
        RegCloseKey(key);
    }
    else
        return E_FAIL;

    return S_OK;
}

static HRESULT WINAPI InputProcessorProfiles_IsEnabledLanguageProfile(
        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
        REFGUID guidProfile, BOOL *pfEnable)
{
    HKEY key;
    WCHAR buf[39];
    WCHAR buf2[39];
    WCHAR fullkey[168];
    ULONG res;

    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
    TRACE("(%p) %s, %i, %s, %p\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfile),pfEnable);

    if (!pfEnable)
        return E_INVALIDARG;

    StringFromGUID2(rclsid, buf, 39);
    StringFromGUID2(guidProfile, buf2, 39);
    sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);

    res = RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, &key);

    if (!res)
    {
        DWORD count = sizeof(DWORD);
        res = RegQueryValueExW(key, szwEnable, 0, NULL, (LPBYTE)pfEnable, &count);
        RegCloseKey(key);
    }

    if (res)  /* Try Default */
    {
        res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | KEY_WRITE, &key);

        if (!res)
        {
            DWORD count = sizeof(DWORD);
            res = RegQueryValueExW(key, szwEnable, 0, NULL, (LPBYTE)pfEnable, &count);
            RegCloseKey(key);
        }
    }

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

static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfileByDefault(
        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
        REFGUID guidProfile, BOOL fEnable)
{
    HKEY key;
    WCHAR buf[39];
    WCHAR buf2[39];
    WCHAR fullkey[168];
    ULONG res;

    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
    TRACE("(%p) %s %x %s %i\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfile),fEnable);

    StringFromGUID2(rclsid, buf, 39);
    StringFromGUID2(guidProfile, buf2, 39);
    sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);

    res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | KEY_WRITE, &key);

    if (!res)
    {
        RegSetValueExW(key, szwEnable, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
        RegCloseKey(key);
    }
    else
        return E_FAIL;

    return S_OK;
}

static HRESULT WINAPI InputProcessorProfiles_SubstituteKeyboardLayout(
        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
        REFGUID guidProfile, HKL hKL)
{
    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}


static const ITfInputProcessorProfilesVtbl InputProcessorProfiles_InputProcessorProfilesVtbl =
{
    InputProcessorProfiles_QueryInterface,
    InputProcessorProfiles_AddRef,
    InputProcessorProfiles_Release,

    InputProcessorProfiles_Register,
    InputProcessorProfiles_Unregister,
    InputProcessorProfiles_AddLanguageProfile,
    InputProcessorProfiles_RemoveLanguageProfile,
    InputProcessorProfiles_EnumInputProcessorInfo,
    InputProcessorProfiles_GetDefaultLanguageProfile,
    InputProcessorProfiles_SetDefaultLanguageProfile,
    InputProcessorProfiles_ActivateLanguageProfile,
    InputProcessorProfiles_GetActiveLanguageProfile,
    InputProcessorProfiles_GetLanguageProfileDescription,
    InputProcessorProfiles_GetCurrentLanguage,
    InputProcessorProfiles_ChangeCurrentLanguage,
    InputProcessorProfiles_GetLanguageList,
    InputProcessorProfiles_EnumLanguageProfiles,
    InputProcessorProfiles_EnableLanguageProfile,
    InputProcessorProfiles_IsEnabledLanguageProfile,
    InputProcessorProfiles_EnableLanguageProfileByDefault,
    InputProcessorProfiles_SubstituteKeyboardLayout
};

/*****************************************************
 * ITfSource functions
 *****************************************************/
static HRESULT WINAPI IPPSource_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
{
    InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
    return InputProcessorProfiles_QueryInterface((ITfInputProcessorProfiles *)This, iid, *ppvOut);
}

static ULONG WINAPI IPPSource_AddRef(ITfSource *iface)
{
    InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
    return InputProcessorProfiles_AddRef((ITfInputProcessorProfiles*)This);
}

static ULONG WINAPI IPPSource_Release(ITfSource *iface)
{
    InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
    return InputProcessorProfiles_Release((ITfInputProcessorProfiles *)This);
}

static HRESULT WINAPI IPPSource_AdviseSink(ITfSource *iface,
        REFIID riid, IUnknown *punk, DWORD *pdwCookie)
{
    InputProcessorProfilesSink *ipps;
    InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);

    TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);

    if (!riid || !punk || !pdwCookie)
        return E_INVALIDARG;

    if (IsEqualIID(riid, &IID_ITfLanguageProfileNotifySink))
    {
        ipps = HeapAlloc(GetProcessHeap(),0,sizeof(InputProcessorProfilesSink));
        if (!ipps)
            return E_OUTOFMEMORY;
        if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&ipps->interfaces.pITfLanguageProfileNotifySink)))
        {
            HeapFree(GetProcessHeap(),0,ipps);
            return CONNECT_E_CANNOTCONNECT;
        }
        list_add_head(&This->LanguageProfileNotifySink,&ipps->entry);
        *pdwCookie = generate_Cookie(COOKIE_MAGIC_IPPSINK, ipps);
    }
    else
    {
        FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
        return E_NOTIMPL;
    }

    TRACE("cookie %x\n",*pdwCookie);

    return S_OK;
}

static HRESULT WINAPI IPPSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
{
    InputProcessorProfilesSink *sink;
    InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);

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

    if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_IPPSINK)
        return E_INVALIDARG;

    sink = remove_Cookie(pdwCookie);
    if (!sink)
        return CONNECT_E_NOCONNECTION;

    list_remove(&sink->entry);
    free_sink(sink);

    return S_OK;
}

static const ITfSourceVtbl InputProcessorProfiles_SourceVtbl =
{
    IPPSource_QueryInterface,
    IPPSource_AddRef,
    IPPSource_Release,

    IPPSource_AdviseSink,
    IPPSource_UnadviseSink,
};

HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
{
    InputProcessorProfiles *This;
    if (pUnkOuter)
        return CLASS_E_NOAGGREGATION;

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

    This->InputProcessorProfilesVtbl= &InputProcessorProfiles_InputProcessorProfilesVtbl;
    This->SourceVtbl = &InputProcessorProfiles_SourceVtbl;
    This->refCount = 1;
    This->currentLanguage = GetUserDefaultLCID();

    list_init(&This->LanguageProfileNotifySink);

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

/**************************************************
 * IEnumGUID implementation for ITfInputProcessorProfiles::EnumInputProcessorInfo
 **************************************************/
static void ProfilesEnumGuid_Destructor(ProfilesEnumGuid *This)
{
    TRACE("destroying %p\n", This);
    RegCloseKey(This->key);
    HeapFree(GetProcessHeap(),0,This);
}

static HRESULT WINAPI ProfilesEnumGuid_QueryInterface(IEnumGUID *iface, REFIID iid, LPVOID *ppvOut)
{
    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
    *ppvOut = NULL;

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

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

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

static ULONG WINAPI ProfilesEnumGuid_AddRef(IEnumGUID *iface)
{
    ProfilesEnumGuid *This = (ProfilesEnumGuid*)iface;
    return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI ProfilesEnumGuid_Release(IEnumGUID *iface)
{
    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
    ULONG ret;

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

/*****************************************************
 * IEnumGuid functions
 *****************************************************/
static HRESULT WINAPI ProfilesEnumGuid_Next( LPENUMGUID iface,
    ULONG celt, GUID *rgelt, ULONG *pceltFetched)
{
    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
    ULONG fetched = 0;

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

    if (rgelt == NULL) return E_POINTER;

    if (This->key) while (fetched < celt)
    {
        LSTATUS res;
        HRESULT hr;
        WCHAR catid[39];
        DWORD cName = 39;

        res = RegEnumKeyExW(This->key, This->next_index, catid, &cName,
                    NULL, NULL, NULL, NULL);
        if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
        ++(This->next_index);

        hr = CLSIDFromString(catid, rgelt);
        if (FAILED(hr)) continue;

        ++fetched;
        ++rgelt;
    }

    if (pceltFetched) *pceltFetched = fetched;
    return fetched == celt ? S_OK : S_FALSE;
}

static HRESULT WINAPI ProfilesEnumGuid_Skip( LPENUMGUID iface, ULONG celt)
{
    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
    TRACE("(%p)\n",This);

    This->next_index += celt;
    return S_OK;
}

static HRESULT WINAPI ProfilesEnumGuid_Reset( LPENUMGUID iface)
{
    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
    TRACE("(%p)\n",This);
    This->next_index = 0;
    return S_OK;
}

static HRESULT WINAPI ProfilesEnumGuid_Clone( LPENUMGUID iface,
    IEnumGUID **ppenum)
{
    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
    HRESULT res;

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

    if (ppenum == NULL) return E_POINTER;

    res = ProfilesEnumGuid_Constructor(ppenum);
    if (SUCCEEDED(res))
    {
        ProfilesEnumGuid *new_This = (ProfilesEnumGuid *)*ppenum;
        new_This->next_index = This->next_index;
    }
    return res;
}

static const IEnumGUIDVtbl IEnumGUID_Vtbl ={
    ProfilesEnumGuid_QueryInterface,
    ProfilesEnumGuid_AddRef,
    ProfilesEnumGuid_Release,

    ProfilesEnumGuid_Next,
    ProfilesEnumGuid_Skip,
    ProfilesEnumGuid_Reset,
    ProfilesEnumGuid_Clone
};

static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut)
{
    ProfilesEnumGuid *This;

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

    This->Vtbl= &IEnumGUID_Vtbl;
    This->refCount = 1;

    if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
                    KEY_READ | KEY_WRITE, NULL, &This->key, NULL) != ERROR_SUCCESS)
    {
        HeapFree(GetProcessHeap(), 0, This);
        return E_FAIL;
    }

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

/**************************************************
 * IEnumTfLanguageProfiles implementation
 **************************************************/
static void EnumTfLanguageProfiles_Destructor(EnumTfLanguageProfiles *This)
{
    TRACE("destroying %p\n", This);
    RegCloseKey(This->tipkey);
    if (This->langkey)
        RegCloseKey(This->langkey);
    ITfCategoryMgr_Release(This->catmgr);
    HeapFree(GetProcessHeap(),0,This);
}

static HRESULT WINAPI EnumTfLanguageProfiles_QueryInterface(IEnumTfLanguageProfiles *iface, REFIID iid, LPVOID *ppvOut)
{
    EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
    *ppvOut = NULL;

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

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

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

static ULONG WINAPI EnumTfLanguageProfiles_AddRef(IEnumTfLanguageProfiles *iface)
{
    EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles*)iface;
    return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI EnumTfLanguageProfiles_Release(IEnumTfLanguageProfiles *iface)
{
    EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
    ULONG ret;

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

/*****************************************************
 * IEnumGuid functions
 *****************************************************/
static INT next_LanguageProfile(EnumTfLanguageProfiles *This, CLSID clsid, TF_LANGUAGEPROFILE *tflp)
{
    WCHAR fullkey[168];
    ULONG res;
    WCHAR profileid[39];
    DWORD cName = 39;
    GUID  profile;

    static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};

    if (This->langkey == NULL)
    {
        sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid);
        res = RegOpenKeyExW(This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey);
        if (res)
        {
            This->langkey = NULL;
            return -1;
        }
        This->lang_index = 0;
    }
    res = RegEnumKeyExW(This->langkey, This->lang_index, profileid, &cName,
                NULL, NULL, NULL, NULL);
    if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
    {
        RegCloseKey(This->langkey);
        This->langkey = NULL;
        return -1;
    }
    ++(This->lang_index);

    if (tflp)
    {
        static const GUID * tipcats[3] = { &GUID_TFCAT_TIP_KEYBOARD,
                                           &GUID_TFCAT_TIP_SPEECH,
                                           &GUID_TFCAT_TIP_HANDWRITING };
        res = CLSIDFromString(profileid, &profile);
        if (FAILED(res)) return 0;

        tflp->clsid = clsid;
        tflp->langid = This->langid;
        tflp->fActive = get_active_textservice(&clsid, NULL);
        tflp->guidProfile = profile;
        if (ITfCategoryMgr_FindClosestCategory(This->catmgr, &clsid,
                &tflp->catid, tipcats, 3) != S_OK)
            ITfCategoryMgr_FindClosestCategory(This->catmgr, &clsid,
                    &tflp->catid, NULL, 0);
    }

    return 1;
}

static HRESULT WINAPI EnumTfLanguageProfiles_Next(IEnumTfLanguageProfiles *iface,
    ULONG ulCount, TF_LANGUAGEPROFILE *pProfile, ULONG *pcFetch)
{
    EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
    ULONG fetched = 0;

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

    if (pProfile == NULL) return E_POINTER;

    if (This->tipkey) while (fetched < ulCount)
    {
        LSTATUS res;
        HRESULT hr;
        DWORD cName = 39;
        GUID clsid;

        res = RegEnumKeyExW(This->tipkey, This->tip_index,
                    This->szwCurrentClsid, &cName, NULL, NULL, NULL, NULL);
        if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
        ++(This->tip_index);
        hr = CLSIDFromString(This->szwCurrentClsid, &clsid);
        if (FAILED(hr)) continue;

        while ( fetched < ulCount)
        {
            INT res = next_LanguageProfile(This, clsid, pProfile);
            if (res == 1)
            {
                ++fetched;
                ++pProfile;
            }
            else if (res == -1)
                break;
            else
                continue;
        }
    }

    if (pcFetch) *pcFetch = fetched;
    return fetched == ulCount ? S_OK : S_FALSE;
}

static HRESULT WINAPI EnumTfLanguageProfiles_Skip( IEnumTfLanguageProfiles* iface, ULONG celt)
{
    EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
    FIXME("STUB (%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI EnumTfLanguageProfiles_Reset( IEnumTfLanguageProfiles* iface)
{
    EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
    TRACE("(%p)\n",This);
    This->tip_index = 0;
    if (This->langkey)
        RegCloseKey(This->langkey);
    This->langkey = NULL;
    This->lang_index = 0;
    return S_OK;
}

static HRESULT WINAPI EnumTfLanguageProfiles_Clone( IEnumTfLanguageProfiles *iface,
    IEnumTfLanguageProfiles **ppenum)
{
    EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
    HRESULT res;

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

    if (ppenum == NULL) return E_POINTER;

    res = EnumTfLanguageProfiles_Constructor(This->langid, ppenum);
    if (SUCCEEDED(res))
    {
        EnumTfLanguageProfiles *new_This = (EnumTfLanguageProfiles *)*ppenum;
        new_This->tip_index = This->tip_index;
        lstrcpynW(new_This->szwCurrentClsid,This->szwCurrentClsid,39);

        if (This->langkey)
        {
            WCHAR fullkey[168];
            static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};

            sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid);
            res = RegOpenKeyExW(new_This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey);
            new_This->lang_index = This->lang_index;
        }
    }
    return res;
}

static const IEnumTfLanguageProfilesVtbl IEnumTfLanguageProfiles_Vtbl ={
    EnumTfLanguageProfiles_QueryInterface,
    EnumTfLanguageProfiles_AddRef,
    EnumTfLanguageProfiles_Release,

    EnumTfLanguageProfiles_Clone,
    EnumTfLanguageProfiles_Next,
    EnumTfLanguageProfiles_Reset,
    EnumTfLanguageProfiles_Skip
};

static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut)
{
    HRESULT hr;
    EnumTfLanguageProfiles *This;

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

    This->Vtbl= &IEnumTfLanguageProfiles_Vtbl;
    This->refCount = 1;
    This->langid = langid;

    hr = CategoryMgr_Constructor(NULL,(IUnknown**)&This->catmgr);
    if (FAILED(hr))
    {
        HeapFree(GetProcessHeap(),0,This);
        return hr;
    }

    if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
                    KEY_READ | KEY_WRITE, NULL, &This->tipkey, NULL) != ERROR_SUCCESS)
    {
        HeapFree(GetProcessHeap(), 0, This);
        return E_FAIL;
    }

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