/*
 * Implementation of a generic ConnectionPoint object.
 *
 * Copyright 2000 Huw D M Davies for CodeWeavers
 *
 * See one exported function here is CreateConnectionPoint, see
 * comments just above that function for information.
 */

#include <assert.h>
#include "winerror.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "ole2.h"
#include "olectl.h"
#include "wine/obj_base.h"
#include "wine/obj_connection.h"
#include "connpt.h"

#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(ole);

#define MAXSINKS 10

/************************************************************************
 * Implementation of IConnectionPoint
 */
typedef struct ConnectionPointImpl {

  ICOM_VTABLE(IConnectionPoint)       *lpvtbl;

  /* IUnknown of our main object*/
  IUnknown *Obj;

  /* Reference count */
  DWORD ref;

  /* IID of sink interface */
  IID iid;

  /* Array of sink IUnknowns */
  IUnknown **sinks;
  DWORD maxSinks;

  DWORD nSinks;
} ConnectionPointImpl;

static ICOM_VTABLE(IConnectionPoint) ConnectionPointImpl_VTable;


/************************************************************************
 * Implementation of IEnumConnections
 */
typedef struct EnumConnectionsImpl {

  ICOM_VTABLE(IEnumConnections)       *lpvtbl;

  DWORD ref;

  /* IUnknown of ConnectionPoint, used for ref counting */
  IUnknown *pUnk;

  /* Connection Data */
  CONNECTDATA *pCD;
  DWORD nConns;
  
  /* Next connection to enumerate from */
  DWORD nCur;

} EnumConnectionsImpl;

static EnumConnectionsImpl *EnumConnectionsImpl_Construct(IUnknown *pUnk,
							  DWORD nSinks,
							  CONNECTDATA *pCD);


/************************************************************************
 * ConnectionPointImpl_Construct
 */
static ConnectionPointImpl *ConnectionPointImpl_Construct(IUnknown *pUnk,
							  REFIID riid)
{
  ConnectionPointImpl *Obj;

  Obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*Obj));
  Obj->lpvtbl = &ConnectionPointImpl_VTable;
  Obj->Obj = pUnk;
  Obj->ref = 1;
  Obj->iid =  *riid;
  Obj->maxSinks = MAXSINKS;
  Obj->sinks = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
			 sizeof(IUnknown*) * MAXSINKS);
  Obj->nSinks = 0;
  return Obj;
}

/************************************************************************
 * ConnectionPointImpl_Destroy
 */
static void ConnectionPointImpl_Destroy(ConnectionPointImpl *Obj)
{
  DWORD i;
  for(i = 0; i < Obj->maxSinks; i++) {
    if(Obj->sinks[i]) {
      IUnknown_Release(Obj->sinks[i]);
      Obj->sinks[i] = NULL;
    }
  }
  HeapFree(GetProcessHeap(), 0, Obj->sinks);
  HeapFree(GetProcessHeap(), 0, Obj);
  return;
}

static ULONG WINAPI ConnectionPointImpl_AddRef(IConnectionPoint* iface);
/************************************************************************
 * ConnectionPointImpl_QueryInterface (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static HRESULT WINAPI ConnectionPointImpl_QueryInterface(
  IConnectionPoint*  iface,
  REFIID  riid,
  void**  ppvObject)
{
  ICOM_THIS(ConnectionPointImpl, iface);
  TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);

  /*
   * Perform a sanity check on the parameters.
   */
  if ( (This==0) || (ppvObject==0) )
    return E_INVALIDARG;
  
  /*
   * Initialize the return parameter.
   */
  *ppvObject = 0;
  
  /*
   * Compare the riid with the interface IDs implemented by this object.
   */
  if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) 
  {
    *ppvObject = (IConnectionPoint*)This;
  }
  else if (memcmp(&IID_IConnectionPoint, riid, sizeof(IID_IConnectionPoint)) == 0) 
  {
    *ppvObject = (IConnectionPoint*)This;
  }
  
  /*
   * Check that we obtained an interface.
   */
  if ((*ppvObject)==0)
  {
    FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid));
    return E_NOINTERFACE;
  }
  
  /*
   * Query Interface always increases the reference count by one when it is
   * successful
   */
  ConnectionPointImpl_AddRef((IConnectionPoint*)This);

  return S_OK;;
}


/************************************************************************
 * ConnectionPointImpl_AddRef (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static ULONG WINAPI ConnectionPointImpl_AddRef(IConnectionPoint* iface)
{
  ICOM_THIS(ConnectionPointImpl, iface);
  TRACE("(%p)->(ref=%ld)\n", This, This->ref);
  This->ref++;

  return This->ref;
}
        
/************************************************************************
 * ConnectionPointImpl_Release (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static ULONG WINAPI ConnectionPointImpl_Release( 
      IConnectionPoint* iface)
{
  ICOM_THIS(ConnectionPointImpl, iface);
  TRACE("(%p)->(ref=%ld)\n", This, This->ref);

  /*
   * Decrease the reference count on this object.
   */
  This->ref--;

  /*
   * If the reference count goes down to 0, perform suicide.
   */
  if (This->ref==0)
  {
    ConnectionPointImpl_Destroy(This);

    return 0;
  }
  
  return This->ref;
}

/************************************************************************
 * ConnectionPointImpl_GetConnectionInterface (IConnectionPoint)
 *
 */
static HRESULT WINAPI ConnectionPointImpl_GetConnectionInterface(
					       IConnectionPoint *iface,
					       IID              *piid)
{
  ICOM_THIS(ConnectionPointImpl, iface);
  TRACE("(%p)->(%p) returning %s\n", This, piid, debugstr_guid(&(This->iid)));
  *piid = This->iid;
  return S_OK;
}

/************************************************************************
 * ConnectionPointImpl_GetConnectionPointContainer (IConnectionPoint)
 *
 */
static HRESULT WINAPI ConnectionPointImpl_GetConnectionPointContainer(
				      IConnectionPoint           *iface,
				      IConnectionPointContainer  **ppCPC)
{
  ICOM_THIS(ConnectionPointImpl, iface);
  TRACE("(%p)->(%p)\n", This, ppCPC);

  return IUnknown_QueryInterface(This->Obj,
				 &IID_IConnectionPointContainer,
				 (LPVOID)ppCPC);
}

/************************************************************************
 * ConnectionPointImpl_Advise (IConnectionPoint)
 *
 */
static HRESULT WINAPI ConnectionPointImpl_Advise(IConnectionPoint *iface,
						 IUnknown *lpUnk,
						 DWORD *pdwCookie)
{
  DWORD i;
  ICOM_THIS(ConnectionPointImpl, iface);
  IUnknown *lpSink;
  TRACE("(%p)->(%p, %p)\n", This, lpUnk, pdwCookie);

  *pdwCookie = 0;
  if(FAILED(IUnknown_QueryInterface(lpUnk, &This->iid, (LPVOID)&lpSink)))
    return CONNECT_E_CANNOTCONNECT;

  for(i = 0; i < This->maxSinks; i++) {
    if(This->sinks[i] == NULL)
      break;
  }
  if(i == This->maxSinks) {
    This->maxSinks += MAXSINKS;
    This->sinks = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->sinks,
			      This->maxSinks * sizeof(IUnknown *));
  }
  This->sinks[i] = lpSink;
  This->nSinks++;
  *pdwCookie = i + 1;
  return S_OK;
}


/************************************************************************
 * ConnectionPointImpl_Unadvise (IConnectionPoint)
 *
 */
static HRESULT WINAPI ConnectionPointImpl_Unadvise(IConnectionPoint *iface,
						   DWORD dwCookie)
{
  ICOM_THIS(ConnectionPointImpl, iface);
  TRACE("(%p)->(%ld)\n", This, dwCookie);

  if(dwCookie == 0 || dwCookie > This->maxSinks) return E_INVALIDARG;

  if(This->sinks[dwCookie-1] == NULL) return CONNECT_E_NOCONNECTION;

  IUnknown_Release(This->sinks[dwCookie-1]);
  This->sinks[dwCookie-1] = NULL;
  This->nSinks--;
  return S_OK;
}

/************************************************************************
 * ConnectionPointImpl_EnumConnections (IConnectionPoint)
 *
 */
static HRESULT WINAPI ConnectionPointImpl_EnumConnections(
						    IConnectionPoint *iface,
						    LPENUMCONNECTIONS *ppEnum)
{ 
  ICOM_THIS(ConnectionPointImpl, iface);
  CONNECTDATA *pCD;
  DWORD i, nextslot;
  EnumConnectionsImpl *EnumObj;
  HRESULT hr;

  TRACE("(%p)->(%p)\n", This, ppEnum);
  
  *ppEnum = NULL;

  if(This->nSinks == 0) return OLE_E_NOCONNECTION;

  pCD = HeapAlloc(GetProcessHeap(), 0, sizeof(CONNECTDATA) * This->nSinks);

  for(i = 0, nextslot = 0; i < This->maxSinks; i++) {
    if(This->sinks[i] != NULL) {
      pCD[nextslot].pUnk = This->sinks[i];
      pCD[nextslot].dwCookie = i + 1;
      nextslot++;
    }
  }
  assert(nextslot == This->nSinks);

  /* Bump the ref count of this object up by one.  It gets Released in
     IEnumConnections_Release */
  IUnknown_AddRef((IUnknown*)This);

  EnumObj = EnumConnectionsImpl_Construct((IUnknown*)This, This->nSinks, pCD);
  hr = IEnumConnections_QueryInterface((IEnumConnections*)EnumObj,
				  &IID_IEnumConnections, (LPVOID)ppEnum);
  IEnumConnections_Release((IEnumConnections*)EnumObj);

  HeapFree(GetProcessHeap(), 0, pCD);
  return hr;
}

static ICOM_VTABLE(IConnectionPoint) ConnectionPointImpl_VTable =
{
  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
  ConnectionPointImpl_QueryInterface,
  ConnectionPointImpl_AddRef,
  ConnectionPointImpl_Release,
  ConnectionPointImpl_GetConnectionInterface,
  ConnectionPointImpl_GetConnectionPointContainer,
  ConnectionPointImpl_Advise,
  ConnectionPointImpl_Unadvise,
  ConnectionPointImpl_EnumConnections
};


static ICOM_VTABLE(IEnumConnections) EnumConnectionsImpl_VTable;
static ULONG WINAPI EnumConnectionsImpl_AddRef(IEnumConnections* iface);

/************************************************************************
 * EnumConnectionsImpl_Construct
 */
static EnumConnectionsImpl *EnumConnectionsImpl_Construct(IUnknown *pUnk,
							  DWORD nSinks,
							  CONNECTDATA *pCD)
{
  EnumConnectionsImpl *Obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*Obj));
  DWORD i;

  Obj->lpvtbl = &EnumConnectionsImpl_VTable;
  Obj->ref = 1;
  Obj->pUnk = pUnk;
  Obj->pCD = HeapAlloc(GetProcessHeap(), 0, nSinks * sizeof(CONNECTDATA));
  Obj->nConns = nSinks;
  Obj->nCur = 0;

  for(i = 0; i < nSinks; i++) {
    Obj->pCD[i] = pCD[i];
    IUnknown_AddRef(Obj->pCD[i].pUnk);
  }
  return Obj;
}

/************************************************************************
 * EnumConnectionsImpl_Destroy
 */
static void EnumConnectionsImpl_Destroy(EnumConnectionsImpl *Obj)
{
  DWORD i;

  for(i = 0; i < Obj->nConns; i++)
    IUnknown_Release(Obj->pCD[i].pUnk);

  HeapFree(GetProcessHeap(), 0, Obj->pCD);
  HeapFree(GetProcessHeap(), 0, Obj);
  return;
}

/************************************************************************
 * EnumConnectionsImpl_QueryInterface (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static HRESULT WINAPI EnumConnectionsImpl_QueryInterface(
  IEnumConnections*  iface,
  REFIID  riid,
  void**  ppvObject)
{
  ICOM_THIS(ConnectionPointImpl, iface);
  TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);

  /*
   * Perform a sanity check on the parameters.
   */
  if ( (This==0) || (ppvObject==0) )
    return E_INVALIDARG;
  
  /*
   * Initialize the return parameter.
   */
  *ppvObject = 0;
  
  /*
   * Compare the riid with the interface IDs implemented by this object.
   */
  if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) 
  {
    *ppvObject = (IEnumConnections*)This;
  }
  else if (memcmp(&IID_IEnumConnections, riid, sizeof(IID_IEnumConnections)) == 0) 
  {
    *ppvObject = (IEnumConnections*)This;
  }
  
  /*
   * Check that we obtained an interface.
   */
  if ((*ppvObject)==0)
  {
    FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid));
    return E_NOINTERFACE;
  }
  
  /*
   * Query Interface always increases the reference count by one when it is
   * successful
   */
  EnumConnectionsImpl_AddRef((IEnumConnections*)This);

  return S_OK;;
}


/************************************************************************
 * EnumConnectionsImpl_AddRef (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static ULONG WINAPI EnumConnectionsImpl_AddRef(IEnumConnections* iface)
{
  ICOM_THIS(EnumConnectionsImpl, iface);
  TRACE("(%p)->(ref=%ld)\n", This, This->ref);
  This->ref++;
  IUnknown_AddRef(This->pUnk);
  return This->ref;
}
        
/************************************************************************
 * EnumConnectionsImpl_Release (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static ULONG WINAPI EnumConnectionsImpl_Release(IEnumConnections* iface)
{
  ICOM_THIS(EnumConnectionsImpl, iface);
  TRACE("(%p)->(ref=%ld)\n", This, This->ref);

  IUnknown_Release(This->pUnk);

  /*
   * Decrease the reference count on this object.
   */
  This->ref--;

  /*
   * If the reference count goes down to 0, perform suicide.
   */
  if (This->ref==0)
  {
    EnumConnectionsImpl_Destroy(This);

    return 0;
  }
  
  return This->ref;
}

/************************************************************************
 * EnumConnectionsImpl_Next (IEnumConnections)
 *
 */
static HRESULT WINAPI EnumConnectionsImpl_Next(IEnumConnections* iface,
					       ULONG cConn, LPCONNECTDATA pCD,
					       ULONG *pEnum)
{
  ICOM_THIS(EnumConnectionsImpl, iface);
  DWORD nRet = 0;
  TRACE("(%p)->(%ld, %p, %p)\n", This, cConn, pCD, pEnum);

  if(pEnum == NULL) {
    if(cConn != 1)
      return E_POINTER;
  } else
    *pEnum = 0;

  if(This->nCur >= This->nConns)
    return S_FALSE;

  while(This->nCur < This->nConns && cConn) {
    *pCD++ = This->pCD[This->nCur];
    IUnknown_AddRef(This->pCD[This->nCur].pUnk);
    This->nCur++;
    cConn--;
    nRet++;
  }

  if(pEnum)
    *pEnum = nRet;

  return S_OK;
}


/************************************************************************
 * EnumConnectionsImpl_Skip (IEnumConnections)
 *
 */
static HRESULT WINAPI EnumConnectionsImpl_Skip(IEnumConnections* iface,
					       ULONG cSkip)
{
  ICOM_THIS(EnumConnectionsImpl, iface);
  TRACE("(%p)->(%ld)\n", This, cSkip);

  if(This->nCur + cSkip >= This->nConns)
    return S_FALSE;

  This->nCur += cSkip;

  return S_OK;
}


/************************************************************************
 * EnumConnectionsImpl_Reset (IEnumConnections)
 *
 */
static HRESULT WINAPI EnumConnectionsImpl_Reset(IEnumConnections* iface)
{
  ICOM_THIS(EnumConnectionsImpl, iface);
  TRACE("(%p)\n", This);

  This->nCur = 0;

  return S_OK;
}


/************************************************************************
 * EnumConnectionsImpl_Clone (IEnumConnections)
 *
 */
static HRESULT WINAPI EnumConnectionsImpl_Clone(IEnumConnections* iface,
						LPENUMCONNECTIONS *ppEnum)
{
  ICOM_THIS(EnumConnectionsImpl, iface);
  EnumConnectionsImpl *newObj;
  TRACE("(%p)->(%p)\n", This, ppEnum);
  
  newObj = EnumConnectionsImpl_Construct(This->pUnk, This->nConns, This->pCD);
  newObj->nCur = This->nCur;
  *ppEnum = (LPENUMCONNECTIONS)newObj;
  IUnknown_AddRef(This->pUnk);
  return S_OK;
}
  
static ICOM_VTABLE(IEnumConnections) EnumConnectionsImpl_VTable =
{
  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
  EnumConnectionsImpl_QueryInterface,
  EnumConnectionsImpl_AddRef,
  EnumConnectionsImpl_Release,
  EnumConnectionsImpl_Next,
  EnumConnectionsImpl_Skip,
  EnumConnectionsImpl_Reset,
  EnumConnectionsImpl_Clone
};

/************************************************************************
 *
 *  The exported function to create the connection point.
 *  NB not a windows API
 *
 * PARAMS
 * pUnk [in] IUnknown of object to which the ConnectionPoint is associated.
 *           Needed to access IConnectionPointContainer.
 *
 * riid [in] IID of sink interface that this ConnectionPoint manages
 *
 * pCP [out] returns IConnectionPoint
 *
 */
HRESULT CreateConnectionPoint(IUnknown *pUnk, REFIID riid,
			      IConnectionPoint **pCP)
{
  ConnectionPointImpl *Obj;
  HRESULT hr;

  Obj = ConnectionPointImpl_Construct(pUnk, riid);
  if(!Obj) return E_OUTOFMEMORY;

  hr = IConnectionPoint_QueryInterface((IConnectionPoint *)Obj, 
				       &IID_IConnectionPoint, (LPVOID)pCP);
  IConnectionPoint_Release((IConnectionPoint *)Obj);
  return hr;
}
