/*
 * Copyright 2005-2007 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
 */

#include "config.h"

#include <stdarg.h>
#include <assert.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "ole2.h"
#include "shlobj.h"

#include "wine/debug.h"

#include "mshtml_private.h"
#include "htmlevent.h"
#include "binding.h"

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
WINE_DECLARE_DEBUG_CHANNEL(gecko);

#define NS_APPSTARTUPNOTIFIER_CONTRACTID "@mozilla.org/embedcomp/appstartup-notifier;1"
#define NS_WEBBROWSER_CONTRACTID "@mozilla.org/embedding/browser/nsWebBrowser;1"
#define NS_MEMORY_CONTRACTID "@mozilla.org/xpcom/memory-service;1"
#define NS_COMMANDPARAMS_CONTRACTID "@mozilla.org/embedcomp/command-params;1"
#define NS_HTMLSERIALIZER_CONTRACTID "@mozilla.org/layout/contentserializer;1?mimetype=text/html"
#define NS_EDITORCONTROLLER_CONTRACTID "@mozilla.org/editor/editorcontroller;1"
#define NS_PREFERENCES_CONTRACTID "@mozilla.org/preferences;1"
#define NS_VARIANT_CONTRACTID "@mozilla.org/variant;1"

#define PR_UINT32_MAX 0xffffffff

#define NS_STRING_CONTAINER_INIT_DEPEND  0x0002
#define NS_CSTRING_CONTAINER_INIT_DEPEND 0x0002

static nsresult (CDECL *NS_InitXPCOM2)(nsIServiceManager**,void*,void*);
static nsresult (CDECL *NS_ShutdownXPCOM)(nsIServiceManager*);
static nsresult (CDECL *NS_GetComponentRegistrar)(nsIComponentRegistrar**);
static nsresult (CDECL *NS_StringContainerInit2)(nsStringContainer*,const PRUnichar*,PRUint32,PRUint32);
static nsresult (CDECL *NS_CStringContainerInit2)(nsCStringContainer*,const char*,PRUint32,PRUint32);
static nsresult (CDECL *NS_StringContainerFinish)(nsStringContainer*);
static nsresult (CDECL *NS_CStringContainerFinish)(nsCStringContainer*);
static nsresult (CDECL *NS_StringSetData)(nsAString*,const PRUnichar*,PRUint32);
static nsresult (CDECL *NS_CStringSetData)(nsACString*,const char*,PRUint32);
static nsresult (CDECL *NS_NewLocalFile)(const nsAString*,cpp_bool,nsIFile**);
static PRUint32 (CDECL *NS_StringGetData)(const nsAString*,const PRUnichar **,cpp_bool*);
static PRUint32 (CDECL *NS_CStringGetData)(const nsACString*,const char**,cpp_bool*);

static HINSTANCE xul_handle = NULL;

static nsIServiceManager *pServMgr = NULL;
static nsIComponentManager *pCompMgr = NULL;
static nsIMemory *nsmem = NULL;
static nsIFile *profile_directory, *plugin_directory;

static const WCHAR wszNsContainer[] = {'N','s','C','o','n','t','a','i','n','e','r',0};

static ATOM nscontainer_class;
static WCHAR gecko_path[MAX_PATH];
static unsigned gecko_path_len;

nsresult create_nsfile(const PRUnichar *path, nsIFile **ret)
{
    nsAString str;
    nsresult nsres;

    nsAString_InitDepend(&str, path);
    nsres = NS_NewLocalFile(&str, FALSE, ret);
    nsAString_Finish(&str);

    if(NS_FAILED(nsres))
        WARN("NS_NewLocalFile failed: %08x\n", nsres);
    return nsres;
}

typedef struct {
    nsISimpleEnumerator nsISimpleEnumerator_iface;
    LONG ref;
    nsISupports *value;
} nsSingletonEnumerator;

static inline nsSingletonEnumerator *impl_from_nsISimpleEnumerator(nsISimpleEnumerator *iface)
{
    return CONTAINING_RECORD(iface, nsSingletonEnumerator, nsISimpleEnumerator_iface);
}

static nsresult NSAPI nsSingletonEnumerator_QueryInterface(nsISimpleEnumerator *iface, nsIIDRef riid, void **ppv)
{
    nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);

    if(IsEqualGUID(&IID_nsISupports, riid)) {
        TRACE("(%p)->(IID_nsISupports %p)\n", This, ppv);
        *ppv = &This->nsISimpleEnumerator_iface;
    }else if(IsEqualGUID(&IID_nsISimpleEnumerator, riid)) {
        TRACE("(%p)->(IID_nsISimpleEnumerator %p)\n", This, ppv);
        *ppv = &This->nsISimpleEnumerator_iface;
    }else {
        TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
        *ppv = NULL;
        return NS_NOINTERFACE;
    }

    nsISupports_AddRef((nsISupports*)*ppv);
    return NS_OK;
}

static nsrefcnt NSAPI nsSingletonEnumerator_AddRef(nsISimpleEnumerator *iface)
{
    nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);
    nsrefcnt ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static nsrefcnt NSAPI nsSingletonEnumerator_Release(nsISimpleEnumerator *iface)
{
    nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);
    nsrefcnt ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref) {
        if(This->value)
            nsISupports_Release(This->value);
        heap_free(This);
    }

    return ref;
}

static nsresult NSAPI nsSingletonEnumerator_HasMoreElements(nsISimpleEnumerator *iface, cpp_bool *_retval)
{
    nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);

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

    *_retval = This->value != NULL;
    return NS_OK;
}

static nsresult NSAPI nsSingletonEnumerator_GetNext(nsISimpleEnumerator *iface, nsISupports **_retval)
{
    nsSingletonEnumerator *This = impl_from_nsISimpleEnumerator(iface);

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

    if(!This->value)
        return NS_ERROR_UNEXPECTED;

    *_retval = This->value;
    This->value = NULL;
    return NS_OK;
}

static const nsISimpleEnumeratorVtbl nsSingletonEnumeratorVtbl = {
    nsSingletonEnumerator_QueryInterface,
    nsSingletonEnumerator_AddRef,
    nsSingletonEnumerator_Release,
    nsSingletonEnumerator_HasMoreElements,
    nsSingletonEnumerator_GetNext
};

static nsISimpleEnumerator *create_singleton_enumerator(nsISupports *value)
{
    nsSingletonEnumerator *ret;

    ret = heap_alloc(sizeof(*ret));
    if(!ret)
        return NULL;

    ret->nsISimpleEnumerator_iface.lpVtbl = &nsSingletonEnumeratorVtbl;
    ret->ref = 1;

    if(value)
        nsISupports_AddRef(value);
    ret->value = value;
    return &ret->nsISimpleEnumerator_iface;
}

static nsresult NSAPI nsDirectoryServiceProvider2_QueryInterface(nsIDirectoryServiceProvider2 *iface,
        nsIIDRef riid, void **result)
{
    if(IsEqualGUID(&IID_nsISupports, riid)) {
        TRACE("(IID_nsISupports %p)\n", result);
        *result = iface;
    }else if(IsEqualGUID(&IID_nsIDirectoryServiceProvider, riid)) {
        TRACE("(IID_nsIDirectoryServiceProvider %p)\n", result);
        *result = iface;
    }else if(IsEqualGUID(&IID_nsIDirectoryServiceProvider2, riid)) {
        TRACE("(IID_nsIDirectoryServiceProvider2 %p)\n", result);
        *result = iface;
    }else {
        WARN("(%s %p)\n", debugstr_guid(riid), result);
        *result = NULL;
        return NS_NOINTERFACE;
    }

    nsISupports_AddRef((nsISupports*)*result);
    return NS_OK;
}

static nsrefcnt NSAPI nsDirectoryServiceProvider2_AddRef(nsIDirectoryServiceProvider2 *iface)
{
    return 2;
}

static nsrefcnt NSAPI nsDirectoryServiceProvider2_Release(nsIDirectoryServiceProvider2 *iface)
{
    return 1;
}

static nsresult create_profile_directory(void)
{
    static const WCHAR wine_geckoW[] = {'\\','w','i','n','e','_','g','e','c','k','o',0};

    WCHAR path[MAX_PATH + sizeof(wine_geckoW)/sizeof(WCHAR)];
    cpp_bool exists;
    nsresult nsres;
    HRESULT hres;

    hres = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path);
    if(FAILED(hres)) {
        ERR("SHGetFolderPath failed: %08x\n", hres);
        return NS_ERROR_FAILURE;
    }

    strcatW(path, wine_geckoW);
    nsres = create_nsfile(path, &profile_directory);
    if(NS_FAILED(nsres))
        return nsres;

    nsres = nsIFile_Exists(profile_directory, &exists);
    if(NS_FAILED(nsres)) {
        ERR("Exists failed: %08x\n", nsres);
        return nsres;
    }

    if(!exists) {
        nsres = nsIFile_Create(profile_directory, 1, 0700);
        if(NS_FAILED(nsres))
            ERR("Create failed: %08x\n", nsres);
    }

    return nsres;
}

static nsresult NSAPI nsDirectoryServiceProvider2_GetFile(nsIDirectoryServiceProvider2 *iface,
        const char *prop, cpp_bool *persistent, nsIFile **_retval)
{
    TRACE("(%s %p %p)\n", debugstr_a(prop), persistent, _retval);

    if(!strcmp(prop, "ProfD")) {
        if(!profile_directory) {
            nsresult nsres;

            nsres = create_profile_directory();
            if(NS_FAILED(nsres))
                return nsres;
        }

        return nsIFile_Clone(profile_directory, _retval);
    }

    return NS_ERROR_FAILURE;
}

static nsresult NSAPI nsDirectoryServiceProvider2_GetFiles(nsIDirectoryServiceProvider2 *iface,
        const char *prop, nsISimpleEnumerator **_retval)
{
    TRACE("(%s %p)\n", debugstr_a(prop), _retval);

    if(!strcmp(prop, "APluginsDL")) {
        WCHAR plugin_path[MAX_PATH];
        nsIFile *file;
        int len;
        nsresult nsres;

        if(!plugin_directory) {
            static const WCHAR gecko_pluginW[] = {'\\','g','e','c','k','o','\\','p','l','u','g','i','n',0};

            len = GetSystemDirectoryW(plugin_path, (sizeof(plugin_path)-sizeof(gecko_pluginW))/sizeof(WCHAR)+1);
            if(!len)
                return NS_ERROR_UNEXPECTED;

            strcpyW(plugin_path+len, gecko_pluginW);
            nsres = create_nsfile(plugin_path, &plugin_directory);
            if(NS_FAILED(nsres))
                return nsres;
        }

        nsres = nsIFile_Clone(plugin_directory, &file);
        if(NS_FAILED(nsres))
            return nsres;

        *_retval = create_singleton_enumerator((nsISupports*)file);
        nsIFile_Release(file);
        if(!*_retval)
            return NS_ERROR_OUT_OF_MEMORY;

        return NS_OK;
    }

    return NS_ERROR_FAILURE;
}

static const nsIDirectoryServiceProvider2Vtbl nsDirectoryServiceProvider2Vtbl = {
    nsDirectoryServiceProvider2_QueryInterface,
    nsDirectoryServiceProvider2_AddRef,
    nsDirectoryServiceProvider2_Release,
    nsDirectoryServiceProvider2_GetFile,
    nsDirectoryServiceProvider2_GetFiles
};

static nsIDirectoryServiceProvider2 nsDirectoryServiceProvider2 =
    { &nsDirectoryServiceProvider2Vtbl };

static LRESULT WINAPI nsembed_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    NSContainer *This;
    nsresult nsres;

    static const WCHAR wszTHIS[] = {'T','H','I','S',0};

    if(msg == WM_CREATE) {
        This = *(NSContainer**)lParam;
        SetPropW(hwnd, wszTHIS, This);
    }else {
        This = GetPropW(hwnd, wszTHIS);
    }

    switch(msg) {
    case WM_SIZE:
        TRACE("(%p)->(WM_SIZE)\n", This);

        nsres = nsIBaseWindow_SetSize(This->window,
                LOWORD(lParam), HIWORD(lParam), TRUE);
        if(NS_FAILED(nsres))
            WARN("SetSize failed: %08x\n", nsres);
        break;

    case WM_PARENTNOTIFY:
        TRACE("WM_PARENTNOTIFY %x\n", (unsigned)wParam);

        switch(wParam) {
        case WM_LBUTTONDOWN:
        case WM_RBUTTONDOWN:
            nsIWebBrowserFocus_Activate(This->focus);
        }
    }

    return DefWindowProcW(hwnd, msg, wParam, lParam);
}


static void register_nscontainer_class(void)
{
    static WNDCLASSEXW wndclass = {
        sizeof(WNDCLASSEXW),
        CS_DBLCLKS,
        nsembed_proc,
        0, 0, NULL, NULL, NULL, NULL, NULL,
        wszNsContainer,
        NULL,
    };
    wndclass.hInstance = hInst;
    nscontainer_class = RegisterClassExW(&wndclass);
}

static BOOL install_wine_gecko(void)
{
    PROCESS_INFORMATION pi;
    STARTUPINFOW si;
    WCHAR app[MAX_PATH];
    WCHAR *args;
    LONG len;
    BOOL ret;

    static const WCHAR controlW[] = {'\\','c','o','n','t','r','o','l','.','e','x','e',0};
    static const WCHAR argsW[] =
        {' ','a','p','p','w','i','z','.','c','p','l',' ','i','n','s','t','a','l','l','_','g','e','c','k','o',0};

    len = GetSystemDirectoryW(app, MAX_PATH-sizeof(controlW)/sizeof(WCHAR));
    memcpy(app+len, controlW, sizeof(controlW));

    args = heap_alloc(len*sizeof(WCHAR) + sizeof(controlW) + sizeof(argsW));
    if(!args)
        return FALSE;

    memcpy(args, app, len*sizeof(WCHAR) + sizeof(controlW));
    memcpy(args + len + sizeof(controlW)/sizeof(WCHAR)-1, argsW, sizeof(argsW));

    TRACE("starting %s\n", debugstr_w(args));

    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    ret = CreateProcessW(app, args, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
    heap_free(args);
    if (ret) {
        CloseHandle(pi.hThread);
        WaitForSingleObject(pi.hProcess, INFINITE);
        CloseHandle(pi.hProcess);
    }

    return ret;
}

static void set_environment(LPCWSTR gre_path)
{
    WCHAR path_env[MAX_PATH], buf[20];
    int len, debug_level = 0;

    static const WCHAR pathW[] = {'P','A','T','H',0};
    static const WCHAR warnW[] = {'w','a','r','n',0};
    static const WCHAR xpcom_debug_breakW[] =
        {'X','P','C','O','M','_','D','E','B','U','G','_','B','R','E','A','K',0};
    static const WCHAR nspr_log_modulesW[] =
        {'N','S','P','R','_','L','O','G','_','M','O','D','U','L','E','S',0};
    static const WCHAR debug_formatW[] = {'a','l','l',':','%','d',0};

    /* We have to modify PATH as XPCOM loads other DLLs from this directory. */
    GetEnvironmentVariableW(pathW, path_env, sizeof(path_env)/sizeof(WCHAR));
    len = strlenW(path_env);
    path_env[len++] = ';';
    strcpyW(path_env+len, gre_path);
    SetEnvironmentVariableW(pathW, path_env);

    SetEnvironmentVariableW(xpcom_debug_breakW, warnW);

    if(TRACE_ON(gecko))
        debug_level = 5;
    else if(WARN_ON(gecko))
        debug_level = 3;
    else if(ERR_ON(gecko))
        debug_level = 2;

    sprintfW(buf, debug_formatW, debug_level);
    SetEnvironmentVariableW(nspr_log_modulesW, buf);
}

static BOOL load_xul(const PRUnichar *gre_path)
{
    static const WCHAR xul_dllW[] = {'\\','x','u','l','.','d','l','l',0};
    WCHAR file_name[MAX_PATH];

    strcpyW(file_name, gre_path);
    strcatW(file_name, xul_dllW);

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

    set_environment(gre_path);

    xul_handle = LoadLibraryExW(file_name, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
    if(!xul_handle) {
        WARN("Could not load XUL: %d\n", GetLastError());
        return FALSE;
    }

#define NS_DLSYM(func) \
    func = (void *)GetProcAddress(xul_handle, #func "_P"); \
    if(!func) \
        ERR("Could not GetProcAddress(" #func ") failed\n")

    NS_DLSYM(NS_InitXPCOM2);
    NS_DLSYM(NS_ShutdownXPCOM);
    NS_DLSYM(NS_GetComponentRegistrar);
    NS_DLSYM(NS_StringContainerInit2);
    NS_DLSYM(NS_CStringContainerInit2);
    NS_DLSYM(NS_StringContainerFinish);
    NS_DLSYM(NS_CStringContainerFinish);
    NS_DLSYM(NS_StringSetData);
    NS_DLSYM(NS_CStringSetData);
    NS_DLSYM(NS_NewLocalFile);
    NS_DLSYM(NS_StringGetData);
    NS_DLSYM(NS_CStringGetData);

#undef NS_DLSYM

#define NS_DLSYM(func) \
    func = (void *)GetProcAddress(xul_handle, #func); \
    if(!func) \
        ERR("Could not GetProcAddress(" #func ") failed\n")

    NS_DLSYM(ccref_incr);
    NS_DLSYM(ccref_decr);
    NS_DLSYM(ccref_init);
    NS_DLSYM(ccref_unmark_if_purple);
    NS_DLSYM(ccp_init);
    NS_DLSYM(describe_cc_node);
    NS_DLSYM(note_cc_edge);

#undef NS_DLSYM

    return TRUE;
}

static BOOL check_version(LPCWSTR gre_path, const char *version_string)
{
    WCHAR file_name[MAX_PATH];
    char version[128];
    DWORD read=0;
    HANDLE hfile;

    static const WCHAR wszVersion[] = {'\\','V','E','R','S','I','O','N',0};

    strcpyW(file_name, gre_path);
    strcatW(file_name, wszVersion);

    hfile = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if(hfile == INVALID_HANDLE_VALUE) {
        ERR("Could not open VERSION file\n");
        return FALSE;
    }

    ReadFile(hfile, version, sizeof(version), &read, NULL);
    version[read] = 0;
    CloseHandle(hfile);

    TRACE("%s\n", debugstr_a(version));

    if(strcmp(version, version_string)) {
        ERR("Unexpected version %s, expected %s\n", debugstr_a(version),
            debugstr_a(version_string));
        return FALSE;
    }

    return TRUE;
}

static BOOL load_wine_gecko_v(PRUnichar *gre_path, HKEY mshtml_key,
        const char *version, const char *version_string)
{
    DWORD res, type, size = MAX_PATH;
    HKEY hkey = mshtml_key;

    static const WCHAR wszGeckoPath[] =
        {'G','e','c','k','o','P','a','t','h',0};

    if(version) {
        /* @@ Wine registry key: HKLM\Software\Wine\MSHTML\<version> */
        res = RegOpenKeyA(mshtml_key, version, &hkey);
        if(res != ERROR_SUCCESS)
            return FALSE;
    }

    res = RegQueryValueExW(hkey, wszGeckoPath, NULL, &type, (LPBYTE)gre_path, &size);
    if(hkey != mshtml_key)
        RegCloseKey(hkey);
    if(res != ERROR_SUCCESS || type != REG_SZ)
        return FALSE;

    if(!check_version(gre_path, version_string))
        return FALSE;

    return load_xul(gre_path);
}

static BOOL load_wine_gecko(PRUnichar *gre_path)
{
    HKEY hkey;
    DWORD res;
    BOOL ret;

    static const WCHAR wszMshtmlKey[] = {
        'S','o','f','t','w','a','r','e','\\','W','i','n','e',
        '\\','M','S','H','T','M','L',0};

    /* @@ Wine registry key: HKLM\Software\Wine\MSHTML */
    res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszMshtmlKey, &hkey);
    if(res != ERROR_SUCCESS)
        return FALSE;

    ret = load_wine_gecko_v(gre_path, hkey, GECKO_VERSION, GECKO_VERSION_STRING);

    RegCloseKey(hkey);
    return ret;
}

static void set_bool_pref(nsIPrefBranch *pref, const char *pref_name, BOOL val)
{
    nsresult nsres;

    nsres = nsIPrefBranch_SetBoolPref(pref, pref_name, val);
    if(NS_FAILED(nsres))
        ERR("Could not set pref %s\n", debugstr_a(pref_name));
}

static void set_int_pref(nsIPrefBranch *pref, const char *pref_name, int val)
{
    nsresult nsres;

    nsres = nsIPrefBranch_SetIntPref(pref, pref_name, val);
    if(NS_FAILED(nsres))
        ERR("Could not set pref %s\n", debugstr_a(pref_name));
}

static void set_string_pref(nsIPrefBranch *pref, const char *pref_name, const char *val)
{
    nsresult nsres;

    nsres = nsIPrefBranch_SetCharPref(pref, pref_name, val);
    if(NS_FAILED(nsres))
        ERR("Could not set pref %s\n", debugstr_a(pref_name));
}

static void set_lang(nsIPrefBranch *pref)
{
    char langs[100];
    DWORD res, size, type;
    HKEY hkey;

    static const WCHAR international_keyW[] =
        {'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',
         '\\','I','n','t','e','r','n','a','t','i','o','n','a','l',0};

    res = RegOpenKeyW(HKEY_CURRENT_USER, international_keyW, &hkey);
    if(res != ERROR_SUCCESS)
        return;

    size = sizeof(langs);
    res = RegQueryValueExA(hkey, "AcceptLanguage", 0, &type, (LPBYTE)langs, &size);
    RegCloseKey(hkey);
    if(res != ERROR_SUCCESS || type != REG_SZ)
        return;

    TRACE("Setting lang %s\n", debugstr_a(langs));

    set_string_pref(pref, "intl.accept_languages", langs);
}

static void set_preferences(void)
{
    nsIPrefBranch *pref;
    nsresult nsres;

    nsres = nsIServiceManager_GetServiceByContractID(pServMgr, NS_PREFERENCES_CONTRACTID,
            &IID_nsIPrefBranch, (void**)&pref);
    if(NS_FAILED(nsres)) {
        ERR("Could not get preference service: %08x\n", nsres);
        return;
    }

    set_lang(pref);
    set_bool_pref(pref, "security.warn_entering_secure", FALSE);
    set_bool_pref(pref, "security.warn_submit_insecure", FALSE);
    set_int_pref(pref, "layout.spellcheckDefault", 0);

    nsIPrefBranch_Release(pref);
}

static BOOL init_xpcom(const PRUnichar *gre_path)
{
    nsIComponentRegistrar *registrar = NULL;
    nsIFile *gre_dir;
    WCHAR *ptr;
    nsresult nsres;

    nsres = create_nsfile(gre_path, &gre_dir);
    if(NS_FAILED(nsres)) {
        FreeLibrary(xul_handle);
        return FALSE;
    }

    nsres = NS_InitXPCOM2(&pServMgr, gre_dir, (nsIDirectoryServiceProvider*)&nsDirectoryServiceProvider2);
    if(NS_FAILED(nsres)) {
        ERR("NS_InitXPCOM2 failed: %08x\n", nsres);
        FreeLibrary(xul_handle);
        return FALSE;
    }

    strcpyW(gecko_path, gre_path);
    for(ptr = gecko_path; *ptr; ptr++) {
        if(*ptr == '\\')
            *ptr = '/';
    }
    gecko_path_len = ptr-gecko_path;

    nsres = nsIServiceManager_QueryInterface(pServMgr, &IID_nsIComponentManager, (void**)&pCompMgr);
    if(NS_FAILED(nsres))
        ERR("Could not get nsIComponentManager: %08x\n", nsres);

    nsres = NS_GetComponentRegistrar(&registrar);
    if(NS_SUCCEEDED(nsres))
        init_nsio(pCompMgr, registrar);
    else
        ERR("NS_GetComponentRegistrar failed: %08x\n", nsres);

    init_mutation(pCompMgr);
    set_preferences();

    nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_MEMORY_CONTRACTID,
            NULL, &IID_nsIMemory, (void**)&nsmem);
    if(NS_FAILED(nsres))
        ERR("Could not get nsIMemory: %08x\n", nsres);

    if(registrar) {
        register_nsservice(registrar, pServMgr);
        nsIComponentRegistrar_Release(registrar);
    }

    init_node_cc();

    return TRUE;
}

static CRITICAL_SECTION cs_load_gecko;
static CRITICAL_SECTION_DEBUG cs_load_gecko_dbg =
{
    0, 0, &cs_load_gecko,
    { &cs_load_gecko_dbg.ProcessLocksList, &cs_load_gecko_dbg.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": load_gecko") }
};
static CRITICAL_SECTION cs_load_gecko = { &cs_load_gecko_dbg, -1, 0, 0, 0, 0 };

BOOL load_gecko(void)
{
    PRUnichar gre_path[MAX_PATH];
    BOOL ret = FALSE;

    static DWORD loading_thread;

    TRACE("()\n");

    /* load_gecko may be called recursively */
    if(loading_thread == GetCurrentThreadId())
        return pCompMgr != NULL;

    EnterCriticalSection(&cs_load_gecko);

    if(!loading_thread) {
        loading_thread = GetCurrentThreadId();

        if(load_wine_gecko(gre_path)
           || (install_wine_gecko() && load_wine_gecko(gre_path)))
            ret = init_xpcom(gre_path);
        else
           MESSAGE("Could not load wine-gecko. HTML rendering will be disabled.\n");
    }else {
        ret = pCompMgr != NULL;
    }

    LeaveCriticalSection(&cs_load_gecko);

    return ret;
}

void *nsalloc(size_t size)
{
    return nsIMemory_Alloc(nsmem, size);
}

void nsfree(void *mem)
{
    nsIMemory_Free(nsmem, mem);
}

static BOOL nsACString_Init(nsACString *str, const char *data)
{
    return NS_SUCCEEDED(NS_CStringContainerInit2(str, data, PR_UINT32_MAX, 0));
}

/*
 * Initializes nsACString with data owned by caller.
 * Caller must ensure that data is valid during lifetime of string object.
 */
void nsACString_InitDepend(nsACString *str, const char *data)
{
    NS_CStringContainerInit2(str, data, PR_UINT32_MAX, NS_CSTRING_CONTAINER_INIT_DEPEND);
}

void nsACString_SetData(nsACString *str, const char *data)
{
    NS_CStringSetData(str, data, PR_UINT32_MAX);
}

PRUint32 nsACString_GetData(const nsACString *str, const char **data)
{
    return NS_CStringGetData(str, data, NULL);
}

void nsACString_Finish(nsACString *str)
{
    NS_CStringContainerFinish(str);
}

BOOL nsAString_Init(nsAString *str, const PRUnichar *data)
{
    return NS_SUCCEEDED(NS_StringContainerInit2(str, data, PR_UINT32_MAX, 0));
}

/*
 * Initializes nsAString with data owned by caller.
 * Caller must ensure that data is valid during lifetime of string object.
 */
void nsAString_InitDepend(nsAString *str, const PRUnichar *data)
{
    NS_StringContainerInit2(str, data, PR_UINT32_MAX, NS_STRING_CONTAINER_INIT_DEPEND);
}

void nsAString_SetData(nsAString *str, const PRUnichar *data)
{
    NS_StringSetData(str, data, PR_UINT32_MAX);
}

PRUint32 nsAString_GetData(const nsAString *str, const PRUnichar **data)
{
    return NS_StringGetData(str, data, NULL);
}

void nsAString_Finish(nsAString *str)
{
    NS_StringContainerFinish(str);
}

HRESULT return_nsstr(nsresult nsres, nsAString *nsstr, BSTR *p)
{
    const PRUnichar *str;

    if(NS_FAILED(nsres)) {
        ERR("failed: %08x\n", nsres);
        nsAString_Finish(nsstr);
        return E_FAIL;
    }

    nsAString_GetData(nsstr, &str);
    TRACE("ret %s\n", debugstr_w(str));
    if(*str) {
        *p = SysAllocString(str);
        if(!*p)
            return E_OUTOFMEMORY;
    }else {
        *p = NULL;
    }

    nsAString_Finish(nsstr);
    return S_OK;
}

nsICommandParams *create_nscommand_params(void)
{
    nsICommandParams *ret = NULL;
    nsresult nsres;

    if(!pCompMgr)
        return NULL;

    nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
            NS_COMMANDPARAMS_CONTRACTID, NULL, &IID_nsICommandParams,
            (void**)&ret);
    if(NS_FAILED(nsres))
        ERR("Could not get nsICommandParams\n");

    return ret;
}

nsIWritableVariant *create_nsvariant(void)
{
    nsIWritableVariant *ret = NULL;
    nsresult nsres;

    if(!pCompMgr)
        return NULL;

    nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
            NS_VARIANT_CONTRACTID, NULL, &IID_nsIWritableVariant, (void**)&ret);
    if(NS_FAILED(nsres))
        ERR("Could not get nsIVariant\n");

    return ret;
}

nsresult get_nsinterface(nsISupports *iface, REFIID riid, void **ppv)
{
    nsIInterfaceRequestor *iface_req;
    nsresult nsres;

    nsres = nsISupports_QueryInterface(iface, &IID_nsIInterfaceRequestor, (void**)&iface_req);
    if(NS_FAILED(nsres))
        return nsres;

    nsres = nsIInterfaceRequestor_GetInterface(iface_req, riid, ppv);
    nsIInterfaceRequestor_Release(iface_req);

    return nsres;
}

static HRESULT nsnode_to_nsstring_rec(nsIContentSerializer *serializer, nsIDOMNode *nsnode, nsAString *str)
{
    nsIDOMNodeList *node_list = NULL;
    cpp_bool has_children = FALSE;
    nsIContent *nscontent;
    PRUint16 type;
    nsresult nsres;

    nsIDOMNode_HasChildNodes(nsnode, &has_children);

    nsres = nsIDOMNode_GetNodeType(nsnode, &type);
    if(NS_FAILED(nsres)) {
        ERR("GetType failed: %08x\n", nsres);
        return E_FAIL;
    }

    if(type != DOCUMENT_NODE) {
        nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIContent, (void**)&nscontent);
        if(NS_FAILED(nsres)) {
            ERR("Could not get nsIContent interface: %08x\n", nsres);
            return E_FAIL;
        }
    }

    switch(type) {
    case ELEMENT_NODE:
        nsIContentSerializer_AppendElementStart(serializer, nscontent, nscontent, str);
        break;
    case TEXT_NODE:
        nsIContentSerializer_AppendText(serializer, nscontent, 0, -1, str);
        break;
    case COMMENT_NODE:
        nsres = nsIContentSerializer_AppendComment(serializer, nscontent, 0, -1, str);
        break;
    case DOCUMENT_NODE: {
        nsIDocument *nsdoc;
        nsIDOMNode_QueryInterface(nsnode, &IID_nsIDocument, (void**)&nsdoc);
        nsIContentSerializer_AppendDocumentStart(serializer, nsdoc, str);
        nsIDocument_Release(nsdoc);
        break;
    }
    case DOCUMENT_TYPE_NODE:
        WARN("Ignoring DOCUMENT_TYPE_NODE\n");
        break;
    case DOCUMENT_FRAGMENT_NODE:
        break;
    default:
        FIXME("Unhandled type %u\n", type);
    }

    if(has_children) {
        PRUint32 child_cnt, i;
        nsIDOMNode *child_node;

        nsIDOMNode_GetChildNodes(nsnode, &node_list);
        nsIDOMNodeList_GetLength(node_list, &child_cnt);

        for(i=0; i<child_cnt; i++) {
            nsres = nsIDOMNodeList_Item(node_list, i, &child_node);
            if(NS_SUCCEEDED(nsres)) {
                nsnode_to_nsstring_rec(serializer, child_node, str);
                nsIDOMNode_Release(child_node);
            }else {
                ERR("Item failed: %08x\n", nsres);
            }
        }

        nsIDOMNodeList_Release(node_list);
    }

    if(type == ELEMENT_NODE)
        nsIContentSerializer_AppendElementEnd(serializer, nscontent, str);

    if(type != DOCUMENT_NODE)
        nsIContent_Release(nscontent);
    return S_OK;
}

HRESULT nsnode_to_nsstring(nsIDOMNode *nsnode, nsAString *str)
{
    nsIContentSerializer *serializer;
    nsresult nsres;
    HRESULT hres;

    nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
            NS_HTMLSERIALIZER_CONTRACTID, NULL, &IID_nsIContentSerializer,
            (void**)&serializer);
    if(NS_FAILED(nsres)) {
        ERR("Could not get nsIContentSerializer: %08x\n", nsres);
        return E_FAIL;
    }

    nsres = nsIContentSerializer_Init(serializer, 0, 100, NULL, FALSE, FALSE /* FIXME */);
    if(NS_FAILED(nsres))
        ERR("Init failed: %08x\n", nsres);

    hres = nsnode_to_nsstring_rec(serializer, nsnode, str);
    if(SUCCEEDED(hres)) {
        nsres = nsIContentSerializer_Flush(serializer, str);
        if(NS_FAILED(nsres))
            ERR("Flush failed: %08x\n", nsres);
    }

    nsIContentSerializer_Release(serializer);
    return hres;
}

void get_editor_controller(NSContainer *This)
{
    nsIEditingSession *editing_session = NULL;
    nsIControllerContext *ctrlctx;
    nsresult nsres;

    if(This->editor) {
        nsIEditor_Release(This->editor);
        This->editor = NULL;
    }

    if(This->editor_controller) {
        nsIController_Release(This->editor_controller);
        This->editor_controller = NULL;
    }

    nsres = get_nsinterface((nsISupports*)This->webbrowser, &IID_nsIEditingSession,
            (void**)&editing_session);
    if(NS_FAILED(nsres)) {
        ERR("Could not get nsIEditingSession: %08x\n", nsres);
        return;
    }

    nsres = nsIEditingSession_GetEditorForWindow(editing_session,
            This->doc->basedoc.window->nswindow, &This->editor);
    nsIEditingSession_Release(editing_session);
    if(NS_FAILED(nsres)) {
        ERR("Could not get editor: %08x\n", nsres);
        return;
    }

    nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
            NS_EDITORCONTROLLER_CONTRACTID, NULL, &IID_nsIControllerContext, (void**)&ctrlctx);
    if(NS_SUCCEEDED(nsres)) {
        nsres = nsIControllerContext_SetCommandContext(ctrlctx, (nsISupports *)This->editor);
        if(NS_FAILED(nsres))
            ERR("SetCommandContext failed: %08x\n", nsres);
        nsres = nsIControllerContext_QueryInterface(ctrlctx, &IID_nsIController,
                (void**)&This->editor_controller);
        nsIControllerContext_Release(ctrlctx);
        if(NS_FAILED(nsres))
            ERR("Could not get nsIController interface: %08x\n", nsres);
    }else {
        ERR("Could not create edit controller: %08x\n", nsres);
    }
}

void close_gecko(void)
{
    TRACE("()\n");

    release_nsio();
    init_mutation(NULL);

    if(profile_directory) {
        nsIFile_Release(profile_directory);
        profile_directory = NULL;
    }

    if(plugin_directory) {
        nsIFile_Release(plugin_directory);
        plugin_directory = NULL;
    }

    if(pCompMgr)
        nsIComponentManager_Release(pCompMgr);

    if(pServMgr)
        nsIServiceManager_Release(pServMgr);

    if(nsmem)
        nsIMemory_Release(nsmem);

    /* Gecko doesn't really support being unloaded */
    /* if (hXPCOM) FreeLibrary(hXPCOM); */

    DeleteCriticalSection(&cs_load_gecko);
}

BOOL is_gecko_path(const char *path)
{
    WCHAR *buf, *ptr;
    BOOL ret;

    buf = heap_strdupAtoW(path);
    if(strlenW(buf) < gecko_path_len)
        return FALSE;

    buf[gecko_path_len] = 0;
    for(ptr = buf; *ptr; ptr++) {
        if(*ptr == '\\')
            *ptr = '/';
    }

    ret = !strcmpiW(buf, gecko_path);
    heap_free(buf);
    return ret;
}

struct nsWeakReference {
    nsIWeakReference nsIWeakReference_iface;

    LONG ref;

    NSContainer *nscontainer;
};

static inline nsWeakReference *impl_from_nsIWeakReference(nsIWeakReference *iface)
{
    return CONTAINING_RECORD(iface, nsWeakReference, nsIWeakReference_iface);
}

static nsresult NSAPI nsWeakReference_QueryInterface(nsIWeakReference *iface,
        nsIIDRef riid, void **result)
{
    nsWeakReference *This = impl_from_nsIWeakReference(iface);

    if(IsEqualGUID(&IID_nsISupports, riid)) {
        TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
        *result = &This->nsIWeakReference_iface;
    }else if(IsEqualGUID(&IID_nsIWeakReference, riid)) {
        TRACE("(%p)->(IID_nsIWeakReference %p)\n", This, result);
        *result = &This->nsIWeakReference_iface;
    }else {
        WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
        *result = NULL;
        return NS_NOINTERFACE;
    }

    nsISupports_AddRef((nsISupports*)*result);
    return NS_OK;
}

static nsrefcnt NSAPI nsWeakReference_AddRef(nsIWeakReference *iface)
{
    nsWeakReference *This = impl_from_nsIWeakReference(iface);
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static nsrefcnt NSAPI nsWeakReference_Release(nsIWeakReference *iface)
{
    nsWeakReference *This = impl_from_nsIWeakReference(iface);
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref) {
        assert(!This->nscontainer);
        heap_free(This);
    }

    return ref;
}

static nsresult NSAPI nsWeakReference_QueryReferent(nsIWeakReference *iface,
        const nsIID *riid, void **result)
{
    nsWeakReference *This = impl_from_nsIWeakReference(iface);

    if(!This->nscontainer)
        return NS_ERROR_NULL_POINTER;

    return nsIWebBrowserChrome_QueryInterface(&This->nscontainer->nsIWebBrowserChrome_iface, riid, result);
}

static const nsIWeakReferenceVtbl nsWeakReferenceVtbl = {
    nsWeakReference_QueryInterface,
    nsWeakReference_AddRef,
    nsWeakReference_Release,
    nsWeakReference_QueryReferent
};

/**********************************************************
 *      nsIWebBrowserChrome interface
 */

static inline NSContainer *impl_from_nsIWebBrowserChrome(nsIWebBrowserChrome *iface)
{
    return CONTAINING_RECORD(iface, NSContainer, nsIWebBrowserChrome_iface);
}

static nsresult NSAPI nsWebBrowserChrome_QueryInterface(nsIWebBrowserChrome *iface,
        nsIIDRef riid, void **result)
{
    NSContainer *This = impl_from_nsIWebBrowserChrome(iface);

    *result = NULL;
    if(IsEqualGUID(&IID_nsISupports, riid)) {
        TRACE("(%p)->(IID_nsISupports, %p)\n", This, result);
        *result = &This->nsIWebBrowserChrome_iface;
    }else if(IsEqualGUID(&IID_nsIWebBrowserChrome, riid)) {
        TRACE("(%p)->(IID_nsIWebBrowserChrome, %p)\n", This, result);
        *result = &This->nsIWebBrowserChrome_iface;
    }else if(IsEqualGUID(&IID_nsIContextMenuListener, riid)) {
        TRACE("(%p)->(IID_nsIContextMenuListener, %p)\n", This, result);
        *result = &This->nsIContextMenuListener_iface;
    }else if(IsEqualGUID(&IID_nsIURIContentListener, riid)) {
        TRACE("(%p)->(IID_nsIURIContentListener %p)\n", This, result);
        *result = &This->nsIURIContentListener_iface;
    }else if(IsEqualGUID(&IID_nsIEmbeddingSiteWindow, riid)) {
        TRACE("(%p)->(IID_nsIEmbeddingSiteWindow %p)\n", This, result);
        *result = &This->nsIEmbeddingSiteWindow_iface;
    }else if(IsEqualGUID(&IID_nsITooltipListener, riid)) {
        TRACE("(%p)->(IID_nsITooltipListener %p)\n", This, result);
        *result = &This->nsITooltipListener_iface;
    }else if(IsEqualGUID(&IID_nsIInterfaceRequestor, riid)) {
        TRACE("(%p)->(IID_nsIInterfaceRequestor %p)\n", This, result);
        *result = &This->nsIInterfaceRequestor_iface;
    }else if(IsEqualGUID(&IID_nsISupportsWeakReference, riid)) {
        TRACE("(%p)->(IID_nsISupportsWeakReference %p)\n", This, result);
        *result = &This->nsISupportsWeakReference_iface;
    }

    if(*result) {
        nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
        return NS_OK;
    }

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
    return NS_NOINTERFACE;
}

static nsrefcnt NSAPI nsWebBrowserChrome_AddRef(nsIWebBrowserChrome *iface)
{
    NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static nsrefcnt NSAPI nsWebBrowserChrome_Release(nsIWebBrowserChrome *iface)
{
    NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref) {
        if(This->parent)
            nsIWebBrowserChrome_Release(&This->parent->nsIWebBrowserChrome_iface);
        if(This->weak_reference) {
            This->weak_reference->nscontainer = NULL;
            nsIWeakReference_Release(&This->weak_reference->nsIWeakReference_iface);
        }
        heap_free(This);
    }

    return ref;
}

static nsresult NSAPI nsWebBrowserChrome_SetStatus(nsIWebBrowserChrome *iface,
        PRUint32 statusType, const PRUnichar *status)
{
    NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
    TRACE("(%p)->(%d %s)\n", This, statusType, debugstr_w(status));
    return NS_OK;
}

static nsresult NSAPI nsWebBrowserChrome_GetWebBrowser(nsIWebBrowserChrome *iface,
        nsIWebBrowser **aWebBrowser)
{
    NSContainer *This = impl_from_nsIWebBrowserChrome(iface);

    TRACE("(%p)->(%p)\n", This, aWebBrowser);

    if(!aWebBrowser)
        return NS_ERROR_INVALID_ARG;

    if(This->webbrowser)
        nsIWebBrowser_AddRef(This->webbrowser);
    *aWebBrowser = This->webbrowser;
    return S_OK;
}

static nsresult NSAPI nsWebBrowserChrome_SetWebBrowser(nsIWebBrowserChrome *iface,
        nsIWebBrowser *aWebBrowser)
{
    NSContainer *This = impl_from_nsIWebBrowserChrome(iface);

    TRACE("(%p)->(%p)\n", This, aWebBrowser);

    if(aWebBrowser != This->webbrowser)
        ERR("Wrong nsWebBrowser!\n");

    return NS_OK;
}

static nsresult NSAPI nsWebBrowserChrome_GetChromeFlags(nsIWebBrowserChrome *iface,
        PRUint32 *aChromeFlags)
{
    NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
    WARN("(%p)->(%p)\n", This, aChromeFlags);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsWebBrowserChrome_SetChromeFlags(nsIWebBrowserChrome *iface,
        PRUint32 aChromeFlags)
{
    NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
    WARN("(%p)->(%08x)\n", This, aChromeFlags);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsWebBrowserChrome_DestroyBrowserWindow(nsIWebBrowserChrome *iface)
{
    NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
    TRACE("(%p)\n", This);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsWebBrowserChrome_SizeBrowserTo(nsIWebBrowserChrome *iface,
        PRInt32 aCX, PRInt32 aCY)
{
    NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
    WARN("(%p)->(%d %d)\n", This, aCX, aCY);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsWebBrowserChrome_ShowAsModal(nsIWebBrowserChrome *iface)
{
    NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
    WARN("(%p)\n", This);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsWebBrowserChrome_IsWindowModal(nsIWebBrowserChrome *iface, cpp_bool *_retval)
{
    NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
    WARN("(%p)->(%p)\n", This, _retval);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsWebBrowserChrome_ExitModalEventLoop(nsIWebBrowserChrome *iface,
        nsresult aStatus)
{
    NSContainer *This = impl_from_nsIWebBrowserChrome(iface);
    WARN("(%p)->(%08x)\n", This, aStatus);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static const nsIWebBrowserChromeVtbl nsWebBrowserChromeVtbl = {
    nsWebBrowserChrome_QueryInterface,
    nsWebBrowserChrome_AddRef,
    nsWebBrowserChrome_Release,
    nsWebBrowserChrome_SetStatus,
    nsWebBrowserChrome_GetWebBrowser,
    nsWebBrowserChrome_SetWebBrowser,
    nsWebBrowserChrome_GetChromeFlags,
    nsWebBrowserChrome_SetChromeFlags,
    nsWebBrowserChrome_DestroyBrowserWindow,
    nsWebBrowserChrome_SizeBrowserTo,
    nsWebBrowserChrome_ShowAsModal,
    nsWebBrowserChrome_IsWindowModal,
    nsWebBrowserChrome_ExitModalEventLoop
};

/**********************************************************
 *      nsIContextMenuListener interface
 */

static inline NSContainer *impl_from_nsIContextMenuListener(nsIContextMenuListener *iface)
{
    return CONTAINING_RECORD(iface, NSContainer, nsIContextMenuListener_iface);
}

static nsresult NSAPI nsContextMenuListener_QueryInterface(nsIContextMenuListener *iface,
        nsIIDRef riid, void **result)
{
    NSContainer *This = impl_from_nsIContextMenuListener(iface);
    return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
}

static nsrefcnt NSAPI nsContextMenuListener_AddRef(nsIContextMenuListener *iface)
{
    NSContainer *This = impl_from_nsIContextMenuListener(iface);
    return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
}

static nsrefcnt NSAPI nsContextMenuListener_Release(nsIContextMenuListener *iface)
{
    NSContainer *This = impl_from_nsIContextMenuListener(iface);
    return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
}

static nsresult NSAPI nsContextMenuListener_OnShowContextMenu(nsIContextMenuListener *iface,
        PRUint32 aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode)
{
    NSContainer *This = impl_from_nsIContextMenuListener(iface);
    nsIDOMMouseEvent *event;
    HTMLDOMNode *node;
    POINT pt;
    DWORD dwID = CONTEXT_MENU_DEFAULT;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%08x %p %p)\n", This, aContextFlags, aEvent, aNode);

    fire_event(This->doc->basedoc.doc_node /* FIXME */, EVENTID_CONTEXTMENU, TRUE, aNode, aEvent);

    nsres = nsIDOMEvent_QueryInterface(aEvent, &IID_nsIDOMMouseEvent, (void**)&event);
    if(NS_FAILED(nsres)) {
        ERR("Could not get nsIDOMMouseEvent interface: %08x\n", nsres);
        return nsres;
    }

    nsIDOMMouseEvent_GetScreenX(event, &pt.x);
    nsIDOMMouseEvent_GetScreenY(event, &pt.y);
    nsIDOMMouseEvent_Release(event);

    switch(aContextFlags) {
    case CONTEXT_NONE:
    case CONTEXT_DOCUMENT:
    case CONTEXT_TEXT:
        dwID = CONTEXT_MENU_DEFAULT;
        break;
    case CONTEXT_IMAGE:
    case CONTEXT_IMAGE|CONTEXT_LINK:
        dwID = CONTEXT_MENU_IMAGE;
        break;
    case CONTEXT_LINK:
        dwID = CONTEXT_MENU_ANCHOR;
        break;
    case CONTEXT_INPUT:
        dwID = CONTEXT_MENU_CONTROL;
        break;
    default:
        FIXME("aContextFlags=%08x\n", aContextFlags);
    };

    hres = get_node(This->doc->basedoc.doc_node, aNode, TRUE, &node);
    if(FAILED(hres))
        return NS_ERROR_FAILURE;

    show_context_menu(This->doc, dwID, &pt, (IDispatch*)&node->IHTMLDOMNode_iface);
    node_release(node);
    return NS_OK;
}

static const nsIContextMenuListenerVtbl nsContextMenuListenerVtbl = {
    nsContextMenuListener_QueryInterface,
    nsContextMenuListener_AddRef,
    nsContextMenuListener_Release,
    nsContextMenuListener_OnShowContextMenu
};

/**********************************************************
 *      nsIURIContentListener interface
 */

static inline NSContainer *impl_from_nsIURIContentListener(nsIURIContentListener *iface)
{
    return CONTAINING_RECORD(iface, NSContainer, nsIURIContentListener_iface);
}

static nsresult NSAPI nsURIContentListener_QueryInterface(nsIURIContentListener *iface,
        nsIIDRef riid, void **result)
{
    NSContainer *This = impl_from_nsIURIContentListener(iface);
    return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
}

static nsrefcnt NSAPI nsURIContentListener_AddRef(nsIURIContentListener *iface)
{
    NSContainer *This = impl_from_nsIURIContentListener(iface);
    return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
}

static nsrefcnt NSAPI nsURIContentListener_Release(nsIURIContentListener *iface)
{
    NSContainer *This = impl_from_nsIURIContentListener(iface);
    return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
}

static nsresult NSAPI nsURIContentListener_OnStartURIOpen(nsIURIContentListener *iface,
                                                          nsIURI *aURI, cpp_bool *_retval)
{
    NSContainer *This = impl_from_nsIURIContentListener(iface);
    nsACString spec_str;
    const char *spec;
    nsresult nsres;

    nsACString_Init(&spec_str, NULL);
    nsIURI_GetSpec(aURI, &spec_str);
    nsACString_GetData(&spec_str, &spec);

    TRACE("(%p)->(%p(%s) %p)\n", This, aURI, debugstr_a(spec), _retval);

    nsACString_Finish(&spec_str);

    nsres = on_start_uri_open(This, aURI, _retval);
    if(NS_FAILED(nsres))
        return nsres;

    return !*_retval && This->content_listener
        ? nsIURIContentListener_OnStartURIOpen(This->content_listener, aURI, _retval)
        : NS_OK;
}

static nsresult NSAPI nsURIContentListener_DoContent(nsIURIContentListener *iface,
        const char *aContentType, cpp_bool aIsContentPreferred, nsIRequest *aRequest,
        nsIStreamListener **aContentHandler, cpp_bool *_retval)
{
    NSContainer *This = impl_from_nsIURIContentListener(iface);

    TRACE("(%p)->(%s %x %p %p %p)\n", This, debugstr_a(aContentType), aIsContentPreferred,
            aRequest, aContentHandler, _retval);

    return This->content_listener
        ? nsIURIContentListener_DoContent(This->content_listener, aContentType,
                  aIsContentPreferred, aRequest, aContentHandler, _retval)
        : NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsURIContentListener_IsPreferred(nsIURIContentListener *iface,
        const char *aContentType, char **aDesiredContentType, cpp_bool *_retval)
{
    NSContainer *This = impl_from_nsIURIContentListener(iface);

    TRACE("(%p)->(%s %p %p)\n", This, debugstr_a(aContentType), aDesiredContentType, _retval);

    /* FIXME: Should we do something here? */
    *_retval = TRUE; 

    return This->content_listener
        ? nsIURIContentListener_IsPreferred(This->content_listener, aContentType,
                  aDesiredContentType, _retval)
        : NS_OK;
}

static nsresult NSAPI nsURIContentListener_CanHandleContent(nsIURIContentListener *iface,
        const char *aContentType, cpp_bool aIsContentPreferred, char **aDesiredContentType,
        cpp_bool *_retval)
{
    NSContainer *This = impl_from_nsIURIContentListener(iface);

    TRACE("(%p)->(%s %x %p %p)\n", This, debugstr_a(aContentType), aIsContentPreferred,
            aDesiredContentType, _retval);

    return This->content_listener
        ? nsIURIContentListener_CanHandleContent(This->content_listener, aContentType,
                aIsContentPreferred, aDesiredContentType, _retval)
        : NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsURIContentListener_GetLoadCookie(nsIURIContentListener *iface,
        nsISupports **aLoadCookie)
{
    NSContainer *This = impl_from_nsIURIContentListener(iface);

    WARN("(%p)->(%p)\n", This, aLoadCookie);

    return This->content_listener
        ? nsIURIContentListener_GetLoadCookie(This->content_listener, aLoadCookie)
        : NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsURIContentListener_SetLoadCookie(nsIURIContentListener *iface,
        nsISupports *aLoadCookie)
{
    NSContainer *This = impl_from_nsIURIContentListener(iface);

    WARN("(%p)->(%p)\n", This, aLoadCookie);

    return This->content_listener
        ? nsIURIContentListener_SetLoadCookie(This->content_listener, aLoadCookie)
        : NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsURIContentListener_GetParentContentListener(nsIURIContentListener *iface,
        nsIURIContentListener **aParentContentListener)
{
    NSContainer *This = impl_from_nsIURIContentListener(iface);

    TRACE("(%p)->(%p)\n", This, aParentContentListener);

    if(This->content_listener)
        nsIURIContentListener_AddRef(This->content_listener);

    *aParentContentListener = This->content_listener;
    return NS_OK;
}

static nsresult NSAPI nsURIContentListener_SetParentContentListener(nsIURIContentListener *iface,
        nsIURIContentListener *aParentContentListener)
{
    NSContainer *This = impl_from_nsIURIContentListener(iface);

    TRACE("(%p)->(%p)\n", This, aParentContentListener);

    if(aParentContentListener == &This->nsIURIContentListener_iface)
        return NS_OK;

    if(This->content_listener)
        nsIURIContentListener_Release(This->content_listener);

    This->content_listener = aParentContentListener;
    if(This->content_listener)
        nsIURIContentListener_AddRef(This->content_listener);

    return NS_OK;
}

static const nsIURIContentListenerVtbl nsURIContentListenerVtbl = {
    nsURIContentListener_QueryInterface,
    nsURIContentListener_AddRef,
    nsURIContentListener_Release,
    nsURIContentListener_OnStartURIOpen,
    nsURIContentListener_DoContent,
    nsURIContentListener_IsPreferred,
    nsURIContentListener_CanHandleContent,
    nsURIContentListener_GetLoadCookie,
    nsURIContentListener_SetLoadCookie,
    nsURIContentListener_GetParentContentListener,
    nsURIContentListener_SetParentContentListener
};

/**********************************************************
 *      nsIEmbeddinSiteWindow interface
 */

static inline NSContainer *impl_from_nsIEmbeddingSiteWindow(nsIEmbeddingSiteWindow *iface)
{
    return CONTAINING_RECORD(iface, NSContainer, nsIEmbeddingSiteWindow_iface);
}

static nsresult NSAPI nsEmbeddingSiteWindow_QueryInterface(nsIEmbeddingSiteWindow *iface,
        nsIIDRef riid, void **result)
{
    NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
    return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
}

static nsrefcnt NSAPI nsEmbeddingSiteWindow_AddRef(nsIEmbeddingSiteWindow *iface)
{
    NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
    return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
}

static nsrefcnt NSAPI nsEmbeddingSiteWindow_Release(nsIEmbeddingSiteWindow *iface)
{
    NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
    return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
}

static nsresult NSAPI nsEmbeddingSiteWindow_SetDimensions(nsIEmbeddingSiteWindow *iface,
        PRUint32 flags, PRInt32 x, PRInt32 y, PRInt32 cx, PRInt32 cy)
{
    NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
    WARN("(%p)->(%08x %d %d %d %d)\n", This, flags, x, y, cx, cy);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsEmbeddingSiteWindow_GetDimensions(nsIEmbeddingSiteWindow *iface,
        PRUint32 flags, PRInt32 *x, PRInt32 *y, PRInt32 *cx, PRInt32 *cy)
{
    NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
    WARN("(%p)->(%08x %p %p %p %p)\n", This, flags, x, y, cx, cy);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsEmbeddingSiteWindow_SetFocus(nsIEmbeddingSiteWindow *iface)
{
    NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);

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

    return nsIBaseWindow_SetFocus(This->window);
}

static nsresult NSAPI nsEmbeddingSiteWindow_GetVisibility(nsIEmbeddingSiteWindow *iface,
        cpp_bool *aVisibility)
{
    NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);

    TRACE("(%p)->(%p)\n", This, aVisibility);

    *aVisibility = This->doc && This->doc->hwnd && IsWindowVisible(This->doc->hwnd);
    return NS_OK;
}

static nsresult NSAPI nsEmbeddingSiteWindow_SetVisibility(nsIEmbeddingSiteWindow *iface,
        cpp_bool aVisibility)
{
    NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);

    TRACE("(%p)->(%x)\n", This, aVisibility);

    return NS_OK;
}

static nsresult NSAPI nsEmbeddingSiteWindow_GetTitle(nsIEmbeddingSiteWindow *iface,
        PRUnichar **aTitle)
{
    NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
    WARN("(%p)->(%p)\n", This, aTitle);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsEmbeddingSiteWindow_SetTitle(nsIEmbeddingSiteWindow *iface,
        const PRUnichar *aTitle)
{
    NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);
    WARN("(%p)->(%s)\n", This, debugstr_w(aTitle));
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsEmbeddingSiteWindow_GetSiteWindow(nsIEmbeddingSiteWindow *iface,
        void **aSiteWindow)
{
    NSContainer *This = impl_from_nsIEmbeddingSiteWindow(iface);

    TRACE("(%p)->(%p)\n", This, aSiteWindow);

    *aSiteWindow = This->hwnd;
    return NS_OK;
}

static const nsIEmbeddingSiteWindowVtbl nsEmbeddingSiteWindowVtbl = {
    nsEmbeddingSiteWindow_QueryInterface,
    nsEmbeddingSiteWindow_AddRef,
    nsEmbeddingSiteWindow_Release,
    nsEmbeddingSiteWindow_SetDimensions,
    nsEmbeddingSiteWindow_GetDimensions,
    nsEmbeddingSiteWindow_SetFocus,
    nsEmbeddingSiteWindow_GetVisibility,
    nsEmbeddingSiteWindow_SetVisibility,
    nsEmbeddingSiteWindow_GetTitle,
    nsEmbeddingSiteWindow_SetTitle,
    nsEmbeddingSiteWindow_GetSiteWindow
};

static inline NSContainer *impl_from_nsITooltipListener(nsITooltipListener *iface)
{
    return CONTAINING_RECORD(iface, NSContainer, nsITooltipListener_iface);
}

static nsresult NSAPI nsTooltipListener_QueryInterface(nsITooltipListener *iface, nsIIDRef riid,
        void **result)
{
    NSContainer *This = impl_from_nsITooltipListener(iface);
    return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
}

static nsrefcnt NSAPI nsTooltipListener_AddRef(nsITooltipListener *iface)
{
    NSContainer *This = impl_from_nsITooltipListener(iface);
    return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
}

static nsrefcnt NSAPI nsTooltipListener_Release(nsITooltipListener *iface)
{
    NSContainer *This = impl_from_nsITooltipListener(iface);
    return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
}

static nsresult NSAPI nsTooltipListener_OnShowTooltip(nsITooltipListener *iface,
        PRInt32 aXCoord, PRInt32 aYCoord, const PRUnichar *aTipText)
{
    NSContainer *This = impl_from_nsITooltipListener(iface);

    if (This->doc)
        show_tooltip(This->doc, aXCoord, aYCoord, aTipText);

    return NS_OK;
}

static nsresult NSAPI nsTooltipListener_OnHideTooltip(nsITooltipListener *iface)
{
    NSContainer *This = impl_from_nsITooltipListener(iface);

    if (This->doc)
        hide_tooltip(This->doc);

    return NS_OK;
}

static const nsITooltipListenerVtbl nsTooltipListenerVtbl = {
    nsTooltipListener_QueryInterface,
    nsTooltipListener_AddRef,
    nsTooltipListener_Release,
    nsTooltipListener_OnShowTooltip,
    nsTooltipListener_OnHideTooltip
};

static inline NSContainer *impl_from_nsIInterfaceRequestor(nsIInterfaceRequestor *iface)
{
    return CONTAINING_RECORD(iface, NSContainer, nsIInterfaceRequestor_iface);
}

static nsresult NSAPI nsInterfaceRequestor_QueryInterface(nsIInterfaceRequestor *iface,
        nsIIDRef riid, void **result)
{
    NSContainer *This = impl_from_nsIInterfaceRequestor(iface);
    return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
}

static nsrefcnt NSAPI nsInterfaceRequestor_AddRef(nsIInterfaceRequestor *iface)
{
    NSContainer *This = impl_from_nsIInterfaceRequestor(iface);
    return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
}

static nsrefcnt NSAPI nsInterfaceRequestor_Release(nsIInterfaceRequestor *iface)
{
    NSContainer *This = impl_from_nsIInterfaceRequestor(iface);
    return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
}

static nsresult NSAPI nsInterfaceRequestor_GetInterface(nsIInterfaceRequestor *iface,
        nsIIDRef riid, void **result)
{
    NSContainer *This = impl_from_nsIInterfaceRequestor(iface);

    if(IsEqualGUID(&IID_nsIDOMWindow, riid)) {
        TRACE("(%p)->(IID_nsIDOMWindow %p)\n", This, result);
        return nsIWebBrowser_GetContentDOMWindow(This->webbrowser, (nsIDOMWindow**)result);
    }

    return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
}

static const nsIInterfaceRequestorVtbl nsInterfaceRequestorVtbl = {
    nsInterfaceRequestor_QueryInterface,
    nsInterfaceRequestor_AddRef,
    nsInterfaceRequestor_Release,
    nsInterfaceRequestor_GetInterface
};

static inline NSContainer *impl_from_nsISupportsWeakReference(nsISupportsWeakReference *iface)
{
    return CONTAINING_RECORD(iface, NSContainer, nsISupportsWeakReference_iface);
}

static nsresult NSAPI nsSupportsWeakReference_QueryInterface(nsISupportsWeakReference *iface,
        nsIIDRef riid, void **result)
{
    NSContainer *This = impl_from_nsISupportsWeakReference(iface);
    return nsIWebBrowserChrome_QueryInterface(&This->nsIWebBrowserChrome_iface, riid, result);
}

static nsrefcnt NSAPI nsSupportsWeakReference_AddRef(nsISupportsWeakReference *iface)
{
    NSContainer *This = impl_from_nsISupportsWeakReference(iface);
    return nsIWebBrowserChrome_AddRef(&This->nsIWebBrowserChrome_iface);
}

static nsrefcnt NSAPI nsSupportsWeakReference_Release(nsISupportsWeakReference *iface)
{
    NSContainer *This = impl_from_nsISupportsWeakReference(iface);
    return nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
}

static nsresult NSAPI nsSupportsWeakReference_GetWeakReference(nsISupportsWeakReference *iface,
        nsIWeakReference **_retval)
{
    NSContainer *This = impl_from_nsISupportsWeakReference(iface);

    TRACE("(%p)->(%p)\n", This, _retval);

    if(!This->weak_reference) {
        This->weak_reference = heap_alloc(sizeof(nsWeakReference));
        if(!This->weak_reference)
            return NS_ERROR_OUT_OF_MEMORY;

        This->weak_reference->nsIWeakReference_iface.lpVtbl = &nsWeakReferenceVtbl;
        This->weak_reference->ref = 1;
        This->weak_reference->nscontainer = This;
    }

    *_retval = &This->weak_reference->nsIWeakReference_iface;
    nsIWeakReference_AddRef(*_retval);
    return NS_OK;
}

static const nsISupportsWeakReferenceVtbl nsSupportsWeakReferenceVtbl = {
    nsSupportsWeakReference_QueryInterface,
    nsSupportsWeakReference_AddRef,
    nsSupportsWeakReference_Release,
    nsSupportsWeakReference_GetWeakReference
};

static HRESULT init_nscontainer(NSContainer *nscontainer)
{
    nsIWebBrowserSetup *wbsetup;
    nsIScrollable *scrollable;
    nsresult nsres;

    nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_WEBBROWSER_CONTRACTID,
            NULL, &IID_nsIWebBrowser, (void**)&nscontainer->webbrowser);
    if(NS_FAILED(nsres)) {
        ERR("Creating WebBrowser failed: %08x\n", nsres);
        return E_FAIL;
    }

    nsres = nsIWebBrowser_SetContainerWindow(nscontainer->webbrowser, &nscontainer->nsIWebBrowserChrome_iface);
    if(NS_FAILED(nsres)) {
        ERR("SetContainerWindow failed: %08x\n", nsres);
        return E_FAIL;
    }

    nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIBaseWindow,
            (void**)&nscontainer->window);
    if(NS_FAILED(nsres)) {
        ERR("Could not get nsIBaseWindow interface: %08x\n", nsres);
        return E_FAIL;
    }

    nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIWebBrowserSetup,
                                         (void**)&wbsetup);
    if(NS_SUCCEEDED(nsres)) {
        nsres = nsIWebBrowserSetup_SetProperty(wbsetup, SETUP_IS_CHROME_WRAPPER, FALSE);
        nsIWebBrowserSetup_Release(wbsetup);
        if(NS_FAILED(nsres)) {
            ERR("SetProperty(SETUP_IS_CHROME_WRAPPER) failed: %08x\n", nsres);
            return E_FAIL;
        }
    }else {
        ERR("Could not get nsIWebBrowserSetup interface\n");
        return E_FAIL;
    }

    nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIWebNavigation,
            (void**)&nscontainer->navigation);
    if(NS_FAILED(nsres)) {
        ERR("Could not get nsIWebNavigation interface: %08x\n", nsres);
        return E_FAIL;
    }

    nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIWebBrowserFocus,
            (void**)&nscontainer->focus);
    if(NS_FAILED(nsres)) {
        ERR("Could not get nsIWebBrowserFocus interface: %08x\n", nsres);
        return E_FAIL;
    }

    if(!nscontainer_class) {
        register_nscontainer_class();
        if(!nscontainer_class)
            return E_FAIL;
    }

    nscontainer->hwnd = CreateWindowExW(0, wszNsContainer, NULL,
            WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 100, 100,
            GetDesktopWindow(), NULL, hInst, nscontainer);
    if(!nscontainer->hwnd) {
        WARN("Could not create window\n");
        return E_FAIL;
    }

    nsres = nsIBaseWindow_InitWindow(nscontainer->window, nscontainer->hwnd, NULL, 0, 0, 100, 100);
    if(NS_SUCCEEDED(nsres)) {
        nsres = nsIBaseWindow_Create(nscontainer->window);
        if(NS_FAILED(nsres)) {
            WARN("Creating window failed: %08x\n", nsres);
            return E_FAIL;
        }

        nsIBaseWindow_SetVisibility(nscontainer->window, FALSE);
        nsIBaseWindow_SetEnabled(nscontainer->window, FALSE);
    }else {
        ERR("InitWindow failed: %08x\n", nsres);
        return E_FAIL;
    }

    nsres = nsIWebBrowser_SetParentURIContentListener(nscontainer->webbrowser,
            &nscontainer->nsIURIContentListener_iface);
    if(NS_FAILED(nsres))
        ERR("SetParentURIContentListener failed: %08x\n", nsres);

    nsres = nsIWebBrowser_QueryInterface(nscontainer->webbrowser, &IID_nsIScrollable, (void**)&scrollable);
    if(NS_SUCCEEDED(nsres)) {
        nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable,
                ScrollOrientation_Y, Scrollbar_Always);
        if(NS_FAILED(nsres))
            ERR("Could not set default Y scrollbar prefs: %08x\n", nsres);

        nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable,
                ScrollOrientation_X, Scrollbar_Auto);
        if(NS_FAILED(nsres))
            ERR("Could not set default X scrollbar prefs: %08x\n", nsres);

        nsIScrollable_Release(scrollable);
    }else {
        ERR("Could not get nsIScrollable: %08x\n", nsres);
    }

    return S_OK;
}

HRESULT create_nscontainer(HTMLDocumentObj *doc, NSContainer **_ret)
{
    NSContainer *ret;
    HRESULT hres;

    if(!load_gecko())
        return CLASS_E_CLASSNOTAVAILABLE;

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

    ret->nsIWebBrowserChrome_iface.lpVtbl = &nsWebBrowserChromeVtbl;
    ret->nsIContextMenuListener_iface.lpVtbl = &nsContextMenuListenerVtbl;
    ret->nsIURIContentListener_iface.lpVtbl = &nsURIContentListenerVtbl;
    ret->nsIEmbeddingSiteWindow_iface.lpVtbl = &nsEmbeddingSiteWindowVtbl;
    ret->nsITooltipListener_iface.lpVtbl = &nsTooltipListenerVtbl;
    ret->nsIInterfaceRequestor_iface.lpVtbl = &nsInterfaceRequestorVtbl;
    ret->nsISupportsWeakReference_iface.lpVtbl = &nsSupportsWeakReferenceVtbl;

    ret->doc = doc;
    ret->ref = 1;

    hres = init_nscontainer(ret);
    if(SUCCEEDED(hres))
        *_ret = ret;
    else
        nsIWebBrowserChrome_Release(&ret->nsIWebBrowserChrome_iface);
    return hres;
}

void NSContainer_Release(NSContainer *This)
{
    TRACE("(%p)\n", This);

    This->doc = NULL;

    ShowWindow(This->hwnd, SW_HIDE);
    SetParent(This->hwnd, NULL);

    nsIBaseWindow_SetVisibility(This->window, FALSE);
    nsIBaseWindow_Destroy(This->window);

    nsIWebBrowser_SetContainerWindow(This->webbrowser, NULL);

    nsIWebBrowser_Release(This->webbrowser);
    This->webbrowser = NULL;

    nsIWebNavigation_Release(This->navigation);
    This->navigation = NULL;

    nsIBaseWindow_Release(This->window);
    This->window = NULL;

    nsIWebBrowserFocus_Release(This->focus);
    This->focus = NULL;

    if(This->editor_controller) {
        nsIController_Release(This->editor_controller);
        This->editor_controller = NULL;
    }

    if(This->editor) {
        nsIEditor_Release(This->editor);
        This->editor = NULL;
    }

    if(This->content_listener) {
        nsIURIContentListener_Release(This->content_listener);
        This->content_listener = NULL;
    }

    if(This->hwnd) {
        DestroyWindow(This->hwnd);
        This->hwnd = NULL;
    }

    nsIWebBrowserChrome_Release(&This->nsIWebBrowserChrome_iface);
}
