/*
 *    Word splitter Implementation
 *
 * Copyright 2006 Mike McCormack
 *
 * 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 <stdarg.h>
#include <stdio.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "ole2.h"
#include "indexsrv.h"
#include "initguid.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(infosoft);

DEFINE_GUID(CLSID_wb_Neutral,0x369647e0,0x17b0,0x11ce,0x99,0x50,0x00,0xaa,0x00,0x4b,0xbb,0x1f);

BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
{
    switch(fdwReason)
    {
    case DLL_WINE_PREATTACH:
        return FALSE;  /* prefer native version */
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hInstDLL);
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

extern HRESULT WINAPI wb_Constructor(IUnknown*, REFIID, LPVOID *);

typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown*, REFIID, LPVOID*);

typedef struct
{
    const IClassFactoryVtbl *lpVtbl;
    LPFNCREATEINSTANCE      lpfnCI;
} CFImpl;

static HRESULT WINAPI infosoftcf_fnQueryInterface ( LPCLASSFACTORY iface,
        REFIID riid, LPVOID *ppvObj)
{
    CFImpl *This = (CFImpl *)iface;

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

    *ppvObj = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IClassFactory))
    {
        *ppvObj = This;
        return S_OK;
    }

    TRACE("-- E_NOINTERFACE\n");
    return E_NOINTERFACE;
}

static ULONG WINAPI infosoftcf_fnAddRef (LPCLASSFACTORY iface)
{
    return 2;
}

static ULONG WINAPI infosoftcf_fnRelease(LPCLASSFACTORY iface)
{
    return 1;
}

static HRESULT WINAPI infosoftcf_fnCreateInstance( LPCLASSFACTORY iface,
        LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject)
{
    CFImpl *This = (CFImpl *)iface;

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

    *ppvObject = NULL;

    return This->lpfnCI(pUnkOuter, riid, ppvObject);
}

static HRESULT WINAPI infosoftcf_fnLockServer(LPCLASSFACTORY iface, BOOL fLock)
{
    FIXME("%p %d\n", iface, fLock);
    return E_NOTIMPL;
}

static const IClassFactoryVtbl infosoft_cfvt =
{
    infosoftcf_fnQueryInterface,
    infosoftcf_fnAddRef,
    infosoftcf_fnRelease,
    infosoftcf_fnCreateInstance,
    infosoftcf_fnLockServer
};

static CFImpl wb_cf = { &infosoft_cfvt, &wb_Constructor };

/***********************************************************************
 *             DllGetClassObject (INFOSOFT.@)
 */
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
{
    IClassFactory   *pcf = NULL;

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

    if (!ppv)
        return E_INVALIDARG;
    *ppv = NULL;

    if (IsEqualIID(rclsid, &CLSID_wb_Neutral))
        pcf = (IClassFactory*) &wb_cf;
    else
        return CLASS_E_CLASSNOTAVAILABLE;

    return IClassFactory_QueryInterface(pcf, iid, ppv);
}


HRESULT WINAPI DllCanUnloadNow(void)
{
    FIXME("\n");
    return S_FALSE;
}

static HRESULT add_key_val( LPCSTR key, LPCSTR valname, LPCSTR value )
{
    HKEY hkey;

    if (RegCreateKeyA( HKEY_CLASSES_ROOT, key, &hkey ) != ERROR_SUCCESS) return E_FAIL;
    RegSetValueA( hkey, valname, REG_SZ, value, strlen( value ) + 1 );
    RegCloseKey( hkey );
    return S_OK;
}

static HRESULT add_wordbreaker_clsid( LPCSTR lang, const CLSID *id)
{
    CHAR key[100], val[50];

    strcpy(key, "CLSID\\");
    sprintf(key+6, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
            id->Data1, id->Data2, id->Data3,
            id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
            id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7]);
    sprintf(val, "%s Word Breaker", lang);
    add_key_val( key, NULL, val );
    strcat(key, "\\InProcServer32");
    add_key_val( key, NULL, "infosoft.dll" );
    add_key_val( key, "ThreadingModel", "Both" );
    return S_OK;
}

#define ADD_BREAKER(name)  add_wordbreaker_clsid( #name, &CLSID_wb_##name )

static HRESULT add_content_index_keys(void)
{
    ADD_BREAKER(Neutral); /* in query.dll on Windows */
    return S_OK;
}

/***********************************************************************
 *             DllRegisterServer (INFOSOFT.@)
 */
HRESULT WINAPI DllRegisterServer(void)
{
    add_content_index_keys();
    return S_OK;
}
