/* This contains the implementation of the Lobby Service
 * Providers interface required to communicate with Direct Play
 *
 * Copyright 2001 Peter Hunnisett <hunnise@nortelnetworks.com>
 */

#include "winerror.h"
#include "debugtools.h"

#include "lobbysp.h"
#include "dplay_global.h"
#include "dpinit.h"

DEFAULT_DEBUG_CHANNEL(dplay);

/* Prototypes */
static BOOL DPLSP_CreateIUnknown( LPVOID lpSP );
static BOOL DPLSP_DestroyIUnknown( LPVOID lpSP );
static BOOL DPLSP_CreateDPLobbySP( LPVOID lpSP, IDirectPlay2Impl* dp );
static BOOL DPLSP_DestroyDPLobbySP( LPVOID lpSP );


/* Predefine the interface */
typedef struct IDPLobbySPImpl IDPLobbySPImpl;

typedef struct tagDPLobbySPIUnknownData
{
  ULONG             ulObjRef;
  CRITICAL_SECTION  DPLSP_lock;
} DPLobbySPIUnknownData;

typedef struct tagDPLobbySPData
{
  IDirectPlay2Impl* dplay;
} DPLobbySPData;

#define DPLSP_IMPL_FIELDS \
   ULONG ulInterfaceRef; \
   DPLobbySPIUnknownData* unk; \
   DPLobbySPData* sp;

struct IDPLobbySPImpl
{
  ICOM_VFIELD(IDPLobbySP);
  DPLSP_IMPL_FIELDS
};

/* Forward declaration of virtual tables */
static ICOM_VTABLE(IDPLobbySP) dpLobbySPVT;

extern
HRESULT DPLSP_CreateInterface( REFIID riid, LPVOID* ppvObj, IDirectPlay2Impl* dp )
{
  TRACE( " for %s\n", debugstr_guid( riid ) );

  *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
                       sizeof( IDPLobbySPImpl ) );

  if( *ppvObj == NULL )
  {
    return DPERR_OUTOFMEMORY;
  }

  if( IsEqualGUID( &IID_IDPLobbySP, riid ) )
  {
    ICOM_THIS(IDPLobbySPImpl,*ppvObj);
    ICOM_VTBL(This) = &dpLobbySPVT;
  }
  else
  {
    /* Unsupported interface */
    HeapFree( GetProcessHeap(), 0, *ppvObj );
    *ppvObj = NULL;

    return E_NOINTERFACE;
  }

  /* Initialize it */
  if( DPLSP_CreateIUnknown( *ppvObj ) &&
      DPLSP_CreateDPLobbySP( *ppvObj, dp )
    )
  {
    IDPLobbySP_AddRef( (LPDPLOBBYSP)*ppvObj );
    return S_OK;
  }

  /* Initialize failed, destroy it */
  DPLSP_DestroyDPLobbySP( *ppvObj );
  DPLSP_DestroyIUnknown( *ppvObj );

  HeapFree( GetProcessHeap(), 0, *ppvObj );
  *ppvObj = NULL;

  return DPERR_NOMEMORY;
}

static BOOL DPLSP_CreateIUnknown( LPVOID lpSP )
{
  ICOM_THIS(IDPLobbySPImpl,lpSP);

  This->unk = (DPLobbySPIUnknownData*)HeapAlloc( GetProcessHeap(),
                                                    HEAP_ZERO_MEMORY,
                                                    sizeof( *(This->unk) ) );

  if ( This->unk == NULL )
  {
    return FALSE;
  }

  InitializeCriticalSection( &This->unk->DPLSP_lock );

  return TRUE;
}

static BOOL DPLSP_DestroyIUnknown( LPVOID lpSP )
{
  ICOM_THIS(IDPLobbySPImpl,lpSP);

  DeleteCriticalSection( &This->unk->DPLSP_lock );
  HeapFree( GetProcessHeap(), 0, This->unk );

  return TRUE;
}

static BOOL DPLSP_CreateDPLobbySP( LPVOID lpSP, IDirectPlay2Impl* dp )
{
  ICOM_THIS(IDPLobbySPImpl,lpSP);

  This->sp = (DPLobbySPData*)HeapAlloc( GetProcessHeap(),
                                        HEAP_ZERO_MEMORY,
                                        sizeof( *(This->sp) ) );

  if ( This->sp == NULL )
  {
    return FALSE;
  }

  This->sp->dplay = dp;

  /* Normally we should be keeping a reference, but since only the dplay
   * interface that created us can destroy us, we do not keep a reference
   * to it (ie we'd be stuck with always having one reference to the dplay
   * object, and hence us, around).
   * NOTE: The dp object does reference count us.
   *
   * FIXME: This is a kludge to get around a problem where a queryinterface
   *        is used to get a new interface and then is closed. We will then
   *        reference garbage. However, with this we will never deallocate
   *        the interface we store. The correct fix is to require all
   *        DP internal interfaces to use the This->dp2 interface which
   *        should be changed to This->dp
   */
  IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp );


  return TRUE;
}

static BOOL DPLSP_DestroyDPLobbySP( LPVOID lpSP )
{
  ICOM_THIS(IDPLobbySPImpl,lpSP);

  HeapFree( GetProcessHeap(), 0, This->sp );

  return TRUE;
}

static
HRESULT WINAPI DPLSP_QueryInterface
( LPDPLOBBYSP iface, 
  REFIID riid,
  LPVOID* ppvObj 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );

  *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
                       sizeof( *This ) );

  if( *ppvObj == NULL )
  {
    return DPERR_OUTOFMEMORY;
  }

  CopyMemory( *ppvObj, This, sizeof( *This )  );
  (*(IDPLobbySPImpl**)ppvObj)->ulInterfaceRef = 0;

  if( IsEqualGUID( &IID_IDPLobbySP, riid ) )
  {
    ICOM_THIS(IDPLobbySPImpl,*ppvObj);
    ICOM_VTBL(This) = &dpLobbySPVT;
  }
  else
  {
    /* Unsupported interface */
    HeapFree( GetProcessHeap(), 0, *ppvObj );
    *ppvObj = NULL;

    return E_NOINTERFACE;
  }

  IDPLobbySP_AddRef( (LPDPLOBBYSP)*ppvObj );

  return S_OK;
}

static 
ULONG WINAPI DPLSP_AddRef
( LPDPLOBBYSP iface )
{
  ULONG ulInterfaceRefCount, ulObjRefCount;
  ICOM_THIS(IDPLobbySPImpl,iface);

  ulObjRefCount       = InterlockedIncrement( &This->unk->ulObjRef );
  ulInterfaceRefCount = InterlockedIncrement( &This->ulInterfaceRef );

  TRACE( "ref count incremented to %lu:%lu for %p\n",
         ulInterfaceRefCount, ulObjRefCount, This );

  return ulObjRefCount;
}

static
ULONG WINAPI DPLSP_Release
( LPDPLOBBYSP iface )
{
  ULONG ulInterfaceRefCount, ulObjRefCount;
  ICOM_THIS(IDPLobbySPImpl,iface);

  ulObjRefCount       = InterlockedDecrement( &This->unk->ulObjRef );
  ulInterfaceRefCount = InterlockedDecrement( &This->ulInterfaceRef );

  TRACE( "ref count decremented to %lu:%lu for %p\n",
         ulInterfaceRefCount, ulObjRefCount, This );

  /* Deallocate if this is the last reference to the object */
  if( ulObjRefCount == 0 )
  {
     DPLSP_DestroyDPLobbySP( This );
     DPLSP_DestroyIUnknown( This );
  }

  if( ulInterfaceRefCount == 0 )
  {
    HeapFree( GetProcessHeap(), 0, This );
  }

  return ulInterfaceRefCount;
}

static 
HRESULT WINAPI IDPLobbySPImpl_AddGroupToGroup
( LPDPLOBBYSP iface, 
  LPSPDATA_ADDREMOTEGROUPTOGROUP argtg 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, argtg );
  return DP_OK;
}

static 
HRESULT WINAPI IDPLobbySPImpl_AddPlayerToGroup
( LPDPLOBBYSP iface, 
  LPSPDATA_ADDREMOTEPLAYERTOGROUP arptg 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, arptg );
  return DP_OK;
}

static 
HRESULT WINAPI IDPLobbySPImpl_CreateGroup
( LPDPLOBBYSP iface, 
  LPSPDATA_CREATEREMOTEGROUP crg 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, crg );
  return DP_OK;
}

static 
HRESULT WINAPI IDPLobbySPImpl_CreateGroupInGroup
( LPDPLOBBYSP iface, 
  LPSPDATA_CREATEREMOTEGROUPINGROUP crgig 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, crgig );
  return DP_OK;
}

static
HRESULT WINAPI IDPLobbySPImpl_DeleteGroupFromGroup
( LPDPLOBBYSP iface, 
  LPSPDATA_DELETEREMOTEGROUPFROMGROUP drgfg 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, drgfg );
  return DP_OK;
}

static
HRESULT WINAPI IDPLobbySPImpl_DeletePlayerFromGroup
( LPDPLOBBYSP iface, 
  LPSPDATA_DELETEREMOTEPLAYERFROMGROUP drpfg 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, drpfg );
  return DP_OK;
}

static
HRESULT WINAPI IDPLobbySPImpl_DestroyGroup
( LPDPLOBBYSP iface, 
  LPSPDATA_DESTROYREMOTEGROUP drg 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, drg );
  return DP_OK;
}

static
HRESULT WINAPI IDPLobbySPImpl_EnumSessionsResponse
( LPDPLOBBYSP iface, 
  LPSPDATA_ENUMSESSIONSRESPONSE er 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, er );
  return DP_OK;
}

static
HRESULT WINAPI IDPLobbySPImpl_GetSPDataPointer
( LPDPLOBBYSP iface, 
  LPVOID* lplpData 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, lplpData );
  return DP_OK;
}

static
HRESULT WINAPI IDPLobbySPImpl_HandleMessage
( LPDPLOBBYSP iface, 
  LPSPDATA_HANDLEMESSAGE hm 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, hm );
  return DP_OK;
}

static
HRESULT WINAPI IDPLobbySPImpl_SendChatMessage
( LPDPLOBBYSP iface, 
  LPSPDATA_CHATMESSAGE cm 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, cm );
  return DP_OK;
}

static
HRESULT WINAPI IDPLobbySPImpl_SetGroupName
( LPDPLOBBYSP iface, 
  LPSPDATA_SETREMOTEGROUPNAME srgn 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, srgn );
  return DP_OK;
}

static
HRESULT WINAPI IDPLobbySPImpl_SetPlayerName
( LPDPLOBBYSP iface, 
  LPSPDATA_SETREMOTEPLAYERNAME srpn 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, srpn );
  return DP_OK;
}

static
HRESULT WINAPI IDPLobbySPImpl_SetSessionDesc
( LPDPLOBBYSP iface, 
  LPSPDATA_SETSESSIONDESC ssd 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, ssd );
  return DP_OK;
}

static
HRESULT WINAPI IDPLobbySPImpl_SetSPDataPointer
( LPDPLOBBYSP iface, 
  LPVOID lpData 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, lpData );
  return DP_OK;
}

static
HRESULT WINAPI IDPLobbySPImpl_StartSession
( LPDPLOBBYSP iface, 
  LPSPDATA_STARTSESSIONCOMMAND ssc 
)
{
  ICOM_THIS(IDPLobbySPImpl,iface);
  FIXME( "(%p)->(%p):stub\n", This, ssc );
  return DP_OK;
}


static struct ICOM_VTABLE(IDPLobbySP) dpLobbySPVT =
{
  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE

  DPLSP_QueryInterface,
  DPLSP_AddRef,
  DPLSP_Release,

  IDPLobbySPImpl_AddGroupToGroup,
  IDPLobbySPImpl_AddPlayerToGroup,
  IDPLobbySPImpl_CreateGroup,
  IDPLobbySPImpl_CreateGroupInGroup,
  IDPLobbySPImpl_DeleteGroupFromGroup,
  IDPLobbySPImpl_DeletePlayerFromGroup,
  IDPLobbySPImpl_DestroyGroup,
  IDPLobbySPImpl_EnumSessionsResponse,
  IDPLobbySPImpl_GetSPDataPointer,
  IDPLobbySPImpl_HandleMessage,
  IDPLobbySPImpl_SendChatMessage,
  IDPLobbySPImpl_SetGroupName, 
  IDPLobbySPImpl_SetPlayerName, 
  IDPLobbySPImpl_SetSessionDesc,
  IDPLobbySPImpl_SetSPDataPointer,
  IDPLobbySPImpl_StartSession

};
