/*
 * 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

static const WCHAR szEmpty[] = {0};

/* 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;
}

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];
    LPWSTR ptr;

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

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

    /* FIXME: HACK */
    if((ptr = strchrW(buf, '#')))
       *ptr = 0;

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

static void DoSync(HHInfo *info)
{
    WCHAR buf[INTERNET_MAX_URL_LENGTH];
    HRESULT hres;
    DWORD len;
    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->pszFile, buf, NULL)) || (len = 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, GWLP_USERDATA);
    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     = 0;
    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 (!pHHInfo->WinType.fNotExpanded)
        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, GWLP_USERDATA, (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, GWLP_USERDATA);
    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);
    return 0;
}

static LRESULT OnTabChange(HWND hwnd)
{
    HHInfo *info = (HHInfo*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);

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

    if (!info)
        return 0;

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

    info->current_tab = SendMessageW(info->hwndTabCtrl, TCM_GETCURSEL, 0, 0);

    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)
                    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, GWLP_USERDATA);
        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 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     = 0;
    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, GWLP_USERDATA);

    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_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;

    /* 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, 0, (LPARAM)&tbAB);

    *pdwNumButtons = 0;

    if (dwButtonFlags & HHWIN_BUTTON_EXPAND)
    {
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_EXPAND, nHistBitmaps + HIST_VIEWTREE);
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_CONTRACT, nHistBitmaps + HIST_VIEWTREE);

        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 + HH_STOP);

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

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

    /* FIXME: Load the correct button bitmaps */
    if (dwButtonFlags & HHWIN_BUTTON_SYNC)
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_SYNC, nStdBitmaps + STD_PRINT);

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

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

    if (dwButtonFlags & HHWIN_BUTTON_JUMP1)
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_JUMP1, nStdBitmaps + STD_PRINT);

    if (dwButtonFlags & HHWIN_BUTTON_JUMP2)
        TB_AddButton(pButtons,(*pdwNumButtons)++, IDTB_JUMP2, nStdBitmaps + STD_PRINT);

    if (dwButtonFlags & HHWIN_BUTTON_ZOOM)
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_ZOOM, nStdBitmaps + STD_PRINT);

    if (dwButtonFlags & HHWIN_BUTTON_TOC_NEXT)
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_TOC_NEXT, nStdBitmaps + STD_PRINT);

    if (dwButtonFlags & HHWIN_BUTTON_TOC_PREV)
        TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_TOC_PREV, 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 | WS_VISIBLE | 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);
    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 (!info->WinType.fNotExpanded)
        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, GWLP_USERDATA, (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->WinType.hwndToolBar, &rectTB);
    GetClientRect(info->hwndSizeBar, &rectSB);

    if (info->WinType.fNotExpanded)
        rc->left = 0;
    else
    {
        GetClientRect(info->WinType.hwndNavigation, &rectNP);
        rc->left = rectNP.right + rectSB.right;
    }

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

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, GWLP_USERDATA, (LONG_PTR)pHHInfo);

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

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

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

    ResizeTabChild(info, TAB_CONTENTS);
    ShowWindow(info->tabs[TAB_CONTENTS].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, GWLP_USERDATA, (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, GWLP_USERDATA);

    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, GWLP_USERDATA);
            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, GWLP_USERDATA);
            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     = 0;
    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     = 0;
    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, GWLP_USERDATA, (LONG_PTR)info);
    SetWindowLongPtrW(hwndCallback, GWLP_USERDATA, (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, GWLP_USERDATA);
    DWORD dwSize;
    RECT rc;

    if (!pHHInfo)
        return 0;

    if (!pHHInfo->WinType.fNotExpanded)
    {
        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;
}

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, GWLP_USERDATA));
        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;
    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     = 0;
    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 | 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.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;

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

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

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

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

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

    GetObjectW(GetStockObject(ANSI_VAR_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);

    return TRUE;
}

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

    if (!info)
        return;

    /* Free allocated strings */
    heap_free(info->pszType);
    heap_free(info->pszCaption);
    heap_free(info->pszToc);
    heap_free(info->pszIndex);
    heap_free(info->pszFile);
    heap_free(info->pszHome);
    heap_free(info->pszJump1);
    heap_free(info->pszJump2);
    heap_free(info->pszUrlJump1);
    heap_free(info->pszUrlJump2);

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

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

    if(info->WinType.hwndHelp)
        DestroyWindow(info->WinType.hwndHelp);

    heap_free(info);
    OleUninitialize();
}

HHInfo *CreateHelpViewer(LPCWSTR filename)
{
    HHInfo *info = heap_alloc_zero(sizeof(HHInfo));
    int i;

    /* 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;
    }

    if(!CreateViewer(info)) {
        ReleaseHelpViewer(info);
        return NULL;
    }

    return info;
}
