/*
 * Pointer Moniker Implementation
 *
 * Copyright 1999 Noomen Hamza
 * Copyright 2008 Robert Shearman (for CodeWeavers)
 *
 * 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 <stdarg.h>
#include <string.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winuser.h"
#include "objbase.h"
#include "oleidl.h"
#include "wine/debug.h"
#include "moniker.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

/* PointerMoniker data structure */
typedef struct PointerMonikerImpl{

    IMoniker IMoniker_iface;

    LONG ref; /* reference counter for this object */

    IUnknown *pObject; /* custom marshaler */
} PointerMonikerImpl;

static inline PointerMonikerImpl *impl_from_IMoniker(IMoniker *iface)
{
return CONTAINING_RECORD(iface, PointerMonikerImpl, IMoniker_iface);
}

static HRESULT WINAPI
PointerMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
{
    PointerMonikerImpl *This = impl_from_IMoniker(iface);

    TRACE("(%p,%p,%p)\n",This,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 (IsEqualIID(&IID_IUnknown, riid) ||
        IsEqualIID(&IID_IPersist, riid) ||
        IsEqualIID(&IID_IPersistStream, riid) ||
        IsEqualIID(&IID_IMoniker, riid))
        *ppvObject = iface;

    /* Check that we obtained an interface.*/
    if ((*ppvObject)==0)
        return E_NOINTERFACE;

    /* always increase the reference count by one when it is successful */
    IMoniker_AddRef(iface);

    return S_OK;
}

/******************************************************************************
 *        PointerMoniker_AddRef
 ******************************************************************************/
static ULONG WINAPI
PointerMonikerImpl_AddRef(IMoniker* iface)
{
    PointerMonikerImpl *This = impl_from_IMoniker(iface);

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

    return InterlockedIncrement(&This->ref);
}

/******************************************************************************
 *        PointerMoniker_Release
 ******************************************************************************/
static ULONG WINAPI
PointerMonikerImpl_Release(IMoniker* iface)
{
    PointerMonikerImpl *This = impl_from_IMoniker(iface);
    ULONG ref;

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

    ref = InterlockedDecrement(&This->ref);

    /* destroy the object if there's no more reference on it */
    if (ref == 0)
    {
        if (This->pObject) IUnknown_Release(This->pObject);
        HeapFree(GetProcessHeap(),0,This);
    }

    return ref;
}

/******************************************************************************
 *        PointerMoniker_GetClassID
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
{
    TRACE("(%p,%p)\n",iface,pClassID);

    if (pClassID==NULL)
        return E_POINTER;

    *pClassID = CLSID_PointerMoniker;

    return S_OK;
}

/******************************************************************************
 *        PointerMoniker_IsDirty
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_IsDirty(IMoniker* iface)
{
    /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
       method in the OLE-provided moniker interfaces always return S_FALSE because
       their internal state never changes. */

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

    return S_FALSE;
}

/******************************************************************************
 *        PointerMoniker_Load
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_Load(IMoniker* iface,IStream* pStm)
{
    TRACE("(%p)\n", pStm);

    return E_NOTIMPL;
}

/******************************************************************************
 *        PointerMoniker_Save
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
{
    TRACE("(%p, %d)\n", pStm, fClearDirty);

    return E_NOTIMPL;
}

/******************************************************************************
 *        PointerMoniker_GetSizeMax
 *
 * PARAMS
 * pcbSize [out] Pointer to size of stream needed to save object
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
{
    TRACE("(%p,%p)\n",iface,pcbSize);

    if (!pcbSize)
        return E_POINTER;

    pcbSize->u.LowPart = 0;
    pcbSize->u.HighPart = 0;

    return E_NOTIMPL;
}

/******************************************************************************
 *                  PointerMoniker_BindToObject
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
                             REFIID riid, VOID** ppvResult)
{
    PointerMonikerImpl *This = impl_from_IMoniker(iface);

    TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);

    if (!This->pObject)
        return E_UNEXPECTED;

    return IUnknown_QueryInterface(This->pObject, riid, ppvResult);
}

/******************************************************************************
 *        PointerMoniker_BindToStorage
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
                              REFIID riid, VOID** ppvResult)
{
    PointerMonikerImpl *This = impl_from_IMoniker(iface);

    TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);

    if (!This->pObject)
        return E_UNEXPECTED;

    return IUnknown_QueryInterface(This->pObject, riid, ppvResult);
}

/******************************************************************************
 *        PointerMoniker_Reduce
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
                       IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
{
    TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);

    if (ppmkReduced==NULL)
        return E_POINTER;

    PointerMonikerImpl_AddRef(iface);

    *ppmkReduced=iface;

    return MK_S_REDUCED_TO_SELF;
}
/******************************************************************************
 *        PointerMoniker_ComposeWith
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
                            BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
{

    HRESULT res=S_OK;
    DWORD mkSys,mkSys2;
    IEnumMoniker* penumMk=0;
    IMoniker *pmostLeftMk=0;
    IMoniker* tempMkComposite=0;

    TRACE("(%p,%d,%p)\n", pmkRight, fOnlyIfNotGeneric, ppmkComposite);

    if ((ppmkComposite==NULL)||(pmkRight==NULL))
	return E_POINTER;

    *ppmkComposite=0;

    IMoniker_IsSystemMoniker(pmkRight,&mkSys);

    /* If pmkRight is an anti-moniker, the returned moniker is NULL */
    if(mkSys==MKSYS_ANTIMONIKER)
        return res;

    else
        /* if pmkRight is a composite whose leftmost component is an anti-moniker,           */
        /* the returned moniker is the composite after the leftmost anti-moniker is removed. */

         if(mkSys==MKSYS_GENERICCOMPOSITE){

            res=IMoniker_Enum(pmkRight,TRUE,&penumMk);

            if (FAILED(res))
                return res;

            res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);

            IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);

            if(mkSys2==MKSYS_ANTIMONIKER){

                IMoniker_Release(pmostLeftMk);

                tempMkComposite=iface;
                IMoniker_AddRef(iface);

                while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){

                    res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);

                    IMoniker_Release(tempMkComposite);
                    IMoniker_Release(pmostLeftMk);

                    tempMkComposite=*ppmkComposite;
                    IMoniker_AddRef(tempMkComposite);
                }
                return res;
            }
            else
                return CreateGenericComposite(iface,pmkRight,ppmkComposite);
         }
         /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
          composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
          a NULL moniker and a return value of MK_E_NEEDGENERIC */
          else
            if (!fOnlyIfNotGeneric)
                return CreateGenericComposite(iface,pmkRight,ppmkComposite);

            else
                return MK_E_NEEDGENERIC;
}

/******************************************************************************
 *        PointerMoniker_Enum
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
{
    TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);

    if (ppenumMoniker == NULL)
        return E_POINTER;

    *ppenumMoniker = NULL;

    return S_OK;
}

/******************************************************************************
 *        PointerMoniker_IsEqual
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
{
    PointerMonikerImpl *This = impl_from_IMoniker(iface);
    DWORD mkSys;

    TRACE("(%p,%p)\n",iface,pmkOtherMoniker);

    if (pmkOtherMoniker==NULL)
        return S_FALSE;

    IMoniker_IsSystemMoniker(pmkOtherMoniker,&mkSys);

    if (mkSys==MKSYS_POINTERMONIKER)
    {
        PointerMonikerImpl *pOtherMoniker = impl_from_IMoniker(pmkOtherMoniker);
        return This->pObject == pOtherMoniker->pObject ? S_OK : S_FALSE;
    }
    else
        return S_FALSE;
}

/******************************************************************************
 *        PointerMoniker_Hash
 ******************************************************************************/
static HRESULT WINAPI PointerMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
{
    PointerMonikerImpl *This = impl_from_IMoniker(iface);

    if (pdwHash==NULL)
        return E_POINTER;

    *pdwHash = (DWORD)This->pObject;

    return S_OK;
}

/******************************************************************************
 *        PointerMoniker_IsRunning
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
                          IMoniker* pmkNewlyRunning)
{
    TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);

    return S_OK;
}

/******************************************************************************
 *        PointerMoniker_GetTimeOfLastChange
 ******************************************************************************/
static HRESULT WINAPI PointerMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
                                                   IBindCtx* pbc,
                                                   IMoniker* pmkToLeft,
                                                   FILETIME* pAntiTime)
{
    TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pAntiTime);
    return E_NOTIMPL;
}

/******************************************************************************
 *        PointerMoniker_Inverse
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
{
    TRACE("(%p,%p)\n",iface,ppmk);

    return CreateAntiMoniker(ppmk);
}

/******************************************************************************
 *        PointerMoniker_CommonPrefixWith
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
{
    TRACE("(%p, %p)\n", pmkOther, ppmkPrefix);

    *ppmkPrefix = NULL;

    if (PointerMonikerImpl_IsEqual(iface, pmkOther))
    {
        IMoniker_AddRef(iface);

        *ppmkPrefix=iface;

        return MK_S_US;
    }
    else
        return MK_E_NOPREFIX;
}

/******************************************************************************
 *        PointerMoniker_RelativePathTo
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
{
    TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);

    if (ppmkRelPath==NULL)
        return E_POINTER;

    *ppmkRelPath = NULL;

    return E_NOTIMPL;
}

/******************************************************************************
 *        PointerMoniker_GetDisplayName
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
                               IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
{
    TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);

    if (ppszDisplayName==NULL)
        return E_POINTER;

    *ppszDisplayName = NULL;
    return E_NOTIMPL;
}

/******************************************************************************
 *        PointerMoniker_ParseDisplayName
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_ParseDisplayName(IMoniker* iface, IBindCtx* pbc,
                                 IMoniker* pmkToLeft, LPOLESTR pszDisplayName,
                                 ULONG* pchEaten, IMoniker** ppmkOut)
{
    PointerMonikerImpl *This = impl_from_IMoniker(iface);
    HRESULT hr;
    IParseDisplayName *pPDN;

    TRACE("(%p,%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);

    if (pmkToLeft)
        return MK_E_SYNTAX;

    if (!This->pObject)
        return E_UNEXPECTED;

    hr = IUnknown_QueryInterface(This->pObject, &IID_IParseDisplayName, (void **)&pPDN);
    if (FAILED(hr))
        return hr;

    hr = IParseDisplayName_ParseDisplayName(pPDN, pbc, pszDisplayName, pchEaten, ppmkOut);
    IParseDisplayName_Release(pPDN);

    return hr;
}

/******************************************************************************
 *        PointerMoniker_IsSystemMoniker
 ******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
{
    TRACE("(%p,%p)\n",iface,pwdMksys);

    if (!pwdMksys)
        return E_POINTER;

    *pwdMksys = MKSYS_POINTERMONIKER;

    return S_OK;
}

/********************************************************************************/
/* Virtual function table for the PointerMonikerImpl class which  include IPersist,*/
/* IPersistStream and IMoniker functions.                                       */
static const IMonikerVtbl VT_PointerMonikerImpl =
{
    PointerMonikerImpl_QueryInterface,
    PointerMonikerImpl_AddRef,
    PointerMonikerImpl_Release,
    PointerMonikerImpl_GetClassID,
    PointerMonikerImpl_IsDirty,
    PointerMonikerImpl_Load,
    PointerMonikerImpl_Save,
    PointerMonikerImpl_GetSizeMax,
    PointerMonikerImpl_BindToObject,
    PointerMonikerImpl_BindToStorage,
    PointerMonikerImpl_Reduce,
    PointerMonikerImpl_ComposeWith,
    PointerMonikerImpl_Enum,
    PointerMonikerImpl_IsEqual,
    PointerMonikerImpl_Hash,
    PointerMonikerImpl_IsRunning,
    PointerMonikerImpl_GetTimeOfLastChange,
    PointerMonikerImpl_Inverse,
    PointerMonikerImpl_CommonPrefixWith,
    PointerMonikerImpl_RelativePathTo,
    PointerMonikerImpl_GetDisplayName,
    PointerMonikerImpl_ParseDisplayName,
    PointerMonikerImpl_IsSystemMoniker
};

/******************************************************************************
 *         PointerMoniker_Construct (local function)
 *******************************************************************************/
static void PointerMonikerImpl_Construct(PointerMonikerImpl* This, IUnknown *punk)
{
    TRACE("(%p)\n",This);

    /* Initialize the virtual function table. */
    This->IMoniker_iface.lpVtbl = &VT_PointerMonikerImpl;
    This->ref = 1;
    if (punk)
        IUnknown_AddRef(punk);
    This->pObject      = punk;
}

/***********************************************************************
 *           CreatePointerMoniker (OLE32.@)
 *
 * Creates a moniker which represents a pointer.
 *
 * PARAMS
 *  punk [I] Pointer to the object to represent.
 *  ppmk [O] Address that receives the pointer to the created moniker.
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: Any HRESULT code.
 */
HRESULT WINAPI CreatePointerMoniker(LPUNKNOWN punk, LPMONIKER *ppmk)
{
    PointerMonikerImpl *This;

    TRACE("(%p, %p)\n", punk, ppmk);

    if (!ppmk)
        return E_INVALIDARG;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
    if (!This)
    {
        *ppmk = NULL;
        return E_OUTOFMEMORY;
    }

    PointerMonikerImpl_Construct(This, punk);
    *ppmk = &This->IMoniker_iface;
    return S_OK;
}

static HRESULT WINAPI PointerMonikerCF_QueryInterface(LPCLASSFACTORY iface,
                                                  REFIID riid, LPVOID *ppv)
{
    *ppv = NULL;
    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
    {
        *ppv = iface;
        IUnknown_AddRef(iface);
        return S_OK;
    }
    return E_NOINTERFACE;
}

static ULONG WINAPI PointerMonikerCF_AddRef(LPCLASSFACTORY iface)
{
    return 2; /* non-heap based object */
}

static ULONG WINAPI PointerMonikerCF_Release(LPCLASSFACTORY iface)
{
    return 1; /* non-heap based object */
}

static HRESULT WINAPI PointerMonikerCF_CreateInstance(LPCLASSFACTORY iface,
    LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
    IMoniker *pMoniker;
    HRESULT  hr;

    TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);

    *ppv = NULL;

    if (pUnk)
        return CLASS_E_NOAGGREGATION;

    hr = CreatePointerMoniker(NULL, &pMoniker);
    if (FAILED(hr))
        return hr;

	hr = IMoniker_QueryInterface(pMoniker, riid, ppv);

    if (FAILED(hr))
        IMoniker_Release(pMoniker);

    return hr;
}

static HRESULT WINAPI PointerMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
    FIXME("(%d), stub!\n",fLock);
    return S_OK;
}

static const IClassFactoryVtbl PointerMonikerCFVtbl =
{
    PointerMonikerCF_QueryInterface,
    PointerMonikerCF_AddRef,
    PointerMonikerCF_Release,
    PointerMonikerCF_CreateInstance,
    PointerMonikerCF_LockServer
};
static const IClassFactoryVtbl *PointerMonikerCF = &PointerMonikerCFVtbl;

HRESULT PointerMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
    return IClassFactory_QueryInterface((IClassFactory *)&PointerMonikerCF, riid, ppv);
}
