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

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

    INameSpaceTreeControlCustomDraw *customdraw;
    INameSpaceTreeControlDropHandler *dragdrop;
    INameSpaceTreeControlEvents *events;
} 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->events) return E_NOTIMPL;

    refcount = IShellItem_AddRef(psi);
    ret = INameSpaceTreeControlEvents_OnGetDefaultIconIndex(This->events, 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->events) return S_OK;

    refcount = IShellItem_AddRef(psi);
    ret = INameSpaceTreeControlEvents_OnItemAdded(This->events, 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->events) return S_OK;

    refcount = IShellItem_AddRef(psi);
    ret = INameSpaceTreeControlEvents_OnItemDeleted(This->events, 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->events) return S_OK;

    refcount = IShellItem_AddRef(psi);
    ret = INameSpaceTreeControlEvents_OnBeforeExpand(This->events, 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->events) return S_OK;

    refcount = IShellItem_AddRef(psi);
    ret = INameSpaceTreeControlEvents_OnAfterExpand(This->events, 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->events) return S_OK;

    refcount = IShellItem_AddRef(psi);
    ret = INameSpaceTreeControlEvents_OnItemClick(This->events, 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->events) return S_OK;

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

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

    return INameSpaceTreeControlEvents_OnKeyboardInput(This->events, 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");
    }

    INameSpaceTreeControl2_AddRef(&This->INameSpaceTreeControl2_iface);

    /* Subclass the treeview to get the keyboard 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");
    }

    INameSpaceTreeControl2_RemoveAllRoots(&This->INameSpaceTreeControl2_iface);

    /* This reference was added in create_namespacetree */
    INameSpaceTreeControl2_Release(&This->INameSpaceTreeControl2_iface);
    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->INameSpaceTreeControl2_iface;
    }
    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;
    INITCOMMONCONTROLSEX icex;
    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;

    icex.dwSize = sizeof( icex );
    icex.dwICC = ICC_TREEVIEW_CLASSES;
    InitCommonControlsEx( &icex );

    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)
        rc = *prc;
    else
        SetRectEmpty(&rc);

    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 *handler, DWORD *cookie)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);

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

    *cookie = 0;

    /* Only one client supported */
    if (This->events || This->customdraw || This->dragdrop)
        return E_FAIL;

    /* FIXME: request INameSpaceTreeAccessible too */
    IUnknown_QueryInterface(handler, &IID_INameSpaceTreeControlEvents, (void**)&This->events);
    IUnknown_QueryInterface(handler, &IID_INameSpaceTreeControlCustomDraw, (void**)&This->customdraw);
    IUnknown_QueryInterface(handler, &IID_INameSpaceTreeControlDropHandler, (void**)&This->dragdrop);

    if (This->events || This->customdraw || This->dragdrop)
        *cookie = 1;

    return *cookie ? S_OK : E_FAIL;
}

static HRESULT WINAPI NSTC2_fnTreeUnadvise(INameSpaceTreeControl2* iface, DWORD cookie)
{
    NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface);

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

    /* The cookie is ignored. */

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

    if (This->customdraw)
    {
        INameSpaceTreeControlCustomDraw_Release(This->customdraw);
        This->customdraw = NULL;
    }

    if (This->dragdrop)
    {
        INameSpaceTreeControlDropHandler_Release(This->dragdrop);
        This->dragdrop = 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;
    int 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 INameSpaceTreeControl2_InsertRoot(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;

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

    if (list_empty(&This->roots))
        return E_INVALIDARG;

    LIST_FOR_EACH_ENTRY_SAFE(cur1, cur2, &This->roots, nstc_root, entry)
        INameSpaceTreeControl2_RemoveRoot(iface, cur1->psi);

    return S_OK;
}

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;

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

    psiselected = get_selected_shellitem(This);
    if(!psiselected)
    {
        *psiaItems = NULL;
        return E_FAIL;
    }

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

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);
    return INameSpaceTreeControl2_QueryInterface(&This->INameSpaceTreeControl2_iface, riid, ppvObject);
}

static ULONG WINAPI IOW_fnAddRef(IOleWindow *iface)
{
    NSTC2Impl *This = impl_from_IOleWindow(iface);
    return INameSpaceTreeControl2_AddRef(&This->INameSpaceTreeControl2_iface);
}

static ULONG WINAPI IOW_fnRelease(IOleWindow *iface)
{
    NSTC2Impl *This = impl_from_IOleWindow(iface);
    return INameSpaceTreeControl2_Release(&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));
    if (!nstc)
        return E_OUTOFMEMORY;

    nstc->ref = 1;
    nstc->INameSpaceTreeControl2_iface.lpVtbl = &vt_INameSpaceTreeControl2;
    nstc->IOleWindow_iface.lpVtbl = &vt_IOleWindow;

    list_init(&nstc->roots);

    ret = INameSpaceTreeControl2_QueryInterface(&nstc->INameSpaceTreeControl2_iface, riid, ppv);
    INameSpaceTreeControl2_Release(&nstc->INameSpaceTreeControl2_iface);

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