/*
 * Copyright 2006 Jacek Caban for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>
#include <stdio.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"

#include "wine/debug.h"

#include "mshtml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

typedef struct {
    HTMLTextContainer textcont;

    const IHTMLBodyElementVtbl *lpHTMLBodyElementVtbl;

    ConnectionPoint cp_propnotif;

    nsIDOMHTMLBodyElement *nsbody;
} HTMLBodyElement;

#define HTMLBODY(x)  (&(x)->lpHTMLBodyElementVtbl)

static const WCHAR aquaW[] = {'a','q','u','a',0};
static const WCHAR blackW[] = {'b','l','a','c','k',0};
static const WCHAR blueW[] = {'b','l','u','e',0};
static const WCHAR fuchsiaW[] = {'f','u','s','h','s','i','a',0};
static const WCHAR grayW[] = {'g','r','a','y',0};
static const WCHAR greenW[] = {'g','r','e','e','n',0};
static const WCHAR limeW[] = {'l','i','m','e',0};
static const WCHAR maroonW[] = {'m','a','r','o','o','n',0};
static const WCHAR navyW[] = {'n','a','v','y',0};
static const WCHAR oliveW[] = {'o','l','i','v','e',0};
static const WCHAR purpleW[] = {'p','u','r','p','l','e',0};
static const WCHAR redW[] = {'r','e','d',0};
static const WCHAR silverW[] = {'s','i','l','v','e','r',0};
static const WCHAR tealW[] = {'t','e','a','l',0};
static const WCHAR whiteW[] = {'w','h','i','t','e',0};
static const WCHAR yellowW[] = {'y','e','l','l','o','w',0};

static const struct {
    LPCWSTR keyword;
    DWORD rgb;
} keyword_table[] = {
    {aquaW,     0x00ffff},
    {blackW,    0x000000},
    {blueW,     0x0000ff},
    {fuchsiaW,  0xff00ff},
    {grayW,     0x808080},
    {greenW,    0x008000},
    {limeW,     0x00ff00},
    {maroonW,   0x800000},
    {navyW,     0x000080},
    {oliveW,    0x808000},
    {purpleW,   0x800080},
    {redW,      0xff0000},
    {silverW,   0xc0c0c0},
    {tealW,     0x008080},
    {whiteW,    0xffffff},
    {yellowW,   0xffff00}
};

static int comp_value(const WCHAR *ptr, int dpc)
{
    int ret = 0;
    WCHAR ch;

    if(dpc > 2)
        dpc = 2;

    while(dpc--) {
        if(!*ptr)
            ret *= 16;
        else if(isdigitW(ch = *ptr++))
            ret = ret*16 + (ch-'0');
        else if('a' <= ch && ch <= 'f')
            ret = ret*16 + (ch-'a') + 10;
        else if('A' <= ch && ch <= 'F')
            ret = ret*16 + (ch-'A') + 10;
        else
            ret *= 16;
    }

    return ret;
}

/* Based on Gecko NS_LooseHexToRGB */
static int loose_hex_to_rgb(const WCHAR *hex)
{
    int len, dpc;

    len = strlenW(hex);
    if(*hex == '#') {
        hex++;
        len--;
    }
    if(len <= 3)
        return 0;

    dpc = min(len/3 + (len%3 ? 1 : 0), 4);
    return (comp_value(hex, dpc) << 16)
        | (comp_value(hex+dpc, dpc) << 8)
        | comp_value(hex+2*dpc, dpc);
}

static HRESULT nscolor_to_str(LPCWSTR color, BSTR *ret)
{
    int i, rgb = -1;

    static const WCHAR formatW[] = {'#','%','0','2','x','%','0','2','x','%','0','2','x',0};

    if(!color || !*color) {
        *ret = NULL;
        return S_OK;
    }

    if(*color != '#') {
        for(i=0; i < sizeof(keyword_table)/sizeof(keyword_table[0]); i++) {
            if(!strcmpiW(color, keyword_table[i].keyword))
                rgb = keyword_table[i].rgb;
        }
    }
    if(rgb == -1)
        rgb = loose_hex_to_rgb(color);

    *ret = SysAllocStringLen(NULL, 7);
    if(!*ret)
        return E_OUTOFMEMORY;

    sprintfW(*ret, formatW, rgb>>16, (rgb>>8)&0xff, rgb&0xff);

    TRACE("%s -> %s\n", debugstr_w(color), debugstr_w(*ret));
    return S_OK;
}

static BOOL variant_to_nscolor(const VARIANT *v, nsAString *nsstr)
{
    switch(V_VT(v)) {
    case VT_BSTR:
        nsAString_Init(nsstr, V_BSTR(v));
        return TRUE;

    case VT_I4: {
        PRUnichar buf[10];
        static const WCHAR formatW[] = {'#','%','x',0};

        wsprintfW(buf, formatW, V_I4(v));
        nsAString_Init(nsstr, buf);
        return TRUE;
    }

    default:
        FIXME("invalid vt=%d\n", V_VT(v));
    }

    return FALSE;

}

static void nscolor_to_variant(const nsAString *nsstr, VARIANT *p)
{
    const PRUnichar *color;

    nsAString_GetData(nsstr, &color);

    if(*color == '#') {
        V_VT(p) = VT_I4;
        V_I4(p) = strtolW(color+1, NULL, 16);
    }else {
        V_VT(p) = VT_BSTR;
        V_BSTR(p) = SysAllocString(color);
    }
}

#define HTMLBODY_THIS(iface) DEFINE_THIS(HTMLBodyElement, HTMLBodyElement, iface)

static HRESULT WINAPI HTMLBodyElement_QueryInterface(IHTMLBodyElement *iface,
                                                     REFIID riid, void **ppv)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);

    return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(&This->textcont.element.node), riid, ppv);
}

static ULONG WINAPI HTMLBodyElement_AddRef(IHTMLBodyElement *iface)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);

    return IHTMLDOMNode_AddRef(HTMLDOMNODE(&This->textcont.element.node));
}

static ULONG WINAPI HTMLBodyElement_Release(IHTMLBodyElement *iface)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);

    return IHTMLDOMNode_Release(HTMLDOMNODE(&This->textcont.element.node));
}

static HRESULT WINAPI HTMLBodyElement_GetTypeInfoCount(IHTMLBodyElement *iface, UINT *pctinfo)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->textcont.element.node.dispex), pctinfo);
}

static HRESULT WINAPI HTMLBodyElement_GetTypeInfo(IHTMLBodyElement *iface, UINT iTInfo,
                                              LCID lcid, ITypeInfo **ppTInfo)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->textcont.element.node.dispex), iTInfo, lcid, ppTInfo);
}

static HRESULT WINAPI HTMLBodyElement_GetIDsOfNames(IHTMLBodyElement *iface, REFIID riid,
                                                LPOLESTR *rgszNames, UINT cNames,
                                                LCID lcid, DISPID *rgDispId)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->textcont.element.node.dispex), riid, rgszNames, cNames, lcid, rgDispId);
}

static HRESULT WINAPI HTMLBodyElement_Invoke(IHTMLBodyElement *iface, DISPID dispIdMember,
                            REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                            VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    return IDispatchEx_Invoke(DISPATCHEX(&This->textcont.element.node.dispex), dispIdMember, riid, lcid,
            wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
}

static HRESULT WINAPI HTMLBodyElement_put_background(IHTMLBodyElement *iface, BSTR v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    HRESULT hr = S_OK;
    nsAString nsstr;
    nsresult nsres;

    TRACE("(%p)->(%s)\n", This, debugstr_w(v));

    nsAString_Init(&nsstr, v);

    nsres = nsIDOMHTMLBodyElement_SetBackground(This->nsbody, &nsstr);
    if(!NS_SUCCEEDED(nsres))
    {
        hr = E_FAIL;
    }

    nsAString_Finish(&nsstr);

    return hr;
}

static HRESULT WINAPI HTMLBodyElement_get_background(IHTMLBodyElement *iface, BSTR *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    nsAString background_str;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    nsAString_Init(&background_str, NULL);

    nsres = nsIDOMHTMLBodyElement_GetBackground(This->nsbody, &background_str);
    if(NS_SUCCEEDED(nsres)) {
        const PRUnichar *background;
        nsAString_GetData(&background_str, &background);
        *p = *background ? SysAllocString(background) : NULL;
    }else {
        ERR("GetBackground failed: %08x\n", nsres);
        *p = NULL;
    }

    nsAString_Finish(&background_str);

    TRACE("*p = %s\n", debugstr_w(*p));
    return S_OK;
}

static HRESULT WINAPI HTMLBodyElement_put_bgProperties(IHTMLBodyElement *iface, BSTR v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_bgProperties(IHTMLBodyElement *iface, BSTR *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_leftMargin(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_leftMargin(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_topMargin(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_topMargin(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_rightMargin(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_rightMargin(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_bottomMargin(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_bottomMargin(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->(%x)\n", This, v);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_bgColor(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    nsAString strColor;
    nsresult nsres;

    TRACE("(%p)->()\n", This);

    if(!variant_to_nscolor(&v, &strColor))
        return S_OK;

    nsres = nsIDOMHTMLBodyElement_SetBgColor(This->nsbody, &strColor);
    nsAString_Finish(&strColor);
    if(NS_FAILED(nsres))
        ERR("SetBgColor failed: %08x\n", nsres);

    return S_OK;
}

static HRESULT WINAPI HTMLBodyElement_get_bgColor(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    nsAString strColor;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, p);

    nsAString_Init(&strColor, NULL);
    nsres = nsIDOMHTMLBodyElement_GetBgColor(This->nsbody, &strColor);
    if(NS_SUCCEEDED(nsres)) {
        const PRUnichar *color;

        nsAString_GetData(&strColor, &color);
        V_VT(p) = VT_BSTR;
        hres = nscolor_to_str(color, &V_BSTR(p));
    }else {
        ERR("SetBgColor failed: %08x\n", nsres);
        hres = E_FAIL;
    }

    nsAString_Finish(&strColor);
    return hres;
}

static HRESULT WINAPI HTMLBodyElement_put_text(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    nsAString text;
    nsresult nsres;

    TRACE("(%p)->(v%d)\n", This, V_VT(&v));

    if(!variant_to_nscolor(&v, &text))
        return S_OK;

    nsres = nsIDOMHTMLBodyElement_SetText(This->nsbody, &text);
    nsAString_Finish(&text);

    return S_OK;
}

static HRESULT WINAPI HTMLBodyElement_get_text(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    nsAString text;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, p);

    nsAString_Init(&text, NULL);
    nsres = nsIDOMHTMLBodyElement_GetText(This->nsbody, &text);
    if(NS_SUCCEEDED(nsres)) {
        const PRUnichar *color;

        nsAString_GetData(&text, &color);
        V_VT(p) = VT_BSTR;
        hres = nscolor_to_str(color, &V_BSTR(p));
    }else {
        ERR("GetText failed: %08x\n", nsres);
        hres = E_FAIL;
    }

    nsAString_Finish(&text);

    return S_OK;
}

static HRESULT WINAPI HTMLBodyElement_put_link(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    nsAString link_str;
    nsresult nsres;

    TRACE("(%p)->(v%d)\n", This, V_VT(&v));

    if(!variant_to_nscolor(&v, &link_str))
        return S_OK;

    nsres = nsIDOMHTMLBodyElement_SetLink(This->nsbody, &link_str);
    nsAString_Finish(&link_str);
    if(NS_FAILED(nsres))
        ERR("SetLink failed: %08x\n", nsres);

    return S_OK;
}

static HRESULT WINAPI HTMLBodyElement_get_link(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    nsAString link_str;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    nsAString_Init(&link_str, NULL);
    nsres = nsIDOMHTMLBodyElement_GetLink(This->nsbody, &link_str);
    if(NS_FAILED(nsres))
        ERR("GetLink failed: %08x\n", nsres);

    nscolor_to_variant(&link_str, p);
    nsAString_Finish(&link_str);

    return S_OK;
}

static HRESULT WINAPI HTMLBodyElement_put_vLink(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    nsAString vlink_str;
    nsresult nsres;

    TRACE("(%p)->(v%d)\n", This, V_VT(&v));

    if(!variant_to_nscolor(&v, &vlink_str))
        return S_OK;

    nsres = nsIDOMHTMLBodyElement_SetVLink(This->nsbody, &vlink_str);
    nsAString_Finish(&vlink_str);
    if(NS_FAILED(nsres))
        ERR("SetLink failed: %08x\n", nsres);

    return S_OK;
}

static HRESULT WINAPI HTMLBodyElement_get_vLink(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    nsAString vlink_str;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    nsAString_Init(&vlink_str, NULL);
    nsres = nsIDOMHTMLBodyElement_GetVLink(This->nsbody, &vlink_str);
    if(NS_FAILED(nsres))
        ERR("GetLink failed: %08x\n", nsres);

    nscolor_to_variant(&vlink_str, p);
    nsAString_Finish(&vlink_str);

    return S_OK;
}

static HRESULT WINAPI HTMLBodyElement_put_aLink(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    nsAString alink_str;
    nsresult nsres;

    TRACE("(%p)->(v%d)\n", This, V_VT(&v));

    if(!variant_to_nscolor(&v, &alink_str))
        return S_OK;

    nsres = nsIDOMHTMLBodyElement_SetALink(This->nsbody, &alink_str);
    nsAString_Finish(&alink_str);
    if(NS_FAILED(nsres))
        ERR("SetALink failed: %08x\n", nsres);

    return S_OK;
}

static HRESULT WINAPI HTMLBodyElement_get_aLink(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    nsAString alink_str;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    nsAString_Init(&alink_str, NULL);
    nsres = nsIDOMHTMLBodyElement_GetALink(This->nsbody, &alink_str);
    if(NS_FAILED(nsres))
        ERR("GetALink failed: %08x\n", nsres);

    nscolor_to_variant(&alink_str, p);
    nsAString_Finish(&alink_str);

    return S_OK;
}

static HRESULT WINAPI HTMLBodyElement_put_onload(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_onload(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_onunload(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_onunload(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_scroll(IHTMLBodyElement *iface, BSTR v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_scroll(IHTMLBodyElement *iface, BSTR *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_onselect(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_onselect(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_onbeforeunload(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_onbeforeunload(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_createTextRange(IHTMLBodyElement *iface, IHTMLTxtRange **range)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
    nsIDOMDocumentRange *nsdocrange;
    nsIDOMRange *nsrange = NULL;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, range);

    if(!This->textcont.element.node.doc->nsdoc) {
        WARN("No nsdoc\n");
        return E_UNEXPECTED;
    }

    nsres = nsIDOMDocument_QueryInterface(This->textcont.element.node.doc->nsdoc, &IID_nsIDOMDocumentRange,
            (void**)&nsdocrange);
    if(NS_FAILED(nsres)) {
        ERR("Could not get nsIDOMDocumentRabge iface: %08x\n", nsres);
        return E_FAIL;
    }

    nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &nsrange);
    if(NS_SUCCEEDED(nsres)) {
        nsres = nsIDOMRange_SelectNodeContents(nsrange, This->textcont.element.node.nsnode);
        if(NS_FAILED(nsres))
            ERR("SelectNodeContents failed: %08x\n", nsres);
    }else {
        ERR("CreateRange failed: %08x\n", nsres);
    }

    nsIDOMDocumentRange_Release(nsdocrange);

    hres = HTMLTxtRange_Create(This->textcont.element.node.doc->basedoc.doc_node, nsrange, range);

    nsIDOMRange_Release(nsrange);
    return hres;
}

#undef HTMLBODY_THIS

static const IHTMLBodyElementVtbl HTMLBodyElementVtbl = {
    HTMLBodyElement_QueryInterface,
    HTMLBodyElement_AddRef,
    HTMLBodyElement_Release,
    HTMLBodyElement_GetTypeInfoCount,
    HTMLBodyElement_GetTypeInfo,
    HTMLBodyElement_GetIDsOfNames,
    HTMLBodyElement_Invoke,
    HTMLBodyElement_put_background,
    HTMLBodyElement_get_background,
    HTMLBodyElement_put_bgProperties,
    HTMLBodyElement_get_bgProperties,
    HTMLBodyElement_put_leftMargin,
    HTMLBodyElement_get_leftMargin,
    HTMLBodyElement_put_topMargin,
    HTMLBodyElement_get_topMargin,
    HTMLBodyElement_put_rightMargin,
    HTMLBodyElement_get_rightMargin,
    HTMLBodyElement_put_bottomMargin,
    HTMLBodyElement_get_bottomMargin,
    HTMLBodyElement_put_noWrap,
    HTMLBodyElement_get_noWrap,
    HTMLBodyElement_put_bgColor,
    HTMLBodyElement_get_bgColor,
    HTMLBodyElement_put_text,
    HTMLBodyElement_get_text,
    HTMLBodyElement_put_link,
    HTMLBodyElement_get_link,
    HTMLBodyElement_put_vLink,
    HTMLBodyElement_get_vLink,
    HTMLBodyElement_put_aLink,
    HTMLBodyElement_get_aLink,
    HTMLBodyElement_put_onload,
    HTMLBodyElement_get_onload,
    HTMLBodyElement_put_onunload,
    HTMLBodyElement_get_onunload,
    HTMLBodyElement_put_scroll,
    HTMLBodyElement_get_scroll,
    HTMLBodyElement_put_onselect,
    HTMLBodyElement_get_onselect,
    HTMLBodyElement_put_onbeforeunload,
    HTMLBodyElement_get_onbeforeunload,
    HTMLBodyElement_createTextRange
};

#define HTMLBODY_NODE_THIS(iface) DEFINE_THIS2(HTMLBodyElement, textcont.element.node, iface)

static HRESULT HTMLBodyElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
{
    HTMLBodyElement *This = HTMLBODY_NODE_THIS(iface);

    *ppv = NULL;

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = HTMLBODY(This);
    }else if(IsEqualGUID(&IID_IDispatch, riid)) {
        TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
        *ppv = HTMLBODY(This);
    }else if(IsEqualGUID(&IID_IHTMLBodyElement, riid)) {
        TRACE("(%p)->(IID_IHTMLBodyElement %p)\n", This, ppv);
        *ppv = HTMLBODY(This);
    }else if(IsEqualGUID(&IID_IHTMLTextContainer, riid)) {
        TRACE("(%p)->(IID_IHTMLTextContainer %p)\n", &This->textcont, ppv);
        *ppv = HTMLTEXTCONT(&This->textcont);
    }

    if(*ppv) {
        IUnknown_AddRef((IUnknown*)*ppv);
        return S_OK;
    }

    return HTMLElement_QI(&This->textcont.element.node, riid, ppv);
}

static void HTMLBodyElement_destructor(HTMLDOMNode *iface)
{
    HTMLBodyElement *This = HTMLBODY_NODE_THIS(iface);

    nsIDOMHTMLBodyElement_Release(This->nsbody);

    HTMLElement_destructor(&This->textcont.element.node);
}

static event_target_t **HTMLBodyElement_get_event_target(HTMLDOMNode *iface)
{
    HTMLBodyElement *This = HTMLBODY_NODE_THIS(iface);

    return This->textcont.element.node.doc
        ? &This->textcont.element.node.doc->body_event_target
        : &This->textcont.element.node.event_target;
}

#undef HTMLBODY_NODE_THIS

static const NodeImplVtbl HTMLBodyElementImplVtbl = {
    HTMLBodyElement_QI,
    HTMLBodyElement_destructor,
    HTMLBodyElement_get_event_target
};

static const tid_t HTMLBodyElement_iface_tids[] = {
    IHTMLBodyElement_tid,
    IHTMLBodyElement2_tid,
    IHTMLDOMNode_tid,
    IHTMLDOMNode2_tid,
    IHTMLElement_tid,
    IHTMLElement2_tid,
    IHTMLElement3_tid,
    IHTMLElement4_tid,
    IHTMLTextContainer_tid,
    IHTMLUniqueName_tid,
    0
};

static dispex_static_data_t HTMLBodyElement_dispex = {
    NULL,
    DispHTMLBody_tid,
    NULL,
    HTMLBodyElement_iface_tids
};

HTMLElement *HTMLBodyElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem)
{
    HTMLBodyElement *ret = heap_alloc_zero(sizeof(HTMLBodyElement));
    nsresult nsres;

    TRACE("(%p)->(%p)\n", ret, nselem);

    ret->lpHTMLBodyElementVtbl = &HTMLBodyElementVtbl;
    ret->textcont.element.node.vtbl = &HTMLBodyElementImplVtbl;

    HTMLTextContainer_Init(&ret->textcont, doc, nselem, &HTMLBodyElement_dispex);

    ConnectionPoint_Init(&ret->cp_propnotif, &ret->textcont.element.cp_container, &IID_IPropertyNotifySink, NULL);

    nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLBodyElement,
                                             (void**)&ret->nsbody);
    if(NS_FAILED(nsres))
        ERR("Could not get nsDOMHTMLBodyElement: %08x\n", nsres);

    return &ret->textcont.element;
}
