/*
 * 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");
    }

    INameSpaceTreeControl2_AddRef(&This->INameSpaceTreeControl2_iface);

    /* 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");
    }

    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;
    }
    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 = INameSpaceTreeControl2_QueryInterface(&nstc->INameSpaceTreeControl2_iface, riid, ppv);
    INameSpaceTreeControl2_Release(&nstc->INameSpaceTreeControl2_iface);

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