/* 
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 */

#include "config.h"

#include <stdarg.h>

#define COBJMACROS
#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: */
static HRESULT WINAPI IDirectPlay8ClientImpl_QueryInterface(PDIRECTPLAY8CLIENT iface, REFIID riid, LPVOID *ppobj)
{
    IDirectPlay8ClientImpl *This = (IDirectPlay8ClientImpl *)iface;

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

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

static 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;
}

static 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: */

static 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; 
}

static 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; 
}

static 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; 
}

static 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; 
}

static 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; 
}

static 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; 
}

static 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; 
}

static 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; 
}

static 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; 
}

static 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; 
}

static 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; 
}

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

static 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; 
}

static 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; 
}

static 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; 
}

static 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; 
}

static 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; 
}

static 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; 
}

static 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);
}
