/*
 * ExplorerBrowser Control implementation.
 *
 * Copyright 2010 David Hedberg
 *
 * 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 <stdarg.h>

#define COBJMACROS
#define NONAMELESSUNION

#include "winerror.h"
#include "windef.h"
#include "winbase.h"

#include "wine/list.h"
#include "wine/debug.h"
#include "debughlp.h"

#include "shell32_main.h"
#include "pidl.h"

WINE_DEFAULT_DEBUG_CHANNEL(shell);

#define SPLITTER_WIDTH 2
#define NP_MIN_WIDTH 60
#define SV_MIN_WIDTH 150

typedef struct _event_client {
    struct list entry;
    IExplorerBrowserEvents *pebe;
    DWORD cookie;
} event_client;

typedef struct _travellog_entry {
    struct list entry;
    LPITEMIDLIST pidl;
} travellog_entry;

typedef struct _ExplorerBrowserImpl {
    IExplorerBrowser  IExplorerBrowser_iface;
    IShellBrowser     IShellBrowser_iface;
    ICommDlgBrowser3  ICommDlgBrowser3_iface;
    IObjectWithSite   IObjectWithSite_iface;
    INameSpaceTreeControlEvents INameSpaceTreeControlEvents_iface;
    IInputObject      IInputObject_iface;
    LONG ref;
    BOOL destroyed;

    HWND hwnd_main;
    HWND hwnd_sv;

    RECT splitter_rc;
    struct {
        INameSpaceTreeControl2 *pnstc2;
        HWND hwnd_splitter, hwnd_nstc;
        DWORD nstc_cookie;
        UINT width;
        BOOL show;
        RECT rc;
    } navpane;

    EXPLORER_BROWSER_OPTIONS eb_options;
    FOLDERSETTINGS fs;

    struct list event_clients;
    DWORD events_next_cookie;
    struct list travellog;
    travellog_entry *travellog_cursor;
    int travellog_count;

    IShellView *psv;
    RECT sv_rc;
    LPITEMIDLIST current_pidl;

    IUnknown *punk_site;
    ICommDlgBrowser *pcdb_site;
    ICommDlgBrowser2 *pcdb2_site;
    ICommDlgBrowser3 *pcdb3_site;
    IExplorerPaneVisibility *pepv_site;
} ExplorerBrowserImpl;

static void initialize_navpane(ExplorerBrowserImpl *This, HWND hwnd_parent, RECT *rc);

/**************************************************************************
 * Event functions.
 */
static void events_unadvise_all(ExplorerBrowserImpl *This)
{
    event_client *client, *curs;
    TRACE("%p\n", This);

    LIST_FOR_EACH_ENTRY_SAFE(client, curs, &This->event_clients, event_client, entry)
    {
        TRACE("Removing %p\n", client);
        list_remove(&client->entry);
        IExplorerBrowserEvents_Release(client->pebe);
        HeapFree(GetProcessHeap(), 0, client);
    }
}

static HRESULT events_NavigationPending(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
{
    event_client *cursor;
    HRESULT hres = S_OK;

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

    LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
    {
        TRACE("Notifying %p\n", cursor);
        hres = IExplorerBrowserEvents_OnNavigationPending(cursor->pebe, pidl);

        /* If this failed for any reason, the browsing is supposed to be aborted. */
        if(FAILED(hres))
            break;
    }

    return hres;
}

static void events_NavigationComplete(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
{
    event_client *cursor;

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

    LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
    {
        TRACE("Notifying %p\n", cursor);
        IExplorerBrowserEvents_OnNavigationComplete(cursor->pebe, pidl);
    }
}

static void events_NavigationFailed(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
{
    event_client *cursor;

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

    LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
    {
        TRACE("Notifying %p\n", cursor);
        IExplorerBrowserEvents_OnNavigationFailed(cursor->pebe, pidl);
    }
}

static void events_ViewCreated(ExplorerBrowserImpl *This, IShellView *psv)
{
    event_client *cursor;

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

    LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
    {
        TRACE("Notifying %p\n", cursor);
        IExplorerBrowserEvents_OnViewCreated(cursor->pebe, psv);
    }
}

/**************************************************************************
 * Travellog functions.
 */
static void travellog_remove_entry(ExplorerBrowserImpl *This, travellog_entry *entry)
{
    TRACE("Removing %p\n", entry);

    list_remove(&entry->entry);
    ILFree(entry->pidl);
    HeapFree(GetProcessHeap(), 0, entry);
    This->travellog_count--;
}

static void travellog_remove_all_entries(ExplorerBrowserImpl *This)
{
    travellog_entry *cursor, *cursor2;
    TRACE("%p\n", This);

    LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
        travellog_remove_entry(This, cursor);

    This->travellog_cursor = NULL;
}

static void travellog_add_entry(ExplorerBrowserImpl *This, LPITEMIDLIST pidl)
{
    travellog_entry *new, *cursor, *cursor2;
    TRACE("%p (old count %d)\n", pidl, This->travellog_count);

    /* Replace the old tail, if any, with the new entry */
    if(This->travellog_cursor)
    {
        LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, &This->travellog, travellog_entry, entry)
        {
            if(cursor == This->travellog_cursor)
                break;
            travellog_remove_entry(This, cursor);
        }
    }

    /* Create and add the new entry */
    new = HeapAlloc(GetProcessHeap(), 0, sizeof(travellog_entry));
    new->pidl = ILClone(pidl);
    list_add_tail(&This->travellog, &new->entry);
    This->travellog_cursor = new;
    This->travellog_count++;

    /* Remove the first few entries if the size limit is reached. */
    if(This->travellog_count > 200)
    {
        UINT i = 0;
        LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
        {
            if(i++ > 10)
                break;
            travellog_remove_entry(This, cursor);
        }
    }
}

static LPCITEMIDLIST travellog_go_back(ExplorerBrowserImpl *This)
{
    travellog_entry *prev;
    TRACE("%p, %p\n", This, This->travellog_cursor);

    if(!This->travellog_cursor)
        return NULL;

    prev = LIST_ENTRY(list_prev(&This->travellog, &This->travellog_cursor->entry),
                      travellog_entry, entry);
    if(!prev)
        return NULL;

    This->travellog_cursor = prev;
    return prev->pidl;
}

static LPCITEMIDLIST travellog_go_forward(ExplorerBrowserImpl *This)
{
    travellog_entry *next;
    TRACE("%p, %p\n", This, This->travellog_cursor);

    if(!This->travellog_cursor)
        return NULL;

    next = LIST_ENTRY(list_next(&This->travellog, &This->travellog_cursor->entry),
                      travellog_entry, entry);
    if(!next)
        return NULL;

    This->travellog_cursor = next;
    return next->pidl;
}

/**************************************************************************
 * Helper functions
 */
static void update_layout(ExplorerBrowserImpl *This)
{
    RECT rc;
    INT navpane_width_actual;
    INT shellview_width_actual;
    TRACE("%p (navpane: %d, EBO_SHOWFRAMES: %d)\n",
          This, This->navpane.show, This->eb_options & EBO_SHOWFRAMES);

    GetClientRect(This->hwnd_main, &rc);

    if((This->eb_options & EBO_SHOWFRAMES) && This->navpane.show)
        navpane_width_actual = This->navpane.width;
    else
        navpane_width_actual = 0;

    shellview_width_actual = rc.right - navpane_width_actual;
    if(shellview_width_actual < SV_MIN_WIDTH && navpane_width_actual)
    {
        INT missing_width = SV_MIN_WIDTH - shellview_width_actual;
        if(missing_width < (navpane_width_actual - NP_MIN_WIDTH))
        {
            /* Shrink the navpane */
            navpane_width_actual -= missing_width;
            shellview_width_actual += missing_width;
        }
        else
        {
            /* Hide the navpane */
            shellview_width_actual += navpane_width_actual;
            navpane_width_actual = 0;
        }
    }

    /**************************************************************
     *  Calculate rectangles for the panes. All rectangles contain
     *  the position of the panes relative to hwnd_main.
     */

    if(navpane_width_actual)
    {
        This->navpane.rc.left = This->navpane.rc.top = 0;
        This->navpane.rc.right = navpane_width_actual;
        This->navpane.rc.bottom = rc.bottom;

        if(!This->navpane.hwnd_splitter)
            initialize_navpane(This, This->hwnd_main, &This->navpane.rc);
    }
    else
        ZeroMemory(&This->navpane.rc, sizeof(RECT));

    This->sv_rc.left   = navpane_width_actual;
    This->sv_rc.top    = 0;
    This->sv_rc.right  = This->sv_rc.left + shellview_width_actual;
    This->sv_rc.bottom = rc.bottom;
}

static void size_panes(ExplorerBrowserImpl *This)
{
    MoveWindow(This->navpane.hwnd_splitter,
               This->navpane.rc.right - SPLITTER_WIDTH, This->navpane.rc.top,
               SPLITTER_WIDTH, This->navpane.rc.bottom - This->navpane.rc.top,
               TRUE);

    MoveWindow(This->hwnd_sv,
               This->sv_rc.left, This->sv_rc.top,
               This->sv_rc.right - This->sv_rc.left, This->sv_rc.bottom - This->sv_rc.top,
               TRUE);
}

static HRESULT change_viewmode(ExplorerBrowserImpl *This, UINT viewmode)
{
    IFolderView *pfv;
    HRESULT hr;

    if(!This->psv)
        return E_FAIL;

    hr = IShellView_QueryInterface(This->psv, &IID_IFolderView, (void*)&pfv);
    if(SUCCEEDED(hr))
    {
        hr = IFolderView_SetCurrentViewMode(pfv, This->fs.ViewMode);
        IFolderView_Release(pfv);
    }

    return hr;
}

static HRESULT create_new_shellview(ExplorerBrowserImpl *This, IShellItem *psi)
{
    IShellBrowser *psb = &This->IShellBrowser_iface;
    IShellFolder *psf;
    IShellView *psv;
    HWND hwnd_new;
    HRESULT hr;

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

    hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFObject, &IID_IShellFolder, (void**)&psf);
    if(SUCCEEDED(hr))
    {
        hr = IShellFolder_CreateViewObject(psf, This->hwnd_main, &IID_IShellView, (void**)&psv);
        if(SUCCEEDED(hr))
        {
            if(This->hwnd_sv)
            {
                IShellView_DestroyViewWindow(This->psv);
                This->hwnd_sv = NULL;
            }

            hr = IShellView_CreateViewWindow(psv, This->psv, &This->fs, psb, &This->sv_rc, &hwnd_new);
            if(SUCCEEDED(hr))
            {
                /* Replace the old shellview */
                if(This->psv) IShellView_Release(This->psv);

                This->psv = psv;
                This->hwnd_sv = hwnd_new;
                events_ViewCreated(This, psv);
            }
            else
            {
                ERR("CreateViewWindow failed (0x%x)\n", hr);
                IShellView_Release(psv);
            }
        }
        else
            ERR("CreateViewObject failed (0x%x)\n", hr);

        IShellFolder_Release(psf);
    }
    else
        ERR("SI::BindToHandler failed (0x%x)\n", hr);

    return hr;
}

static void get_interfaces_from_site(ExplorerBrowserImpl *This)
{
    IServiceProvider *psp;
    HRESULT hr;

    /* Calling this with This->punk_site set to NULL should properly
     * release any previously fetched interfaces.
     */

    if(This->pcdb_site)
    {
        ICommDlgBrowser_Release(This->pcdb_site);
        if(This->pcdb2_site) ICommDlgBrowser2_Release(This->pcdb2_site);
        if(This->pcdb3_site) ICommDlgBrowser3_Release(This->pcdb3_site);

        This->pcdb_site = NULL;
        This->pcdb2_site = NULL;
        This->pcdb3_site = NULL;
    }

    if(This->pepv_site)
    {
        IExplorerPaneVisibility_Release(This->pepv_site);
        This->pepv_site = NULL;
    }

    if(!This->punk_site)
        return;

    hr = IUnknown_QueryInterface(This->punk_site, &IID_IServiceProvider, (void**)&psp);
    if(FAILED(hr))
    {
        ERR("Failed to get IServiceProvider from site.\n");
        return;
    }

    /* ICommDlgBrowser */
    IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser,
                                  (void**)&This->pcdb_site);
    IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser2,
                                  (void**)&This->pcdb2_site);
    IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser3,
                                  (void**)&This->pcdb3_site);

    /* IExplorerPaneVisibility */
    IServiceProvider_QueryService(psp, &SID_ExplorerPaneVisibility, &IID_IExplorerPaneVisibility,
                                  (void**)&This->pepv_site);

    IServiceProvider_Release(psp);
}

/**************************************************************************
 * General pane functionality.
 */
static void update_panestate(ExplorerBrowserImpl *This)
{
    EXPLORERPANESTATE eps = EPS_DONTCARE;
    BOOL show_navpane;
    TRACE("%p\n", This);

    if(!This->pepv_site) return;

    IExplorerPaneVisibility_GetPaneState(This->pepv_site, (REFEXPLORERPANE) &EP_NavPane, &eps);
    if( !(eps & EPS_DEFAULT_OFF) )
        show_navpane = TRUE;
    else
        show_navpane = FALSE;

    if(This->navpane.show != show_navpane)
    {
        update_layout(This);
        size_panes(This);
    }

    This->navpane.show = show_navpane;
}

static void splitter_draw(HWND hwnd, RECT *rc)
{
    HDC hdc = GetDC(hwnd);
    InvertRect(hdc, rc);
    ReleaseDC(hwnd, hdc);
}

/**************************************************************************
 * The Navigation Pane.
 */
static LRESULT navpane_splitter_beginresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
{
    TRACE("\n");

    SetCapture(hwnd);

    CopyRect(&This->splitter_rc, &This->navpane.rc);
    This->splitter_rc.left = This->splitter_rc.right - SPLITTER_WIDTH;

    splitter_draw(GetParent(hwnd), &This->splitter_rc);

    return TRUE;
}

static LRESULT navpane_splitter_resizing(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
{
    int new_width, dx;
    RECT rc;

    if(GetCapture() != hwnd) return FALSE;

    dx = (SHORT)LOWORD(lParam);
    TRACE("%d.\n", dx);

    CopyRect(&rc, &This->navpane.rc);

    new_width = This->navpane.width + dx;
    if(new_width > NP_MIN_WIDTH && This->sv_rc.right - new_width > SV_MIN_WIDTH)
    {
        rc.right = new_width;
        rc.left = rc.right - SPLITTER_WIDTH;
        splitter_draw(GetParent(hwnd), &This->splitter_rc);
        splitter_draw(GetParent(hwnd), &rc);
        CopyRect(&This->splitter_rc, &rc);
    }

    return TRUE;
}

static LRESULT navpane_splitter_endresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
{
    int new_width, dx;

    if(GetCapture() != hwnd) return FALSE;

    dx = (SHORT)LOWORD(lParam);
    TRACE("%d.\n", dx);

    splitter_draw(GetParent(hwnd), &This->splitter_rc);

    new_width = This->navpane.width + dx;
    if(new_width < NP_MIN_WIDTH)
        new_width = NP_MIN_WIDTH;
    else if(This->sv_rc.right - new_width < SV_MIN_WIDTH)
        new_width = This->sv_rc.right - SV_MIN_WIDTH;

    This->navpane.width = new_width;

    update_layout(This);
    size_panes(This);

    ReleaseCapture();

    return TRUE;
}

static LRESULT navpane_on_wm_create(HWND hwnd, CREATESTRUCTW *crs)
{
    ExplorerBrowserImpl *This = crs->lpCreateParams;
    INameSpaceTreeControl2 *pnstc2;
    DWORD style;
    HRESULT hr;

    TRACE("%p\n", This);
    SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
    This->navpane.hwnd_splitter = hwnd;

    hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER,
                          &IID_INameSpaceTreeControl2, (void**)&pnstc2);

    if(SUCCEEDED(hr))
    {
        style = NSTCS_HASEXPANDOS | NSTCS_ROOTHASEXPANDO | NSTCS_SHOWSELECTIONALWAYS;
        hr = INameSpaceTreeControl2_Initialize(pnstc2, GetParent(hwnd), NULL, style);
        if(SUCCEEDED(hr))
        {
            INameSpaceTreeControlEvents *pnstce;
            IShellFolder *psfdesktop;
            IShellItem *psi;
            IOleWindow *pow;
            LPITEMIDLIST pidl;
            DWORD cookie, style2 = NSTCS2_DISPLAYPADDING;

            hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFF, style2);
            if(FAILED(hr))
                ERR("SetControlStyle2 failed (0x%08x)\n", hr);

            hr = INameSpaceTreeControl2_QueryInterface(pnstc2, &IID_IOleWindow, (void**)&pow);
            if(SUCCEEDED(hr))
            {
                IOleWindow_GetWindow(pow, &This->navpane.hwnd_nstc);
                IOleWindow_Release(pow);
            }
            else
                ERR("QueryInterface(IOleWindow) failed (0x%08x)\n", hr);

            pnstce = &This->INameSpaceTreeControlEvents_iface;
            hr = INameSpaceTreeControl2_TreeAdvise(pnstc2, (IUnknown*)pnstce, &cookie);
            if(FAILED(hr))
                ERR("TreeAdvise failed. (0x%08x).\n", hr);

            /*
             * Add the default roots
             */

            /* TODO: This should be FOLDERID_Links */
            hr = SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
            if(SUCCEEDED(hr))
            {
                hr = SHCreateShellItem(NULL, NULL, pidl, &psi);
                if(SUCCEEDED(hr))
                {
                    hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_NONFOLDERS, NSTCRS_VISIBLE, NULL);
                    IShellItem_Release(psi);
                }
                ILFree(pidl);
            }

            SHGetDesktopFolder(&psfdesktop);
            hr = SHGetItemFromObject((IUnknown*)psfdesktop, &IID_IShellItem, (void**)&psi);
            IShellFolder_Release(psfdesktop);
            if(SUCCEEDED(hr))
            {
                hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_FOLDERS, NSTCRS_EXPANDED, NULL);
                IShellItem_Release(psi);
            }

            /* TODO:
             * We should advertise IID_INameSpaceTreeControl to the site of the
             * host through its IProfferService interface, if any.
             */

            This->navpane.pnstc2 = pnstc2;
            This->navpane.nstc_cookie = cookie;

            return TRUE;
        }
    }

    This->navpane.pnstc2 = NULL;
    ERR("Failed (0x%08x)\n", hr);

    return FALSE;
}

static LRESULT navpane_on_wm_size_move(ExplorerBrowserImpl *This)
{
    UINT height, width;
    TRACE("%p\n", This);

    width = This->navpane.rc.right - This->navpane.rc.left - SPLITTER_WIDTH;
    height = This->navpane.rc.bottom - This->navpane.rc.top;

    MoveWindow(This->navpane.hwnd_nstc,
               This->navpane.rc.left, This->navpane.rc.top,
               width, height,
               TRUE);

    return FALSE;
}

static LRESULT navpane_on_wm_destroy(ExplorerBrowserImpl *This)
{
    INameSpaceTreeControl2_TreeUnadvise(This->navpane.pnstc2, This->navpane.nstc_cookie);
    INameSpaceTreeControl2_Release(This->navpane.pnstc2);
    This->navpane.pnstc2 = NULL;
    return TRUE;
}

static LRESULT CALLBACK navpane_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
    ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);

    switch(uMessage) {
    case WM_CREATE:           return navpane_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
    case WM_MOVE:             /* Fall through */
    case WM_SIZE:             return navpane_on_wm_size_move(This);
    case WM_DESTROY:          return navpane_on_wm_destroy(This);
    case WM_LBUTTONDOWN:      return navpane_splitter_beginresize(This, hWnd, lParam);
    case WM_MOUSEMOVE:        return navpane_splitter_resizing(This, hWnd, lParam);
    case WM_LBUTTONUP:        return navpane_splitter_endresize(This, hWnd, lParam);
    default:
        return DefWindowProcW(hWnd, uMessage, wParam, lParam);
    }
    return 0;
}

static void initialize_navpane(ExplorerBrowserImpl *This, HWND hwnd_parent, RECT *rc)
{
    WNDCLASSW wc;
    HWND splitter;
    static const WCHAR navpane_classname[] = {'e','b','_','n','a','v','p','a','n','e',0};

    if( !GetClassInfoW(shell32_hInstance, navpane_classname, &wc) )
    {
        wc.style            = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc      = navpane_wndproc;
        wc.cbClsExtra       = 0;
        wc.cbWndExtra       = 0;
        wc.hInstance        = shell32_hInstance;
        wc.hIcon            = 0;
        wc.hCursor          = LoadCursorW(0, (LPWSTR)IDC_SIZEWE);
        wc.hbrBackground    = (HBRUSH)(COLOR_HIGHLIGHT + 1);
        wc.lpszMenuName     = NULL;
        wc.lpszClassName    = navpane_classname;

        if (!RegisterClassW(&wc)) return;
    }

    splitter = CreateWindowExW(0, navpane_classname, NULL,
                               WS_CHILD | WS_TABSTOP | WS_VISIBLE,
                               rc->right - SPLITTER_WIDTH, rc->top,
                               SPLITTER_WIDTH, rc->bottom - rc->top,
                               hwnd_parent, 0, shell32_hInstance, This);
    if(!splitter)
        ERR("Failed to create navpane : %d.\n", GetLastError());
}

/**************************************************************************
 * Main window related functions.
 */
static LRESULT main_on_wm_create(HWND hWnd, CREATESTRUCTW *crs)
{
    ExplorerBrowserImpl *This = crs->lpCreateParams;
    TRACE("%p\n", This);

    SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LPARAM)This);
    This->hwnd_main = hWnd;

    return TRUE;
}

static LRESULT main_on_wm_size(ExplorerBrowserImpl *This)
{
    update_layout(This);
    size_panes(This);

    return TRUE;
}

static LRESULT main_on_cwm_getishellbrowser(ExplorerBrowserImpl *This)
{
    return (LRESULT)&This->IShellBrowser_iface;
}

static LRESULT CALLBACK main_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
    ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);

    switch(uMessage)
    {
    case WM_CREATE:           return main_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
    case WM_SIZE:             return main_on_wm_size(This);
    case CWM_GETISHELLBROWSER: return main_on_cwm_getishellbrowser(This);
    default:                  return DefWindowProcW(hWnd, uMessage, wParam, lParam);
    }

    return 0;
}

/**************************************************************************
 * IExplorerBrowser Implementation
 */

static inline ExplorerBrowserImpl *impl_from_IExplorerBrowser(IExplorerBrowser *iface)
{
    return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IExplorerBrowser_iface);
}

static HRESULT WINAPI IExplorerBrowser_fnQueryInterface(IExplorerBrowser *iface,
                                                        REFIID riid, void **ppvObject)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);

    *ppvObject = NULL;
    if(IsEqualIID(riid, &IID_IExplorerBrowser) ||
       IsEqualIID(riid, &IID_IUnknown))
    {
        *ppvObject = &This->IExplorerBrowser_iface;
    }
    else if(IsEqualIID(riid, &IID_IShellBrowser))
    {
        *ppvObject = &This->IShellBrowser_iface;
    }
    else if(IsEqualIID(riid, &IID_ICommDlgBrowser) ||
            IsEqualIID(riid, &IID_ICommDlgBrowser2) ||
            IsEqualIID(riid, &IID_ICommDlgBrowser3))
    {
        *ppvObject = &This->ICommDlgBrowser3_iface;
    }
    else if(IsEqualIID(riid, &IID_IObjectWithSite))
    {
        *ppvObject = &This->IObjectWithSite_iface;
    }
    else if(IsEqualIID(riid, &IID_IInputObject))
    {
        *ppvObject = &This->IInputObject_iface;
    }

    if(*ppvObject)
    {
        IUnknown_AddRef((IUnknown*)*ppvObject);
        return S_OK;
    }

    return E_NOINTERFACE;
}

static ULONG WINAPI IExplorerBrowser_fnAddRef(IExplorerBrowser *iface)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    LONG ref = InterlockedIncrement(&This->ref);
    TRACE("%p - ref %d\n", This, ref);

    return ref;
}

static ULONG WINAPI IExplorerBrowser_fnRelease(IExplorerBrowser *iface)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    LONG ref = InterlockedDecrement(&This->ref);
    TRACE("%p - ref %d\n", This, ref);

    if(!ref)
    {
        TRACE("Freeing.\n");

        if(!This->destroyed)
            IExplorerBrowser_Destroy(iface);

        IObjectWithSite_SetSite(&This->IObjectWithSite_iface, NULL);

        HeapFree(GetProcessHeap(), 0, This);
        return 0;
    }

    return ref;
}

static HRESULT WINAPI IExplorerBrowser_fnInitialize(IExplorerBrowser *iface,
                                                    HWND hwndParent, const RECT *prc,
                                                    const FOLDERSETTINGS *pfs)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    WNDCLASSW wc;
    LONG style;
    static const WCHAR EB_CLASS_NAME[] =
        {'E','x','p','l','o','r','e','r','B','r','o','w','s','e','r','C','o','n','t','r','o','l',0};

    TRACE("%p (%p, %p, %p)\n", This, hwndParent, prc, pfs);

    if(This->hwnd_main)
        return E_UNEXPECTED;

    if(!hwndParent)
        return E_INVALIDARG;

    if( !GetClassInfoW(shell32_hInstance, EB_CLASS_NAME, &wc) )
    {
        wc.style            = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc      = main_wndproc;
        wc.cbClsExtra       = 0;
        wc.cbWndExtra       = 0;
        wc.hInstance        = shell32_hInstance;
        wc.hIcon            = 0;
        wc.hCursor          = LoadCursorW(0, (LPWSTR)IDC_ARROW);
        wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW + 1);
        wc.lpszMenuName     = NULL;
        wc.lpszClassName    = EB_CLASS_NAME;

        if (!RegisterClassW(&wc)) return E_FAIL;
    }

    style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER;
    This->hwnd_main = CreateWindowExW(WS_EX_CONTROLPARENT, EB_CLASS_NAME, NULL, style,
                                      prc->left, prc->top,
                                      prc->right - prc->left, prc->bottom - prc->top,
                                      hwndParent, 0, shell32_hInstance, This);

    if(!This->hwnd_main)
    {
        ERR("Failed to create the window.\n");
        return E_FAIL;
    }

    This->fs.ViewMode = pfs ? pfs->ViewMode : FVM_DETAILS;
    This->fs.fFlags = pfs ? (pfs->fFlags | FWF_NOCLIENTEDGE) : FWF_NOCLIENTEDGE;

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnDestroy(IExplorerBrowser *iface)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    TRACE("%p\n", This);

    if(This->psv)
    {
        IShellView_DestroyViewWindow(This->psv);
        IShellView_Release(This->psv);
        This->psv = NULL;
        This->hwnd_sv = NULL;
    }

    events_unadvise_all(This);
    travellog_remove_all_entries(This);

    ILFree(This->current_pidl);
    This->current_pidl = NULL;

    DestroyWindow(This->hwnd_main);
    This->destroyed = TRUE;

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnSetRect(IExplorerBrowser *iface,
                                                 HDWP *phdwp, RECT rcBrowser)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    TRACE("%p (%p, %s)\n", This, phdwp, wine_dbgstr_rect(&rcBrowser));

    if(phdwp && *phdwp)
    {
        *phdwp = DeferWindowPos(*phdwp, This->hwnd_main, NULL, rcBrowser.left, rcBrowser.top,
                                rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top,
                                SWP_NOZORDER | SWP_NOACTIVATE);
        if(!*phdwp)
            return E_FAIL;
    }
    else
    {
        MoveWindow(This->hwnd_main, rcBrowser.left, rcBrowser.top,
                   rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top, TRUE);
    }

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnSetPropertyBag(IExplorerBrowser *iface,
                                                        LPCWSTR pszPropertyBag)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    FIXME("stub, %p (%s)\n", This, debugstr_w(pszPropertyBag));

    if(!pszPropertyBag)
        return E_INVALIDARG;

    /* FIXME: This method is currently useless as we don't save any
     * settings anywhere, but at least one application breaks if we
     * return E_NOTIMPL.
     */

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnSetEmptyText(IExplorerBrowser *iface,
                                                      LPCWSTR pszEmptyText)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    FIXME("stub, %p (%s)\n", This, debugstr_w(pszEmptyText));

    return E_NOTIMPL;
}

static HRESULT WINAPI IExplorerBrowser_fnSetFolderSettings(IExplorerBrowser *iface,
                                                           const FOLDERSETTINGS *pfs)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    TRACE("%p (%p)\n", This, pfs);

    if(!pfs)
        return E_INVALIDARG;

    This->fs.ViewMode = pfs->ViewMode;
    This->fs.fFlags = pfs->fFlags | FWF_NOCLIENTEDGE;

    /* Change the settings of the current view, if any. */
    return change_viewmode(This, This->fs.ViewMode);
}

static HRESULT WINAPI IExplorerBrowser_fnAdvise(IExplorerBrowser *iface,
                                                IExplorerBrowserEvents *psbe,
                                                DWORD *pdwCookie)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    event_client *client;
    TRACE("%p (%p, %p)\n", This, psbe, pdwCookie);

    client = HeapAlloc(GetProcessHeap(), 0, sizeof(event_client));
    client->pebe = psbe;
    client->cookie = ++This->events_next_cookie;

    IExplorerBrowserEvents_AddRef(psbe);
    *pdwCookie = client->cookie;

    list_add_tail(&This->event_clients, &client->entry);

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnUnadvise(IExplorerBrowser *iface,
                                                  DWORD dwCookie)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    event_client *client;
    TRACE("%p (0x%x)\n", This, dwCookie);

    LIST_FOR_EACH_ENTRY(client, &This->event_clients, event_client, entry)
    {
        if(client->cookie == dwCookie)
        {
            list_remove(&client->entry);
            IExplorerBrowserEvents_Release(client->pebe);
            HeapFree(GetProcessHeap(), 0, client);
            return S_OK;
        }
    }

    return E_INVALIDARG;
}

static HRESULT WINAPI IExplorerBrowser_fnSetOptions(IExplorerBrowser *iface,
                                                    EXPLORER_BROWSER_OPTIONS dwFlag)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    static const EXPLORER_BROWSER_OPTIONS unsupported_options =
        EBO_ALWAYSNAVIGATE | EBO_NOWRAPPERWINDOW | EBO_HTMLSHAREPOINTVIEW;

    TRACE("%p (0x%x)\n", This, dwFlag);

    if(dwFlag & unsupported_options)
        FIXME("Flags 0x%08x contains unsupported options.\n", dwFlag);

    This->eb_options = dwFlag;

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnGetOptions(IExplorerBrowser *iface,
                                                    EXPLORER_BROWSER_OPTIONS *pdwFlag)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    TRACE("%p (%p)\n", This, pdwFlag);

    *pdwFlag = This->eb_options;

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
                                                        PCUIDLIST_RELATIVE pidl,
                                                        UINT uFlags)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    LPITEMIDLIST absolute_pidl = NULL;
    HRESULT hr;
    static const UINT unsupported_browse_flags =
        SBSP_NEWBROWSER | EBF_SELECTFROMDATAOBJECT | EBF_NODROPTARGET;
    TRACE("%p (%p, 0x%x)\n", This, pidl, uFlags);

    if(!This->hwnd_main)
        return E_FAIL;

    if(This->destroyed)
        return HRESULT_FROM_WIN32(ERROR_BUSY);

    if(This->current_pidl && (This->eb_options & EBO_NAVIGATEONCE))
        return E_FAIL;

    if(uFlags & SBSP_EXPLOREMODE)
        return E_INVALIDARG;

    if(uFlags & unsupported_browse_flags)
        FIXME("Argument 0x%x contains unsupported flags.\n", uFlags);

    if(uFlags & SBSP_NAVIGATEBACK)
    {
        TRACE("SBSP_NAVIGATEBACK\n");
        absolute_pidl = ILClone(travellog_go_back(This));
        if(!absolute_pidl && !This->current_pidl)
            return E_FAIL;
        else if(!absolute_pidl)
            return S_OK;

    }
    else if(uFlags & SBSP_NAVIGATEFORWARD)
    {
        TRACE("SBSP_NAVIGATEFORWARD\n");
        absolute_pidl = ILClone(travellog_go_forward(This));
        if(!absolute_pidl && !This->current_pidl)
            return E_FAIL;
        else if(!absolute_pidl)
            return S_OK;

    }
    else if(uFlags & SBSP_PARENT)
    {
        if(This->current_pidl)
        {
            if(_ILIsPidlSimple(This->current_pidl))
            {
                absolute_pidl = _ILCreateDesktop();
            }
            else
            {
                absolute_pidl = ILClone(This->current_pidl);
                ILRemoveLastID(absolute_pidl);
            }
        }
        if(!absolute_pidl)
        {
            ERR("Failed to get parent pidl.\n");
            return E_FAIL;
        }

    }
    else if(uFlags & SBSP_RELATIVE)
    {
        /* SBSP_RELATIVE has precedence over SBSP_ABSOLUTE */
        TRACE("SBSP_RELATIVE\n");
        if(This->current_pidl)
        {
            absolute_pidl = ILCombine(This->current_pidl, pidl);
        }
        if(!absolute_pidl)
        {
            ERR("Failed to get absolute pidl.\n");
            return E_FAIL;
        }
    }
    else
    {
        TRACE("SBSP_ABSOLUTE\n");
        absolute_pidl = ILClone(pidl);
        if(!absolute_pidl && !This->current_pidl)
            return E_INVALIDARG;
        else if(!absolute_pidl)
            return S_OK;
    }

    /* TODO: Asynchronous browsing. Return S_OK here and finish in
     * another thread. */

    hr = events_NavigationPending(This, absolute_pidl);
    if(FAILED(hr))
    {
        TRACE("Browsing aborted.\n");
        ILFree(absolute_pidl);
        return E_FAIL;
    }

    get_interfaces_from_site(This);
    update_panestate(This);

    /* Only browse if the new pidl differs from the old */
    if(!ILIsEqual(This->current_pidl, absolute_pidl))
    {
        IShellItem *psi;
        hr = SHCreateItemFromIDList(absolute_pidl, &IID_IShellItem, (void**)&psi);
        if(SUCCEEDED(hr))
        {
            hr = create_new_shellview(This, psi);
            if(FAILED(hr))
            {
                events_NavigationFailed(This, absolute_pidl);
                ILFree(absolute_pidl);
                IShellItem_Release(psi);
                return E_FAIL;
            }

            /* Add to travellog */
            if( !(This->eb_options & EBO_NOTRAVELLOG) &&
                !(uFlags & (SBSP_NAVIGATEFORWARD|SBSP_NAVIGATEBACK)) )
            {
                travellog_add_entry(This, absolute_pidl);
            }

            IShellItem_Release(psi);
        }
    }

    events_NavigationComplete(This, absolute_pidl);
    ILFree(This->current_pidl);
    This->current_pidl = absolute_pidl;

    /* Expand the NameSpaceTree to the current location. */
    if(This->navpane.show && This->navpane.pnstc2)
    {
        IShellItem *psi;
        hr = SHCreateItemFromIDList(This->current_pidl, &IID_IShellItem, (void**)&psi);
        if(SUCCEEDED(hr))
        {
            INameSpaceTreeControl2_EnsureItemVisible(This->navpane.pnstc2, psi);
            IShellItem_Release(psi);
        }
    }

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnBrowseToObject(IExplorerBrowser *iface,
                                                        IUnknown *punk, UINT uFlags)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    LPITEMIDLIST pidl;
    HRESULT hr;
    TRACE("%p (%p, 0x%x)\n", This, punk, uFlags);

    if(!punk)
        return IExplorerBrowser_BrowseToIDList(iface, NULL, uFlags);

    hr = SHGetIDListFromObject(punk, &pidl);
    if(SUCCEEDED(hr))
    {
        hr = IExplorerBrowser_BrowseToIDList(iface, pidl, uFlags);
        ILFree(pidl);
    }

    return hr;
}

static HRESULT WINAPI IExplorerBrowser_fnFillFromObject(IExplorerBrowser *iface,
                                                        IUnknown *punk,
                                                        EXPLORER_BROWSER_FILL_FLAGS dwFlags)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    FIXME("stub, %p (%p, 0x%x)\n", This, punk, dwFlags);

    return E_NOTIMPL;
}

static HRESULT WINAPI IExplorerBrowser_fnRemoveAll(IExplorerBrowser *iface)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    FIXME("stub, %p\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI IExplorerBrowser_fnGetCurrentView(IExplorerBrowser *iface,
                                                        REFIID riid, void **ppv)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppv);

    if(!This->psv)
        return E_FAIL;

    return IShellView_QueryInterface(This->psv, riid, ppv);
}

static const IExplorerBrowserVtbl vt_IExplorerBrowser =
{
    IExplorerBrowser_fnQueryInterface,
    IExplorerBrowser_fnAddRef,
    IExplorerBrowser_fnRelease,
    IExplorerBrowser_fnInitialize,
    IExplorerBrowser_fnDestroy,
    IExplorerBrowser_fnSetRect,
    IExplorerBrowser_fnSetPropertyBag,
    IExplorerBrowser_fnSetEmptyText,
    IExplorerBrowser_fnSetFolderSettings,
    IExplorerBrowser_fnAdvise,
    IExplorerBrowser_fnUnadvise,
    IExplorerBrowser_fnSetOptions,
    IExplorerBrowser_fnGetOptions,
    IExplorerBrowser_fnBrowseToIDList,
    IExplorerBrowser_fnBrowseToObject,
    IExplorerBrowser_fnFillFromObject,
    IExplorerBrowser_fnRemoveAll,
    IExplorerBrowser_fnGetCurrentView
};

/**************************************************************************
 * IShellBrowser Implementation
 */

static inline ExplorerBrowserImpl *impl_from_IShellBrowser(IShellBrowser *iface)
{
    return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IShellBrowser_iface);
}

static HRESULT WINAPI IShellBrowser_fnQueryInterface(IShellBrowser *iface,
                                                     REFIID riid, void **ppvObject)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p\n", This);
    return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
}

static ULONG WINAPI IShellBrowser_fnAddRef(IShellBrowser *iface)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p\n", This);
    return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
}

static ULONG WINAPI IShellBrowser_fnRelease(IShellBrowser *iface)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p\n", This);
    return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
}

static HRESULT WINAPI IShellBrowser_fnGetWindow(IShellBrowser *iface, HWND *phwnd)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p (%p)\n", This, phwnd);

    if(!This->hwnd_main)
        return E_FAIL;

    *phwnd = This->hwnd_main;
    return S_OK;
}

static HRESULT WINAPI IShellBrowser_fnContextSensitiveHelp(IShellBrowser *iface,
                                                           BOOL fEnterMode)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (%d)\n", This, fEnterMode);

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnInsertMenusSB(IShellBrowser *iface,
                                                    HMENU hmenuShared,
                                                    LPOLEMENUGROUPWIDTHS lpMenuWidths)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p (%p, %p)\n", This, hmenuShared, lpMenuWidths);

    /* Not implemented. */
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnSetMenuSB(IShellBrowser *iface,
                                                HMENU hmenuShared,
                                                HOLEMENU holemenuReserved,
                                                HWND hwndActiveObject)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p (%p, %p, %p)\n", This, hmenuShared, holemenuReserved, hwndActiveObject);

    /* Not implemented. */
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnRemoveMenusSB(IShellBrowser *iface,
                                                    HMENU hmenuShared)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p (%p)\n", This, hmenuShared);

    /* Not implemented. */
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnSetStatusTextSB(IShellBrowser *iface,
                                                      LPCOLESTR pszStatusText)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (%s)\n", This, debugstr_w(pszStatusText));

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnEnableModelessSB(IShellBrowser *iface,
                                                       BOOL fEnable)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (%d)\n", This, fEnable);

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnTranslateAcceleratorSB(IShellBrowser *iface,
                                                             MSG *pmsg, WORD wID)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (%p, 0x%x)\n", This, pmsg, wID);

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnBrowseObject(IShellBrowser *iface,
                                                   LPCITEMIDLIST pidl, UINT wFlags)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p (%p, %x)\n", This, pidl, wFlags);

    return IExplorerBrowser_BrowseToIDList(&This->IExplorerBrowser_iface, pidl, wFlags);
}

static HRESULT WINAPI IShellBrowser_fnGetViewStateStream(IShellBrowser *iface,
                                                         DWORD grfMode,
                                                         IStream **ppStrm)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (0x%x, %p)\n", This, grfMode, ppStrm);

    *ppStrm = NULL;
    return E_FAIL;
}

static HRESULT WINAPI IShellBrowser_fnGetControlWindow(IShellBrowser *iface,
                                                       UINT id, HWND *phwnd)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("(%p)->(%d, %p)\n", This, id, phwnd);
    if (phwnd) *phwnd = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnSendControlMsg(IShellBrowser *iface,
                                                     UINT id, UINT uMsg,
                                                     WPARAM wParam, LPARAM lParam,
                                                     LRESULT *pret)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (%d, %d, %lx, %lx, %p)\n", This, id, uMsg, wParam, lParam, pret);

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnQueryActiveShellView(IShellBrowser *iface,
                                                           IShellView **ppshv)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p (%p)\n", This, ppshv);

    if(!This->psv)
        return E_FAIL;

    *ppshv = This->psv;
    IShellView_AddRef(This->psv);

    return S_OK;
}

static HRESULT WINAPI IShellBrowser_fnOnViewWindowActive(IShellBrowser *iface,
                                                         IShellView *pshv)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (%p)\n", This, pshv);

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnSetToolbarItems(IShellBrowser *iface,
                                                      LPTBBUTTONSB lpButtons,
                                                      UINT nButtons, UINT uFlags)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (%p, %d, 0x%x)\n", This, lpButtons, nButtons, uFlags);

    return E_NOTIMPL;
}

static const IShellBrowserVtbl vt_IShellBrowser = {
    IShellBrowser_fnQueryInterface,
    IShellBrowser_fnAddRef,
    IShellBrowser_fnRelease,
    IShellBrowser_fnGetWindow,
    IShellBrowser_fnContextSensitiveHelp,
    IShellBrowser_fnInsertMenusSB,
    IShellBrowser_fnSetMenuSB,
    IShellBrowser_fnRemoveMenusSB,
    IShellBrowser_fnSetStatusTextSB,
    IShellBrowser_fnEnableModelessSB,
    IShellBrowser_fnTranslateAcceleratorSB,
    IShellBrowser_fnBrowseObject,
    IShellBrowser_fnGetViewStateStream,
    IShellBrowser_fnGetControlWindow,
    IShellBrowser_fnSendControlMsg,
    IShellBrowser_fnQueryActiveShellView,
    IShellBrowser_fnOnViewWindowActive,
    IShellBrowser_fnSetToolbarItems
};

/**************************************************************************
 * ICommDlgBrowser3 Implementation
 */

static inline ExplorerBrowserImpl *impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface)
{
    return CONTAINING_RECORD(iface, ExplorerBrowserImpl, ICommDlgBrowser3_iface);
}

static HRESULT WINAPI ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3 *iface,
                                                        REFIID riid,
                                                        void **ppvObject)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p\n", This);
    return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
}

static ULONG WINAPI ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3 *iface)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p\n", This);
    return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
}

static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p\n", This);
    return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
}

static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *iface,
                                                          IShellView *shv)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    IDataObject *pdo;
    HRESULT hr;
    HRESULT ret = S_FALSE;

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

    hr = IShellView_GetItemObject(shv, SVGIO_SELECTION, &IID_IDataObject, (void**)&pdo);
    if(SUCCEEDED(hr))
    {
        FORMATETC fmt;
        STGMEDIUM medium;

        fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
        fmt.ptd = NULL;
        fmt.dwAspect = DVASPECT_CONTENT;
        fmt.lindex = -1;
        fmt.tymed = TYMED_HGLOBAL;

        hr = IDataObject_GetData(pdo, &fmt ,&medium);
        IDataObject_Release(pdo);
        if(SUCCEEDED(hr))
        {
            LPIDA pida = GlobalLock(medium.u.hGlobal);
            LPCITEMIDLIST pidl_child = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1]);

            /* Handle folders by browsing to them. */
            if(_ILIsFolder(pidl_child) || _ILIsDrive(pidl_child) || _ILIsSpecialFolder(pidl_child))
            {
                IExplorerBrowser_BrowseToIDList(&This->IExplorerBrowser_iface, pidl_child, SBSP_RELATIVE);
                ret = S_OK;
            }
            GlobalUnlock(medium.u.hGlobal);
            GlobalFree(medium.u.hGlobal);
        }
        else
            ERR("Failed to get data from IDataObject.\n");
    } else
        ERR("Failed to get IDataObject.\n");

    /* If we didn't handle the default command, check if we have a
     * client that does */
    if(ret == S_FALSE && This->pcdb_site)
        return ICommDlgBrowser_OnDefaultCommand(This->pcdb_site, shv);

    return ret;
}
static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface,
                                                       IShellView *shv, ULONG uChange)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%p, %d)\n", This, shv, uChange);

    if(This->pcdb_site)
        return ICommDlgBrowser_OnStateChange(This->pcdb_site, shv, uChange);

    return E_NOTIMPL;
}
static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface,
                                                       IShellView *pshv, LPCITEMIDLIST pidl)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%p, %p)\n", This, pshv, pidl);

    if(This->pcdb_site)
        return ICommDlgBrowser_IncludeObject(This->pcdb_site, pshv, pidl);

    return S_OK;
}

static HRESULT WINAPI ICommDlgBrowser3_fnNotify(ICommDlgBrowser3 *iface,
                                                IShellView *pshv,
                                                DWORD dwNotifyType)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%p, 0x%x)\n", This, pshv, dwNotifyType);

    if(This->pcdb2_site)
        return ICommDlgBrowser2_Notify(This->pcdb2_site, pshv, dwNotifyType);

    return S_OK;
}

static HRESULT WINAPI ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3 *iface,
                                                            IShellView *pshv,
                                                            LPWSTR pszText, int cchMax)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%p, %s, %d)\n", This, pshv, debugstr_w(pszText), cchMax);

    if(This->pcdb2_site)
        return ICommDlgBrowser2_GetDefaultMenuText(This->pcdb2_site, pshv, pszText, cchMax);

    return S_OK;
}

static HRESULT WINAPI ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3 *iface,
                                                      DWORD *pdwFlags)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%p)\n", This, pdwFlags);

    if(This->pcdb2_site)
        return ICommDlgBrowser2_GetViewFlags(This->pcdb2_site, pdwFlags);

    return S_OK;
}

static HRESULT WINAPI ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3 *iface,
                                                         IShellView *pshv, int iColumn)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%p, %d)\n", This, pshv, iColumn);

    if(This->pcdb3_site)
        return ICommDlgBrowser3_OnColumnClicked(This->pcdb3_site, pshv, iColumn);

    return S_OK;
}

static HRESULT WINAPI ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3 *iface,
                                                          LPWSTR pszFileSpec,
                                                          int cchFileSpec)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%s, %d)\n", This, debugstr_w(pszFileSpec), cchFileSpec);

    if(This->pcdb3_site)
        return ICommDlgBrowser3_GetCurrentFilter(This->pcdb3_site, pszFileSpec, cchFileSpec);

    return S_OK;
}

static HRESULT WINAPI ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3 *iface,
                                                          IShellView *pshv)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%p)\n", This, pshv);

    if(This->pcdb3_site)
        return ICommDlgBrowser3_OnPreviewCreated(This->pcdb3_site, pshv);

    return S_OK;
}

static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3 = {
    ICommDlgBrowser3_fnQueryInterface,
    ICommDlgBrowser3_fnAddRef,
    ICommDlgBrowser3_fnRelease,
    ICommDlgBrowser3_fnOnDefaultCommand,
    ICommDlgBrowser3_fnOnStateChange,
    ICommDlgBrowser3_fnIncludeObject,
    ICommDlgBrowser3_fnNotify,
    ICommDlgBrowser3_fnGetDefaultMenuText,
    ICommDlgBrowser3_fnGetViewFlags,
    ICommDlgBrowser3_fnOnColumnClicked,
    ICommDlgBrowser3_fnGetCurrentFilter,
    ICommDlgBrowser3_fnOnPreviewCreated
};

/**************************************************************************
 * IObjectWithSite Implementation
 */

static inline ExplorerBrowserImpl *impl_from_IObjectWithSite(IObjectWithSite *iface)
{
    return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IObjectWithSite_iface);
}

static HRESULT WINAPI IObjectWithSite_fnQueryInterface(IObjectWithSite *iface,
                                                       REFIID riid, void **ppvObject)
{
    ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
    TRACE("%p\n", This);
    return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
}

static ULONG WINAPI IObjectWithSite_fnAddRef(IObjectWithSite *iface)
{
    ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
    TRACE("%p\n", This);
    return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
}

static ULONG WINAPI IObjectWithSite_fnRelease(IObjectWithSite *iface)
{
    ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
    TRACE("%p\n", This);
    return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
}

static HRESULT WINAPI IObjectWithSite_fnSetSite(IObjectWithSite *iface, IUnknown *punk_site)
{
    ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
    TRACE("%p (%p)\n", This, punk_site);

    if(This->punk_site)
    {
        IUnknown_Release(This->punk_site);
        This->punk_site = NULL;
        get_interfaces_from_site(This);
    }

    This->punk_site = punk_site;

    if(This->punk_site)
        IUnknown_AddRef(This->punk_site);

    return S_OK;
}

static HRESULT WINAPI IObjectWithSite_fnGetSite(IObjectWithSite *iface, REFIID riid, void **ppvSite)
{
    ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
    TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvSite);

    if(!This->punk_site)
        return E_FAIL;

    return IUnknown_QueryInterface(This->punk_site, riid, ppvSite);
}

static const IObjectWithSiteVtbl vt_IObjectWithSite = {
    IObjectWithSite_fnQueryInterface,
    IObjectWithSite_fnAddRef,
    IObjectWithSite_fnRelease,
    IObjectWithSite_fnSetSite,
    IObjectWithSite_fnGetSite
};

/**************************************************************************
 * INameSpaceTreeControlEvents Implementation
 */
static inline ExplorerBrowserImpl *impl_from_INameSpaceTreeControlEvents(INameSpaceTreeControlEvents *iface)
{
    return CONTAINING_RECORD(iface, ExplorerBrowserImpl, INameSpaceTreeControlEvents_iface);
}

static HRESULT WINAPI NSTCEvents_fnQueryInterface(INameSpaceTreeControlEvents *iface,
                                                  REFIID riid, void **ppvObject)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);

    *ppvObject = NULL;
    if(IsEqualIID(riid, &IID_INameSpaceTreeControlEvents) ||
       IsEqualIID(riid, &IID_IUnknown))
    {
        *ppvObject = iface;
    }

    if(*ppvObject)
    {
        IUnknown_AddRef((IUnknown*)*ppvObject);
        return S_OK;
    }

    return E_NOINTERFACE;
}

static ULONG WINAPI NSTCEvents_fnAddRef(INameSpaceTreeControlEvents *iface)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p\n", This);
    return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
}

static ULONG WINAPI NSTCEvents_fnRelease(INameSpaceTreeControlEvents *iface)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p\n", This);
    return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
}

static HRESULT WINAPI NSTCEvents_fnOnItemClick(INameSpaceTreeControlEvents *iface,
                                               IShellItem *psi,
                                               NSTCEHITTEST nstceHitTest,
                                               NSTCECLICKTYPE nstceClickType)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstceHitTest, nstceClickType);
    return S_OK;
}

static HRESULT WINAPI NSTCEvents_fnOnPropertyItemCommit(INameSpaceTreeControlEvents *iface,
                                                        IShellItem *psi)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnItemStateChanging(INameSpaceTreeControlEvents *iface,
                                                       IShellItem *psi,
                                                       NSTCITEMSTATE nstcisMask,
                                                       NSTCITEMSTATE nstcisState)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstcisMask, nstcisState);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnItemStateChanged(INameSpaceTreeControlEvents *iface,
                                                      IShellItem *psi,
                                                      NSTCITEMSTATE nstcisMask,
                                                      NSTCITEMSTATE nstcisState)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstcisMask, nstcisState);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnSelectionChanged(INameSpaceTreeControlEvents *iface,
                                                      IShellItemArray *psiaSelection)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    IShellItem *psi;
    HRESULT hr;
    TRACE("%p (%p)\n", This, psiaSelection);

    hr = IShellItemArray_GetItemAt(psiaSelection, 0, &psi);
    if(SUCCEEDED(hr))
    {
        hr = IExplorerBrowser_BrowseToObject(&This->IExplorerBrowser_iface,
                                             (IUnknown*)psi, SBSP_DEFBROWSER);
        IShellItem_Release(psi);
    }

    return hr;
}

static HRESULT WINAPI NSTCEvents_fnOnKeyboardInput(INameSpaceTreeControlEvents *iface,
                                                   UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%d, 0x%lx, 0x%lx)\n", This, uMsg, wParam, lParam);
    return S_OK;
}

static HRESULT WINAPI NSTCEvents_fnOnBeforeExpand(INameSpaceTreeControlEvents *iface,
                                                  IShellItem *psi)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnAfterExpand(INameSpaceTreeControlEvents *iface,
                                                 IShellItem *psi)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnBeginLabelEdit(INameSpaceTreeControlEvents *iface,
                                                    IShellItem *psi)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnEndLabelEdit(INameSpaceTreeControlEvents *iface,
                                                  IShellItem *psi)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnGetToolTip(INameSpaceTreeControlEvents *iface,
                                                IShellItem *psi, LPWSTR pszTip, int cchTip)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, %p, %d)\n", This, psi, pszTip, cchTip);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnBeforeItemDelete(INameSpaceTreeControlEvents *iface,
                                                      IShellItem *psi)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnItemAdded(INameSpaceTreeControlEvents *iface,
                                               IShellItem *psi, BOOL fIsRoot)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnItemDeleted(INameSpaceTreeControlEvents *iface,
                                                 IShellItem *psi, BOOL fIsRoot)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnBeforeContextMenu(INameSpaceTreeControlEvents *iface,
                                                       IShellItem *psi, REFIID riid, void **ppv)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, %s, %p)\n", This, psi, shdebugstr_guid(riid), ppv);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnAfterContextMenu(INameSpaceTreeControlEvents *iface,
                                                      IShellItem *psi, IContextMenu *pcmIn,
                                                      REFIID riid, void **ppv)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, %p, %s, %p)\n", This, psi, pcmIn, shdebugstr_guid(riid), ppv);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnBeforeStateImageChange(INameSpaceTreeControlEvents *iface,
                                                            IShellItem *psi)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnGetDefaultIconIndex(INameSpaceTreeControlEvents* iface,
                                                         IShellItem *psi,
                                                         int *piDefaultIcon, int *piOpenIcon)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, %p, %p)\n", This, psi, piDefaultIcon, piOpenIcon);
    return E_NOTIMPL;
}


static const INameSpaceTreeControlEventsVtbl vt_INameSpaceTreeControlEvents =  {
    NSTCEvents_fnQueryInterface,
    NSTCEvents_fnAddRef,
    NSTCEvents_fnRelease,
    NSTCEvents_fnOnItemClick,
    NSTCEvents_fnOnPropertyItemCommit,
    NSTCEvents_fnOnItemStateChanging,
    NSTCEvents_fnOnItemStateChanged,
    NSTCEvents_fnOnSelectionChanged,
    NSTCEvents_fnOnKeyboardInput,
    NSTCEvents_fnOnBeforeExpand,
    NSTCEvents_fnOnAfterExpand,
    NSTCEvents_fnOnBeginLabelEdit,
    NSTCEvents_fnOnEndLabelEdit,
    NSTCEvents_fnOnGetToolTip,
    NSTCEvents_fnOnBeforeItemDelete,
    NSTCEvents_fnOnItemAdded,
    NSTCEvents_fnOnItemDeleted,
    NSTCEvents_fnOnBeforeContextMenu,
    NSTCEvents_fnOnAfterContextMenu,
    NSTCEvents_fnOnBeforeStateImageChange,
    NSTCEvents_fnOnGetDefaultIconIndex
};

/**************************************************************************
 * IInputObject Implementation
 */

static inline ExplorerBrowserImpl *impl_from_IInputObject(IInputObject *iface)
{
    return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IInputObject_iface);
}

static HRESULT WINAPI IInputObject_fnQueryInterface(IInputObject *iface,
                                                    REFIID riid, void **ppvObject)
{
    ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
    TRACE("%p\n", This);
    return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
}

static ULONG WINAPI IInputObject_fnAddRef(IInputObject *iface)
{
    ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
    TRACE("%p\n", This);
    return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
}

static ULONG WINAPI IInputObject_fnRelease(IInputObject *iface)
{
    ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
    TRACE("%p\n", This);
    return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
}

static HRESULT WINAPI IInputObject_fnUIActivateIO(IInputObject *iface, BOOL fActivate, MSG *pMsg)
{
    ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
    FIXME("stub, %p (%d, %p)\n", This, fActivate, pMsg);
    return E_NOTIMPL;
}

static HRESULT WINAPI IInputObject_fnHasFocusIO(IInputObject *iface)
{
    ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
    FIXME("stub, %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI IInputObject_fnTranslateAcceleratorIO(IInputObject *iface, MSG *pMsg)
{
    ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
    FIXME("stub, %p (%p)\n", This, pMsg);
    return E_NOTIMPL;
}

static IInputObjectVtbl vt_IInputObject = {
    IInputObject_fnQueryInterface,
    IInputObject_fnAddRef,
    IInputObject_fnRelease,
    IInputObject_fnUIActivateIO,
    IInputObject_fnHasFocusIO,
    IInputObject_fnTranslateAcceleratorIO
};

HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
{
    ExplorerBrowserImpl *eb;
    HRESULT ret;

    TRACE("%p %s %p\n", pUnkOuter, shdebugstr_guid (riid), ppv);

    if(!ppv)
        return E_POINTER;
    if(pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    eb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ExplorerBrowserImpl));
    eb->ref = 1;
    eb->IExplorerBrowser_iface.lpVtbl = &vt_IExplorerBrowser;
    eb->IShellBrowser_iface.lpVtbl    = &vt_IShellBrowser;
    eb->ICommDlgBrowser3_iface.lpVtbl = &vt_ICommDlgBrowser3;
    eb->IObjectWithSite_iface.lpVtbl  = &vt_IObjectWithSite;
    eb->INameSpaceTreeControlEvents_iface.lpVtbl = &vt_INameSpaceTreeControlEvents;
    eb->IInputObject_iface.lpVtbl     = &vt_IInputObject;

    /* Default settings */
    eb->navpane.width = 150;
    eb->navpane.show = TRUE;

    list_init(&eb->event_clients);
    list_init(&eb->travellog);

    ret = IExplorerBrowser_QueryInterface(&eb->IExplorerBrowser_iface, riid, ppv);
    IExplorerBrowser_Release(&eb->IExplorerBrowser_iface);

    TRACE("--(%p)\n", ppv);
    return ret;
}
