/*
 * CHM Utility API
 *
 * Copyright 2005 James Hawkins
 * Copyright 2007 Jacek Caban
 *
 * 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 "winreg.h"
#include "shlwapi.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp);

/* Reads a string from the #STRINGS section in the CHM file */
static LPCSTR GetChmString(CHMInfo *chm, DWORD offset)
{
    LPCSTR str;

    if(!chm->strings_stream)
        return NULL;

    if(chm->strings_size <= (offset >> BLOCK_BITS)) {
        chm->strings_size = (offset >> BLOCK_BITS)+1;
        if(chm->strings)
            chm->strings = heap_realloc_zero(chm->strings,
                    chm->strings_size*sizeof(char*));
        else
            chm->strings = heap_alloc_zero(
                    chm->strings_size*sizeof(char*));

    }

    if(!chm->strings[offset >> BLOCK_BITS]) {
        LARGE_INTEGER pos;
        DWORD read;
        HRESULT hres;

        pos.QuadPart = offset & ~BLOCK_MASK;
        hres = IStream_Seek(chm->strings_stream, pos, STREAM_SEEK_SET, NULL);
        if(FAILED(hres)) {
            WARN("Seek failed: %08x\n", hres);
            return NULL;
        }

        chm->strings[offset >> BLOCK_BITS] = heap_alloc(BLOCK_SIZE);

        hres = IStream_Read(chm->strings_stream, chm->strings[offset >> BLOCK_BITS],
                            BLOCK_SIZE, &read);
        if(FAILED(hres)) {
            WARN("Read failed: %08x\n", hres);
            heap_free(chm->strings[offset >> BLOCK_BITS]);
            chm->strings[offset >> BLOCK_BITS] = NULL;
            return NULL;
        }
    }

    str = chm->strings[offset >> BLOCK_BITS] + (offset & BLOCK_MASK);
    TRACE("offset %#x => %s\n", offset, debugstr_a(str));
    return str;
}

static BOOL ReadChmSystem(CHMInfo *chm)
{
    IStream *stream;
    DWORD ver=0xdeadbeef, read, buf_size;
    char *buf;
    HRESULT hres;

    struct {
        WORD code;
        WORD len;
    } entry;

    static const WCHAR wszSYSTEM[] = {'#','S','Y','S','T','E','M',0};

    hres = IStorage_OpenStream(chm->pStorage, wszSYSTEM, NULL, STGM_READ, 0, &stream);
    if(FAILED(hres)) {
        WARN("Could not open #SYSTEM stream: %08x\n", hres);
        return FALSE;
    }

    IStream_Read(stream, &ver, sizeof(ver), &read);
    TRACE("version is %x\n", ver);

    buf = heap_alloc(8*sizeof(DWORD));
    buf_size = 8*sizeof(DWORD);

    while(1) {
        hres = IStream_Read(stream, &entry, sizeof(entry), &read);
        if(hres != S_OK)
            break;

        if(entry.len > buf_size)
            buf = heap_realloc(buf, buf_size=entry.len);

        hres = IStream_Read(stream, buf, entry.len, &read);
        if(hres != S_OK)
            break;

        switch(entry.code) {
        case 0x0:
            TRACE("TOC is %s\n", debugstr_an(buf, entry.len));
            heap_free(chm->defToc);
            chm->defToc = strdupnAtoW(buf, entry.len);
            break;
        case 0x2:
            TRACE("Default topic is %s\n", debugstr_an(buf, entry.len));
            heap_free(chm->defTopic);
            chm->defTopic = strdupnAtoW(buf, entry.len);
            break;
        case 0x3:
            TRACE("Title is %s\n", debugstr_an(buf, entry.len));
            heap_free(chm->defTitle);
            chm->defTitle = strdupnAtoW(buf, entry.len);
            break;
        case 0x4:
            /* TODO: Currently only the Locale ID is loaded from this field */
            TRACE("Locale is: %d\n", *(LCID*)&buf[0]);
            if(!GetLocaleInfoW(*(LCID*)&buf[0], LOCALE_IDEFAULTANSICODEPAGE|LOCALE_RETURN_NUMBER,
                               (WCHAR *)&chm->codePage, sizeof(chm->codePage)/sizeof(WCHAR)))
                chm->codePage = CP_ACP;
            break;
        case 0x5:
            TRACE("Window name is %s\n", debugstr_an(buf, entry.len));
            chm->defWindow = strdupnAtoW(buf, entry.len);
            break;
        case 0x6:
            TRACE("Compiled file is %s\n", debugstr_an(buf, entry.len));
            heap_free(chm->compiledFile);
            chm->compiledFile = strdupnAtoW(buf, entry.len);
            break;
        case 0x9:
            TRACE("Version is %s\n", debugstr_an(buf, entry.len));
            break;
        case 0xa:
            TRACE("Time is %08x\n", *(DWORD*)buf);
            break;
        case 0xc:
            TRACE("Number of info types: %d\n", *(DWORD*)buf);
            break;
        case 0xf:
            TRACE("Check sum: %x\n", *(DWORD*)buf);
            break;
        default:
            TRACE("unhandled code %x, size %x\n", entry.code, entry.len);
        }
    }

    heap_free(buf);
    IStream_Release(stream);

    return SUCCEEDED(hres);
}

LPWSTR FindContextAlias(CHMInfo *chm, DWORD index)
{
    IStream *ivb_stream;
    DWORD size, read, i;
    DWORD *buf;
    LPCSTR ret = NULL;
    HRESULT hres;

    static const WCHAR wszIVB[] = {'#','I','V','B',0};

    hres = IStorage_OpenStream(chm->pStorage, wszIVB, NULL, STGM_READ, 0, &ivb_stream);
    if(FAILED(hres)) {
        WARN("Could not open #IVB stream: %08x\n", hres);
        return NULL;
    }

    hres = IStream_Read(ivb_stream, &size, sizeof(size), &read);
    if(FAILED(hres)) {
        WARN("Read failed: %08x\n", hres);
        IStream_Release(ivb_stream);
        return NULL;
    }

    buf = heap_alloc(size);
    hres = IStream_Read(ivb_stream, buf, size, &read);
    IStream_Release(ivb_stream);
    if(FAILED(hres)) {
        WARN("Read failed: %08x\n", hres);
        heap_free(buf);
        return NULL;
    }

    size /= 2*sizeof(DWORD);

    for(i=0; i<size; i++) {
        if(buf[2*i] == index) {
            ret = GetChmString(chm, buf[2*i+1]);
            break;
        }
    }

    heap_free(buf);

    TRACE("returning %s\n", debugstr_a(ret));
    return strdupAtoW(ret);
}

/*
 * Tests if the file <chmfile>.<ext> exists, used for loading Indices, Table of Contents, etc.
 * when these files are not available from the HH_WINTYPE structure.
 */
static WCHAR *FindHTMLHelpSetting(HHInfo *info, const WCHAR *extW)
{
    static const WCHAR periodW[] = {'.',0};
    IStorage *pStorage = info->pCHMInfo->pStorage;
    IStream *pStream;
    WCHAR *filename;
    HRESULT hr;

    filename = heap_alloc( (strlenW(info->pCHMInfo->compiledFile)
                            + strlenW(periodW) + strlenW(extW) + 1) * sizeof(WCHAR) );
    strcpyW(filename, info->pCHMInfo->compiledFile);
    strcatW(filename, periodW);
    strcatW(filename, extW);
    hr = IStorage_OpenStream(pStorage, filename, NULL, STGM_READ, 0, &pStream);
    if (FAILED(hr))
    {
        heap_free(filename);
        return strdupAtoW("");
    }
    IStream_Release(pStream);
    return filename;
}

static inline WCHAR *MergeChmString(LPCWSTR src, WCHAR **dst)
{
    if(*dst == NULL)
        *dst = strdupW(src);
    return *dst;
}

void MergeChmProperties(HH_WINTYPEW *src, HHInfo *info, BOOL override)
{
    DWORD unhandled_params = src->fsValidMembers & ~(HHWIN_PARAM_PROPERTIES|HHWIN_PARAM_STYLES
                             |HHWIN_PARAM_EXSTYLES|HHWIN_PARAM_RECT|HHWIN_PARAM_NAV_WIDTH
                             |HHWIN_PARAM_SHOWSTATE|HHWIN_PARAM_INFOTYPES|HHWIN_PARAM_TB_FLAGS
                             |HHWIN_PARAM_EXPANSION|HHWIN_PARAM_TABPOS|HHWIN_PARAM_TABORDER
                             |HHWIN_PARAM_HISTORY_COUNT|HHWIN_PARAM_CUR_TAB);
    HH_WINTYPEW *dst = &info->WinType;
    DWORD merge = override ? src->fsValidMembers : src->fsValidMembers & ~dst->fsValidMembers;

    if (unhandled_params)
        FIXME("Unsupported fsValidMembers fields: 0x%x\n", unhandled_params);

    dst->fsValidMembers |= merge;
    if (dst->cbStruct == 0)
    {
        /* If the structure has not been filled in yet then use all of the values */
        dst->cbStruct = sizeof(HH_WINTYPEW);
        merge = ~0;
    }
    if (merge & HHWIN_PARAM_PROPERTIES) dst->fsWinProperties = src->fsWinProperties;
    if (merge & HHWIN_PARAM_STYLES) dst->dwStyles = src->dwStyles;
    if (merge & HHWIN_PARAM_EXSTYLES) dst->dwExStyles = src->dwExStyles;
    if (merge & HHWIN_PARAM_RECT) dst->rcWindowPos = src->rcWindowPos;
    if (merge & HHWIN_PARAM_NAV_WIDTH) dst->iNavWidth = src->iNavWidth;
    if (merge & HHWIN_PARAM_SHOWSTATE) dst->nShowState = src->nShowState;
    if (merge & HHWIN_PARAM_INFOTYPES) dst->paInfoTypes = src->paInfoTypes;
    if (merge & HHWIN_PARAM_TB_FLAGS) dst->fsToolBarFlags = src->fsToolBarFlags;
    if (merge & HHWIN_PARAM_EXPANSION) dst->fNotExpanded = src->fNotExpanded;
    if (merge & HHWIN_PARAM_TABPOS) dst->tabpos = src->tabpos;
    if (merge & HHWIN_PARAM_TABORDER) memcpy(dst->tabOrder, src->tabOrder, sizeof(src->tabOrder));
    if (merge & HHWIN_PARAM_HISTORY_COUNT) dst->cHistory = src->cHistory;
    if (merge & HHWIN_PARAM_CUR_TAB) dst->curNavType = src->curNavType;

    /*
     * Note: We assume that hwndHelp, hwndCaller, hwndToolBar, hwndNavigation, and hwndHTML cannot be
     * modified by the user.  rcHTML and rcMinSize are not currently supported, so don't bother to copy them.
     */

    dst->pszType       = MergeChmString(src->pszType, &info->stringsW.pszType);
    dst->pszFile       = MergeChmString(src->pszFile, &info->stringsW.pszFile);
    dst->pszToc        = MergeChmString(src->pszToc, &info->stringsW.pszToc);
    dst->pszIndex      = MergeChmString(src->pszIndex, &info->stringsW.pszIndex);
    dst->pszCaption    = MergeChmString(src->pszCaption, &info->stringsW.pszCaption);
    dst->pszHome       = MergeChmString(src->pszHome, &info->stringsW.pszHome);
    dst->pszJump1      = MergeChmString(src->pszJump1, &info->stringsW.pszJump1);
    dst->pszJump2      = MergeChmString(src->pszJump2, &info->stringsW.pszJump2);
    dst->pszUrlJump1   = MergeChmString(src->pszUrlJump1, &info->stringsW.pszUrlJump1);
    dst->pszUrlJump2   = MergeChmString(src->pszUrlJump2, &info->stringsW.pszUrlJump2);

    /* FIXME: pszCustomTabs is a list of multiple zero-terminated strings so ReadString won't
     * work in this case
     */
#if 0
    dst->pszCustomTabs = MergeChmString(src->pszCustomTabs, &info->pszCustomTabs);
#endif
}

static inline WCHAR *ConvertChmString(HHInfo *info, const WCHAR **str)
{
    WCHAR *ret = NULL;

    if(*str)
        *str = ret = strdupAtoW(GetChmString(info->pCHMInfo, (DWORD_PTR)*str));
    return ret;
}

/* Loads the HH_WINTYPE data from the CHM file
 *
 * FIXME: There may be more than one window type in the file, so
 *        add the ability to choose a certain window type
 */
BOOL LoadWinTypeFromCHM(HHInfo *info)
{
    LARGE_INTEGER liOffset;
    WCHAR *pszType = NULL, *pszFile = NULL, *pszToc = NULL, *pszIndex = NULL, *pszCaption = NULL;
    WCHAR *pszHome = NULL, *pszJump1 = NULL, *pszJump2 = NULL, *pszUrlJump1 = NULL, *pszUrlJump2 = NULL;
    IStorage *pStorage = info->pCHMInfo->pStorage;
    IStream *pStream = NULL;
    HH_WINTYPEW wintype;
    HRESULT hr;
    DWORD cbRead;
    BOOL ret = FALSE;

    static const WCHAR null[] = {0};
    static const WCHAR toc_extW[] = {'h','h','c',0};
    static const WCHAR index_extW[] = {'h','h','k',0};
    static const WCHAR windowsW[] = {'#','W','I','N','D','O','W','S',0};

    hr = IStorage_OpenStream(pStorage, windowsW, NULL, STGM_READ, 0, &pStream);
    if (SUCCEEDED(hr))
    {
        /* jump past the #WINDOWS header */
        liOffset.QuadPart = sizeof(DWORD) * 2;

        hr = IStream_Seek(pStream, liOffset, STREAM_SEEK_SET, NULL);
        if (FAILED(hr)) goto done;

        /* read the HH_WINTYPE struct data */
        hr = IStream_Read(pStream, &wintype, sizeof(wintype), &cbRead);
        if (FAILED(hr)) goto done;

        /* convert the #STRINGS offsets to actual strings */
        pszType     = ConvertChmString(info, &wintype.pszType);
        pszFile     = ConvertChmString(info, &wintype.pszFile);
        pszToc      = ConvertChmString(info, &wintype.pszToc);
        pszIndex    = ConvertChmString(info, &wintype.pszIndex);
        pszCaption  = ConvertChmString(info, &wintype.pszCaption);
        pszHome     = ConvertChmString(info, &wintype.pszHome);
        pszJump1    = ConvertChmString(info, &wintype.pszJump1);
        pszJump2    = ConvertChmString(info, &wintype.pszJump2);
        pszUrlJump1 = ConvertChmString(info, &wintype.pszUrlJump1);
        pszUrlJump2 = ConvertChmString(info, &wintype.pszUrlJump2);
    }
    else
    {
        /* no defined window types so use (hopefully) sane defaults */
        static const WCHAR defaultwinW[] = {'d','e','f','a','u','l','t','w','i','n','\0'};
        memset(&wintype, 0, sizeof(wintype));
        wintype.cbStruct = sizeof(wintype);
        wintype.fUniCodeStrings = TRUE;
        wintype.pszType    = pszType     = strdupW(info->pCHMInfo->defWindow ? info->pCHMInfo->defWindow : defaultwinW);
        wintype.pszToc     = pszToc      = strdupW(info->pCHMInfo->defToc ? info->pCHMInfo->defToc : null);
        wintype.pszIndex   = pszIndex    = strdupW(null);
        wintype.fsValidMembers = 0;
        wintype.fsWinProperties = HHWIN_PROP_TRI_PANE;
        wintype.dwStyles = WS_POPUP;
        wintype.dwExStyles = 0;
        wintype.nShowState = SW_SHOW;
        wintype.curNavType = HHWIN_NAVTYPE_TOC;
    }

    /* merge the new data with any pre-existing HH_WINTYPE structure */
    MergeChmProperties(&wintype, info, FALSE);
    if (!info->WinType.pszCaption)
        info->WinType.pszCaption = info->stringsW.pszCaption = strdupW(info->pCHMInfo->defTitle ? info->pCHMInfo->defTitle : null);
    if (!info->WinType.pszFile)
        info->WinType.pszFile    = info->stringsW.pszFile    = strdupW(info->pCHMInfo->defTopic ? info->pCHMInfo->defTopic : null);
    if (!info->WinType.pszToc)
        info->WinType.pszToc     = info->stringsW.pszToc     = FindHTMLHelpSetting(info, toc_extW);
    if (!info->WinType.pszIndex)
        info->WinType.pszIndex   = info->stringsW.pszIndex   = FindHTMLHelpSetting(info, index_extW);

    heap_free(pszType);
    heap_free(pszFile);
    heap_free(pszToc);
    heap_free(pszIndex);
    heap_free(pszCaption);
    heap_free(pszHome);
    heap_free(pszJump1);
    heap_free(pszJump2);
    heap_free(pszUrlJump1);
    heap_free(pszUrlJump2);
    ret = TRUE;

done:
    if (pStream)
        IStream_Release(pStream);

    return ret;
}

LPCWSTR skip_schema(LPCWSTR url)
{
    static const WCHAR its_schema[] = {'i','t','s',':'};
    static const WCHAR msits_schema[] = {'m','s','-','i','t','s',':'};
    static const WCHAR mk_schema[] = {'m','k',':','@','M','S','I','T','S','t','o','r','e',':'};

    if(!strncmpiW(its_schema, url, sizeof(its_schema)/sizeof(WCHAR)))
        return url+sizeof(its_schema)/sizeof(WCHAR);
    if(!strncmpiW(msits_schema, url, sizeof(msits_schema)/sizeof(WCHAR)))
        return url+sizeof(msits_schema)/sizeof(WCHAR);
    if(!strncmpiW(mk_schema, url, sizeof(mk_schema)/sizeof(WCHAR)))
        return url+sizeof(mk_schema)/sizeof(WCHAR);

    return url;
}

void SetChmPath(ChmPath *file, LPCWSTR base_file, LPCWSTR path)
{
    LPCWSTR ptr;
    static const WCHAR separatorW[] = {':',':',0};

    path = skip_schema(path);

    ptr = strstrW(path, separatorW);
    if(ptr) {
        WCHAR chm_file[MAX_PATH];
        WCHAR rel_path[MAX_PATH];
        WCHAR base_path[MAX_PATH];
        LPWSTR p;

        strcpyW(base_path, base_file);
        p = strrchrW(base_path, '\\');
        if(p)
            *p = 0;

        memcpy(rel_path, path, (ptr-path)*sizeof(WCHAR));
        rel_path[ptr-path] = 0;

        PathCombineW(chm_file, base_path, rel_path);

        file->chm_file = strdupW(chm_file);
        ptr += 2;
    }else {
        file->chm_file = strdupW(base_file);
        ptr = path;
    }

    file->chm_index = strdupW(ptr);

    TRACE("ChmFile = {%s %s}\n", debugstr_w(file->chm_file), debugstr_w(file->chm_index));
}

IStream *GetChmStream(CHMInfo *info, LPCWSTR parent_chm, ChmPath *chm_file)
{
    IStorage *storage;
    IStream *stream = NULL;
    HRESULT hres;

    TRACE("%s (%s :: %s)\n", debugstr_w(parent_chm), debugstr_w(chm_file->chm_file),
          debugstr_w(chm_file->chm_index));

    if(parent_chm || chm_file->chm_file) {
        hres = IITStorage_StgOpenStorage(info->pITStorage,
                chm_file->chm_file ? chm_file->chm_file : parent_chm, NULL,
                STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &storage);
        if(FAILED(hres)) {
            WARN("Could not open storage: %08x\n", hres);
            return NULL;
        }
    }else {
        storage = info->pStorage;
        IStorage_AddRef(info->pStorage);
    }

    hres = IStorage_OpenStream(storage, chm_file->chm_index, NULL, STGM_READ, 0, &stream);
    IStorage_Release(storage);
    if(FAILED(hres))
        WARN("Could not open stream: %08x\n", hres);

    return stream;
}

/*
 * Retrieve a CHM document and parse the data from the <title> element to get the document's title.
 */
WCHAR *GetDocumentTitle(CHMInfo *info, LPCWSTR document)
{
    strbuf_t node, node_name, content;
    WCHAR *document_title = NULL;
    IStream *str = NULL;
    IStorage *storage;
    stream_t stream;
    HRESULT hres;

    TRACE("%s\n", debugstr_w(document));

    storage = info->pStorage;
    if(!storage) {
        WARN("Could not open storage to obtain the title for a document.\n");
        return NULL;
    }
    IStorage_AddRef(storage);

    hres = IStorage_OpenStream(storage, document, NULL, STGM_READ, 0, &str);
    IStorage_Release(storage);
    if(FAILED(hres))
        WARN("Could not open stream: %08x\n", hres);

    stream_init(&stream, str);
    strbuf_init(&node);
    strbuf_init(&content);
    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, "title")) {
            if(next_content(&stream, &content) && content.len > 1)
            {
                document_title = strdupnAtoW(&content.buf[1], content.len-1);
                FIXME("magic: %s\n", debugstr_w(document_title));
                break;
            }
        }

        strbuf_zero(&node);
    }

    strbuf_free(&node);
    strbuf_free(&content);
    strbuf_free(&node_name);
    IStream_Release(str);

    return document_title;
}

/* Opens the CHM file for reading */
CHMInfo *OpenCHM(LPCWSTR szFile)
{
    HRESULT hres;
    CHMInfo *ret;

    static const WCHAR wszSTRINGS[] = {'#','S','T','R','I','N','G','S',0};

    if (!(ret = heap_alloc_zero(sizeof(CHMInfo))))
        return NULL;
    ret->codePage = CP_ACP;

    if (!(ret->szFile = strdupW(szFile))) {
        heap_free(ret);
        return NULL;
    }

    hres = CoCreateInstance(&CLSID_ITStorage, NULL, CLSCTX_INPROC_SERVER,
            &IID_IITStorage, (void **) &ret->pITStorage) ;
    if(FAILED(hres)) {
        WARN("Could not create ITStorage: %08x\n", hres);
        return CloseCHM(ret);
    }

    hres = IITStorage_StgOpenStorage(ret->pITStorage, szFile, NULL,
            STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &ret->pStorage);
    if(FAILED(hres)) {
        WARN("Could not open storage: %08x\n", hres);
        return CloseCHM(ret);
    }
    hres = IStorage_OpenStream(ret->pStorage, wszSTRINGS, NULL, STGM_READ, 0,
            &ret->strings_stream);
    if(FAILED(hres)) {
        WARN("Could not open #STRINGS stream: %08x\n", hres);
        /* It's not critical, so we pass */
    }

    if(!ReadChmSystem(ret)) {
        WARN("Could not read #SYSTEM\n");
        return CloseCHM(ret);
    }

    return ret;
}

CHMInfo *CloseCHM(CHMInfo *chm)
{
    if(chm->pITStorage)
        IITStorage_Release(chm->pITStorage);

    if(chm->pStorage)
        IStorage_Release(chm->pStorage);

    if(chm->strings_stream)
        IStream_Release(chm->strings_stream);

    if(chm->strings_size) {
        DWORD i;

        for(i=0; i<chm->strings_size; i++)
            heap_free(chm->strings[i]);
    }

    heap_free(chm->strings);
    heap_free(chm->defWindow);
    heap_free(chm->defTitle);
    heap_free(chm->defTopic);
    heap_free(chm->defToc);
    heap_free(chm->szFile);
    heap_free(chm->compiledFile);
    heap_free(chm);

    return NULL;
}
