
#include "windef.h"
#include "wine/obj_base.h"
#include "winerror.h"
#include "debugtools.h"
#include "dpinit.h"

DEFAULT_DEBUG_CHANNEL(dplay);


/*******************************************************************************
 * DirectPlayLobby ClassFactory
 */

typedef struct
{
    /* IUnknown fields */
    ICOM_VFIELD(IClassFactory);
    DWORD                       ref;
} IClassFactoryImpl;

static HRESULT WINAPI
DP_and_DPL_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
        ICOM_THIS(IClassFactoryImpl,iface);

        FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);

        return E_NOINTERFACE;
}

static ULONG WINAPI
DP_and_DPL_AddRef(LPCLASSFACTORY iface) {
        ICOM_THIS(IClassFactoryImpl,iface);
        return ++(This->ref);
}

static ULONG WINAPI DP_and_DPL_Release(LPCLASSFACTORY iface) {
        ICOM_THIS(IClassFactoryImpl,iface);
        /* static class (reference starts @ 1), won't ever be freed */
        return --(This->ref);
}

static HRESULT WINAPI DP_and_DPL_CreateInstance(
        LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
) {
        ICOM_THIS(IClassFactoryImpl,iface);

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

        if ( DPL_CreateInterface( riid, ppobj ) == S_OK )
        {
           return S_OK;
        }
        else if ( DP_CreateInterface( riid, ppobj ) == S_OK )
        {
           return S_OK;
        }

        return E_NOINTERFACE;
}

static HRESULT WINAPI DP_and_DPL_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
        ICOM_THIS(IClassFactoryImpl,iface);
        FIXME("(%p)->(%d),stub!\n",This,dolock);
        return S_OK;
}

static ICOM_VTABLE(IClassFactory) DP_and_DPL_Vtbl = {
        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
        DP_and_DPL_QueryInterface,
        DP_and_DPL_AddRef,
        DP_and_DPL_Release,
        DP_and_DPL_CreateInstance,
        DP_and_DPL_LockServer
};

static IClassFactoryImpl DP_and_DPL_CF = {&DP_and_DPL_Vtbl, 1 };


/*******************************************************************************
 * DPLAYX_DllGetClassObject [DPLAYX.11]
 * Retrieves DP or DPL class object from a DLL object
 *
 * NOTES
 *    Docs say returns STDAPI
 *
 * PARAMS
 *    rclsid [I] CLSID for the class object
 *    riid   [I] Reference to identifier of interface for class object
 *    ppv    [O] Address of variable to receive interface pointer for riid
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
 *             E_UNEXPECTED
 */
DWORD WINAPI DPLAYX_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
{
    TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);

    if ( IsEqualCLSID( riid, &IID_IClassFactory ) )
    {
        *ppv = (LPVOID)&DP_and_DPL_CF;
        IClassFactory_AddRef( (IClassFactory*)*ppv );

        return S_OK;
    }

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