/* DirectInput 8
 *
 * Copyright 2002 TransGaming Technologies Inc.
 * Copyright 2006 Roderick Colenbrander
 *
 * 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 <assert.h>
#include <stdarg.h>
#include <string.h>

#define COBJMACROS

#include "wine/debug.h"
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "objbase.h"
#include "rpcproxy.h"
#include "dinput.h"

WINE_DEFAULT_DEBUG_CHANNEL(dinput);

static HINSTANCE instance;
static LONG dll_count;

/*
 * Dll lifetime tracking declaration
 */
static void LockModule(void)
{
    InterlockedIncrement(&dll_count);
}

static void UnlockModule(void)
{
    InterlockedDecrement(&dll_count);
}

/******************************************************************************
 *	DirectInput8Create (DINPUT8.@)
 */
HRESULT WINAPI DECLSPEC_HOTPATCH DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI, LPUNKNOWN punkOuter) {
    IDirectInputA *pDI;
    HRESULT hr, hrCo;

    TRACE("hInst (%p), dwVersion: %d, riid (%s), punkOuter (%p))\n", hinst, dwVersion, debugstr_guid(riid), punkOuter);

    if (!ppDI)
        return E_POINTER;

    if (!IsEqualGUID(&IID_IDirectInput8A, riid) &&
        !IsEqualGUID(&IID_IDirectInput8W, riid) &&
        !IsEqualGUID(&IID_IUnknown, riid))
    {
        *ppDI = NULL;
        return DIERR_NOINTERFACE;
    }

    hrCo = CoInitialize(NULL);

    hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInputA, (void **)&pDI);

    /* Ensure balance of calls. */
    if (SUCCEEDED(hrCo))
        CoUninitialize();

    if (FAILED(hr)) {
        ERR("CoCreateInstance failed with hr = 0x%08x\n", hr);
        return hr;
    }

    hr = IDirectInput_QueryInterface(pDI, riid, ppDI);
    IDirectInput_Release(pDI);

    if (FAILED(hr))
        return hr;

    /* When aggregation is used (punkOuter!=NULL) the application needs to manually call Initialize. */
    if(punkOuter == NULL && IsEqualGUID(&IID_IDirectInput8A, riid)) {
        IDirectInput8A *DI = *ppDI;

        hr = IDirectInput8_Initialize(DI, hinst, dwVersion);
        if (FAILED(hr))
        {
            IDirectInput8_Release(DI);
            *ppDI = NULL;
            return hr;
        }
    }

    if(punkOuter == NULL && IsEqualGUID(&IID_IDirectInput8W, riid)) {
        IDirectInput8W *DI = *ppDI;

        hr = IDirectInput8_Initialize(DI, hinst, dwVersion);
        if (FAILED(hr))
        {
            IDirectInput8_Release(DI);
            *ppDI = NULL;
            return hr;
        }
    }

    return S_OK;
}

/*******************************************************************************
 * DirectInput8 ClassFactory
 */
typedef struct
{
    /* IUnknown fields */
    IClassFactory IClassFactory_iface;
} IClassFactoryImpl;

static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
{
    return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
}

static HRESULT WINAPI DI8CF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
    IClassFactoryImpl *This = impl_from_IClassFactory(iface);
    FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj);
    return E_NOINTERFACE;
}

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

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

static HRESULT WINAPI DI8CF_CreateInstance(LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj) {
    IClassFactoryImpl *This = impl_from_IClassFactory(iface);

    TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
    if( IsEqualGUID( &IID_IDirectInput8A, riid ) || IsEqualGUID( &IID_IDirectInput8W, riid ) || IsEqualGUID( &IID_IUnknown, riid )) {
        IDirectInputA *ppDI;
        HRESULT hr;

        hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInputA, (void **)&ppDI);
        if (FAILED(hr))
            return hr;

        hr = IDirectInput_QueryInterface(ppDI, riid, ppobj);
        IDirectInput_Release(ppDI);

        return hr;
    }

    ERR("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj);    
    return E_NOINTERFACE;
}

static HRESULT WINAPI DI8CF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
    TRACE("(%p)->(%d)\n", iface, dolock);

    if(dolock)
        LockModule();
    else
        UnlockModule();

    return S_OK;
}

static const IClassFactoryVtbl DI8CF_Vtbl = {
    DI8CF_QueryInterface,
    DI8CF_AddRef,
    DI8CF_Release,
    DI8CF_CreateInstance,
    DI8CF_LockServer
};
static IClassFactoryImpl DINPUT8_CF = { { &DI8CF_Vtbl } };


/***********************************************************************
 *		DllCanUnloadNow (DINPUT8.@)
 */
HRESULT WINAPI DllCanUnloadNow(void)
{
    return dll_count == 0 ? S_OK : S_FALSE;
}

/***********************************************************************
 *		DllGetClassObject (DINPUT8.@)
 */
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
    TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
    if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
        *ppv = &DINPUT8_CF;
        IClassFactory_AddRef((IClassFactory*)*ppv);
        return S_OK;
    }

    FIXME("(%s,%s,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
    return CLASS_E_CLASSNOTAVAILABLE;
}

/***********************************************************************
 *		DllMain
 */
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD reason, LPVOID lpv)
{
    switch (reason)
    {
    case DLL_PROCESS_ATTACH:
        instance = hInstDLL;
        DisableThreadLibraryCalls( hInstDLL );
        break;
    }
    return TRUE;
}

/***********************************************************************
 *		DllRegisterServer (DINPUT8.@)
 */
HRESULT WINAPI DllRegisterServer(void)
{
    return __wine_register_resources( instance );
}

/***********************************************************************
 *		DllUnregisterServer (DINPUT8.@)
 */
HRESULT WINAPI DllUnregisterServer(void)
{
    return __wine_unregister_resources( instance );
}
