/* 
 * DirectPlay8 Client
 * 
 * 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 "dpnet_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(dpnet);

/* IDirectPlay8Client IUnknown parts follow: */
HRESULT WINAPI IDirectPlay8ClientImpl_QueryInterface(PDIRECTPLAY8CLIENT iface, REFIID riid, LPVOID *ppobj)
{
    IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;

    if (IsEqualGUID(riid, &IID_IUnknown)
        || IsEqualGUID(riid, &IID_IDirectPlay8Client)) {
        IDirectPlay8ClientImpl_AddRef(iface);
        *ppobj = This;
        return DPN_OK;
    }

    WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
    return E_NOINTERFACE;
}

ULONG WINAPI IDirectPlay8ClientImpl_AddRef(PDIRECTPLAY8CLIENT iface) {
    IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1);

    return refCount;
}

ULONG WINAPI IDirectPlay8ClientImpl_Release(PDIRECTPLAY8CLIENT iface) {
    IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1);

    if (!refCount) {
        HeapFree(GetProcessHeap(), 0, This);
    }
    return refCount;
}

/* IDirectPlay8Client Interface follow: */

HRESULT WINAPI IDirectPlay8ClientImpl_Initialize(PDIRECTPLAY8CLIENT iface,  PVOID CONST pvUserContext, CONST PFNDPNMESSAGEHANDLER pfn, CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%p,%p,%lx): Stub\n", This, pvUserContext, pfn, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_EnumServiceProviders(PDIRECTPLAY8CLIENT iface, 
							   CONST GUID * CONST pguidServiceProvider, 
							   CONST GUID * CONST pguidApplication, 
							   DPN_SERVICE_PROVIDER_INFO * CONST pSPInfoBuffer, 
							   PDWORD CONST pcbEnumData, 
							   PDWORD CONST pcReturned, 
							   CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%lx): Stub\n", This, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_EnumHosts(PDIRECTPLAY8CLIENT iface, 
						PDPN_APPLICATION_DESC CONST pApplicationDesc, 
						IDirectPlay8Address * CONST pAddrHost, 
						IDirectPlay8Address * CONST pDeviceInfo, 
						PVOID CONST pUserEnumData, CONST DWORD dwUserEnumDataSize, CONST DWORD dwEnumCount, 
						CONST DWORD dwRetryInterval, 
						CONST DWORD dwTimeOut, 
						PVOID CONST pvUserContext, 
						DPNHANDLE * CONST pAsyncHandle, 
						CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  /*FIXME("(%p):(%p,%p,%p,%p,%lu,%lu,%lu,%lu): Stub\n", This, pApplicationDesc, pAddrHost, pDeviceInfo, pUserEnumData, dwUserEnumDataSize, dwEnumCount, dwRetryInterval, dwTimeOut);*/
  FIXME("(%p):(%p,%p,%lx): Stub\n", This, pvUserContext, pAsyncHandle, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_CancelAsyncOperation(PDIRECTPLAY8CLIENT iface, CONST DPNHANDLE hAsyncHandle, CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%lu,%lx): Stub\n", This, hAsyncHandle, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_Connect(PDIRECTPLAY8CLIENT iface, 
					      CONST DPN_APPLICATION_DESC * CONST pdnAppDesc,
					      IDirectPlay8Address * CONST pHostAddr,
					      IDirectPlay8Address * CONST pDeviceInfo, 
					      CONST DPN_SECURITY_DESC * CONST pdnSecurity, 
					      CONST DPN_SECURITY_CREDENTIALS * CONST pdnCredentials, 
					      CONST void * CONST pvUserConnectData, 
					      CONST DWORD dwUserConnectDataSize, 
					      void * CONST pvAsyncContext, 
					      DPNHANDLE * CONST phAsyncHandle, 
					      CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%p,%p,%lx): Stub\n", This, pvAsyncContext, phAsyncHandle, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_Send(PDIRECTPLAY8CLIENT iface, 
					   CONST DPN_BUFFER_DESC * CONST prgBufferDesc, 
					   CONST DWORD cBufferDesc, 
					   CONST DWORD dwTimeOut, 
					   void * CONST pvAsyncContext, 
					   DPNHANDLE * CONST phAsyncHandle, 
					   CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%p,%p,%lx): Stub\n", This, pvAsyncContext, phAsyncHandle, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_GetSendQueueInfo(PDIRECTPLAY8CLIENT iface, DWORD * CONST pdwNumMsgs, DWORD * CONST pdwNumBytes, CONST DWORD dwFlags) {
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%lx): Stub\n", This, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_GetApplicationDesc(PDIRECTPLAY8CLIENT iface, DPN_APPLICATION_DESC * CONST pAppDescBuffer, DWORD * CONST pcbDataSize, CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%lx): Stub\n", This, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_SetClientInfo(PDIRECTPLAY8CLIENT iface, 
						    CONST DPN_PLAYER_INFO * CONST pdpnPlayerInfo, 
						    PVOID CONST pvAsyncContext, 
						    DPNHANDLE * CONST phAsyncHandle, 
						    CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%p,%p,%lx): Stub\n", This, pvAsyncContext, phAsyncHandle, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_GetServerInfo(PDIRECTPLAY8CLIENT iface, DPN_PLAYER_INFO * CONST pdpnPlayerInfo, DWORD * CONST pdwSize, CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%lx): Stub\n", This, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_GetServerAddress(PDIRECTPLAY8CLIENT iface, IDirectPlay8Address ** CONST pAddress, CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%lx): Stub\n", This, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_Close(PDIRECTPLAY8CLIENT iface, CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%lx): Stub\n", This, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_ReturnBuffer(PDIRECTPLAY8CLIENT iface, CONST DPNHANDLE hBufferHandle, CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%lx): Stub\n", This, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_GetCaps(PDIRECTPLAY8CLIENT iface, DPN_CAPS * CONST pdpCaps, CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%lx): Stub\n", This, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_SetCaps(PDIRECTPLAY8CLIENT iface, CONST DPN_CAPS * CONST pdpCaps, CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%lx): Stub\n", This, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_SetSPCaps(PDIRECTPLAY8CLIENT iface, CONST GUID * CONST pguidSP, CONST DPN_SP_CAPS * CONST pdpspCaps, CONST DWORD dwFlags ) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%lx): Stub\n", This, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_GetSPCaps(PDIRECTPLAY8CLIENT iface, CONST GUID * CONST pguidSP, DPN_SP_CAPS * CONST pdpspCaps, CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%lx): Stub\n", This, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_GetConnectionInfo(PDIRECTPLAY8CLIENT iface, DPN_CONNECTION_INFO * CONST pdpConnectionInfo, CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%lx): Stub\n", This, dwFlags);
  return DPN_OK; 
}

HRESULT WINAPI IDirectPlay8ClientImpl_RegisterLobby(PDIRECTPLAY8CLIENT iface, CONST DPNHANDLE dpnHandle, struct IDirectPlay8LobbiedApplication * CONST pIDP8LobbiedApplication, CONST DWORD dwFlags) { 
  IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;
  FIXME("(%p):(%lx): Stub\n", This, dwFlags);
  return DPN_OK; 
}

static const IDirectPlay8ClientVtbl DirectPlay8Client_Vtbl =
{
    IDirectPlay8ClientImpl_QueryInterface,
    IDirectPlay8ClientImpl_AddRef,
    IDirectPlay8ClientImpl_Release,
    IDirectPlay8ClientImpl_Initialize,
    IDirectPlay8ClientImpl_EnumServiceProviders,
    IDirectPlay8ClientImpl_EnumHosts,
    IDirectPlay8ClientImpl_CancelAsyncOperation,
    IDirectPlay8ClientImpl_Connect,
    IDirectPlay8ClientImpl_Send,
    IDirectPlay8ClientImpl_GetSendQueueInfo,
    IDirectPlay8ClientImpl_GetApplicationDesc,
    IDirectPlay8ClientImpl_SetClientInfo,
    IDirectPlay8ClientImpl_GetServerInfo,
    IDirectPlay8ClientImpl_GetServerAddress,
    IDirectPlay8ClientImpl_Close,
    IDirectPlay8ClientImpl_ReturnBuffer,
    IDirectPlay8ClientImpl_GetCaps,
    IDirectPlay8ClientImpl_SetCaps,
    IDirectPlay8ClientImpl_SetSPCaps,
    IDirectPlay8ClientImpl_GetSPCaps,
    IDirectPlay8ClientImpl_GetConnectionInfo,
    IDirectPlay8ClientImpl_RegisterLobby
};

HRESULT DPNET_CreateDirectPlay8Client(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj) {
  IDirectPlay8ClientImpl* client;

  TRACE("(%p, %s, %p)\n", punkOuter, debugstr_guid(riid), ppobj);
  
  client = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectPlay8ClientImpl));
  if (NULL == client) {
    *ppobj = NULL;
    return E_OUTOFMEMORY;
  }
  client->lpVtbl = &DirectPlay8Client_Vtbl;
  client->ref = 0; /* will be inited with QueryInterface */
  return IDirectPlay8ClientImpl_QueryInterface ((PDIRECTPLAY8CLIENT)client, riid, ppobj);
}
