/**
 * Dispatch API functions
 *
 * Copyright 2000  Francois Jacques, Macadamian Technologies Inc.
 *
 * 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 "config.h"

#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "oleauto.h"
#include "winerror.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

static IDispatch * StdDispatch_Construct(IUnknown * punkOuter, void * pvThis, ITypeInfo * pTypeInfo);

/******************************************************************************
 *		DispInvoke (OLEAUT32.30)
 *
 * Call an object method using the information from its type library.
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: Returns DISP_E_EXCEPTION and updates pexcepinfo if an exception occurs.
 *           DISP_E_BADPARAMCOUNT if the number of parameters is incorrect.
 *           DISP_E_MEMBERNOTFOUND if the method does not exist.
 *           puArgErr is updated if a parameter error (see notes) occurs.
 *           Otherwise, returns the result of calling ITypeInfo_Invoke().
 *
 * NOTES
 *  Parameter errors include the following:
 *| DISP_E_BADVARTYPE
 *| E_INVALIDARG            An argument was invalid
 *| DISP_E_TYPEMISMATCH,
 *| DISP_E_OVERFLOW         An argument was valid but could not be coerced
 *| DISP_E_PARAMNOTOPTIONAL A non optional parameter was not passed
 *| DISP_E_PARAMNOTFOUND    A parameter was passed that was not expected by the method
 *  This call defers to ITypeInfo_Invoke().
 */
HRESULT WINAPI DispInvoke(
	VOID       *_this,        /* [in] Object to call method on */
	ITypeInfo  *ptinfo,       /* [in] Object type info */
	DISPID      dispidMember, /* [in] DISPID of the member (e.g. from GetIDsOfNames()) */
	USHORT      wFlags,       /* [in] Kind of method call (DISPATCH_ flags from "oaidl.h") */
	DISPPARAMS *pparams,      /* [in] Array of method arguments */
	VARIANT    *pvarResult,   /* [out] Destination for the result of the call */
	EXCEPINFO  *pexcepinfo,   /* [out] Destination for exception information */
	UINT       *puArgErr)     /* [out] Destination for bad argument */
{
    TRACE("\n");

    return ITypeInfo_Invoke(ptinfo, _this, dispidMember, wFlags,
                            pparams, pvarResult, pexcepinfo, puArgErr);
}

/******************************************************************************
 *		DispGetIDsOfNames (OLEAUT32.29)
 *
 * Convert a set of parameter names to DISPIDs for DispInvoke().
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: An HRESULT error code.
 *
 * NOTES
 *  This call defers to ITypeInfo_GetIDsOfNames(). The ITypeInfo interface passed
 *  as ptinfo contains the information to map names to DISPIDs.
 */
HRESULT WINAPI DispGetIDsOfNames(
	ITypeInfo  *ptinfo,    /* [in] Object's type info */
	OLECHAR   **rgszNames, /* [in] Array of names to get DISPIDs for */
	UINT        cNames,    /* [in] Number of names in rgszNames */
	DISPID     *rgdispid)  /* [out] Destination for converted DISPIDs */
{
    return ITypeInfo_GetIDsOfNames(ptinfo, rgszNames, cNames, rgdispid);
}

/******************************************************************************
 *		DispGetParam (OLEAUT32.28)
 *
 * Retrieve a parameter from a DISPPARAMS structure and coerce it to the
 * specified variant type.
 *
 * NOTES
 *  Coercion is done using system (0) locale.
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_PARAMNOTFOUND, if position is invalid. or
 *           DISP_E_TYPEMISMATCH, if the coercion failed. puArgErr is
 *           set to the index of the argument in pdispparams.
 */
HRESULT WINAPI DispGetParam(
	DISPPARAMS *pdispparams, /* [in] Parameter list */
	UINT        position,    /* [in] Position of parameter to coerce in pdispparams */
	VARTYPE     vtTarg,      /* [in] Type of value to coerce to */
	VARIANT    *pvarResult,  /* [out] Destination for resulting variant */
	UINT       *puArgErr)    /* [out] Destination for error code */
{
    /* position is counted backwards */
    UINT pos;
    HRESULT hr;

    TRACE("position=%d, cArgs=%d, cNamedArgs=%d\n",
          position, pdispparams->cArgs, pdispparams->cNamedArgs);
    if (position < pdispparams->cArgs) {
      /* positional arg? */
      pos = pdispparams->cArgs - position - 1;
    } else {
      /* FIXME: is this how to handle named args? */
      for (pos=0; pos<pdispparams->cNamedArgs; pos++)
        if (pdispparams->rgdispidNamedArgs[pos] == position) break;

      if (pos==pdispparams->cNamedArgs)
        return DISP_E_PARAMNOTFOUND;
    }
    hr = VariantChangeType(pvarResult,
                           &pdispparams->rgvarg[pos],
                           0, vtTarg);
    if (hr == DISP_E_TYPEMISMATCH) *puArgErr = pos;
    return hr;
}

/******************************************************************************
 * CreateStdDispatch [OLEAUT32.32]
 *
 * Create and return a standard IDispatch object.
 *
 * RETURNS
 *  Success: S_OK. ppunkStdDisp contains the new object.
 *  Failure: An HRESULT error code.
 *
 * NOTES
 *  Outer unknown appears to be completely ignored.
 */
HRESULT WINAPI CreateStdDispatch(
        IUnknown* punkOuter,
        void* pvThis,
	ITypeInfo* ptinfo,
	IUnknown** ppunkStdDisp)
{
    TRACE("(%p, %p, %p, %p)\n", punkOuter, pvThis, ptinfo, ppunkStdDisp);

    *ppunkStdDisp = (LPUNKNOWN)StdDispatch_Construct(punkOuter, pvThis, ptinfo);
    if (!*ppunkStdDisp)
        return E_OUTOFMEMORY;
    return S_OK;
}


/******************************************************************************
 * IDispatch {OLEAUT32}
 *
 * NOTES
 *  The IDispatch interface provides a single interface to dispatch method calls,
 *  regardless of whether the object to be called is in or out of process,
 *  local or remote (e.g. being called over a network). This interface is late-bound
 *  (linked at run-time), as opposed to early-bound (linked at compile time).
 *
 *  The interface is used by objects that wish to called by scripting
 *  languages such as VBA, in order to minimise the amount of COM and C/C++
 *  knowledge required, or by objects that wish to live out of process from code
 *  that will call their methods.
 *
 *  Method, property and parameter names can be localised. The details required to
 *  map names to methods and parameters are collected in a type library, usually
 *  output by an IDL compiler using the objects IDL description. This information is
 *  accessible programmatically through the ITypeLib interface (for a type library),
 *  and the ITypeInfo interface (for an object within the type library). Type information
 *  can also be created at run-time using CreateDispTypeInfo().
 *
 * WRAPPERS
 *  Instead of using IDispatch directly, there are several wrapper functions available
 *  to simplify the process of calling an objects methods through IDispatch.
 *
 *  A standard implementation of an IDispatch object is created by calling
 *  CreateStdDispatch(). Numeric Id values for the parameters and methods (DISPIDs)
 *  of an object of interest are retrieved by calling DispGetIDsOfNames(). DispGetParam()
 *  retrieves information about a particular parameter. Finally the DispInvoke()
 *  function is responsible for actually calling methods on an object.
 *
 * METHODS
 */

typedef struct
{
    const IDispatchVtbl *lpVtbl;
    void * pvThis;
    ITypeInfo * pTypeInfo;
    LONG ref;
} StdDispatch;

/******************************************************************************
 * IDispatch_QueryInterface {OLEAUT32}
 *
 * See IUnknown_QueryInterface.
 */
static HRESULT WINAPI StdDispatch_QueryInterface(
  LPDISPATCH iface,
  REFIID riid,
  void** ppvObject)
{
    StdDispatch *This = (StdDispatch *)iface;
    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObject);

    if (IsEqualIID(riid, &IID_IDispatch) ||
        IsEqualIID(riid, &IID_IUnknown))
    {
        *ppvObject = This;
	IUnknown_AddRef((LPUNKNOWN)*ppvObject);
	return S_OK;
    }
    return E_NOINTERFACE;
}

/******************************************************************************
 * IDispatch_AddRef {OLEAUT32}
 *
 * See IUnknown_AddRef.
 */
static ULONG WINAPI StdDispatch_AddRef(LPDISPATCH iface)
{
    StdDispatch *This = (StdDispatch *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);

    return refCount;
}

/******************************************************************************
 * IDispatch_Release {OLEAUT32}
 *
 * See IUnknown_Release.
 */
static ULONG WINAPI StdDispatch_Release(LPDISPATCH iface)
{
    StdDispatch *This = (StdDispatch *)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(ref before=%u)\n", This, refCount + 1);

    if (!refCount)
    {
        ITypeInfo_Release(This->pTypeInfo);
        CoTaskMemFree(This);
    }

    return refCount;
}

/******************************************************************************
 * IDispatch_GetTypeInfoCount {OLEAUT32}
 *
 * Get the count of type information in an IDispatch interface.
 *
 * PARAMS
 *  iface   [I] IDispatch interface
 *  pctinfo [O] Destination for the count
 *
 * RETURNS
 *  Success: S_OK. pctinfo is updated with the count. This is always 1 if
 *           the object provides type information, and 0 if it does not.
 *  Failure: E_NOTIMPL. The object does not provide type information.
 *
 * NOTES
 *  See IDispatch() and IDispatch_GetTypeInfo().
 */
static HRESULT WINAPI StdDispatch_GetTypeInfoCount(LPDISPATCH iface, UINT * pctinfo)
{
    StdDispatch *This = (StdDispatch *)iface;
    TRACE("(%p)\n", pctinfo);

    *pctinfo = This->pTypeInfo ? 1 : 0;
    return S_OK;
}

/******************************************************************************
 * IDispatch_GetTypeInfo {OLEAUT32}
 *
 * Get type information from an IDispatch interface.
 *
 * PARAMS
 *  iface   [I] IDispatch interface
 *  iTInfo  [I] Index of type information.
 *  lcid    [I] Locale of the type information to get
 *  ppTInfo [O] Destination for the ITypeInfo object
 *
 * RETURNS
 *  Success: S_OK. ppTInfo is updated with the objects type information
 *  Failure: DISP_E_BADINDEX, if iTInfo is any value other than 0.
 *
 * NOTES
 *  See IDispatch.
 */
static HRESULT WINAPI StdDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
{
    StdDispatch *This = (StdDispatch *)iface;
    TRACE("(%d, %x, %p)\n", iTInfo, lcid, ppTInfo);

    *ppTInfo = NULL;
    if (iTInfo != 0)
        return DISP_E_BADINDEX;

    if (This->pTypeInfo)
    {
      *ppTInfo = This->pTypeInfo;
      ITypeInfo_AddRef(*ppTInfo);
    }
    return S_OK;
}

/******************************************************************************
 * IDispatch_GetIDsOfNames {OLEAUT32}
 *
 * Convert a methods name and an optional set of parameter names into DISPIDs
 * for passing to IDispatch_Invoke().
 *
 * PARAMS
 *  iface     [I] IDispatch interface
 *  riid      [I] Reserved, set to IID_NULL
 *  rgszNames [I] Name to convert
 *  cNames    [I] Number of names in rgszNames
 *  lcid      [I] Locale of the type information to convert from
 *  rgDispId  [O] Destination for converted DISPIDs.
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_UNKNOWNNAME, if any of the names is invalid.
 *           DISP_E_UNKNOWNLCID if lcid is invalid.
 *           Otherwise, an HRESULT error code.
 *
 * NOTES
 *  This call defers to ITypeInfo_GetIDsOfNames(), using the ITypeInfo object
 *  contained within the IDispatch object.
 *  The first member of the names list must be a method name. The names following
 *  the method name are the parameters for that method.
 */
static HRESULT WINAPI StdDispatch_GetIDsOfNames(LPDISPATCH iface, REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId)
{
    StdDispatch *This = (StdDispatch *)iface;
    TRACE("(%s, %p, %d, 0x%x, %p)\n", debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);

    if (!IsEqualGUID(riid, &IID_NULL))
    {
        FIXME(" expected riid == IID_NULL\n");
        return E_INVALIDARG;
    }
    return DispGetIDsOfNames(This->pTypeInfo, rgszNames, cNames, rgDispId);
}

/******************************************************************************
 * IDispatch_Invoke {OLEAUT32}
 *
 * Call an object method.
 *
 * PARAMS
 *  iface        [I] IDispatch interface
 *  dispIdMember [I] DISPID of the method (from GetIDsOfNames())
 *  riid         [I] Reserved, set to IID_NULL
 *  lcid         [I] Locale of the type information to convert parameters with
 *  wFlags,      [I] Kind of method call (DISPATCH_ flags from "oaidl.h")
 *  pDispParams  [I] Array of method arguments
 *  pVarResult   [O] Destination for the result of the call
 *  pExcepInfo   [O] Destination for exception information
 *  puArgErr     [O] Destination for bad argument
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: See DispInvoke() for failure cases.
 *
 * NOTES
 *  See DispInvoke() and IDispatch().
 */
static HRESULT WINAPI StdDispatch_Invoke(LPDISPATCH iface, DISPID dispIdMember, REFIID riid, LCID lcid,
                                         WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult,
                                         EXCEPINFO * pExcepInfo, UINT * puArgErr)
{
    StdDispatch *This = (StdDispatch *)iface;
    TRACE("(%d, %s, 0x%x, 0x%x, %p, %p, %p, %p)\n", dispIdMember, debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    if (!IsEqualGUID(riid, &IID_NULL))
    {
        FIXME(" expected riid == IID_NULL\n");
        return E_INVALIDARG;
    }
    return DispInvoke(This->pvThis, This->pTypeInfo, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
}

static const IDispatchVtbl StdDispatch_VTable =
{
  StdDispatch_QueryInterface,
  StdDispatch_AddRef,
  StdDispatch_Release,
  StdDispatch_GetTypeInfoCount,
  StdDispatch_GetTypeInfo,
  StdDispatch_GetIDsOfNames,
  StdDispatch_Invoke
};

static IDispatch * StdDispatch_Construct(
  IUnknown * punkOuter,
  void * pvThis,
  ITypeInfo * pTypeInfo)
{
    StdDispatch * pStdDispatch;

    pStdDispatch = CoTaskMemAlloc(sizeof(StdDispatch));
    if (!pStdDispatch)
        return (IDispatch *)pStdDispatch;

    pStdDispatch->lpVtbl = &StdDispatch_VTable;
    pStdDispatch->pvThis = pvThis;
    pStdDispatch->pTypeInfo = pTypeInfo;
    pStdDispatch->ref = 1;

    /* we keep a reference to the type info so prevent it from
     * being destroyed until we are done with it */
    ITypeInfo_AddRef(pTypeInfo);

    return (IDispatch *)pStdDispatch;
}
