/*****************************************************************************\
    FILE: ftpdhlp.cpp
    
    DESCRIPTION:
        Replace strings in a dialog template with attributes about an FTP
    item (ftp server, ftp dir, or ftp file).
\*****************************************************************************/

#include "priv.h"
#include "ftpurl.h"
#include "ftpdhlp.h"

#define SZ_WSPRINTFSTR_S            TEXT("%s")
#define SZ_WSPRINTFSTR_U            TEXT("%u")



class CSizeHolder
{
public:
    BOOL IsAllFolders(void) {return m_fAllFolders;};
    void FoundNonFolder(void) {m_fAllFolders = FALSE;};

    HRESULT GetError(void) {return m_hr;};
    void SetError(HRESULT hr) {m_hr = hr;};

    void AddSize(ULONGLONG ullSizeToAdd) { m_ullTotalSize += ullSizeToAdd;};
    ULONGLONG GetTotalSize(void) {return m_ullTotalSize;};

    CSizeHolder() {m_ullTotalSize = 0; m_fAllFolders = TRUE; m_hr = S_OK;};
    ~CSizeHolder() {};

private:
    BOOL    m_fAllFolders;
    HRESULT m_hr;
    ULONGLONG   m_ullTotalSize;
};



HRESULT CFtpDialogTemplate::_ReinsertDlgText(HWND hwnd, LPCVOID pv, LPCTSTR ptszFormat)
{
    TCHAR szDlgTemplate[256];
    TCHAR szFinalString[1024];            // wnsprintf maxes at 1024
    
    GetWindowText(hwnd, szDlgTemplate, ARRAYSIZE(szDlgTemplate));
    wnsprintf(szFinalString, ARRAYSIZE(szFinalString), szDlgTemplate, pv);
    
    // Are they the same?
    if (!StrCmp(szDlgTemplate, szFinalString))
        wnsprintf(szFinalString, ARRAYSIZE(szFinalString), ptszFormat, pv); // Yes
    
    SetWindowText(hwnd, szFinalString);
    return S_OK;
}


/*****************************************************************************\
    FUNCTION: _ReplaceIcon
    
    DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpDialogTemplate::_ReplaceIcon(HWND hwnd, HICON hicon)
{
    hicon = (HICON)SendMessage(hwnd, STM_SETICON, (WPARAM)hicon, 0L);
    if (hicon)
    {
        DestroyIcon(hicon);
    }
    return S_OK;
}

/*****************************************************************************\
    FUNCTION: _InitIcon
    
    DESCRIPTION:
        _HACKHACK_  We go straight to CFtpIcon to get the pxi
    instead of going through CFtpFolder.  Same effect, but
    saves some memory allocations.  What's more important,
    we don't necessarily have a psf to play with, so we really
    have no choice.

    Yes, it's gross.
\*****************************************************************************/
HRESULT CFtpDialogTemplate::_InitIcon(HWND hwnd, CFtpFolder * pff, CFtpPidlList * pflHfpl)
{
    IExtractIcon * pxi;
    HRESULT hr;
    
    if (pflHfpl && pflHfpl->GetCount() == 1)
    {
        SHFILEINFO sfi;
        hr = FtpPidl_GetFileInfo(pflHfpl->GetPidl(0), &sfi, SHGFI_ICON | SHGFI_LARGEICON);
        if (SUCCEEDED(hr))
            hr = _ReplaceIcon(hwnd, sfi.hIcon);
    }
    else
    {
        hr = CFtpIcon_Create(pff, pflHfpl, IID_IExtractIcon, (LPVOID *)&pxi);
        if (SUCCEEDED(hr))
        {
            TCHAR szPath[MAX_PATH];
            int i;
            UINT ui;
            
            hr = pxi->GetIconLocation(0, szPath, ARRAYSIZE(szPath), &i, &ui);
            if (EVAL(SUCCEEDED(hr)))
            {
                CHAR szPathAnsi[MAX_PATH];
                
                SHTCharToAnsi(szPath, szPathAnsi, ARRAYSIZE(szPathAnsi));
                hr = _ReplaceIcon(hwnd, ExtractIconA(g_hinst, szPathAnsi, i));
            }
            
            ASSERT(pxi);
            pxi->Release();
        }
    }
    
    return hr;
}


void GetItemName(CFtpFolder * pff, CFtpPidlList * pflHfpl, LPWSTR pwzName, DWORD cchSize)
{
    // Are multiple items selected?
    if (1 < pflHfpl->GetCount())
        LoadString(HINST_THISDLL, IDS_SEVERAL_SELECTED, pwzName, cchSize);
    else
    {
        LPCITEMIDLIST pidl;
    
        if (0 == pflHfpl->GetCount())
            pidl = FtpID_GetLastIDReferense(pff->GetPrivatePidlReference());
        else
            pidl = FtpID_GetLastIDReferense(pflHfpl->GetPidl(0));

        if (pidl)
            FtpPidl_GetDisplayName(pidl, pwzName, cchSize);
    }
}


BOOL CanEditName(CFtpFolder * pff, CFtpPidlList * pflHfpl)
{
    int nNumItems = pflHfpl->GetCount();
    BOOL fCanRename = TRUE;

    // we can edit except for multiply selected items
    if (2 <= nNumItems)
        fCanRename = FALSE;
    else
    {
        // If they chose the background properties for a server,
        // we won't let the change the server name.
        if (0 == nNumItems)
        {
            LPCITEMIDLIST pidlFolder = pff->GetPrivatePidlReference();

            if (pidlFolder && (ILIsEmpty(pidlFolder) || (ILIsEmpty(_ILNext(pidlFolder)))))
            {
                fCanRename = FALSE;
            }
        }
        else if (1 == nNumItems)
        {
            // Now I'm worried that pflHfpl->GetPidl(0) is a PIDL pointing to
            // an FTP Server.
            LPCITEMIDLIST pidl = pflHfpl->GetPidl(0);

            if (pidl && !ILIsEmpty(pidl) &&
                FtpID_IsServerItemID(pidl) && ILIsEmpty(_ILNext(pidl)))
            {
                fCanRename = FALSE;
            }
        }
    }

    return fCanRename;
}


/*****************************************************************************\
    FUNCTION: _InitName
    
    DESCRIPTION:
        Get the name of the object in the pflHfpl.  If there is more than one
    thing, use ellipses.
\*****************************************************************************/
HRESULT CFtpDialogTemplate::_InitName(HWND hwnd, CFtpFolder * pff, CFtpPidlList * pflHfpl)
{
    HRESULT hr = S_OK;
    WCHAR wzName[MAX_PATH];

    GetItemName(pff, pflHfpl, wzName, ARRAYSIZE(wzName));
    hr = _ReinsertDlgText(hwnd, wzName, SZ_WSPRINTFSTR_S);
    // We only use the static filename when more than one item is selected
    // because that is the case that we can't do a rename.  Are there
    // multiple items selected?
    if (m_fEditable && CanEditName(pff, pflHfpl))
    {
        // Hide because we will use IDC_FILENAME_EDITABLE instead.
        ShowEnableWindow(hwnd, FALSE);
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: _InitNameEditable
    
    DESCRIPTION:
        Get the name of the object in the pflHfpl.  If there is more than one
    thing, use ellipses.
\*****************************************************************************/
HRESULT CFtpDialogTemplate::_InitNameEditable(HWND hwnd, CFtpFolder * pff, CFtpPidlList * pflHfpl)
{
    HRESULT hr = S_OK;
    TCHAR szName[MAX_PATH];

    GetItemName(pff, pflHfpl, szName, ARRAYSIZE(szName));
    hr = _ReinsertDlgText(hwnd, szName, SZ_WSPRINTFSTR_S);

    // We only use the static filename when more than one item is selected
    // because that is the case that we can't do a rename.  Are there
    // multiple items selected?
    if (!m_fEditable || !CanEditName(pff, pflHfpl))
    {
        // Hide because we will use IDC_FILENAME_EDITABLE instead.
        ShowEnableWindow(hwnd, FALSE);
    }

    return hr;
}


void GetNameFromPidlList(CFtpFolder * pff, CFtpPidlList * pflHfpl, LPWSTR pwzName, DWORD cchSize)
{
    LPCITEMIDLIST pidl;
    
    if (0 == pflHfpl->GetCount())
        pidl = FtpID_GetLastIDReferense(pff->GetPrivatePidlReference());
    else
        pidl = FtpID_GetLastIDReferense(pflHfpl->GetPidl(0));

    if (pidl)
    {
        FtpPidl_GetLastItemDisplayName(pidl, pwzName, cchSize);
    }
}


/*****************************************************************************\
    FUNCTION: _InitType
    
    DESCRIPTION:
        Get the type of the pidls identified by pflHfpl.
\*****************************************************************************/
HRESULT CFtpDialogTemplate::_InitType(HWND hwnd, CFtpFolder * pff, CFtpPidlList * pflHfpl)
{
    TCHAR szType[MAX_URL_STRING];
    
    szType[0] = 0;
    switch (pflHfpl->GetCount())
    {
    case 0:
        {
            // Find out if it's a folder or an ftp server root.
            LPCITEMIDLIST pidl = FtpID_GetLastIDReferense(pff->GetPrivatePidlReference());
            if (pidl)
                LoadString(HINST_THISDLL, (FtpID_IsServerItemID(pidl) ? IDS_ITEMTYPE_SERVER : IDS_ITEMTYPE_FOLDER), szType, ARRAYSIZE(szType));
        }
        break;
        
    case 1:
        // Just one item is selected, so get it's type.
        FtpPidl_GetFileType(pflHfpl->GetPidl(0), szType, ARRAYSIZE(szType));
        break;
        
    default:
        // Display "Several Selected" because they can span 1 type.
        LoadString(HINST_THISDLL, IDS_SEVERAL_SELECTED, szType, ARRAYSIZE(szType));
        break;
    }
    
    return _ReinsertDlgText(hwnd, szType, SZ_WSPRINTFSTR_S);
}


/*****************************************************************************\
    FUNCTION: _InitLocation
    
    DESCRIPTION:
        Get the name of the folder identified by pidl.
\*****************************************************************************/
HRESULT CFtpDialogTemplate::_InitLocation(HWND hwnd, CFtpFolder * pff, CFtpPidlList * pidlList)
{
    HRESULT hr = E_FAIL;
    TCHAR szUrl[MAX_PATH];
    LPITEMIDLIST pidl = GetPidlFromFtpFolderAndPidlList(pff, pidlList);

    ASSERT(pidlList && pff);
    if (pidl)
    {
        // If more than one items are selected, then we only want to
        // show the common location.
        if (1 < pidlList->GetCount())
            ILRemoveLastID(pidl);
        hr = UrlCreateFromPidl(pidl, SHGDN_FORADDRESSBAR, szUrl, ARRAYSIZE(szUrl), 0, TRUE);
        if (SUCCEEDED(hr))
        {
            hr = _ReinsertDlgText(hwnd, szUrl, SZ_WSPRINTFSTR_S);
        }
        ILFree(pidl);
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: _InitSizeTally
    
    DESCRIPTION:
        Total up the size of each file referred to in the pidl.
\*****************************************************************************/
int CFtpDialogTemplate::_InitSizeTally(LPVOID pvPidl, LPVOID pvSizeHolder)
{
    BOOL fSuccess = TRUE;
    LPCITEMIDLIST pidl = (LPCITEMIDLIST) pvPidl;
    CSizeHolder * pSizeHolder = (CSizeHolder *) pvSizeHolder;

    // Did we get a valid size and is pSizeHolder still valid?
    if (SUCCEEDED(pSizeHolder->GetError()))
    {
        // Yes, so keep accumulating if it's a file.
        if (!FtpID_IsServerItemID(pidl) && !FtpItemID_IsDirectory(pidl, FALSE))
        {
            ULARGE_INTEGER uliPidlFileSize;
            uliPidlFileSize.QuadPart = FtpItemID_GetFileSize(pidl);

            pSizeHolder->AddSize(uliPidlFileSize.QuadPart);
            pSizeHolder->FoundNonFolder();  // Show that at least one was a file.
            if (!uliPidlFileSize.QuadPart)
                fSuccess = FALSE;
        }
    }
    else
    {
        pSizeHolder->SetError(E_FAIL);
        fSuccess = FALSE;
    }

    return fSuccess;
}

#define MAX_FILE_SIZE           64

HRESULT GetFileSizeFromULargeInteger(ULARGE_INTEGER uliSize, LPTSTR pszSizeStr, DWORD cchSize)
{
    WCHAR wzSizeStr[MAX_FILE_SIZE];
    LONGLONG llSize = (LONGLONG) uliSize.QuadPart;

    if (StrFormatByteSizeW(llSize, wzSizeStr, ARRAYSIZE(wzSizeStr)))
        SHUnicodeToTChar(wzSizeStr, pszSizeStr, cchSize);
    else
    {
        CHAR szStrStrA[MAX_FILE_SIZE];

        StrFormatByteSizeA(uliSize.LowPart, szStrStrA, ARRAYSIZE(szStrStrA));
        SHAnsiToTChar(szStrStrA, pszSizeStr, cchSize);
    }

    return S_OK;
}


// From shlwapi.
void Int64ToStr(LONGLONG n, LPTSTR lpBuffer, DWORD cchSize)
{
    TCHAR szTemp[40];
    LONGLONG iChr = 0;

    ASSERT(cchSize > ARRAYSIZE(szTemp));
    do
    {
        szTemp[iChr++] = TEXT('0') + (TCHAR)(n % 10);
        n = n / 10;
    }
    while (n != 0);

    do
    {
        iChr--;
        *lpBuffer++ = szTemp[iChr];
    }
    while (iChr != 0);

    *lpBuffer++ = TEXT('\0');
}


/*****************************************************************************\
    FUNCTION: _InitSize
    
    DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpDialogTemplate::_InitSize(HWND hwnd, HWND hwndLabel, CFtpFolder * pff, CFtpPidlList * pflHfpl)
{
    HRESULT hr;
    TCHAR szSizeStr[MAX_FILE_SIZE];
    CSizeHolder sizeHolder;

    szSizeStr[0] = 0;
    // GetCount maybe 0 if we are doing the background folder.
    if (0 < pflHfpl->GetCount())
    {
        pflHfpl->Enum(CFtpDialogTemplate::_InitSizeTally, (LPVOID) &sizeHolder);
        if (SUCCEEDED(sizeHolder.GetError()))
        {
            // Are there files sizes to display?
            if (!sizeHolder.IsAllFolders())
            {
                TCHAR szBytesStr[MAX_FILE_SIZE];
                TCHAR szBytesStrFormatted[MAX_FILE_SIZE];
                TCHAR szCondencedSizeStr[MAX_FILE_SIZE];
                ULARGE_INTEGER uliTotal;
                uliTotal.QuadPart = sizeHolder.GetTotalSize();

                NUMBERFMT numfmt = {0, 0, 3, TEXT(""), TEXT(","), 0};

                EVAL(SUCCEEDED(GetFileSizeFromULargeInteger(uliTotal, szCondencedSizeStr, ARRAYSIZE(szCondencedSizeStr))));

                Int64ToStr(uliTotal.QuadPart, szBytesStr, ARRAYSIZE(szBytesStr));
                GetNumberFormat(LOCALE_USER_DEFAULT, 0, szBytesStr, &numfmt, szBytesStrFormatted, ARRAYSIZE(szBytesStrFormatted));
                wnsprintf(szSizeStr, ARRAYSIZE(szSizeStr), TEXT("%s (%s bytes)"), szCondencedSizeStr, szBytesStrFormatted);
            }
        }
    }

    if (szSizeStr[0])
    {
        hr = _ReinsertDlgText(hwnd, szSizeStr, SZ_WSPRINTFSTR_S);
    }
    else
    {
        // If more than one item was selected...
        // remove both the label and the value.
        ShowEnableWindow(hwnd, FALSE);
        if (hwndLabel)
            ShowEnableWindow(hwndLabel, FALSE);

        hr = S_OK;
    }

    return hr;
}

// WINVER 0x0500 definition
#ifndef WS_EX_LAYOUTRTL
#define WS_EX_LAYOUTRTL     0x00400000L // Right to left mirroring
#endif


/*****************************************************************************\
    FUNCTION: _InitTime
    
    DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpDialogTemplate::_InitTime(HWND hwnd, HWND hwndLabel, CFtpFolder * pff, CFtpPidlList * pflHfpl)
{
    TCHAR szDateTime[MAX_PATH];
    HRESULT hr = E_FAIL;
    DWORD dwFlags = FDTF_SHORTTIME | FDTF_LONGDATE;
    LCID locale = GetUserDefaultLCID();

    if ((PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_ARABIC)
        || (PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_HEBREW))
        {
            DWORD dwExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);

            if ((BOOLIFY(dwExStyle & WS_EX_RTLREADING)) != (BOOLIFY(dwExStyle & WS_EX_LAYOUTRTL)))
                dwFlags |= FDTF_RTLDATE;
            else
                dwFlags |= FDTF_LTRDATE;
         }      
    
    switch (pflHfpl->GetCount())
    {
    // one item was selected so get the time for that item.
    case 1:
        if (!FtpID_IsServerItemID(pflHfpl->GetPidl(0)))
        {
            FILETIME ftLastModified = FtpPidl_GetFileTime(pflHfpl->GetPidl(0));
            Misc_StringFromFileTime(szDateTime, ARRAYSIZE(szDateTime), &ftLastModified, dwFlags);
            hr = S_OK;
        }
        break;

    // zero items selected means get the properties for the background folder
    case 0:
    {
        LPCITEMIDLIST pidl = FtpID_GetLastIDReferense(pff->GetPrivatePidlReference());
    
        // The user will get 'N/A' for the 'Server' folder. (i.e. ftp://ohserv/)
        if (EVAL(pidl) && !FtpID_IsServerItemID(pidl))
        {
            FILETIME ftLastModified = FtpPidl_GetFileTime(pidl);
            Misc_StringFromFileTime(szDateTime, ARRAYSIZE(szDateTime), &ftLastModified, dwFlags);
            hr = S_OK;
        }
        // Don't free pidl because we have a pointer to someone else's copy.
    }
    }

    if (SUCCEEDED(hr))
    {
        hr = _ReinsertDlgText(hwnd, szDateTime, SZ_WSPRINTFSTR_S);
    }
    else
    {
        // If more than one item was selected...
        // remove both the label and the value.
        ShowEnableWindow(hwnd, FALSE);
        if (hwndLabel)
            ShowEnableWindow(hwndLabel, FALSE);

        hr = S_OK;
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: _InitCount
    
    DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpDialogTemplate::_InitCount(HWND hwnd, CFtpFolder * pff, CFtpPidlList * pflHfpl)
{
    return _ReinsertDlgText(hwnd, IntToPtr(pflHfpl->GetCount()), SZ_WSPRINTFSTR_U);
}


/*****************************************************************************\
    FUNCTION: InitDialog
    
    DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpDialogTemplate::InitDialog(HWND hDlg, BOOL fEditable, UINT id, CFtpFolder * pff, CFtpPidlList * pPidlList)
{
    HRESULT hr = S_OK;
    int nDlgTemlItem;

    m_fEditable = fEditable;
    for (nDlgTemlItem = 0; nDlgTemlItem < DLGTEML_MAX; nDlgTemlItem++)
    {
        HRESULT hrTemp = S_OK;

        HWND hwnd = GetDlgItem(hDlg, id + nDlgTemlItem);
        HWND hwndLabel = GetDlgItem(hDlg, id + nDlgTemlItem + DLGTEML_LABEL);
        if (hwnd)
        {
            switch (nDlgTemlItem)
            {
            case DLGTEML_FILENAME:          hrTemp = _InitName(hwnd, pff, pPidlList); break;
            case DLGTEML_FILENAMEEDITABLE:  hrTemp = _InitNameEditable(hwnd, pff, pPidlList); break;
            case DLGTEML_FILEICON:          hrTemp = _InitIcon(hwnd, pff, pPidlList); break;
            case DLGTEML_FILESIZE:          hrTemp = _InitSize(hwnd, hwndLabel, pff, pPidlList); break;
            case DLGTEML_FILETIME:          hrTemp = _InitTime(hwnd, hwndLabel, pff, pPidlList); break;
            case DLGTEML_FILETYPE:          hrTemp = _InitType(hwnd, pff, pPidlList); break;
            case DLGTEML_LOCATION:          hrTemp = _InitLocation(hwnd, pff, pPidlList); break;
            case DLGTEML_COUNT:             hrTemp = _InitCount(hwnd, pff, pPidlList); break;
            default:
                ASSERT(0);  // What are you thinking?
                break;
            }
        }

        if (EVAL(SUCCEEDED(hr)))
            hr = hrTemp;        // Propogate out the worst error.
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: OnClose
    
    DESCRIPTION:
\*****************************************************************************/
BOOL CFtpDialogTemplate::OnClose(HWND hdlg, HWND hwndBrowser, CFtpFolder * pff, CFtpPidlList * pPidlList)
{
    BOOL fCanClose = TRUE;

    // If the IDC_FILENAME_EDITABLE field is showing, then the user may have done
    // a rename.  Check if that happened and if so, do it now.
    if (IsWindowVisible(GetDlgItem(hdlg, IDC_FILENAME_EDITABLE)))
    {
        WCHAR wzOldName[MAX_PATH];
        WCHAR wzNewName[MAX_PATH];

        GetNameFromPidlList(pff, pPidlList, wzOldName, ARRAYSIZE(wzOldName));
        EVAL(GetWindowTextW(GetDlgItem(hdlg, IDC_FILENAME_EDITABLE), wzNewName, ARRAYSIZE(wzNewName)));

        // Was the name changed?
        if (StrCmpW(wzOldName, wzNewName))
        {
            // Yes, so change it.
            IShellFolder * psfParent = NULL;
            CFtpFolder * pffParent = pff;
            LPCITEMIDLIST pidlItem;

            if (0 == pPidlList->GetCount())
            {
                // We use pidlTarget mainly because we want to assure that the
                // ChangeNotifies are fired with pidlTarget.
                LPITEMIDLIST pidlParent = pff->GetPublicTargetPidlClone();

                if (pidlParent)
                {
                    ILRemoveLastID(pidlParent);
                    pidlItem = FtpID_GetLastIDReferense(pff->GetPrivatePidlReference());
                    IEBindToObject(pidlParent, &psfParent); 
                    ILFree(pidlParent);
                }
            }
            else
            {
                pidlItem = FtpID_GetLastIDReferense(pPidlList->GetPidl(0));
                EVAL(SUCCEEDED(pff->QueryInterface(IID_IShellFolder, (void **) &psfParent)));
            }

            if (psfParent)
            {
                if (EVAL(pidlItem))
                    fCanClose = ((S_OK == psfParent->SetNameOf(hwndBrowser, pidlItem, wzNewName, NULL, NULL)) ? TRUE : FALSE);

                psfParent->Release();
            }
        }
    }

    return fCanClose;
}


/*****************************************************************************\
    FUNCTION: OnDestroy
    
    DESCRIPTION:
\*****************************************************************************/
BOOL CFtpDialogTemplate::OnDestroy(HWND hDlg, BOOL fEditable, UINT id, CFtpFolder* pff, CFtpPidlList* pPidlList)
{
    HRESULT hr = S_OK;
    int nDlgTemlItem;

    for (nDlgTemlItem = 0; nDlgTemlItem < DLGTEML_MAX; nDlgTemlItem++)
    {
        HRESULT hrTemp = S_OK;

        HWND hwnd = GetDlgItem(hDlg, id + nDlgTemlItem);
        HWND hwndLabel = GetDlgItem(hDlg, id + nDlgTemlItem + DLGTEML_LABEL);
        if (hwnd)
        {
            switch (nDlgTemlItem)
            {

            case DLGTEML_FILEICON:
                hrTemp = _ReplaceIcon(hwnd, NULL);
                break;

            case DLGTEML_FILENAME:
            case DLGTEML_FILENAMEEDITABLE:
            case DLGTEML_FILESIZE:
            case DLGTEML_FILETIME:
            case DLGTEML_FILETYPE:
            case DLGTEML_LOCATION:
            case DLGTEML_COUNT:
                break;

            default:
                ASSERT(0);  // What are you thinking?
                break;
            }
        }

        if (SUCCEEDED(hr))
        {
            // Propogate out the worst error.
            hr = hrTemp;
        }
    }

    return hr;  
}


BOOL CFtpDialogTemplate::HasNameChanged(HWND hdlg, CFtpFolder * pff, CFtpPidlList * pPidlList)
{
    BOOL fNameChanged = FALSE;

    // If the IDC_FILENAME_EDITABLE field is showing, then the user may have done
    // a rename.  Check if that happened and if so, do it now.
    if (IsWindowVisible(GetDlgItem(hdlg, IDC_FILENAME_EDITABLE)))
    {
        TCHAR szOldName[MAX_PATH];
        TCHAR szNewName[MAX_PATH];

        GetNameFromPidlList(pff, pPidlList, szOldName, ARRAYSIZE(szOldName));
        EVAL(GetWindowText(GetDlgItem(hdlg, IDC_FILENAME_EDITABLE), szNewName, ARRAYSIZE(szNewName)));

        // Was the name changed?
        if (StrCmp(szOldName, szNewName))
        {
            // Yes, so change it.
            fNameChanged = TRUE;
        }
    }

    return fNameChanged;
}


HRESULT CFtpDialogTemplate::InitDialogWithFindData(HWND hDlg, UINT id, CFtpFolder * pff, const FTP_FIND_DATA * pwfd, LPCWIRESTR pwWirePath, LPCWSTR pwzDisplayPath)
{
    FTP_FIND_DATA wfd = *pwfd;
    LPITEMIDLIST pidl;
    HRESULT hr;
    
    ASSERT(pwfd);

    StrCpyNA(wfd.cFileName, pwWirePath, ARRAYSIZE(wfd.cFileName));
    hr = FtpItemID_CreateReal(&wfd, pwzDisplayPath, &pidl);
    if (SUCCEEDED(hr))
    {
        CFtpPidlList * pfpl = NULL;
        
        hr = CFtpPidlList_Create(1, (LPCITEMIDLIST *) &pidl, &pfpl);
        if (SUCCEEDED(hr))
        {
            hr = InitDialog(hDlg, FALSE, id, pff, pfpl);
            pfpl->Release();
        }

        ILFree(pidl);
    }
    
    return hr;
}
