/*
 * Implementation of IWebBrowser interface for IE Web Browser control
 *
 * 2001 John R. Sheets (for CodeWeavers)
 *
 * Copyright (c) 2003 TransGaming Technologies
 * david@transgaming.com
 */

#include "wine/debug.h"
#include "shdocvw.h"
#include "oleauto.h"
#include "wine/unicode.h"

#include "htmlguid.h"

WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);

/**********************************************************************
 * Implement the IWebBrowser interface
 */

static ICOM_VTABLE(IWebBrowser) WB_Vtbl;
static ICOM_VTABLE(IWebBrowser2) WB2_Vtbl;

extern ICOM_VTABLE(IViewObject) VOBJ_Vtbl;
extern ICOM_VTABLE(IViewObject2) VOBJ2_Vtbl;
extern ICOM_VTABLE(IOleObject) WBOOBJ_Vtbl;
extern ICOM_VTABLE(IOleInPlaceObject) WBOIPO_Vtbl;
extern ICOM_VTABLE(IOleControl) WBOC_Vtbl;
extern ICOM_VTABLE(IProvideClassInfo) WBPCI_Vtbl;
extern ICOM_VTABLE(IProvideClassInfo2) WBPCI2_Vtbl;
extern ICOM_VTABLE(IConnectionPointContainer) WBCPC_Vtbl;
extern ICOM_VTABLE(IQuickActivate) WBQA_Vtbl;
extern ICOM_VTABLE(IPersistStorage) WBPS_Vtbl;
extern ICOM_VTABLE(IPersistStreamInit) WBPSI_Vtbl;
extern ICOM_VTABLE(IRunnableObject) WBRUNOBJ_Vtbl;

static HRESULT WINAPI WB_QueryInterface(LPWEBBROWSER iface, REFIID riid, LPVOID *ppobj)
{
    ICOM_THIS(IWebBrowserImpl, iface);

    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppobj);
    if (IsEqualGUID(&IID_IUnknown, riid) ||
        IsEqualGUID(&IID_IDispatch, riid) ||
        IsEqualGUID(&IID_IWebBrowser, riid))
    {
        TRACE("IUnknown, IDispatch or IWebBrower\n");
        This->ref++;
        *ppobj = This;
        return S_OK;
    }
    /* actually, we may be able to get away with just having
     * the IWebBrowser2 vtbl - since everything in IWebBrowser
     * appears to be in IWebBrowser2
     */
    else if (IsEqualGUID(&IID_IWebBrowser2, riid))
    {
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl2;
        TRACE("IWebBrowser2\n");
        return S_OK;
    }
    else if (IsEqualGUID(&IID_IViewObject, riid))
    {
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl_VO;
        TRACE("IViewObject\n");
        return S_OK;
    }
    else if (IsEqualGUID(&IID_IViewObject2, riid))
    {
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl_VO2;
        TRACE("IViewObject2\n");
        return S_OK;
    }
    else if (IsEqualGUID(&IID_IOleObject, riid))
    {
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl_OOBJ;
        TRACE("IOleObject\n");
        return S_OK;
    }
    else if (IsEqualGUID(&IID_IOleInPlaceObject, riid))
    {
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl_OIPO;
        TRACE("IOleInPlaceObject\n");
        return S_OK;
    }
    else if (IsEqualGUID(&IID_IOleControl, riid))
    {
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl_OC;
        TRACE("IOleControl\n");
        return S_OK;
    }
    else if (IsEqualGUID(&IID_IProvideClassInfo, riid))
    {
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl_PCI;
        TRACE("IProvideClassInfo\n");
        return S_OK;
    }
    else if (IsEqualGUID(&IID_IProvideClassInfo2, riid))
    {
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl_PCI2;
        TRACE("IProvideClassInfo2\n");
        return S_OK;
    }
    else if (IsEqualGUID(&IID_IConnectionPointContainer, riid))
    {
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl_CPC;
        TRACE("IConnectionPointContainer\n");
        return S_OK;
    }
    else if (IsEqualGUID(&IID_IQuickActivate, riid))
    {
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl_QA;
        TRACE("IQuickActivate\n");
        return S_OK;
    }
    else if (IsEqualGUID(&IID_IPersistStorage, riid))
    {
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl_PS;
        TRACE("IPersistStorage\n");
        return S_OK;
    }
    else if (IsEqualGUID(&IID_IPersistStreamInit, riid))
    {
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl_PSI;
        TRACE("IPersistStreamInit\n");
        return S_OK;
    }
    else if (IsEqualGUID(&IID_IRunnableObject, riid))
    {
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl_RUNOBJ;
        TRACE("IRunnableObject\n");
        return S_OK;
    }
    else
    {
        FIXME("(%p)->(%s, %p): no interface\n", iface, debugstr_guid(riid), ppobj);
        return E_NOINTERFACE;
    }
}

static ULONG WINAPI WB_AddRef(LPWEBBROWSER iface)
{
    ICOM_THIS(IWebBrowserImpl, iface);
    TRACE("(%p)->()\n", iface);
    return ++(This->ref);
}

static ULONG WINAPI WB_Release(LPWEBBROWSER iface)
{
    ICOM_THIS(IWebBrowserImpl, iface);
    TRACE("(%p)->()\n", iface);
    if (--(This->ref)) return This->ref;

    HeapFree(GetProcessHeap(), 0, This);
    return 0;
}

/* IDispatch methods */
static HRESULT WINAPI WB_GetTypeInfoCount(LPWEBBROWSER iface, UINT *pctinfo)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_GetTypeInfo(LPWEBBROWSER iface, UINT iTInfo, LCID lcid,
                                     LPTYPEINFO *ppTInfo)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_GetIDsOfNames(LPWEBBROWSER iface, REFIID riid,
                                       LPOLESTR *rgszNames, UINT cNames,
                                       LCID lcid, DISPID *rgDispId)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_Invoke(LPWEBBROWSER iface, DISPID dispIdMember,
                                REFIID riid, LCID lcid, WORD wFlags,
                                DISPPARAMS *pDispParams, VARIANT *pVarResult,
                                EXCEPINFO *pExepInfo, UINT *puArgErr)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

/* IWebBrowser methods */
static HRESULT WINAPI WB_GoBack(LPWEBBROWSER iface)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_GoForward(LPWEBBROWSER iface)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_GoHome(LPWEBBROWSER iface)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_GoSearch(LPWEBBROWSER iface)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_Navigate(LPWEBBROWSER iface, BSTR URL,
                                  VARIANT *Flags, VARIANT *TargetFrameName,
                                  VARIANT *PostData, VARIANT *Headers)
{
    ICOM_THIS(IWebBrowserImpl, iface);
    TRACE("(%p)->(%s, %p, %p, %p, %p)\n", iface, debugstr_w(URL), Flags, TargetFrameName,
          PostData, Headers);
    return IWebBrowser2_Navigate((LPWEBBROWSER2)(&(This->lpVtbl2)), URL, Flags,
                                 TargetFrameName, PostData, Headers);
}

static HRESULT WINAPI WB_Refresh(LPWEBBROWSER iface)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_Refresh2(LPWEBBROWSER iface, VARIANT *Level)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_Stop(LPWEBBROWSER iface)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_get_Application(LPWEBBROWSER iface, LPVOID *ppDisp)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_get_Parent(LPWEBBROWSER iface, LPVOID *ppDisp)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_get_Container(LPWEBBROWSER iface, LPVOID *ppDisp)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_get_Document(LPWEBBROWSER iface, LPVOID *ppDisp)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_get_TopLevelContainer(LPWEBBROWSER iface, VARIANT *pBool)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_get_Type(LPWEBBROWSER iface, BSTR *Type)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_get_Left(LPWEBBROWSER iface, long *pl)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_put_Left(LPWEBBROWSER iface, long Left)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_get_Top(LPWEBBROWSER iface, long *pl)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_put_Top(LPWEBBROWSER iface, long Top)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_get_Width(LPWEBBROWSER iface, long *pl)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_put_Width(LPWEBBROWSER iface, long Width)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_get_Height(LPWEBBROWSER iface, long *pl)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_put_Height(LPWEBBROWSER iface, long Height)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_get_LocationName(LPWEBBROWSER iface, BSTR *LocationName)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB_get_LocationURL(LPWEBBROWSER iface, BSTR *LocationURL)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    *LocationURL = "\0\0\0\0";
    return S_OK;
}

static HRESULT WINAPI WB_get_Busy(LPWEBBROWSER iface, VARIANT *pBool)
{
    /*ICOM_THIS(IWebBrowserImpl, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

/* IWebBrowser2 */

static HRESULT WINAPI WB2_QueryInterface(LPWEBBROWSER2 iface, REFIID riid, LPVOID *ppobj)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);

    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppobj);
    return IWebBrowser_QueryInterface((LPWEBBROWSER) This, riid, ppobj);
}

static ULONG WINAPI WB2_AddRef(LPWEBBROWSER2 iface)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);
    TRACE("(%p)->()\n", iface);
    return IWebBrowser_AddRef((LPWEBBROWSER) This);
}

static ULONG WINAPI WB2_Release(LPWEBBROWSER2 iface)
{
    ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);
    TRACE("(%p)->()\n", iface);
    return IWebBrowser_Release((LPWEBBROWSER) This);
}

/* IDispatch methods */
static HRESULT WINAPI WB2_GetTypeInfoCount(LPWEBBROWSER2 iface, UINT *pctinfo)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_GetTypeInfo(LPWEBBROWSER2 iface, UINT iTInfo, LCID lcid,
                                     LPTYPEINFO *ppTInfo)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_GetIDsOfNames(LPWEBBROWSER2 iface, REFIID riid,
                                       LPOLESTR *rgszNames, UINT cNames,
                                       LCID lcid, DISPID *rgDispId)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_Invoke(LPWEBBROWSER2 iface, DISPID dispIdMember,
                                REFIID riid, LCID lcid, WORD wFlags,
                                DISPPARAMS *pDispParams, VARIANT *pVarResult,
                                EXCEPINFO *pExepInfo, UINT *puArgErr)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

/* IWebBrowser methods */
static HRESULT WINAPI WB2_GoBack(LPWEBBROWSER2 iface)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_GoForward(LPWEBBROWSER2 iface)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_GoHome(LPWEBBROWSER2 iface)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_GoSearch(LPWEBBROWSER2 iface)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_Navigate(LPWEBBROWSER2 iface, BSTR URL,
                                  VARIANT *Flags, VARIANT *TargetFrameName,
                                  VARIANT *PostData, VARIANT *Headers)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    VARIANT vURL;

    V_VT(&vURL) = VT_BSTR;
    V_BSTR(&vURL) = SysAllocStringLen(URL, SysStringLen(URL));
    return IWebBrowser2_Navigate2(iface, &vURL, Flags, TargetFrameName,
                                  PostData, Headers);
}

static HRESULT WINAPI WB2_Refresh(LPWEBBROWSER2 iface)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_Refresh2(LPWEBBROWSER2 iface, VARIANT *Level)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_Stop(LPWEBBROWSER2 iface)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Application(LPWEBBROWSER2 iface, LPVOID *ppDisp)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Parent(LPWEBBROWSER2 iface, LPVOID *ppDisp)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Container(LPWEBBROWSER2 iface, LPVOID *ppDisp)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Document(LPWEBBROWSER2 iface, LPVOID *ppDisp)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    HRESULT hr;
    FIXME("(%p)->(...): semi stub\n", iface);
    hr = CoCreateInstance(&CLSID_HTMLViewer, NULL, CLSCTX_INPROC_SERVER,
                          &IID_IDispatch, ppDisp);
    return hr;
}

static HRESULT WINAPI WB2_get_TopLevelContainer(LPWEBBROWSER2 iface, VARIANT *pBool)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Type(LPWEBBROWSER2 iface, BSTR *Type)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Left(LPWEBBROWSER2 iface, long *pl)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_Left(LPWEBBROWSER2 iface, long Left)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Top(LPWEBBROWSER2 iface, long *pl)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_Top(LPWEBBROWSER2 iface, long Top)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Width(LPWEBBROWSER2 iface, long *pl)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_Width(LPWEBBROWSER2 iface, long Width)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Height(LPWEBBROWSER2 iface, long *pl)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_Height(LPWEBBROWSER2 iface, long Height)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_LocationName(LPWEBBROWSER2 iface, BSTR *LocationName)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_LocationURL(LPWEBBROWSER2 iface, BSTR *LocationURL)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Busy(LPWEBBROWSER2 iface, VARIANT *pBool)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}


static HRESULT WINAPI WB2_Quit(LPWEBBROWSER2 iface)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_ClientToWindow(LPWEBBROWSER2 iface, int* pcx, int* pcy) 
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_PutProperty(LPWEBBROWSER2 iface, BSTR Property, VARIANT vtValue)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_GetProperty(LPWEBBROWSER2 iface, BSTR Property, VARIANT* pvtValue)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Name(LPWEBBROWSER2 iface, BSTR* Name)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_HWND (LPWEBBROWSER2 iface, long* pHWND) 
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_FullName (LPWEBBROWSER2 iface, BSTR* FullName)  
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Path (LPWEBBROWSER2 iface, BSTR*  Path)  
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Visible (LPWEBBROWSER2 iface, VARIANT_BOOL* pBool) 
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_Visible(LPWEBBROWSER2 iface, VARIANT_BOOL Value) 
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_StatusBar (LPWEBBROWSER2 iface, VARIANT_BOOL* pBool) 
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_StatusBar (LPWEBBROWSER2 iface, VARIANT_BOOL Value)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_StatusText (LPWEBBROWSER2 iface, BSTR* StatusText)  
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_StatusText (LPWEBBROWSER2 iface, BSTR StatusText)  
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_ToolBar (LPWEBBROWSER2 iface, int* Value)  
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_ToolBar (LPWEBBROWSER2 iface, int Value)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_MenuBar (LPWEBBROWSER2 iface, VARIANT_BOOL* Value)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_MenuBar (LPWEBBROWSER2 iface, VARIANT_BOOL Value)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_FullScreen (LPWEBBROWSER2 iface, VARIANT_BOOL*  pbFullScreen)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_FullScreen (LPWEBBROWSER2 iface, VARIANT_BOOL bFullScreen)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_Navigate2 (LPWEBBROWSER2 iface, VARIANT* URL, VARIANT* Flags,
                              VARIANT* TargetFrameName, VARIANT* PostData,
                              VARIANT* Headers)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(%p, %p, %p, %p, %p): stub\n", iface,
          URL, Flags, TargetFrameName, PostData, Headers);

    if (V_VT(URL) == VT_BSTR)
        FIXME("Program trying to display URL (you may wish to browse here): \n\t%s\n",
              debugstr_wn(V_BSTR(URL), strlenW(V_BSTR(URL))));
    return S_OK;
}

static HRESULT WINAPI WB2_QueryStatusWB(LPWEBBROWSER2 iface, OLECMDID cmdID, OLECMDF* pcmdf)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_ExecWB(LPWEBBROWSER2 iface, OLECMDID cmdID,
                          OLECMDEXECOPT cmdexecopt, VARIANT* pvaIn,
                          VARIANT* pvaOut)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_ShowBrowserBar(LPWEBBROWSER2 iface, VARIANT* pvaClsid,
                                  VARIANT* pvarShow, VARIANT* pvarSize)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_ReadyState( LPWEBBROWSER2 iface, READYSTATE* plReadyState)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Offline (LPWEBBROWSER2 iface, VARIANT_BOOL* pbOffline)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_Offline (LPWEBBROWSER2 iface, VARIANT_BOOL bOffline)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Silent (LPWEBBROWSER2 iface, VARIANT_BOOL* pbSilent)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_Silent (LPWEBBROWSER2 iface, VARIANT_BOOL bSilent)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_RegisterAsBrowser (LPWEBBROWSER2 iface,
                                          VARIANT_BOOL* pbRegister)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_RegisterAsBrowser (LPWEBBROWSER2 iface,
                                          VARIANT_BOOL bRegister)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_RegisterAsDropTarget (LPWEBBROWSER2 iface,
                                             VARIANT_BOOL* pbRegister)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_RegisterAsDropTarget (LPWEBBROWSER2 iface,
                                             VARIANT_BOOL bRegister)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_TheaterMode (LPWEBBROWSER2 iface,
                                    VARIANT_BOOL* pbRegister)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_TheaterMode (LPWEBBROWSER2 iface,
                                    VARIANT_BOOL bRegister)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_AddressBar (LPWEBBROWSER2 iface,
                                   VARIANT_BOOL* Value)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_AddressBar (LPWEBBROWSER2 iface,
                                   VARIANT_BOOL Value)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_get_Resizable (LPWEBBROWSER2 iface,
                                  VARIANT_BOOL* Value)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI WB2_put_Resizable (LPWEBBROWSER2 iface,
                                  VARIANT_BOOL Value)
{
    /*ICOM_THIS_MULTI(IWebBrowserImpl, lpVtbl2, iface);*/
    FIXME("(%p)->(...): stub\n", iface);
    return S_OK;
}

HRESULT SHDOCVW_CreateWebBrowser(IUnknown *pOuter, REFIID riid, LPVOID *ppobj)
{
    IWebBrowserImpl *ipWB;
    HRESULT hr;
    TRACE("()\n");

    ipWB = (IWebBrowserImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                                        sizeof(IWebBrowserImpl));
    if (ipWB == NULL) return E_OUTOFMEMORY;
    ICOM_VTBL(ipWB) = &WB_Vtbl;
    ipWB->lpVtbl2 = &WB2_Vtbl;
    ipWB->lpVtbl_VO = &VOBJ_Vtbl;
    ipWB->lpVtbl_VO2 = &VOBJ2_Vtbl;
    ipWB->lpVtbl_OOBJ = &WBOOBJ_Vtbl;
    ipWB->lpVtbl_OIPO = &WBOIPO_Vtbl;
    ipWB->lpVtbl_OC = &WBOC_Vtbl;
    ipWB->lpVtbl_PCI = &WBPCI_Vtbl;
    ipWB->lpVtbl_PCI2 = &WBPCI2_Vtbl;
    ipWB->lpVtbl_CPC = &WBCPC_Vtbl;
    ipWB->lpVtbl_QA = &WBQA_Vtbl;
    ipWB->lpVtbl_PS = &WBPS_Vtbl;
    ipWB->lpVtbl_PSI = &WBPSI_Vtbl;
    ipWB->lpVtbl_RUNOBJ = &WBRUNOBJ_Vtbl;

    IWebBrowser_AddRef((IWebBrowser *)ipWB);
    hr = IWebBrowser_QueryInterface((IWebBrowser *)ipWB, riid, ppobj);
    IWebBrowser_Release((IWebBrowser *)ipWB);

    if (SUCCEEDED(hr))
        return S_OK;
    else
        return E_NOINTERFACE;
}

/**********************************************************************
 * IWebBrowser virtual function table for IE Web Browser component
 */

static ICOM_VTABLE(IWebBrowser) WB_Vtbl =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    WB_QueryInterface,
    WB_AddRef,
    WB_Release,
    WB_GetTypeInfoCount,
    WB_GetTypeInfo,
    WB_GetIDsOfNames,
    WB_Invoke,
    WB_GoBack,
    WB_GoForward,
    WB_GoHome,
    WB_GoSearch,
    WB_Navigate,
    WB_Refresh,
    WB_Refresh2,
    WB_Stop,
    WB_get_Application,
    WB_get_Parent,
    WB_get_Container,
    WB_get_Document,
    WB_get_TopLevelContainer,
    WB_get_Type,
    WB_get_Left,
    WB_put_Left,
    WB_get_Top,
    WB_put_Top,
    WB_get_Width,
    WB_put_Width,
    WB_get_Height,
    WB_put_Height,
    WB_get_LocationName,
    WB_get_LocationURL,
    WB_get_Busy
};

/**********************************************************************
 * IWebBrowser2 virtual function table for IE Web Browser component
 */

static ICOM_VTABLE(IWebBrowser2) WB2_Vtbl =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    WB2_QueryInterface,
    WB2_AddRef,
    WB2_Release,
    WB2_GetTypeInfoCount,
    WB2_GetTypeInfo,
    WB2_GetIDsOfNames,
    WB2_Invoke,
    WB2_GoBack,
    WB2_GoForward,
    WB2_GoHome,
    WB2_GoSearch,
    WB2_Navigate,
    WB2_Refresh,
    WB2_Refresh2,
    WB2_Stop,
    WB2_get_Application,
    WB2_get_Parent,
    WB2_get_Container,
    WB2_get_Document,
    WB2_get_TopLevelContainer,
    WB2_get_Type,
    WB2_get_Left,
    WB2_put_Left,
    WB2_get_Top,
    WB2_put_Top,
    WB2_get_Width,
    WB2_put_Width,
    WB2_get_Height,
    WB2_put_Height,
    WB2_get_LocationName,
    WB2_get_LocationURL,
    WB2_get_Busy,
    WB2_Quit,
    WB2_ClientToWindow,
    WB2_PutProperty,
    WB2_GetProperty,
    WB2_get_Name,
    WB2_get_HWND,
    WB2_get_FullName,
    WB2_get_Path,
    WB2_get_Visible,
    WB2_put_Visible,
    WB2_get_StatusBar,
    WB2_put_StatusBar,
    WB2_get_StatusText,
    WB2_put_StatusText,
    WB2_get_ToolBar,
    WB2_put_ToolBar,
    WB2_get_MenuBar,
    WB2_put_MenuBar,
    WB2_get_FullScreen,
    WB2_put_FullScreen,
    WB2_Navigate2,
    WB2_QueryStatusWB,
    WB2_ExecWB,
    WB2_ShowBrowserBar,
    WB2_get_ReadyState,
    WB2_get_Offline,
    WB2_put_Offline,
    WB2_get_Silent,
    WB2_put_Silent,
    WB2_get_RegisterAsBrowser,
    WB2_put_RegisterAsBrowser,
    WB2_get_RegisterAsDropTarget,
    WB2_put_RegisterAsDropTarget,
    WB2_get_TheaterMode,
    WB2_put_TheaterMode,
    WB2_get_AddressBar,
    WB2_put_AddressBar,
    WB2_get_Resizable,
    WB2_put_Resizable
};

