/**
 * 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
 *
 * TODO: Type coercion is implemented in variant.c but not called yet.
 */

#include "config.h"

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

#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 */
{
    /**
     * TODO:
     * For each param, call DispGetParam to perform type coercion
     */
    FIXME("Coercion of arguments not implemented\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;
}

/******************************************************************************
 * CreateDispTypeInfo [OLEAUT32.31]
 *
 * Build type information for an object so it can be called through an
 * IDispatch interface.
 *
 * RETURNS
 *  Success: S_OK. pptinfo contains the created ITypeInfo object.
 *  Failure: E_INVALIDARG, if one or more arguments is invalid.
 *
 * NOTES
 *  This call allows an objects methods to be accessed through IDispatch, by
 *  building an ITypeInfo object that IDispatch can use to call through.
 */
HRESULT WINAPI CreateDispTypeInfo(
	INTERFACEDATA *pidata, /* [I] Description of the interface to build type info for */
	LCID lcid, /* [I] Locale Id */
	ITypeInfo **pptinfo) /* [O] Destination for created ITypeInfo object */
{
	FIXME("(%p,%ld,%p),stub\n",pidata,lcid,pptinfo);
	return 0;
}

/******************************************************************************
 * 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
{
    ICOM_VFIELD(IDispatch);
    void * pvThis;
    ITypeInfo * pTypeInfo;
    ULONG ref;
} StdDispatch;

/******************************************************************************
 * IDispatch_QueryInterface {OLEAUT32}
 *
 * See IUnknown_QueryInterface.
 */
static HRESULT WINAPI StdDispatch_QueryInterface(
  LPDISPATCH iface,
  REFIID riid,
  void** ppvObject)
{
    ICOM_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)
{
    ICOM_THIS(StdDispatch, iface);
    TRACE("()\n");

    return ++This->ref;
}

/******************************************************************************
 * IDispatch_Release {OLEAUT32}
 *
 * See IUnknown_Release.
 */
static ULONG WINAPI StdDispatch_Release(LPDISPATCH iface)
{
    ICOM_THIS(StdDispatch, iface);
    ULONG ret;
    TRACE("(%p)->()\n", This);

    ret = This->ref--;

    if (This->ref == 0)
    {
        ITypeInfo_Release(This->pTypeInfo);
        CoTaskMemFree(This);
    }

    return ret;
}

/******************************************************************************
 * 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)
{
    ICOM_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)
{
    ICOM_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)
{
    ICOM_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)
{
    ICOM_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 ICOM_VTABLE(IDispatch) StdDispatch_VTable =
{
  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
  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;
}
