// View.cpp : implementation of the CKrbManagerView class
//

#include "stdafx.h"
#include "KrbManager.h"

#include "Doc.h"
#include "View.h"
#include <winsock.h>
#include "krb.h"

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

/////////////////////////////////////////////////////////////////////////////
// CKrbManagerView

static UINT NEAR update_cache = RegisterWindowMessage("krb4-update-cache");

IMPLEMENT_DYNCREATE(CKrbManagerView, CListView)

BEGIN_MESSAGE_MAP(CKrbManagerView, CListView)
	//{{AFX_MSG_MAP(CKrbManagerView)
	ON_WM_CREATE()
    ON_REGISTERED_MESSAGE(update_cache, OnUpdateCache)
	ON_COMMAND(ID_FILE_DESTROY, OnFileDestroy)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CKrbManagerView construction/destruction

CKrbManagerView::CKrbManagerView()
{
}

CKrbManagerView::~CKrbManagerView()
{
}

BOOL CKrbManagerView::PreCreateWindow(CREATESTRUCT& cs)
{
	return CListView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CKrbManagerView drawing

void CKrbManagerView::OnDraw(CDC* pDC)
{
}

/////////////////////////////////////////////////////////////////////////////
// CKrbManagerView diagnostics

#ifdef _DEBUG
void CKrbManagerView::AssertValid() const
{
	CListView::AssertValid();
}

void CKrbManagerView::Dump(CDumpContext& dc) const
{
	CListView::Dump(dc);
}

CKrbManagerDoc* CKrbManagerView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CKrbManagerDoc)));
	return (CKrbManagerDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CKrbManagerView message handlers

void CKrbManagerView::AddColumn(int index, LPSTR plsz, int width)
{
    CListCtrl &list = GetListCtrl();
    LV_COLUMN col;
    col.mask = LVCF_TEXT | LVCF_WIDTH;
    col.fmt = LVCFMT_LEFT;
    if(width == -1)
        col.cx = list.GetStringWidth(plsz) + 15;
    else
        col.cx = width;
    col.pszText = plsz;
    col.cchTextMax = 0;
    col.iSubItem = index > 0 ? index : -1;
    if(col.iSubItem != -1)
        col.mask |= LVCF_SUBITEM;

    list.InsertColumn(index, &col);
}

void CKrbManagerView::OnInitialUpdate() 
{
    CListCtrl &list = GetListCtrl();
    char time_str[64];
    time_t t = 0;
    struct tm *tm = localtime(&t);
    strftime(time_str, sizeof(time_str), "%c", tm);
    int time_width = list.GetStringWidth(time_str) + 15;
    AddColumn(0, "  ");
    AddColumn(1, "Start time", time_width);
    AddColumn(2, "End time", time_width);
    AddColumn(3, "Principal", list.GetStringWidth("krbtgt.XXXXXXXXXXXXX@XXXXXXXXXXXXX") + 15);
    AddColumn(4, "Kvno");

    image_list.Create(IDB_BITMAP1, 16, 0, 0xffffff);
    list.SetImageList(&image_list, LVSIL_SMALL);

    CListView::OnInitialUpdate();
}

int CKrbManagerView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    lpCreateStruct->style |= LVS_REPORT;
	if (CListView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	return 0;
}

void CKrbManagerView::UpdateCacheList()
{
    CListCtrl &list = GetListCtrl();
    list.DeleteAllItems();

    int ret;
    
    ret = tf_init(NULL, R_TKT_FIL);
    if(ret){
        GetDocument()->SetTitle("(No tickets)");
        return;
    }
    char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];

    ret = tf_get_pname(pname);
    if(ret){
        GetDocument()->SetTitle("(No tickets)");
        return;
    }
    ret = tf_get_pinst(pinst);
    if(ret){
        GetDocument()->SetTitle("(No tickets)");
        return;
    }

    int num = 0;
    CREDENTIALS c;
    while((ret = tf_get_cred(&c)) == KSUCCESS){
        if(num == 0)
            strcpy(prealm, c.realm);               
        int nitem = list.InsertItem(LVIF_TEXT | LVIF_STATE, num, "", 0, 0, 0, NULL);
        HRESULT ret = GetLastError();
        LV_ITEM item;
        item.mask = LVIF_TEXT;
        item.iItem = nitem;

        struct tm *tm = localtime((time_t*)&c.issue_date);
        char time_str[64];
        strftime(time_str, sizeof(time_str), "%c", tm);
        item.iSubItem = 1;
        item.pszText = time_str;
        list.SetItem(&item);
        time_t end = krb_life_to_time(c.issue_date, c.lifetime);
        tm = localtime(&end);
        strftime(time_str, sizeof(time_str), "%c", tm);
        item.iSubItem = 2;
        list.SetItem(&item);
        item.iSubItem = 3;
        item.pszText = krb_unparse_name_long(c.service, c.instance, c.realm);
        list.SetItem(&item);
        char tmp[32];
        _snprintf(tmp, sizeof(tmp), "%u", c.kvno);
        item.pszText = tmp;
        item.iSubItem = 4;
        list.SetItem(&item);
        num++;
    }
    GetDocument()->SetTitle(krb_unparse_name_long(pname, pinst, prealm));
}

void CKrbManagerView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
{
    UpdateCacheList();
    CListView::OnUpdate(pSender, lHint, pHint);
}

LRESULT CKrbManagerView::OnUpdateCache(WPARAM wParam, LPARAM lParam)
{
    UpdateCacheList();
    return 0;
}


void CKrbManagerView::OnFileDestroy() 
{
	dest_tkt();
    UpdateCacheList();
}
