/*
 * Implement for HTML Document object's interfaces:
 *   IHTMLDocument
 *
 * Copyright (c) 2004 TransGaming Technologies
 */

#include "winbase.h"
#include "winuser.h"
#include "wingdi.h"

#include "oleauto.h"
#include "htmlguid.h"
#include "mshtml.h"

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

#include "mshtml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

static ICOM_VTABLE(IDispatch) mshtmlDispatchVT;
static ICOM_VTABLE(IHTMLDocument) mshtmlHTMLDocumentVT;
static ICOM_VTABLE(IHTMLDocument2) mshtmlHTMLDocument2VT;

/* IDispatch */

static HRESULT WINAPI html_Dispatch_QueryInterface(LPDISPATCH iface, REFIID riid,
                                                   LPVOID *ppobj)
{
    ICOM_THIS(HTMLDocumentImpl, iface);

    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppobj);

    if (IsEqualGUID(&IID_IUnknown, riid) ||
        IsEqualGUID(&IID_IDispatch, riid))
    {
        TRACE("IUnknown or IDispatch\n");
        This->ref++;
        *ppobj = This;
        return S_OK;
    }
    else if (IsEqualGUID(&IID_IHTMLDocument, riid))
    {
        TRACE("IHTMLDocument\n");
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl_HTMLDocument;
        return S_OK;
    }
    else if (IsEqualGUID(&IID_IHTMLDocument2, riid))
    {
        TRACE("IHTMLDocument2\n");
        This->ref++;
        *ppobj = (LPVOID *)&This->lpVtbl_HTMLDocument2;
        return S_OK;
    }
    else
    {
        FIXME("(%p)->(%s, %p): no interface\n", iface, debugstr_guid(riid), ppobj);
        return E_NOINTERFACE;
    }
}

static ULONG WINAPI html_Dispatch_AddRef(LPDISPATCH iface)
{
    ICOM_THIS(HTMLDocumentImpl, iface);
    TRACE("(%p)->()\n", iface);
    return ++(This->ref);
}

static ULONG WINAPI html_Dispatch_Release(LPDISPATCH iface)
{
    ICOM_THIS(HTMLDocumentImpl, iface);
    TRACE("(%p)->()\n", iface);

    if (--(This->ref)) return This->ref;

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

/* IHTMLDocument */

static HRESULT WINAPI html_HTMLDocument_QueryInterface(LPHTMLDOCUMENT iface,
                                                       REFIID riid, LPVOID *ppobj)
{
    ICOM_THIS_MULTI(HTMLDocumentImpl, lpVtbl_HTMLDocument, iface);
    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppobj);
    return IDispatch_QueryInterface((LPDISPATCH)This, riid, ppobj);
}

static ULONG WINAPI html_HTMLDocument_AddRef(LPHTMLDOCUMENT iface)
{
    ICOM_THIS_MULTI(HTMLDocumentImpl, lpVtbl_HTMLDocument, iface);
    TRACE("(%p)\n", iface);
    return IDispatch_AddRef((LPDISPATCH)This);
}

static ULONG WINAPI html_HTMLDocument_Release(LPHTMLDOCUMENT iface)
{
    ICOM_THIS_MULTI(HTMLDocumentImpl, lpVtbl_HTMLDocument, iface);
    TRACE("(%p)\n", iface);
    return IDispatch_Release((LPDISPATCH)This);
}

static HRESULT CALLBACK html_HTMLDocument_get_Script(
    LPHTMLDOCUMENT This,
    IDispatch** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

/* IHTMLDocument2 */

static HRESULT WINAPI html_HTMLDocument2_QueryInterface(LPHTMLDOCUMENT2 iface,
                                                        REFIID riid, LPVOID *ppobj)
{
    ICOM_THIS_MULTI(HTMLDocumentImpl, lpVtbl_HTMLDocument2, iface);
    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppobj);
    return IDispatch_QueryInterface((LPDISPATCH)This, riid, ppobj);
}

static ULONG WINAPI html_HTMLDocument2_AddRef(LPHTMLDOCUMENT2 iface)
{
    ICOM_THIS_MULTI(HTMLDocumentImpl, lpVtbl_HTMLDocument2, iface);
    TRACE("(%p)\n", iface);
    return IDispatch_AddRef((LPDISPATCH)This);
}

static ULONG WINAPI html_HTMLDocument2_Release(LPHTMLDOCUMENT2 iface)
{
    ICOM_THIS_MULTI(HTMLDocumentImpl, lpVtbl_HTMLDocument2, iface);
    TRACE("(%p)\n", iface);
    return IDispatch_Release((LPDISPATCH)This);
}

static HRESULT CALLBACK html_HTMLDocument2_get_Script(
    LPHTMLDOCUMENT2 This,
    IDispatch** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_all(
    LPHTMLDOCUMENT2 This,
    IHTMLElementCollection** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_body(
    LPHTMLDOCUMENT2 This,
    IHTMLElement** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_activeElement(
    LPHTMLDOCUMENT2 This,
    IHTMLElement** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_images(
    LPHTMLDOCUMENT2 This,
    IHTMLElementCollection** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_applets(
    LPHTMLDOCUMENT2 This,
    IHTMLElementCollection** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_links(
    LPHTMLDOCUMENT2 This,
    IHTMLElementCollection** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_forms(
    LPHTMLDOCUMENT2 This,
    IHTMLElementCollection** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_anchors(
    LPHTMLDOCUMENT2 This,
    IHTMLElementCollection** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_title(
    LPHTMLDOCUMENT2 This,
    BSTR v)
{
    FIXME("(%p)->(%p):stub\n", This,
        v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_title(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_scripts(
    LPHTMLDOCUMENT2 This,
    IHTMLElementCollection** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_designMode(
    LPHTMLDOCUMENT2 This,
    BSTR v)
{
    FIXME("(%p)->(%p):stub\n", This,
        v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_designMode(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_selection(
    LPHTMLDOCUMENT2 This,
    IHTMLSelectionObject** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_readyState(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_frames(
    LPHTMLDOCUMENT2 This,
    IHTMLFramesCollection2** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_embeds(
    LPHTMLDOCUMENT2 This,
    IHTMLElementCollection** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_plugins(
    LPHTMLDOCUMENT2 This,
    IHTMLElementCollection** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_alinkColor(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_alinkColor(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_bgColor(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_bgColor(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_fgColor(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_fgColor(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_linkColor(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_linkColor(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_vlinkColor(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_vlinkColor(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_referrer(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_location(
    LPHTMLDOCUMENT2 This,
    IHTMLLocation** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_lastModified(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_URL(
    LPHTMLDOCUMENT2 This,
    BSTR v)
{
    FIXME("(%p)->(%p):stub\n", This,
        v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_URL(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_domain(
    LPHTMLDOCUMENT2 This,
    BSTR v)
{
    FIXME("(%p)->(%p):stub\n", This,
        v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_domain(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_cookie(
    LPHTMLDOCUMENT2 This,
    BSTR v)
{
    FIXME("(%p)->(%p):stub\n", This,
        v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_cookie(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_expando(
    LPHTMLDOCUMENT2 This,
    VARIANT_BOOL v)
{
    FIXME("(%p)->(%d):stub\n", This,
        v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_expando(
    LPHTMLDOCUMENT2 This,
    VARIANT_BOOL* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = 0;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_charset(
    LPHTMLDOCUMENT2 This,
    BSTR v)
{
    FIXME("(%p)->(%p):stub\n", This,
        v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_charset(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_defaultCharset(
    LPHTMLDOCUMENT2 This,
    BSTR v)
{
    FIXME("(%p)->(%p):stub\n", This,
        v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_defaultCharset(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_mimeType(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_fileSize(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_fileCreatedDate(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_fileModifiedDate(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_fileUpdatedDate(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_security(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_protocol(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_nameProp(
    LPHTMLDOCUMENT2 This,
    BSTR* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_write(
    LPHTMLDOCUMENT2 This,
    SAFEARRAY* psarray)
{
    FIXME("(%p)->(%p):stub\n", This,
        psarray);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_writeln(
    LPHTMLDOCUMENT2 This,
    SAFEARRAY* psarray)
{
    FIXME("(%p)->(%p):stub\n", This,
        psarray);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_open(
    LPHTMLDOCUMENT2 This,
    BSTR url,
    VARIANT name,
    VARIANT features,
    VARIANT replace,
    IDispatch** pomWindowResult)
{
    FIXME("(%p)->(%p,%p,%p,%p,%p):stub\n", This,
        url,
        &name,
        &features,
        &replace,
        pomWindowResult);
    *pomWindowResult = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_close(
    LPHTMLDOCUMENT2 This)
{
    FIXME("(%p)->():stub\n", This);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_clear(
    LPHTMLDOCUMENT2 This)
{
    FIXME("(%p)->():stub\n", This);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_queryCommandSupported(
    LPHTMLDOCUMENT2 This,
    BSTR cmdID,
    VARIANT_BOOL* pfRet)
{
    FIXME("(%p)->(%p,%p):stub\n", This,
        cmdID,
        pfRet);
    *pfRet = 0;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_queryCommandEnabled(
    LPHTMLDOCUMENT2 This,
    BSTR cmdID,
    VARIANT_BOOL* pfRet)
{
    FIXME("(%p)->(%p,%p):stub\n", This,
        cmdID,
        pfRet);
    *pfRet = 0;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_queryCommandState(
    LPHTMLDOCUMENT2 This,
    BSTR cmdID,
    VARIANT_BOOL* pfRet)
{
    FIXME("(%p)->(%p,%p):stub\n", This,
        cmdID,
        pfRet);
    *pfRet = 0;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_queryCommandIndeterm(
    LPHTMLDOCUMENT2 This,
    BSTR cmdID,
    VARIANT_BOOL* pfRet)
{
    FIXME("(%p)->(%p,%p):stub\n", This,
        cmdID,
        pfRet);
    *pfRet = 0;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_queryCommandText(
    LPHTMLDOCUMENT2 This,
    BSTR cmdID,
    BSTR* pcmdText)
{
    FIXME("(%p)->(%p,%p):stub\n", This,
        cmdID,
        pcmdText);
    *pcmdText = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_queryCommandValue(
    LPHTMLDOCUMENT2 This,
    BSTR cmdID,
    VARIANT* pcmdValue)
{
    FIXME("(%p)->(%p,%p):stub\n", This,
        cmdID,
        pcmdValue);
    VariantInit(pcmdValue);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_execCommand(
    LPHTMLDOCUMENT2 This,
    BSTR cmdID,
    VARIANT_BOOL showUI,
    VARIANT value,
    VARIANT_BOOL* pfRet)
{
    FIXME("(%p)->(%p,%d,%p,%p):stub\n", This,
        cmdID,
        showUI,
        &value,
        pfRet);
    *pfRet = 0;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_execCommandShowHelp(
    LPHTMLDOCUMENT2 This,
    BSTR cmdID,
    VARIANT_BOOL* pfRet)
{
    FIXME("(%p)->(%p,%p):stub\n", This,
        cmdID,
        pfRet);
    *pfRet = 0;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_createElement(
    LPHTMLDOCUMENT2 This,
    BSTR eTag,
    IHTMLElement** newElem)
{
    FIXME("(%p)->(%p,%p):stub\n", This,
        eTag,
        newElem);
    *newElem = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onhelp(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onhelp(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onclick(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onclick(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_ondblclick(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_ondblclick(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onkeyup(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onkeyup(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onkeydown(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onkeydown(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onkeypress(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onkeypress(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onmouseup(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onmouseup(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onmousedown(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onmousedown(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onmousemove(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onmousemove(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onmouseout(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onmouseout(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onmouseover(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onmouseover(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onreadystatechange(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onreadystatechange(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onafterupdate(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onafterupdate(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onrowexit(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onrowexit(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onrowenter(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onrowenter(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_ondragstart(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_ondragstart(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onselectstart(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onselectstart(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_elementFromPoint(
    LPHTMLDOCUMENT2 This,
    long x,
    long y,
    IHTMLElement** elementHit)
{
    FIXME("(%p)->(%ld,%ld,%p):stub\n", This,
        x,
        y,
        elementHit);
    *elementHit = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_parentWindow(
    LPHTMLDOCUMENT2 This,
    IHTMLWindow2** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_styleSheets(
    LPHTMLDOCUMENT2 This,
    IHTMLStyleSheetsCollection** p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    *p = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onbeforeupdate(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onbeforeupdate(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_put_onerrorupdate(
    LPHTMLDOCUMENT2 This,
    VARIANT v)
{
    FIXME("(%p)->(%p):stub\n", This,
        &v);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_get_onerrorupdate(
    LPHTMLDOCUMENT2 This,
    VARIANT* p)
{
    FIXME("(%p)->(%p):stub\n", This,
        p);
    VariantInit(p);
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_toString(
    LPHTMLDOCUMENT2 This,
    BSTR* String)
{
    FIXME("(%p)->(%p):stub\n", This,
        String);
    *String = NULL;
    return S_OK;
}

static HRESULT CALLBACK html_HTMLDocument2_createStyleSheet(
    LPHTMLDOCUMENT2 This,
    BSTR bstrHref,
    long lIndex,
    IHTMLStyleSheet** ppnewStyleSheet)
{
    FIXME("(%p)->(%p,%ld,%p):stub\n", This,
        bstrHref,
        lIndex,
        ppnewStyleSheet);
    *ppnewStyleSheet = NULL;
    return S_OK;
}

/* other stuff */

HRESULT html_CreateDocument(IUnknown *pOuter, REFIID riid, LPVOID *ppobj)
{
    HTMLDocumentImpl *document;
    HRESULT hr;

    TRACE("()\n");

    document = (HTMLDocumentImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                                            sizeof(HTMLDocumentImpl));
    if (document == NULL) return E_OUTOFMEMORY;

    ICOM_VTBL(document) = &mshtmlDispatchVT;
    document->lpVtbl_HTMLDocument = &mshtmlHTMLDocumentVT;
    document->lpVtbl_HTMLDocument2 = &mshtmlHTMLDocument2VT;

    IDispatch_AddRef((LPDISPATCH)document);
    hr = IDispatch_QueryInterface((LPDISPATCH)document, riid, ppobj);
    IDispatch_Release((LPDISPATCH)document);

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

static ICOM_VTABLE(IDispatch) mshtmlDispatchVT =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    /* IUnknown */
    html_Dispatch_QueryInterface,
    html_Dispatch_AddRef,
    html_Dispatch_Release,
    /* IDispatch */
    0xdeada000, /* GetTypeInfoCount */
    0xdeada001, /* GetTypeInfo */
    0xdeada002, /* GetIDsOfName */
    0xdeada003, /* Invoke */
};

static ICOM_VTABLE(IHTMLDocument) mshtmlHTMLDocumentVT =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    /* IUnknown */
    html_HTMLDocument_QueryInterface,
    html_HTMLDocument_AddRef,
    html_HTMLDocument_Release,
    /* IDispatch */
    0xdeada100, /* GetTypeInfoCount */
    0xdeada101, /* GetTypeInfo */
    0xdeada102, /* GetIDsOfName */
    0xdeada103, /* Invoke */
    /* IHTMLDocument */
    html_HTMLDocument_get_Script
};

static ICOM_VTABLE(IHTMLDocument2) mshtmlHTMLDocument2VT =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    /* IUnknown */
    html_HTMLDocument2_QueryInterface,
    html_HTMLDocument2_AddRef,
    html_HTMLDocument2_Release,
    /* IDispatch */
    0xdeada200, /* GetTypeInfoCount */
    0xdeada201, /* GetTypeInfo */
    0xdeada202, /* GetIDsOfName */
    0xdeada203, /* Invoke */
    /* IHTMLDocument */
    html_HTMLDocument2_get_Script,
    /* IHTMLDocument2 */
    html_HTMLDocument2_get_all,
    html_HTMLDocument2_get_body,
    html_HTMLDocument2_get_activeElement,
    html_HTMLDocument2_get_images,
    html_HTMLDocument2_get_applets,
    html_HTMLDocument2_get_links,
    html_HTMLDocument2_get_forms,
    html_HTMLDocument2_get_anchors,
    html_HTMLDocument2_put_title,
    html_HTMLDocument2_get_title,
    html_HTMLDocument2_get_scripts,
    html_HTMLDocument2_put_designMode,
    html_HTMLDocument2_get_designMode,
    html_HTMLDocument2_get_selection,
    html_HTMLDocument2_get_readyState,
    html_HTMLDocument2_get_frames,
    html_HTMLDocument2_get_embeds,
    html_HTMLDocument2_get_plugins,
    html_HTMLDocument2_put_alinkColor,
    html_HTMLDocument2_get_alinkColor,
    html_HTMLDocument2_put_bgColor,
    html_HTMLDocument2_get_bgColor,
    html_HTMLDocument2_put_fgColor,
    html_HTMLDocument2_get_fgColor,
    html_HTMLDocument2_put_linkColor,
    html_HTMLDocument2_get_linkColor,
    html_HTMLDocument2_put_vlinkColor,
    html_HTMLDocument2_get_vlinkColor,
    html_HTMLDocument2_get_referrer,
    html_HTMLDocument2_get_location,
    html_HTMLDocument2_get_lastModified,
    html_HTMLDocument2_put_URL,
    html_HTMLDocument2_get_URL,
    html_HTMLDocument2_put_domain,
    html_HTMLDocument2_get_domain,
    html_HTMLDocument2_put_cookie,
    html_HTMLDocument2_get_cookie,
    html_HTMLDocument2_put_expando,
    html_HTMLDocument2_get_expando,
    html_HTMLDocument2_put_charset,
    html_HTMLDocument2_get_charset,
    html_HTMLDocument2_put_defaultCharset,
    html_HTMLDocument2_get_defaultCharset,
    html_HTMLDocument2_get_mimeType,
    html_HTMLDocument2_get_fileSize,
    html_HTMLDocument2_get_fileCreatedDate,
    html_HTMLDocument2_get_fileModifiedDate,
    html_HTMLDocument2_get_fileUpdatedDate,
    html_HTMLDocument2_get_security,
    html_HTMLDocument2_get_protocol,
    html_HTMLDocument2_get_nameProp,
    html_HTMLDocument2_write,
    html_HTMLDocument2_writeln,
    html_HTMLDocument2_open,
    html_HTMLDocument2_close,
    html_HTMLDocument2_clear,
    html_HTMLDocument2_queryCommandSupported,
    html_HTMLDocument2_queryCommandEnabled,
    html_HTMLDocument2_queryCommandState,
    html_HTMLDocument2_queryCommandIndeterm,
    html_HTMLDocument2_queryCommandText,
    html_HTMLDocument2_queryCommandValue,
    html_HTMLDocument2_execCommand,
    html_HTMLDocument2_execCommandShowHelp,
    html_HTMLDocument2_createElement,
    html_HTMLDocument2_put_onhelp,
    html_HTMLDocument2_get_onhelp,
    html_HTMLDocument2_put_onclick,
    html_HTMLDocument2_get_onclick,
    html_HTMLDocument2_put_ondblclick,
    html_HTMLDocument2_get_ondblclick,
    html_HTMLDocument2_put_onkeyup,
    html_HTMLDocument2_get_onkeyup,
    html_HTMLDocument2_put_onkeydown,
    html_HTMLDocument2_get_onkeydown,
    html_HTMLDocument2_put_onkeypress,
    html_HTMLDocument2_get_onkeypress,
    html_HTMLDocument2_put_onmouseup,
    html_HTMLDocument2_get_onmouseup,
    html_HTMLDocument2_put_onmousedown,
    html_HTMLDocument2_get_onmousedown,
    html_HTMLDocument2_put_onmousemove,
    html_HTMLDocument2_get_onmousemove,
    html_HTMLDocument2_put_onmouseout,
    html_HTMLDocument2_get_onmouseout,
    html_HTMLDocument2_put_onmouseover,
    html_HTMLDocument2_get_onmouseover,
    html_HTMLDocument2_put_onreadystatechange,
    html_HTMLDocument2_get_onreadystatechange,
    html_HTMLDocument2_put_onafterupdate,
    html_HTMLDocument2_get_onafterupdate,
    html_HTMLDocument2_put_onrowexit,
    html_HTMLDocument2_get_onrowexit,
    html_HTMLDocument2_put_onrowenter,
    html_HTMLDocument2_get_onrowenter,
    html_HTMLDocument2_put_ondragstart,
    html_HTMLDocument2_get_ondragstart,
    html_HTMLDocument2_put_onselectstart,
    html_HTMLDocument2_get_onselectstart,
    html_HTMLDocument2_elementFromPoint,
    html_HTMLDocument2_get_parentWindow,
    html_HTMLDocument2_get_styleSheets,
    html_HTMLDocument2_put_onbeforeupdate,
    html_HTMLDocument2_get_onbeforeupdate,
    html_HTMLDocument2_put_onerrorupdate,
    html_HTMLDocument2_get_onerrorupdate,
    html_HTMLDocument2_toString,
    html_HTMLDocument2_createStyleSheet
};
