// LocalTreeCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "ConsoleApp.h"
#include "LocalTreeCtrl.h"

#include "MainFrm.h"
#include "LocalView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

BOOL DeleteDirectory(CString sDirectory);

/////////////////////////////////////////////////////////////////////////////
// CLocalTreeCtrl

CLocalTreeCtrl::CLocalTreeCtrl()
{
}

CLocalTreeCtrl::~CLocalTreeCtrl()
{
}

#ifdef _USE_XTREME_TOOLKITPRO
BEGIN_MESSAGE_MAP(CLocalTreeCtrl, CXTShellTreeCtrl)
#else // _USE_XTREME_TOOLKITPRO
BEGIN_MESSAGE_MAP(CLocalTreeCtrl, CTreeCtrl)
#endif // _USE_XTREME_TOOLKITPRO
	//{{AFX_MSG_MAP(CLocalTreeCtrl)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLocalTreeCtrl message handlers

BOOL CLocalTreeCtrl::PreTranslateMessage(MSG* pMsg)
{
	CMainFrame *pmf = (CMainFrame *)AfxGetMainWnd();

	switch (pMsg->message)
	{
	case WM_SETFOCUS:
	case WM_LBUTTONDOWN:
	case WM_RBUTTONDOWN:
		pmf->SetFocus(this);
		break;
	case WM_KEYDOWN:
		if (GetKeyState(VK_CONTROL) & 128) {
			if (pMsg->wParam == VK_D) {
				DeleteSelectedItem();
				return TRUE;
			}
			else if (pMsg->wParam == VK_V) {
				if (PasteClipboard())
					return TRUE;
			}
		}
		break;
	}

	return CTreeCtrl::PreTranslateMessage(pMsg);
}

void CLocalTreeCtrl::DeleteSelectedItem()
{
#ifndef _USE_XTREME_TOOLKITPRO
	IPTxShTreeNode* pnode = (IPTxShTreeNode*)get_SelectedNode();
	if (((CLocalView*)GetParent())->m_pnodeRoot == pnode)
		return;

	if (AfxMessageBox("선택된 폴더를 삭제하시겠습니까?", MB_YESNO) != IDYES)
		return;

	VARIANT_BOOL bFileSystem;

	pnode->get_IsFileSystem(&bFileSystem);
	if (bFileSystem) {
		BSTR bstr;
		pnode->get_PathName(&bstr);
		CString sPath(bstr);
		::SysFreeString(bstr);

		if (sPath == "")
			return;

		if (!DeleteDirectory(sPath))
			return;

		Refresh();
	}
#endif // !_USE_XTREME_TOOLKITPRO
}

BOOL CLocalTreeCtrl::PasteClipboard()
{
	CMainFrame* pmf = (CMainFrame*)AfxGetMainWnd();

#ifndef  _USE_XTREME_TOOLKITPRO 
	VARIANT_BOOL bFileSystem;

	IPTxShTreeNode *pnode = (IPTxShTreeNode*)get_SelectedNode();
	pnode->get_IsFileSystem(&bFileSystem);
	if (!bFileSystem)
		return FALSE;

	BSTR bstr;
	pnode->get_PathName(&bstr);
	CString sPath(bstr);
	::SysFreeString(bstr);

	COleDataObject odo;

	if (odo.AttachClipboard() && odo.IsDataAvailable(CF_HDROP))
		return ((CLocalView*)GetParent())->CopyClipboard(odo, sPath);

	if (pmf->m_cbs == CBS_NONE)
		return FALSE;

	if (pmf->m_saDragSource.GetCount() == 0)
		return FALSE;

	pmf->m_sDragTarget = sPath;
#endif // !_USE_XTREME_TOOLKITPRO
	return pmf->Download(false);
}
#ifdef _USE_XTREME_TOOLKITPRO
BOOL CLocalTreeCtrl::InitTreeViewItems(LPSHELLFOLDER lpsf, LPITEMIDLIST lpifq, HTREEITEM hParent)
{
	CWaitCursor wait; // show wait cursor.

	// Allocate a shell memory object.
	CShellMalloc lpMalloc;

	if (!lpMalloc)
		return FALSE;

	// Get the IEnumIDList object for the given folder.
	LPENUMIDLIST lpe = NULL;
	if (FAILED(lpsf->EnumObjects(::GetParent(m_pTreeCtrl->m_hWnd), m_uFlags, &lpe)))
		return FALSE;

	if (lpe == NULL)
		return FALSE;

	ULONG        ulFetched = 0;
	HTREEITEM    hPrev = NULL;
	LPITEMIDLIST lpi = NULL;

	// Enumerate through the list of folder and non-folder objects.
	while (lpe->Next(1, &lpi, &ulFetched) == S_OK)
	{
		// Create a fully qualified path to the current item
		// the SH* shell api's take a fully qualified path pidl,
		// (see GetIcon above where I call SHGetFileInfo) whereas the
		// interface methods take a relative path pidl.
		ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_DISPLAYATTRMASK | SFGAO_REMOVABLE | SFGAO_COMPRESSED | SFGAO_ENCRYPTED;

		// Determine what type of object we have.
		lpsf->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lpi, &ulAttrs);

		// We need this next if statement so that we don't add things like
		// the MSN to our tree.  MSN is not a folder, but according to the
		// shell it has subfolders.
		if ((ulAttrs & SFGAO_FOLDER) || m_bShowFiles)
		{
			TV_ITEM  tvi;
			tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;

			if ((ulAttrs & SFGAO_HASSUBFOLDER) || (m_bShowFiles && (ulAttrs & SFGAO_FOLDER)))
			{
				//This item has sub-folders, so let's put the + in the TreeView.
				//The first time the user clicks on the item, we'll populate the
				//sub-folders.
				tvi.cChildren = 1;
				tvi.mask |= TVIF_CHILDREN;
			}

			// Allocate memory for ITEMDATA struct
			CString szBuff;
			XT_TVITEMDATA* lptvid = (XT_TVITEMDATA*)lpMalloc.Alloc(sizeof(XT_TVITEMDATA));
			if (lptvid == NULL || GetName(lpsf, lpi, SHGDN_NORMAL, szBuff) == FALSE)
			{
				if (lptvid)
				{
					lpMalloc.Free(lptvid);
				}
				if (lpe)
				{
					lpe->Release();
				}
				if (lpi)
				{
					lpMalloc.Free(lpi);
				}
				return FALSE;
			}


			// Now, make a copy of the ITEMIDLIST and store the parent folders SF.
			lptvid->lpi = DuplicateItem(lpMalloc, lpi);
			lptvid->lpsfParent = lpsf;
			lptvid->lpifq = ConcatPidls(lpMalloc, lpifq, lpi);
			lpsf->AddRef();

			GetNormalAndSelectedIcons(lptvid->lpifq, &tvi);

			tvi.lParam = (LPARAM)lptvid;
			tvi.pszText = (LPTSTR)(LPCTSTR)szBuff;
			tvi.cchTextMax = 0;

			// Populate the TreeVeiw Insert Struct
			// The item is the one filled above.
			// Insert it after the last item inserted at this level.
			// And indicate this is a root entry.
			TV_INSERTSTRUCT tvins;
			tvins.item = tvi;
			tvins.hInsertAfter = hPrev;
			tvins.hParent = hParent;

			// Add the item to the tree
			hPrev = m_pTreeCtrl->InsertItem(&tvins);
			SetAttributes(hPrev, ulAttrs);
		}

		// Free the pidl that the shell gave us.
		if (lpi)
		{
			lpMalloc.Free(lpi);
			lpi = 0;
		}
	}
	if (lpi)
	{
		lpMalloc.Free(lpi);
	}

	if (lpe)
	{
		lpe->Release();
	}

	return TRUE;
}
#endif // _USE_XTREME_TOOLKITPRO