/*
 * Copyright 2006-2007 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>

#define COBJMACROS

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

#include "wine/debug.h"

#include "mshtml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

static const WCHAR brW[] = {'b','r',0};
static const WCHAR hrW[] = {'h','r',0};

typedef struct {
    IHTMLTxtRange     IHTMLTxtRange_iface;
    IOleCommandTarget IOleCommandTarget_iface;

    LONG ref;

    nsIDOMRange *nsrange;
    HTMLDocumentNode *doc;

    struct list entry;
} HTMLTxtRange;

typedef struct {
    WCHAR *buf;
    DWORD len;
    DWORD size;
} wstrbuf_t;

typedef struct {
    PRUint16 type;
    nsIDOMNode *node;
    PRUint32 off;
    nsAString str;
    const PRUnichar *p;
} dompos_t;

typedef enum {
    RU_UNKNOWN,
    RU_CHAR,
    RU_WORD,
    RU_SENTENCE,
    RU_TEXTEDIT
} range_unit_t;

static HTMLTxtRange *get_range_object(HTMLDocumentNode *doc, IHTMLTxtRange *iface)
{
    HTMLTxtRange *iter;

    LIST_FOR_EACH_ENTRY(iter, &doc->range_list, HTMLTxtRange, entry) {
        if(&iter->IHTMLTxtRange_iface == iface)
            return iter;
    }

    ERR("Could not find range in document\n");
    return NULL;
}

static range_unit_t string_to_unit(LPCWSTR str)
{
    static const WCHAR characterW[] =
        {'c','h','a','r','a','c','t','e','r',0};
    static const WCHAR wordW[] =
        {'w','o','r','d',0};
    static const WCHAR sentenceW[] =
        {'s','e','n','t','e','n','c','e',0};
    static const WCHAR texteditW[] =
        {'t','e','x','t','e','d','i','t',0};

    if(!strcmpiW(str, characterW))  return RU_CHAR;
    if(!strcmpiW(str, wordW))       return RU_WORD;
    if(!strcmpiW(str, sentenceW))   return RU_SENTENCE;
    if(!strcmpiW(str, texteditW))   return RU_TEXTEDIT;

    return RU_UNKNOWN;
}

static int string_to_nscmptype(LPCWSTR str)
{
    static const WCHAR seW[] = {'S','t','a','r','t','T','o','E','n','d',0};
    static const WCHAR ssW[] = {'S','t','a','r','t','T','o','S','t','a','r','t',0};
    static const WCHAR esW[] = {'E','n','d','T','o','S','t','a','r','t',0};
    static const WCHAR eeW[] = {'E','n','d','T','o','E','n','d',0};

    if(!strcmpiW(str, seW))  return NS_START_TO_END;
    if(!strcmpiW(str, ssW))  return NS_START_TO_START;
    if(!strcmpiW(str, esW))  return NS_END_TO_START;
    if(!strcmpiW(str, eeW))  return NS_END_TO_END;

    return -1;
}

static PRUint16 get_node_type(nsIDOMNode *node)
{
    PRUint16 type = 0;

    if(node)
        nsIDOMNode_GetNodeType(node, &type);

    return type;
}

static BOOL is_elem_tag(nsIDOMNode *node, LPCWSTR istag)
{
    nsIDOMElement *elem;
    nsAString tag_str;
    const PRUnichar *tag;
    BOOL ret = FALSE;
    nsresult nsres;

    nsres = nsIDOMNode_QueryInterface(node, &IID_nsIDOMElement, (void**)&elem);
    if(NS_FAILED(nsres))
        return FALSE;

    nsAString_Init(&tag_str, NULL);
    nsIDOMElement_GetTagName(elem, &tag_str);
    nsIDOMElement_Release(elem);
    nsAString_GetData(&tag_str, &tag);

    ret = !strcmpiW(tag, istag);

    nsAString_Finish(&tag_str);

    return ret;
}

static BOOL is_space_elem(nsIDOMNode *node)
{
    nsIDOMElement *elem;
    nsAString tag_str;
    const PRUnichar *tag;
    BOOL ret = FALSE;
    nsresult nsres;

    nsres = nsIDOMNode_QueryInterface(node, &IID_nsIDOMElement, (void**)&elem);
    if(NS_FAILED(nsres))
        return FALSE;

    nsAString_Init(&tag_str, NULL);
    nsIDOMElement_GetTagName(elem, &tag_str);
    nsIDOMElement_Release(elem);
    nsAString_GetData(&tag_str, &tag);

    ret = !strcmpiW(tag, brW) || !strcmpiW(tag, hrW);

    nsAString_Finish(&tag_str);

    return ret;
}

static inline BOOL wstrbuf_init(wstrbuf_t *buf)
{
    buf->len = 0;
    buf->size = 16;
    buf->buf = heap_alloc(buf->size * sizeof(WCHAR));
    if (!buf->buf) return FALSE;
    *buf->buf = 0;
    return TRUE;
}

static inline void wstrbuf_finish(wstrbuf_t *buf)
{
    heap_free(buf->buf);
}

static void wstrbuf_append_len(wstrbuf_t *buf, LPCWSTR str, int len)
{
    if(buf->len+len >= buf->size) {
        buf->size = 2*buf->size+len;
        buf->buf = heap_realloc(buf->buf, buf->size * sizeof(WCHAR));
    }

    memcpy(buf->buf+buf->len, str, len*sizeof(WCHAR));
    buf->len += len;
    buf->buf[buf->len] = 0;
}

static void wstrbuf_append_nodetxt(wstrbuf_t *buf, LPCWSTR str, int len)
{
    const WCHAR *s = str;
    WCHAR *d;

    TRACE("%s\n", debugstr_wn(str, len));

    if(buf->len+len >= buf->size) {
        buf->size = 2*buf->size+len;
        buf->buf = heap_realloc(buf->buf, buf->size * sizeof(WCHAR));
    }

    if(buf->len && isspaceW(buf->buf[buf->len-1])) {
        while(s < str+len && isspaceW(*s))
            s++;
    }

    d = buf->buf+buf->len;
    while(s < str+len) {
        if(isspaceW(*s)) {
            *d++ = ' ';
            s++;
            while(s < str+len && isspaceW(*s))
                s++;
        }else {
            *d++ = *s++;
        }
    }

    buf->len = d - buf->buf;
    *d = 0;
}

static void wstrbuf_append_node(wstrbuf_t *buf, nsIDOMNode *node)
{

    switch(get_node_type(node)) {
    case TEXT_NODE: {
        nsIDOMText *nstext;
        nsAString data_str;
        const PRUnichar *data;

        nsIDOMNode_QueryInterface(node, &IID_nsIDOMText, (void**)&nstext);

        nsAString_Init(&data_str, NULL);
        nsIDOMText_GetData(nstext, &data_str);
        nsAString_GetData(&data_str, &data);
        wstrbuf_append_nodetxt(buf, data, strlenW(data));
        nsAString_Finish(&data_str);

        nsIDOMText_Release(nstext);

        break;
    }
    case ELEMENT_NODE:
        if(is_elem_tag(node, brW)) {
            static const WCHAR endlW[] = {'\r','\n'};
            wstrbuf_append_len(buf, endlW, 2);
        }else if(is_elem_tag(node, hrW)) {
            static const WCHAR endl2W[] = {'\r','\n','\r','\n'};
            wstrbuf_append_len(buf, endl2W, 4);
        }
    }
}

static void wstrbuf_append_node_rec(wstrbuf_t *buf, nsIDOMNode *node)
{
    nsIDOMNode *iter, *tmp;

    wstrbuf_append_node(buf, node);

    nsIDOMNode_GetFirstChild(node, &iter);
    while(iter) {
        wstrbuf_append_node_rec(buf, iter);
        nsIDOMNode_GetNextSibling(iter, &tmp);
        nsIDOMNode_Release(iter);
        iter = tmp;
    }
}

static BOOL fill_nodestr(dompos_t *pos)
{
    nsIDOMText *text;
    nsresult nsres;

    if(pos->type != TEXT_NODE)
        return FALSE;

    nsres = nsIDOMNode_QueryInterface(pos->node, &IID_nsIDOMText, (void**)&text);
    if(NS_FAILED(nsres))
        return FALSE;

    nsAString_Init(&pos->str, NULL);
    nsIDOMText_GetData(text, &pos->str);
    nsIDOMText_Release(text);
    nsAString_GetData(&pos->str, &pos->p);

    if(pos->off == -1)
        pos->off = *pos->p ? strlenW(pos->p)-1 : 0;

    return TRUE;
}

static nsIDOMNode *next_node(nsIDOMNode *iter)
{
    nsIDOMNode *ret, *tmp;
    nsresult nsres;

    if(!iter)
        return NULL;

    nsres = nsIDOMNode_GetFirstChild(iter, &ret);
    if(NS_SUCCEEDED(nsres) && ret)
        return ret;

    nsIDOMNode_AddRef(iter);

    do {
        nsres = nsIDOMNode_GetNextSibling(iter, &ret);
        if(NS_SUCCEEDED(nsres) && ret) {
            nsIDOMNode_Release(iter);
            return ret;
        }

        nsres = nsIDOMNode_GetParentNode(iter, &tmp);
        nsIDOMNode_Release(iter);
        iter = tmp;
    }while(NS_SUCCEEDED(nsres) && iter);

    return NULL;
}

static nsIDOMNode *prev_node(HTMLTxtRange *This, nsIDOMNode *iter)
{
    nsIDOMNode *ret, *tmp;
    nsresult nsres;

    if(!iter) {
        nsIDOMHTMLElement *nselem;

        nsIDOMHTMLDocument_GetBody(This->doc->nsdoc, &nselem);
        nsIDOMElement_GetLastChild(nselem, &tmp);
        if(!tmp)
            return (nsIDOMNode*)nselem;

        while(tmp) {
            ret = tmp;
            nsIDOMNode_GetLastChild(ret, &tmp);
        }

        nsIDOMElement_Release(nselem);

        return ret;
    }

    nsres = nsIDOMNode_GetLastChild(iter, &ret);
    if(NS_SUCCEEDED(nsres) && ret)
        return ret;

    nsIDOMNode_AddRef(iter);

    do {
        nsres = nsIDOMNode_GetPreviousSibling(iter, &ret);
        if(NS_SUCCEEDED(nsres) && ret) {
            nsIDOMNode_Release(iter);
            return ret;
        }

        nsres = nsIDOMNode_GetParentNode(iter, &tmp);
        nsIDOMNode_Release(iter);
        iter = tmp;
    }while(NS_SUCCEEDED(nsres) && iter);

    return NULL;
}

static nsIDOMNode *get_child_node(nsIDOMNode *node, PRUint32 off)
{
    nsIDOMNodeList *node_list;
    nsIDOMNode *ret = NULL;

    nsIDOMNode_GetChildNodes(node, &node_list);
    nsIDOMNodeList_Item(node_list, off, &ret);
    nsIDOMNodeList_Release(node_list);

    return ret;
}

static void get_cur_pos(HTMLTxtRange *This, BOOL start, dompos_t *pos)
{
    nsIDOMNode *node;
    PRInt32 off;

    pos->p = NULL;

    if(!start) {
        cpp_bool collapsed;
        nsIDOMRange_GetCollapsed(This->nsrange, &collapsed);
        start = collapsed;
    }

    if(start) {
        nsIDOMRange_GetStartContainer(This->nsrange, &node);
        nsIDOMRange_GetStartOffset(This->nsrange, &off);
    }else {
        nsIDOMRange_GetEndContainer(This->nsrange, &node);
        nsIDOMRange_GetEndOffset(This->nsrange, &off);
    }

    pos->type = get_node_type(node);
    if(pos->type == ELEMENT_NODE) {
        if(start) {
            pos->node = get_child_node(node, off);
            pos->off = 0;
        }else {
            pos->node = off ? get_child_node(node, off-1) : prev_node(This, node);
            pos->off = -1;
        }

        pos->type = get_node_type(pos->node);
        nsIDOMNode_Release(node);
    }else if(start) {
        pos->node = node;
        pos->off = off;
    }else if(off) {
        pos->node = node;
        pos->off = off-1;
    }else {
        pos->node = prev_node(This, node);
        pos->off = -1;
        nsIDOMNode_Release(node);
    }

    if(pos->type == TEXT_NODE)
        fill_nodestr(pos);
}

static void set_range_pos(HTMLTxtRange *This, BOOL start, dompos_t *pos)
{
    nsresult nsres;

    if(start) {
        if(pos->type == TEXT_NODE)
            nsres = nsIDOMRange_SetStart(This->nsrange, pos->node, pos->off);
        else
            nsres = nsIDOMRange_SetStartBefore(This->nsrange, pos->node);
    }else {
        if(pos->type == TEXT_NODE && pos->p[pos->off+1])
            nsres = nsIDOMRange_SetEnd(This->nsrange, pos->node, pos->off+1);
        else
            nsres = nsIDOMRange_SetEndAfter(This->nsrange, pos->node);
    }

    if(NS_FAILED(nsres))
        ERR("failed: %p %08x\n", pos->node, nsres);
}

static inline void dompos_release(dompos_t *pos)
{
    if(pos->node)
        nsIDOMNode_Release(pos->node);

    if(pos->p)
        nsAString_Finish(&pos->str);
}

static inline void dompos_addref(dompos_t *pos)
{
    if(pos->node)
        nsIDOMNode_AddRef(pos->node);

    if(pos->type == TEXT_NODE)
        fill_nodestr(pos);
}

static inline BOOL dompos_cmp(const dompos_t *pos1, const dompos_t *pos2)
{
    return pos1->node == pos2->node && pos1->off == pos2->off;
}

static void range_to_string(HTMLTxtRange *This, wstrbuf_t *buf)
{
    nsIDOMNode *iter, *tmp;
    dompos_t start_pos, end_pos;
    cpp_bool collapsed;

    nsIDOMRange_GetCollapsed(This->nsrange, &collapsed);
    if(collapsed) {
        wstrbuf_finish(buf);
        buf->buf = NULL;
        buf->size = 0;
        return;
    }

    get_cur_pos(This, FALSE, &end_pos);
    get_cur_pos(This, TRUE, &start_pos);

    if(start_pos.type == TEXT_NODE) {
        if(start_pos.node == end_pos.node) {
            wstrbuf_append_nodetxt(buf, start_pos.p+start_pos.off, end_pos.off-start_pos.off+1);
            iter = start_pos.node;
            nsIDOMNode_AddRef(iter);
        }else {
            wstrbuf_append_nodetxt(buf, start_pos.p+start_pos.off, strlenW(start_pos.p+start_pos.off));
            iter = next_node(start_pos.node);
        }
    }else {
        iter = start_pos.node;
        nsIDOMNode_AddRef(iter);
    }

    while(iter != end_pos.node) {
        wstrbuf_append_node(buf, iter);
        tmp = next_node(iter);
        nsIDOMNode_Release(iter);
        iter = tmp;
    }

    nsIDOMNode_AddRef(end_pos.node);

    if(start_pos.node != end_pos.node) {
        if(end_pos.type == TEXT_NODE)
            wstrbuf_append_nodetxt(buf, end_pos.p, end_pos.off+1);
        else
            wstrbuf_append_node(buf, end_pos.node);
    }

    nsIDOMNode_Release(iter);
    dompos_release(&start_pos);
    dompos_release(&end_pos);

    if(buf->len) {
        WCHAR *p;

        for(p = buf->buf+buf->len-1; p >= buf->buf && isspaceW(*p); p--);

        p = strchrW(p, '\r');
        if(p)
            *p = 0;
    }
}

HRESULT get_node_text(HTMLDOMNode *node, BSTR *ret)
{
    wstrbuf_t buf;
    HRESULT hres = S_OK;

    if (!wstrbuf_init(&buf))
        return E_OUTOFMEMORY;
    wstrbuf_append_node_rec(&buf, node->nsnode);
    if(buf.buf) {
        *ret = SysAllocString(buf.buf);
        if(!*ret)
            hres = E_OUTOFMEMORY;
    } else {
        *ret = NULL;
    }
    wstrbuf_finish(&buf);

    if(SUCCEEDED(hres))
        TRACE("ret %s\n", debugstr_w(*ret));
    return hres;
}

static WCHAR get_pos_char(const dompos_t *pos)
{
    switch(pos->type) {
    case TEXT_NODE:
        return pos->p[pos->off];
    case ELEMENT_NODE:
        if(is_space_elem(pos->node))
            return '\n';
    }

    return 0;
}

static void end_space(const dompos_t *pos, dompos_t *new_pos)
{
    const WCHAR *p;

    *new_pos = *pos;
    dompos_addref(new_pos);

    if(pos->type != TEXT_NODE)
        return;

    p = new_pos->p+new_pos->off;

    if(!*p || !isspace(*p))
        return;

    while(p[1] && isspace(p[1]))
        p++;

    new_pos->off = p - new_pos->p;
}

static WCHAR next_char(const dompos_t *pos, dompos_t *new_pos)
{
    nsIDOMNode *iter, *tmp;
    dompos_t last_space, tmp_pos;
    const WCHAR *p;
    WCHAR cspace = 0;

    if(pos->type == TEXT_NODE && pos->off != -1 && pos->p[pos->off]) {
        p = pos->p+pos->off;

        if(isspace(*p))
            while(isspaceW(*++p));
        else
            p++;

        if(*p && isspaceW(*p)) {
            cspace = ' ';
            while(p[1] && isspaceW(p[1]))
                p++;
        }

        if(*p) {
            *new_pos = *pos;
            new_pos->off = p - pos->p;
            dompos_addref(new_pos);

            return cspace ? cspace : *p;
        }else {
            last_space = *pos;
            last_space.off = p - pos->p;
            dompos_addref(&last_space);
        }
    }

    iter = next_node(pos->node);

    while(iter) {
        switch(get_node_type(iter)) {
        case TEXT_NODE:
            tmp_pos.node = iter;
            tmp_pos.type = TEXT_NODE;
            tmp_pos.off = 0;
            dompos_addref(&tmp_pos);

            p = tmp_pos.p;

            if(!*p) {
                dompos_release(&tmp_pos);
                break;
            }else if(isspaceW(*p)) {
                if(cspace)
                    dompos_release(&last_space);
                else
                    cspace = ' ';

                while(p[1] && isspaceW(p[1]))
                      p++;

                tmp_pos.off = p-tmp_pos.p;

                if(!p[1]) {
                    last_space = tmp_pos;
                    break;
                }

                *new_pos = tmp_pos;
                nsIDOMNode_Release(iter);
                return cspace;
            }else if(cspace) {
                *new_pos = last_space;
                dompos_release(&tmp_pos);
                nsIDOMNode_Release(iter);

                return cspace;
            }else if(*p) {
                tmp_pos.off = 0;
                *new_pos = tmp_pos;
            }

            nsIDOMNode_Release(iter);
            return *p;

        case ELEMENT_NODE:
            if(is_elem_tag(iter, brW)) {
                if(cspace)
                    dompos_release(&last_space);
                cspace = '\n';

                nsIDOMNode_AddRef(iter);
                last_space.node = iter;
                last_space.type = ELEMENT_NODE;
                last_space.off = 0;
                last_space.p = NULL;
            }else if(is_elem_tag(iter, hrW)) {
                if(cspace) {
                    *new_pos = last_space;
                    nsIDOMNode_Release(iter);
                    return cspace;
                }

                new_pos->node = iter;
                new_pos->type = ELEMENT_NODE;
                new_pos->off = 0;
                new_pos->p = NULL;
                return '\n';
            }
        }

        tmp = iter;
        iter = next_node(iter);
        nsIDOMNode_Release(tmp);
    }

    if(cspace) {
        *new_pos = last_space;
    }else {
        *new_pos = *pos;
        dompos_addref(new_pos);
    }

    return cspace;
}

static WCHAR prev_char(HTMLTxtRange *This, const dompos_t *pos, dompos_t *new_pos)
{
    nsIDOMNode *iter, *tmp;
    const WCHAR *p;
    BOOL skip_space = FALSE;

    if(pos->type == TEXT_NODE && isspaceW(pos->p[pos->off]))
        skip_space = TRUE;

    if(pos->type == TEXT_NODE && pos->off) {
        p = pos->p+pos->off-1;

        if(skip_space) {
            while(p >= pos->p && isspace(*p))
                p--;
        }

        if(p >= pos->p) {
            *new_pos = *pos;
            new_pos->off = p-pos->p;
            dompos_addref(new_pos);
            return new_pos->p[new_pos->off];
        }
    }

    iter = prev_node(This, pos->node);

    while(iter) {
        switch(get_node_type(iter)) {
        case TEXT_NODE: {
            dompos_t tmp_pos;

            tmp_pos.node = iter;
            tmp_pos.type = TEXT_NODE;
            tmp_pos.off = 0;
            dompos_addref(&tmp_pos);

            p = tmp_pos.p + strlenW(tmp_pos.p)-1;

            if(skip_space) {
                while(p >= tmp_pos.p && isspaceW(*p))
                    p--;
            }

            if(p < tmp_pos.p) {
                dompos_release(&tmp_pos);
                break;
            }

            tmp_pos.off = p-tmp_pos.p;
            *new_pos = tmp_pos;
            nsIDOMNode_Release(iter);
            return *p;
        }

        case ELEMENT_NODE:
            if(is_elem_tag(iter, brW)) {
                if(skip_space) {
                    skip_space = FALSE;
                    break;
                }
            }else if(!is_elem_tag(iter, hrW)) {
                break;
            }

            new_pos->node = iter;
            new_pos->type = ELEMENT_NODE;
            new_pos->off = 0;
            new_pos->p = NULL;
            return '\n';
        }

        tmp = iter;
        iter = prev_node(This, iter);
        nsIDOMNode_Release(tmp);
    }

    *new_pos = *pos;
    dompos_addref(new_pos);
    return 0;
}

static LONG move_next_chars(LONG cnt, const dompos_t *pos, BOOL col, const dompos_t *bound_pos,
        BOOL *bounded, dompos_t *new_pos)
{
    dompos_t iter, tmp;
    LONG ret = 0;
    WCHAR c;

    if(bounded)
        *bounded = FALSE;

    if(col)
        ret++;

    if(ret >= cnt) {
        end_space(pos, new_pos);
        return ret;
    }

    c = next_char(pos, &iter);
    ret++;

    while(ret < cnt) {
        tmp = iter;
        c = next_char(&tmp, &iter);
        dompos_release(&tmp);
        if(!c)
            break;

        ret++;
        if(bound_pos && dompos_cmp(&tmp, bound_pos)) {
            *bounded = TRUE;
            ret++;
        }
    }

    *new_pos = iter;
    return ret;
}

static LONG move_prev_chars(HTMLTxtRange *This, LONG cnt, const dompos_t *pos, BOOL end,
        const dompos_t *bound_pos, BOOL *bounded, dompos_t *new_pos)
{
    dompos_t iter, tmp;
    LONG ret = 0;
    BOOL prev_eq = FALSE;
    WCHAR c;

    if(bounded)
        *bounded = FALSE;

    c = prev_char(This, pos, &iter);
    if(c)
        ret++;

    while(c && ret < cnt) {
        tmp = iter;
        c = prev_char(This, &tmp, &iter);
        dompos_release(&tmp);
        if(!c) {
            if(end)
                ret++;
            break;
        }

        ret++;

        if(prev_eq) {
            *bounded = TRUE;
            ret++;
        }

        prev_eq = bound_pos && dompos_cmp(&iter, bound_pos);
    }

    *new_pos = iter;
    return ret;
}

static LONG find_prev_space(HTMLTxtRange *This, const dompos_t *pos, BOOL first_space, dompos_t *ret)
{
    dompos_t iter, tmp;
    WCHAR c;

    c = prev_char(This, pos, &iter);
    if(!c || (first_space && isspaceW(c))) {
        *ret = iter;
        return FALSE;
    }

    while(1) {
        tmp = iter;
        c = prev_char(This, &tmp, &iter);
        if(!c || isspaceW(c)) {
            dompos_release(&iter);
            break;
        }
        dompos_release(&tmp);
    }

    *ret = tmp;
    return TRUE;
}

static int find_word_end(const dompos_t *pos, dompos_t *ret)
{
    dompos_t iter, tmp;
    int cnt = 1;
    WCHAR c;
    c = get_pos_char(pos);
    if(isspaceW(c)) {
        *ret = *pos;
        dompos_addref(ret);
        return 0;
    }

    c = next_char(pos, &iter);
    if(!c) {
        *ret = iter;
        return 0;
    }
    if(c == '\n') {
        *ret = *pos;
        dompos_addref(ret);
        return 0;
    }

    while(c && !isspaceW(c)) {
        tmp = iter;
        c = next_char(&tmp, &iter);
        if(c == '\n') {
            dompos_release(&iter);
            iter = tmp;
        }else {
            cnt++;
            dompos_release(&tmp);
        }
    }

    *ret = iter;
    return cnt;
}

static LONG move_next_words(LONG cnt, const dompos_t *pos, dompos_t *new_pos)
{
    dompos_t iter, tmp;
    LONG ret = 0;
    WCHAR c;

    c = get_pos_char(pos);
    if(isspaceW(c)) {
        end_space(pos, &iter);
        ret++;
    }else {
        c = next_char(pos, &iter);
        if(c && isspaceW(c))
            ret++;
    }

    while(c && ret < cnt) {
        tmp = iter;
        c = next_char(&tmp, &iter);
        dompos_release(&tmp);
        if(isspaceW(c))
            ret++;
    }

    *new_pos = iter;
    return ret;
}

static LONG move_prev_words(HTMLTxtRange *This, LONG cnt, const dompos_t *pos, dompos_t *new_pos)
{
    dompos_t iter, tmp;
    LONG ret = 0;

    iter = *pos;
    dompos_addref(&iter);

    while(ret < cnt) {
        if(!find_prev_space(This, &iter, FALSE, &tmp))
            break;

        dompos_release(&iter);
        iter = tmp;
        ret++;
    }

    *new_pos = iter;
    return ret;
}

static inline HTMLTxtRange *impl_from_IHTMLTxtRange(IHTMLTxtRange *iface)
{
    return CONTAINING_RECORD(iface, HTMLTxtRange, IHTMLTxtRange_iface);
}

static HRESULT WINAPI HTMLTxtRange_QueryInterface(IHTMLTxtRange *iface, REFIID riid, void **ppv)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);

    *ppv = NULL;

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = &This->IHTMLTxtRange_iface;
    }else if(IsEqualGUID(&IID_IDispatch, riid)) {
        TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
        *ppv = &This->IHTMLTxtRange_iface;
    }else if(IsEqualGUID(&IID_IHTMLTxtRange, riid)) {
        TRACE("(%p)->(IID_IHTMLTxtRange %p)\n", This, ppv);
        *ppv = &This->IHTMLTxtRange_iface;
    }else if(IsEqualGUID(&IID_IOleCommandTarget, riid)) {
        TRACE("(%p)->(IID_IOleCommandTarget %p)\n", This, ppv);
        *ppv = &This->IOleCommandTarget_iface;
    }

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

    WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
    return E_NOINTERFACE;
}

static ULONG WINAPI HTMLTxtRange_AddRef(IHTMLTxtRange *iface)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static ULONG WINAPI HTMLTxtRange_Release(IHTMLTxtRange *iface)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref) {
        if(This->nsrange)
            nsISelection_Release(This->nsrange);
        if(This->doc)
            list_remove(&This->entry);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI HTMLTxtRange_GetTypeInfoCount(IHTMLTxtRange *iface, UINT *pctinfo)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%p)\n", This, pctinfo);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_GetTypeInfo(IHTMLTxtRange *iface, UINT iTInfo,
                                               LCID lcid, ITypeInfo **ppTInfo)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_GetIDsOfNames(IHTMLTxtRange *iface, REFIID riid,
                                                 LPOLESTR *rgszNames, UINT cNames,
                                                 LCID lcid, DISPID *rgDispId)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
          lcid, rgDispId);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_Invoke(IHTMLTxtRange *iface, DISPID dispIdMember,
                            REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                            VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
          lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_get_htmlText(IHTMLTxtRange *iface, BSTR *p)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);

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

    *p = NULL;

    if(This->nsrange) {
        nsIDOMDocumentFragment *fragment;
        nsresult nsres;

        nsres = nsIDOMRange_CloneContents(This->nsrange, &fragment);
        if(NS_SUCCEEDED(nsres)) {
            const PRUnichar *nstext;
            nsAString nsstr;

            nsAString_Init(&nsstr, NULL);
            nsnode_to_nsstring((nsIDOMNode*)fragment, &nsstr);
            nsIDOMDocumentFragment_Release(fragment);

            nsAString_GetData(&nsstr, &nstext);
            *p = SysAllocString(nstext);

            nsAString_Finish(&nsstr);
        }
    }

    if(!*p) {
        const WCHAR emptyW[] = {0};
        *p = SysAllocString(emptyW);
    }

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

static HRESULT WINAPI HTMLTxtRange_put_text(IHTMLTxtRange *iface, BSTR v)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    nsIDOMText *text_node;
    nsAString text_str;
    nsresult nsres;

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

    if(!This->doc)
        return MSHTML_E_NODOC;

    nsAString_InitDepend(&text_str, v);
    nsres = nsIDOMHTMLDocument_CreateTextNode(This->doc->nsdoc, &text_str, &text_node);
    nsAString_Finish(&text_str);
    if(NS_FAILED(nsres)) {
        ERR("CreateTextNode failed: %08x\n", nsres);
        return S_OK;
    }
    nsres = nsIDOMRange_DeleteContents(This->nsrange);
    if(NS_FAILED(nsres))
        ERR("DeleteContents failed: %08x\n", nsres);

    nsres = nsIDOMRange_InsertNode(This->nsrange, (nsIDOMNode*)text_node);
    if(NS_FAILED(nsres))
        ERR("InsertNode failed: %08x\n", nsres);

    nsres = nsIDOMRange_SetEndAfter(This->nsrange, (nsIDOMNode*)text_node);
    if(NS_FAILED(nsres))
        ERR("SetEndAfter failed: %08x\n", nsres);

    return IHTMLTxtRange_collapse(&This->IHTMLTxtRange_iface, VARIANT_FALSE);
}

static HRESULT WINAPI HTMLTxtRange_get_text(IHTMLTxtRange *iface, BSTR *p)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    wstrbuf_t buf;

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

    *p = NULL;
    if(!This->nsrange)
        return S_OK;

    if (!wstrbuf_init(&buf))
        return E_OUTOFMEMORY;
    range_to_string(This, &buf);
    if (buf.buf)
        *p = SysAllocString(buf.buf);
    wstrbuf_finish(&buf);

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

static HRESULT WINAPI HTMLTxtRange_parentElement(IHTMLTxtRange *iface, IHTMLElement **parent)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    nsIDOMNode *nsnode, *tmp;
    HTMLDOMNode *node;
    HRESULT hres;

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

    nsIDOMRange_GetCommonAncestorContainer(This->nsrange, &nsnode);
    while(nsnode && get_node_type(nsnode) != ELEMENT_NODE) {
        nsIDOMNode_GetParentNode(nsnode, &tmp);
        nsIDOMNode_Release(nsnode);
        nsnode = tmp;
    }

    if(!nsnode) {
        *parent = NULL;
        return S_OK;
    }

    hres = get_node(This->doc, nsnode, TRUE, &node);
    nsIDOMNode_Release(nsnode);
    if(FAILED(hres))
        return hres;

    return IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_IHTMLElement, (void**)parent);
}

static HRESULT WINAPI HTMLTxtRange_duplicate(IHTMLTxtRange *iface, IHTMLTxtRange **Duplicate)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    nsIDOMRange *nsrange = NULL;
    HRESULT hres;

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

    nsIDOMRange_CloneRange(This->nsrange, &nsrange);
    hres = HTMLTxtRange_Create(This->doc, nsrange, Duplicate);
    nsIDOMRange_Release(nsrange);

    return hres;
}

static HRESULT WINAPI HTMLTxtRange_inRange(IHTMLTxtRange *iface, IHTMLTxtRange *Range,
        VARIANT_BOOL *InRange)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    HTMLTxtRange *src_range;
    PRInt16 nsret = 0;
    nsresult nsres;

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

    *InRange = VARIANT_FALSE;

    src_range = get_range_object(This->doc, Range);
    if(!src_range)
        return E_FAIL;

    nsres = nsIDOMRange_CompareBoundaryPoints(This->nsrange, NS_START_TO_START,
            src_range->nsrange, &nsret);
    if(NS_SUCCEEDED(nsres) && nsret <= 0) {
        nsres = nsIDOMRange_CompareBoundaryPoints(This->nsrange, NS_END_TO_END,
                src_range->nsrange, &nsret);
        if(NS_SUCCEEDED(nsres) && nsret >= 0)
            *InRange = VARIANT_TRUE;
    }

    if(NS_FAILED(nsres))
        ERR("CompareBoundaryPoints failed: %08x\n", nsres);

    return S_OK;
}

static HRESULT WINAPI HTMLTxtRange_isEqual(IHTMLTxtRange *iface, IHTMLTxtRange *Range,
        VARIANT_BOOL *IsEqual)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    HTMLTxtRange *src_range;
    PRInt16 nsret = 0;
    nsresult nsres;

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

    *IsEqual = VARIANT_FALSE;

    src_range = get_range_object(This->doc, Range);
    if(!src_range)
        return E_FAIL;

    nsres = nsIDOMRange_CompareBoundaryPoints(This->nsrange, NS_START_TO_START,
            src_range->nsrange, &nsret);
    if(NS_SUCCEEDED(nsres) && !nsret) {
        nsres = nsIDOMRange_CompareBoundaryPoints(This->nsrange, NS_END_TO_END,
                src_range->nsrange, &nsret);
        if(NS_SUCCEEDED(nsres) && !nsret)
            *IsEqual = VARIANT_TRUE;
    }

    if(NS_FAILED(nsres))
        ERR("CompareBoundaryPoints failed: %08x\n", nsres);

    return S_OK;
}

static HRESULT WINAPI HTMLTxtRange_scrollIntoView(IHTMLTxtRange *iface, VARIANT_BOOL fStart)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%x)\n", This, fStart);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_collapse(IHTMLTxtRange *iface, VARIANT_BOOL Start)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);

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

    nsIDOMRange_Collapse(This->nsrange, Start != VARIANT_FALSE);
    return S_OK;
}

static HRESULT WINAPI HTMLTxtRange_expand(IHTMLTxtRange *iface, BSTR Unit, VARIANT_BOOL *Success)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    range_unit_t unit;

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

    unit = string_to_unit(Unit);
    if(unit == RU_UNKNOWN)
        return E_INVALIDARG;

    *Success = VARIANT_FALSE;

    switch(unit) {
    case RU_WORD: {
        dompos_t end_pos, start_pos, new_start_pos, new_end_pos;
        cpp_bool collapsed;

        nsIDOMRange_GetCollapsed(This->nsrange, &collapsed);

        get_cur_pos(This, TRUE, &start_pos);
        get_cur_pos(This, FALSE, &end_pos);

        if(find_word_end(&end_pos, &new_end_pos) || collapsed) {
            set_range_pos(This, FALSE, &new_end_pos);
            *Success = VARIANT_TRUE;
        }

        if(start_pos.type && (get_pos_char(&end_pos) || !dompos_cmp(&new_end_pos, &end_pos))) {
            if(find_prev_space(This, &start_pos, TRUE, &new_start_pos)) {
                set_range_pos(This, TRUE, &new_start_pos);
                *Success = VARIANT_TRUE;
            }
            dompos_release(&new_start_pos);
        }

        dompos_release(&new_end_pos);
        dompos_release(&end_pos);
        dompos_release(&start_pos);

        break;
    }

    case RU_TEXTEDIT: {
        nsIDOMHTMLElement *nsbody = NULL;
        nsresult nsres;

        nsres = nsIDOMHTMLDocument_GetBody(This->doc->nsdoc, &nsbody);
        if(NS_FAILED(nsres) || !nsbody) {
            ERR("Could not get body: %08x\n", nsres);
            break;
        }

        nsres = nsIDOMRange_SelectNodeContents(This->nsrange, (nsIDOMNode*)nsbody);
        nsIDOMHTMLElement_Release(nsbody);
        if(NS_FAILED(nsres)) {
            ERR("Collapse failed: %08x\n", nsres);
            break;
        }

        *Success = VARIANT_TRUE;
        break;
    }

    default:
        FIXME("Unimplemented unit %s\n", debugstr_w(Unit));
    }

    return S_OK;
}

static HRESULT WINAPI HTMLTxtRange_move(IHTMLTxtRange *iface, BSTR Unit,
        LONG Count, LONG *ActualCount)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    range_unit_t unit;

    TRACE("(%p)->(%s %d %p)\n", This, debugstr_w(Unit), Count, ActualCount);

    unit = string_to_unit(Unit);
    if(unit == RU_UNKNOWN)
        return E_INVALIDARG;

    if(!Count) {
        *ActualCount = 0;
        return IHTMLTxtRange_collapse(&This->IHTMLTxtRange_iface, TRUE);
    }

    switch(unit) {
    case RU_CHAR: {
        dompos_t cur_pos, new_pos;

        get_cur_pos(This, TRUE, &cur_pos);

        if(Count > 0) {
            *ActualCount = move_next_chars(Count, &cur_pos, TRUE, NULL, NULL, &new_pos);
            set_range_pos(This, FALSE, &new_pos);
            dompos_release(&new_pos);

            IHTMLTxtRange_collapse(&This->IHTMLTxtRange_iface, FALSE);
        }else {
            *ActualCount = -move_prev_chars(This, -Count, &cur_pos, FALSE, NULL, NULL, &new_pos);
            set_range_pos(This, TRUE, &new_pos);
            IHTMLTxtRange_collapse(&This->IHTMLTxtRange_iface, TRUE);
            dompos_release(&new_pos);
        }

        dompos_release(&cur_pos);
        break;
    }

    case RU_WORD: {
        dompos_t cur_pos, new_pos;

        get_cur_pos(This, TRUE, &cur_pos);

        if(Count > 0) {
            *ActualCount = move_next_words(Count, &cur_pos, &new_pos);
            set_range_pos(This, FALSE, &new_pos);
            dompos_release(&new_pos);
            IHTMLTxtRange_collapse(&This->IHTMLTxtRange_iface, FALSE);
        }else {
            *ActualCount = -move_prev_words(This, -Count, &cur_pos, &new_pos);
            set_range_pos(This, TRUE, &new_pos);
            IHTMLTxtRange_collapse(&This->IHTMLTxtRange_iface, TRUE);
            dompos_release(&new_pos);
        }

        dompos_release(&cur_pos);
        break;
    }

    default:
        FIXME("unimplemented unit %s\n", debugstr_w(Unit));
    }

    TRACE("ret %d\n", *ActualCount);
    return S_OK;
}

static HRESULT WINAPI HTMLTxtRange_moveStart(IHTMLTxtRange *iface, BSTR Unit,
        LONG Count, LONG *ActualCount)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    range_unit_t unit;

    TRACE("(%p)->(%s %d %p)\n", This, debugstr_w(Unit), Count, ActualCount);

    unit = string_to_unit(Unit);
    if(unit == RU_UNKNOWN)
        return E_INVALIDARG;

    if(!Count) {
        *ActualCount = 0;
        return S_OK;
    }

    switch(unit) {
    case RU_CHAR: {
        dompos_t start_pos, end_pos, new_pos;
        cpp_bool collapsed;

        get_cur_pos(This, TRUE, &start_pos);
        get_cur_pos(This, FALSE, &end_pos);
        nsIDOMRange_GetCollapsed(This->nsrange, &collapsed);

        if(Count > 0) {
            BOOL bounded;

            *ActualCount = move_next_chars(Count, &start_pos, collapsed, &end_pos, &bounded, &new_pos);
            set_range_pos(This, !bounded, &new_pos);
            if(bounded)
                IHTMLTxtRange_collapse(&This->IHTMLTxtRange_iface, FALSE);
        }else {
            *ActualCount = -move_prev_chars(This, -Count, &start_pos, FALSE, NULL, NULL, &new_pos);
            set_range_pos(This, TRUE, &new_pos);
        }

        dompos_release(&start_pos);
        dompos_release(&end_pos);
        dompos_release(&new_pos);
        break;
    }

    default:
        FIXME("unimplemented unit %s\n", debugstr_w(Unit));
    }

    return S_OK;
}

static HRESULT WINAPI HTMLTxtRange_moveEnd(IHTMLTxtRange *iface, BSTR Unit,
        LONG Count, LONG *ActualCount)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    range_unit_t unit;

    TRACE("(%p)->(%s %d %p)\n", This, debugstr_w(Unit), Count, ActualCount);

    unit = string_to_unit(Unit);
    if(unit == RU_UNKNOWN)
        return E_INVALIDARG;

    if(!Count) {
        *ActualCount = 0;
        return S_OK;
    }

    switch(unit) {
    case RU_CHAR: {
        dompos_t start_pos, end_pos, new_pos;
        cpp_bool collapsed;

        get_cur_pos(This, TRUE, &start_pos);
        get_cur_pos(This, FALSE, &end_pos);
        nsIDOMRange_GetCollapsed(This->nsrange, &collapsed);

        if(Count > 0) {
            *ActualCount = move_next_chars(Count, &end_pos, collapsed, NULL, NULL, &new_pos);
            set_range_pos(This, FALSE, &new_pos);
        }else {
            BOOL bounded;

            *ActualCount = -move_prev_chars(This, -Count, &end_pos, TRUE, &start_pos, &bounded, &new_pos);
            set_range_pos(This, bounded, &new_pos);
            if(bounded)
                IHTMLTxtRange_collapse(&This->IHTMLTxtRange_iface, TRUE);
        }

        dompos_release(&start_pos);
        dompos_release(&end_pos);
        dompos_release(&new_pos);
        break;
    }

    default:
        FIXME("unimplemented unit %s\n", debugstr_w(Unit));
    }

    return S_OK;
}

static HRESULT WINAPI HTMLTxtRange_select(IHTMLTxtRange *iface)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    nsISelection *nsselection;
    nsresult nsres;

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

    nsres = nsIDOMWindow_GetSelection(This->doc->basedoc.window->nswindow, &nsselection);
    if(NS_FAILED(nsres)) {
        ERR("GetSelection failed: %08x\n", nsres);
        return E_FAIL;
    }

    nsISelection_RemoveAllRanges(nsselection);
    nsISelection_AddRange(nsselection, This->nsrange);
    nsISelection_Release(nsselection);
    return S_OK;
}

static HRESULT WINAPI HTMLTxtRange_pasteHTML(IHTMLTxtRange *iface, BSTR html)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(html));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_moveToElementText(IHTMLTxtRange *iface, IHTMLElement *element)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%p)\n", This, element);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_setEndPoint(IHTMLTxtRange *iface, BSTR how,
        IHTMLTxtRange *SourceRange)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(how), SourceRange);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_compareEndPoints(IHTMLTxtRange *iface, BSTR how,
        IHTMLTxtRange *SourceRange, LONG *ret)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    HTMLTxtRange *src_range;
    PRInt16 nsret = 0;
    int nscmpt;
    nsresult nsres;

    TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(how), SourceRange, ret);

    nscmpt = string_to_nscmptype(how);
    if(nscmpt == -1)
        return E_INVALIDARG;

    src_range = get_range_object(This->doc, SourceRange);
    if(!src_range)
        return E_FAIL;

    nsres = nsIDOMRange_CompareBoundaryPoints(This->nsrange, nscmpt, src_range->nsrange, &nsret);
    if(NS_FAILED(nsres))
        ERR("CompareBoundaryPoints failed: %08x\n", nsres);

    *ret = nsret;
    return S_OK;
}

static HRESULT WINAPI HTMLTxtRange_findText(IHTMLTxtRange *iface, BSTR String,
        LONG count, LONG Flags, VARIANT_BOOL *Success)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%s %d %08x %p)\n", This, debugstr_w(String), count, Flags, Success);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_moveToPoint(IHTMLTxtRange *iface, LONG x, LONG y)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%d %d)\n", This, x, y);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_getBookmark(IHTMLTxtRange *iface, BSTR *Bookmark)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%p)\n", This, Bookmark);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_moveToBookmark(IHTMLTxtRange *iface, BSTR Bookmark,
        VARIANT_BOOL *Success)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(Bookmark), Success);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_queryCommandSupported(IHTMLTxtRange *iface, BSTR cmdID,
        VARIANT_BOOL *pfRet)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_queryCommandEnabled(IHTMLTxtRange *iface, BSTR cmdID,
        VARIANT_BOOL *pfRet)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_queryCommandState(IHTMLTxtRange *iface, BSTR cmdID,
        VARIANT_BOOL *pfRet)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_queryCommandIndeterm(IHTMLTxtRange *iface, BSTR cmdID,
        VARIANT_BOOL *pfRet)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_queryCommandText(IHTMLTxtRange *iface, BSTR cmdID,
        BSTR *pcmdText)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pcmdText);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_queryCommandValue(IHTMLTxtRange *iface, BSTR cmdID,
        VARIANT *pcmdValue)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pcmdValue);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_execCommand(IHTMLTxtRange *iface, BSTR cmdID,
        VARIANT_BOOL showUI, VARIANT value, VARIANT_BOOL *pfRet)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%s %x v %p)\n", This, debugstr_w(cmdID), showUI, pfRet);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLTxtRange_execCommandShowHelp(IHTMLTxtRange *iface, BSTR cmdID,
        VARIANT_BOOL *pfRet)
{
    HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface);
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
    return E_NOTIMPL;
}

static const IHTMLTxtRangeVtbl HTMLTxtRangeVtbl = {
    HTMLTxtRange_QueryInterface,
    HTMLTxtRange_AddRef,
    HTMLTxtRange_Release,
    HTMLTxtRange_GetTypeInfoCount,
    HTMLTxtRange_GetTypeInfo,
    HTMLTxtRange_GetIDsOfNames,
    HTMLTxtRange_Invoke,
    HTMLTxtRange_get_htmlText,
    HTMLTxtRange_put_text,
    HTMLTxtRange_get_text,
    HTMLTxtRange_parentElement,
    HTMLTxtRange_duplicate,
    HTMLTxtRange_inRange,
    HTMLTxtRange_isEqual,
    HTMLTxtRange_scrollIntoView,
    HTMLTxtRange_collapse,
    HTMLTxtRange_expand,
    HTMLTxtRange_move,
    HTMLTxtRange_moveStart,
    HTMLTxtRange_moveEnd,
    HTMLTxtRange_select,
    HTMLTxtRange_pasteHTML,
    HTMLTxtRange_moveToElementText,
    HTMLTxtRange_setEndPoint,
    HTMLTxtRange_compareEndPoints,
    HTMLTxtRange_findText,
    HTMLTxtRange_moveToPoint,
    HTMLTxtRange_getBookmark,
    HTMLTxtRange_moveToBookmark,
    HTMLTxtRange_queryCommandSupported,
    HTMLTxtRange_queryCommandEnabled,
    HTMLTxtRange_queryCommandState,
    HTMLTxtRange_queryCommandIndeterm,
    HTMLTxtRange_queryCommandText,
    HTMLTxtRange_queryCommandValue,
    HTMLTxtRange_execCommand,
    HTMLTxtRange_execCommandShowHelp
};

static inline HTMLTxtRange *impl_from_IOleCommandTarget(IOleCommandTarget *iface)
{
    return CONTAINING_RECORD(iface, HTMLTxtRange, IOleCommandTarget_iface);
}

static HRESULT WINAPI RangeCommandTarget_QueryInterface(IOleCommandTarget *iface, REFIID riid, void **ppv)
{
    HTMLTxtRange *This = impl_from_IOleCommandTarget(iface);
    return IHTMLTxtRange_QueryInterface(&This->IHTMLTxtRange_iface, riid, ppv);
}

static ULONG WINAPI RangeCommandTarget_AddRef(IOleCommandTarget *iface)
{
    HTMLTxtRange *This = impl_from_IOleCommandTarget(iface);
    return IHTMLTxtRange_AddRef(&This->IHTMLTxtRange_iface);
}

static ULONG WINAPI RangeCommandTarget_Release(IOleCommandTarget *iface)
{
    HTMLTxtRange *This = impl_from_IOleCommandTarget(iface);
    return IHTMLTxtRange_Release(&This->IHTMLTxtRange_iface);
}

static HRESULT WINAPI RangeCommandTarget_QueryStatus(IOleCommandTarget *iface, const GUID *pguidCmdGroup,
        ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
{
    HTMLTxtRange *This = impl_from_IOleCommandTarget(iface);
    FIXME("(%p)->(%s %d %p %p)\n", This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
    return E_NOTIMPL;
}

static HRESULT exec_indent(HTMLTxtRange *This, VARIANT *in, VARIANT *out)
{
    nsIDOMHTMLElement *blockquote_elem, *p_elem;
    nsIDOMDocumentFragment *fragment;
    nsIDOMNode *tmp;

    static const PRUnichar blockquoteW[] = {'B','L','O','C','K','Q','U','O','T','E',0};
    static const PRUnichar pW[] = {'P',0};

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

    if(!This->doc->nsdoc) {
        WARN("NULL nsdoc\n");
        return E_NOTIMPL;
    }

    create_nselem(This->doc, blockquoteW, &blockquote_elem);
    create_nselem(This->doc, pW, &p_elem);

    nsIDOMRange_ExtractContents(This->nsrange, &fragment);
    nsIDOMElement_AppendChild(p_elem, (nsIDOMNode*)fragment, &tmp);
    nsIDOMDocumentFragment_Release(fragment);
    nsIDOMNode_Release(tmp);

    nsIDOMElement_AppendChild(blockquote_elem, (nsIDOMNode*)p_elem, &tmp);
    nsIDOMElement_Release(p_elem);
    nsIDOMNode_Release(tmp);

    nsIDOMRange_InsertNode(This->nsrange, (nsIDOMNode*)blockquote_elem);
    nsIDOMElement_Release(blockquote_elem);

    return S_OK;
}

static HRESULT WINAPI RangeCommandTarget_Exec(IOleCommandTarget *iface, const GUID *pguidCmdGroup,
        DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
{
    HTMLTxtRange *This = impl_from_IOleCommandTarget(iface);

    TRACE("(%p)->(%s %d %x %p %p)\n", This, debugstr_guid(pguidCmdGroup), nCmdID,
          nCmdexecopt, pvaIn, pvaOut);

    if(pguidCmdGroup && IsEqualGUID(&CGID_MSHTML, pguidCmdGroup)) {
        switch(nCmdID) {
        case IDM_INDENT:
            return exec_indent(This, pvaIn, pvaOut);
        default:
            FIXME("Unsupported cmdid %d of CGID_MSHTML\n", nCmdID);
        }
    }else {
        FIXME("Unsupported cmd %d of group %s\n", nCmdID, debugstr_guid(pguidCmdGroup));
    }

    return E_NOTIMPL;
}

static const IOleCommandTargetVtbl OleCommandTargetVtbl = {
    RangeCommandTarget_QueryInterface,
    RangeCommandTarget_AddRef,
    RangeCommandTarget_Release,
    RangeCommandTarget_QueryStatus,
    RangeCommandTarget_Exec
};

HRESULT HTMLTxtRange_Create(HTMLDocumentNode *doc, nsIDOMRange *nsrange, IHTMLTxtRange **p)
{
    HTMLTxtRange *ret;

    ret = heap_alloc(sizeof(HTMLTxtRange));
    if(!ret)
        return E_OUTOFMEMORY;

    ret->IHTMLTxtRange_iface.lpVtbl = &HTMLTxtRangeVtbl;
    ret->IOleCommandTarget_iface.lpVtbl = &OleCommandTargetVtbl;
    ret->ref = 1;

    if(nsrange)
        nsIDOMRange_AddRef(nsrange);
    ret->nsrange = nsrange;

    ret->doc = doc;
    list_add_head(&doc->range_list, &ret->entry);

    *p = &ret->IHTMLTxtRange_iface;
    return S_OK;
}

void detach_ranges(HTMLDocumentNode *This)
{
    HTMLTxtRange *iter;

    LIST_FOR_EACH_ENTRY(iter, &This->range_list, HTMLTxtRange, entry) {
        iter->doc = NULL;
    }
}
