/* 
 * DirectPlay
 * 
 * Copyright 2004 Raphael Junqueira
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include "config.h"

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"
#include "objbase.h"
#include "wine/debug.h"

#include "dplay8.h"
/*
 *#include "dplobby8.h"
 *#include "dplay8sp.h"
 */
#include "dpnet_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(dpnet);

/* At process attach */
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
  TRACE("%p,%lx,%p\n", hInstDLL, fdwReason, lpvReserved);
  if (fdwReason == DLL_PROCESS_ATTACH) {
    DisableThreadLibraryCalls(hInstDLL);    
  }
  return TRUE;
}

/***********************************************************************
 *             DirectPlay8Create (DPNET.@)
 */
HRESULT WINAPI DirectPlay8Create(REFGUID lpGUID, LPVOID *ppvInt, LPUNKNOWN punkOuter)
{
    TRACE("(%s, %p, %p): stub\n", debugstr_guid(lpGUID), ppvInt, punkOuter);
    return S_OK;
}

/*******************************************************************************
 * DirectPlay ClassFactory
 */
typedef struct
{
  /* IUnknown fields */
  IClassFactoryVtbl *lpVtbl;
  DWORD      ref; 
  REFCLSID   rclsid;
  HRESULT   (*pfnCreateInstanceFactory)(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj);
} IClassFactoryImpl;

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

static ULONG WINAPI DICF_AddRef(LPCLASSFACTORY iface) {
  IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
  return ++(This->ref);
}

static ULONG WINAPI DICF_Release(LPCLASSFACTORY iface) {
  IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
  /* static class, won't be  freed */
  return --(This->ref);
}

static HRESULT WINAPI DICF_CreateInstance(LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj) {
  IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
  
  TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
  return This->pfnCreateInstanceFactory(iface, pOuter, riid, ppobj);
}

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

static IClassFactoryVtbl DICF_Vtbl = {
  DICF_QueryInterface,
  DICF_AddRef,
  DICF_Release,
  DICF_CreateInstance,
  DICF_LockServer
};

static IClassFactoryImpl DPNET_CFS[] = {
  { &DICF_Vtbl, 1, &CLSID_DirectPlay8Client,  DPNET_CreateDirectPlay8Client },
  { &DICF_Vtbl, 1, &CLSID_DirectPlay8Server,  DPNET_CreateDirectPlay8Server },
  { &DICF_Vtbl, 1, &CLSID_DirectPlay8Peer,    DPNET_CreateDirectPlay8Peer },
  { &DICF_Vtbl, 1, &CLSID_DirectPlay8Address, DPNET_CreateDirectPlay8Address },
  { NULL, 0, NULL, NULL }
};

/***********************************************************************
 *             DllCanUnloadNow (DPNET.@)
 */
BOOL WINAPI DPNET_DllCanUnloadNow(void)
{
    return S_FALSE;
}

/***********************************************************************
 *		DllGetClassObject (DPNET.@)
 */
HRESULT WINAPI DPNET_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
    int i = 0;

    TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
    /*
    if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
    	*ppv = (LPVOID)&DPNET_CF;
	IClassFactory_AddRef((IClassFactory*)*ppv);
	return S_OK;
    }
    */
    while (NULL != DPNET_CFS[i].rclsid) {
      if (IsEqualGUID(rclsid, DPNET_CFS[i].rclsid)) {
	DICF_AddRef((IClassFactory*) &DPNET_CFS[i]);
	*ppv = &DPNET_CFS[i];
	return S_OK;
      }
      ++i;
    }

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