/****************************************************************************
 
  Copyright (c) 1998-1999 Microsoft Corporation
                                                              
  Module Name:  cplcallingcardtab.cpp
                                                              
       Author:  toddb - 10/06/98

****************************************************************************/

//
// Functions used only by the Calling Card tab of the New Location Property Sheet.
// Shared functions are in the Location.cpp file.
//
#include "cplPreComp.h"
#include "cplLocationPS.h"


INT_PTR CALLBACK CLocationPropSheet::CallingCard_DialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    CLocationPropSheet* pthis = (CLocationPropSheet*) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);

    switch(uMsg)
    {
    case WM_INITDIALOG:
        pthis = (CLocationPropSheet*)(((PROPSHEETPAGE*)lParam)->lParam);
        SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pthis); 
        return pthis->CallingCard_OnInitDialog(hwndDlg);

    case WM_COMMAND:
        pthis->CallingCard_OnCommand(hwndDlg, LOWORD(wParam), HIWORD(wParam), (HWND)lParam );
        return 1;

    case WM_NOTIFY:
        return pthis->CallingCard_OnNotify(hwndDlg, (LPNMHDR)lParam);
   
    case WM_HELP:
        // Process clicks on controls after Context Help mode selected
        WinHelp ((HWND)((LPHELPINFO)lParam)->hItemHandle, gszHelpFile, HELP_WM_HELP, (DWORD_PTR)(LPTSTR) a104HelpIDs);
        break;
        
    case WM_CONTEXTMENU:
        // Process right-clicks on controls
        WinHelp ((HWND) wParam, gszHelpFile, HELP_CONTEXTMENU, (DWORD_PTR)(LPVOID) a104HelpIDs);
        break;
    }

    return 0;
}

BOOL CLocationPropSheet::CallingCard_OnInitDialog(HWND hDlg)
{
    RECT rc;
    HWND hwnd = GetDlgItem(hDlg, IDC_LIST);

    GetClientRect(hwnd, &rc);

    LVCOLUMN lvc;
    lvc.mask = LVCF_SUBITEM | LVCF_WIDTH;
    lvc.iSubItem = 0;
    lvc.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
    ListView_InsertColumn( hwnd, 0, &lvc );
    
    ListView_SetExtendedListViewStyleEx(hwnd, 
        LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT, 
        LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT);

    m_dwDefaultCard = m_pLoc->GetPreferredCardID();
    if ( 0 == m_dwDefaultCard )
    {
        // Card0 is the "None (Direct Dial)" card which we want to go away
        m_pLoc->UseCallingCard(FALSE);
    }

    PopulateCardList( hwnd );

	// The PIN is not displayed when it's not safe (at logon time, for ex.)

	m_bShowPIN = TapiIsSafeToDisplaySensitiveData();
	
    SetDataForSelectedCard(hDlg);

    hwnd = GetDlgItem(hDlg,IDC_CARDNUMBER);
    SendMessage(hwnd,EM_SETLIMITTEXT,CPL_SETTEXTLIMIT,0);
    LimitInput(hwnd, LIF_ALLOWNUMBER|LIF_ALLOWSPACE);

    hwnd = GetDlgItem(hDlg,IDC_PIN);
    SendMessage(hwnd,EM_SETLIMITTEXT,CPL_SETTEXTLIMIT,0);
    LimitInput(hwnd, LIF_ALLOWNUMBER|LIF_ALLOWSPACE);

    return 0;
}

int CALLBACK CallingCard_ListSort(LPARAM lItem1, LPARAM lItem2, LPARAM )
{
    if ( !lItem1 )
    {
        return -1;
    }
    if ( !lItem2 )
    {
        return 1;
    }

    CCallingCard * pCard1 = (CCallingCard *)lItem1;
    CCallingCard * pCard2 = (CCallingCard *)lItem2;

    return StrCmpIW(pCard1->GetCardName(),pCard2->GetCardName());
}

void CLocationPropSheet::PopulateCardList( HWND hwndList )
{
    CCallingCard * pCard;

    HIMAGELIST himl = ImageList_Create(16, 16, ILC_COLOR|ILC_MASK, 2, 2);
    HBITMAP hBmp = CreateMappedBitmap(GetUIInstance(), IDB_BUTTONS, 0, NULL, 0);

    if (NULL != hBmp)
    {
        ImageList_AddMasked( himl, hBmp, CLR_DEFAULT);
        DeleteObject( hBmp );
    }

    ListView_SetImageList(hwndList, himl, LVSIL_SMALL);

    // Add our special "none" item
    AddCardToList(hwndList,NULL,FALSE);

    m_Cards.Initialize();
    m_Cards.Reset(TRUE);    // TRUE means show "hidden" cards, FALSE means hide them

    while ( S_OK == m_Cards.Next(1,&pCard,NULL) )
    {
        if ( !pCard->IsMarkedHidden() )
        {
            // Card0 is the "None (Direct Dial)" card which we don't want to show
            if ( 0 != pCard->GetCardID() )
            {
                AddCardToList(hwndList,pCard,FALSE);
            }
        }
    }

    ListView_SortItems(hwndList, CallingCard_ListSort, 0);

    EnsureVisible(hwndList, m_pCard);
}

void CLocationPropSheet::AddCardToList(HWND hwndList, CCallingCard * pCard, BOOL bSelect)
{
    TCHAR szText[MAX_INPUT];
    // basically, bSelect is FALSE when we are first populating the list and TRUE when we
    // add items later.  When the value is FALSE what we really mean is "Select the item
    // only if it is the currently selected item based on the location settings".
    if (pCard)
    {
        SHUnicodeToTChar(pCard->GetCardName(), szText, ARRAYSIZE(szText));
        bSelect = bSelect || ((m_dwDefaultCard != 0) && (m_dwDefaultCard==pCard->GetCardID()));
    }
    else
    {
        LoadString(GetUIInstance(), IDS_NONE, szText, ARRAYSIZE(szText));
        bSelect = bSelect || !(m_dwDefaultCard != 0);
    }

    LVITEM lvi;
    lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
    lvi.iItem = 0;
    lvi.iSubItem = 0;
    lvi.pszText = szText;
    lvi.iImage = 0;
    lvi.lParam = (LPARAM)pCard;

    if ( bSelect )
    {
        lvi.mask |= LVIF_STATE;
        lvi.state = lvi.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
        lvi.iImage = 1;
        SetCheck(hwndList, m_pCard, FALSE);
        m_pCard = pCard;
    }

    ListView_InsertItem(hwndList, &lvi);
}

void CLocationPropSheet::SetCheck(HWND hwndList, CCallingCard * pCard, int iImage)
{
    LVFINDINFO lvfi;
    lvfi.flags = LVFI_PARAM;
    lvfi.lParam = (LPARAM)pCard;
    int iItem = ListView_FindItem(hwndList,-1,&lvfi);

    if (-1 != iItem)
    {
        LVITEM lvi;
        lvi.mask = LVIF_IMAGE;
        lvi.iItem = iItem;
        lvi.iSubItem = 0;
        lvi.iImage = iImage;

        ListView_SetItem( hwndList, &lvi );
        ListView_Update( hwndList, iItem ); // need the font to be drawn non-bold
    }
}

void CLocationPropSheet::EnsureVisible(HWND hwndList, CCallingCard * pCard)
{
    LVFINDINFO lvfi;
    lvfi.flags = LVFI_PARAM;
    lvfi.lParam = (LPARAM)pCard;
    int iItem = ListView_FindItem(hwndList,-1,&lvfi);

    if (-1 != iItem)
    {
        ListView_EnsureVisible( hwndList, iItem, FALSE );
    }

}

void CLocationPropSheet::UpdateCardInList(HWND hwndList, CCallingCard * pCard)
{
    LVFINDINFO lvfi;
    lvfi.flags = LVFI_PARAM;
    lvfi.lParam = (LPARAM)pCard;
    int iItem = ListView_FindItem(hwndList,-1,&lvfi);

    if (-1 != iItem)
    {
        TCHAR szText[MAX_INPUT];
        SHUnicodeToTChar( pCard->GetCardName(), szText, ARRAYSIZE(szText) );

        LVITEM lvi;
        lvi.mask = LVIF_TEXT | LVIF_PARAM;
        lvi.iItem = iItem;
        lvi.iSubItem = 0;
        lvi.pszText = szText;
        lvi.lParam = (LONG_PTR)pCard;

        ListView_SetItem( hwndList, &lvi );
    }
}

void CLocationPropSheet::SetDataForSelectedCard(HWND hDlg)
{
    // if a card is selected, then set the text for:
    //  PIN Number
    //  Card Number
    //  Long Distance Access Number
    //  International Access Number
    if ( m_pCard )
    {
        TCHAR szText[MAX_INPUT];

        if(m_bShowPIN)
        {
        	SHUnicodeToTChar(m_pCard->GetPIN(), szText, ARRAYSIZE(szText));
        	SetWindowText( GetDlgItem(hDlg, IDC_PIN), szText );
        }
        else
        {
	        SetWindowText( GetDlgItem(hDlg, IDC_PIN), TEXT("") );
        }

        SHUnicodeToTChar(m_pCard->GetAccountNumber(), szText, ARRAYSIZE(szText));
        SetWindowText( GetDlgItem(hDlg, IDC_CARDNUMBER), szText );

        SHUnicodeToTChar(m_pCard->GetLongDistanceAccessNumber(), szText, ARRAYSIZE(szText));
        SetWindowText( GetDlgItem(hDlg, IDC_LONGDISTANCE), szText );

        SHUnicodeToTChar(m_pCard->GetInternationalAccessNumber(), szText, ARRAYSIZE(szText));
        SetWindowText( GetDlgItem(hDlg, IDC_INTERNATIONAL), szText );

        SHUnicodeToTChar(m_pCard->GetLocalAccessNumber(), szText, ARRAYSIZE(szText));
        SetWindowText( GetDlgItem(hDlg, IDC_LOCAL), szText );
    }
    else
    {
        SetWindowText( GetDlgItem(hDlg, IDC_PIN), TEXT("") );
        SetWindowText( GetDlgItem(hDlg, IDC_CARDNUMBER), TEXT("") );
        SetWindowText( GetDlgItem(hDlg, IDC_LONGDISTANCE), TEXT("") );
        SetWindowText( GetDlgItem(hDlg, IDC_INTERNATIONAL), TEXT("") );
        SetWindowText( GetDlgItem(hDlg, IDC_LOCAL), TEXT("") );
    }

    // The button state depends on whether a card is selected
    BOOL bEnable = 0!=m_pCard;
    EnableWindow( GetDlgItem(hDlg, IDC_EDIT),       bEnable );
    HWND hwnd = GetDlgItem(hDlg, IDC_DELETE);
    if ( !bEnable && GetFocus() == hwnd )
    {
        HWND hwndDef = GetDlgItem(hDlg, IDC_NEW);
        SendMessage(hwnd, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE,0));
        SendMessage(hwndDef, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE,0));
        SetFocus(hwndDef);
    }
    EnableWindow( hwnd, bEnable );
    EnableWindow( GetDlgItem(hDlg, IDC_SETDEFAULT), bEnable );

    EnableWindow( GetDlgItem(hDlg, IDC_PIN), bEnable );
    EnableWindow( GetDlgItem(hDlg, IDC_CARDNUMBER), bEnable );
}

BOOL CLocationPropSheet::CallingCard_OnCommand(HWND hwndParent, int wID, int wNotifyCode, HWND hwndCrl)
{
    switch ( wID )
    {
    case IDC_NEW:
    case IDC_EDIT:
        LaunchCallingCardPropSheet(IDC_NEW == wID, hwndParent);
        break;

    case IDC_DELETE:
        DeleteSelectedCard(GetDlgItem(hwndParent,IDC_LIST));
        break;

    case IDC_PIN:
    case IDC_CARDNUMBER:
        if ( EN_CHANGE == wNotifyCode )
        {
            SendMessage(GetParent(hwndParent),PSM_CHANGED,(WPARAM)hwndParent,0);
        }
        break;

    default:
        return 0;
    }
    return 1;
}

void CLocationPropSheet::LaunchCallingCardPropSheet(BOOL bNew, HWND hwndParent)
{
    CCallingCard * pCard;
    if ( bNew )
    {
        TCHAR szCardName[MAX_INPUT];
        WCHAR wszCardName[MAX_INPUT];

        pCard = new CCallingCard;
		if (NULL == pCard)
		{
			// Nothing much to do.
			return;
		}
        LoadString(GetUIInstance(), IDS_NEWCALLINGCARD, szCardName, ARRAYSIZE(szCardName));
        SHTCharToUnicode(szCardName, wszCardName, ARRAYSIZE(wszCardName));
        pCard->Initialize(
            0,
            wszCardName,
            0,
            L"",
            L"",
            L"",
            L"",
            L"",
            L"",
            L"",
            L"" );
    }
    else
    {
        pCard = m_pCard;
        if ( !pCard )
        {
            // must have clicked on the None card, do nothing.  We can only get
            // here when the user double clicks on an item.
            MessageBeep(0);
            return;
        }
    }

    CCallingCardPropSheet ccps( bNew, m_bShowPIN, pCard, &m_Cards );
    int iRes = ccps.DoPropSheet(hwndParent);

    if ( PSN_APPLY == iRes )
    {
        HWND hwndList = GetDlgItem(hwndParent,IDC_LIST);
        if ( bNew )
        {
            pCard->SetCardID(m_Cards.AllocNewCardID());
            m_Cards.AddCard(pCard);
            AddCardToList(hwndList, pCard, TRUE);
        }
        else
        {
            UpdateCardInList(hwndList, pCard);
        }
        ListView_SortItems(hwndList, CallingCard_ListSort, 0);

        EnsureVisible(hwndList, pCard);

		// It's safe to display the PIN number after an Apply in the detail dialog
		m_bShowPIN = TRUE;
        SetDataForSelectedCard(hwndParent);

        SendMessage(GetParent(hwndParent),PSM_CHANGED,(WPARAM)hwndParent,0);
    }
    else if (bNew)
    {
        delete pCard;
    }
}

BOOL CLocationPropSheet::CallingCard_OnNotify(HWND hwndDlg, LPNMHDR pnmhdr)
{
    // Let the generic handler have a crack at it first
    OnNotify(hwndDlg, pnmhdr);

    switch (pnmhdr->idFrom)
    {
    case IDC_LIST:
        #define pnmlv ((LPNMLISTVIEW)pnmhdr)

        switch (pnmhdr->code)
        {
        case LVN_ITEMCHANGED:
            if ( (pnmlv->uChanged & LVIF_STATE) && (pnmlv->uNewState & LVIS_SELECTED) )
            {
                LVITEM lvi;
                lvi.iItem = pnmlv->iItem;
                lvi.iSubItem = pnmlv->iSubItem;
                lvi.mask = LVIF_PARAM;
                ListView_GetItem( pnmhdr->hwndFrom, &lvi );
                CCallingCard * pCard = (CCallingCard *)lvi.lParam;

                // update the location to reflect the selected card
                if ( 0!=pCard )
                {
                    m_dwDefaultCard = pCard->GetCardID();
                }
                else
                {
                    m_dwDefaultCard = 0;
                }

                // clear the previous check using the old m_pCard value
                SetCheck(pnmhdr->hwndFrom, m_pCard, FALSE);

                // Update m_pCard to the currently selected item
                m_pCard = pCard;

                // set the Edit and Delete button states and update the card info
                m_bShowPIN = TapiIsSafeToDisplaySensitiveData();
                SetDataForSelectedCard(hwndDlg);

                // set the newly selected card to checked
                SetCheck(pnmhdr->hwndFrom, m_pCard, TRUE);
            }
            break;

        case NM_DBLCLK:
            // Assert( pCard == m_pCard );
            if ( -1 != pnmlv->iItem )
            {
                // Do edit case
                LaunchCallingCardPropSheet(FALSE,hwndDlg);
            }
            else
            {
                // Do new case
                LaunchCallingCardPropSheet(TRUE,hwndDlg);
            }
            break;

        case NM_CUSTOMDRAW:
            #define lplvcd ((LPNMLVCUSTOMDRAW)pnmhdr)

            if(lplvcd->nmcd.dwDrawStage == CDDS_PREPAINT)
            {
                // Request prepaint notifications for each item.
                SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,CDRF_NOTIFYITEMDRAW);
                return CDRF_NOTIFYITEMDRAW;
            }

            if(lplvcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
            {
                LVITEM lvi;
                lvi.iItem = (int)lplvcd->nmcd.dwItemSpec;
                lvi.iSubItem = 0;
                lvi.mask = LVIF_PARAM;
                ListView_GetItem( pnmhdr->hwndFrom, &lvi );
                CCallingCard * pCard = (CCallingCard *)lvi.lParam;

                if( (!pCard && 0 == m_dwDefaultCard) || 
                    (pCard && pCard->GetCardID() == m_dwDefaultCard) )
                {
                    extern HFONT g_hfontBold;
                    if (g_hfontBold)
                    {
                        SelectObject(lplvcd->nmcd.hdc, g_hfontBold);
                        SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,CDRF_NEWFONT);
                        return CDRF_NEWFONT;
                    }
                }

                SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,CDRF_DODEFAULT);
                return CDRF_DODEFAULT;
            }
            return 0;
            #undef lplvcd

        default:
            break;
        }
        break;
        #undef pnmlv

    default:
        switch (pnmhdr->code)
        {
        case PSN_APPLY:
            return CallingCard_OnApply(hwndDlg);

        default:
            break;
        }
        return 0;
    }
    return 1;
}

BOOL CLocationPropSheet::CallingCard_OnApply(HWND hwndDlg)
{
    // if a calling card should be used make sure one is selected
    if ( m_dwDefaultCard != 0 )
    {
        CCallingCard * pCard = m_Cards.GetCallingCard(m_dwDefaultCard);

        if ( !pCard )
        {
            HWND hwndList = GetDlgItem(hwndDlg,IDC_LIST);
            // error, no card is set as the default
            PropSheet_SetCurSelByID(GetParent(hwndDlg),IDD_LOC_CALLINGCARD);
            ShowErrorMessage(hwndList, IDS_NOCARDSELECTED);
            SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,PSNRET_INVALID_NOCHANGEPAGE);
            return TRUE;
        }

        // Store the original values before we change them:
        WCHAR wszOldCardNum[128];
        WCHAR wszOldPIN[128];
        StrCpyNW( wszOldCardNum, pCard->GetAccountNumber(), ARRAYSIZE(wszOldCardNum));
        StrCpyNW( wszOldPIN, pCard->GetPIN(), ARRAYSIZE(wszOldPIN));

        // get the current values:
        TCHAR szText[MAX_INPUT];
        WCHAR wszBuf[MAX_INPUT];

        GetWindowText(GetDlgItem(hwndDlg,IDC_CARDNUMBER), szText, ARRAYSIZE(szText));
        LOG((TL_INFO, "CallingCard_OnApply: Setting card number to %s", szText));
        SHTCharToUnicode(szText, wszBuf, ARRAYSIZE(wszBuf));
        pCard->SetAccountNumber(wszBuf);

        GetWindowText(GetDlgItem(hwndDlg,IDC_PIN), szText, ARRAYSIZE(szText));
        LOG((TL_INFO, "CallingCard_OnApply: Setting pin number to %s", szText));
        SHTCharToUnicode(szText, wszBuf, ARRAYSIZE(wszBuf));
        pCard->SetPIN(wszBuf);

        // check for validity:
        DWORD dwResult = pCard->Validate();
        if ( dwResult )
        {
            HWND hwnd;
            int iStrID;

            // something isn't valid, revert to old card Num and PIN in case
            // the user later decided to cancel
            pCard->SetAccountNumber(wszOldCardNum);
            pCard->SetPIN(wszOldPIN);

            if ( dwResult & CCVF_NOCARDNUMBER)
            {
                hwnd = GetDlgItem(hwndDlg, IDC_CARDNUMBER);
                iStrID = IDS_MUSTENTERCARDNUMBER;
            }
            else if ( dwResult & CCVF_NOPINNUMBER )
            {
                hwnd = GetDlgItem(hwndDlg, IDC_PIN);
                iStrID = IDS_MUSTENTERPINNUMBER;
            }
            else
            {
                hwnd = GetDlgItem(hwndDlg, IDC_LIST);
                iStrID = IDS_INVALIDCARD;
            }
            PropSheet_SetCurSelByID(GetParent(hwndDlg),IDD_LOC_CALLINGCARD);
            ShowErrorMessage(hwnd, iStrID);
            SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,PSNRET_INVALID_NOCHANGEPAGE);
            return TRUE;
        }
    }

    m_pLoc->SetPreferredCardID(m_dwDefaultCard);
    m_pLoc->UseCallingCard(m_dwDefaultCard != 0);
    m_Cards.SaveToRegistry();
    m_bShowPIN = TRUE;
    m_bWasApplied = TRUE;
    return PSNRET_NOERROR;
}

int DeleteItemAndSelectFirst( HWND hwndParent, int iList, int iItem, int iDel, int iAdd )
{
    HWND hwnd = GetDlgItem(hwndParent, iList);
    ListView_DeleteItem(hwnd, iItem);

    // Try to select the first item, if possible
    iItem = 0;
    LVITEM lvi;
    lvi.mask = LVIF_PARAM;
    lvi.iItem = iItem;
    lvi.iSubItem = 0;
    if ( ListView_GetItem(hwnd, &lvi) )
    {
        ListView_SetItemState(hwnd, iItem, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
        ListView_EnsureVisible(hwnd, iItem, FALSE);
    }
    else
    {
        iItem = -1;
    }

    hwnd = GetDlgItem(hwndParent,iDel);
    if ( -1 == iItem )
    {
        if ( GetFocus() == hwnd )
        {
            HWND hwndDef = GetDlgItem(hwndParent,iAdd);
            SendMessage(hwnd, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE,0));
            SendMessage(hwndDef, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE,0));
            SetFocus(hwndDef);
        }
    }
    EnableWindow(hwnd, -1!=iItem);

    return iItem;
}

void CLocationPropSheet::DeleteSelectedCard(HWND hwndList)
{
    // First we confirm the delete with the user
    TCHAR szText[1024];
    TCHAR szTitle[128];
    int result;
    HWND hwndParent = GetParent(hwndList);
    
    LoadString(GetUIInstance(), IDS_DELETECARDTEXT, szText, ARRAYSIZE(szText));
    LoadString(GetUIInstance(), IDS_CONFIRMDELETE, szTitle, ARRAYSIZE(szTitle));

    result = SHMessageBoxCheck( hwndParent, szText, szTitle, MB_YESNO, IDYES, TEXT("TAPIDeleteCallingCard") );
    if ( IDYES == result )
    {
        // remove the item corresponding to m_pCard from the list
        LVFINDINFO lvfi;
        lvfi.flags = LVFI_PARAM;
        lvfi.lParam = (LPARAM)m_pCard;
        int iItem = ListView_FindItem(hwndList, -1, &lvfi);
        if ( -1 != iItem )
        {
            HWND hwndParent = GetParent(hwndList);
            m_Cards.RemoveCard(m_pCard);
            iItem = DeleteItemAndSelectFirst( hwndParent, IDC_LIST, iItem, IDC_DELETE, IDC_ADD );

            if ( -1 != iItem )
            {
                LVITEM lvi;
                lvi.iItem = iItem;
                lvi.iSubItem = 0;
                lvi.mask = LVIF_PARAM;
                ListView_GetItem( hwndList, &lvi );

                // Store the currently selected item
                m_pCard = (CCallingCard*)lvi.lParam;
            }
            else
            {
                m_pCard = NULL;
            }

			m_bShowPIN = TapiIsSafeToDisplaySensitiveData();

            SetDataForSelectedCard(hwndParent);
            SendMessage(GetParent(hwndParent), PSM_CHANGED, (WPARAM)hwndParent, 0);
        }
        else
        {
            // It's really bad if this ever happens (which it shouldn't).  This means our
            // data is in an unknown state and we might do anything (even destroy data).
            LOG((TL_ERROR, "DeleteSelectedCard: Card Not Found!"));
        }
    }
}