/*
 * Copyright 2007 Jacek Caban for CodeWeavers
 * Copyright 2010 Erich Hoover
 *
 * 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
 */

#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "hhctrl.h"
#include "stream.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp);

/* Fill the TreeView object corresponding to the Index items */
static void fill_index_tree(HWND hwnd, IndexItem *item)
{
    int index = 0;
    LVITEMW lvi;

    while(item) {
        TRACE("tree debug: %s\n", debugstr_w(item->keyword));

        if(!item->keyword)
        {
            FIXME("HTML Help index item has no keyword.\n");
            item = item->next;
            continue;
        }
        memset(&lvi, 0, sizeof(lvi));
        lvi.iItem = index++;
        lvi.mask = LVIF_TEXT|LVIF_PARAM|LVIF_INDENT;
        lvi.iIndent = item->indentLevel;
        lvi.cchTextMax = strlenW(item->keyword)+1;
        lvi.pszText = item->keyword;
        lvi.lParam = (LPARAM)item;
        item->id = (HTREEITEM)SendMessageW(hwnd, LVM_INSERTITEMW, 0, (LPARAM)&lvi);
        item = item->next;
    }
}

/* Parse the attributes correspond to a list item, including sub-topics.
 *
 * Each list item has, at minimum, a param of type "keyword" and two
 * parameters corresponding to a "sub-topic."  For each sub-topic there
 * must be a "name" param and a "local" param, if there is only one
 * sub-topic then there isn't really a sub-topic, the index will jump
 * directly to the requested item.
 */
static void parse_index_obj_node_param(IndexItem *item, const char *text)
{
    const char *ptr;
    LPWSTR *param;
    int len, wlen;

    ptr = get_attr(text, "name", &len);
    if(!ptr) {
        WARN("name attr not found\n");
        return;
    }

    /* Allocate a new sub-item, either on the first run or whenever a
     * sub-topic has filled out both the "name" and "local" params.
     */
    if(item->itemFlags == 0x11 && (!strncasecmp("name", ptr, len) || !strncasecmp("local", ptr, len))) {
        item->nItems++;
        item->items = heap_realloc(item->items, sizeof(IndexSubItem)*item->nItems);
        item->items[item->nItems-1].name = NULL;
        item->items[item->nItems-1].local = NULL;
        item->itemFlags = 0x00;
    }
    if(!strncasecmp("keyword", ptr, len)) {
        param = &item->keyword;
    }else if(!item->keyword && !strncasecmp("name", ptr, len)) {
        /* Some HTML Help index files use an additional "name" parameter
         * rather than the "keyword" parameter.  In this case, the first
         * occurance of the "name" parameter is the keyword.
         */
        param = &item->keyword;
    }else if(!strncasecmp("name", ptr, len)) {
        item->itemFlags |= 0x01;
        param = &item->items[item->nItems-1].name;
    }else if(!strncasecmp("local", ptr, len)) {
        item->itemFlags |= 0x10;
        param = &item->items[item->nItems-1].local;
    }else {
        WARN("unhandled param %s\n", debugstr_an(ptr, len));
        return;
    }

    ptr = get_attr(text, "value", &len);
    if(!ptr) {
        WARN("value attr not found\n");
        return;
    }

    wlen = MultiByteToWideChar(CP_ACP, 0, ptr, len, NULL, 0);
    *param = heap_alloc((wlen+1)*sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, ptr, len, *param, wlen);
    (*param)[wlen] = 0;
}

/* Parse the object tag corresponding to a list item.
 *
 * At this step we look for all of the "param" child tags, using this information
 * to build up the information about the list item.  When we reach the </object>
 * tag we know that we've finished parsing this list item.
 */
static IndexItem *parse_index_sitemap_object(HHInfo *info, stream_t *stream)
{
    strbuf_t node, node_name;
    IndexItem *item;

    strbuf_init(&node);
    strbuf_init(&node_name);

    item = heap_alloc_zero(sizeof(IndexItem));
    item->nItems = 0;
    item->items = heap_alloc_zero(0);
    item->itemFlags = 0x11;

    while(next_node(stream, &node)) {
        get_node_name(&node, &node_name);

        TRACE("%s\n", node.buf);

        if(!strcasecmp(node_name.buf, "param")) {
            parse_index_obj_node_param(item, node.buf);
        }else if(!strcasecmp(node_name.buf, "/object")) {
            break;
        }else {
            WARN("Unhandled tag! %s\n", node_name.buf);
        }

        strbuf_zero(&node);
    }

    strbuf_free(&node);
    strbuf_free(&node_name);

    return item;
}

/* Parse the HTML list item node corresponding to a specific help entry.
 *
 * At this stage we look for the only child tag we expect to find under
 * the list item: the <OBJECT> tag.  We also only expect to find object
 * tags with the "type" attribute set to "text/sitemap".
 */
static IndexItem *parse_li(HHInfo *info, stream_t *stream)
{
    strbuf_t node, node_name;
    IndexItem *ret = NULL;

    strbuf_init(&node);
    strbuf_init(&node_name);

    while(next_node(stream, &node)) {
        get_node_name(&node, &node_name);

        TRACE("%s\n", node.buf);

        if(!strcasecmp(node_name.buf, "object")) {
            const char *ptr;
            int len;

            static const char sz_text_sitemap[] = "text/sitemap";

            ptr = get_attr(node.buf, "type", &len);

            if(ptr && len == sizeof(sz_text_sitemap)-1
               && !memcmp(ptr, sz_text_sitemap, len)) {
                ret = parse_index_sitemap_object(info, stream);
                break;
            }
        }else {
            WARN("Unhandled tag! %s\n", node_name.buf);
        }

        strbuf_zero(&node);
    }

    strbuf_free(&node);
    strbuf_free(&node_name);

    return ret;
}

/* Parse the HTML Help page corresponding to all of the Index items.
 *
 * At this high-level stage we locate out each HTML list item tag.
 * Since there is no end-tag for the <LI> item, we must hope that
 * the <LI> entry is parsed correctly or tags might get lost.
 *
 * Within each entry it is also possible to encounter an additional
 * <UL> tag.  When this occurs the tag indicates that the topics
 * contained within it are related to the parent <LI> topic and
 * should be inset by an indent.
 */
static void parse_hhindex(HHInfo *info, IStream *str, IndexItem *item)
{
    stream_t stream;
    strbuf_t node, node_name;
    int indent_level = -1;

    strbuf_init(&node);
    strbuf_init(&node_name);

    stream_init(&stream, str);

    while(next_node(&stream, &node)) {
        get_node_name(&node, &node_name);

        TRACE("%s\n", node.buf);

        if(!strcasecmp(node_name.buf, "li")) {
            item->next = parse_li(info, &stream);
            item->next->merge = item->merge;
            item = item->next;
            item->indentLevel = indent_level;
        }else if(!strcasecmp(node_name.buf, "ul")) {
            indent_level++;
        }else if(!strcasecmp(node_name.buf, "/ul")) {
            indent_level--;
        }else {
            WARN("Unhandled tag! %s\n", node_name.buf);
        }

        strbuf_zero(&node);
    }

    strbuf_free(&node);
    strbuf_free(&node_name);
}

/* Initialize the HTML Help Index tab */
void InitIndex(HHInfo *info)
{
    IStream *stream;

    info->index = heap_alloc_zero(sizeof(IndexItem));
    info->index->nItems = 0;
    SetChmPath(&info->index->merge, info->pCHMInfo->szFile, info->WinType.pszIndex);

    stream = GetChmStream(info->pCHMInfo, info->pCHMInfo->szFile, &info->index->merge);
    if(!stream) {
        TRACE("Could not get index stream\n");
        return;
    }

    parse_hhindex(info, stream, info->index);
    IStream_Release(stream);

    fill_index_tree(info->tabs[TAB_INDEX].hwnd, info->index->next);
}

/* Free all of the Index items, including all of the "sub-items" that
 * correspond to different sub-topics.
 */
void ReleaseIndex(HHInfo *info)
{
    IndexItem *item = info->index, *next;
    int i;

    /* Note: item->merge is identical for all items, only free once */
    heap_free(item->merge.chm_file);
    heap_free(item->merge.chm_index);
    while(item) {
        next = item->next;

        heap_free(item->keyword);
        for(i=0;i<item->nItems;i++) {
            heap_free(item->items[i].name);
            heap_free(item->items[i].local);
        }
        heap_free(item->items);

        item = next;
    }
}
