/* This contains the implementation of the Lobby Service
 * Providers interface required to communicate with Direct Play
 *
 * Copyright 2001 Peter Hunnisett
 *
 * 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 "winerror.h"
#include "wine/debug.h"

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

WINE_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);
    This->lpVtbl = &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);
    This->lpVtbl = &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

};
