/*
 * NamespaceTreeControl 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
#define NONAMELESSSTRUCT

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

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

#include "explorerframe_main.h"

WINE_DEFAULT_DEBUG_CHANNEL(nstc);

typedef struct nstc_root {
    IShellItem *psi;
    HTREEITEM htreeitem;
    SHCONTF enum_flags;
    NSTCROOTSTYLE root_style;
    IShellItemFilter *pif;
    struct list entry;
} nstc_root;

typedef struct {
    INameSpaceTreeControl2 INameSpaceTreeControl2_iface;
    IOleWindow IOleWindow_iface;
    LONG ref;

    HWND hwnd_main;
    HWND hwnd_tv;

    WNDPROC tv_oldwndproc;

    NSTCSTYLE style;
    NSTCSTYLE2 style2;
    struct list roots;

    INameSpaceTreeControlEvents *pnstce;
} NSTC2Impl;

static const DWORD unsupported_styles =
    NSTCS_SINGLECLICKEXPAND | NSTCS_NOREPLACEOPEN | NSTCS_NOORDERSTREAM | NSTCS_FAVORITESMODE |
    NSTCS_EMPTYTEXT | NSTCS_ALLOWJUNCTIONS | NSTCS_SHOWTABSBUTTON | NSTCS_SHOWDELETEBUTTON |
    NSTCS_SHOWREFRESHBUTTON | NSTCS_SPRINGEXPAND | NSTCS_RICHTOOLTIP | NSTCS_NOINDENTCHECKS;
static const DWORD unsupported_styles2 =
    NSTCS2_INTERRUPTNOTIFICATIONS | NSTCS2_SHOWNULLSPACEMENU | NSTCS2_DISPLAYPADDING |
    NSTCS2_DISPLAYPINNEDONLY | NTSCS2_NOSINGLETONAUTOEXPAND | NTSCS2_NEVERINSERTNONENUMERATED;

static inline NSTC2Impl *impl_from_INameSpaceTreeControl2(INameSpaceTreeControl2 *iface)
{
    return CONTAINING_RECORD(iface, NSTC2Impl, INameSpaceTreeControl2_iface);
}

static inline NSTC2Impl *impl_from_IOleWindow(IOleWindow *iface)
{
    return CONTAINING_RECORD(iface, NSTC2Impl, IOleWindow_iface);
}

/* Forward declarations */
static LRESULT CALLBACK tv_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam);

/*************************************************************************
* NamespaceTree event wrappers
*/
static HRESULT events_OnGetDefaultIconIndex(NSTC2Impl *This, IShellItem *psi,
                                            int *piDefaultIcon, int *piOpenIcon)
{
    HRESULT ret;
    LONG refcount;
    if(!This->pnstce) return E_NOTIMPL;

    refcount = IShellItem_AddRef(psi);
    ret = INameSpaceTreeControlEvents_OnGetDefaultIconIndex(This->pnstce, psi, piDefaultIcon, piOpenIcon);
    if(IShellItem_Release(psi) < refcount - 1)
        ERR("ShellItem was released by client - please file a bug.\n");
    return ret;
}

static HRESULT events_OnItemAdded(NSTC2Impl *This, IShellItem *psi, BOOL fIsRoot)
{
    HRESULT ret;
    LONG refcount;
    if(!This->pnstce) return S_OK;

    refcount = IShellItem_AddRef(psi);
    ret = INameSpaceTreeControlEvents_OnItemAdded(This->pnstce, psi, fIsRoot);
    if(IShellItem_Release(psi) < refcount - 1)
        ERR("ShellItem was released by client - please file a bug.\n");
    return ret;
}

static HRESULT events_OnItemDeleted(NSTC2Impl *This, IShellItem *psi, BOOL fIsRoot)
{
    HRESULT ret;
    LONG refcount;
    if(!This->pnstce) return S_OK;

    refcount = IShellItem_AddRef(psi);
    ret = INameSpaceTreeControlEvents_OnItemDeleted(This->pnstce, psi, fIsRoot);
    if(IShellItem_Release(psi) < refcount - 1)
        ERR("ShellItem was released by client - please file a bug.\n");
    return ret;
}

static HRESULT events_OnBeforeExpand(NSTC2Impl *This, IShellItem *psi)
{
    HRESULT ret;
    LONG refcount;
    if(!This->pnstce) return S_OK;

    refcount = IShellItem_AddRef(psi);
    ret = INameSpaceTreeControlEvents_OnBeforeExpand(This->pnstce, psi);
    if(IShellItem_Release(psi) < refcount - 1)
        ERR("ShellItem was released by client - please file a bug.\n");
    return ret;
}

static HRESULT events_OnAfterExpand(NSTC2Impl *This, IShellItem *psi)
{
    HRESULT ret;
    LONG refcount;
    if(!This->pnstce) return S_OK;

    refcount = IShellItem_AddRef(psi);
    ret = INameSpaceTreeControlEvents_OnAfterExpand(This->pnstce, psi);
    if(IShellItem_Release(psi) < refcount - 1)
        ERR("ShellItem was released by client - please file a bug.\n");
    return ret;
}

static HRESULT events_OnItemClick(NSTC2Impl *This, IShellItem *psi,
                                  NSTCEHITTEST nstceHitTest, NSTCECLICKTYPE nstceClickType)
{
    HRESULT ret;
    LONG refcount;
    if(!This->pnstce) return S_OK;

    refcount = IShellItem_AddRef(psi);
    ret = INameSpaceTreeControlEvents_OnItemClick(This->pnstce, psi, nstceHitTest, nstceClickType);
    if(IShellItem_Release(psi) < refcount - 1)
        ERR("ShellItem was released by client - please file a bug.\n");
    return ret;
}

static HRESULT events_OnSelectionChanged(NSTC2Impl *This, IShellItemArray *psia)
{
    if(!This->pnstce) return S_OK;

    return INameSpaceTreeControlEvents_OnSelectionChanged(This->pnstce, psia);
}

static HRESULT events_OnKeyboardInput(NSTC2Impl *This, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if(!This->pnstce) return S_OK;

    return INameSpaceTreeControlEvents_OnKeyboardInput(This->pnstce, uMsg, wParam, lParam);
}

/*************************************************************************
 * NamespaceTree helper functions
 */
static DWORD treeview_style_from_nstcs(NSTC2Impl *This, NSTCSTYLE nstcs,
                                       NSTCSTYLE nstcs_mask, DWORD *new_style)
{
    DWORD old_style, tv_mask = 0;
    TRACE("%p, %x, %x, %p\n", This, nstcs, nstcs_mask, new_style);

    if(This->hwnd_tv)
        old_style = GetWindowLongPtrW(This->hwnd_tv, GWL_STYLE);
    else
        old_style = /* The default */
            WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
            WS_TABSTOP | TVS_NOHSCROLL | TVS_NONEVENHEIGHT | TVS_INFOTIP |
            TVS_EDITLABELS | TVS_TRACKSELECT;

    if(nstcs_mask & NSTCS_HASEXPANDOS)         tv_mask |= TVS_HASBUTTONS;
    if(nstcs_mask & NSTCS_HASLINES)            tv_mask |= TVS_HASLINES;
    if(nstcs_mask & NSTCS_FULLROWSELECT)       tv_mask |= TVS_FULLROWSELECT;
    if(nstcs_mask & NSTCS_HORIZONTALSCROLL)    tv_mask |= TVS_NOHSCROLL;
    if(nstcs_mask & NSTCS_ROOTHASEXPANDO)      tv_mask |= TVS_LINESATROOT;
    if(nstcs_mask & NSTCS_SHOWSELECTIONALWAYS) tv_mask |= TVS_SHOWSELALWAYS;
    if(nstcs_mask & NSTCS_NOINFOTIP)           tv_mask |= TVS_INFOTIP;
    if(nstcs_mask & NSTCS_EVENHEIGHT)          tv_mask |= TVS_NONEVENHEIGHT;
    if(nstcs_mask & NSTCS_DISABLEDRAGDROP)     tv_mask |= TVS_DISABLEDRAGDROP;
    if(nstcs_mask & NSTCS_NOEDITLABELS)        tv_mask |= TVS_EDITLABELS;
    if(nstcs_mask & NSTCS_CHECKBOXES)          tv_mask |= TVS_CHECKBOXES;

    *new_style = 0;

    if(nstcs & NSTCS_HASEXPANDOS)         *new_style |= TVS_HASBUTTONS;
    if(nstcs & NSTCS_HASLINES)            *new_style |= TVS_HASLINES;
    if(nstcs & NSTCS_FULLROWSELECT)       *new_style |= TVS_FULLROWSELECT;
    if(!(nstcs & NSTCS_HORIZONTALSCROLL)) *new_style |= TVS_NOHSCROLL;
    if(nstcs & NSTCS_ROOTHASEXPANDO)      *new_style |= TVS_LINESATROOT;
    if(nstcs & NSTCS_SHOWSELECTIONALWAYS) *new_style |= TVS_SHOWSELALWAYS;
    if(!(nstcs & NSTCS_NOINFOTIP))        *new_style |= TVS_INFOTIP;
    if(!(nstcs & NSTCS_EVENHEIGHT))       *new_style |= TVS_NONEVENHEIGHT;
    if(nstcs & NSTCS_DISABLEDRAGDROP)     *new_style |= TVS_DISABLEDRAGDROP;
    if(!(nstcs & NSTCS_NOEDITLABELS))     *new_style |= TVS_EDITLABELS;
    if(nstcs & NSTCS_CHECKBOXES)          *new_style |= TVS_CHECKBOXES;

    *new_style = (old_style & ~tv_mask) | (*new_style & tv_mask);

    TRACE("old: %08x, new: %08x\n", old_style, *new_style);

    return old_style^*new_style;
}

static IShellItem *shellitem_from_treeitem(NSTC2Impl *This, HTREEITEM hitem)
{
    TVITEMEXW tvi;

    tvi.mask = TVIF_PARAM;
    tvi.lParam = 0;
    tvi.hItem = hitem;

    SendMessageW(This->hwnd_tv, TVM_GETITEMW, 0, (LPARAM)&tvi);

    TRACE("ShellItem: %p\n", (void*)tvi.lParam);
    return (IShellItem*)tvi.lParam;
}

/* Returns the root that the given treeitem belongs to. */
static nstc_root *root_for_treeitem(NSTC2Impl *This, HTREEITEM hitem)
{
    HTREEITEM tmp, hroot = hitem;
    nstc_root *root;

    /* Work our way up the hierarchy */
    for(tmp = hitem; tmp != NULL; hroot = tmp?tmp:hroot)
        tmp = (HTREEITEM)SendMessageW(This->hwnd_tv, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hroot);

    /* Search through the list of roots for a match */
    LIST_FOR_EACH_ENTRY(root, &This->roots, nstc_root, entry)
        if(root->htreeitem == hroot)
            break;

    TRACE("root is %p\n", root);
    return root;
}

/* Find a shellitem in the tree, starting from the given node. */
static HTREEITEM search_for_shellitem(NSTC2Impl *This, HTREEITEM node,
                                      IShellItem *psi)
{
    IShellItem *psi_node;
    HTREEITEM next, result = NULL;
    HRESULT hr;
    int cmpo;
    TRACE("%p, %p, %p\n", This, node, psi);

    /* Check this node */
    psi_node = shellitem_from_treeitem(This, node);
    hr = IShellItem_Compare(psi, psi_node, SICHINT_DISPLAY, &cmpo);
    if(hr == S_OK)
        return node;

    /* Any children? */
    next = (HTREEITEM)SendMessageW(This->hwnd_tv, TVM_GETNEXTITEM,
                                   TVGN_CHILD, (LPARAM)node);
    if(next)
    {
        result = search_for_shellitem(This, next, psi);
        if(result) return result;
    }

    /* Try our next sibling. */
    next = (HTREEITEM)SendMessageW(This->hwnd_tv, TVM_GETNEXTITEM,
                                   TVGN_NEXT, (LPARAM)node);
    if(next)
        result = search_for_shellitem(This, next, psi);

    return result;
}

static HTREEITEM treeitem_from_shellitem(NSTC2Impl *This, IShellItem *psi)
{
    HTREEITEM root;
    TRACE("%p, %p\n", This, psi);

    root = (HTREEITEM)SendMessageW(This->hwnd_tv, TVM_GETNEXTITEM,
                                   TVGN_ROOT, 0);
    if(!root)
        return NULL;

    return search_for_shellitem(This, root, psi);
}

static int get_icon(LPCITEMIDLIST lpi, UINT extra_flags)
{
    SHFILEINFOW sfi;
    UINT flags = SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON;
    SHGetFileInfoW((LPCWSTR)lpi, 0 ,&sfi, sizeof(SHFILEINFOW), flags | extra_flags);
    return sfi.iIcon;
}

/* Insert a shellitem into the given place in the tree and return the
   resulting treeitem. */
static HTREEITEM insert_shellitem(NSTC2Impl *This, IShellItem *psi,
                                  HTREEITEM hParent, HTREEITEM hInsertAfter)
{
    TVINSERTSTRUCTW tvins;
    TVITEMEXW *tvi = &tvins.u.itemex;
    HTREEITEM hinserted;
    TRACE("%p (%p, %p)\n", psi, hParent, hInsertAfter);

    tvi->mask = TVIF_PARAM | TVIF_CHILDREN | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
    tvi->cChildren = I_CHILDRENCALLBACK;
    tvi->iImage = tvi->iSelectedImage = I_IMAGECALLBACK;
    tvi->pszText = LPSTR_TEXTCALLBACKW;

    /* Every treeitem contains a pointer to the corresponding ShellItem. */
    tvi->lParam = (LPARAM)psi;
    tvins.hParent = hParent;
    tvins.hInsertAfter = hInsertAfter;

    hinserted = (HTREEITEM)SendMessageW(This->hwnd_tv, TVM_INSERTITEMW, 0,
                                        (LPARAM)(LPTVINSERTSTRUCTW)&tvins);
    if(hinserted)
        IShellItem_AddRef(psi);

    return hinserted;
}

/* Enumerates the children of the folder represented by hitem
 * according to the settings for the root, and adds them to the
 * treeview. Returns the number of children added. */
static UINT fill_sublevel(NSTC2Impl *This, HTREEITEM hitem)
{
    IShellItem *psiParent = shellitem_from_treeitem(This, hitem);
    nstc_root *root = root_for_treeitem(This, hitem);
    LPITEMIDLIST pidl_parent;
    IShellFolder *psf;
    IEnumIDList *peidl;
    UINT added = 0;
    HRESULT hr;

    hr = SHGetIDListFromObject((IUnknown*)psiParent, &pidl_parent);
    if(SUCCEEDED(hr))
    {
        hr = IShellItem_BindToHandler(psiParent, NULL, &BHID_SFObject, &IID_IShellFolder, (void**)&psf);
        if(SUCCEEDED(hr))
        {
            hr = IShellFolder_EnumObjects(psf, NULL, root->enum_flags, &peidl);
            if(SUCCEEDED(hr))
            {
                LPITEMIDLIST pidl;
                IShellItem *psi;
                ULONG fetched;

                while( S_OK == IEnumIDList_Next(peidl, 1, &pidl, &fetched) )
                {
                    hr = SHCreateShellItem(NULL, psf , pidl, &psi);
                    ILFree(pidl);
                    if(SUCCEEDED(hr))
                    {
                        if(insert_shellitem(This, psi, hitem, NULL))
                        {
                            events_OnItemAdded(This, psi, FALSE);
                            added++;
                        }

                        IShellItem_Release(psi);
                    }
                    else
                        ERR("SHCreateShellItem failed with 0x%08x\n", hr);
                }
                IEnumIDList_Release(peidl);
            }
            else
                ERR("EnumObjects failed with 0x%08x\n", hr);

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

        ILFree(pidl_parent);
    }
    else
        ERR("SHGetIDListFromObject failed with 0x%08x\n", hr);

    return added;
}

static HTREEITEM get_selected_treeitem(NSTC2Impl *This)
{
    return (HTREEITEM)SendMessageW(This->hwnd_tv, TVM_GETNEXTITEM, TVGN_CARET, 0);
}

static IShellItem *get_selected_shellitem(NSTC2Impl *This)
{
    return shellitem_from_treeitem(This, get_selected_treeitem(This));
}

static void collapse_all(NSTC2Impl *This, HTREEITEM node)
{
    HTREEITEM next;

    /* Collapse this node first, and then first child/next sibling. */
    SendMessageW(This->hwnd_tv, TVM_EXPAND, TVE_COLLAPSE, (LPARAM)node);

    next = (HTREEITEM)SendMessageW(This->hwnd_tv, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)node);
    if(next) collapse_all(This, next);

    next = (HTREEITEM)SendMessageW(This->hwnd_tv, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)node);
    if(next) collapse_all(This, next);
}

static HTREEITEM treeitem_from_point(NSTC2Impl *This, const POINT *pt, UINT *hitflag)
{
    TVHITTESTINFO tviht;
    tviht.pt.x = pt->x;
    tviht.pt.y = pt->y;
    tviht.hItem = NULL;

    SendMessageW(This->hwnd_tv, TVM_HITTEST, 0, (LPARAM)&tviht);
    if(hitflag) *hitflag = tviht.flags;
    return tviht.hItem;
}

/*************************************************************************
 * NamespaceTree window functions
 */
static LRESULT create_namespacetree(HWND hWnd, CREATESTRUCTW *crs)
{
    NSTC2Impl *This = crs->lpCreateParams;
    HIMAGELIST ShellSmallIconList;
    DWORD treeview_style, treeview_ex_style;

    TRACE("%p (%p)\n", This, crs);
    SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LPARAM)This);
    This->hwnd_main = hWnd;

    treeview_style_from_nstcs(This, This->style, 0xFFFFFFFF, &treeview_style);

    This->hwnd_tv = CreateWindowExW(0, WC_TREEVIEWW, NULL, treeview_style,
                                    0, 0, crs->cx, crs->cy,
                                    hWnd, NULL, explorerframe_hinstance, NULL);

    if(!This->hwnd_tv)
    {
        ERR("Failed to create treeview!\n");
        return HRESULT_FROM_WIN32(GetLastError());
    }

    treeview_ex_style = TVS_EX_DRAWIMAGEASYNC | TVS_EX_RICHTOOLTIP |
        TVS_EX_DOUBLEBUFFER | TVS_EX_NOSINGLECOLLAPSE;

    if(This->style & NSTCS_AUTOHSCROLL)
        treeview_ex_style |= TVS_EX_AUTOHSCROLL;
    if(This->style & NSTCS_FADEINOUTEXPANDOS)
        treeview_ex_style |= TVS_EX_FADEINOUTEXPANDOS;
    if(This->style & NSTCS_PARTIALCHECKBOXES)
        treeview_ex_style |= TVS_EX_PARTIALCHECKBOXES;
    if(This->style & NSTCS_EXCLUSIONCHECKBOXES)
        treeview_ex_style |= TVS_EX_EXCLUSIONCHECKBOXES;
    if(This->style & NSTCS_DIMMEDCHECKBOXES)
        treeview_ex_style |= TVS_EX_DIMMEDCHECKBOXES;

    SendMessageW(This->hwnd_tv, TVM_SETEXTENDEDSTYLE, treeview_ex_style, 0xffff);

    if(Shell_GetImageLists(NULL, &ShellSmallIconList))
    {
        SendMessageW(This->hwnd_tv, TVM_SETIMAGELIST,
                     (WPARAM)TVSIL_NORMAL, (LPARAM)ShellSmallIconList);
    }
    else
    {
        ERR("Failed to get the System Image List.\n");
    }

    INameSpaceTreeControl_AddRef((INameSpaceTreeControl*)This);

    /* Subclass the treeview to get the keybord events. */
    This->tv_oldwndproc = (WNDPROC)SetWindowLongPtrW(This->hwnd_tv, GWLP_WNDPROC,
                                                     (ULONG_PTR)tv_wndproc);
    if(This->tv_oldwndproc)
        SetPropA(This->hwnd_tv, "PROP_THIS", This);

    return TRUE;
}

static LRESULT resize_namespacetree(NSTC2Impl *This)
{
    RECT rc;
    TRACE("%p\n", This);

    GetClientRect(This->hwnd_main, &rc);
    MoveWindow(This->hwnd_tv, 0, 0, rc.right-rc.left, rc.bottom-rc.top, TRUE);

    return TRUE;
}

static LRESULT destroy_namespacetree(NSTC2Impl *This)
{
    TRACE("%p\n", This);

    /* Undo the subclassing */
    if(This->tv_oldwndproc)
    {
        SetWindowLongPtrW(This->hwnd_tv, GWLP_WNDPROC, (ULONG_PTR)This->tv_oldwndproc);
        RemovePropA(This->hwnd_tv, "PROP_THIS");
    }

    INameSpaceTreeControl_RemoveAllRoots((INameSpaceTreeControl*)This);

    /* This reference was added in create_namespacetree */
    INameSpaceTreeControl_Release((INameSpaceTreeControl*)This);
    return TRUE;
}

static LRESULT on_tvn_deleteitemw(NSTC2Impl *This, LPARAM lParam)
{
    NMTREEVIEWW *nmtv = (NMTREEVIEWW*)lParam;
    TRACE("%p\n", This);

    IShellItem_Release((IShellItem*)nmtv->itemOld.lParam);
    return TRUE;
}

static LRESULT on_tvn_getdispinfow(NSTC2Impl *This, LPARAM lParam)
{
    NMTVDISPINFOW *dispinfo = (NMTVDISPINFOW*)lParam;
    TVITEMEXW *item = (TVITEMEXW*)&dispinfo->item;
    IShellItem *psi = shellitem_from_treeitem(This, item->hItem);
    HRESULT hr;

    TRACE("%p, %p (mask: %x)\n", This, dispinfo, item->mask);

    if(item->mask & TVIF_CHILDREN)
    {
        SFGAOF sfgao;

        hr = IShellItem_GetAttributes(psi, SFGAO_HASSUBFOLDER, &sfgao);
        if(SUCCEEDED(hr))
            item->cChildren = (sfgao & SFGAO_HASSUBFOLDER)?1:0;
        else
            item->cChildren = 1;

        item->mask |= TVIF_DI_SETITEM;
    }

    if(item->mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE))
    {
        LPITEMIDLIST pidl;

        hr = events_OnGetDefaultIconIndex(This, psi, &item->iImage, &item->iSelectedImage);
        if(FAILED(hr))
        {
            hr = SHGetIDListFromObject((IUnknown*)psi, &pidl);
            if(SUCCEEDED(hr))
            {
                item->iImage = item->iSelectedImage = get_icon(pidl, 0);
                item->mask |= TVIF_DI_SETITEM;
                ILFree(pidl);
            }
            else
                ERR("Failed to get IDList (%08x).\n", hr);
        }
    }

    if(item->mask & TVIF_TEXT)
    {
        LPWSTR display_name;

        hr = IShellItem_GetDisplayName(psi, SIGDN_NORMALDISPLAY, &display_name);
        if(SUCCEEDED(hr))
        {
            lstrcpynW(item->pszText, display_name, MAX_PATH);
            item->mask |= TVIF_DI_SETITEM;
            CoTaskMemFree(display_name);
        }
        else
            ERR("Failed to get display name (%08x).\n", hr);
    }

    return TRUE;
}

static BOOL treenode_has_subfolders(NSTC2Impl *This, HTREEITEM node)
{
    return SendMessageW(This->hwnd_tv, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)node);
}

static LRESULT on_tvn_itemexpandingw(NSTC2Impl *This, LPARAM lParam)
{
    NMTREEVIEWW *nmtv = (NMTREEVIEWW*)lParam;
    IShellItem *psi;
    TRACE("%p\n", This);

    psi = shellitem_from_treeitem(This, nmtv->itemNew.hItem);
    events_OnBeforeExpand(This, psi);

    if(!treenode_has_subfolders(This, nmtv->itemNew.hItem))
    {
        /* The node has no children, try to find some */
        if(!fill_sublevel(This, nmtv->itemNew.hItem))
        {
            TVITEMEXW tvi;
            /* Failed to enumerate any children, remove the expando
             * (if any). */
            tvi.hItem = nmtv->itemNew.hItem;
            tvi.mask = TVIF_CHILDREN;
            tvi.cChildren = 0;
            SendMessageW(This->hwnd_tv, TVM_SETITEMW, 0, (LPARAM)&tvi);

            return TRUE;
        }
    }
    return FALSE;
}

static LRESULT on_tvn_itemexpandedw(NSTC2Impl *This, LPARAM lParam)
{
    NMTREEVIEWW *nmtv = (NMTREEVIEWW*)lParam;
    IShellItem *psi;
    TRACE("%p\n", This);

    psi = shellitem_from_treeitem(This, nmtv->itemNew.hItem);
    events_OnAfterExpand(This, psi);
    return TRUE;
}

static LRESULT on_tvn_selchangedw(NSTC2Impl *This, LPARAM lParam)
{
    NMTREEVIEWW *nmtv = (NMTREEVIEWW*)lParam;
    IShellItemArray *psia;
    IShellItem *psi;
    HRESULT hr;
    TRACE("%p\n", This);

    /* Note: Only supports one selected item. */
    psi = shellitem_from_treeitem(This, nmtv->itemNew.hItem);
    hr = SHCreateShellItemArrayFromShellItem(psi, &IID_IShellItemArray, (void**)&psia);
    if(SUCCEEDED(hr))
    {
        events_OnSelectionChanged(This, psia);
        IShellItemArray_Release(psia);
    }

    return TRUE;
}

static LRESULT on_nm_click(NSTC2Impl *This, NMHDR *nmhdr)
{
    TVHITTESTINFO tvhit;
    IShellItem *psi;
    HRESULT hr;
    TRACE("%p (%p)\n", This, nmhdr);

    GetCursorPos(&tvhit.pt);
    ScreenToClient(This->hwnd_tv, &tvhit.pt);
    SendMessageW(This->hwnd_tv, TVM_HITTEST, 0, (LPARAM)&tvhit);

    if(tvhit.flags & (TVHT_NOWHERE|TVHT_ABOVE|TVHT_BELOW))
        return TRUE;

    /* TVHT_ maps onto the corresponding NSTCEHT_ */
    psi = shellitem_from_treeitem(This, tvhit.hItem);
    hr = events_OnItemClick(This, psi, tvhit.flags, NSTCECT_LBUTTON);

    /* The expando should not be expanded unless
     * double-clicked. */
    if(tvhit.flags == TVHT_ONITEMBUTTON)
        return TRUE;

    if(SUCCEEDED(hr))
        return FALSE;
    else
        return TRUE;
}

static LRESULT on_wm_mbuttonup(NSTC2Impl *This, WPARAM wParam, LPARAM lParam)
{
    TVHITTESTINFO tvhit;
    IShellItem *psi;
    HRESULT hr;
    TRACE("%p (%lx, %lx)\n", This, wParam, lParam);

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

    SendMessageW(This->hwnd_tv, TVM_HITTEST, 0, (LPARAM)&tvhit);

    /* Seems to generate only ONITEM and ONITEMICON */
    if( !(tvhit.flags & (TVHT_ONITEM|TVHT_ONITEMICON)) )
        return FALSE;

    psi = shellitem_from_treeitem(This, tvhit.hItem);
    hr = events_OnItemClick(This, psi, tvhit.flags, NSTCECT_MBUTTON);

    if(SUCCEEDED(hr))
        return FALSE;
    else
        return TRUE;
}

static LRESULT on_kbd_event(NSTC2Impl *This, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    IShellItem *psi;
    HTREEITEM hitem;
    TRACE("%p : %d, %lx, %lx\n", This, uMsg, wParam, lParam);

    /* Handled by the client? */
    if(FAILED(events_OnKeyboardInput(This, uMsg, wParam, lParam)))
        return TRUE;

    if(uMsg == WM_KEYDOWN)
    {
        switch(wParam)
        {
        case VK_DELETE:
            psi = get_selected_shellitem(This);
            FIXME("Deletion of file requested (shellitem: %p).\n", psi);
            return TRUE;

        case VK_F2:
            hitem = get_selected_treeitem(This);
            SendMessageW(This->hwnd_tv, TVM_EDITLABELW, 0, (LPARAM)hitem);
            return TRUE;
        }
    }

    /* Let the TreeView handle the key */
    return FALSE;
}

static LRESULT CALLBACK tv_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
    NSTC2Impl *This = (NSTC2Impl*)GetPropA(hWnd, "PROP_THIS");

    switch(uMessage) {
    case WM_KEYDOWN:
    case WM_KEYUP:
    case WM_CHAR:
    case WM_SYSKEYDOWN:
    case WM_SYSKEYUP:
    case WM_SYSCHAR:
        if(on_kbd_event(This, uMessage, wParam, lParam))
            return TRUE;
        break;

    case WM_MBUTTONUP:        return on_wm_mbuttonup(This, wParam, lParam);
    }

    /* Pass the message on to the treeview */
    return CallWindowProcW(This->tv_oldwndproc, hWnd, uMessage, wParam, lParam);
}

static LRESULT CALLBACK NSTC2_WndProc(HWND hWnd, UINT uMessage,
                                      WPARAM wParam, LPARAM lParam)
{
    NSTC2Impl *This = (NSTC2Impl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
    NMHDR *nmhdr;

    switch(uMessage)
    {
    case WM_NCCREATE:         return create_namespacetree(hWnd, (CREATESTRUCTW*)lParam);
    case WM_SIZE:             return resize_namespacetree(This);
    case WM_DESTROY:          return destroy_namespacetree(This);
    case WM_NOTIFY:
        nmhdr = (NMHDR*)lParam;
        switch(nmhdr->code)
        {
        case NM_CLICK:            return on_nm_click(This, nmhdr);
        case TVN_DELETEITEMW:     return on_tvn_deleteitemw(This, lParam);
        case TVN_GETDISPINFOW:    return on_tvn_getdispinfow(This, lParam);
        case TVN_ITEMEXPANDINGW:  return on_tvn_itemexpandingw(This, lParam);
        case TVN_ITEMEXPANDEDW:   return on_tvn_itemexpandedw(This, lParam);
        case TVN_SELCHANGEDW:     return on_tvn_selchangedw(This, lParam);
        default:                  break;
        }
        break;
    default:                  return DefWindowProcW(hWnd, uMessage, wParam, lParam);
    }
    return 0;
}

/**************************************************************************
 * INameSpaceTreeControl2 Implementation
 */
static HRESULT WINAPI NSTC2_fnQueryInterface(INameSpaceTreeControl2* iface,
                                             REFIID riid,
                                             void **ppvObject)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    TRACE("%p (%s, %p)\n", This, debugstr_guid(riid), ppvObject);

    *ppvObject = NULL;
    if(IsEqualIID(riid, &IID_INameSpaceTreeControl2) ||
       IsEqualIID(riid, &IID_INameSpaceTreeControl) ||
       IsEqualIID(riid, &IID_IUnknown))
    {
        *ppvObject = This;
    }
    else if(IsEqualIID(riid, &IID_IOleWindow))
    {
        *ppvObject = &This->IOleWindow_iface;
    }

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

    return E_NOINTERFACE;
}

static ULONG WINAPI NSTC2_fnAddRef(INameSpaceTreeControl2* iface)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    LONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI NSTC2_fnRelease(INameSpaceTreeControl2* iface)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    LONG ref = InterlockedDecrement(&This->ref);

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

    if(!ref)
    {
        TRACE("Freeing.\n");
        HeapFree(GetProcessHeap(), 0, This);
        EFRAME_UnlockModule();
        return 0;
    }

    return ref;
}

static HRESULT WINAPI NSTC2_fnInitialize(INameSpaceTreeControl2* iface,
                                         HWND hwndParent,
                                         RECT *prc,
                                         NSTCSTYLE nstcsFlags)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    WNDCLASSW wc;
    DWORD window_style, window_ex_style;
    RECT rc;
    static const WCHAR NSTC2_CLASS_NAME[] =
        {'N','a','m','e','s','p','a','c','e','T','r','e','e',
         'C','o','n','t','r','o','l',0};

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

    if(nstcsFlags & unsupported_styles)
        FIXME("0x%08x contains the unsupported style(s) 0x%08x\n",
              nstcsFlags, nstcsFlags & unsupported_styles);

    This->style = nstcsFlags;

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

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

    /* NSTCS_TABSTOP and NSTCS_BORDER affects the host window */
    window_style = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
        (nstcsFlags & NSTCS_BORDER ? WS_BORDER : 0);
    window_ex_style = nstcsFlags & NSTCS_TABSTOP ? WS_EX_CONTROLPARENT : 0;

    if(prc)
        CopyRect(&rc, prc);
    else
        rc.left = rc.right = rc.top = rc.bottom = 0;

    This->hwnd_main = CreateWindowExW(window_ex_style, NSTC2_CLASS_NAME, NULL, window_style,
                                      rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
                                      hwndParent, 0, explorerframe_hinstance, This);

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

    return S_OK;
}

static HRESULT WINAPI NSTC2_fnTreeAdvise(INameSpaceTreeControl2* iface,
                                         IUnknown *punk,
                                         DWORD *pdwCookie)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    HRESULT hr;
    TRACE("%p (%p, %p)\n", This, punk, pdwCookie);

    *pdwCookie = 0;

    /* Only one client supported */
    if(This->pnstce)
        return E_FAIL;

    hr = IUnknown_QueryInterface(punk, &IID_INameSpaceTreeControlEvents,(void**)&This->pnstce);
    if(SUCCEEDED(hr))
    {
        *pdwCookie = 1;
        return hr;
    }

    return E_FAIL;
}

static HRESULT WINAPI NSTC2_fnTreeUnadvise(INameSpaceTreeControl2* iface,
                                           DWORD dwCookie)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    TRACE("%p (%x)\n", This, dwCookie);

    /* The cookie is ignored. */

    if(This->pnstce)
    {
        INameSpaceTreeControlEvents_Release(This->pnstce);
        This->pnstce = NULL;
    }

    return S_OK;
}

static HRESULT WINAPI NSTC2_fnInsertRoot(INameSpaceTreeControl2* iface,
                                         int iIndex,
                                         IShellItem *psiRoot,
                                         SHCONTF grfEnumFlags,
                                         NSTCROOTSTYLE grfRootStyle,
                                         IShellItemFilter *pif)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    nstc_root *new_root;
    struct list *add_after_entry;
    HTREEITEM add_after_hitem;
    UINT i;

    TRACE("%p, %d, %p, %x, %x, %p\n", This, iIndex, psiRoot, grfEnumFlags, grfRootStyle, pif);

    new_root = HeapAlloc(GetProcessHeap(), 0, sizeof(nstc_root));
    if(!new_root)
        return E_OUTOFMEMORY;

    new_root->psi = psiRoot;
    new_root->enum_flags = grfEnumFlags;
    new_root->root_style = grfRootStyle;
    new_root->pif = pif;

    /* We want to keep the roots in the internal list and in the
     * treeview in the same order. */
    add_after_entry = &This->roots;
    for(i = 0; i < max(0, iIndex) && list_next(&This->roots, add_after_entry); i++)
        add_after_entry = list_next(&This->roots, add_after_entry);

    if(add_after_entry == &This->roots)
        add_after_hitem = TVI_FIRST;
    else
        add_after_hitem = LIST_ENTRY(add_after_entry, nstc_root, entry)->htreeitem;

    new_root->htreeitem = insert_shellitem(This, psiRoot, TVI_ROOT, add_after_hitem);
    if(!new_root->htreeitem)
    {
        WARN("Failed to add the root.\n");
        HeapFree(GetProcessHeap(), 0, new_root);
        return E_FAIL;
    }

    list_add_after(add_after_entry, &new_root->entry);
    events_OnItemAdded(This, psiRoot, TRUE);

    if(grfRootStyle & NSTCRS_HIDDEN)
    {
        TVITEMEXW tvi;
        tvi.mask = TVIF_STATEEX;
        tvi.uStateEx = TVIS_EX_FLAT;
        tvi.hItem = new_root->htreeitem;

        SendMessageW(This->hwnd_tv, TVM_SETITEMW, 0, (LPARAM)&tvi);
    }

    if(grfRootStyle & NSTCRS_EXPANDED)
        SendMessageW(This->hwnd_tv, TVM_EXPAND, TVE_EXPAND,
                     (LPARAM)new_root->htreeitem);

    return S_OK;
}

static HRESULT WINAPI NSTC2_fnAppendRoot(INameSpaceTreeControl2* iface,
                                         IShellItem *psiRoot,
                                         SHCONTF grfEnumFlags,
                                         NSTCROOTSTYLE grfRootStyle,
                                         IShellItemFilter *pif)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    UINT root_count;
    TRACE("%p, %p, %x, %x, %p\n",
          This, psiRoot, grfEnumFlags, grfRootStyle, pif);

    root_count = list_count(&This->roots);

    return NSTC2_fnInsertRoot(iface, root_count, psiRoot, grfEnumFlags, grfRootStyle, pif);
}

static HRESULT WINAPI NSTC2_fnRemoveRoot(INameSpaceTreeControl2* iface,
                                         IShellItem *psiRoot)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    nstc_root *cursor, *root = NULL;
    TRACE("%p (%p)\n", This, psiRoot);

    if(!psiRoot)
        return E_NOINTERFACE;

    LIST_FOR_EACH_ENTRY(cursor, &This->roots, nstc_root, entry)
    {
        HRESULT hr;
        int order;
        hr = IShellItem_Compare(psiRoot, cursor->psi, SICHINT_DISPLAY, &order);
        if(hr == S_OK)
        {
            root = cursor;
            break;
        }
    }

    TRACE("root %p\n", root);
    if(root)
    {
        events_OnItemDeleted(This, root->psi, TRUE);
        SendMessageW(This->hwnd_tv, TVM_DELETEITEM, 0, (LPARAM)root->htreeitem);
        list_remove(&root->entry);
        HeapFree(GetProcessHeap(), 0, root);
        return S_OK;
    }
    else
    {
        WARN("No matching root found.\n");
        return E_FAIL;
    }
}

static HRESULT WINAPI NSTC2_fnRemoveAllRoots(INameSpaceTreeControl2* iface)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    nstc_root *cur1, *cur2;
    UINT removed = 0;
    TRACE("%p\n", This);

    LIST_FOR_EACH_ENTRY_SAFE(cur1, cur2, &This->roots, nstc_root, entry)
    {
        NSTC2_fnRemoveRoot(iface, cur1->psi);
        removed++;
    }

    if(removed)
        return S_OK;
    else
        return E_INVALIDARG;
}

static HRESULT WINAPI NSTC2_fnGetRootItems(INameSpaceTreeControl2* iface,
                                           IShellItemArray **ppsiaRootItems)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    IShellFolder *psf;
    LPITEMIDLIST *array;
    nstc_root *root;
    UINT count, i;
    HRESULT hr;
    TRACE("%p (%p)\n", This, ppsiaRootItems);

    count = list_count(&This->roots);

    if(!count)
        return E_INVALIDARG;

    array = HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST*)*count);

    i = 0;
    LIST_FOR_EACH_ENTRY(root, &This->roots, nstc_root, entry)
        SHGetIDListFromObject((IUnknown*)root->psi, &array[i++]);

    SHGetDesktopFolder(&psf);
    hr = SHCreateShellItemArray(NULL, psf, count, (PCUITEMID_CHILD_ARRAY)array,
                                ppsiaRootItems);
    IShellFolder_Release(psf);

    for(i = 0; i < count; i++)
        ILFree(array[i]);

    HeapFree(GetProcessHeap(), 0, array);

    return hr;
}

static HRESULT WINAPI NSTC2_fnSetItemState(INameSpaceTreeControl2* iface,
                                           IShellItem *psi,
                                           NSTCITEMSTATE nstcisMask,
                                           NSTCITEMSTATE nstcisFlags)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    TVITEMEXW tvi;
    HTREEITEM hitem;

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

    hitem = treeitem_from_shellitem(This, psi);
    if(!hitem) return E_INVALIDARG;

    /* Passing both NSTCIS_SELECTED and NSTCIS_SELECTEDNOEXPAND results
       in two TVM_SETITEMW's */
    if((nstcisMask&nstcisFlags) & NSTCIS_SELECTED)
    {
        SendMessageW(This->hwnd_tv, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hitem);
        SendMessageW(This->hwnd_tv, TVM_ENSUREVISIBLE, 0, (LPARAM)hitem);
    }
    if((nstcisMask&nstcisFlags) & NSTCIS_SELECTEDNOEXPAND)
    {
        SendMessageW(This->hwnd_tv, TVM_SELECTITEM, TVGN_CARET|TVSI_NOSINGLEEXPAND, (LPARAM)hitem);
    }

    /* If NSTCIS_EXPANDED is among the flags, the mask is ignored. */
    if((nstcisMask|nstcisFlags) & NSTCIS_EXPANDED)
    {
        WPARAM arg = nstcisFlags&NSTCIS_EXPANDED ? TVE_EXPAND:TVE_COLLAPSE;
        SendMessageW(This->hwnd_tv, TVM_EXPAND, arg, (LPARAM)hitem);
    }

    if(nstcisMask & NSTCIS_DISABLED)
        tvi.mask = TVIF_STATE | TVIF_STATEEX;
    else if( ((nstcisMask^nstcisFlags) & (NSTCIS_SELECTED|NSTCIS_EXPANDED|NSTCIS_SELECTEDNOEXPAND)) ||
             ((nstcisMask|nstcisFlags) & NSTCIS_BOLD) ||
             (nstcisFlags & NSTCIS_DISABLED) )
        tvi.mask = TVIF_STATE;
    else
        tvi.mask = 0;

    if(tvi.mask)
    {
        tvi.stateMask = tvi.state = 0;
        tvi.stateMask |= ((nstcisFlags^nstcisMask)&NSTCIS_SELECTED) ? TVIS_SELECTED : 0;
        tvi.stateMask |= (nstcisMask|nstcisFlags)&NSTCIS_BOLD ? TVIS_BOLD:0;
        tvi.state     |= (nstcisMask&nstcisFlags)&NSTCIS_BOLD ? TVIS_BOLD:0;

        if((nstcisMask&NSTCIS_EXPANDED)^(nstcisFlags&NSTCIS_EXPANDED))
        {
            tvi.stateMask = 0;
        }

        tvi.uStateEx = (nstcisFlags&nstcisMask)&NSTCIS_DISABLED?TVIS_EX_DISABLED:0;
        tvi.hItem = hitem;

        SendMessageW(This->hwnd_tv, TVM_SETITEMW, 0, (LPARAM)&tvi);
    }

    return S_OK;
}

static HRESULT WINAPI NSTC2_fnGetItemState(INameSpaceTreeControl2* iface,
                                           IShellItem *psi,
                                           NSTCITEMSTATE nstcisMask,
                                           NSTCITEMSTATE *pnstcisFlags)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    HTREEITEM hitem;
    TVITEMEXW tvi;
    TRACE("%p (%p, %x, %p)\n", This, psi, nstcisMask, pnstcisFlags);

    hitem = treeitem_from_shellitem(This, psi);
    if(!hitem)
        return E_INVALIDARG;

    *pnstcisFlags = 0;

    tvi.hItem = hitem;
    tvi.mask = TVIF_STATE;
    tvi.stateMask = TVIS_SELECTED|TVIS_EXPANDED|TVIS_BOLD;

    if(nstcisMask & NSTCIS_DISABLED)
        tvi.mask |= TVIF_STATEEX;

    SendMessageW(This->hwnd_tv, TVM_GETITEMW, 0, (LPARAM)&tvi);
    *pnstcisFlags |= (tvi.state & TVIS_SELECTED)?NSTCIS_SELECTED:0;
    *pnstcisFlags |= (tvi.state & TVIS_EXPANDED)?NSTCIS_EXPANDED:0;
    *pnstcisFlags |= (tvi.state & TVIS_BOLD)?NSTCIS_BOLD:0;
    *pnstcisFlags |= (tvi.uStateEx & TVIS_EX_DISABLED)?NSTCIS_DISABLED:0;

    *pnstcisFlags &= nstcisMask;

    return S_OK;
}

static HRESULT WINAPI NSTC2_fnGetSelectedItems(INameSpaceTreeControl2* iface,
                                               IShellItemArray **psiaItems)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    IShellItem *psiselected;
    HRESULT hr;
    TRACE("%p (%p)\n", This, psiaItems);

    psiselected = get_selected_shellitem(This);
    if(!psiselected)
        return E_FAIL;

    hr = SHCreateShellItemArrayFromShellItem(psiselected, &IID_IShellItemArray,
                                             (void**)psiaItems);
    return hr;
}

static HRESULT WINAPI NSTC2_fnGetItemCustomState(INameSpaceTreeControl2* iface,
                                                 IShellItem *psi,
                                                 int *piStateNumber)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    FIXME("stub, %p (%p, %p)\n", This, psi, piStateNumber);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTC2_fnSetItemCustomState(INameSpaceTreeControl2* iface,
                                                 IShellItem *psi,
                                                 int iStateNumber)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    FIXME("stub, %p (%p, %d)\n", This, psi, iStateNumber);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTC2_fnEnsureItemVisible(INameSpaceTreeControl2* iface,
                                                IShellItem *psi)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    HTREEITEM hitem;

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

    hitem = treeitem_from_shellitem(This, psi);
    if(hitem)
    {
        SendMessageW(This->hwnd_tv, TVM_ENSUREVISIBLE, 0, (WPARAM)hitem);
        return S_OK;
    }

    return E_INVALIDARG;
}

static HRESULT WINAPI NSTC2_fnSetTheme(INameSpaceTreeControl2* iface,
                                       LPCWSTR pszTheme)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    FIXME("stub, %p (%p)\n", This, pszTheme);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTC2_fnGetNextItem(INameSpaceTreeControl2* iface,
                                          IShellItem *psi,
                                          NSTCGNI nstcgi,
                                          IShellItem **ppsiNext)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    HTREEITEM hitem, hnext;
    UINT tvgn;
    TRACE("%p (%p, %x, %p)\n", This, psi, nstcgi, ppsiNext);

    if(!ppsiNext) return E_POINTER;
    if(!psi)      return E_FAIL;

    *ppsiNext = NULL;

    hitem = treeitem_from_shellitem(This, psi);
    if(!hitem)
        return E_INVALIDARG;

    switch(nstcgi)
    {
    case NSTCGNI_NEXT:         tvgn = TVGN_NEXT; break;
    case NSTCGNI_NEXTVISIBLE:  tvgn = TVGN_NEXTVISIBLE; break;
    case NSTCGNI_PREV:         tvgn = TVGN_PREVIOUS; break;
    case NSTCGNI_PREVVISIBLE:  tvgn = TVGN_PREVIOUSVISIBLE; break;
    case NSTCGNI_PARENT:       tvgn = TVGN_PARENT; break;
    case NSTCGNI_CHILD:        tvgn = TVGN_CHILD; break;
    case NSTCGNI_FIRSTVISIBLE: tvgn = TVGN_FIRSTVISIBLE; break;
    case NSTCGNI_LASTVISIBLE:  tvgn = TVGN_LASTVISIBLE; break;
    default:
        FIXME("Unknown nstcgi value %d\n", nstcgi);
        return E_FAIL;
    }

    hnext = (HTREEITEM)SendMessageW(This->hwnd_tv, TVM_GETNEXTITEM, tvgn, (WPARAM)hitem);
    if(hnext)
    {
        *ppsiNext = shellitem_from_treeitem(This, hnext);
        IShellItem_AddRef(*ppsiNext);
        return S_OK;
    }

    return E_FAIL;
}

static HRESULT WINAPI NSTC2_fnHitTest(INameSpaceTreeControl2* iface,
                                      POINT *ppt,
                                      IShellItem **ppsiOut)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    HTREEITEM hitem;
    TRACE("%p (%p, %p)\n", This, ppsiOut, ppt);

    if(!ppt || !ppsiOut)
        return E_POINTER;

    *ppsiOut = NULL;

    hitem = treeitem_from_point(This, ppt, NULL);
    if(hitem)
        *ppsiOut = shellitem_from_treeitem(This, hitem);

    if(*ppsiOut)
    {
        IShellItem_AddRef(*ppsiOut);
        return S_OK;
    }

    return S_FALSE;
}

static HRESULT WINAPI NSTC2_fnGetItemRect(INameSpaceTreeControl2* iface,
                                          IShellItem *psi,
                                          RECT *prect)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    HTREEITEM hitem;
    TRACE("%p (%p, %p)\n", This, psi, prect);

    if(!psi || !prect)
        return E_POINTER;

    hitem = treeitem_from_shellitem(This, psi);
    if(hitem)
    {
        *(HTREEITEM*)prect = hitem;
        if(SendMessageW(This->hwnd_tv, TVM_GETITEMRECT, FALSE, (LPARAM)prect))
        {
            MapWindowPoints(This->hwnd_tv, HWND_DESKTOP, (POINT*)prect, 2);
            return S_OK;
        }
    }

    return E_INVALIDARG;
}

static HRESULT WINAPI NSTC2_fnCollapseAll(INameSpaceTreeControl2* iface)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    nstc_root *root;
    TRACE("%p\n", This);

    LIST_FOR_EACH_ENTRY(root, &This->roots, nstc_root, entry)
        collapse_all(This, root->htreeitem);

    return S_OK;
}

static HRESULT WINAPI NSTC2_fnSetControlStyle(INameSpaceTreeControl2* iface,
                                              NSTCSTYLE nstcsMask,
                                              NSTCSTYLE nstcsStyle)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    static const DWORD tv_style_flags =
        NSTCS_HASEXPANDOS | NSTCS_HASLINES | NSTCS_FULLROWSELECT |
        NSTCS_HORIZONTALSCROLL | NSTCS_ROOTHASEXPANDO |
        NSTCS_SHOWSELECTIONALWAYS | NSTCS_NOINFOTIP | NSTCS_EVENHEIGHT |
        NSTCS_DISABLEDRAGDROP | NSTCS_NOEDITLABELS | NSTCS_CHECKBOXES;
    static const DWORD host_style_flags = NSTCS_TABSTOP | NSTCS_BORDER;
    static const DWORD nstc_flags =
        NSTCS_SINGLECLICKEXPAND | NSTCS_NOREPLACEOPEN | NSTCS_NOORDERSTREAM |
        NSTCS_FAVORITESMODE | NSTCS_EMPTYTEXT | NSTCS_ALLOWJUNCTIONS |
        NSTCS_SHOWTABSBUTTON | NSTCS_SHOWDELETEBUTTON | NSTCS_SHOWREFRESHBUTTON;
    TRACE("%p (%x, %x)\n", This, nstcsMask, nstcsStyle);

    /* Fail if there is an attempt to set an unknown style. */
    if(nstcsMask & ~(tv_style_flags | host_style_flags | nstc_flags))
        return E_FAIL;

    if(nstcsMask & tv_style_flags)
    {
        DWORD new_style;
        treeview_style_from_nstcs(This, nstcsStyle, nstcsMask, &new_style);
        SetWindowLongPtrW(This->hwnd_tv, GWL_STYLE, new_style);
    }

    /* Flags affecting the host window */
    if(nstcsMask & NSTCS_BORDER)
    {
        DWORD new_style = GetWindowLongPtrW(This->hwnd_main, GWL_STYLE);
        new_style &= ~WS_BORDER;
        new_style |= nstcsStyle & NSTCS_BORDER ? WS_BORDER : 0;
        SetWindowLongPtrW(This->hwnd_main, GWL_STYLE, new_style);
    }
    if(nstcsMask & NSTCS_TABSTOP)
    {
        DWORD new_style = GetWindowLongPtrW(This->hwnd_main, GWL_EXSTYLE);
        new_style &= ~WS_EX_CONTROLPARENT;
        new_style |= nstcsStyle & NSTCS_TABSTOP ? WS_EX_CONTROLPARENT : 0;
        SetWindowLongPtrW(This->hwnd_main, GWL_EXSTYLE, new_style);
    }

    if((nstcsStyle & nstcsMask) & unsupported_styles)
        FIXME("mask & style (0x%08x) contains unsupported style(s): 0x%08x\n",
              (nstcsStyle & nstcsMask),
              (nstcsStyle & nstcsMask) & unsupported_styles);

    This->style &= ~nstcsMask;
    This->style |= (nstcsStyle & nstcsMask);

    return S_OK;
}

static HRESULT WINAPI NSTC2_fnGetControlStyle(INameSpaceTreeControl2* iface,
                                              NSTCSTYLE nstcsMask,
                                              NSTCSTYLE *pnstcsStyle)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    TRACE("%p (%x, %p)\n", This, nstcsMask, pnstcsStyle);

    *pnstcsStyle = (This->style & nstcsMask);

    return S_OK;
}

static HRESULT WINAPI NSTC2_fnSetControlStyle2(INameSpaceTreeControl2* iface,
                                               NSTCSTYLE2 nstcsMask,
                                               NSTCSTYLE2 nstcsStyle)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    TRACE("%p (%x, %x)\n", This, nstcsMask, nstcsStyle);

    if((nstcsStyle & nstcsMask) & unsupported_styles2)
        FIXME("mask & style (0x%08x) contains unsupported style(s): 0x%08x\n",
              (nstcsStyle & nstcsMask),
              (nstcsStyle & nstcsMask) & unsupported_styles2);

    This->style2 &= ~nstcsMask;
    This->style2 |= (nstcsStyle & nstcsMask);

    return S_OK;
}

static HRESULT WINAPI NSTC2_fnGetControlStyle2(INameSpaceTreeControl2* iface,
                                               NSTCSTYLE2 nstcsMask,
                                               NSTCSTYLE2 *pnstcsStyle)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);
    TRACE("%p (%x, %p)\n", This, nstcsMask, pnstcsStyle);

    *pnstcsStyle = (This->style2 & nstcsMask);

    return S_OK;
}

static const INameSpaceTreeControl2Vtbl vt_INameSpaceTreeControl2 = {
    NSTC2_fnQueryInterface,
    NSTC2_fnAddRef,
    NSTC2_fnRelease,
    NSTC2_fnInitialize,
    NSTC2_fnTreeAdvise,
    NSTC2_fnTreeUnadvise,
    NSTC2_fnAppendRoot,
    NSTC2_fnInsertRoot,
    NSTC2_fnRemoveRoot,
    NSTC2_fnRemoveAllRoots,
    NSTC2_fnGetRootItems,
    NSTC2_fnSetItemState,
    NSTC2_fnGetItemState,
    NSTC2_fnGetSelectedItems,
    NSTC2_fnGetItemCustomState,
    NSTC2_fnSetItemCustomState,
    NSTC2_fnEnsureItemVisible,
    NSTC2_fnSetTheme,
    NSTC2_fnGetNextItem,
    NSTC2_fnHitTest,
    NSTC2_fnGetItemRect,
    NSTC2_fnCollapseAll,
    NSTC2_fnSetControlStyle,
    NSTC2_fnGetControlStyle,
    NSTC2_fnSetControlStyle2,
    NSTC2_fnGetControlStyle2
};

/**************************************************************************
 * IOleWindow Implementation
 */

static HRESULT WINAPI IOW_fnQueryInterface(IOleWindow *iface, REFIID riid, void **ppvObject)
{
    NSTC2Impl *This = impl_from_IOleWindow(iface);
    TRACE("%p\n", This);
    return NSTC2_fnQueryInterface(&This->INameSpaceTreeControl2_iface, riid, ppvObject);
}

static ULONG WINAPI IOW_fnAddRef(IOleWindow *iface)
{
    NSTC2Impl *This = impl_from_IOleWindow(iface);
    TRACE("%p\n", This);
    return NSTC2_fnAddRef(&This->INameSpaceTreeControl2_iface);
}

static ULONG WINAPI IOW_fnRelease(IOleWindow *iface)
{
    NSTC2Impl *This = impl_from_IOleWindow(iface);
    TRACE("%p\n", This);
    return NSTC2_fnRelease(&This->INameSpaceTreeControl2_iface);
}

static HRESULT WINAPI IOW_fnGetWindow(IOleWindow *iface, HWND *phwnd)
{
    NSTC2Impl *This = impl_from_IOleWindow(iface);
    TRACE("%p (%p)\n", This, phwnd);

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

static HRESULT WINAPI IOW_fnContextSensitiveHelp(IOleWindow *iface, BOOL fEnterMode)
{
    NSTC2Impl *This = impl_from_IOleWindow(iface);
    TRACE("%p (%d)\n", This, fEnterMode);

    /* Not implemented */
    return E_NOTIMPL;
}

static const IOleWindowVtbl vt_IOleWindow = {
    IOW_fnQueryInterface,
    IOW_fnAddRef,
    IOW_fnRelease,
    IOW_fnGetWindow,
    IOW_fnContextSensitiveHelp
};

HRESULT NamespaceTreeControl_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
{
    NSTC2Impl *nstc;
    HRESULT ret;

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

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

    EFRAME_LockModule();

    nstc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NSTC2Impl));
    nstc->ref = 1;
    nstc->INameSpaceTreeControl2_iface.lpVtbl = &vt_INameSpaceTreeControl2;
    nstc->IOleWindow_iface.lpVtbl = &vt_IOleWindow;

    list_init(&nstc->roots);

    ret = INameSpaceTreeControl_QueryInterface((INameSpaceTreeControl*)nstc, riid, ppv);
    INameSpaceTreeControl_Release((INameSpaceTreeControl*)nstc);

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