/*
 * Copyright 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 "hhctrl.h"
#include "stream.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp);

void strbuf_init(strbuf_t *buf)
{
    buf->size = 8;
    buf->len = 0;
    buf->buf = heap_alloc(buf->size);
}

void strbuf_zero(strbuf_t *buf)
{
    buf->len = 0;
}

void strbuf_free(strbuf_t *buf)
{
    heap_free(buf->buf);
}

void strbuf_append(strbuf_t *buf, const char *data, int len)
{
    if(buf->len+len > buf->size) {
        buf->size = buf->len+len;
        buf->buf = heap_realloc(buf->buf, buf->size);
    }

    memcpy(buf->buf+buf->len, data, len);
    buf->len += len;
}

void stream_init(stream_t *stream, IStream *str)
{
    memset(stream, 0, sizeof(stream_t));
    stream->str = str;
}

BOOL stream_chr(stream_t *stream, strbuf_t *buf, char c)
{
    BOOL b = TRUE;
    ULONG i;

    while(b) {
        for(i=stream->p; i<stream->size; i++) {
            if(stream->buf[i] == c) {
                b = FALSE;
                break;
            }
        }

        if(buf && i > stream->p)
            strbuf_append(buf, stream->buf+stream->p, i-stream->p);
        stream->p = i;

        if(stream->p == stream->size) {
            stream->p = 0;
            IStream_Read(stream->str, stream->buf, sizeof(stream->buf), &stream->size);
            if(!stream->size)
                break;
        }
    }

    return stream->size != 0;
}

void get_node_name(strbuf_t *node, strbuf_t *name)
{
    const char *ptr = node->buf+1;

    strbuf_zero(name);

    while(*ptr != '>' && !isspace(*ptr))
        ptr++;

    strbuf_append(name, node->buf+1, ptr-node->buf-1);
    strbuf_append(name, "", 1);
}

/* Return the stream content up to the next HTML tag.
 *
 * Note: the first returned character is the end of the last tag (>).
 */
BOOL next_content(stream_t *stream, strbuf_t *buf)
{
    if(!stream_chr(stream, buf, '<'))
        return FALSE;

    return TRUE;
}

BOOL next_node(stream_t *stream, strbuf_t *buf)
{
    if(!stream_chr(stream, NULL, '<'))
        return FALSE;

    if(!stream_chr(stream, buf, '>'))
        return FALSE;

    strbuf_append(buf, ">", 2);

    return TRUE;
}

/*
 * Find the value of a named HTML attribute.
 *
 * Note: Attribute names are case insensitive, so it is necessary to
 * put both the node text and the attribute name in the same case
 * before attempting a string search.
 */
const char *get_attr(const char *node, const char *name, int *len)
{
    const char *ptr, *ptr2;
    int name_len, node_len;
    char name_buf[32];
    char *node_buf;
    int i;

    /* Create a lower case copy of the node */
    node_len = strlen(node)+1;
    node_buf = heap_alloc(node_len*sizeof(char));
    if(!node_buf)
        return NULL;
    memcpy(node_buf, node, node_len);
    for(i=0;i<node_len;i++)
        node_buf[i] = tolower(node_buf[i]);
    /* Create a lower case copy of the attribute name (search string) */
    name_len = strlen(name);
    memcpy(name_buf, name, name_len);
    for(i=0;i<name_len;i++)
        name_buf[i] = tolower(name_buf[i]);
    name_buf[name_len++] = '=';
    name_buf[name_len++] = '\"';
    name_buf[name_len] = 0;

    ptr = strstr(node_buf, name_buf);
    if(!ptr) {
        WARN("name not found\n");
        heap_free(node_buf);
        return NULL;
    }

    ptr += name_len;
    ptr2 = strchr(ptr, '\"');
    if(!ptr2)
    {
        heap_free(node_buf);
        return NULL;
    }

    *len = ptr2-ptr;
    /* Return the pointer offset within the original string */
    ptr = node+(ptr-node_buf);

    heap_free(node_buf);
    return ptr;
}
