/*
 *	Monikers
 *
 *	Copyright 1998	Marcus Meissner
 *      Copyright 1999  Noomen Hamza
 */

#include <assert.h>
#include <string.h>

#include "winerror.h"
#include "winbase.h"
#include "wtypes.h"
#include "wine/obj_base.h"
#include "wine/obj_storage.h"
#include "wine/obj_misc.h"
#include "wine/obj_moniker.h"
#include "debugtools.h"
#include "heap.h"
#include "ole2.h"

#include "compobj_private.h"

DEFAULT_DEBUG_CHANNEL(ole);

#define  BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */

/* define the structure of the running object table elements */
typedef struct RunObject{

    IUnknown*  pObj; /* points on a running object*/
    IMoniker*  pmkObj; /* points on a moniker who identifies this object */
    FILETIME   lastModifObj;
    DWORD      identRegObj; /* registration key relative to this object */
    DWORD      regTypeObj; /* registration type : strong or weak */
}RunObject;

/* define the RunningObjectTableImpl structure */
typedef struct RunningObjectTableImpl{

    ICOM_VFIELD(IRunningObjectTable);
    ULONG      ref;

    RunObject* runObjTab;            /* pointer to the first object in the table       */
    DWORD      runObjTabSize;       /* current table size                            */
    DWORD      runObjTabLastIndx;  /* first free index element in the table.        */
    DWORD      runObjTabRegister; /* registration key of the next registered object */
    
} RunningObjectTableImpl;

RunningObjectTableImpl* runningObjectTableInstance=0;

/* IRunningObjectTable prototype functions : */
/* IUnknown functions*/
static HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject);
static ULONG   WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface);
static ULONG   WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface);
/* IRunningObjectTable functions */
static HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,IUnknown* punkObject,IMoniker* pmkObjectName,DWORD* pdwRegister);
static HRESULT WINAPI RunningObjectTableImpl_Revoke(IRunningObjectTable* iface, DWORD dwRegister);
static HRESULT WINAPI RunningObjectTableImpl_IsRunning(IRunningObjectTable* iface, IMoniker* pmkObjectName);
static HRESULT WINAPI RunningObjectTableImpl_GetObject(IRunningObjectTable* iface, IMoniker* pmkObjectName,IUnknown** ppunkObject);
static HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface, DWORD dwRegister,FILETIME* pfiletime);
static HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface, IMoniker* pmkObjectName,FILETIME* pfiletime);
static HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface, IEnumMoniker** ppenumMoniker);
/* Local functions*/
HRESULT WINAPI RunningObjectTableImpl_Initialize();
HRESULT WINAPI RunningObjectTableImpl_UnInitialize();
HRESULT WINAPI RunningObjectTableImpl_Destroy();
HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx);

/* Virtual function table for the IRunningObjectTable class. */
static ICOM_VTABLE(IRunningObjectTable) VT_RunningObjectTableImpl =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    RunningObjectTableImpl_QueryInterface,
    RunningObjectTableImpl_AddRef,
    RunningObjectTableImpl_Release,
    RunningObjectTableImpl_Register,
    RunningObjectTableImpl_Revoke,
    RunningObjectTableImpl_IsRunning,
    RunningObjectTableImpl_GetObject,
    RunningObjectTableImpl_NoteChangeTime,
    RunningObjectTableImpl_GetTimeOfLastChange,
    RunningObjectTableImpl_EnumRunning
};

/***********************************************************************
 *        RunningObjectTable_QueryInterface
 */
HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject)
{
    ICOM_THIS(RunningObjectTableImpl,iface);

    TRACE("(%p,%p,%p)\n",This,riid,ppvObject);

    /* validate arguments */
    if (This==0)
        return CO_E_NOTINITIALIZED;

    if (ppvObject==0)
        return E_INVALIDARG;

    *ppvObject = 0;

    if (IsEqualIID(&IID_IUnknown, riid))
        *ppvObject = (IRunningObjectTable*)This;
    else
        if (IsEqualIID(&IID_IRunningObjectTable, riid))
            *ppvObject = (IRunningObjectTable*)This;

    if ((*ppvObject)==0)
        return E_NOINTERFACE;

    RunningObjectTableImpl_AddRef(iface);

    return S_OK;
}

/***********************************************************************
 *        RunningObjectTable_AddRef
 */
ULONG   WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
{
    ICOM_THIS(RunningObjectTableImpl,iface);

    TRACE("(%p)\n",This);

    return ++(This->ref);
}

/***********************************************************************
 *        RunningObjectTable_Initialize
 */
HRESULT WINAPI RunningObjectTableImpl_Destroy()
{
    TRACE("()\n");
    
    if (runningObjectTableInstance==NULL)
        return E_INVALIDARG;

    /* free the ROT table memory */
    HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab);

    /* free the ROT structure memory */
    HeapFree(GetProcessHeap(),0,runningObjectTableInstance);

    return S_OK;
}

/***********************************************************************
 *        RunningObjectTable_Release
 */
ULONG   WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface)
{
    DWORD i;
    ICOM_THIS(RunningObjectTableImpl,iface);

    TRACE("(%p)\n",This);

    This->ref--;

    /* unitialize ROT structure if there's no more reference to it*/
    if (This->ref==0){

        /* release all registered objects */
        for(i=0;i<This->runObjTabLastIndx;i++)
        {
            if (( This->runObjTab[i].regTypeObj &  ROTFLAGS_REGISTRATIONKEEPSALIVE) != 0)
                IUnknown_Release(This->runObjTab[i].pObj);
 
            IMoniker_Release(This->runObjTab[i].pmkObj);
        }
       /*  RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
        *  when RunningObjectTableImpl_UnInitialize function is called
        */

        /* there's no more elements in the table */
        This->runObjTabRegister=0;
        This->runObjTabLastIndx=0;

        return 0;
    }

    return This->ref;
}

/***********************************************************************
 *        RunningObjectTable_Initialize
 */
HRESULT WINAPI RunningObjectTableImpl_Initialize()
{
    TRACE("()\n");

    /* create the unique instance of the RunningObjectTableImpl structure */
    runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl));

    if (runningObjectTableInstance == 0)
        return E_OUTOFMEMORY;

    /* initialize the virtual table function */
    ICOM_VTBL(runningObjectTableInstance) = &VT_RunningObjectTableImpl;

    /* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
    /* the ROT refered many times  not in the same time (all the objects in the ROT will  */
    /* be removed every time the ROT is removed ) */
    runningObjectTableInstance->ref = 1;

    /* allocate space memory for the table which contains all the running objects */
    runningObjectTableInstance->runObjTab = HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject[BLOCK_TAB_SIZE]));

    if (runningObjectTableInstance->runObjTab == NULL)
        return E_OUTOFMEMORY;

    runningObjectTableInstance->runObjTabSize=BLOCK_TAB_SIZE;
    runningObjectTableInstance->runObjTabRegister=1;
    runningObjectTableInstance->runObjTabLastIndx=0;

    return S_OK;
}

/***********************************************************************
 *        RunningObjectTable_UnInitialize
 */
HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
{
    TRACE("()\n");

    if (runningObjectTableInstance==NULL)
        return E_POINTER;
    
    RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance);

    RunningObjectTableImpl_Destroy();

    return S_OK;
}

/***********************************************************************
 *        RunningObjectTable_Register
 */
HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface,
                                               DWORD grfFlags,           /* Registration options */
                                               IUnknown *punkObject,     /* Pointer to the object being registered */
                                               IMoniker *pmkObjectName,  /* Pointer to the moniker of the object being registered */
                                               DWORD *pdwRegister)       /* Pointer to the value identifying the  registration */
{
    HRESULT res=S_OK;
    ICOM_THIS(RunningObjectTableImpl,iface);

    TRACE("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);

    /* there's only two types of register : strong and or weak registration (only one must be passed on parameter) */
    if ( ( (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || !(grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
         (!(grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) ||  (grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
         (grfFlags) )
        return E_INVALIDARG;

    if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
        return E_INVALIDARG;

    /* verify if the object to be registered was registered before */
    if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL)==S_OK)
        res = MK_S_MONIKERALREADYREGISTERED;

    /* put the new registered object in the first free element in the table */
    This->runObjTab[This->runObjTabLastIndx].pObj = punkObject;
    This->runObjTab[This->runObjTabLastIndx].pmkObj = pmkObjectName;
    This->runObjTab[This->runObjTabLastIndx].regTypeObj = grfFlags;
    This->runObjTab[This->runObjTabLastIndx].identRegObj = This->runObjTabRegister;
    CoFileTimeNow(&(This->runObjTab[This->runObjTabLastIndx].lastModifObj));
    
    /* gives a registration identifier to the registered object*/
    (*pdwRegister)= This->runObjTabRegister;

    if (This->runObjTabRegister == 0xFFFFFFFF){

        FIXME("runObjTabRegister: %ld is out of data limite \n",This->runObjTabRegister);
	return E_FAIL;
}
    This->runObjTabRegister++;
    This->runObjTabLastIndx++;
    
    if (This->runObjTabLastIndx == This->runObjTabSize){ /* table is full ! so it must be resized */

        This->runObjTabSize+=BLOCK_TAB_SIZE; /* newsize table */
        This->runObjTab=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->runObjTab,
                        This->runObjTabSize * sizeof(RunObject));
        if (!This->runObjTab)
            return E_OUTOFMEMORY;
    }
    /* add a reference to the object in the strong registration case */
    if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 )
        IUnknown_AddRef(punkObject);

    IMoniker_AddRef(pmkObjectName);
    
    return res;
}

/***********************************************************************
 *        RunningObjectTable_Revoke
 */
HRESULT WINAPI RunningObjectTableImpl_Revoke(  IRunningObjectTable* iface,
                                               DWORD dwRegister)  /* Value identifying registration to be revoked*/
{

    DWORD index,j;
    ICOM_THIS(RunningObjectTableImpl,iface);

    TRACE("(%p,%ld)\n",This,dwRegister);

    /* verify if the object to be revoked was registered before or not */
    if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)

        return E_INVALIDARG;

    /* release the object if it was registered with a strong registrantion option */
    if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0)
        IUnknown_Release(This->runObjTab[index].pObj);

    IMoniker_Release(This->runObjTab[index].pmkObj);
    
    /* remove the object from the table */
    for(j=index; j<This->runObjTabLastIndx-1; j++)
        This->runObjTab[j]= This->runObjTab[j+1];
    
    This->runObjTabLastIndx--;

    return S_OK;
}

/***********************************************************************
 *        RunningObjectTable_IsRunning
 */
HRESULT WINAPI RunningObjectTableImpl_IsRunning(  IRunningObjectTable* iface,
                                                  IMoniker *pmkObjectName)  /* Pointer to the moniker of the object whose status is desired */
{    
    ICOM_THIS(RunningObjectTableImpl,iface);

    TRACE("(%p,%p)\n",This,pmkObjectName);

    return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL);
}

/***********************************************************************
 *        RunningObjectTable_GetObject
 */
HRESULT WINAPI RunningObjectTableImpl_GetObject(  IRunningObjectTable* iface,
                                                  IMoniker *pmkObjectName,/* Pointer to the moniker on the object */
                                                  IUnknown **ppunkObject) /* Address of output variable that receives the IUnknown interface pointer */
{
    DWORD index;
    ICOM_THIS(RunningObjectTableImpl,iface);

    TRACE("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);

    if (ppunkObject==NULL)
        return E_POINTER;
    
    *ppunkObject=0;

    /* verify if the object was registered before or not */
    if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
        return MK_E_UNAVAILABLE;

    /* add a reference to the object then set output object argument */
    IUnknown_AddRef(This->runObjTab[index].pObj);
    *ppunkObject=This->runObjTab[index].pObj;

    return S_OK;
}

/***********************************************************************
 *        RunningObjectTable_NoteChangeTime
 */
HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
                                                     DWORD dwRegister,  /* Value identifying registration being updated */
                                                     FILETIME *pfiletime) /* Pointer to structure containing object's last change time */
{
    DWORD index=-1;
    ICOM_THIS(RunningObjectTableImpl,iface);

    TRACE("(%p,%ld,%p)\n",This,dwRegister,pfiletime);

    /* verify if the object to be changed was registered before or not */
    if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
        return E_INVALIDARG;

    /* set the new value of the last time change */
    This->runObjTab[index].lastModifObj= (*pfiletime);

    return S_OK;
}
    
/***********************************************************************
 *        RunningObjectTable_GetTimeOfLastChange
 */
HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
                                                          IMoniker *pmkObjectName,  /* Pointer to moniker on the object whose status is desired */
                                                          FILETIME *pfiletime)       /* Pointer to structure that receives object's last change time */
{
    DWORD index=-1;
    ICOM_THIS(RunningObjectTableImpl,iface);

    TRACE("(%p,%p,%p)\n",This,pmkObjectName,pfiletime);

    if (pmkObjectName==NULL || pfiletime==NULL)
        return E_INVALIDARG;

    /* verify if the object was registered before or not */
    if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
        return MK_E_UNAVAILABLE;;

    (*pfiletime)= This->runObjTab[index].lastModifObj;

    return S_OK;
}

/***********************************************************************
 *        RunningObjectTable_EnumRunning
 */
HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
                                                  IEnumMoniker **ppenumMoniker) /* Address of output variable that receives the IEnumMoniker interface pointer */
{
    FIXME("(%p,%p) needs the IEnumMoniker implementation  \n",iface,ppenumMoniker);
    return E_NOTIMPL;
}

/***********************************************************************
 *        GetObjectIndex
 */
HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,
                                                     DWORD identReg,
                                                     IMoniker* pmk,
                                                     DWORD *indx)
{

    DWORD i;

    TRACE("(%p,%ld,%p,%p)\n",This,identReg,pmk,indx);

    if (pmk!=NULL)
        /* search object identified by a moniker */
        for(i=0 ; (i < This->runObjTabLastIndx) &&(!IMoniker_IsEqual(This->runObjTab[i].pmkObj,pmk)==S_OK);i++);
    else
        /* search object identified by a register identifier */
        for(i=0;((i<This->runObjTabLastIndx)&&(This->runObjTab[i].identRegObj!=identReg));i++);
    
    if (i==This->runObjTabLastIndx)  return S_FALSE;

    if (indx != NULL)  *indx=i;

    return S_OK;
}

/******************************************************************************
 *		GetRunningObjectTable16	[OLE2.30]
 */
HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
{
	FIXME("(%ld,%p),stub!\n",reserved,pprot);
    return E_NOTIMPL;
}

/***********************************************************************
 *           GetRunningObjectTable (OLE2.73)
 */
HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
{
    IID riid=IID_IRunningObjectTable;
    HRESULT res;

    TRACE("()\n");

    if (reserved!=0)
        return E_UNEXPECTED;

    if(runningObjectTableInstance==NULL)
        return CO_E_NOTINITIALIZED;

    res = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);

    return res;
}

/******************************************************************************
 *              OleRun        [OLE32.123]
 */
HRESULT WINAPI OleRun(LPUNKNOWN pUnknown)
{
  IRunnableObject	*runable;
  ICOM_THIS(IRunnableObject,pUnknown);
  LRESULT		ret;

  ret = IRunnableObject_QueryInterface(This,&IID_IRunnableObject,(LPVOID*)&runable);
  if (ret) 
	return 0; /* Appears to return no error. */
  ret  = IRunnableObject_Run(runable,NULL);
  IRunnableObject_Release(runable);
  return ret;
}

/******************************************************************************
 *              MkParseDisplayName        [OLE32.81]
 */
HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szUserName,
				LPDWORD pchEaten, LPMONIKER *ppmk)
{
    FIXME("(%p, %s, %p, %p): stub.\n", pbc, debugstr_w(szUserName), pchEaten, *ppmk);
    if (!(IsValidInterface((LPUNKNOWN) pbc)))
	return E_INVALIDARG;

    return MK_E_SYNTAX;
}
