/**
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 "winreg.h"
#include "winnls.h"         /* for PRIMARYLANGID */

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);
WINE_DECLARE_DEBUG_CHANNEL(typelib);

static IDispatch * WINAPI 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 DISPID's 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 DISPID's.
 */
HRESULT WINAPI DispGetIDsOfNames(
	ITypeInfo  *ptinfo,    /* [in] Object's type info */
	OLECHAR   **rgszNames, /* [in] Array of names to get DISPID's for */
	UINT        cNames,    /* [in] Number of names in rgszNames */
	DISPID     *rgdispid)  /* [out] Destination for converted DISPID's */
{
    return ITypeInfo_GetIDsOfNames(ptinfo, rgszNames, cNames, rgdispid);
}

/******************************************************************************
 *		DispGetParam (OLEAUT32.28)
 *
 * Retrive 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 programatically 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 (DISPID's)
 *  of an object of interest are retrieved by calling DispGetIDsOfNames(). DispGetParam()
 *  retrieves information about a particular parameter. Finally the DispInvoke()
 *  function is responsable 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 = (LPVOID)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=%lu)\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=%lu)\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, %lx, %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 DISPID's
 * 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 DISPID's.
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_UNKNOWNNAME, if any of the names is invalid.
 *           DISP_E_UNKNOWNLCID if lcid is invalid.
 *           Otherwise, an 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%lx, %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("(%ld, %s, 0x%lx, 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 * WINAPI 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;
}
