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

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

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winhelp.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(winhelp);

static inline unsigned short GET_USHORT(const BYTE* buffer, unsigned i)
{
    return (BYTE)buffer[i] + 0x100 * (BYTE)buffer[i + 1];
}

static inline short GET_SHORT(const BYTE* buffer, unsigned i)
{
    return (BYTE)buffer[i] + 0x100 * (signed char)buffer[i+1];
}

static inline unsigned GET_UINT(const BYTE* buffer, unsigned i)
{
    return GET_USHORT(buffer, i) + 0x10000 * GET_USHORT(buffer, i + 2);
}

static HLPFILE *first_hlpfile = 0;
static BYTE    *file_buffer;
static UINT     file_buffer_size;

static struct
{
    UINT        num;
    unsigned*   offsets;
    char*       buffer;
} phrases;

static struct
{
    BYTE**      map;
    BYTE*       end;
    UINT        wMapLen;
} topic;

static struct
{
    UINT                wFont;
    UINT                wIndent;
    UINT                wHSpace;
    UINT                wVSpace;
    HLPFILE_LINK*       link;
} attributes;

static BOOL  HLPFILE_DoReadHlpFile(HLPFILE*, LPCSTR);
static BOOL  HLPFILE_ReadFileToBuffer(HFILE);
static BOOL  HLPFILE_FindSubFile(LPCSTR name, BYTE**, BYTE**);
static BOOL  HLPFILE_SystemCommands(HLPFILE*);
static INT   HLPFILE_UncompressedLZ77_Size(BYTE *ptr, BYTE *end);
static BYTE* HLPFILE_UncompressLZ77(BYTE *ptr, BYTE *end, BYTE *newptr);
static BOOL  HLPFILE_UncompressLZ77_Phrases(HLPFILE*);
static BOOL  HLPFILE_Uncompress_Phrases40(HLPFILE*);
static BOOL  HLPFILE_Uncompress_Topic(HLPFILE*);
static BOOL  HLPFILE_GetContext(HLPFILE*);
static BOOL  HLPFILE_GetKeywords(HLPFILE*);
static BOOL  HLPFILE_GetMap(HLPFILE*);
static BOOL  HLPFILE_AddPage(HLPFILE*, BYTE*, BYTE*, unsigned);
static BOOL  HLPFILE_AddParagraph(HLPFILE*, BYTE *, BYTE*, unsigned*);
static void  HLPFILE_Uncompress2(const BYTE*, const BYTE*, BYTE*, const BYTE*);
static BOOL  HLPFILE_Uncompress3(char*, const char*, const BYTE*, const BYTE*);
static void  HLPFILE_UncompressRLE(const BYTE* src, const BYTE* end, BYTE** dst, unsigned dstsz);
static BOOL  HLPFILE_ReadFont(HLPFILE* hlpfile);

/***********************************************************************
 *
 *           HLPFILE_PageByNumber
 */
static HLPFILE_PAGE *HLPFILE_PageByNumber(HLPFILE* hlpfile, UINT wNum)
{
    HLPFILE_PAGE *page;
    UINT          temp = wNum;

    WINE_TRACE("<%s>[%u]\n", hlpfile->lpszPath, wNum);

    for (page = hlpfile->first_page; page && temp; page = page->next) temp--;
    if (!page)
        WINE_ERR("Page of number %u not found in file %s\n", wNum, hlpfile->lpszPath);
    return page;
}

/* FIXME:
 * this finds the page containing the offset. The offset can either
 * refer to the top of the page (offset == page->offset), or
 * to some paragraph inside the page...
 * As of today, we only return the page... we should also return
 * a paragraph, and then, while opening a new page, compute the
 * y-offset of the paragraph to be shown and scroll the window
 * accordinly
 */
/******************************************************************
 *		HLPFILE_PageByOffset
 *
 *
 */
HLPFILE_PAGE *HLPFILE_PageByOffset(HLPFILE* hlpfile, LONG offset)
{
    HLPFILE_PAGE*       page;
    HLPFILE_PAGE*       found;

    if (!hlpfile) return 0;

    WINE_TRACE("<%s>[%x]\n", hlpfile->lpszPath, offset);

    if (offset == 0xFFFFFFFF) return NULL;
    page = NULL;

    for (found = NULL, page = hlpfile->first_page; page; page = page->next)
    {
        if (page->offset <= offset && (!found || found->offset < page->offset))
            found = page;
    }
    if (!found)
        WINE_ERR("Page of offset %u not found in file %s\n",
                 offset, hlpfile->lpszPath);
    return found;
}

/**************************************************************************
 * comp_PageByHash
 *
 * HLPFILE_BPTreeCompare function for '|CONTEXT' B+ tree file
 *
 */
static int comp_PageByHash(void *p, const void *key,
                           int leaf, void** next)
{
    LONG lKey = (LONG)key;
    LONG lTest = GET_UINT(p, 0);

    *next = (char *)p+(leaf?8:6);
    WINE_TRACE("Comparing '%u' with '%u'\n", lKey, lTest);
    if (lTest < lKey) return -1;
    if (lTest > lKey) return 1;
    return 0;
}

/***********************************************************************
 *
 *           HLPFILE_HlpFilePageByHash
 */
HLPFILE_PAGE *HLPFILE_PageByHash(HLPFILE* hlpfile, LONG lHash)
{
    BYTE *ptr;

    if (!hlpfile) return 0;

    WINE_TRACE("<%s>[%x]\n", hlpfile->lpszPath, lHash);

    /* For win 3.0 files hash values are really page numbers */
    if (hlpfile->version <= 16)
        return HLPFILE_PageByNumber(hlpfile, lHash);

    ptr = HLPFILE_BPTreeSearch(hlpfile->Context, (void*)lHash, comp_PageByHash);
    if (!ptr)
    {
        WINE_ERR("Page of hash %x not found in file %s\n", lHash, hlpfile->lpszPath);
        return NULL;
    }

    return HLPFILE_PageByOffset(hlpfile, GET_UINT(ptr, 4));
}

/***********************************************************************
 *
 *           HLPFILE_PageByMap
 */
HLPFILE_PAGE *HLPFILE_PageByMap(HLPFILE* hlpfile, LONG lMap)
{
    unsigned int i;

    if (!hlpfile) return 0;

    WINE_TRACE("<%s>[%x]\n", hlpfile->lpszPath, lMap);

    for (i = 0; i < hlpfile->wMapLen; i++)
    {
        if (hlpfile->Map[i].lMap == lMap)
            return HLPFILE_PageByOffset(hlpfile, hlpfile->Map[i].offset);
    }

    WINE_ERR("Page of Map %x not found in file %s\n", lMap, hlpfile->lpszPath);
    return NULL;
}

/***********************************************************************
 *
 *           HLPFILE_Contents
 */
HLPFILE_PAGE* HLPFILE_Contents(HLPFILE *hlpfile)
{
    HLPFILE_PAGE*       page = NULL;

    if (!hlpfile) return NULL;

    page = HLPFILE_PageByOffset(hlpfile, hlpfile->contents_start);
    if (!page) page = hlpfile->first_page;
    return page;
}

/***********************************************************************
 *
 *           HLPFILE_Hash
 */
LONG HLPFILE_Hash(LPCSTR lpszContext)
{
    LONG lHash = 0;
    CHAR c;

    while ((c = *lpszContext++))
    {
        CHAR x = 0;
        if (c >= 'A' && c <= 'Z') x = c - 'A' + 17;
        if (c >= 'a' && c <= 'z') x = c - 'a' + 17;
        if (c >= '1' && c <= '9') x = c - '0';
        if (c == '0') x = 10;
        if (c == '.') x = 12;
        if (c == '_') x = 13;
        if (x) lHash = lHash * 43 + x;
    }
    return lHash;
}

/***********************************************************************
 *
 *           HLPFILE_ReadHlpFile
 */
HLPFILE *HLPFILE_ReadHlpFile(LPCSTR lpszPath)
{
    HLPFILE*      hlpfile;

    for (hlpfile = first_hlpfile; hlpfile; hlpfile = hlpfile->next)
    {
        if (!strcmp(lpszPath, hlpfile->lpszPath))
        {
            hlpfile->wRefCount++;
            return hlpfile;
        }
    }

    hlpfile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                        sizeof(HLPFILE) + lstrlen(lpszPath) + 1);
    if (!hlpfile) return 0;

    hlpfile->lpszPath           = (char*)hlpfile + sizeof(HLPFILE);
    hlpfile->contents_start     = 0xFFFFFFFF;
    hlpfile->next               = first_hlpfile;
    hlpfile->wRefCount          = 1;

    strcpy(hlpfile->lpszPath, lpszPath);

    first_hlpfile = hlpfile;
    if (hlpfile->next) hlpfile->next->prev = hlpfile;

    phrases.offsets = NULL;
    phrases.buffer = NULL;
    topic.map = NULL;
    topic.end = NULL;
    file_buffer = NULL;

    if (!HLPFILE_DoReadHlpFile(hlpfile, lpszPath))
    {
        HLPFILE_FreeHlpFile(hlpfile);
        hlpfile = 0;
    }

    HeapFree(GetProcessHeap(), 0, phrases.offsets);
    HeapFree(GetProcessHeap(), 0, phrases.buffer);
    HeapFree(GetProcessHeap(), 0, topic.map);
    HeapFree(GetProcessHeap(), 0, file_buffer);

    return hlpfile;
}

/***********************************************************************
 *
 *           HLPFILE_DoReadHlpFile
 */
static BOOL HLPFILE_DoReadHlpFile(HLPFILE *hlpfile, LPCSTR lpszPath)
{
    BOOL        ret;
    HFILE       hFile;
    OFSTRUCT    ofs;
    BYTE*       buf;
    DWORD       ref = 0x0C;
    unsigned    index, old_index, offset, len, offs;

    hFile = OpenFile(lpszPath, &ofs, OF_READ);
    if (hFile == HFILE_ERROR) return FALSE;

    ret = HLPFILE_ReadFileToBuffer(hFile);
    _lclose(hFile);
    if (!ret) return FALSE;

    if (!HLPFILE_SystemCommands(hlpfile)) return FALSE;

    /* load phrases support */
    if (!HLPFILE_UncompressLZ77_Phrases(hlpfile))
        HLPFILE_Uncompress_Phrases40(hlpfile);

    if (!HLPFILE_Uncompress_Topic(hlpfile)) return FALSE;
    if (!HLPFILE_ReadFont(hlpfile)) return FALSE;

    buf = topic.map[0];
    old_index = -1;
    offs = 0;
    do
    {
        BYTE*   end;

        if (hlpfile->version <= 16)
        {
            index  = (ref - 0x0C) / hlpfile->dsize;
            offset = (ref - 0x0C) % hlpfile->dsize;
        }
        else
        {
            index  = (ref - 0x0C) >> 14;
            offset = (ref - 0x0C) & 0x3FFF;
        }

        if (hlpfile->version <= 16 && index != old_index && index != 0)
        {
            /* we jumped to the next block, adjust pointers */
            ref -= 12;
            offset -= 12;
        }

        WINE_TRACE("ref=%08x => [%u/%u]\n", ref, index, offset);

        if (index >= topic.wMapLen) {WINE_WARN("maplen\n"); break;}
        buf = topic.map[index] + offset;
        if (buf + 0x15 >= topic.end) {WINE_WARN("extra\n"); break;}
        end = min(buf + GET_UINT(buf, 0), topic.end);
        if (index != old_index) {offs = 0; old_index = index;}

        switch (buf[0x14])
	{
	case 0x02:
            if (!HLPFILE_AddPage(hlpfile, buf, end, index * 0x8000L + offs)) return FALSE;
            break;

	case 0x01:
	case 0x20:
	case 0x23:
            if (!HLPFILE_AddParagraph(hlpfile, buf, end, &len)) return FALSE;
            offs += len;
            break;

	default:
            WINE_ERR("buf[0x14] = %x\n", buf[0x14]);
	}

        if (hlpfile->version <= 16)
        {
            ref += GET_UINT(buf, 0xc);
            if (GET_UINT(buf, 0xc) == 0)
                break;
        }
        else
            ref = GET_UINT(buf, 0xc);
    } while (ref != 0xffffffff);

    HLPFILE_GetKeywords(hlpfile);
    HLPFILE_GetMap(hlpfile);
    if (hlpfile->version <= 16) return TRUE;
    return HLPFILE_GetContext(hlpfile);
}

/***********************************************************************
 *
 *           HLPFILE_AddPage
 */
static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned offset)
{
    HLPFILE_PAGE* page;
    BYTE*         title;
    UINT          titlesize, blocksize, datalen;
    char*         ptr;
    HLPFILE_MACRO*macro;

    blocksize = GET_UINT(buf, 0);
    datalen = GET_UINT(buf, 0x10);
    title = buf + datalen;
    if (title > end) {WINE_WARN("page2\n"); return FALSE;};

    titlesize = GET_UINT(buf, 4);
    page = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_PAGE) + titlesize + 1);
    if (!page) return FALSE;
    page->lpszTitle = (char*)page + sizeof(HLPFILE_PAGE);

    if (titlesize > blocksize - datalen)
    {
        /* need to decompress */
        if (hlpfile->hasPhrases)
            HLPFILE_Uncompress2(title, end, (BYTE*)page->lpszTitle, (BYTE*)page->lpszTitle + titlesize);
        else if (hlpfile->hasPhrases40)
            HLPFILE_Uncompress3(page->lpszTitle, page->lpszTitle + titlesize, title, end);
        else
        {
            WINE_FIXME("Text size is too long, splitting\n");
            titlesize = blocksize - datalen;
            memcpy(page->lpszTitle, title, titlesize);
        }
    }
    else
        memcpy(page->lpszTitle, title, titlesize);

    page->lpszTitle[titlesize] = '\0';

    if (hlpfile->first_page)
    {
        hlpfile->last_page->next = page;
        page->prev = hlpfile->last_page;
        hlpfile->last_page = page;
    }
    else
    {
        hlpfile->first_page = page;
        hlpfile->last_page = page;
        page->prev = NULL;
    }

    page->file            = hlpfile;
    page->next            = NULL;
    page->first_paragraph = NULL;
    page->first_macro     = NULL;
    page->wNumber         = GET_UINT(buf, 0x21);
    page->offset          = offset;

    page->browse_bwd = GET_UINT(buf, 0x19);
    page->browse_fwd = GET_UINT(buf, 0x1D);

    WINE_TRACE("Added page[%d]: title='%s' %08x << %08x >> %08x\n",
               page->wNumber, page->lpszTitle, 
               page->browse_bwd, page->offset, page->browse_fwd);

    memset(&attributes, 0, sizeof(attributes));

    /* now load macros */
    ptr = page->lpszTitle + strlen(page->lpszTitle) + 1;
    while (ptr < page->lpszTitle + titlesize)
    {
        unsigned len = strlen(ptr);
        char*    macro_str;

        WINE_TRACE("macro: %s\n", ptr);
        macro = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_MACRO) + len + 1);
        macro->lpszMacro = macro_str = (char*)(macro + 1);
        memcpy(macro_str, ptr, len + 1);
        /* FIXME: shall we really link macro in reverse order ??
         * may produce strange results when played at page opening
         */
        macro->next = page->first_macro;
        page->first_macro = macro;
        ptr += len + 1;
    }

    return TRUE;
}

static long fetch_long(BYTE** ptr)
{
    long        ret;

    if (*(*ptr) & 1)
    {
        ret = (*(unsigned long*)(*ptr) - 0x80000000L) / 2;
        (*ptr) += 4;
    }
    else
    {
        ret = (*(unsigned short*)(*ptr) - 0x8000) / 2;
        (*ptr) += 2;
    }

    return ret;
}

static unsigned long fetch_ulong(BYTE** ptr)
{
    unsigned long        ret;

    if (*(*ptr) & 1)
    {
        ret = *(unsigned long*)(*ptr) / 2;
        (*ptr) += 4;
    }
    else
    {
        ret = *(unsigned short*)(*ptr) / 2;
        (*ptr) += 2;
    }
    return ret;
}    

static short fetch_short(BYTE** ptr)
{
    short       ret;

    if (*(*ptr) & 1)
    {
        ret = (*(unsigned short*)(*ptr) - 0x8000) / 2;
        (*ptr) += 2;
    }
    else
    {
        ret = (*(unsigned char*)(*ptr) - 0x80) / 2;
        (*ptr)++;
    }
    return ret;
}

static unsigned short fetch_ushort(BYTE** ptr)
{
    unsigned short ret;

    if (*(*ptr) & 1)
    {
        ret = *(unsigned short*)(*ptr) / 2;
        (*ptr) += 2;
    }
    else
    {
        ret = *(unsigned char*)(*ptr) / 2;
        (*ptr)++;
    }
    return ret;
}

/******************************************************************
 *		HLPFILE_DecompressGfx
 *
 * Decompress the data part of a bitmap or a metafile
 */
static BYTE*    HLPFILE_DecompressGfx(BYTE* src, unsigned csz, unsigned sz, BYTE packing)
{
    BYTE*       dst;
    BYTE*       tmp;
    BYTE*       tmp2;
    unsigned    sz77;

    WINE_TRACE("Unpacking (%d) from %u bytes to %u bytes\n", packing, csz, sz);

    switch (packing)
    {
    case 0: /* uncompressed */
        if (sz != csz)
            WINE_WARN("Bogus gfx sizes (uncompressed): %u / %u\n", sz, csz);
        dst = src;
        break;
    case 1: /* RunLen */
        tmp = dst = HeapAlloc(GetProcessHeap(), 0, sz);
        if (!dst) return NULL;
        HLPFILE_UncompressRLE(src, src + csz, &tmp, sz);
        if (tmp - dst != sz)
            WINE_WARN("Bogus gfx sizes (RunLen): %u/%u\n", tmp - dst, sz);
        break;
    case 2: /* LZ77 */
        sz77 = HLPFILE_UncompressedLZ77_Size(src, src + csz);
        dst = HeapAlloc(GetProcessHeap(), 0, sz77);
        if (!dst) return NULL;
        HLPFILE_UncompressLZ77(src, src + csz, dst);
        if (sz77 != sz)
            WINE_WARN("Bogus gfx sizes (LZ77): %u / %u\n", sz77, sz);
        break;
    case 3: /* LZ77 then RLE */
        sz77 = HLPFILE_UncompressedLZ77_Size(src, src + csz);
        tmp = HeapAlloc(GetProcessHeap(), 0, sz77);
        if (!tmp) return FALSE;
        HLPFILE_UncompressLZ77(src, src + csz, tmp);
        dst = tmp2 = HeapAlloc(GetProcessHeap(), 0, sz);
        if (!dst)
        {
            HeapFree(GetProcessHeap(), 0, tmp);
            return FALSE;
        }
        HLPFILE_UncompressRLE(tmp, tmp + sz77, &tmp2, sz);
        if (tmp2 - dst != sz)
            WINE_WARN("Bogus gfx sizes (LZ77+RunLen): %u / %u\n", tmp2 - dst, sz);
        HeapFree(GetProcessHeap(), 0, tmp);
        break;
    default:
        WINE_FIXME("Unsupported packing %u\n", packing);
        return NULL;
    }
    return dst;
}

/******************************************************************
 *		HLPFILE_LoadBitmap
 *
 *
 */
static BOOL HLPFILE_LoadBitmap(BYTE* beg, BYTE type, BYTE pack, 
                               HLPFILE_PARAGRAPH* paragraph)
{
    BYTE*               ptr;
    BYTE*               pict_beg;
    BITMAPINFO*         bi;
    unsigned long       off, csz;
    HDC                 hdc;

    bi = HeapAlloc(GetProcessHeap(), 0, sizeof(*bi));
    if (!bi) return FALSE;

    ptr = beg + 2; /* for type and pack */

    bi->bmiHeader.biSize          = sizeof(bi->bmiHeader);
    bi->bmiHeader.biXPelsPerMeter = fetch_ulong(&ptr);
    bi->bmiHeader.biYPelsPerMeter = fetch_ulong(&ptr);
    bi->bmiHeader.biPlanes        = fetch_ushort(&ptr);
    bi->bmiHeader.biBitCount      = fetch_ushort(&ptr);
    bi->bmiHeader.biWidth         = fetch_ulong(&ptr);
    bi->bmiHeader.biHeight        = fetch_ulong(&ptr);
    bi->bmiHeader.biClrUsed       = fetch_ulong(&ptr);
    bi->bmiHeader.biClrImportant  = fetch_ulong(&ptr);
    bi->bmiHeader.biCompression   = BI_RGB;
    if (bi->bmiHeader.biBitCount > 32) WINE_FIXME("Unknown bit count %u\n", bi->bmiHeader.biBitCount);
    if (bi->bmiHeader.biPlanes != 1) WINE_FIXME("Unsupported planes %u\n", bi->bmiHeader.biPlanes);
    bi->bmiHeader.biSizeImage = (((bi->bmiHeader.biWidth * bi->bmiHeader.biBitCount + 31) & ~31) / 8) * bi->bmiHeader.biHeight;
    WINE_TRACE("planes=%d bc=%d size=(%d,%d)\n",
               bi->bmiHeader.biPlanes, bi->bmiHeader.biBitCount, 
               bi->bmiHeader.biWidth, bi->bmiHeader.biHeight);

    csz = fetch_ulong(&ptr);
    fetch_ulong(&ptr); /* hotspot size */

    off = GET_UINT(ptr, 0);     ptr += 4;
    /* GET_UINT(ptr, 0); hotspot offset */ ptr += 4;
    
    /* now read palette info */
    if (type == 0x06)
    {
        unsigned nc = bi->bmiHeader.biClrUsed;
        unsigned i;
        
        /* not quite right, especially for bitfields type of compression */
        if (!nc && bi->bmiHeader.biBitCount <= 8)
            nc = 1 << bi->bmiHeader.biBitCount;
        
        bi = HeapReAlloc(GetProcessHeap(), 0, bi, sizeof(*bi) + nc * sizeof(RGBQUAD));
        if (!bi) return FALSE;
        for (i = 0; i < nc; i++)
        {
            bi->bmiColors[i].rgbBlue     = ptr[0];
            bi->bmiColors[i].rgbGreen    = ptr[1];
            bi->bmiColors[i].rgbRed      = ptr[2];
            bi->bmiColors[i].rgbReserved = 0;
            ptr += 4;
        }
    }
    pict_beg = HLPFILE_DecompressGfx(beg + off, csz, bi->bmiHeader.biSizeImage, pack);
    
    paragraph->u.gfx.u.bmp.hBitmap = CreateDIBitmap(hdc = GetDC(0), &bi->bmiHeader, 
                                                    CBM_INIT, pict_beg, 
                                                    bi, DIB_RGB_COLORS);
    ReleaseDC(0, hdc);      
    if (!paragraph->u.gfx.u.bmp.hBitmap)
        WINE_ERR("Couldn't create bitmap\n");
    
    HeapFree(GetProcessHeap(), 0, bi);
    if (pict_beg != beg + off) HeapFree(GetProcessHeap(), 0, pict_beg);

    return TRUE;
}

/******************************************************************
 *		HLPFILE_LoadMetaFile
 *
 *
 */
static BOOL     HLPFILE_LoadMetaFile(BYTE* beg, BYTE pack, HLPFILE_PARAGRAPH* paragraph)
{
    BYTE*               ptr;
    unsigned long       size, csize;
    unsigned long       off, hsoff;
    BYTE*               bits;
    LPMETAFILEPICT      lpmfp;

    WINE_TRACE("Loading metafile\n");

    ptr = beg + 2; /* for type and pack */

    lpmfp = &paragraph->u.gfx.u.mfp;
    lpmfp->mm = fetch_ushort(&ptr); /* mapping mode */

    lpmfp->xExt = GET_USHORT(ptr, 0);
    lpmfp->yExt = GET_USHORT(ptr, 2);
    ptr += 4;

    size = fetch_ulong(&ptr); /* decompressed size */
    csize = fetch_ulong(&ptr); /* compressed size */
    fetch_ulong(&ptr); /* hotspot size */
    off = GET_UINT(ptr, 0);
    hsoff = GET_UINT(ptr, 4);
    ptr += 8;

    WINE_TRACE("sz=%lu csz=%lu (%d,%d) offs=%lu/%u,%lu\n",
               size, csize, lpmfp->xExt, lpmfp->yExt, off, ptr - beg, hsoff);

    bits = HLPFILE_DecompressGfx(beg + off, csize, size, pack);
    if (!bits) return FALSE;

    paragraph->cookie = para_metafile;

    lpmfp->hMF = SetMetaFileBitsEx(size, bits);

    if (!lpmfp->hMF)
        WINE_FIXME("Couldn't load metafile\n");

    if (bits != beg + off) HeapFree(GetProcessHeap(), 0, bits);

    return TRUE;
}

/******************************************************************
 *		HLPFILE_LoadGfxByAddr
 *
 *
 */
static  BOOL    HLPFILE_LoadGfxByAddr(HLPFILE *hlpfile, BYTE* ref,
                                      unsigned long size, 
                                      HLPFILE_PARAGRAPH* paragraph)
{
    unsigned    i, numpict;

    numpict = GET_USHORT(ref, 2);
    WINE_TRACE("Got picture magic=%04x #=%d\n", 
               GET_USHORT(ref, 0), numpict);

    for (i = 0; i < numpict; i++)
    {
        BYTE*   beg;
        BYTE*   ptr;
        BYTE    type, pack;

        WINE_TRACE("Offset[%d] = %x\n", i, GET_UINT(ref, (1 + i) * 4));
        beg = ptr = ref + GET_UINT(ref, (1 + i) * 4);

        type = *ptr++;
        pack = *ptr++;
        
        switch (type)
        {
        case 5: /* device dependent bmp */
        case 6: /* device independent bmp */
            HLPFILE_LoadBitmap(beg, type, pack, paragraph);
            break;
        case 8: 
            HLPFILE_LoadMetaFile(beg, pack, paragraph);
            break;
        default: WINE_FIXME("Unknown type %u\n", type); return FALSE;
        }

        /* FIXME: hotspots */

        /* FIXME: implement support for multiple picture format */
        if (numpict != 1) WINE_FIXME("Supporting only one bitmap format per logical bitmap (for now). Using first format\n");
        break;
    }
    return TRUE;
}

/******************************************************************
 *		HLPFILE_LoadGfxByIndex
 *
 *
 */
static  BOOL    HLPFILE_LoadGfxByIndex(HLPFILE *hlpfile, unsigned index, 
                                       HLPFILE_PARAGRAPH* paragraph)
{
    char        tmp[16];
    BYTE        *ref, *end;
    BOOL        ret;

    WINE_TRACE("Loading picture #%d\n", index);

    if (index < hlpfile->numBmps && hlpfile->bmps[index] != NULL)
    {
        paragraph->u.gfx.u.bmp.hBitmap = hlpfile->bmps[index];
        return TRUE;
    }

    sprintf(tmp, "|bm%u", index);

    if (!HLPFILE_FindSubFile(tmp, &ref, &end)) {WINE_WARN("no sub file\n"); return FALSE;}

    ref += 9;

    ret = HLPFILE_LoadGfxByAddr(hlpfile, ref, end - ref, paragraph);

    /* cache bitmap */
    if (ret && paragraph->cookie == para_bitmap)
    {
        if (index >= hlpfile->numBmps)
        {
            hlpfile->numBmps = index + 1;
	    if (hlpfile->bmps)
        	hlpfile->bmps = HeapReAlloc(GetProcessHeap(), 0, hlpfile->bmps, 
                                        hlpfile->numBmps * sizeof(hlpfile->bmps[0]));
	    else
	    	hlpfile->bmps = HeapAlloc(GetProcessHeap(), 0, 
                                        hlpfile->numBmps * sizeof(hlpfile->bmps[0]));

        }
        hlpfile->bmps[index] = paragraph->u.gfx.u.bmp.hBitmap;
    }
    return ret;
}

/******************************************************************
 *		HLPFILE_AllocLink
 *
 *
 */
static HLPFILE_LINK*       HLPFILE_AllocLink(int cookie, const char* str, LONG hash,
                                             BOOL clrChange, unsigned wnd)
{
    HLPFILE_LINK*  link;
    char*          link_str;

    /* FIXME: should build a string table for the attributes.link.lpszPath
     * they are reallocated for each link
     */
    link = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_LINK) + strlen(str) + 1);
    if (!link) return NULL;

    link->cookie     = cookie;
    link->lpszString = link_str = (char*)link + sizeof(HLPFILE_LINK);
    strcpy(link_str, str);
    link->lHash      = hash;
    link->bClrChange = clrChange ? 1 : 0;
    link->window     = wnd;
    link->wRefCount   = 1;

    WINE_TRACE("Link[%d] to %s@%08x:%d\n",
               link->cookie, link->lpszString, 
               link->lHash, link->window);
    return link;
}

/***********************************************************************
 *
 *           HLPFILE_AddParagraph
 */
static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned* len)
{
    HLPFILE_PAGE      *page;
    HLPFILE_PARAGRAPH *paragraph, **paragraphptr;
    UINT               textsize;
    BYTE              *format, *format_end;
    char              *text, *text_base, *text_end;
    long               size, blocksize, datalen;
    unsigned short     bits;
    unsigned           nc, ncol = 1;

    if (!hlpfile->last_page) {WINE_WARN("no page\n"); return FALSE;};
    page = hlpfile->last_page;
    for (paragraphptr = &page->first_paragraph; *paragraphptr;
         paragraphptr = &(*paragraphptr)->next) /* Nothing */;

    if (buf + 0x19 > end) {WINE_WARN("header too small\n"); return FALSE;};

    blocksize = GET_UINT(buf, 0);
    size = GET_UINT(buf, 0x4);
    datalen = GET_UINT(buf, 0x10);
    text = text_base = HeapAlloc(GetProcessHeap(), 0, size);
    if (!text) return FALSE;
    if (size > blocksize - datalen)
    {
        /* need to decompress */
        if (hlpfile->hasPhrases)
            HLPFILE_Uncompress2(buf + datalen, end, (BYTE*)text, (BYTE*)text + size);
        else if (hlpfile->hasPhrases40)
            HLPFILE_Uncompress3(text, text + size, buf + datalen, end);
        else
        {
            WINE_FIXME("Text size is too long, splitting\n");
            size = blocksize - datalen;
            memcpy(text, buf + datalen, size);
        }
    }
    else
        memcpy(text, buf + datalen, size);

    text_end = text + size;

    format = buf + 0x15;
    format_end = buf + GET_UINT(buf, 0x10);

    if (buf[0x14] == 0x20 || buf[0x14] == 0x23)
    {
        fetch_long(&format);
        *len = fetch_ushort(&format);
    }
    else *len = end-buf-15;

    if (buf[0x14] == 0x23)
    {
        char    type;

        ncol = *format++;

        WINE_TRACE("#cols %u\n", ncol);
        type = *format++;
        if (type == 0 || type == 2)
            format += 2;
        format += ncol * 4;
    }

    for (nc = 0; nc < ncol; nc++)
    {
        WINE_TRACE("looking for format at offset %u for column %d\n", format - (buf + 0x15), nc);
        if (buf[0x14] == 0x23)
            format += 5;
        if (buf[0x14] == 0x01)
            format += 6;
        else
            format += 4;
        bits = GET_USHORT(format, 0); format += 2;
        if (bits & 0x0001) fetch_long(&format);
        if (bits & 0x0002) fetch_short(&format);
        if (bits & 0x0004) fetch_short(&format);
        if (bits & 0x0008) fetch_short(&format);
        if (bits & 0x0010) fetch_short(&format);
        if (bits & 0x0020) fetch_short(&format);
        if (bits & 0x0040) fetch_short(&format);
        if (bits & 0x0100) format += 3;
        if (bits & 0x0200)
        {
            int                 ntab = fetch_short(&format);
            unsigned short      ts;

            while (ntab-- > 0)
            {
                ts = fetch_ushort(&format);
                if (ts & 0x4000) fetch_ushort(&format);
            }
        }
        /* 0x0400, 0x0800 and 0x1000 don't need space */
        if ((bits & 0xE080) != 0) 
            WINE_FIXME("Unsupported bits %04x, potential trouble ahead\n", bits);

        while (text < text_end && format < format_end)
        {
            WINE_TRACE("Got text: %s (%p/%p - %p/%p)\n", wine_dbgstr_a(text), text, text_end, format, format_end);
            textsize = strlen(text) + 1;
            if (textsize > 1)
            {
                paragraph = HeapAlloc(GetProcessHeap(), 0,
                                      sizeof(HLPFILE_PARAGRAPH) + textsize);
                if (!paragraph) return FALSE;
                *paragraphptr = paragraph;
                paragraphptr = &paragraph->next;

                paragraph->next            = NULL;
                paragraph->link            = attributes.link;
                if (paragraph->link) paragraph->link->wRefCount++;
                paragraph->cookie          = para_normal_text;
                paragraph->u.text.wFont    = attributes.wFont;
                paragraph->u.text.wVSpace  = attributes.wVSpace;
                paragraph->u.text.wHSpace  = attributes.wHSpace;
                paragraph->u.text.wIndent  = attributes.wIndent;
                paragraph->u.text.lpszText = (char*)paragraph + sizeof(HLPFILE_PARAGRAPH);
                strcpy(paragraph->u.text.lpszText, text);

                attributes.wVSpace = 0;
                attributes.wHSpace = 0;
            }
            /* else: null text, keep on storing attributes */
            text += textsize;

	    if (*format == 0xff)
            {
                format++;
                break;
            }

            WINE_TRACE("format=%02x\n", *format);
            switch (*format)
            {
            case 0x20:
                WINE_FIXME("NIY20\n");
                format += 5;
                break;

            case 0x21:
                WINE_FIXME("NIY21\n");
                format += 3;
                break;

	    case 0x80:
                attributes.wFont = GET_USHORT(format, 1);
                WINE_TRACE("Changing font to %d\n", attributes.wFont);
                format += 3;
                break;

	    case 0x81:
                attributes.wVSpace++;
                format += 1;
                break;

	    case 0x82:
                attributes.wVSpace++;
                attributes.wIndent = 0;
                format += 1;
                break;

	    case 0x83:
                attributes.wIndent++;
                format += 1;
                break;

#if 0
	    case 0x84:
                format += 3;
                break;
#endif

	    case 0x86:
	    case 0x87:
	    case 0x88:
                {
                    BYTE    pos = (*format - 0x86);
                    BYTE    type = format[1];
                    long    size;

                    format += 2;
                    size = fetch_long(&format);

                    paragraph = HeapAlloc(GetProcessHeap(), 0,
                                          sizeof(HLPFILE_PARAGRAPH) + textsize);
                    if (!paragraph) return FALSE;
                    *paragraphptr = paragraph;
                    paragraphptr = &paragraph->next;

                    paragraph->next        = NULL;
                    paragraph->link        = attributes.link;
                    if (paragraph->link) paragraph->link->wRefCount++;
                    paragraph->cookie      = para_bitmap;
                    paragraph->u.gfx.pos   = pos;
                    switch (type)
                    {
                    case 0x22:
                        fetch_ushort(&format); /* hot spot */
                        /* fall thru */
                    case 0x03:
                        switch (GET_SHORT(format, 0))
                        {
                        case 0:
                            HLPFILE_LoadGfxByIndex(hlpfile, GET_SHORT(format, 2), 
                                                   paragraph);
                            break;
                        case 1:
                            WINE_FIXME("does it work ??? %x<%lu>#%u\n", 
                                       GET_SHORT(format, 0), 
                                       size, GET_SHORT(format, 2));
                            HLPFILE_LoadGfxByAddr(hlpfile, format + 2, size - 4, 
                                                  paragraph);
                            break;
                        default:
                            WINE_FIXME("??? %u\n", GET_SHORT(format, 0));
                            break;
                        }
                        break;
                    case 0x05:
                        WINE_FIXME("Got an embedded element %s\n", format + 6);
                        break;
                    default:
                        WINE_FIXME("Got a type %d picture\n", type);
                        break;
                    }
                    if (attributes.wVSpace) paragraph->u.gfx.pos |= 0x8000;

                    format += size;
                }
                break;

	    case 0x89:
                HLPFILE_FreeLink(attributes.link);
                attributes.link = NULL;
                format += 1;
                break;

            case 0x8B:
            case 0x8C:
                WINE_FIXME("NIY non-break space/hyphen\n");
                format += 1;
                break;

#if 0
	    case 0xA9:
                format += 2;
                break;
#endif

            case 0xC8:
            case 0xCC:
                WINE_TRACE("macro => %s\n", format + 3);
                HLPFILE_FreeLink(attributes.link);
                attributes.link = HLPFILE_AllocLink(hlp_link_macro, (const char*)format + 3, 
                                                    0, !(*format & 4), -1);
                format += 3 + GET_USHORT(format, 1);
                break;

            case 0xE0:
            case 0xE1:
                WINE_WARN("jump topic 1 => %u\n", GET_UINT(format, 1));
                HLPFILE_FreeLink(attributes.link);
                attributes.link = HLPFILE_AllocLink((*format & 1) ? hlp_link_link : hlp_link_popup,
                                                    hlpfile->lpszPath,
                                                    GET_UINT(format, 1)-16,
                                                    1, -1);


                format += 5;
                break;

	    case 0xE2:
	    case 0xE3:
            case 0xE6:
            case 0xE7:
                HLPFILE_FreeLink(attributes.link);
                attributes.link = HLPFILE_AllocLink((*format & 1) ? hlp_link_link : hlp_link_popup,
                                                    hlpfile->lpszPath, 
                                                    GET_UINT(format, 1), 
                                                    !(*format & 4), -1);
                format += 5;
                break;

	    case 0xEA:
            case 0xEB:
            case 0xEE:
            case 0xEF:
                {
                    char*       ptr = (char*) format + 8;
                    BYTE        type = format[3];
                    int         wnd = -1;
                    char*       str;

                    if (type == 1) wnd = *ptr++;
                    if (type == 4 || type == 6)
                    {
                        str = ptr;
                        ptr += strlen(ptr) + 1;
                    }
                    else
                        str = hlpfile->lpszPath;
                    if (type == 6)
                    {
                        for (wnd = hlpfile->numWindows - 1; wnd >= 0; wnd--)
                        {
                            if (!strcmp(ptr, hlpfile->windows[wnd].name)) break;
                        }
                        if (wnd == -1)
                            WINE_WARN("Couldn't find window info for %s\n", ptr);
                    }
                    HLPFILE_FreeLink(attributes.link);
                    attributes.link = HLPFILE_AllocLink((*format & 4) ? hlp_link_link : hlp_link_popup,
                                                        str, GET_UINT(format, 4),
                                                        !(*format & 1), wnd);
                }
                format += 3 + GET_USHORT(format, 1);
                break;

	    default:
                WINE_WARN("format %02x\n", *format);
                format++;
	    }
	}
    }
    HeapFree(GetProcessHeap(), 0, text_base);
    return TRUE;
}

/******************************************************************
 *		HLPFILE_ReadFont
 *
 *
 */
static BOOL HLPFILE_ReadFont(HLPFILE* hlpfile)
{
    BYTE        *ref, *end;
    unsigned    i, len, idx;
    unsigned    face_num, dscr_num, face_offset, dscr_offset;
    BYTE        flag, family;

    if (!HLPFILE_FindSubFile("|FONT", &ref, &end))
    {
        WINE_WARN("no subfile FONT\n");
        hlpfile->numFonts = 0;
        hlpfile->fonts = NULL;
        return FALSE;
    }

    ref += 9;

    face_num    = GET_USHORT(ref, 0);
    dscr_num    = GET_USHORT(ref, 2);
    face_offset = GET_USHORT(ref, 4);
    dscr_offset = GET_USHORT(ref, 6);

    WINE_TRACE("Got NumFacenames=%u@%u NumDesc=%u@%u\n",
               face_num, face_offset, dscr_num, dscr_offset);

    hlpfile->numFonts = dscr_num;
    hlpfile->fonts = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_FONT) * dscr_num);

    len = (dscr_offset - face_offset) / face_num;
/* EPP     for (i = face_offset; i < dscr_offset; i += len) */
/* EPP         WINE_FIXME("[%d]: %*s\n", i / len, len, ref + i); */
    for (i = 0; i < dscr_num; i++)
    {
        flag = ref[dscr_offset + i * 11 + 0];
        family = ref[dscr_offset + i * 11 + 2];

        hlpfile->fonts[i].LogFont.lfHeight = -ref[dscr_offset + i * 11 + 1] / 2 - 3;
        hlpfile->fonts[i].LogFont.lfWidth = 0;
        hlpfile->fonts[i].LogFont.lfEscapement = 0;
        hlpfile->fonts[i].LogFont.lfOrientation = 0;
        hlpfile->fonts[i].LogFont.lfWeight = (flag & 1) ? 700 : 400;
        hlpfile->fonts[i].LogFont.lfItalic = (flag & 2) ? TRUE : FALSE;
        hlpfile->fonts[i].LogFont.lfUnderline = (flag & 4) ? TRUE : FALSE;
        hlpfile->fonts[i].LogFont.lfStrikeOut = (flag & 8) ? TRUE : FALSE;
        hlpfile->fonts[i].LogFont.lfCharSet = DEFAULT_CHARSET;
        hlpfile->fonts[i].LogFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
        hlpfile->fonts[i].LogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
        hlpfile->fonts[i].LogFont.lfQuality = DEFAULT_QUALITY;
        hlpfile->fonts[i].LogFont.lfPitchAndFamily = DEFAULT_PITCH;

        switch (family)
        {
        case 0x01: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_MODERN;     break;
        case 0x02: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_ROMAN;      break;
        case 0x03: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_SWISS;      break;
        case 0x04: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_SCRIPT;     break;
        case 0x05: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_DECORATIVE; break;
        default: WINE_FIXME("Unknown family %u\n", family);
        }
        idx = GET_USHORT(ref, dscr_offset + i * 11 + 3);

        if (idx < face_num)
        {
            memcpy(hlpfile->fonts[i].LogFont.lfFaceName, ref + face_offset + idx * len, min(len, LF_FACESIZE - 1));
            hlpfile->fonts[i].LogFont.lfFaceName[min(len, LF_FACESIZE - 1)] = '\0';
        }
        else
        {
            WINE_FIXME("Too high face ref (%u/%u)\n", idx, face_num);
            strcpy(hlpfile->fonts[i].LogFont.lfFaceName, "Helv");
        }
        hlpfile->fonts[i].hFont = 0;
        hlpfile->fonts[i].color = RGB(ref[dscr_offset + i * 11 + 5],
                                      ref[dscr_offset + i * 11 + 6],
                                      ref[dscr_offset + i * 11 + 7]);
#define X(b,s) ((flag & (1 << b)) ? "-"s: "")
        WINE_TRACE("Font[%d]: flags=%02x%s%s%s%s%s%s pSize=%u family=%u face=%s[%u] color=%08x\n",
                   i, flag,
                   X(0, "bold"),
                   X(1, "italic"),
                   X(2, "underline"),
                   X(3, "strikeOut"),
                   X(4, "dblUnderline"),
                   X(5, "smallCaps"),
                   ref[dscr_offset + i * 11 + 1],
                   family,
                   hlpfile->fonts[i].LogFont.lfFaceName, idx,
                   GET_UINT(ref, dscr_offset + i * 11 + 5) & 0x00FFFFFF);
    }
    return TRUE;
}

/***********************************************************************
 *
 *           HLPFILE_ReadFileToBuffer
 */
static BOOL HLPFILE_ReadFileToBuffer(HFILE hFile)
{
    BYTE  header[16], dummy[1];

    if (_hread(hFile, header, 16) != 16) {WINE_WARN("header\n"); return FALSE;};

    /* sanity checks */
    if (GET_UINT(header, 0) != 0x00035F3F)
    {WINE_WARN("wrong header\n"); return FALSE;};

    file_buffer_size = GET_UINT(header, 12);
    file_buffer = HeapAlloc(GetProcessHeap(), 0, file_buffer_size + 1);
    if (!file_buffer) return FALSE;

    memcpy(file_buffer, header, 16);
    if (_hread(hFile, file_buffer + 16, file_buffer_size - 16) != file_buffer_size - 16)
    {WINE_WARN("filesize1\n"); return FALSE;};

    if (_hread(hFile, dummy, 1) != 0) WINE_WARN("filesize2\n");

    file_buffer[file_buffer_size] = '\0'; /* FIXME: was '0', sounds ackward to me */

    return TRUE;
}

/**************************************************************************
 * comp_FindSubFile
 *
 * HLPFILE_BPTreeCompare function for HLPFILE directory.
 *
 */
static int comp_FindSubFile(void *p, const void *key,
                            int leaf, void** next)
{
    *next = (char *)p+strlen(p)+(leaf?5:3);
    WINE_TRACE("Comparing '%s' with '%s'\n", (char *)p, (char *)key);
    return strcmp(p, key);
}

/***********************************************************************
 *
 *           HLPFILE_FindSubFile
 */
static BOOL HLPFILE_FindSubFile(LPCSTR name, BYTE **subbuf, BYTE **subend)
{
    BYTE *ptr;

    WINE_TRACE("looking for file '%s'\n", name);
    ptr = HLPFILE_BPTreeSearch(file_buffer + GET_UINT(file_buffer, 4),
                               name, comp_FindSubFile);
    if (!ptr) return FALSE;
    *subbuf = file_buffer + GET_UINT(ptr, strlen(name)+1);
    if (*subbuf >= file_buffer + file_buffer_size)
    {
        WINE_ERR("internal file %s does not fit\n", name);
        return FALSE;
    }
    *subend = *subbuf + GET_UINT(*subbuf, 0);
    if (*subend > file_buffer + file_buffer_size)
    {
        WINE_ERR("internal file %s does not fit\n", name);
        return FALSE;
    }
    if (GET_UINT(*subbuf, 0) < GET_UINT(*subbuf, 4) + 9)
    {
        WINE_ERR("invalid size provided for internal file %s\n", name);
        return FALSE;
    }
    return TRUE;
}

/***********************************************************************
 *
 *           HLPFILE_SystemCommands
 */
static BOOL HLPFILE_SystemCommands(HLPFILE* hlpfile)
{
    BYTE *buf, *ptr, *end;
    HLPFILE_MACRO *macro, **m;
    LPSTR p;
    unsigned short magic, minor, major, flags;

    hlpfile->lpszTitle = NULL;

    if (!HLPFILE_FindSubFile("|SYSTEM", &buf, &end)) return FALSE;

    magic = GET_USHORT(buf + 9, 0);
    minor = GET_USHORT(buf + 9, 2);
    major = GET_USHORT(buf + 9, 4);
    /* gen date on 4 bytes */
    flags = GET_USHORT(buf + 9, 10);
    WINE_TRACE("Got system header: magic=%04x version=%d.%d flags=%04x\n",
               magic, major, minor, flags);
    if (magic != 0x036C || major != 1)
    {WINE_WARN("Wrong system header\n"); return FALSE;}
    if (minor <= 16)
    {
        hlpfile->tbsize = 0x800;
        hlpfile->compressed = 0;
    }
    else if (flags == 0)
    {
        hlpfile->tbsize = 0x1000;
        hlpfile->compressed = 0;
    }
    else if (flags == 4)
    {
        hlpfile->tbsize = 0x1000;
        hlpfile->compressed = 1;
    }
    else
    {
        hlpfile->tbsize = 0x800;
        hlpfile->compressed = 1;
    }

    if (hlpfile->compressed)
        hlpfile->dsize = 0x4000;
    else
        hlpfile->dsize = hlpfile->tbsize - 0x0C;

    hlpfile->version = minor;
    hlpfile->flags = flags;

    for (ptr = buf + 0x15; ptr + 4 <= end; ptr += GET_USHORT(ptr, 2) + 4)
    {
        char *str = (char*) ptr + 4;
        switch (GET_USHORT(ptr, 0))
	{
	case 1:
            if (hlpfile->lpszTitle) {WINE_WARN("title\n"); break;}
            hlpfile->lpszTitle = HeapAlloc(GetProcessHeap(), 0, strlen(str) + 1);
            if (!hlpfile->lpszTitle) return FALSE;
            lstrcpy(hlpfile->lpszTitle, str);
            WINE_TRACE("Title: %s\n", hlpfile->lpszTitle);
            break;

	case 2:
            if (hlpfile->lpszCopyright) {WINE_WARN("copyright\n"); break;}
            hlpfile->lpszCopyright = HeapAlloc(GetProcessHeap(), 0, strlen(str) + 1);
            if (!hlpfile->lpszCopyright) return FALSE;
            lstrcpy(hlpfile->lpszCopyright, str);
            WINE_TRACE("Copyright: %s\n", hlpfile->lpszCopyright);
            break;

	case 3:
            if (GET_USHORT(ptr, 2) != 4) {WINE_WARN("system3\n");break;}
            hlpfile->contents_start = GET_UINT(ptr, 4);
            WINE_TRACE("Setting contents start at %08lx\n", hlpfile->contents_start);
            break;

	case 4:
            macro = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_MACRO) + lstrlen(str) + 1);
            if (!macro) break;
            p = (char*)macro + sizeof(HLPFILE_MACRO);
            lstrcpy(p, str);
            macro->lpszMacro = p;
            macro->next = 0;
            for (m = &hlpfile->first_macro; *m; m = &(*m)->next);
            *m = macro;
            break;

        case 6:
            if (GET_USHORT(ptr, 2) != 90) {WINE_WARN("system6\n");break;}

	    if (hlpfile->windows) 
        	hlpfile->windows = HeapReAlloc(GetProcessHeap(), 0, hlpfile->windows, 
                                           sizeof(HLPFILE_WINDOWINFO) * ++hlpfile->numWindows);
	    else 
        	hlpfile->windows = HeapAlloc(GetProcessHeap(), 0, 
                                           sizeof(HLPFILE_WINDOWINFO) * ++hlpfile->numWindows);
	    
            if (hlpfile->windows)
            {
                unsigned flags = GET_USHORT(ptr, 4);
                HLPFILE_WINDOWINFO* wi = &hlpfile->windows[hlpfile->numWindows - 1];

                if (flags & 0x0001) strcpy(wi->type, &str[2]);
                else wi->type[0] = '\0';
                if (flags & 0x0002) strcpy(wi->name, &str[12]);
                else wi->name[0] = '\0';
                if (flags & 0x0004) strcpy(wi->caption, &str[23]);
                else lstrcpynA(wi->caption, hlpfile->lpszTitle, sizeof(wi->caption));
                wi->origin.x = (flags & 0x0008) ? GET_USHORT(ptr, 76) : CW_USEDEFAULT;
                wi->origin.y = (flags & 0x0010) ? GET_USHORT(ptr, 78) : CW_USEDEFAULT;
                wi->size.cx = (flags & 0x0020) ? GET_USHORT(ptr, 80) : CW_USEDEFAULT;
                wi->size.cy = (flags & 0x0040) ? GET_USHORT(ptr, 82) : CW_USEDEFAULT;
                wi->style = (flags & 0x0080) ? GET_USHORT(ptr, 84) : SW_SHOW;
                wi->win_style = WS_OVERLAPPEDWINDOW;
                wi->sr_color = (flags & 0x0100) ? GET_UINT(ptr, 86) : 0xFFFFFF;
                wi->nsr_color = (flags & 0x0200) ? GET_UINT(ptr, 90) : 0xFFFFFF;
                WINE_TRACE("System-Window: flags=%c%c%c%c%c%c%c%c type=%s name=%s caption=%s (%d,%d)x(%d,%d)\n",
                           flags & 0x0001 ? 'T' : 't',
                           flags & 0x0002 ? 'N' : 'n',
                           flags & 0x0004 ? 'C' : 'c',
                           flags & 0x0008 ? 'X' : 'x',
                           flags & 0x0010 ? 'Y' : 'y',
                           flags & 0x0020 ? 'W' : 'w',
                           flags & 0x0040 ? 'H' : 'h',
                           flags & 0x0080 ? 'S' : 's',
                           wi->type, wi->name, wi->caption, wi->origin.x, wi->origin.y,
                           wi->size.cx, wi->size.cy);
            }
            break;
	default:
            WINE_WARN("Unsupported SystemRecord[%d]\n", GET_USHORT(ptr, 0));
	}
    }
    if (!hlpfile->lpszTitle)
        hlpfile->lpszTitle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1);
    return TRUE;
}

/***********************************************************************
 *
 *           HLPFILE_UncompressedLZ77_Size
 */
static INT HLPFILE_UncompressedLZ77_Size(BYTE *ptr, BYTE *end)
{
    int  i, newsize = 0;

    while (ptr < end)
    {
        int mask = *ptr++;
        for (i = 0; i < 8 && ptr < end; i++, mask >>= 1)
	{
            if (mask & 1)
	    {
                int code = GET_USHORT(ptr, 0);
                int len  = 3 + (code >> 12);
                newsize += len;
                ptr     += 2;
	    }
            else newsize++, ptr++;
	}
    }

    return newsize;
}

/***********************************************************************
 *
 *           HLPFILE_UncompressLZ77
 */
static BYTE *HLPFILE_UncompressLZ77(BYTE *ptr, BYTE *end, BYTE *newptr)
{
    int i;

    while (ptr < end)
    {
        int mask = *ptr++;
        for (i = 0; i < 8 && ptr < end; i++, mask >>= 1)
	{
            if (mask & 1)
	    {
                int code   = GET_USHORT(ptr, 0);
                int len    = 3 + (code >> 12);
                int offset = code & 0xfff;
                /*
                 * We must copy byte-by-byte here. We cannot use memcpy nor
                 * memmove here. Just example:
                 * a[]={1,2,3,4,5,6,7,8,9,10}
                 * newptr=a+2;
                 * offset=1;
                 * We expect:
                 * {1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 11, 12}
                 */
                for (; len>0; len--, newptr++) *newptr = *(newptr-offset-1);
                ptr    += 2;
	    }
            else *newptr++ = *ptr++;
	}
    }

    return newptr;
}

/***********************************************************************
 *
 *           HLPFILE_UncompressLZ77_Phrases
 */
static BOOL HLPFILE_UncompressLZ77_Phrases(HLPFILE* hlpfile)
{
    UINT i, num, dec_size, head_size;
    BYTE *buf, *end;

    if (!HLPFILE_FindSubFile("|Phrases", &buf, &end)) return FALSE;

    if (hlpfile->version <= 16)
        head_size = 13;
    else
        head_size = 17;

    num = phrases.num = GET_USHORT(buf, 9);
    if (buf + 2 * num + 0x13 >= end) {WINE_WARN("1a\n"); return FALSE;};

    if (hlpfile->version <= 16)
        dec_size = end - buf - 15 - 2 * num;
    else
        dec_size = HLPFILE_UncompressedLZ77_Size(buf + 0x13 + 2 * num, end);

    phrases.offsets = HeapAlloc(GetProcessHeap(), 0, sizeof(unsigned) * (num + 1));
    phrases.buffer  = HeapAlloc(GetProcessHeap(), 0, dec_size);
    if (!phrases.offsets || !phrases.buffer)
    {
        HeapFree(GetProcessHeap(), 0, phrases.offsets);
        HeapFree(GetProcessHeap(), 0, phrases.buffer);
        return FALSE;
    }

    for (i = 0; i <= num; i++)
        phrases.offsets[i] = GET_USHORT(buf, head_size + 2 * i) - 2 * num - 2;

    if (hlpfile->version <= 16)
        memcpy(phrases.buffer, buf + 15 + 2*num, dec_size);
    else
        HLPFILE_UncompressLZ77(buf + 0x13 + 2 * num, end, (BYTE*)phrases.buffer);

    hlpfile->hasPhrases = TRUE;
    return TRUE;
}

/***********************************************************************
 *
 *           HLPFILE_Uncompress_Phrases40
 */
static BOOL HLPFILE_Uncompress_Phrases40(HLPFILE* hlpfile)
{
    UINT num;
    INT dec_size, cpr_size;
    BYTE *buf_idx, *end_idx;
    BYTE *buf_phs, *end_phs;
    long* ptr, mask = 0;
    unsigned int i;
    unsigned short bc, n;

    if (!HLPFILE_FindSubFile("|PhrIndex", &buf_idx, &end_idx) ||
        !HLPFILE_FindSubFile("|PhrImage", &buf_phs, &end_phs)) return FALSE;

    ptr = (long*)(buf_idx + 9 + 28);
    bc = GET_USHORT(buf_idx, 9 + 24) & 0x0F;
    num = phrases.num = GET_USHORT(buf_idx, 9 + 4);

    WINE_TRACE("Index: Magic=%08x #entries=%u CpsdSize=%u PhrImgSize=%u\n"
               "\tPhrImgCprsdSize=%u 0=%u bc=%x ukn=%x\n",
               GET_UINT(buf_idx, 9 + 0),
               GET_UINT(buf_idx, 9 + 4),
               GET_UINT(buf_idx, 9 + 8),
               GET_UINT(buf_idx, 9 + 12),
               GET_UINT(buf_idx, 9 + 16),
               GET_UINT(buf_idx, 9 + 20),
               GET_USHORT(buf_idx, 9 + 24),
               GET_USHORT(buf_idx, 9 + 26));

    dec_size = GET_UINT(buf_idx, 9 + 12);
    cpr_size = GET_UINT(buf_idx, 9 + 16);

    if (dec_size != cpr_size &&
        dec_size != HLPFILE_UncompressedLZ77_Size(buf_phs + 9, end_phs))
    {
        WINE_WARN("size mismatch %u %u\n",
                  dec_size, HLPFILE_UncompressedLZ77_Size(buf_phs + 9, end_phs));
        dec_size = max(dec_size, HLPFILE_UncompressedLZ77_Size(buf_phs + 9, end_phs));
    }

    phrases.offsets = HeapAlloc(GetProcessHeap(), 0, sizeof(unsigned) * (num + 1));
    phrases.buffer  = HeapAlloc(GetProcessHeap(), 0, dec_size);
    if (!phrases.offsets || !phrases.buffer)
    {
        HeapFree(GetProcessHeap(), 0, phrases.offsets);
        HeapFree(GetProcessHeap(), 0, phrases.buffer);
        return FALSE;
    }

#define getbit() (ptr += (mask < 0), mask = mask*2 + (mask<=0), (*ptr & mask) != 0)

    phrases.offsets[0] = 0;
    for (i = 0; i < num; i++)
    {
        for (n = 1; getbit(); n += 1 << bc);
        if (getbit()) n++;
        if (bc > 1 && getbit()) n += 2;
        if (bc > 2 && getbit()) n += 4;
        if (bc > 3 && getbit()) n += 8;
        if (bc > 4 && getbit()) n += 16;
        phrases.offsets[i + 1] = phrases.offsets[i] + n;
    }
#undef getbit

    if (dec_size == cpr_size)
        memcpy(phrases.buffer, buf_phs + 9, dec_size);
    else
        HLPFILE_UncompressLZ77(buf_phs + 9, end_phs, (BYTE*)phrases.buffer);

    hlpfile->hasPhrases40 = TRUE;
    return TRUE;
}

/***********************************************************************
 *
 *           HLPFILE_Uncompress_Topic
 */
static BOOL HLPFILE_Uncompress_Topic(HLPFILE* hlpfile)
{
    BYTE *buf, *ptr, *end, *newptr;
    unsigned int i, newsize = 0;
    unsigned int topic_size;

    if (!HLPFILE_FindSubFile("|TOPIC", &buf, &end))
    {WINE_WARN("topic0\n"); return FALSE;}

    buf += 9; /* Skip file header */
    topic_size = end - buf;
    if (hlpfile->compressed)
    {
        topic.wMapLen = (topic_size - 1) / hlpfile->tbsize + 1;

        for (i = 0; i < topic.wMapLen; i++)
        {
            ptr = buf + i * hlpfile->tbsize;

            /* I don't know why, it's necessary for printman.hlp */
            if (ptr + 0x44 > end) ptr = end - 0x44;

            newsize += HLPFILE_UncompressedLZ77_Size(ptr + 0xc, min(end, ptr + hlpfile->tbsize));
        }

        topic.map = HeapAlloc(GetProcessHeap(), 0,
                              topic.wMapLen * sizeof(topic.map[0]) + newsize);
        if (!topic.map) return FALSE;
        newptr = (BYTE*)(topic.map + topic.wMapLen);
        topic.end = newptr + newsize;

        for (i = 0; i < topic.wMapLen; i++)
        {
            ptr = buf + i * hlpfile->tbsize;
            if (ptr + 0x44 > end) ptr = end - 0x44;

            topic.map[i] = newptr;
            newptr = HLPFILE_UncompressLZ77(ptr + 0xc, min(end, ptr + hlpfile->tbsize), newptr);
        }
    }
    else
    {
        /* basically, we need to copy the TopicBlockSize byte pages
         * (removing the first 0x0C) in one single area in memory
         */
        topic.wMapLen = (topic_size - 1) / hlpfile->tbsize + 1;
        topic.map = HeapAlloc(GetProcessHeap(), 0,
                              topic.wMapLen * (sizeof(topic.map[0]) + hlpfile->dsize));
        if (!topic.map) return FALSE;
        newptr = (BYTE*)(topic.map + topic.wMapLen);
        topic.end = newptr + topic_size;

        for (i = 0; i < topic.wMapLen; i++)
        {
            topic.map[i] = newptr + i * hlpfile->dsize;
            memcpy(topic.map[i], buf + i * hlpfile->tbsize + 0x0C, hlpfile->dsize);
        }
    }
    return TRUE;
}

/***********************************************************************
 *
 *           HLPFILE_Uncompress2
 */

static void HLPFILE_Uncompress2(const BYTE *ptr, const BYTE *end, BYTE *newptr, const BYTE *newend)
{
    BYTE *phptr, *phend;
    UINT code;
    UINT index;

    while (ptr < end && newptr < newend)
    {
        if (!*ptr || *ptr >= 0x10)
            *newptr++ = *ptr++;
        else
	{
            code  = 0x100 * ptr[0] + ptr[1];
            index = (code - 0x100) / 2;

            phptr = (BYTE*)phrases.buffer + phrases.offsets[index];
            phend = (BYTE*)phrases.buffer + phrases.offsets[index + 1];

            if (newptr + (phend - phptr) > newend)
            {
                WINE_FIXME("buffer overflow %p > %p for %d bytes\n", 
                           newptr, newend, phend - phptr);
                return;
            }
            memcpy(newptr, phptr, phend - phptr);
            newptr += phend - phptr;
            if (code & 1) *newptr++ = ' ';

            ptr += 2;
	}
    }
    if (newptr > newend) WINE_FIXME("buffer overflow %p > %p\n", newptr, newend);
}

/******************************************************************
 *		HLPFILE_Uncompress3
 *
 *
 */
static BOOL HLPFILE_Uncompress3(char* dst, const char* dst_end,
                                const BYTE* src, const BYTE* src_end)
{
    unsigned int idx, len;

    for (; src < src_end; src++)
    {
        if ((*src & 1) == 0)
        {
            idx = *src / 2;
            if (idx > phrases.num) 
            {
                WINE_ERR("index in phrases %d/%d\n", idx, phrases.num);
                len = 0;
            }
            else 
            {
                len = phrases.offsets[idx + 1] - phrases.offsets[idx];
                if (dst + len <= dst_end)
                    memcpy(dst, &phrases.buffer[phrases.offsets[idx]], len);
            }
        }
        else if ((*src & 0x03) == 0x01)
        {
            idx = (*src + 1) * 64;
            idx += *++src;
            if (idx > phrases.num) 
            {
                WINE_ERR("index in phrases %d/%d\n", idx, phrases.num);
                len = 0;
            }
            else
            {
                len = phrases.offsets[idx + 1] - phrases.offsets[idx];
                if (dst + len <= dst_end)
                    memcpy(dst, &phrases.buffer[phrases.offsets[idx]], len);
            }
        }
        else if ((*src & 0x07) == 0x03)
        {
            len = (*src / 8) + 1;
            if (dst + len <= dst_end)
                memcpy(dst, src + 1, len);
            src += len;
        }
        else
        {
            len = (*src / 16) + 1;
            if (dst + len <= dst_end)
                memset(dst, ((*src & 0x0F) == 0x07) ? ' ' : 0, len);
        }
        dst += len;
    }

    if (dst > dst_end) WINE_ERR("buffer overflow (%p > %p)\n", dst, dst_end);
    return TRUE;
}

/******************************************************************
 *		HLPFILE_UncompressRLE
 *
 *
 */
static void HLPFILE_UncompressRLE(const BYTE* src, const BYTE* end, BYTE** dst, unsigned dstsz)
{
    BYTE        ch;
    BYTE*       sdst = *dst + dstsz;

    while (src < end)
    {
        ch = *src++;
        if (ch & 0x80)
        {
            ch &= 0x7F;
            if ((*dst) + ch <= sdst)
                memcpy(*dst, src, ch);
            src += ch;
        }
        else
        {
            if ((*dst) + ch <= sdst)
                memset(*dst, (char)*src, ch);
            src++;
        }
        *dst += ch;
    }
    if (*dst != sdst)
        WINE_WARN("Buffer X-flow: d(%u) instead of d(%u)\n",
                  *dst - (sdst - dstsz), dstsz);
}

/**************************************************************************
 * HLPFILE_BPTreeSearch
 *
 * Searches for an element in B+ tree
 *
 * PARAMS
 *     buf        [I] pointer to the embedded file structured as a B+ tree
 *     key        [I] pointer to data to find
 *     comp       [I] compare function
 *
 * RETURNS
 *     Pointer to block identified by key, or NULL if failure.
 *
 */
void* HLPFILE_BPTreeSearch(BYTE* buf, const void* key,
                           HLPFILE_BPTreeCompare comp)
{
    unsigned magic;
    unsigned page_size;
    unsigned cur_page;
    unsigned level;
    BYTE *pages, *ptr, *newptr;
    int i, entries;
    int ret;

    magic = GET_USHORT(buf, 9);
    if (magic != 0x293B)
    {
        WINE_ERR("Invalid magic in B+ tree: 0x%x\n", magic);
        return NULL;
    }
    page_size = GET_USHORT(buf, 9+4);
    cur_page  = GET_USHORT(buf, 9+26);
    level     = GET_USHORT(buf, 9+32);
    pages     = buf + 9 + 38;
    while (--level > 0)
    {
        ptr = pages + cur_page*page_size;
        entries = GET_SHORT(ptr, 2);
        ptr += 6;
        for (i = 0; i < entries; i++)
        {
            if (comp(ptr, key, 0, (void **)&newptr) > 0) break;
            ptr = newptr;
        }
        cur_page = GET_USHORT(ptr-2, 0);
    }
    ptr = pages + cur_page*page_size;
    entries = GET_SHORT(ptr, 2);
    ptr += 8;
    for (i = 0; i < entries; i++)
    {
        ret = comp(ptr, key, 1, (void **)&newptr);
        if (ret == 0) return ptr;
        if (ret > 0) return NULL;
        ptr = newptr;
    }
    return NULL;
}

/**************************************************************************
 * HLPFILE_BPTreeEnum
 *
 * Enumerates elements in B+ tree.
 *
 * PARAMS
 *     buf        [I]  pointer to the embedded file structured as a B+ tree
 *     cb         [I]  compare function
 *     cookie     [IO] cookie for cb function
 */
void HLPFILE_BPTreeEnum(BYTE* buf, HLPFILE_BPTreeCallback cb, void* cookie)
{
    unsigned magic;
    unsigned page_size;
    unsigned cur_page;
    unsigned level;
    BYTE *pages, *ptr, *newptr;
    int i, entries;

    magic = GET_USHORT(buf, 9);
    if (magic != 0x293B)
    {
        WINE_ERR("Invalid magic in B+ tree: 0x%x\n", magic);
        return;
    }
    page_size = GET_USHORT(buf, 9+4);
    cur_page  = GET_USHORT(buf, 9+26);
    level     = GET_USHORT(buf, 9+32);
    pages     = buf + 9 + 38;
    while (--level > 0)
    {
        ptr = pages + cur_page*page_size;
        cur_page = GET_USHORT(ptr, 4);
    }
    while (cur_page != 0xFFFF)
    {
        ptr = pages + cur_page*page_size;
        entries = GET_SHORT(ptr, 2);
        ptr += 8;
        for (i = 0; i < entries; i++)
        {
            cb(ptr, (void **)&newptr, cookie);
            ptr = newptr;
        }
        cur_page = GET_USHORT(pages+cur_page*page_size, 6);
    }
}


/***********************************************************************
 *
 *           HLPFILE_GetContext
 */
static BOOL HLPFILE_GetContext(HLPFILE *hlpfile)
{
    BYTE                *cbuf, *cend;
    unsigned            clen;

    if (!HLPFILE_FindSubFile("|CONTEXT",  &cbuf, &cend)) {WINE_WARN("context0\n"); return FALSE;}

    clen = cend - cbuf;
    hlpfile->Context = HeapAlloc(GetProcessHeap(), 0, clen);
    if (!hlpfile->Context) return FALSE;
    memcpy(hlpfile->Context, cbuf, clen);

    return TRUE;
}

/***********************************************************************
 *
 *           HLPFILE_GetKeywords
 */
static BOOL HLPFILE_GetKeywords(HLPFILE *hlpfile)
{
    BYTE                *cbuf, *cend;
    unsigned            clen;

    if (!HLPFILE_FindSubFile("|KWBTREE",  &cbuf, &cend)) return FALSE;
    clen = cend - cbuf;
    hlpfile->kwbtree = HeapAlloc(GetProcessHeap(), 0, clen);
    if (!hlpfile->kwbtree) return FALSE;
    memcpy(hlpfile->kwbtree, cbuf, clen);

    if (!HLPFILE_FindSubFile("|KWDATA",  &cbuf, &cend))
    {
        WINE_ERR("corrupted help file: kwbtree present but kwdata absent\n");
        HeapFree(GetProcessHeap(), 0, hlpfile->kwbtree);
        return FALSE;
    }
    clen = cend - cbuf;
    hlpfile->kwdata = HeapAlloc(GetProcessHeap(), 0, clen);
    if (!hlpfile->kwdata)
    {
        HeapFree(GetProcessHeap(), 0, hlpfile->kwdata);
        return FALSE;
    }
    memcpy(hlpfile->kwdata, cbuf, clen);

    return TRUE;
}

/***********************************************************************
 *
 *           HLPFILE_GetMap
 */
static BOOL HLPFILE_GetMap(HLPFILE *hlpfile)
{
    BYTE                *cbuf, *cend;
    unsigned            entries, i;

    if (!HLPFILE_FindSubFile("|CTXOMAP",  &cbuf, &cend)) {WINE_WARN("no map section\n"); return FALSE;}

    entries = GET_USHORT(cbuf, 9);
    hlpfile->Map = HeapAlloc(GetProcessHeap(), 0, entries * sizeof(HLPFILE_MAP));
    if (!hlpfile->Map) return FALSE;
    hlpfile->wMapLen = entries;
    for (i = 0; i < entries; i++)
    {
        hlpfile->Map[i].lMap = GET_UINT(cbuf+11,i*8);
        hlpfile->Map[i].offset = GET_UINT(cbuf+11,i*8+4);
    }
    return TRUE;
}

/******************************************************************
 *		HLPFILE_DeleteLink
 *
 *
 */
void HLPFILE_FreeLink(HLPFILE_LINK* link)
{
    if (link && !--link->wRefCount)
        HeapFree(GetProcessHeap(), 0, link);
}

/***********************************************************************
 *
 *           HLPFILE_DeleteParagraph
 */
static void HLPFILE_DeleteParagraph(HLPFILE_PARAGRAPH* paragraph)
{
    HLPFILE_PARAGRAPH* next;

    while (paragraph)
    {
        next = paragraph->next;

        if (paragraph->cookie == para_metafile)
            DeleteMetaFile(paragraph->u.gfx.u.mfp.hMF);

        HLPFILE_FreeLink(paragraph->link);

        HeapFree(GetProcessHeap(), 0, paragraph);
        paragraph = next;
    }
}

/***********************************************************************
 *
 *           DeleteMacro
 */
static void HLPFILE_DeleteMacro(HLPFILE_MACRO* macro)
{
    HLPFILE_MACRO*      next;

    while (macro)
    {
        next = macro->next;
        HeapFree(GetProcessHeap(), 0, macro);
        macro = next;
    }
}

/***********************************************************************
 *
 *           DeletePage
 */
static void HLPFILE_DeletePage(HLPFILE_PAGE* page)
{
    HLPFILE_PAGE* next;

    while (page)
    {
        next = page->next;
        HLPFILE_DeleteParagraph(page->first_paragraph);
        HLPFILE_DeleteMacro(page->first_macro);
        HeapFree(GetProcessHeap(), 0, page);
        page = next;
    }
}

/***********************************************************************
 *
 *           HLPFILE_FreeHlpFile
 */
void HLPFILE_FreeHlpFile(HLPFILE* hlpfile)
{
    unsigned i;

    if (!hlpfile || --hlpfile->wRefCount > 0) return;

    if (hlpfile->next) hlpfile->next->prev = hlpfile->prev;
    if (hlpfile->prev) hlpfile->prev->next = hlpfile->next;
    else first_hlpfile = hlpfile->next;

    if (hlpfile->numFonts)
    {
        for (i = 0; i < hlpfile->numFonts; i++)
        {
            DeleteObject(hlpfile->fonts[i].hFont);
        }
        HeapFree(GetProcessHeap(), 0, hlpfile->fonts);
    }

    if (hlpfile->numBmps)
    {
        for (i = 0; i < hlpfile->numBmps; i++)
        {
            DeleteObject(hlpfile->bmps[i]);
        }
        HeapFree(GetProcessHeap(), 0, hlpfile->bmps);
    }

    HLPFILE_DeletePage(hlpfile->first_page);
    HLPFILE_DeleteMacro(hlpfile->first_macro);

    if (hlpfile->numWindows)    HeapFree(GetProcessHeap(), 0, hlpfile->windows);
    HeapFree(GetProcessHeap(), 0, hlpfile->Context);
    HeapFree(GetProcessHeap(), 0, hlpfile->Map);
    HeapFree(GetProcessHeap(), 0, hlpfile->lpszTitle);
    HeapFree(GetProcessHeap(), 0, hlpfile->lpszCopyright);
    HeapFree(GetProcessHeap(), 0, hlpfile);
}
