/*
 * Help Viewer Implementation
 *
 * Copyright 2005 James Hawkins
 * Copyright 2007 Jacek Caban for CodeWeavers
 * Copyright 2011 Owen Rudge 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 "wingdi.h"
#include "commctrl.h"
#include "wininet.h"

#include "wine/debug.h"

#include "resource.h"

WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp);

static LRESULT Help_OnSize(HWND hWnd);
static void ExpandContract(HHInfo *pHHInfo);

/* Window type defaults */

#define WINTYPE_DEFAULT_X           280
#define WINTYPE_DEFAULT_Y           100
#define WINTYPE_DEFAULT_WIDTH       740
#define WINTYPE_DEFAULT_HEIGHT      640
#define WINTYPE_DEFAULT_NAVWIDTH    250

#define TAB_TOP_PADDING     8
#define TAB_RIGHT_PADDING   4
#define TAB_MARGIN  8
#define EDIT_HEIGHT         20

struct list window_list = LIST_INIT(window_list);

static const WCHAR szEmpty[] = {0};

struct html_encoded_symbol {
    const char *html_code;
    char        ansi_symbol;
};

/*
 * Table mapping the conversion between HTML encoded symbols and their ANSI code page equivalent.
 * Note: Add additional entries in proper alphabetical order (a binary search is used on this table).
 */
struct html_encoded_symbol html_encoded_symbols[] =
{
    {"AElig",  0xC6},
    {"Aacute", 0xC1},
    {"Acirc",  0xC2},
    {"Agrave", 0xC0},
    {"Aring",  0xC5},
    {"Atilde", 0xC3},
    {"Auml",   0xC4},
    {"Ccedil", 0xC7},
    {"ETH",    0xD0},
    {"Eacute", 0xC9},
    {"Ecirc",  0xCA},
    {"Egrave", 0xC8},
    {"Euml",   0xCB},
    {"Iacute", 0xCD},
    {"Icirc",  0xCE},
    {"Igrave", 0xCC},
    {"Iuml",   0xCF},
    {"Ntilde", 0xD1},
    {"Oacute", 0xD3},
    {"Ocirc",  0xD4},
    {"Ograve", 0xD2},
    {"Oslash", 0xD8},
    {"Otilde", 0xD5},
    {"Ouml",   0xD6},
    {"THORN",  0xDE},
    {"Uacute", 0xDA},
    {"Ucirc",  0xDB},
    {"Ugrave", 0xD9},
    {"Uuml",   0xDC},
    {"Yacute", 0xDD},
    {"aacute", 0xE1},
    {"acirc",  0xE2},
    {"acute",  0xB4},
    {"aelig",  0xE6},
    {"agrave", 0xE0},
    {"amp",    '&'},
    {"aring",  0xE5},
    {"atilde", 0xE3},
    {"auml",   0xE4},
    {"brvbar", 0xA6},
    {"ccedil", 0xE7},
    {"cedil",  0xB8},
    {"cent",   0xA2},
    {"copy",   0xA9},
    {"curren", 0xA4},
    {"deg",    0xB0},
    {"divide", 0xF7},
    {"eacute", 0xE9},
    {"ecirc",  0xEA},
    {"egrave", 0xE8},
    {"eth",    0xF0},
    {"euml",   0xEB},
    {"frac12", 0xBD},
    {"frac14", 0xBC},
    {"frac34", 0xBE},
    {"gt",     '>'},
    {"iacute", 0xED},
    {"icirc",  0xEE},
    {"iexcl",  0xA1},
    {"igrave", 0xEC},
    {"iquest", 0xBF},
    {"iuml",   0xEF},
    {"laquo",  0xAB},
    {"lt",     '<'},
    {"macr",   0xAF},
    {"micro",  0xB5},
    {"middot", 0xB7},
    {"nbsp",   ' '},
    {"not",    0xAC},
    {"ntilde", 0xF1},
    {"oacute", 0xF3},
    {"ocirc",  0xF4},
    {"ograve", 0xF2},
    {"ordf",   0xAA},
    {"ordm",   0xBA},
    {"oslash", 0xF8},
    {"otilde", 0xF5},
    {"ouml",   0xF6},
    {"para",   0xB6},
    {"plusmn", 0xB1},
    {"pound",  0xA3},
    {"quot",   '"'},
    {"raquo",  0xBB},
    {"reg",    0xAE},
    {"sect",   0xA7},
    {"shy",    0xAD},
    {"sup1",   0xB9},
    {"sup2",   0xB2},
    {"sup3",   0xB3},
    {"szlig",  0xDF},
    {"thorn",  0xFE},
    {"times",  0xD7},
    {"uacute", 0xFA},
    {"ucirc",  0xFB},
    {"ugrave", 0xF9},
    {"uml",    0xA8},
    {"uuml",   0xFC},
    {"yacute", 0xFD},
    {"yen",    0xA5},
    {"yuml",   0xFF}
};

static inline BOOL navigation_visible(HHInfo *info)
{
    return ((info->WinType.fsWinProperties & HHWIN_PROP_TRI_PANE) && !info->WinType.fNotExpanded);
}

/* Loads a string from the resource file */
static LPWSTR HH_LoadString(DWORD dwID)
{
    LPWSTR string = NULL;
    LPCWSTR stringresource;
    int iSize;

    iSize = LoadStringW(hhctrl_hinstance, dwID, (LPWSTR)&stringresource, 0);

    string = heap_alloc((iSize + 2) * sizeof(WCHAR)); /* some strings (tab text) needs double-null termination */
    memcpy(string, stringresource, iSize*sizeof(WCHAR));
    string[iSize] = 0;

    return string;
}

static HRESULT navigate_url(HHInfo *info, LPCWSTR surl)
{
    VARIANT url;
    HRESULT hres;

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

    V_VT(&url) = VT_BSTR;
    V_BSTR(&url) = SysAllocString(surl);

    hres = IWebBrowser2_Navigate2(info->web_browser, &url, 0, 0, 0, 0);

    VariantClear(&url);

    if(FAILED(hres))
        TRACE("Navigation failed: %08x\n", hres);

    return hres;
}

BOOL NavigateToUrl(HHInfo *info, LPCWSTR surl)
{
    ChmPath chm_path;
    BOOL ret;
    HRESULT hres;

    static const WCHAR url_indicator[] = {':', '/', '/', 0};

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

    if (strstrW(surl, url_indicator)) {
        hres = navigate_url(info, surl);
        if(SUCCEEDED(hres))
            return TRUE;
    } /* look up in chm if it doesn't look like a full url */

    SetChmPath(&chm_path, info->pCHMInfo->szFile, surl);
    ret = NavigateToChm(info, chm_path.chm_file, chm_path.chm_index);

    heap_free(chm_path.chm_file);
    heap_free(chm_path.chm_index);

    return ret;
}

static BOOL AppendFullPathURL(LPCWSTR file, LPWSTR buf, LPCWSTR index)
{
    static const WCHAR url_format[] =
        {'m','k',':','@','M','S','I','T','S','t','o','r','e',':','%','s',':',':','%','s','%','s',0};
    static const WCHAR slash[] = {'/',0};
    static const WCHAR empty[] = {0};
    WCHAR full_path[MAX_PATH];

    TRACE("%s %p %s\n", debugstr_w(file), buf, debugstr_w(index));

    if(!GetFullPathNameW(file, sizeof(full_path)/sizeof(full_path[0]), full_path, NULL)) {
        WARN("GetFullPathName failed: %u\n", GetLastError());
        return FALSE;
    }

    wsprintfW(buf, url_format, full_path, (!index || index[0] == '/') ? empty : slash, index);
    return TRUE;
}

BOOL NavigateToChm(HHInfo *info, LPCWSTR file, LPCWSTR index)
{
    WCHAR buf[INTERNET_MAX_URL_LENGTH];

    TRACE("%p %s %s\n", info, debugstr_w(file), debugstr_w(index));

    if ((!info->web_browser) || !AppendFullPathURL(file, buf, index))
        return FALSE;

    return SUCCEEDED(navigate_url(info, buf));
}

static void DoSync(HHInfo *info)
{
    WCHAR buf[INTERNET_MAX_URL_LENGTH];
    HRESULT hres;
    BSTR url;

    hres = IWebBrowser2_get_LocationURL(info->web_browser, &url);

    if (FAILED(hres))
    {
        WARN("get_LocationURL failed: %08x\n", hres);
        return;
    }

    /* If we're not currently viewing a page in the active .chm file, abort */
    if ((!AppendFullPathURL(info->WinType.pszFile, buf, NULL)) || (lstrlenW(buf) > lstrlenW(url)))
    {
        SysFreeString(url);
        return;
    }

    if (lstrcmpiW(buf, url) > 0)
    {
        static const WCHAR delimW[] = {':',':','/',0};
        const WCHAR *index;

        index = strstrW(url, delimW);

        if (index)
            ActivateContentTopic(info->tabs[TAB_CONTENTS].hwnd, index + 3, info->content); /* skip over ::/ */
    }

    SysFreeString(url);
}

/* Size Bar */

#define SIZEBAR_WIDTH   4

static const WCHAR szSizeBarClass[] = {
    'H','H',' ','S','i','z','e','B','a','r',0
};

/* Draw the SizeBar */
static void SB_OnPaint(HWND hWnd)
{
    PAINTSTRUCT ps;
    HDC hdc;
    RECT rc;
    
    hdc = BeginPaint(hWnd, &ps);

    GetClientRect(hWnd, &rc);

    /* dark frame */
    rc.right += 1;
    rc.bottom -= 1;
    FrameRect(hdc, &rc, GetStockObject(GRAY_BRUSH));

    /* white highlight */
    SelectObject(hdc, GetStockObject(WHITE_PEN));
    MoveToEx(hdc, rc.right, 1, NULL);
    LineTo(hdc, 1, 1);
    LineTo(hdc, 1, rc.bottom - 1);

    
    MoveToEx(hdc, 0, rc.bottom, NULL);
    LineTo(hdc, rc.right, rc.bottom);

    EndPaint(hWnd, &ps);
}

static void SB_OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
    SetCapture(hWnd);
}

static void SB_OnLButtonUp(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
    HHInfo *pHHInfo = (HHInfo *)GetWindowLongPtrW(hWnd, 0);
    POINT pt;

    pt.x = (short)LOWORD(lParam);
    pt.y = (short)HIWORD(lParam);

    /* update the window sizes */
    pHHInfo->WinType.iNavWidth += pt.x;
    Help_OnSize(hWnd);

    ReleaseCapture();
}

static void SB_OnMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
    /* ignore WM_MOUSEMOVE if not dragging the SizeBar */
    if (!(wParam & MK_LBUTTON))
        return;
}

static LRESULT CALLBACK SizeBar_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_LBUTTONDOWN:
            SB_OnLButtonDown(hWnd, wParam, lParam);
            break;
        case WM_LBUTTONUP:
            SB_OnLButtonUp(hWnd, wParam, lParam);
            break;
        case WM_MOUSEMOVE:
            SB_OnMouseMove(hWnd, wParam, lParam);
            break;
        case WM_PAINT:
            SB_OnPaint(hWnd);
            break;
        default:
            return DefWindowProcW(hWnd, message, wParam, lParam);
    }

    return 0;
}

static void HH_RegisterSizeBarClass(HHInfo *pHHInfo)
{
    WNDCLASSEXW wcex;

    wcex.cbSize         = sizeof(WNDCLASSEXW);
    wcex.style          = 0;
    wcex.lpfnWndProc    = SizeBar_WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = sizeof(LONG_PTR);
    wcex.hInstance      = hhctrl_hinstance;
    wcex.hIcon          = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
    wcex.hCursor        = LoadCursorW(NULL, (LPCWSTR)IDC_SIZEWE);
    wcex.hbrBackground  = (HBRUSH)(COLOR_MENU + 1);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = szSizeBarClass;
    wcex.hIconSm        = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);

    RegisterClassExW(&wcex);
}

static void SB_GetSizeBarRect(HHInfo *info, RECT *rc)
{
    RECT rectWND, rectTB, rectNP;

    GetClientRect(info->WinType.hwndHelp, &rectWND);
    GetClientRect(info->WinType.hwndToolBar, &rectTB);
    GetClientRect(info->WinType.hwndNavigation, &rectNP);

    rc->left = rectNP.right;
    rc->top = rectTB.bottom;
    rc->bottom = rectWND.bottom - rectTB.bottom;
    rc->right = SIZEBAR_WIDTH;
}

static BOOL HH_AddSizeBar(HHInfo *pHHInfo)
{
    HWND hWnd;
    HWND hwndParent = pHHInfo->WinType.hwndHelp;
    DWORD dwStyles = WS_CHILDWINDOW | WS_OVERLAPPED;
    DWORD dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR;
    RECT rc;

    if (navigation_visible(pHHInfo))
        dwStyles |= WS_VISIBLE;

    SB_GetSizeBarRect(pHHInfo, &rc);

    hWnd = CreateWindowExW(dwExStyles, szSizeBarClass, szEmpty, dwStyles,
                           rc.left, rc.top, rc.right, rc.bottom,
                           hwndParent, NULL, hhctrl_hinstance, NULL);
    if (!hWnd)
        return FALSE;

    /* store the pointer to the HH info struct */
    SetWindowLongPtrW(hWnd, 0, (LONG_PTR)pHHInfo);

    pHHInfo->hwndSizeBar = hWnd;
    return TRUE;
}

/* Child Window */

static const WCHAR szChildClass[] = {
    'H','H',' ','C','h','i','l','d',0
};

static LRESULT Child_OnPaint(HWND hWnd)
{
    PAINTSTRUCT ps;
    HDC hdc;
    RECT rc;

    hdc = BeginPaint(hWnd, &ps);

    /* Only paint the Navigation pane, identified by the fact
     * that it has a child window
     */
    if (GetWindow(hWnd, GW_CHILD))
    {
        GetClientRect(hWnd, &rc);

        /* set the border color */
        SelectObject(hdc, GetStockObject(DC_PEN));
        SetDCPenColor(hdc, GetSysColor(COLOR_BTNSHADOW));

        /* Draw the top border */
        LineTo(hdc, rc.right, 0);

        SelectObject(hdc, GetStockObject(WHITE_PEN));
        MoveToEx(hdc, 0, 1, NULL);
        LineTo(hdc, rc.right, 1);
    }

    EndPaint(hWnd, &ps);

    return 0;
}

static void ResizeTabChild(HHInfo *info, int tab)
{
    HWND hwnd = info->tabs[tab].hwnd;
    INT width, height;
    RECT rect, tabrc;
    DWORD cnt;

    GetClientRect(info->WinType.hwndNavigation, &rect);
    SendMessageW(info->hwndTabCtrl, TCM_GETITEMRECT, 0, (LPARAM)&tabrc);
    cnt = SendMessageW(info->hwndTabCtrl, TCM_GETROWCOUNT, 0, 0);

    rect.left = TAB_MARGIN;
    rect.top = TAB_TOP_PADDING + cnt*(tabrc.bottom-tabrc.top) + TAB_MARGIN;
    rect.right -= TAB_RIGHT_PADDING + TAB_MARGIN;
    rect.bottom -= TAB_MARGIN;
    width = rect.right-rect.left;
    height = rect.bottom-rect.top;

    SetWindowPos(hwnd, NULL, rect.left, rect.top, width, height,
                 SWP_NOZORDER | SWP_NOACTIVATE);

    switch (tab)
    {
    case TAB_INDEX: {
        int scroll_width = GetSystemMetrics(SM_CXVSCROLL);
        int border_width = GetSystemMetrics(SM_CXBORDER);
        int edge_width = GetSystemMetrics(SM_CXEDGE);

        /* Resize the tab widget column to perfectly fit the tab window and
         * leave sufficient space for the scroll widget.
         */
        SendMessageW(info->tabs[TAB_INDEX].hwnd, LVM_SETCOLUMNWIDTH, 0,
                     width-scroll_width-2*border_width-2*edge_width);

        break;
    }
    case TAB_SEARCH: {
        int scroll_width = GetSystemMetrics(SM_CXVSCROLL);
        int border_width = GetSystemMetrics(SM_CXBORDER);
        int edge_width = GetSystemMetrics(SM_CXEDGE);
        int top_pos = 0;

        SetWindowPos(info->search.hwndEdit, NULL, 0, top_pos, width,
                      EDIT_HEIGHT, SWP_NOZORDER | SWP_NOACTIVATE);
        top_pos += EDIT_HEIGHT + TAB_MARGIN;
        SetWindowPos(info->search.hwndList, NULL, 0, top_pos, width,
                      height-top_pos, SWP_NOZORDER | SWP_NOACTIVATE);
        /* Resize the tab widget column to perfectly fit the tab window and
         * leave sufficient space for the scroll widget.
         */
        SendMessageW(info->search.hwndList, LVM_SETCOLUMNWIDTH, 0,
                     width-scroll_width-2*border_width-2*edge_width);

        break;
    }
    }
}

static LRESULT Child_OnSize(HWND hwnd)
{
    HHInfo *info = (HHInfo*)GetWindowLongPtrW(hwnd, 0);
    RECT rect;

    if(!info || hwnd != info->WinType.hwndNavigation)
        return 0;

    GetClientRect(hwnd, &rect);
    SetWindowPos(info->hwndTabCtrl, HWND_TOP, 0, 0,
                 rect.right - TAB_RIGHT_PADDING,
                 rect.bottom - TAB_TOP_PADDING, SWP_NOMOVE);

    ResizeTabChild(info, TAB_CONTENTS);
    ResizeTabChild(info, TAB_INDEX);
    ResizeTabChild(info, TAB_SEARCH);
    return 0;
}

static LRESULT OnTabChange(HWND hwnd)
{
    HHInfo *info = (HHInfo*)GetWindowLongPtrW(hwnd, 0);
    int tab_id, tab_index, i;

    TRACE("%p\n", hwnd);

    if (!info)
        return 0;

    if(info->tabs[info->current_tab].hwnd)
        ShowWindow(info->tabs[info->current_tab].hwnd, SW_HIDE);

    tab_id = (int) SendMessageW(info->hwndTabCtrl, TCM_GETCURSEL, 0, 0);
    /* convert the ID of the tab to an index in our tab list */
    tab_index = -1;
    for (i=0; i<TAB_NUMTABS; i++)
    {
        if (info->tabs[i].id == tab_id)
        {
            tab_index = i;
            break;
        }
    }
    if (tab_index == -1)
    {
        FIXME("Tab ID %d does not correspond to a valid index in the tab list.\n", tab_id);
        return 0;
    }
    info->current_tab = tab_index;

    if(info->tabs[info->current_tab].hwnd)
        ShowWindow(info->tabs[info->current_tab].hwnd, SW_SHOW);

    return 0;
}

static LRESULT OnTopicChange(HHInfo *info, void *user_data)
{
    LPCWSTR chmfile = NULL, name = NULL, local = NULL;
    ContentItem *citer;
    SearchItem *siter;
    IndexItem *iiter;

    if(!user_data || !info)
        return 0;

    switch (info->current_tab)
    {
    case TAB_CONTENTS:
        citer = (ContentItem *) user_data;
        name = citer->name;
        local = citer->local;
        while(citer) {
            if(citer->merge.chm_file) {
                chmfile = citer->merge.chm_file;
                break;
            }
            citer = citer->parent;
        }
        break;
    case TAB_INDEX:
        iiter = (IndexItem *) user_data;
        if(iiter->nItems == 0) {
            FIXME("No entries for this item!\n");
            return 0;
        }
        if(iiter->nItems > 1) {
            int i = 0;
            LVITEMW lvi;

            SendMessageW(info->popup.hwndList, LVM_DELETEALLITEMS, 0, 0);
            for(i=0;i<iiter->nItems;i++) {
                IndexSubItem *item = &iiter->items[i];
                WCHAR *name = iiter->keyword;

                if(!item->name)
                    item->name = GetDocumentTitle(info->pCHMInfo, item->local);
                if(item->name)
                    name = item->name;
                memset(&lvi, 0, sizeof(lvi));
                lvi.iItem = i;
                lvi.mask = LVIF_TEXT|LVIF_PARAM;
                lvi.cchTextMax = strlenW(name)+1;
                lvi.pszText = name;
                lvi.lParam = (LPARAM) item;
                SendMessageW(info->popup.hwndList, LVM_INSERTITEMW, 0, (LPARAM)&lvi);
            }
            ShowWindow(info->popup.hwndPopup, SW_SHOW);
            return 0;
        }
        name = iiter->items[0].name;
        local = iiter->items[0].local;
        chmfile = iiter->merge.chm_file;
        break;
    case TAB_SEARCH:
        siter = (SearchItem *) user_data;
        name = siter->filename;
        local = siter->filename;
        chmfile = info->pCHMInfo->szFile;
        break;
    default:
        FIXME("Unhandled operation for this tab!\n");
        return 0;
    }

    if(!chmfile)
    {
        FIXME("No help file found for this item!\n");
        return 0;
    }

    TRACE("name %s loal %s\n", debugstr_w(name), debugstr_w(local));

    NavigateToChm(info, chmfile, local);
    return 0;
}

/* Capture the Enter/Return key and send it up to Child_WndProc as an NM_RETURN message */
static LRESULT CALLBACK EditChild_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    WNDPROC editWndProc = (WNDPROC)GetWindowLongPtrW(hWnd, GWLP_USERDATA);

    if(message == WM_KEYUP && wParam == VK_RETURN)
    {
        NMHDR nmhdr;

        nmhdr.hwndFrom = hWnd;
        nmhdr.code = NM_RETURN;
        SendMessageW(GetParent(GetParent(hWnd)), WM_NOTIFY, wParam, (LPARAM)&nmhdr);
    }
    return editWndProc(hWnd, message, wParam, lParam);
}

static LRESULT CALLBACK Child_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_PAINT:
        return Child_OnPaint(hWnd);
    case WM_SIZE:
        return Child_OnSize(hWnd);
    case WM_NOTIFY: {
        HHInfo *info = (HHInfo*)GetWindowLongPtrW(hWnd, 0);
        NMHDR *nmhdr = (NMHDR*)lParam;

        switch(nmhdr->code) {
        case TCN_SELCHANGE:
            return OnTabChange(hWnd);
        case TVN_SELCHANGEDW:
            return OnTopicChange(info, (void*)((NMTREEVIEWW *)lParam)->itemNew.lParam);
        case TVN_ITEMEXPANDINGW: {
            TVITEMW *item = &((NMTREEVIEWW *)lParam)->itemNew;
            HWND hwndTreeView = info->tabs[TAB_CONTENTS].hwnd;

            item->mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE;
            if (item->state & TVIS_EXPANDED)
            {
                item->iImage = HHTV_FOLDER;
                item->iSelectedImage = HHTV_FOLDER;
            }
            else
            {
                item->iImage = HHTV_OPENFOLDER;
                item->iSelectedImage = HHTV_OPENFOLDER;
            }
            SendMessageW(hwndTreeView, TVM_SETITEMW, 0, (LPARAM)item);
            return 0;
        }
        case NM_DBLCLK:
            if(!info)
                return 0;
            switch(info->current_tab)
            {
            case TAB_INDEX:
                return OnTopicChange(info, (void*)((NMITEMACTIVATE *)lParam)->lParam);
            case TAB_SEARCH:
                return OnTopicChange(info, (void*)((NMITEMACTIVATE *)lParam)->lParam);
            }
            break;
        case NM_RETURN:
            if(!info)
                return 0;
            switch(info->current_tab) {
            case TAB_INDEX: {
                HWND hwndList = info->tabs[TAB_INDEX].hwnd;
                LVITEMW lvItem;

                lvItem.iItem = (int) SendMessageW(hwndList, LVM_GETSELECTIONMARK, 0, 0);
                lvItem.mask = TVIF_PARAM;
                SendMessageW(hwndList, LVM_GETITEMW, 0, (LPARAM)&lvItem);
                OnTopicChange(info, (void*) lvItem.lParam);
                return 0;
            }
            case TAB_SEARCH: {
                if(nmhdr->hwndFrom == info->search.hwndEdit) {
                    char needle[100];
                    DWORD i, len;

                    len = GetWindowTextA(info->search.hwndEdit, needle, sizeof(needle));
                    if(!len)
                    {
                        FIXME("Unable to get search text.\n");
                        return 0;
                    }
                    /* Convert the requested text for comparison later against the
                     * lower case version of HTML file contents.
                     */
                    for(i=0;i<len;i++)
                        needle[i] = tolower(needle[i]);
                    InitSearch(info, needle);
                    return 0;
                }else if(nmhdr->hwndFrom == info->search.hwndList) {
                    HWND hwndList = info->search.hwndList;
                    LVITEMW lvItem;

                    lvItem.iItem = (int) SendMessageW(hwndList, LVM_GETSELECTIONMARK, 0, 0);
                    lvItem.mask = TVIF_PARAM;
                    SendMessageW(hwndList, LVM_GETITEMW, 0, (LPARAM)&lvItem);
                    OnTopicChange(info, (void*) lvItem.lParam);
                    return 0;
                }
                break;
            }
            }
            break;
        }
        break;
    }
    default:
        return DefWindowProcW(hWnd, message, wParam, lParam);
    }

    return 0;
}

static void HH_RegisterChildWndClass(HHInfo *pHHInfo)
{
    WNDCLASSEXW wcex;

    wcex.cbSize         = sizeof(WNDCLASSEXW);
    wcex.style          = 0;
    wcex.lpfnWndProc    = Child_WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = sizeof(LONG_PTR);
    wcex.hInstance      = hhctrl_hinstance;
    wcex.hIcon          = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
    wcex.hCursor        = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_BTNFACE + 1);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = szChildClass;
    wcex.hIconSm        = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);

    RegisterClassExW(&wcex);
}

/* Toolbar */

#define ICON_SIZE   20

static void DisplayPopupMenu(HHInfo *info)
{
    HMENU menu, submenu;
    TBBUTTONINFOW button;
    MENUITEMINFOW item;
    POINT coords;
    RECT rect;
    DWORD index;

    menu = LoadMenuW(hhctrl_hinstance, MAKEINTRESOURCEW(MENU_POPUP));

    if (!menu)
        return;

    submenu = GetSubMenu(menu, 0);

    /* Update the Show/Hide menu item */
    item.cbSize = sizeof(MENUITEMINFOW);
    item.fMask = MIIM_FTYPE | MIIM_STATE | MIIM_STRING;
    item.fType = MFT_STRING;
    item.fState = MF_ENABLED;

    if (info->WinType.fNotExpanded)
        item.dwTypeData = HH_LoadString(IDS_SHOWTABS);
    else
        item.dwTypeData = HH_LoadString(IDS_HIDETABS);

    SetMenuItemInfoW(submenu, IDTB_EXPAND, FALSE, &item);
    heap_free(item.dwTypeData);

    /* Find the index toolbar button */
    button.cbSize = sizeof(TBBUTTONINFOW);
    button.dwMask = TBIF_COMMAND;
    index = SendMessageW(info->WinType.hwndToolBar, TB_GETBUTTONINFOW, IDTB_OPTIONS, (LPARAM) &button);

    if (index == -1)
       return;

    /* Get position */
    SendMessageW(info->WinType.hwndToolBar, TB_GETITEMRECT, index, (LPARAM) &rect);

    coords.x = rect.left;
    coords.y = rect.bottom;

    ClientToScreen(info->WinType.hwndToolBar, &coords);
    TrackPopupMenu(submenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON | TPM_NOANIMATION, coords.x, coords.y, 0, info->WinType.hwndHelp, NULL);
}

static void TB_OnClick(HWND hWnd, DWORD dwID)
{
    HHInfo *info = (HHInfo *)GetWindowLongPtrW(hWnd, 0);

    switch (dwID)
    {
        case IDTB_STOP:
            DoPageAction(info, WB_STOP);
            break;
        case IDTB_REFRESH:
            DoPageAction(info, WB_REFRESH);
            break;
        case IDTB_BACK:
            DoPageAction(info, WB_GOBACK);
            break;
        case IDTB_HOME:
            NavigateToChm(info, info->pCHMInfo->szFile, info->WinType.pszHome);
            break;
        case IDTB_FORWARD:
            DoPageAction(info, WB_GOFORWARD);
            break;
        case IDTB_PRINT:
            DoPageAction(info, WB_PRINT);
            break;
        case IDTB_EXPAND:
        case IDTB_CONTRACT:
            ExpandContract(info);
            break;
        case IDTB_SYNC:
            DoSync(info);
            break;
        case IDTB_OPTIONS:
            DisplayPopupMenu(info);
            break;
        case IDTB_NOTES:
        case IDTB_CONTENTS:
        case IDTB_INDEX:
        case IDTB_SEARCH:
        case IDTB_HISTORY:
        case IDTB_FAVORITES:
            /* These are officially unimplemented as of the Windows 7 SDK */
            break;
        case IDTB_BROWSE_FWD:
        case IDTB_BROWSE_BACK:
        case IDTB_JUMP1:
        case IDTB_JUMP2:
        case IDTB_CUSTOMIZE:
        case IDTB_ZOOM:
        case IDTB_TOC_NEXT:
        case IDTB_TOC_PREV:
            break;
    }
}

static void TB_AddButton(TBBUTTON *pButtons, DWORD dwIndex, DWORD dwID, DWORD dwBitmap)
{
    pButtons[dwIndex].iBitmap = dwBitmap;
    pButtons[dwIndex].idCommand = dwID;
    pButtons[dwIndex].fsState = TBSTATE_ENABLED;
    pButtons[dwIndex].fsStyle = BTNS_BUTTON;
    pButtons[dwIndex].dwData = 0;
    pButtons[dwIndex].iString = 0;
}

static void TB_AddButtonsFromFlags(HHInfo *pHHInfo, TBBUTTON *pButtons, DWORD dwButtonFlags, LPDWORD pdwNumButtons)
{
    int nHistBitmaps = 0, nStdBitmaps = 0, nHHBitmaps = 0;
    HWND hToolbar = pHHInfo->WinType.hwndToolBar;
    TBADDBITMAP tbAB;
    DWORD unsupported;

    /* Common bitmaps */
    tbAB.hInst = HINST_COMMCTRL;
    tbAB.nID = IDB_HIST_LARGE_COLOR;
    nHistBitmaps = SendMessageW(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&tbAB);
    tbAB.nID = IDB_STD_LARGE_COLOR;
    nStdBitmaps = SendMessageW(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&tbAB);
    /* hhctrl.ocx bitmaps */
    tbAB.hInst = hhctrl_hinstance;
    tbAB.nID = IDB_HHTOOLBAR;
    nHHBitmaps = SendMessageW(hToolbar, TB_ADDBITMAP, HHTB_NUMBITMAPS, (LPARAM)&tbAB);

    *pdwNumButtons = 0;

    unsupported = dwButtonFlags & (HHWIN_BUTTON_BROWSE_FWD |
        HHWIN_BUTTON_BROWSE_BCK | HHWIN_BUTTON_NOTES | HHWIN_BUTTON_CONTENTS |
        HHWIN_BUTTON_INDEX | HHWIN_BUTTON_SEARCH | HHWIN_BUTTON_HISTORY |
        HHWIN_BUTTON_FAVORITES | HHWIN_BUTTON_JUMP1 | HHWIN_BUTTON_JUMP2 |
        HHWIN_BUTTON_ZOOM | HHWIN_BUTTON_TOC_NEXT | HHWIN_BUTTON_TOC_PREV);
    if (unsupported)
        FIXME("got asked for unsupported buttons: %06x\n", unsupported);

    if (dwButtonFlags & HHWIN_BUTTON_EXPAND)
    {
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_EXPAND, nHHBitmaps + HHTB_EXPAND);
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_CONTRACT, nHHBitmaps + HHTB_CONTRACT);

        if (pHHInfo->WinType.fNotExpanded)
            pButtons[1].fsState |= TBSTATE_HIDDEN;
        else
            pButtons[0].fsState |= TBSTATE_HIDDEN;
    }

    if (dwButtonFlags & HHWIN_BUTTON_BACK)
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_BACK, nHistBitmaps + HIST_BACK);

    if (dwButtonFlags & HHWIN_BUTTON_FORWARD)
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_FORWARD, nHistBitmaps + HIST_FORWARD);

    if (dwButtonFlags & HHWIN_BUTTON_STOP)
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_STOP, nHHBitmaps + HHTB_STOP);

    if (dwButtonFlags & HHWIN_BUTTON_REFRESH)
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_REFRESH, nHHBitmaps + HHTB_REFRESH);

    if (dwButtonFlags & HHWIN_BUTTON_HOME)
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_HOME, nHHBitmaps + HHTB_HOME);

    if (dwButtonFlags & HHWIN_BUTTON_SYNC)
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_SYNC, nHHBitmaps + HHTB_SYNC);

    if (dwButtonFlags & HHWIN_BUTTON_OPTIONS)
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_OPTIONS, nStdBitmaps + STD_PROPERTIES);

    if (dwButtonFlags & HHWIN_BUTTON_PRINT)
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_PRINT, nStdBitmaps + STD_PRINT);
}

static BOOL HH_AddToolbar(HHInfo *pHHInfo)
{
    HWND hToolbar;
    HWND hwndParent = pHHInfo->WinType.hwndHelp;
    DWORD toolbarFlags;
    TBBUTTON buttons[IDTB_TOC_PREV - IDTB_EXPAND];
    DWORD dwStyles, dwExStyles;
    DWORD dwNumButtons, dwIndex;

    if (pHHInfo->WinType.fsWinProperties & HHWIN_PARAM_TB_FLAGS)
        toolbarFlags = pHHInfo->WinType.fsToolBarFlags;
    else
        toolbarFlags = HHWIN_DEF_BUTTONS;

    dwStyles = WS_CHILDWINDOW | TBSTYLE_FLAT | TBSTYLE_WRAPABLE | TBSTYLE_TOOLTIPS | CCS_NODIVIDER;
    dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR;

    hToolbar = CreateWindowExW(dwExStyles, TOOLBARCLASSNAMEW, NULL, dwStyles,
                               0, 0, 0, 0, hwndParent, NULL,
                               hhctrl_hinstance, NULL);
    if (!hToolbar)
        return FALSE;
    pHHInfo->WinType.hwndToolBar = hToolbar;

    SendMessageW(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(ICON_SIZE, ICON_SIZE));
    SendMessageW(hToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
    SendMessageW(hToolbar, WM_SETFONT, (WPARAM)pHHInfo->hFont, TRUE);

    TB_AddButtonsFromFlags(pHHInfo, buttons, toolbarFlags, &dwNumButtons);

    for (dwIndex = 0; dwIndex < dwNumButtons; dwIndex++)
    {
        LPWSTR szBuf = HH_LoadString(buttons[dwIndex].idCommand);
        DWORD dwLen = strlenW(szBuf);
        szBuf[dwLen + 1] = 0; /* Double-null terminate */

        buttons[dwIndex].iString = (DWORD)SendMessageW(hToolbar, TB_ADDSTRINGW, 0, (LPARAM)szBuf);
        heap_free(szBuf);
    }

    SendMessageW(hToolbar, TB_ADDBUTTONSW, dwNumButtons, (LPARAM)buttons);
    SendMessageW(hToolbar, TB_AUTOSIZE, 0, 0);
    if (pHHInfo->WinType.fsWinProperties & HHWIN_PROP_TRI_PANE)
        ShowWindow(hToolbar, SW_SHOW);

    return TRUE;
}

/* Navigation Pane */

static void NP_GetNavigationRect(HHInfo *pHHInfo, RECT *rc)
{
    HWND hwndParent = pHHInfo->WinType.hwndHelp;
    HWND hwndToolbar = pHHInfo->WinType.hwndToolBar;
    RECT rectWND, rectTB;

    GetClientRect(hwndParent, &rectWND);
    GetClientRect(hwndToolbar, &rectTB);

    rc->left = 0;
    rc->top = rectTB.bottom;
    rc->bottom = rectWND.bottom - rectTB.bottom;

    if (!(pHHInfo->WinType.fsValidMembers & HHWIN_PARAM_NAV_WIDTH) &&
          pHHInfo->WinType.iNavWidth == 0)
    {
        pHHInfo->WinType.iNavWidth = WINTYPE_DEFAULT_NAVWIDTH;
    }

    rc->right = pHHInfo->WinType.iNavWidth;
}

static DWORD NP_CreateTab(HINSTANCE hInstance, HWND hwndTabCtrl, DWORD index)
{
    TCITEMW tie;
    LPWSTR tabText = HH_LoadString(index);
    DWORD ret;

    tie.mask = TCIF_TEXT;
    tie.pszText = tabText;

    ret = SendMessageW( hwndTabCtrl, TCM_INSERTITEMW, index, (LPARAM)&tie );

    heap_free(tabText);
    return ret;
}

static BOOL HH_AddNavigationPane(HHInfo *info)
{
    HWND hWnd, hwndTabCtrl;
    HWND hwndParent = info->WinType.hwndHelp;
    DWORD dwStyles = WS_CHILDWINDOW;
    DWORD dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR;
    RECT rc;

    if (navigation_visible(info))
        dwStyles |= WS_VISIBLE;

    NP_GetNavigationRect(info, &rc);

    hWnd = CreateWindowExW(dwExStyles, szChildClass, szEmpty, dwStyles,
                           rc.left, rc.top, rc.right, rc.bottom,
                           hwndParent, NULL, hhctrl_hinstance, NULL);
    if (!hWnd)
        return FALSE;

    SetWindowLongPtrW(hWnd, 0, (LONG_PTR)info);

    hwndTabCtrl = CreateWindowExW(dwExStyles, WC_TABCONTROLW, szEmpty, dwStyles | WS_VISIBLE,
                                  0, TAB_TOP_PADDING,
                                  rc.right - TAB_RIGHT_PADDING,
                                  rc.bottom - TAB_TOP_PADDING,
                                  hWnd, NULL, hhctrl_hinstance, NULL);
    if (!hwndTabCtrl)
        return FALSE;

    if (*info->WinType.pszToc)
        info->tabs[TAB_CONTENTS].id = NP_CreateTab(hhctrl_hinstance, hwndTabCtrl, IDS_CONTENTS);

    if (*info->WinType.pszIndex)
        info->tabs[TAB_INDEX].id = NP_CreateTab(hhctrl_hinstance, hwndTabCtrl, IDS_INDEX);

    if (info->WinType.fsWinProperties & HHWIN_PROP_TAB_SEARCH)
        info->tabs[TAB_SEARCH].id = NP_CreateTab(hhctrl_hinstance, hwndTabCtrl, IDS_SEARCH);

    if (info->WinType.fsWinProperties & HHWIN_PROP_TAB_FAVORITES)
        info->tabs[TAB_FAVORITES].id = NP_CreateTab(hhctrl_hinstance, hwndTabCtrl, IDS_FAVORITES);

    SendMessageW(hwndTabCtrl, WM_SETFONT, (WPARAM)info->hFont, TRUE);

    info->hwndTabCtrl = hwndTabCtrl;
    info->WinType.hwndNavigation = hWnd;
    return TRUE;
}

/* HTML Pane */

static void HP_GetHTMLRect(HHInfo *info, RECT *rc)
{
    RECT rectTB, rectWND, rectNP, rectSB;

    GetClientRect(info->WinType.hwndHelp, &rectWND);
    GetClientRect(info->hwndSizeBar, &rectSB);

    rc->left = 0;
    rc->top = 0;
    if (navigation_visible(info))
    {
        GetClientRect(info->WinType.hwndNavigation, &rectNP);
        rc->left += rectNP.right + rectSB.right;
    }
    if (info->WinType.fsWinProperties & HHWIN_PROP_TRI_PANE)
    {
        GetClientRect(info->WinType.hwndToolBar, &rectTB);
        rc->top += rectTB.bottom;
    }
    rc->right = rectWND.right - rc->left;
    rc->bottom = rectWND.bottom - rc->top;
}

static BOOL HH_AddHTMLPane(HHInfo *pHHInfo)
{
    HWND hWnd;
    HWND hwndParent = pHHInfo->WinType.hwndHelp;
    DWORD dwStyles = WS_CHILDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN;
    DWORD dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_CLIENTEDGE;
    RECT rc;

    HP_GetHTMLRect(pHHInfo, &rc);

    hWnd = CreateWindowExW(dwExStyles, szChildClass, szEmpty, dwStyles,
                           rc.left, rc.top, rc.right, rc.bottom,
                           hwndParent, NULL, hhctrl_hinstance, NULL);
    if (!hWnd)
        return FALSE;

    if (!InitWebBrowser(pHHInfo, hWnd))
        return FALSE;

    /* store the pointer to the HH info struct */
    SetWindowLongPtrW(hWnd, 0, (LONG_PTR)pHHInfo);

    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);

    pHHInfo->WinType.hwndHTML = hWnd;
    return TRUE;
}

static BOOL AddContentTab(HHInfo *info)
{
    HIMAGELIST hImageList;
    HBITMAP hBitmap;
    HWND hWnd;

    if(info->tabs[TAB_CONTENTS].id == -1)
        return TRUE; /* No "Contents" tab */
    hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, WC_TREEVIEWW, szEmpty, WS_CHILD | WS_BORDER | TVS_LINESATROOT
                           | TVS_SHOWSELALWAYS | TVS_HASBUTTONS, 50, 50, 100, 100,
                           info->WinType.hwndNavigation, NULL, hhctrl_hinstance, NULL);
    if(!hWnd) {
        ERR("Could not create treeview control\n");
        return FALSE;
    }

    hImageList = ImageList_Create(16, 16, ILC_COLOR32, 0, HHTV_NUMBITMAPS);
    hBitmap = LoadBitmapW(hhctrl_hinstance, MAKEINTRESOURCEW(IDB_HHTREEVIEW));
    ImageList_Add(hImageList, hBitmap, NULL);
    SendMessageW(hWnd, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)hImageList);

    info->contents.hImageList = hImageList;
    info->tabs[TAB_CONTENTS].hwnd = hWnd;
    ResizeTabChild(info, TAB_CONTENTS);
    ShowWindow(hWnd, SW_SHOW);

    return TRUE;
}

static BOOL AddIndexTab(HHInfo *info)
{
    char hidden_column[] = "Column";
    LVCOLUMNA lvc;

    if(info->tabs[TAB_INDEX].id == -1)
        return TRUE; /* No "Index" tab */
    info->tabs[TAB_INDEX].hwnd = CreateWindowExW(WS_EX_CLIENTEDGE, WC_LISTVIEWW,
           szEmpty, WS_CHILD | WS_BORDER | LVS_SINGLESEL | LVS_REPORT | LVS_NOCOLUMNHEADER, 50, 50, 100, 100,
           info->WinType.hwndNavigation, NULL, hhctrl_hinstance, NULL);
    if(!info->tabs[TAB_INDEX].hwnd) {
        ERR("Could not create ListView control\n");
        return FALSE;
    }
    memset(&lvc, 0, sizeof(lvc));
    lvc.mask = LVCF_TEXT;
    lvc.pszText = hidden_column;
    if(SendMessageW(info->tabs[TAB_INDEX].hwnd, LVM_INSERTCOLUMNA, 0, (LPARAM) &lvc) == -1)
    {
        ERR("Could not create ListView column\n");
        return FALSE;
    }

    ResizeTabChild(info, TAB_INDEX);
    ShowWindow(info->tabs[TAB_INDEX].hwnd, SW_HIDE);

    return TRUE;
}

static BOOL AddSearchTab(HHInfo *info)
{
    HWND hwndList, hwndEdit, hwndContainer;
    char hidden_column[] = "Column";
    WNDPROC editWndProc;
    LVCOLUMNA lvc;

    if(info->tabs[TAB_SEARCH].id == -1)
        return TRUE; /* No "Search" tab */
    hwndContainer = CreateWindowExW(WS_EX_CONTROLPARENT, szChildClass, szEmpty,
                                    WS_CHILD, 0, 0, 0, 0, info->WinType.hwndNavigation,
                                    NULL, hhctrl_hinstance, NULL);
    if(!hwndContainer) {
        ERR("Could not create search window container control.\n");
        return FALSE;
    }
    hwndEdit = CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, szEmpty, WS_CHILD
                                | WS_VISIBLE | ES_LEFT | SS_NOTIFY, 0, 0, 0, 0,
                               hwndContainer, NULL, hhctrl_hinstance, NULL);
    if(!hwndEdit) {
        ERR("Could not create search ListView control.\n");
        return FALSE;
    }
    if(SendMessageW(hwndEdit, WM_SETFONT, (WPARAM) info->hFont, (LPARAM) FALSE) == -1)
    {
        ERR("Could not set font for edit control.\n");
        return FALSE;
    }
    editWndProc = (WNDPROC) SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC, (LONG_PTR)EditChild_WndProc);
    if(!editWndProc) {
        ERR("Could not redirect messages for edit control.\n");
        return FALSE;
    }
    SetWindowLongPtrW(hwndEdit, GWLP_USERDATA, (LONG_PTR)editWndProc);
    hwndList = CreateWindowExW(WS_EX_CLIENTEDGE, WC_LISTVIEWW, szEmpty,
                               WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_SINGLESEL
                                | LVS_REPORT | LVS_NOCOLUMNHEADER, 0, 0, 0, 0,
                               hwndContainer, NULL, hhctrl_hinstance, NULL);
    if(!hwndList) {
        ERR("Could not create search ListView control.\n");
        return FALSE;
    }
    memset(&lvc, 0, sizeof(lvc));
    lvc.mask = LVCF_TEXT;
    lvc.pszText = hidden_column;
    if(SendMessageW(hwndList, LVM_INSERTCOLUMNA, 0, (LPARAM) &lvc) == -1)
    {
        ERR("Could not create ListView column\n");
        return FALSE;
    }

    info->search.hwndEdit = hwndEdit;
    info->search.hwndList = hwndList;
    info->search.hwndContainer = hwndContainer;
    info->tabs[TAB_SEARCH].hwnd = hwndContainer;

    SetWindowLongPtrW(hwndContainer, 0, (LONG_PTR)info);

    ResizeTabChild(info, TAB_SEARCH);

    return TRUE;
}

/* The Index tab's sub-topic popup */

static void ResizePopupChild(HHInfo *info)
{
    int scroll_width = GetSystemMetrics(SM_CXVSCROLL);
    int border_width = GetSystemMetrics(SM_CXBORDER);
    int edge_width = GetSystemMetrics(SM_CXEDGE);
    INT width, height;
    RECT rect;

    if(!info)
        return;

    GetClientRect(info->popup.hwndPopup, &rect);
    SetWindowPos(info->popup.hwndCallback, HWND_TOP, 0, 0,
                 rect.right, rect.bottom, SWP_NOMOVE);

    rect.left = TAB_MARGIN;
    rect.top = TAB_TOP_PADDING + TAB_MARGIN;
    rect.right -= TAB_RIGHT_PADDING + TAB_MARGIN;
    rect.bottom -= TAB_MARGIN;
    width = rect.right-rect.left;
    height = rect.bottom-rect.top;

    SetWindowPos(info->popup.hwndList, NULL, rect.left, rect.top, width, height,
                 SWP_NOZORDER | SWP_NOACTIVATE);

    SendMessageW(info->popup.hwndList, LVM_SETCOLUMNWIDTH, 0,
                 width-scroll_width-2*border_width-2*edge_width);
}

static LRESULT CALLBACK HelpPopup_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HHInfo *info = (HHInfo *)GetWindowLongPtrW(hWnd, 0);

    switch (message)
    {
    case WM_SIZE:
        ResizePopupChild(info);
        return 0;
    case WM_DESTROY:
        DestroyWindow(hWnd);
        return 0;
    case WM_CLOSE:
        ShowWindow(hWnd, SW_HIDE);
        return 0;

    default:
        return DefWindowProcW(hWnd, message, wParam, lParam);
    }

    return 0;
}

static LRESULT CALLBACK PopupChild_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_NOTIFY: {
        NMHDR *nmhdr = (NMHDR*)lParam;
        switch(nmhdr->code)
        {
        case NM_DBLCLK: {
            HHInfo *info = (HHInfo*)GetWindowLongPtrW(hWnd, 0);
            IndexSubItem *iter;

            if(info == 0 || lParam == 0)
                return 0;
            iter = (IndexSubItem*) ((NMITEMACTIVATE *)lParam)->lParam;
            if(iter == 0)
                return 0;
            NavigateToChm(info, info->index->merge.chm_file, iter->local);
            ShowWindow(info->popup.hwndPopup, SW_HIDE);
            return 0;
        }
        case NM_RETURN: {
            HHInfo *info = (HHInfo*)GetWindowLongPtrW(hWnd, 0);
            IndexSubItem *iter;
            LVITEMW lvItem;

            if(info == 0)
                return 0;

            lvItem.iItem = (int) SendMessageW(info->popup.hwndList, LVM_GETSELECTIONMARK, 0, 0);
            lvItem.mask = TVIF_PARAM;
            SendMessageW(info->popup.hwndList, LVM_GETITEMW, 0, (LPARAM)&lvItem);
            iter = (IndexSubItem*) lvItem.lParam;
            NavigateToChm(info, info->index->merge.chm_file, iter->local);
            ShowWindow(info->popup.hwndPopup, SW_HIDE);
            return 0;
        }
        }
        break;
    }
    default:
        return DefWindowProcW(hWnd, message, wParam, lParam);
    }

    return 0;
}

static BOOL AddIndexPopup(HHInfo *info)
{
    static const WCHAR szPopupChildClass[] = {'H','H',' ','P','o','p','u','p',' ','C','h','i','l','d',0};
    static const WCHAR windowCaptionW[] = {'S','e','l','e','c','t',' ','T','o','p','i','c',':',0};
    static const WCHAR windowClassW[] = {'H','H',' ','P','o','p','u','p',0};
    HWND hwndList, hwndPopup, hwndCallback;
    char hidden_column[] = "Column";
    WNDCLASSEXW wcex;
    LVCOLUMNA lvc;

    if(info->tabs[TAB_INDEX].id == -1)
        return TRUE; /* No "Index" tab */

    wcex.cbSize         = sizeof(WNDCLASSEXW);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = HelpPopup_WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = sizeof(LONG_PTR);
    wcex.hInstance      = hhctrl_hinstance;
    wcex.hIcon          = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
    wcex.hCursor        = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_MENU + 1);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = windowClassW;
    wcex.hIconSm        = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
    RegisterClassExW(&wcex);

    wcex.cbSize         = sizeof(WNDCLASSEXW);
    wcex.style          = 0;
    wcex.lpfnWndProc    = PopupChild_WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = sizeof(LONG_PTR);
    wcex.hInstance      = hhctrl_hinstance;
    wcex.hIcon          = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
    wcex.hCursor        = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_BTNFACE + 1);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = szPopupChildClass;
    wcex.hIconSm        = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
    RegisterClassExW(&wcex);

    hwndPopup = CreateWindowExW(WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_APPWINDOW
                                 | WS_EX_WINDOWEDGE | WS_EX_RIGHTSCROLLBAR,
                                windowClassW, windowCaptionW, WS_POPUPWINDOW
                                 | WS_OVERLAPPEDWINDOW | WS_VISIBLE
                                 | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, CW_USEDEFAULT,
                                CW_USEDEFAULT, 300, 200, info->WinType.hwndHelp,
                                NULL, hhctrl_hinstance, NULL);
    if (!hwndPopup)
        return FALSE;

    hwndCallback = CreateWindowExW(WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
                                   szPopupChildClass, szEmpty, WS_CHILDWINDOW | WS_VISIBLE,
                                   0, 0, 0, 0,
                                   hwndPopup, NULL, hhctrl_hinstance, NULL);
    if (!hwndCallback)
        return FALSE;

    ShowWindow(hwndPopup, SW_HIDE);
    hwndList = CreateWindowExW(WS_EX_CLIENTEDGE, WC_LISTVIEWW, szEmpty,
                               WS_CHILD | WS_BORDER | LVS_SINGLESEL | LVS_REPORT
                                | LVS_NOCOLUMNHEADER, 50, 50, 100, 100,
                               hwndCallback, NULL, hhctrl_hinstance, NULL);
    if(!hwndList) {
        ERR("Could not create popup ListView control\n");
        return FALSE;
    }
    memset(&lvc, 0, sizeof(lvc));
    lvc.mask = LVCF_TEXT;
    lvc.pszText = hidden_column;
    if(SendMessageW(hwndList, LVM_INSERTCOLUMNA, 0, (LPARAM) &lvc) == -1)
    {
        ERR("Could not create popup ListView column\n");
        return FALSE;
    }

    info->popup.hwndCallback = hwndCallback;
    info->popup.hwndPopup = hwndPopup;
    info->popup.hwndList = hwndList;
    SetWindowLongPtrW(hwndPopup, 0, (LONG_PTR)info);
    SetWindowLongPtrW(hwndCallback, 0, (LONG_PTR)info);

    ResizePopupChild(info);
    ShowWindow(hwndList, SW_SHOW);

    return TRUE;
}

/* Viewer Window */

static void ExpandContract(HHInfo *pHHInfo)
{
    RECT r, nav;

    pHHInfo->WinType.fNotExpanded = !pHHInfo->WinType.fNotExpanded;
    GetWindowRect(pHHInfo->WinType.hwndHelp, &r);
    NP_GetNavigationRect(pHHInfo, &nav);

    /* hide/show both the nav bar and the size bar */
    if (pHHInfo->WinType.fNotExpanded)
    {
        ShowWindow(pHHInfo->WinType.hwndNavigation, SW_HIDE);
        ShowWindow(pHHInfo->hwndSizeBar, SW_HIDE);
        r.left = r.left + nav.right;

        SendMessageW(pHHInfo->WinType.hwndToolBar, TB_HIDEBUTTON, IDTB_EXPAND, MAKELPARAM(FALSE, 0));
        SendMessageW(pHHInfo->WinType.hwndToolBar, TB_HIDEBUTTON, IDTB_CONTRACT, MAKELPARAM(TRUE, 0));
    }
    else
    {
        ShowWindow(pHHInfo->WinType.hwndNavigation, SW_SHOW);
        ShowWindow(pHHInfo->hwndSizeBar, SW_SHOW);
        r.left = r.left - nav.right;

        SendMessageW(pHHInfo->WinType.hwndToolBar, TB_HIDEBUTTON, IDTB_EXPAND, MAKELPARAM(TRUE, 0));
        SendMessageW(pHHInfo->WinType.hwndToolBar, TB_HIDEBUTTON, IDTB_CONTRACT, MAKELPARAM(FALSE, 0));
    }

    MoveWindow(pHHInfo->WinType.hwndHelp, r.left, r.top, r.right-r.left, r.bottom-r.top, TRUE);
}

static LRESULT Help_OnSize(HWND hWnd)
{
    HHInfo *pHHInfo = (HHInfo *)GetWindowLongPtrW(hWnd, 0);
    DWORD dwSize;
    RECT rc;

    if (!pHHInfo)
        return 0;

    if (navigation_visible(pHHInfo))
    {
        NP_GetNavigationRect(pHHInfo, &rc);
        SetWindowPos(pHHInfo->WinType.hwndNavigation, HWND_TOP, 0, 0,
                     rc.right, rc.bottom, SWP_NOMOVE);

        SB_GetSizeBarRect(pHHInfo, &rc);
        SetWindowPos(pHHInfo->hwndSizeBar, HWND_TOP, rc.left, rc.top,
                     rc.right, rc.bottom, SWP_SHOWWINDOW);

    }

    HP_GetHTMLRect(pHHInfo, &rc);
    SetWindowPos(pHHInfo->WinType.hwndHTML, HWND_TOP, rc.left, rc.top,
                 rc.right, rc.bottom, SWP_SHOWWINDOW);

    /* Resize browser window taking the frame size into account */
    dwSize = GetSystemMetrics(SM_CXFRAME);
    ResizeWebBrowser(pHHInfo, rc.right - dwSize, rc.bottom - dwSize);

    return 0;
}

void UpdateHelpWindow(HHInfo *info)
{
    if (!info->WinType.hwndHelp)
        return;

    WARN("Only the size of the window is currently updated.\n");
    if (info->WinType.fsValidMembers & HHWIN_PARAM_RECT)
    {
        RECT *rect = &info->WinType.rcWindowPos;
        INT x, y, width, height;

        x = rect->left;
        y = rect->top;
        width = rect->right - x;
        height = rect->bottom - y;
        SetWindowPos(info->WinType.hwndHelp, NULL, rect->left, rect->top, width, height,
                     SWP_NOZORDER | SWP_NOACTIVATE);
    }
}

static LRESULT CALLBACK Help_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        if (HIWORD(wParam) == BN_CLICKED)
            TB_OnClick(hWnd, LOWORD(wParam));
        break;
    case WM_SIZE:
        return Help_OnSize(hWnd);
    case WM_CLOSE:
        ReleaseHelpViewer((HHInfo *)GetWindowLongPtrW(hWnd, 0));
        return 0;
    case WM_DESTROY:
        if(hh_process)
            PostQuitMessage(0);
        break;

    default:
        return DefWindowProcW(hWnd, message, wParam, lParam);
    }

    return 0;
}

static BOOL HH_CreateHelpWindow(HHInfo *info)
{
    HWND hWnd, parent = 0;
    RECT winPos = info->WinType.rcWindowPos;
    WNDCLASSEXW wcex;
    DWORD dwStyles, dwExStyles;
    DWORD x, y, width = 0, height = 0;
    LPCWSTR caption;

    static const WCHAR windowClassW[] = {
        'H','H',' ', 'P','a','r','e','n','t',0
    };

    wcex.cbSize         = sizeof(WNDCLASSEXW);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = Help_WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = sizeof(LONG_PTR);
    wcex.hInstance      = hhctrl_hinstance;
    wcex.hIcon          = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
    wcex.hCursor        = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_MENU + 1);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = windowClassW;
    wcex.hIconSm        = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);

    RegisterClassExW(&wcex);

    /* Read in window parameters if available */
    if (info->WinType.fsValidMembers & HHWIN_PARAM_STYLES)
    {
        dwStyles = info->WinType.dwStyles;
        if (!(info->WinType.dwStyles & WS_CHILD))
            dwStyles |= WS_OVERLAPPEDWINDOW;
    }
    else
        dwStyles = WS_OVERLAPPEDWINDOW | WS_VISIBLE |
                   WS_CLIPSIBLINGS | WS_CLIPCHILDREN;

    if (info->WinType.fsValidMembers & HHWIN_PARAM_EXSTYLES)
        dwExStyles = info->WinType.dwExStyles;
    else
        dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_APPWINDOW |
                     WS_EX_WINDOWEDGE | WS_EX_RIGHTSCROLLBAR;

    if (info->WinType.fsValidMembers & HHWIN_PARAM_RECT)
    {
        x = winPos.left;
        y = winPos.top;
        width = winPos.right - x;
        height = winPos.bottom - y;
    }
    if (!width || !height)
    {
        x = WINTYPE_DEFAULT_X;
        y = WINTYPE_DEFAULT_Y;
        width = WINTYPE_DEFAULT_WIDTH;
        height = WINTYPE_DEFAULT_HEIGHT;
    }

    if (!(info->WinType.fsWinProperties & HHWIN_PROP_TRI_PANE) && info->WinType.fNotExpanded)
    {
        if (!(info->WinType.fsValidMembers & HHWIN_PARAM_NAV_WIDTH) &&
              info->WinType.iNavWidth == 0)
        {
            info->WinType.iNavWidth = WINTYPE_DEFAULT_NAVWIDTH;
        }

        x += info->WinType.iNavWidth;
        width -= info->WinType.iNavWidth;
    }


    caption = info->WinType.pszCaption;
    if (!*caption) caption = info->pCHMInfo->defTitle;

    if (info->WinType.dwStyles & WS_CHILD)
        parent = info->WinType.hwndCaller;

    hWnd = CreateWindowExW(dwExStyles, windowClassW, caption,
                           dwStyles, x, y, width, height, parent, NULL, hhctrl_hinstance, NULL);
    if (!hWnd)
        return FALSE;

    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);

    /* store the pointer to the HH info struct */
    SetWindowLongPtrW(hWnd, 0, (LONG_PTR)info);

    info->WinType.hwndHelp = hWnd;
    return TRUE;
}

static void HH_CreateFont(HHInfo *pHHInfo)
{
    LOGFONTW lf;

    GetObjectW(GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONTW), &lf);
    lf.lfWeight = FW_NORMAL;
    lf.lfItalic = FALSE;
    lf.lfUnderline = FALSE;

    pHHInfo->hFont = CreateFontIndirectW(&lf);
}

static void HH_InitRequiredControls(DWORD dwControls)
{
    INITCOMMONCONTROLSEX icex;

    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icex.dwICC = dwControls;
    InitCommonControlsEx(&icex);
}

/* Creates the whole package */
static BOOL CreateViewer(HHInfo *pHHInfo)
{
    HH_CreateFont(pHHInfo);

    if (!HH_CreateHelpWindow(pHHInfo))
        return FALSE;

    HH_InitRequiredControls(ICC_BAR_CLASSES);

    if (!HH_AddToolbar(pHHInfo))
        return FALSE;

    HH_RegisterChildWndClass(pHHInfo);

    if (!HH_AddNavigationPane(pHHInfo))
        return FALSE;

    HH_RegisterSizeBarClass(pHHInfo);

    if (!HH_AddSizeBar(pHHInfo))
        return FALSE;

    if (!HH_AddHTMLPane(pHHInfo))
        return FALSE;

    if (!AddContentTab(pHHInfo))
        return FALSE;

    if (!AddIndexTab(pHHInfo))
        return FALSE;

    if (!AddIndexPopup(pHHInfo))
        return FALSE;

    if (!AddSearchTab(pHHInfo))
        return FALSE;

    InitContent(pHHInfo);
    InitIndex(pHHInfo);

    pHHInfo->viewer_initialized = TRUE;
    return TRUE;
}

void wintype_stringsW_free(struct wintype_stringsW *stringsW)
{
    heap_free(stringsW->pszType);
    heap_free(stringsW->pszCaption);
    heap_free(stringsW->pszToc);
    heap_free(stringsW->pszIndex);
    heap_free(stringsW->pszFile);
    heap_free(stringsW->pszHome);
    heap_free(stringsW->pszJump1);
    heap_free(stringsW->pszJump2);
    heap_free(stringsW->pszUrlJump1);
    heap_free(stringsW->pszUrlJump2);
}

void wintype_stringsA_free(struct wintype_stringsA *stringsA)
{
    heap_free(stringsA->pszType);
    heap_free(stringsA->pszCaption);
    heap_free(stringsA->pszToc);
    heap_free(stringsA->pszIndex);
    heap_free(stringsA->pszFile);
    heap_free(stringsA->pszHome);
    heap_free(stringsA->pszJump1);
    heap_free(stringsA->pszJump2);
    heap_free(stringsA->pszUrlJump1);
    heap_free(stringsA->pszUrlJump2);
    heap_free(stringsA->pszCustomTabs);
}

void ReleaseHelpViewer(HHInfo *info)
{
    TRACE("(%p)\n", info);

    if (!info)
        return;

    list_remove(&info->entry);

    wintype_stringsA_free(&info->stringsA);
    wintype_stringsW_free(&info->stringsW);

    if (info->pCHMInfo)
        CloseCHM(info->pCHMInfo);

    ReleaseWebBrowser(info);
    ReleaseContent(info);
    ReleaseIndex(info);
    ReleaseSearch(info);

    if(info->contents.hImageList)
        ImageList_Destroy(info->contents.hImageList);
    if(info->WinType.hwndHelp)
        DestroyWindow(info->WinType.hwndHelp);

    heap_free(info);
    OleUninitialize();
}

HHInfo *CreateHelpViewer(HHInfo *info, LPCWSTR filename, HWND caller)
{
    HHInfo *tmp_info;
    unsigned int i;

    if(!info)
    {
        info = heap_alloc_zero(sizeof(HHInfo));
        list_add_tail(&window_list, &info->entry);
    }

    /* Set the invalid tab ID (-1) as the default value for all
     * of the tabs, this matches a failed TCM_INSERTITEM call.
     */
    for(i=0;i<sizeof(info->tabs)/sizeof(HHTab);i++)
        info->tabs[i].id = -1;

    OleInitialize(NULL);

    info->pCHMInfo = OpenCHM(filename);
    if(!info->pCHMInfo) {
        ReleaseHelpViewer(info);
        return NULL;
    }

    if (!LoadWinTypeFromCHM(info)) {
        ReleaseHelpViewer(info);
        return NULL;
    }
    info->WinType.hwndCaller = caller;

    /* If the window is already open then load the file in that existing window */
    if ((tmp_info = find_window(info->WinType.pszType)) && tmp_info != info)
    {
        ReleaseHelpViewer(info);
        return CreateHelpViewer(tmp_info, filename, caller);
    }

    if(!info->viewer_initialized && !CreateViewer(info)) {
        ReleaseHelpViewer(info);
        return NULL;
    }

    return info;
}

/*
 * Search the table of HTML entities and return the corresponding ANSI symbol.
 */
static char find_html_symbol(const char *entity, int entity_len)
{
    int max = sizeof(html_encoded_symbols)/sizeof(html_encoded_symbols[0])-1;
    int min = 0, dir;

    while(min <= max)
    {
        int pos = (min+max)/2;
        const char *encoded_symbol = html_encoded_symbols[pos].html_code;
        dir = strncmp(encoded_symbol, entity, entity_len);
        if(dir == 0 && !encoded_symbol[entity_len]) return html_encoded_symbols[pos].ansi_symbol;
        if(dir < 0)
            min = pos+1;
        else
            max = pos-1;
    }
    return 0;
}

/*
 * Decode a string containing HTML encoded characters into a unicode string.
 */
WCHAR *decode_html(const char *html_fragment, int html_fragment_len, UINT code_page)
{
    const char *h = html_fragment, *amp, *sem;
    char symbol, *tmp;
    int len, tmp_len = 0;
    WCHAR *unicode_text;

    tmp = heap_alloc(html_fragment_len+1);
    while(1)
    {
        symbol = 0;
        amp = strchr(h, '&');
        if(!amp) break;
        len = amp-h;
        /* Copy the characters prior to the HTML encoded character */
        memcpy(&tmp[tmp_len], h, len);
        tmp_len += len;
        amp++; /* skip ampersand */
        sem = strchr(amp, ';');
        /* Require a semicolon after the ampersand */
        if(!sem)
        {
            h = amp;
            tmp[tmp_len++] = '&';
            continue;
        }
        /* Find the symbol either by using the ANSI character number (prefixed by the pound symbol)
         * or by searching the HTML entity table */
        len = sem-amp;
        if(amp[0] == '#')
        {
            char *endnum = NULL;
            int tmp;

            tmp = (char) strtol(amp, &endnum, 10);
            if(endnum == sem)
                symbol = tmp;
        }
        else
            symbol = find_html_symbol(amp, len);
        if(!symbol)
        {
            FIXME("Failed to translate HTML encoded character '&%.*s;'.\n", len, amp);
            h = amp;
            tmp[tmp_len++] = '&';
            continue;
        }
        /* Insert the new symbol */
        h = sem+1;
        tmp[tmp_len++] = symbol;
    }
    /* Convert any remaining characters */
    len = html_fragment_len-(h-html_fragment);
    memcpy(&tmp[tmp_len], h, len);
    tmp_len += len;
    tmp[tmp_len++] = 0; /* NULL-terminate the string */

    len = MultiByteToWideChar(code_page, 0, tmp, tmp_len, NULL, 0);
    unicode_text = heap_alloc(len*sizeof(WCHAR));
    MultiByteToWideChar(code_page, 0, tmp, tmp_len, unicode_text, len);
    heap_free(tmp);
    return unicode_text;
}

/* Find the HTMLHelp structure for an existing window title */
HHInfo *find_window(const WCHAR *window)
{
    HHInfo *info;

    LIST_FOR_EACH_ENTRY(info, &window_list, HHInfo, entry)
    {
        if (strcmpW(info->WinType.pszType, window) == 0)
            return info;
    }
    return NULL;
}
