// PNDriveList.cpp : implementation file
//

#include "stdafx.h"
#include "mfc_cmncontrol.h"
#include "PNDriveList.h"

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

/////////////////////////////////////////////////////////////////////////////
// CPNDriveList

CPNDriveList::CPNDriveList()
{
	m_LargeIcons = FALSE;
}

CPNDriveList::~CPNDriveList()
{
	
}


BEGIN_MESSAGE_MAP(CPNDriveList, CListCtrl)
	//{{AFX_MSG_MAP(CPNDriveList)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPNDriveList message handlers

void CPNDriveList::PreSubclassWindow() 
{
	Populate();	
	CListCtrl::PreSubclassWindow();
}

BOOL CPNDriveList::GetDriveIcons(const char *Path, int &iIcon, int &iIconSel )
{
	SHFILEINFO shFileInfo;
	CString strPath;
	int ImageSize = m_LargeIcons ? SHGFI_LARGEICON : SHGFI_SMALLICON;

	// Make sure path has an ending slash or doesn't
	strPath = Path;
	char Ch = strPath.GetAt( strPath.GetLength()-1 );
	if( Ch!='\\' && Ch!='/' )
	{
		if( strPath.Find( '/' ) >=0 )
			strPath +="/";
		else
			strPath +="\\";
	}

	// Get icons for the path
	HIMAGELIST hImageList = (HIMAGELIST)SHGetFileInfo( strPath, 0, &shFileInfo, sizeof( shFileInfo ), SHGFI_SYSICONINDEX | SHGFI_ICON | ImageSize );
	if(  hImageList == 0 )
		return( FALSE );
	iIcon = shFileInfo.iIcon;
	if( SHGetFileInfo( strPath, 0, &shFileInfo, sizeof( shFileInfo ), 
		SHGFI_SYSICONINDEX | SHGFI_SELECTED | ImageSize ) == 0 )
		return( FALSE );
	iIconSel = shFileInfo.iIcon;

	// Release our duplicate image list, and update it with
	// new version of system image list.
	m_ImageList.DeleteImageList();
	m_ImageList.Attach( ImageList_Duplicate(hImageList) );

	return( TRUE );

}

void CPNDriveList::PopulateDrives()
{
	BOOL LargeSize;

	if( m_LargeIcons )
		LargeSize = TRUE;
	else
		LargeSize = FALSE;

	// Setup ListView appearance - Columns
	DeleteAllItems();
	CHeaderCtrl* Hdr;
	Hdr = GetHeaderCtrl();
	if( Hdr->GetSafeHwnd() )
	{
		while( Hdr->GetItemCount() )
			Hdr->DeleteItem(0);
	}
	InsertColumn( 0, "Drives" );
	CRect Rect;
	GetClientRect( &Rect );
	SetColumnWidth( 0, Rect.Width() );
	

	// Determine valid drive letters
	char Drives[128], *pRoot;
	char Volume[64], FileSystem[64];
	CString Descr;
	DWORD Flags, MaxLength;
	int iIcon, iIconSel;
	int Row=0;
	
	GetLogicalDriveStrings( sizeof(Drives), Drives );

	// Iterate through drive letters, determine icons, and add to list view control
	for( pRoot=Drives; *pRoot; pRoot++ )
	{
		switch( GetDriveType( pRoot ) )
		{
			case DRIVE_UNKNOWN:
				Descr.Format( "%c: Unknown", *pRoot );
				break;
			case DRIVE_NO_ROOT_DIR:
				Descr.Format( "%c: Can't determine", *pRoot );
				break;
			case DRIVE_REMOVABLE:
				Descr.Format( "%c: Removable", *pRoot );
				break;
			case DRIVE_FIXED:
				Descr.Format( "%c: Fixed", *pRoot );
				break;
			case DRIVE_REMOTE:
				GetVolumeInformation( pRoot, Volume, sizeof(Volume),
					NULL, &MaxLength, &Flags, FileSystem, sizeof(FileSystem) );
				Descr.Format( "%c: Network drive %s (%s)", *pRoot, Volume, FileSystem );
				break;
			case DRIVE_CDROM:
				Descr.Format( "%c: CD-ROM", *pRoot );
				break;

			case DRIVE_RAMDISK:
				Descr.Format( "%c: RAM Disk", *pRoot );
				break;
		}
		
		// Determine system image for drive
		GetDriveIcons( pRoot, iIcon, iIconSel );
		InsertItem( Row++, Descr, iIcon );

		while( *pRoot )
			pRoot++;
	}
}

void CPNDriveList::GetSysImageList()
{
	//if( m_ImageList.GetSafeHandle() )
	//	return;

	char Drives[128];
	SHFILEINFO shFileInfo;
	int LargeIcon = m_LargeIcons ?  TRUE : FALSE;

	// Get list of drives on the system
	GetLogicalDriveStrings( sizeof(Drives), Drives );

	HIMAGELIST hImageList;

	// Call SHGetFileInfo to retrieve the system image list
	hImageList = (HIMAGELIST)SHGetFileInfo( Drives, 0, &shFileInfo, sizeof( shFileInfo ),
		SHGFI_SYSICONINDEX | (LargeIcon?SHGFI_LARGEICON:SHGFI_SMALLICON) );

	// Set our Image list to be a duplicate of system image list
	m_ImageList.Attach( ImageList_Duplicate(hImageList) );

}

void CPNDriveList::Populate()
{
	if( GetWindowLong( m_hWnd, GWL_STYLE ) & (LVS_SMALLICON|LVS_REPORT) )
		m_LargeIcons = FALSE;
	else
		m_LargeIcons = TRUE;

	GetSysImageList();
	SetImageList( &m_ImageList, m_LargeIcons?LVSIL_NORMAL:LVSIL_SMALL );
	PopulateDrives();
}
