/*
 * ieframe - Internet Explorer main frame window
 *
 * Copyright 2006 Mike McCormack (for CodeWeavers)
 * Copyright 2006 Jacek Caban (for CodeWeavers)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define COBJMACROS

#include <stdarg.h>

#include "ieframe.h"
#include "resource.h"

#include "winuser.h"
#include "wingdi.h"
#include "winnls.h"
#include "ole2.h"
#include "exdisp.h"
#include "oleidl.h"

#include "mshtmcid.h"
#include "shellapi.h"
#include "winreg.h"
#include "shlwapi.h"
#include "intshcut.h"
#include "ddeml.h"
#include "ieautomation.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ieframe);

#define IDI_APPICON 1

#define WM_UPDATEADDRBAR    (WM_APP+1)

static const WCHAR szIEWinFrame[] = { 'I','E','F','r','a','m','e',0 };

/* Windows uses "Microsoft Internet Explorer" */
static const WCHAR wszWineInternetExplorer[] =
        {'W','i','n','e',' ','I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r',0};

static LONG obj_cnt;
static DWORD dde_inst;
static HSZ ddestr_iexplore, ddestr_openurl;
static struct list ie_list = LIST_INIT(ie_list);

HRESULT update_ie_statustext(InternetExplorer* This, LPCWSTR text)
{
    if(!SendMessageW(This->status_hwnd, SB_SETTEXTW, MAKEWORD(SB_SIMPLEID, 0), (LPARAM)text))
        return E_FAIL;

    return S_OK;
}

static void adjust_ie_docobj_rect(HWND frame, RECT* rc)
{
    HWND hwndRebar = GetDlgItem(frame, IDC_BROWSE_REBAR);
    HWND hwndStatus = GetDlgItem(frame, IDC_BROWSE_STATUSBAR);
    INT barHeight = SendMessageW(hwndRebar, RB_GETBARHEIGHT, 0, 0);

    InflateRect(rc, 0, -barHeight);

    if(IsWindowVisible(hwndStatus))
    {
        RECT statusrc;

        GetClientRect(hwndStatus, &statusrc);
        rc->bottom -= statusrc.bottom - statusrc.top;
    }
}

static HMENU get_tb_menu(HMENU menu)
{
    HMENU menu_view = GetSubMenu(menu, 1);

    return GetSubMenu(menu_view, 0);
}

static HMENU get_fav_menu(HMENU menu)
{
    return GetSubMenu(menu, 2);
}

static LPWSTR get_fav_url_from_id(HMENU menu, UINT id)
{
    MENUITEMINFOW item;

    item.cbSize = sizeof(item);
    item.fMask = MIIM_DATA;

    if(!GetMenuItemInfoW(menu, id, FALSE, &item))
        return NULL;

    return (LPWSTR)item.dwItemData;
}

static void free_fav_menu_data(HMENU menu)
{
    LPWSTR url;
    int i;

    for(i = 0; (url = get_fav_url_from_id(menu, ID_BROWSE_GOTOFAV_FIRST + i)); i++)
        heap_free( url );
}

static int get_menu_item_count(HMENU menu)
{
    MENUITEMINFOW item;
    int count = 0;
    int i;

    item.cbSize = sizeof(item);
    item.fMask = MIIM_DATA | MIIM_SUBMENU;

    for(i = 0; GetMenuItemInfoW(menu, i, TRUE, &item); i++)
    {
        if(item.hSubMenu)
            count += get_menu_item_count(item.hSubMenu);
        else
            count++;
    }

    return count;
}

static void add_fav_to_menu(HMENU favmenu, HMENU menu, LPWSTR title, LPCWSTR url)
{
    MENUITEMINFOW item;
    /* Subtract the number of standard elements in the Favorites menu */
    int favcount = get_menu_item_count(favmenu) - 2;
    LPWSTR urlbuf;

    if(favcount > (ID_BROWSE_GOTOFAV_MAX - ID_BROWSE_GOTOFAV_FIRST))
    {
        FIXME("Add support for more than %d Favorites\n", favcount);
        return;
    }

    urlbuf = heap_alloc((lstrlenW(url) + 1) * sizeof(WCHAR));

    if(!urlbuf)
        return;

    lstrcpyW(urlbuf, url);

    item.cbSize = sizeof(item);
    item.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_DATA | MIIM_ID;
    item.fType = MFT_STRING;
    item.dwTypeData = title;
    item.wID = ID_BROWSE_GOTOFAV_FIRST + favcount;
    item.dwItemData = (ULONG_PTR)urlbuf;
    InsertMenuItemW(menu, -1, TRUE, &item);
}

static void add_favs_to_menu(HMENU favmenu, HMENU menu, LPCWSTR dir)
{
    WCHAR path[MAX_PATH*2];
    const WCHAR search[] = {'*',0};
    WCHAR* filename;
    HANDLE findhandle;
    WIN32_FIND_DATAW finddata;
    IUniformResourceLocatorW* urlobj;
    IPersistFile* urlfile = NULL;
    HRESULT res;

    lstrcpyW(path, dir);
    PathAppendW(path, search);

    findhandle = FindFirstFileW(path, &finddata);

    if(findhandle == INVALID_HANDLE_VALUE)
        return;

    res = CoCreateInstance(&CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER, &IID_IUniformResourceLocatorW, (PVOID*)&urlobj);

    if(SUCCEEDED(res))
        res = IUnknown_QueryInterface((IUnknown*)urlobj, &IID_IPersistFile, (PVOID*)&urlfile);

    if(SUCCEEDED(res))
    {
        filename = path + lstrlenW(path) - lstrlenW(search);

        do
        {
            lstrcpyW(filename, finddata.cFileName);

            if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                MENUITEMINFOW item;
                const WCHAR ignore1[] = {'.','.',0};
                const WCHAR ignore2[] = {'.',0};

                if(!lstrcmpW(filename, ignore1) || !lstrcmpW(filename, ignore2))
                    continue;

                item.cbSize = sizeof(item);
                item.fMask = MIIM_STRING | MIIM_SUBMENU;
                item.dwTypeData = filename;
                item.hSubMenu = CreatePopupMenu();
                InsertMenuItemW(menu, -1, TRUE, &item);
                add_favs_to_menu(favmenu, item.hSubMenu, path);
            } else
            {
                WCHAR* fileext;
                WCHAR* url = NULL;
                const WCHAR urlext[] = {'.','u','r','l',0};

                if(lstrcmpiW(PathFindExtensionW(filename), urlext))
                    continue;

                if(FAILED(IPersistFile_Load(urlfile, path, 0)))
                    continue;

                urlobj->lpVtbl->GetURL(urlobj, &url);

                if(!url)
                    continue;

                fileext = filename + lstrlenW(filename) - lstrlenW(urlext);
                *fileext = 0;
                add_fav_to_menu(favmenu, menu, filename, url);
            }
        } while(FindNextFileW(findhandle, &finddata));
    }

    if(urlfile)
        IPersistFile_Release(urlfile);

    if(urlobj)
        IUnknown_Release((IUnknown*)urlobj);

    FindClose(findhandle);
}

static void add_tbs_to_menu(HMENU menu)
{
    HUSKEY toolbar_handle;
    WCHAR toolbar_key[] = {'S','o','f','t','w','a','r','e','\\',
                           'M','i','c','r','o','s','o','f','t','\\',
                           'I','n','t','e','r','n','e','t',' ',
                           'E','x','p','l','o','r','e','r','\\',
                           'T','o','o','l','b','a','r',0};

    if(SHRegOpenUSKeyW(toolbar_key, KEY_READ, NULL, &toolbar_handle, TRUE) == ERROR_SUCCESS)
    {
        HUSKEY classes_handle;
        WCHAR classes_key[] = {'S','o','f','t','w','a','r','e','\\',
                               'C','l','a','s','s','e','s','\\','C','L','S','I','D',0};
        WCHAR guid[39];
        DWORD value_len = sizeof(guid)/sizeof(guid[0]);
        int i;

        if(SHRegOpenUSKeyW(classes_key, KEY_READ, NULL, &classes_handle, TRUE) != ERROR_SUCCESS)
        {
            SHRegCloseUSKey(toolbar_handle);
            ERR("Failed to open key %s\n", debugstr_w(classes_key));
            return;
        }

        for(i = 0; SHRegEnumUSValueW(toolbar_handle, i, guid, &value_len, NULL, NULL, NULL, SHREGENUM_HKLM) == ERROR_SUCCESS; i++)
        {
            WCHAR tb_name[100];
            DWORD tb_name_len = sizeof(tb_name)/sizeof(tb_name[0]);
            HUSKEY tb_class_handle;
            MENUITEMINFOW item;
            LSTATUS ret;
            value_len = sizeof(guid)/sizeof(guid[0]);

            if(lstrlenW(guid) != 38)
            {
                TRACE("Found invalid IE toolbar entry: %s\n", debugstr_w(guid));
                continue;
            }

            if(SHRegOpenUSKeyW(guid, KEY_READ, classes_handle, &tb_class_handle, TRUE) != ERROR_SUCCESS)
            {
                ERR("Failed to get class info for %s\n", debugstr_w(guid));
                continue;
            }

            ret = SHRegQueryUSValueW(tb_class_handle, NULL, NULL, tb_name, &tb_name_len, TRUE, NULL, 0);

            SHRegCloseUSKey(tb_class_handle);

            if(ret != ERROR_SUCCESS)
            {
                ERR("Failed to get toolbar name for %s\n", debugstr_w(guid));
                continue;
            }

            item.cbSize = sizeof(item);
            item.fMask = MIIM_STRING;
            item.dwTypeData = tb_name;
            InsertMenuItemW(menu, GetMenuItemCount(menu), TRUE, &item);
        }

        SHRegCloseUSKey(classes_handle);
        SHRegCloseUSKey(toolbar_handle);
    }
}

static HMENU create_ie_menu(void)
{
    HMENU menu = LoadMenuW(ieframe_instance, MAKEINTRESOURCEW(IDR_BROWSE_MAIN_MENU));
    HMENU favmenu = get_fav_menu(menu);
    WCHAR path[MAX_PATH];

    add_tbs_to_menu(get_tb_menu(menu));

    if(SHGetFolderPathW(NULL, CSIDL_COMMON_FAVORITES, NULL, SHGFP_TYPE_CURRENT, path) == S_OK)
        add_favs_to_menu(favmenu, favmenu, path);

    if(SHGetFolderPathW(NULL, CSIDL_FAVORITES, NULL, SHGFP_TYPE_CURRENT, path) == S_OK)
        add_favs_to_menu(favmenu, favmenu, path);

    return menu;
}

static void ie_navigate(InternetExplorer* This, LPCWSTR url)
{
    VARIANT variant;

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

    IWebBrowser2_Navigate2(&This->IWebBrowser2_iface, &variant, NULL, NULL, NULL, NULL);

    SysFreeString(V_BSTR(&variant));
}

static INT_PTR CALLBACK ie_dialog_open_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    static InternetExplorer* This;

    switch(msg)
    {
        case WM_INITDIALOG:
            This = (InternetExplorer*)lparam;
            EnableWindow(GetDlgItem(hwnd, IDOK), FALSE);
            return TRUE;

        case WM_COMMAND:
            switch(LOWORD(wparam))
            {
                case IDC_BROWSE_OPEN_URL:
                {
                    HWND hwndurl = GetDlgItem(hwnd, IDC_BROWSE_OPEN_URL);
                    int len = GetWindowTextLengthW(hwndurl);

                    EnableWindow(GetDlgItem(hwnd, IDOK), len != 0);
                    break;
                }
                case IDOK:
                {
                    HWND hwndurl = GetDlgItem(hwnd, IDC_BROWSE_OPEN_URL);
                    int len = GetWindowTextLengthW(hwndurl);

                    if(len)
                    {
                        VARIANT url;

                        V_VT(&url) = VT_BSTR;
                        V_BSTR(&url) = SysAllocStringLen(NULL, len);

                        GetWindowTextW(hwndurl, V_BSTR(&url), len + 1);
                        IWebBrowser2_Navigate2(&This->IWebBrowser2_iface, &url, NULL, NULL, NULL, NULL);

                        SysFreeString(V_BSTR(&url));
                    }
                }
                /* fall through */
                case IDCANCEL:
                    EndDialog(hwnd, wparam);
                    return TRUE;
            }
    }
    return FALSE;
}

static void ie_dialog_about(HWND hwnd)
{
    HICON icon = LoadImageW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDI_APPICON), IMAGE_ICON, 48, 48, LR_SHARED);

    ShellAboutW(hwnd, wszWineInternetExplorer, NULL, icon);

    DestroyIcon(icon);
}

static void add_tb_separator(InternetExplorer *ie)
{
    TBBUTTON btn;

    ZeroMemory(&btn, sizeof(btn));

    btn.iBitmap = 3;
    btn.fsStyle = BTNS_SEP;
    SendMessageW(ie->toolbar_hwnd, TB_ADDBUTTONSW, 1, (LPARAM)&btn);
}

static void add_tb_button(InternetExplorer *ie, int bmp, int cmd, int strId)
{
    TBBUTTON btn;
    WCHAR buf[30];

    LoadStringW(ieframe_instance, strId, buf, sizeof(buf)/sizeof(buf[0]));

    btn.iBitmap = bmp;
    btn.idCommand = cmd;
    btn.fsState = TBSTATE_ENABLED;
    btn.fsStyle = BTNS_SHOWTEXT;
    btn.dwData = 0;
    btn.iString = (INT_PTR)buf;

    SendMessageW(ie->toolbar_hwnd, TB_ADDBUTTONSW, 1, (LPARAM)&btn);
}

static void enable_toolbar_button(InternetExplorer *ie, int command, BOOL enable)
{
    SendMessageW(ie->toolbar_hwnd, TB_ENABLEBUTTON, command, enable);
}

static void create_rebar(InternetExplorer *ie)
{
    HWND hwndRebar;
    HWND hwndAddress;
    REBARINFO rebarinf;
    REBARBANDINFOW bandinf;
    WCHAR addr[40];
    HIMAGELIST imagelist;
    SIZE toolbar_size;

    LoadStringW(ieframe_instance, IDS_ADDRESS, addr, sizeof(addr)/sizeof(addr[0]));

    hwndRebar = CreateWindowExW(WS_EX_TOOLWINDOW, REBARCLASSNAMEW, NULL,
            WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|RBS_VARHEIGHT|CCS_TOP|CCS_NODIVIDER, 0, 0, 0, 0,
            ie->frame_hwnd, (HMENU)IDC_BROWSE_REBAR, ieframe_instance, NULL);

    rebarinf.cbSize = sizeof(rebarinf);
    rebarinf.fMask = 0;
    rebarinf.himl = NULL;

    SendMessageW(hwndRebar, RB_SETBARINFO, 0, (LPARAM)&rebarinf);

    ie->toolbar_hwnd = CreateWindowExW(TBSTYLE_EX_MIXEDBUTTONS, TOOLBARCLASSNAMEW, NULL, TBSTYLE_FLAT | WS_CHILD | WS_VISIBLE | CCS_NORESIZE,
            0, 0, 0, 0, hwndRebar, (HMENU)IDC_BROWSE_TOOLBAR, ieframe_instance, NULL);

    imagelist = ImageList_LoadImageW(ieframe_instance, MAKEINTRESOURCEW(IDB_IETOOLBAR), 32, 0, CLR_NONE, IMAGE_BITMAP, LR_CREATEDIBSECTION);

    SendMessageW(ie->toolbar_hwnd, TB_SETIMAGELIST, 0, (LPARAM)imagelist);
    SendMessageW(ie->toolbar_hwnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
    add_tb_button(ie, 0, ID_BROWSE_BACK, IDS_TB_BACK);
    add_tb_button(ie, 1, ID_BROWSE_FORWARD, IDS_TB_FORWARD);
    add_tb_button(ie, 2, ID_BROWSE_STOP, IDS_TB_STOP);
    add_tb_button(ie, 3, ID_BROWSE_REFRESH, IDS_TB_REFRESH);
    add_tb_button(ie, 4, ID_BROWSE_HOME, IDS_TB_HOME);
    add_tb_separator(ie);
    add_tb_button(ie, 5, ID_BROWSE_PRINT, IDS_TB_PRINT);
    SendMessageW(ie->toolbar_hwnd, TB_SETBUTTONSIZE, 0, MAKELPARAM(65,50));
    SendMessageW(ie->toolbar_hwnd, TB_GETMAXSIZE, 0, (LPARAM)&toolbar_size);

    bandinf.cbSize = sizeof(bandinf);
    bandinf.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE;
    bandinf.fStyle = RBBS_CHILDEDGE;
    bandinf.cxMinChild = toolbar_size.cx;
    bandinf.cyMinChild = toolbar_size.cy+2;
    bandinf.hwndChild = ie->toolbar_hwnd;

    SendMessageW(hwndRebar, RB_INSERTBANDW, -1, (LPARAM)&bandinf);

    hwndAddress = CreateWindowExW(0, WC_COMBOBOXEXW, NULL, WS_BORDER|WS_CHILD|WS_VISIBLE|CBS_DROPDOWN,
            0, 0, 100,20,hwndRebar, (HMENU)IDC_BROWSE_ADDRESSBAR, ieframe_instance, NULL);

    bandinf.fMask |= RBBIM_TEXT;
    bandinf.fStyle = RBBS_CHILDEDGE | RBBS_BREAK;
    bandinf.lpText = addr;
    bandinf.cxMinChild = 100;
    bandinf.cyMinChild = 20;
    bandinf.hwndChild = hwndAddress;

    SendMessageW(hwndRebar, RB_INSERTBANDW, -1, (LPARAM)&bandinf);
}

static LRESULT iewnd_OnCreate(HWND hwnd, LPCREATESTRUCTW lpcs)
{
    InternetExplorer* This = (InternetExplorer*)lpcs->lpCreateParams;
    SetWindowLongPtrW(hwnd, 0, (LONG_PTR) lpcs->lpCreateParams);

    This->doc_host.frame_hwnd = This->frame_hwnd = hwnd;

    This->menu = create_ie_menu();

    This->status_hwnd = CreateStatusWindowW(WS_VISIBLE|WS_CHILD|SBT_NOBORDERS|CCS_NODIVIDER,
                                            NULL, hwnd, IDC_BROWSE_STATUSBAR);
    SendMessageW(This->status_hwnd, SB_SIMPLE, TRUE, 0);

    create_rebar(This);

    return 0;
}

static LRESULT iewnd_OnSize(InternetExplorer *This, INT width, INT height)
{
    HWND hwndRebar = GetDlgItem(This->frame_hwnd, IDC_BROWSE_REBAR);
    INT barHeight = SendMessageW(hwndRebar, RB_GETBARHEIGHT, 0, 0);
    RECT docarea = {0, 0, width, height};

    SendMessageW(This->status_hwnd, WM_SIZE, 0, 0);

    adjust_ie_docobj_rect(This->frame_hwnd, &docarea);

    if(This->doc_host.hwnd)
        SetWindowPos(This->doc_host.hwnd, NULL, docarea.left, docarea.top, docarea.right, docarea.bottom,
                     SWP_NOZORDER | SWP_NOACTIVATE);

    SetWindowPos(hwndRebar, NULL, 0, 0, width, barHeight, SWP_NOZORDER | SWP_NOACTIVATE);

    return 0;
}

static LRESULT iewnd_OnNotify(InternetExplorer *This, WPARAM wparam, LPARAM lparam)
{
    NMHDR* hdr = (NMHDR*)lparam;

    if(hdr->idFrom == IDC_BROWSE_ADDRESSBAR && hdr->code == CBEN_ENDEDITW)
    {
        NMCBEENDEDITW* info = (NMCBEENDEDITW*)lparam;

        if(info->fChanged && info->iWhy == CBENF_RETURN)
        {
            VARIANT vt;

            V_VT(&vt) = VT_BSTR;
            V_BSTR(&vt) = SysAllocString(info->szText);

            IWebBrowser2_Navigate2(&This->IWebBrowser2_iface, &vt, NULL, NULL, NULL, NULL);

            SysFreeString(V_BSTR(&vt));

            return 0;
        }
    }

    if(hdr->idFrom == IDC_BROWSE_REBAR && hdr->code == RBN_HEIGHTCHANGE)
    {
        RECT docarea;

        GetClientRect(This->frame_hwnd, &docarea);
        adjust_ie_docobj_rect(This->frame_hwnd, &docarea);

        if(This->doc_host.hwnd)
            SetWindowPos(This->doc_host.hwnd, NULL, docarea.left, docarea.top, docarea.right, docarea.bottom,
                    SWP_NOZORDER | SWP_NOACTIVATE);
    }

    return 0;
}

static LRESULT iewnd_OnDestroy(InternetExplorer *This)
{
    HIMAGELIST list = (HIMAGELIST)SendMessageW(This->toolbar_hwnd, TB_GETIMAGELIST, 0, 0);

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

    free_fav_menu_data(get_fav_menu(This->menu));
    ImageList_Destroy(list);
    This->frame_hwnd = NULL;

    return 0;
}

static LRESULT iewnd_OnCommand(InternetExplorer *This, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch(LOWORD(wparam))
    {
        case ID_BROWSE_OPEN:
            DialogBoxParamW(ieframe_instance, MAKEINTRESOURCEW(IDD_BROWSE_OPEN), hwnd, ie_dialog_open_proc, (LPARAM)This);
            break;

        case ID_BROWSE_PRINT:
            if(This->doc_host.document)
            {
                IOleCommandTarget* target;

                if(FAILED(IUnknown_QueryInterface(This->doc_host.document, &IID_IOleCommandTarget, (LPVOID*)&target)))
                    break;

                IOleCommandTarget_Exec(target, &CGID_MSHTML, IDM_PRINT, OLECMDEXECOPT_DODEFAULT, NULL, NULL);

                IOleCommandTarget_Release(target);
            }
            break;

        case ID_BROWSE_HOME:
            IWebBrowser2_GoHome(&This->IWebBrowser2_iface);
            break;

        case ID_BROWSE_BACK:
            IWebBrowser2_GoBack(&This->IWebBrowser2_iface);
            break;

        case ID_BROWSE_FORWARD:
            IWebBrowser2_GoForward(&This->IWebBrowser2_iface);
            break;

        case ID_BROWSE_STOP:
            IWebBrowser2_Stop(&This->IWebBrowser2_iface);
            break;

        case ID_BROWSE_REFRESH:
            IWebBrowser2_Refresh(&This->IWebBrowser2_iface);
            break;

        case ID_BROWSE_ABOUT:
            ie_dialog_about(hwnd);
            break;

        case ID_BROWSE_QUIT:
            ShowWindow(hwnd, SW_HIDE);
            break;

        default:
            if(LOWORD(wparam) >= ID_BROWSE_GOTOFAV_FIRST && LOWORD(wparam) <= ID_BROWSE_GOTOFAV_MAX)
            {
                LPCWSTR url = get_fav_url_from_id(get_fav_menu(This->menu), LOWORD(wparam));

                if(url)
                    ie_navigate(This, url);
            }
            return DefWindowProcW(hwnd, msg, wparam, lparam);
    }
    return 0;
}

static LRESULT update_addrbar(InternetExplorer *This, LPARAM lparam)
{
    HWND hwndRebar = GetDlgItem(This->frame_hwnd, IDC_BROWSE_REBAR);
    HWND hwndAddress = GetDlgItem(hwndRebar, IDC_BROWSE_ADDRESSBAR);
    HWND hwndEdit = (HWND)SendMessageW(hwndAddress, CBEM_GETEDITCONTROL, 0, 0);
    LPCWSTR url = (LPCWSTR)lparam;

    SendMessageW(hwndEdit, WM_SETTEXT, 0, (LPARAM)url);

    return 0;
}

static LRESULT WINAPI ie_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    InternetExplorer *This = (InternetExplorer*) GetWindowLongPtrW(hwnd, 0);

    switch (msg)
    {
    case WM_CREATE:
        return iewnd_OnCreate(hwnd, (LPCREATESTRUCTW)lparam);
    case WM_CLOSE:
        TRACE("WM_CLOSE\n");
        ShowWindow(hwnd, SW_HIDE);
        return 0;
    case WM_SHOWWINDOW:
        TRACE("WM_SHOWWINDOW %lx\n", wparam);
        if(wparam) {
            IWebBrowser2_AddRef(&This->IWebBrowser2_iface);
            InterlockedIncrement(&This->extern_ref);
        }else {
            release_extern_ref(This, TRUE);
            IWebBrowser2_Release(&This->IWebBrowser2_iface);
        }
        break;
    case WM_DESTROY:
        return iewnd_OnDestroy(This);
    case WM_SIZE:
        return iewnd_OnSize(This, LOWORD(lparam), HIWORD(lparam));
    case WM_COMMAND:
        return iewnd_OnCommand(This, hwnd, msg, wparam, lparam);
    case WM_NOTIFY:
        return iewnd_OnNotify(This, wparam, lparam);
    case WM_DOCHOSTTASK:
        return process_dochost_tasks(&This->doc_host);
    case WM_UPDATEADDRBAR:
        return update_addrbar(This, lparam);
    }
    return DefWindowProcW(hwnd, msg, wparam, lparam);
}

void register_iewindow_class(void)
{
    WNDCLASSEXW wc;

    memset(&wc, 0, sizeof wc);
    wc.cbSize = sizeof(wc);
    wc.style = 0;
    wc.lpfnWndProc = ie_window_proc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = sizeof(InternetExplorer*);
    wc.hInstance = ieframe_instance;
    wc.hIcon = LoadIconW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDI_APPICON));
    wc.hIconSm = LoadImageW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDI_APPICON), IMAGE_ICON,
                            GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED);
    wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
    wc.hbrBackground = 0;
    wc.lpszClassName = szIEWinFrame;
    wc.lpszMenuName = NULL;

    RegisterClassExW(&wc);
}

void unregister_iewindow_class(void)
{
    UnregisterClassW(szIEWinFrame, ieframe_instance);
}

static void create_frame_hwnd(InternetExplorer *This)
{
    CreateWindowExW(
            WS_EX_WINDOWEDGE,
            szIEWinFrame, wszWineInternetExplorer,
            WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
                | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
            NULL, NULL /* FIXME */, ieframe_instance, This);

    create_doc_view_hwnd(&This->doc_host);
}

static inline InternetExplorer *impl_from_DocHost(DocHost *iface)
{
    return CONTAINING_RECORD(iface, InternetExplorer, doc_host);
}

static ULONG IEDocHost_addref(DocHost *iface)
{
    InternetExplorer *This = impl_from_DocHost(iface);
    return IWebBrowser2_AddRef(&This->IWebBrowser2_iface);
}

static ULONG IEDocHost_release(DocHost *iface)
{
    InternetExplorer *This = impl_from_DocHost(iface);
    return IWebBrowser2_Release(&This->IWebBrowser2_iface);
}

static void DocHostContainer_get_docobj_rect(DocHost *This, RECT *rc)
{
    GetClientRect(This->frame_hwnd, rc);
    adjust_ie_docobj_rect(This->frame_hwnd, rc);
}

static HRESULT DocHostContainer_set_status_text(DocHost *iface, const WCHAR *text)
{
    InternetExplorer *This = impl_from_DocHost(iface);
    return update_ie_statustext(This, text);
}

static void DocHostContainer_on_command_state_change(DocHost *iface, LONG command, BOOL enable)
{
    InternetExplorer *This = impl_from_DocHost(iface);

    switch(command) {
    case CSC_NAVIGATEBACK:
        enable_toolbar_button(This, ID_BROWSE_BACK, enable);
        break;
    case CSC_NAVIGATEFORWARD:
        enable_toolbar_button(This, ID_BROWSE_FORWARD, enable);
        break;
    }
}

static void DocHostContainer_set_url(DocHost* iface, const WCHAR *url)
{
    InternetExplorer *This = impl_from_DocHost(iface);

    This->nohome = FALSE;
    SendMessageW(This->frame_hwnd, WM_UPDATEADDRBAR, 0, (LPARAM)url);
}

static const IDocHostContainerVtbl DocHostContainerVtbl = {
    IEDocHost_addref,
    IEDocHost_release,
    DocHostContainer_get_docobj_rect,
    DocHostContainer_set_status_text,
    DocHostContainer_on_command_state_change,
    DocHostContainer_set_url
};

static HRESULT create_ie(InternetExplorer **ret_obj)
{
    InternetExplorer *ret;

    ret = heap_alloc_zero(sizeof(InternetExplorer));
    if(!ret)
        return E_OUTOFMEMORY;

    ret->ref = 1;

    DocHost_Init(&ret->doc_host, &ret->IWebBrowser2_iface, &DocHostContainerVtbl);

    InternetExplorer_WebBrowser_Init(ret);

    HlinkFrame_Init(&ret->hlink_frame, (IUnknown*)&ret->IWebBrowser2_iface, &ret->doc_host);

    create_frame_hwnd(ret);

    InterlockedIncrement(&obj_cnt);
    list_add_tail(&ie_list, &ret->entry);
    *ret_obj = ret;
    return S_OK;
}

HRESULT WINAPI InternetExplorer_Create(IClassFactory *iface, IUnknown *pOuter, REFIID riid, void **ppv)
{
    InternetExplorer *ret;
    HRESULT hres;

    TRACE("(%p %s %p)\n", pOuter, debugstr_guid(riid), ppv);

    hres = create_ie(&ret);
    if(FAILED(hres))
        return hres;

    hres = IWebBrowser2_QueryInterface(&ret->IWebBrowser2_iface, riid, ppv);
    IWebBrowser2_Release(&ret->IWebBrowser2_iface);
    if(FAILED(hres))
        return hres;

    return S_OK;
}

/******************************************************************
 *      IInternetExplorerManager implementation
 */
struct InternetExplorerManager {
    IInternetExplorerManager IInternetExplorerManager_iface;
    LONG ref;
};

static inline InternetExplorerManager *impl_from_IInternetExplorerManager(IInternetExplorerManager *iface)
{
    return CONTAINING_RECORD(iface, InternetExplorerManager, IInternetExplorerManager_iface);
}

static HRESULT WINAPI InternetExplorerManager_QueryInterface(IInternetExplorerManager *iface, REFIID riid, void **out)
{
    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), out);

    if (IsEqualGUID(riid, &IID_IInternetExplorerManager) || IsEqualGUID(riid, &IID_IUnknown))
    {
        IInternetExplorerManager_AddRef(iface);
        *out = iface;
        return S_OK;
    }

    FIXME("interface %s not implemented\n", debugstr_guid(riid));
    *out = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI InternetExplorerManager_AddRef(IInternetExplorerManager *iface)
{
    InternetExplorerManager *This = impl_from_IInternetExplorerManager(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) increasing refcount to %u\n", iface, ref);

    return ref;
}

static ULONG WINAPI InternetExplorerManager_Release(IInternetExplorerManager *iface)
{
    InternetExplorerManager *This = impl_from_IInternetExplorerManager(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) decreasing refcount to %u\n", iface, ref);

    if (ref == 0)
        HeapFree(GetProcessHeap(), 0, This);

    return ref;
}

static HRESULT WINAPI InternetExplorerManager_CreateObject(IInternetExplorerManager *iface, DWORD config, LPCWSTR url, REFIID riid, void **ppv)
{
    FIXME("(%p)->(0x%x, %s, %s, %p) stub!\n", iface, config, debugstr_w(url), debugstr_guid(riid), ppv);

    return E_NOTIMPL;
}

static const IInternetExplorerManagerVtbl InternetExplorerManager_vtbl =
{
    InternetExplorerManager_QueryInterface,
    InternetExplorerManager_AddRef,
    InternetExplorerManager_Release,
    InternetExplorerManager_CreateObject,
};

HRESULT WINAPI InternetExplorerManager_Create(IClassFactory *iface, IUnknown *pOuter, REFIID riid, void **ppv)
{
    InternetExplorerManager *ret;
    HRESULT hr;

    TRACE("(%p %s %p)\n", pOuter, debugstr_guid(riid), ppv);

    if (!(ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret))))
        return E_OUTOFMEMORY;

    ret->IInternetExplorerManager_iface.lpVtbl = &InternetExplorerManager_vtbl;
    ret->ref = 1;

    hr = IInternetExplorerManager_QueryInterface(&ret->IInternetExplorerManager_iface, riid, ppv);
    IInternetExplorerManager_Release(&ret->IInternetExplorerManager_iface);

    return hr;
}

void released_obj(void)
{
    if(!InterlockedDecrement(&obj_cnt))
        PostQuitMessage(0);
}

static BOOL create_ie_window(BOOL nohome, const WCHAR *cmdline)
{
    InternetExplorer *ie;
    HRESULT hres;

    hres = create_ie(&ie);
    if(FAILED(hres))
        return FALSE;

    IWebBrowser2_put_Visible(&ie->IWebBrowser2_iface, VARIANT_TRUE);
    IWebBrowser2_put_MenuBar(&ie->IWebBrowser2_iface, VARIANT_TRUE);

    if(!*cmdline) {
        if (nohome)
            ie->nohome = TRUE;
        else
            IWebBrowser2_GoHome(&ie->IWebBrowser2_iface);
    }else {
        VARIANT var_url;
        int cmdlen;

        cmdlen = strlenW(cmdline);
        if(cmdlen > 2 && cmdline[0] == '"' && cmdline[cmdlen-1] == '"') {
            cmdline++;
            cmdlen -= 2;
        }

        V_VT(&var_url) = VT_BSTR;
        V_BSTR(&var_url) = SysAllocStringLen(cmdline, cmdlen);

        /* navigate to the first page */
        IWebBrowser2_Navigate2(&ie->IWebBrowser2_iface, &var_url, NULL, NULL, NULL, NULL);

        SysFreeString(V_BSTR(&var_url));
    }

    IWebBrowser2_Release(&ie->IWebBrowser2_iface);
    return TRUE;
}

static HDDEDATA open_dde_url(WCHAR *dde_url)
{
    InternetExplorer *ie = NULL, *iter;
    WCHAR *url, *url_end;
    VARIANT urlv;
    HRESULT hres;

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

    url = dde_url;
    if(*url == '"') {
        url++;
        url_end = strchrW(url, '"');
        if(!url_end) {
            FIXME("missing string terminator\n");
            return 0;
        }
        *url_end = 0;
    }else {
        url_end = strchrW(url, ',');
        if(url_end)
            *url_end = 0;
        else
            url_end = url + strlenW(url);
    }

    LIST_FOR_EACH_ENTRY(iter, &ie_list, InternetExplorer, entry) {
        if(iter->nohome) {
            IWebBrowser2_AddRef(&iter->IWebBrowser2_iface);
            ie = iter;
            break;
        }
    }

    if(!ie) {
        hres = create_ie(&ie);
        if(FAILED(hres))
            return 0;
    }

    IWebBrowser2_put_Visible(&ie->IWebBrowser2_iface, VARIANT_TRUE);
    IWebBrowser2_put_MenuBar(&ie->IWebBrowser2_iface, VARIANT_TRUE);

    V_VT(&urlv) = VT_BSTR;
    V_BSTR(&urlv) = SysAllocStringLen(url, url_end-url);
    if(!V_BSTR(&urlv)) {
        IWebBrowser2_Release(&ie->IWebBrowser2_iface);
        return 0;
    }

    hres = IWebBrowser2_Navigate2(&ie->IWebBrowser2_iface, &urlv, NULL, NULL, NULL, NULL);
    if(FAILED(hres))
        return 0;

    IWebBrowser2_Release(&ie->IWebBrowser2_iface);
    return ULongToHandle(DDE_FACK);
}

static HDDEDATA WINAPI dde_proc(UINT type, UINT uFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA data,
        ULONG_PTR dwData1, ULONG_PTR dwData2)
{
    switch(type) {
    case XTYP_CONNECT:
        TRACE("XTYP_CONNECT %p\n", hsz1);
        return ULongToHandle(!DdeCmpStringHandles(hsz1, ddestr_openurl));

    case XTYP_EXECUTE: {
        WCHAR *url;
        DWORD size;
        HDDEDATA ret;

        TRACE("XTYP_EXECUTE %p\n", data);

        size = DdeGetData(data, NULL, 0, 0);
        if(!size) {
            WARN("size = 0\n");
            break;
        }

        url = heap_alloc(size);
        if(!url)
            break;

        if(DdeGetData(data, (BYTE*)url, size, 0) != size) {
            ERR("error during read\n");
            heap_free(url);
            break;
        }

        ret = open_dde_url(url);

        heap_free(url);
        return ret;
    }

    case XTYP_REQUEST:
        FIXME("XTYP_REQUEST\n");
        break;

    default:
        TRACE("type %d\n", type);
    }

    return NULL;
}

static void init_dde(void)
{
    UINT res;

    static const WCHAR iexploreW[] = {'I','E','x','p','l','o','r','e',0};
    static const WCHAR openurlW[] = {'W','W','W','_','O','p','e','n','U','R','L',0};

    res = DdeInitializeW(&dde_inst, dde_proc, CBF_SKIP_ALLNOTIFICATIONS | CBF_FAIL_ADVISES | CBF_FAIL_POKES, 0);
    if(res != DMLERR_NO_ERROR) {
        WARN("DdeInitialize failed: %u\n", res);
        return;
    }

    ddestr_iexplore = DdeCreateStringHandleW(dde_inst, iexploreW, CP_WINUNICODE);
    if(!ddestr_iexplore)
        WARN("Failed to create string handle: %u\n", DdeGetLastError(dde_inst));

    ddestr_openurl = DdeCreateStringHandleW(dde_inst, openurlW, CP_WINUNICODE);
    if(!ddestr_openurl)
        WARN("Failed to create string handle: %u\n", DdeGetLastError(dde_inst));

    if(!DdeNameService(dde_inst, ddestr_iexplore, 0, DNS_REGISTER))
        WARN("DdeNameService failed\n");
}

static void release_dde(void)
{
    if(ddestr_iexplore)
        DdeNameService(dde_inst, ddestr_iexplore, 0, DNS_UNREGISTER);
    if(ddestr_openurl)
        DdeFreeStringHandle(dde_inst, ddestr_openurl);
    if(ddestr_iexplore)
        DdeFreeStringHandle(dde_inst, ddestr_iexplore);
    DdeUninitialize(dde_inst);
}

/******************************************************************
 *		IEWinMain            (ieframe.101)
 *
 * Only returns on error.
 */
DWORD WINAPI IEWinMain(const WCHAR *cmdline, int nShowWindow)
{
    MSG msg;
    HRESULT hres;
    BOOL embedding = FALSE, nohome = FALSE, manager = FALSE;
    DWORD reg_cookie;

    static const WCHAR embeddingW[] = {'-','e','m','b','e','d','d','i','n','g',0};
    static const WCHAR nohomeW[] = {'-','n','o','h','o','m','e',0};
    static const WCHAR startmanagerW[] = {'-','s','t','a','r','t','m','a','n','a','g','e','r',0};

    TRACE("%s %d\n", debugstr_w(cmdline), nShowWindow);

    CoInitialize(NULL);

    init_dde();

    while (*cmdline)
    {
        int length = 0;

        while (*cmdline == ' ' || *cmdline == '\t') cmdline++;
        if (!*cmdline) break;

        while (cmdline[length] && cmdline[length] != ' ' && cmdline[length] != '\t') length++;

        if (!strncmpiW(cmdline, embeddingW, length))
            embedding = TRUE;
        else if (!strncmpiW(cmdline, nohomeW, length))
            nohome = TRUE;
        else if (!strncmpiW(cmdline, startmanagerW, length))
            manager = TRUE;
        else
            break;

        cmdline += length;
    }

    if (manager)
        hres = CoRegisterClassObject(&CLSID_InternetExplorerManager,
            (IUnknown*)&InternetExplorerManagerFactory, CLSCTX_SERVER,
            REGCLS_SINGLEUSE, &reg_cookie);
    else
        hres = CoRegisterClassObject(&CLSID_InternetExplorer,
            (IUnknown*)&InternetExplorerFactory, CLSCTX_SERVER,
            REGCLS_MULTIPLEUSE, &reg_cookie);

    if (FAILED(hres))
    {
        ERR("failed to register CLSID_InternetExplorer%s: %08x\n", manager ? "Manager" : "", hres);
        CoUninitialize();
        ExitProcess(1);
    }

    if (!embedding)
    {
        if(!create_ie_window(nohome, cmdline))
        {
            CoUninitialize();
            ExitProcess(1);
        }
    }

    /* run the message loop for this thread */
    while (GetMessageW(&msg, 0, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }

    CoRevokeClassObject(reg_cookie);
    release_dde();

    CoUninitialize();

    ExitProcess(0);
    return 0;
}
