// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#include "WordBookmark.h"
#include "WordLenses.h"
#include "DFDOM.h"
#include "WordPackage.h"
#include "WordField.h"
#include "WordObjects.h"
#include "WordCaption.h"
#include "WordSheet.h"
#include "DFHTML.h"
#include "DFString.h"
#include "DFCommon.h"
#include "DFPlatform.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>

static void findTargetAndType(WordBookmark *bookmark, WordSheet *sheet);
void findLabel(WordBookmark *bookmark);

////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                //
//                                          WordBookmark                                          //
//                                                                                                //
////////////////////////////////////////////////////////////////////////////////////////////////////

const char *WordBookmarkTypeString(WordBookmarkType type)
{
    switch (type) {
        case WordBookmarkCursor:
            return "Cursor";
        case WordBookmarkHeading:
            return "Heading";
        case WordBookmarkTable:
            return "Table";
        case WordBookmarkFigure:
            return "Figure";
        case WordBookmarkEquation:
            return "Equation";
        default:
            return "Unknown";
    }
}

int WordBookmarkTypeHasLabel(WordBookmarkType type)
{
    switch (type) {
        case WordBookmarkHeading:
        case WordBookmarkTable:
        case WordBookmarkFigure:
            return 1;
        default:
            return 0;
    }
}

WordBookmark *WordBookmarkNew(const char *bookmarkId1, const char *bookmarkName1)
{
    WordBookmark *bookmark = (WordBookmark *)xcalloc(1,sizeof(WordBookmark));
    bookmark->retainCount = 1;
    bookmark->bookmarkId = (bookmarkId1 != NULL) ? xstrdup(bookmarkId1) : NULL;
    bookmark->bookmarkName = (bookmarkName1 != NULL) ? xstrdup(bookmarkName1) : NULL;
    bookmark->type = WordBookmarkUnknown;
    return bookmark;
}

WordBookmark *WordBookmarkRetain(WordBookmark *bookmark)
{
    if (bookmark != NULL)
        bookmark->retainCount++;
    return bookmark;
}

void WordBookmarkRelease(WordBookmark *bookmark)
{
    if ((bookmark == NULL) || (--bookmark->retainCount > 0))
        return;

    free(bookmark->bookmarkId);
    free(bookmark->bookmarkName);
    free(bookmark->label);
    free(bookmark);
}

void WordBookmarkAnalyze(WordBookmark *bookmark, WordSheet *sheet)
{
    // FIXME: Check if the following line is still relevant with the new bookmarks model
    if (bookmark->element == NULL) // new bookmark
        return;
    findTargetAndType(bookmark,sheet);
    findLabel(bookmark);
}

static void findAllNodes(DFNode *node, DFArray *result)
{
    if (node->tag == WORD_PPR)
        return;
    for (DFNode *child = node->first; child != NULL; child = child->next) {
        DFArrayAppend(result,child);
        findAllNodes(child,result);
    }
}

CaptionParts WordBookmarkGetCaptionParts(WordBookmark *bookmark)
{
    CaptionParts parts;
    parts.beforeNum = 0;
    parts.num = 0;
    parts.afterNum = 0;

    // FIXME: Check if the following line is still relevant with the new bookmarks model
    if (bookmark->element == NULL)
        return parts;;

    DFArray *nodes = DFArrayNew(NULL,NULL);
    findAllNodes(bookmark->element,nodes);

    for (size_t i = 0; i < DFArrayCount(nodes); i++) {
        DFNode *node = DFArrayItemAt(nodes,i);
        if (node->tag == WORD_FLDSIMPLE) {
            const char *instr = DFGetAttribute(node,WORD_INSTR);
            if (instr != NULL) {
                const char **args = Word_parseField(instr);
                if ((args[0] != NULL) && !strcmp(args[0],"SEQ"))
                    parts.num = 1;
                free(args);
            }
        }
        else if (node->tag != WORD_BOOKMARK) {
            if (!parts.num)
                parts.beforeNum = 1;
            else
                parts.afterNum = 1;
        }
    }
    DFArrayRelease(nodes);

    return parts;
}

void findLabel(WordBookmark *bookmark)
{
    // FIXME: Not covered by tests
    DFBuffer *buffer = DFBufferNew();
    for (DFNode *child = bookmark->element->first; child != NULL; child = child->next) {
        // FIXME: handle inserted and deleted text
        if (child->tag == WORD_R)
            DFNodeTextToBuffer(child,buffer);
    }
    free(bookmark->label);
    bookmark->label = xstrdup(buffer->data);
    DFBufferRelease(buffer);
}

static int isHeadingOutlineLvl(const char *outlineLvl)
{
    if ((outlineLvl == NULL) || (strlen(outlineLvl) == 0))
        return 0;
    else
        return (atoi(outlineLvl) != 9);
}

static DFNode *findPreviousElement(DFNode *node)
{
    node = node->prev;
    while ((node != NULL) && (node->tag < MIN_ELEMENT_TAG))
        node = node->prev;
    return node;
}

static void findTargetAndType(WordBookmark *bookmark, WordSheet *sheet)
{
    if (DFStringEquals(bookmark->bookmarkName,"_GoBack")) {
        bookmark->type = WordBookmarkCursor;
        bookmark->target = NULL;
        return;
    }
    // FIXME: Check if the following line is still relevant with the new bookmarks model
    assert(bookmark->element != NULL);
    DFNode *p = WordFindContainingParagraph(bookmark->element);
    if (p == NULL)
        return;;
    DFNode *pPr = DFChildWithTag(p,WORD_PPR);
    if (pPr == NULL)
        return;;
    DFNode *pStyle = DFChildWithTag(pPr,WORD_PSTYLE);
    if (pStyle == NULL)
        return;;
    const char *styleId = DFGetAttribute(pStyle,WORD_VAL);
    if (styleId == NULL)
        return;;
    WordStyle *style = WordSheetStyleForTypeId(sheet,"paragraph",styleId);
    if ((style != NULL) && isHeadingOutlineLvl(style->outlineLvl)) {
        bookmark->type = WordBookmarkHeading;
        bookmark->target = p;
    }
    else if (DFStringEquals(styleId,"Caption")) {
        DFNode *prev = findPreviousElement(p);
        if (prev == NULL)
            return;

        if (prev->tag == WORD_TBL) {
            bookmark->type = WordBookmarkTable;
            bookmark->target = prev;
        }
        else if (Word_isFigureParagraph(prev)) {
            bookmark->type = WordBookmarkFigure;
            bookmark->target = prev;
        }
        else if (Word_isEquationParagraph(prev)) {
            bookmark->type = WordBookmarkEquation;
            bookmark->target = prev;
        }
    }
}

DFNode *WordFindContainingParagraph(DFNode *node)
{
    while ((node != NULL) && (node->tag != WORD_P))
        node = node->parent;
    return node;
}

// References: String (id attribute) -> DFArray of A Element objects

static void findReferencesRecursive(DFNode *node, DFHashTable *referencesById)
{
    if (node->tag == HTML_A) {
        const char *href = DFGetAttribute(node,HTML_HREF);
        if ((href != NULL) && (href[0] == '#')) {
            const char *targetId = &href[1];
            DFArray *links = DFHashTableLookup(referencesById,targetId);
            if (links == NULL) {
                links = DFArrayNew(NULL,NULL);
                DFHashTableAdd(referencesById,targetId,links);
                DFArrayRelease(links);
            }
            DFArrayAppend(links,node);
        }
    }
    for (DFNode *child = node->first; child != NULL; child = child->next)
        findReferencesRecursive(child,referencesById);
}

static DFHashTable *findReferences(DFDocument *doc)
{
    DFHashTable *references = DFHashTableNew((DFCopyFunction)DFArrayRetain,(DFFreeFunction)DFArrayRelease);
    findReferencesRecursive(doc->docNode,references);
    return references;
}

static WordBookmark *createBookmark(WordPutData *put)
{
    WordBookmark *bookmark = WordObjectsAddBookmark(put->conv->objects);
    DFNode *bookmarkSpan = DFCreateElement(put->conv->html,HTML_SPAN);
    DFSetAttribute(bookmarkSpan,HTML_CLASS,DFBookmarkClass);
    DFSetAttribute(bookmarkSpan,WORD_NAME,bookmark->bookmarkName);
    DFSetAttribute(bookmarkSpan,WORD_ID,bookmark->bookmarkId);
    bookmark->element = bookmarkSpan;
    return bookmark;
}

void Word_setupBookmarkLinks(WordPutData *put)
{
    DFHashTable *referencesById = findReferences(put->conv->html);
    const char **sortedIds = DFHashTableCopyKeys(referencesById);
    DFSortStringsCaseSensitive(sortedIds);
    for (int idIndex = 0; sortedIds[idIndex]; idIndex++) {
        const char *targetId = sortedIds[idIndex];
        DFArray *references = DFHashTableLookup(referencesById,targetId);
        DFNode *targetElem = DFElementForIdAttr(put->conv->html,targetId);
        if (targetElem == NULL)
            continue;

        // The following is only relevant for figures and tables
        int refText = 0;
        int refLabelNum = 0;
        int refCaptionText = 0;

        for (size_t refIndex = 0; refIndex < DFArrayCount(references); refIndex++) {
            DFNode *a = DFArrayItemAt(references,refIndex);
            const char *className = DFGetAttribute(a,HTML_CLASS);
            if (DFStringEquals(className,DFRefTextClass))
                refText = 1;
            else if (DFStringEquals(className,DFRefLabelNumClass))
                refLabelNum = 1;
            else if (DFStringEquals(className,DFRefCaptionTextClass))
                refCaptionText = 1;
        }

        DFNode *concrete = WordConverterGetConcrete(put,targetElem);
        switch (targetElem->tag) {
            case HTML_H1:
            case HTML_H2:
            case HTML_H3:
            case HTML_H4:
            case HTML_H5:
            case HTML_H6: {
                const char *bookmarkId = NULL;
                const char *bookmarkName = NULL;
                DFNode *bookmarkElem = NULL;
                if ((concrete != NULL) && (concrete->tag == WORD_P)) {

                    // FIXME: We only want to consider the bookmark to be the headings "correct"
                    // bookmark in the case where it contains all of the heading's content, though
                    // excluding other bookmarks that might come before or after it.

                    // If you have the cursor inside a heading bookmark when you save the document,
                    // word puts a bookmark called _GoBack there, and we of course don't want to
                    // confuse that with the actual heading's bookmark (if any).

                    // For now as a temporary hack we just explicitly filter out _GoBack; but there
                    // needs to be a more general fix, as there may be other bookmarks that end up
                    // in the heading.

                    for (DFNode *child = concrete->first; child != NULL; child = child->next) {
                        if ((child->tag == WORD_BOOKMARK) &&
                            !DFStringEquals(DFGetAttribute(child,WORD_NAME),"_GoBack")) {
                            bookmarkElem = child;
                            bookmarkId = DFGetAttribute(bookmarkElem,WORD_ID);
                            bookmarkName = DFGetAttribute(bookmarkElem,WORD_NAME);
                            break;
                        }
                    }
                }

                if ((bookmarkElem == NULL) || (bookmarkId == NULL) || (bookmarkName == NULL)) {
                    // New bookmark
                    WordBookmark *bookmark = WordObjectsAddBookmark(put->conv->objects);
                    bookmarkId =bookmark->bookmarkId;
                    bookmarkName = bookmark->bookmarkName;
                }

                DFNode *bookmarkSpan = DFCreateElement(put->conv->html,HTML_SPAN);
                DFSetAttribute(bookmarkSpan,HTML_CLASS,DFBookmarkClass);

                if (bookmarkElem != NULL) {
                    // FIXME: Not covered by tests
                    DFFormatAttribute(bookmarkSpan,HTML_ID,"%s%u",put->conv->idPrefix,bookmarkElem->seqNo);
                }

                DFSetAttribute(bookmarkSpan,WORD_NAME,bookmarkName);
                DFSetAttribute(bookmarkSpan,WORD_ID,bookmarkId);

                while (targetElem->first != NULL)
                    DFAppendChild(bookmarkSpan,targetElem->first);
                DFAppendChild(targetElem,bookmarkSpan);

                break;
            }
            case HTML_TABLE:
            case HTML_FIGURE: {
                WordCaption *caption = WordObjectsCaptionForTarget(put->conv->objects,targetElem);
                if (caption == NULL)
                    break;

                assert(caption->element != NULL);
                assert((caption->number == NULL) || (caption->number->parent == caption->element));
                assert((caption->contentStart == NULL) || (caption->contentStart->parent == caption->element));

                // Note: caption.number may be null (i.e. if the caption is unnumbered)
                //       caption.contentStart may be null (if there is no text in the caption)

                WordBookmark *captionTextBookmark = NULL;
                WordBookmark *labelNumBookmark = NULL;
                WordBookmark *textBookmark = NULL;

                if (!refCaptionText && !refLabelNum && !refText)
                    refText = 1;

                if (refCaptionText) {
                    captionTextBookmark = createBookmark(put);
                    DFNode *nnext;
                    for (DFNode *n = caption->contentStart; n != NULL; n = nnext) {
                        nnext = n->next;
                        DFAppendChild(captionTextBookmark->element,n);
                    }
                    DFAppendChild(caption->element,captionTextBookmark->element);
                }
                if (refLabelNum && (caption->number != NULL)) {
                    labelNumBookmark = createBookmark(put);
                    DFNode *numberNext = caption->number->next;
                    DFNode *nnext;
                    for (DFNode *n = caption->element->first; (n != NULL) && (n != numberNext); n = nnext) {
                        nnext = n->next;
                        DFAppendChild(labelNumBookmark->element,n);
                    }
                    DFInsertBefore(caption->element,labelNumBookmark->element,caption->element->first);
                }
                if (refText) {
                    textBookmark = createBookmark(put);
                    DFNode *nnext;
                    for (DFNode *n = caption->element->first; n != NULL; n = nnext) {
                        nnext = n->next;
                        DFAppendChild(textBookmark->element,n);
                    }
                    DFAppendChild(caption->element,textBookmark->element);
                }

                caption->captionTextBookmark = captionTextBookmark;
                caption->labelNumBookmark = labelNumBookmark;
                caption->textBookmark = textBookmark;

                break;
            }
        }
    }
    free(sortedIds);
    DFHashTableRelease(referencesById);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                //
//                                         WordRawBookmark                                        //
//                                                                                                //
////////////////////////////////////////////////////////////////////////////////////////////////////

typedef struct WordRawBookmark WordRawBookmark;

struct WordRawBookmark {
    DFNode *startElement;
    DFNode *endElement;
    int startOffset;
    int endOffset;
};

WordRawBookmark *WordRawBookmarkNew(void)
{
    WordRawBookmark *bookmark = (WordRawBookmark *)xcalloc(1,sizeof(WordRawBookmark));
    bookmark->startOffset = -1;
    bookmark->endOffset = -1;
    return bookmark;
}

void WordRawBookmarkFree(WordRawBookmark *bookmark)
{
    free(bookmark);
}

int WordRawBookmarkSize(WordRawBookmark *bookmark)
{
    if ((bookmark->startOffset >= 0) && (bookmark->endOffset >= 0) && (bookmark->endOffset >= bookmark->startOffset))
        return bookmark->endOffset - bookmark->startOffset;
    else
        return -1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                //
//                                       Bookmark collapsing                                      //
//                                                                                                //
////////////////////////////////////////////////////////////////////////////////////////////////////

static void findBookmarkSizes(DFNode *node, DFHashTable *bookmarksById, int *offset)
{
    switch (node->tag) {
        case WORD_BOOKMARKSTART:
        case WORD_BOOKMARKEND: {
            const char *bookmarkId = DFGetAttribute(node,WORD_ID);
            if (bookmarkId == NULL)
                bookmarkId = "";;
            WordRawBookmark *bookmark = DFHashTableLookup(bookmarksById,bookmarkId);
            if (bookmark == NULL) {
                bookmark = WordRawBookmarkNew();
                DFHashTableAdd(bookmarksById,bookmarkId,bookmark);
            }
            if (node->tag == WORD_BOOKMARKSTART) {
                bookmark->startElement = node;
                bookmark->startOffset = *offset;
            }
            else {
                bookmark->endElement = node;
                bookmark->endOffset = *offset;
            }
            break;
        }
        default:
            (*offset)++;
            break;
    }

    for (DFNode *child = node->first; child != NULL; child = child->next) {
        findBookmarkSizes(child,bookmarksById,offset);
    }
}

static int compareStartElements(void *thunk, const void *obj1, const void *obj2)
{
    DFHashTable *bookmarksById = (DFHashTable *)thunk;
    DFNode *element1 = *(DFNode **)obj1;
    DFNode *element2 = *(DFNode **)obj2;
    const char *id1 = DFGetAttribute(element1,WORD_ID);
    const char *id2 = DFGetAttribute(element2,WORD_ID);
    if (id1 == NULL)
        id1 = "";
    if (id2 == NULL)
        id2 = "";;
    WordRawBookmark *bookmark1 = DFHashTableLookup(bookmarksById,id1);
    WordRawBookmark *bookmark2 = DFHashTableLookup(bookmarksById,id2);
    int size1 = WordRawBookmarkSize(bookmark1);
    int size2 = WordRawBookmarkSize(bookmark2);

    if (size1 > size2)
        return -1;
    else if (size1 < size2)
        return 1;
    else
        return DFStringCompare(id1,id2);
}

static void collapseRecursive(DFNode *node, DFHashTable *bookmarksById)
{

    DFNode *next;
    for (DFNode *child = node->first; child != NULL; child = next) {
        next = child->next;

        switch (child->tag) {
            case WORD_BOOKMARKSTART:
            case WORD_BOOKMARKEND: {
                DFArray *startElements = DFArrayNew(NULL,NULL);
                DFArray *endElements = DFArrayNew(NULL,NULL);
                DFHashTable *startIds = DFHashTableNew((DFCopyFunction)xstrdup,(DFFreeFunction)free);
                DFHashTable *endIds = DFHashTableNew((DFCopyFunction)xstrdup,(DFFreeFunction)free);
                DFNode *n;
                for (n = child;
                     (n != NULL) && ((n->tag == WORD_BOOKMARKSTART) || (n->tag == WORD_BOOKMARKEND));
                     n = n->next) {

                    if (n->tag == WORD_BOOKMARKSTART) {
                        const char *idValue = DFGetAttribute(n,WORD_ID);
                        if (idValue == NULL)
                            idValue = "";

                        DFHashTableAdd(startIds,idValue,idValue);
                        DFArrayAppend(startElements,n);
                    }
                    else {
                        const char *idValue = DFGetAttribute(n,WORD_ID);
                        if (idValue == NULL)
                            idValue = "";

                        DFHashTableAdd(endIds,idValue,idValue);
                        DFArrayAppend(endElements,n);
                    }
                }
                next = n;

                DFArraySort(startElements,bookmarksById,compareStartElements);

                for (size_t endIndex = 0; endIndex < DFArrayCount(endElements); endIndex++) {
                    DFNode *elem = DFArrayItemAt(endElements,endIndex);
                    const char *endId = DFGetAttribute(elem,WORD_ID);
                    int found = 0;
                    DFNode *ancestor;
                    for (ancestor = elem->parent; (ancestor != NULL) && !found; ancestor = ancestor->parent) {
                        if ((ancestor->tag == WORD_BOOKMARK) && DFStringEquals(DFGetAttribute(ancestor,WORD_ID),endId)) {
                            found = 1;
                            break;
                        }
                    }

                    if (found) {
                        DFNode *before = ancestor->next;
                        DFNode *nnext;
                        for (DFNode *n = child; n != NULL; n = nnext) {
                            nnext = n->next;
                            DFInsertBefore(ancestor->parent,n,before);
                        }
                    }
                }

                size_t x = 0;
                while (x < DFArrayCount(startElements)) {
                    DFNode *element = DFArrayItemAt(startElements,x);
                    const char *bookmarkId = DFGetAttribute(element,WORD_ID);
                    if (bookmarkId == NULL)
                        bookmarkId = "";
                    if (DFHashTableLookup(endIds,bookmarkId) != NULL) {
                        element->tag = WORD_BOOKMARK;
                        DFArrayRemove(startElements,x);
                    }
                    else {
                        x++;
                    }
                }

                if (DFArrayCount(startElements) > 0) {
                    for (size_t i = 1; i < DFArrayCount(startElements); i++) {
                        DFNode *tempParent = DFArrayItemAt(startElements,i-1);
                        DFNode *tempChild = DFArrayItemAt(startElements,i);
                        DFAppendChild(tempParent,tempChild);
                    }

                    DFNode *last = DFArrayItemAt(startElements,DFArrayCount(startElements)-1);
                    while (next != NULL) {
                        DFNode *tempChild = next;
                        next = next->next;
                        DFAppendChild(last,tempChild);
                    }
                }

                for (size_t eIndex = 0; eIndex < DFArrayCount(startElements); eIndex++) {
                    DFNode *e = DFArrayItemAt(startElements,eIndex);
                    e->tag = WORD_BOOKMARK;
                }
                for (size_t eIndex = 0; eIndex < DFArrayCount(endElements); eIndex++) {
                    DFNode *e = DFArrayItemAt(endElements,eIndex);
                    DFRemoveNode(e);
                }

                if (DFArrayCount(startElements) > 0) {
                    DFNode *last = DFArrayItemAt(startElements,DFArrayCount(startElements)-1);
                    collapseRecursive(last,bookmarksById);
                }

                DFArrayRelease(startElements);
                DFArrayRelease(endElements);
                DFHashTableRelease(startIds);
                DFHashTableRelease(endIds);
                break;
            }
            default:
                collapseRecursive(child,bookmarksById);
                break;
        }
    }
}

static DFNode *findParagraphBackwards(DFNode *node)
{
    do {
        node = DFPrevNode(node);
    }
    while ((node != NULL) && (node->tag != WORD_P));
    return node;
}

static DFNode *findParagraphForwards(DFNode *node)
{
    do {
        node = DFNextNode(node);
    }
    while ((node != NULL) && (node->tag != WORD_P));
    return node;
}

static void putInParagraphsRecursive(DFNode *node)
{
    DFNode *next;
    for (DFNode *child = node->first; child != NULL; child = next) {
        next = child->next;
        putInParagraphsRecursive(child);
    }

    if (((node->tag == WORD_BOOKMARKSTART) || (node->tag == WORD_BOOKMARKEND)) &&
        (node->parent->tag != WORD_P)) {
        DFNode *forwards = findParagraphForwards(node);
        if (forwards != NULL) {
            DFNode *pPr = DFChildWithTag(forwards,WORD_PPR);
            if (pPr != NULL)
                DFInsertBefore(forwards,node,pPr->next);
            else
                DFInsertBefore(forwards,node,forwards->first);
            return;
        }

        DFNode *backwards = findParagraphBackwards(node);
        if (backwards != NULL) {
            DFAppendChild(backwards,node);
            return;
        }

        DFRemoveNode(node);
    }
}

void WordBookmarks_collapseNew(DFDocument *doc)
{
    putInParagraphsRecursive(doc->docNode);
    DFHashTable *bookmarksById = DFHashTableNew(NULL,(DFFreeFunction)WordRawBookmarkFree);
    int offset = 0;
    findBookmarkSizes(doc->root,bookmarksById,&offset);
    collapseRecursive(doc->root,bookmarksById);
    DFHashTableRelease(bookmarksById);
}

static void expandRecursive(DFNode *node)
{
    DFNode *next;
    for (DFNode *child = node->first; child != NULL; child = next) {
        next = child->next;
        expandRecursive(child);
    }

    if (node->tag == WORD_BOOKMARK) {
        const char *bookmarkId = DFGetAttribute(node,WORD_ID);
        const char *bookmarkName = DFGetAttribute(node,WORD_NAME);
        if (bookmarkId == NULL)
            bookmarkId = "";
        if (bookmarkName == NULL)
            bookmarkName = "";;
        DFNode *startElem = DFCreateElement(node->doc,WORD_BOOKMARKSTART);
        DFNode *endElem = DFCreateElement(node->doc,WORD_BOOKMARKEND);
        DFSetAttribute(startElem,WORD_ID,bookmarkId);
        DFSetAttribute(startElem,WORD_NAME,bookmarkName);
        DFSetAttribute(endElem,WORD_ID,bookmarkId);
        DFInsertBefore(node->parent,startElem,node);
        DFInsertBefore(node->parent,endElem,node->next);
        DFRemoveNodeButKeepChildren(node);
    }
}

void WordBookmarks_expandNew(DFDocument *doc)
{
    expandRecursive(doc->docNode);
}

static void removeCaptionBookmarksRecursive(DFNode *node, int inCaption)
{
    if (node->tag == WORD_P) {
        DFNode *pPr = DFChildWithTag(node,WORD_PPR);
        const char *styleId = DFGetChildAttribute(pPr,WORD_PSTYLE,WORD_VAL);
        if (DFStringEquals(styleId,"Caption"))
            inCaption = 1;
    }

    DFNode *next;
    for (DFNode *child = node->first; child != NULL; child = next) {
        next = child->next;
        removeCaptionBookmarksRecursive(child,inCaption);
    }

    if (inCaption) {
        switch (node->tag) {
            case WORD_BOOKMARKSTART:
            case WORD_BOOKMARKEND:
            case WORD_BOOKMARK:
                DFRemoveNodeButKeepChildren(node);
                break;
        }
    }
}

void WordBookmarks_removeCaptionBookmarks(DFDocument *doc)
{
    removeCaptionBookmarksRecursive(doc->docNode,0);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                //
//                                        WordBookmarkLens                                        //
//                                                                                                //
////////////////////////////////////////////////////////////////////////////////////////////////////

static int WordBookmarkIsVisible2(DFNode *concrete);

static DFNode *WordBookmarkGet(WordGetData *get, DFNode *concrete)
{
    if (!WordBookmarkIsVisible2(concrete))
        return NULL;;
    DFNode *abstract = WordConverterCreateAbstract(get,HTML_SPAN,concrete);
    DFSetAttribute(abstract,HTML_CLASS,DFBookmarkClass);
    WordContainerGet(get,&WordParagraphContentLens,abstract,concrete);
    return abstract;
}

static int WordBookmarkIsVisible2(DFNode *concrete)
{
    const char *name = DFGetAttribute(concrete,WORD_NAME);

    if (name == NULL)
        return 0;

    if (DFStringEquals(name,"_GoBack") && (concrete->first == NULL))
        return 0;

    return 1;
}

static int WordBookmarkIsVisible(WordPutData *put, DFNode *concrete)
{
    return WordBookmarkIsVisible2(concrete);
}

static void WordBookmarkPut(WordPutData *put, DFNode *abstract, DFNode *concrete)
{
    WordContainerPut(put,&WordParagraphContentLens,abstract,concrete);
}

static void WordBookmarkRemove(WordPutData *put, DFNode *concrete)
{
    for (DFNode *child = concrete->first; child != NULL; child = child->next)
        WordParagraphContentLens.remove(put,child);
}

WordLens WordBookmarkLens = {
    .isVisible = WordBookmarkIsVisible,
    .get = WordBookmarkGet,
    .put = WordBookmarkPut,
    .create = NULL, // LENS FIXME
    .remove = WordBookmarkRemove,
};
