// PocketPJDlg.cpp : implementation file
//

#include "stdafx.h"
#include "PocketPJ.h"
#include "PocketPJDlg.h"
#include <iphlpapi.h>

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

#define TIMER_ID    101
static CPocketPJDlg *theDlg;

/////////////////////////////////////////////////////////////////////////////
// CPocketPJDlg dialog

CPocketPJDlg::CPocketPJDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CPocketPJDlg::IDD, pParent), m_PopUp(NULL)
{
	//{{AFX_DATA_INIT(CPocketPJDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	theDlg = this;

	m_PopUp = new CPopUpWnd(this);
	m_PopUp->Hide();

	unsigned i;
	m_PopUpCount = 0;
	for (i=0; i<POPUP_MAX_TYPE; ++i) {
	    m_PopUpState[i] = FALSE;
	}
}

void CPocketPJDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CPocketPJDlg)
	DDX_Control(pDX, IDC_URL, m_Url);
	DDX_Control(pDX, IDC_BUDDY_LIST, m_BuddyList);
	DDX_Control(pDX, IDC_BTN_ACTION, m_BtnUrlAction);
	DDX_Control(pDX, IDC_BTN_ACC, m_BtnAcc);
	DDX_Control(pDX, IDC_ACC_ID, m_AccId);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CPocketPJDlg, CDialog)
	//{{AFX_MSG_MAP(CPocketPJDlg)
	ON_BN_CLICKED(IDC_BTN_ACC, OnBtnAcc)
	ON_BN_CLICKED(IDC_BTN_ACTION, OnBtnAction)
	ON_COMMAND(IDC_ACC_SETTINGS, OnSettings)
	ON_COMMAND(IDC_URI_CALL, OnUriCall)
	ON_WM_TIMER()
	ON_COMMAND(IDC_URI_ADD_BUDDY, OnUriAddBuddy)
	ON_COMMAND(IDC_URI_DEL_BUDDY, OnUriDelBuddy)
	ON_COMMAND(IDC_ACC_ONLINE, OnAccOnline)
	ON_COMMAND(IDC_ACC_INVISIBLE, OnAccInvisible)
	ON_NOTIFY(NM_CLICK, IDC_BUDDY_LIST, OnClickBuddyList)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


void CPocketPJDlg::Error(const CString &title, pj_status_t rc)
{
    char errmsg[PJ_ERR_MSG_SIZE];
    wchar_t werrmsg[PJ_ERR_MSG_SIZE];

    pj_strerror(rc, errmsg, sizeof(errmsg));
    pj_ansi_to_unicode(errmsg, strlen(errmsg), werrmsg, PJ_ARRAY_SIZE(werrmsg));

    AfxMessageBox(title + _T(": ") + werrmsg);
}

BOOL CPocketPJDlg::Restart()
{
    unsigned i;
    pj_status_t status;

    char ver[80];
    sprintf(ver, "PocketPJ/%s", pj_get_version());

    ShowWindow(SW_SHOW);
    PopUp_Show(POPUP_REGISTRATION, ver,
	       "Starting up....", "", "", "", 0);

    KillTimer(TIMER_ID);

    // Destroy first.
    PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Cleaning up..");
    pjsua_destroy();

    m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_OFFLINE)) );
    UpdateWindow();


    // Create
    PopUp_Show(POPUP_REGISTRATION, ver,
	       "Starting up....", "Creating stack..", "", "", 0);

    status = pjsua_create();
    if (status != PJ_SUCCESS) {
	Error(_T("Error in creating library"), status);
	PopUp_Hide(POPUP_REGISTRATION);
	return FALSE;
    }

    pjsua_config cfg;
    pjsua_logging_config log_cfg;
    pjsua_media_config media_cfg;

    pjsua_config_default(&cfg);
    cfg.max_calls = 1;
    cfg.thread_cnt = 0;
    cfg.user_agent = pj_str(ver);

    cfg.cb.on_call_state = &on_call_state;
    cfg.cb.on_call_media_state = &on_call_media_state;
    cfg.cb.on_incoming_call = &on_incoming_call;
    cfg.cb.on_reg_state = &on_reg_state;
    cfg.cb.on_buddy_state = &on_buddy_state;
    cfg.cb.on_pager = &on_pager;

    /* Configure nameserver */
    char nameserver[60];
    {
	FIXED_INFO fi;
	PIP_ADDR_STRING pDNS = NULL;
	ULONG len = sizeof(fi);
	CString err;

	PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Retrieving network parameters..");
	if (GetNetworkParams(&fi, &len) != ERROR_SUCCESS) {
	    err = _T("Info: Error querying network parameters. You must configure DNS server.");
	} else if (fi.CurrentDnsServer) {
	    pDNS = fi.CurrentDnsServer;
	} else if (fi.DnsServerList.IpAddress.String[0] != 0) {
	    pDNS = &fi.DnsServerList;
	} else {
	    err = _T("Info: DNS server not configured. You must configure DNS server.");
	} 
	
	if (err.GetLength()) {
	    if (m_Cfg.m_DNS.GetLength()) {
		pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_DNS, m_Cfg.m_DNS.GetLength(),
				   nameserver, sizeof(nameserver));
		cfg.nameserver_count = 1;
		cfg.nameserver[0] = pj_str(nameserver);
	    } else {
		AfxMessageBox(err);
		pjsua_destroy();
		PopUp_Hide(POPUP_REGISTRATION);
		return FALSE;
	    }
	} else {
	    strcpy(nameserver, pDNS->IpAddress.String);
	    cfg.nameserver_count = 1;
	    cfg.nameserver[0] = pj_str(nameserver);
	}
    }

    char tmp_stun[80];
    if (m_Cfg.m_UseStun) {
	pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_StunSrv, m_Cfg.m_StunSrv.GetLength(),
			   tmp_stun, sizeof(tmp_stun));
	cfg.stun_host = pj_str(tmp_stun);
    }

    pjsua_logging_config_default(&log_cfg);
    log_cfg.msg_logging = PJ_TRUE;
    log_cfg.log_filename = pj_str("\\PocketPJ.TXT");

    pjsua_media_config_default(&media_cfg);
    media_cfg.clock_rate = 8000;
    media_cfg.audio_frame_ptime = 40;
    media_cfg.ec_tail_len = 0;
    media_cfg.ilbc_mode = 30;
    media_cfg.max_media_ports = 8;
    // use default quality setting
    //media_cfg.quality = 5;
    media_cfg.thread_cnt = 1;
    media_cfg.enable_ice = m_Cfg.m_UseIce;
    media_cfg.no_vad = !m_Cfg.m_VAD;

    if (m_Cfg.m_EchoSuppress) {
	media_cfg.ec_options = PJMEDIA_ECHO_SIMPLE;
	media_cfg.ec_tail_len = m_Cfg.m_EcTail;
    }

    // Init
    PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Initializing..");
    status = pjsua_init(&cfg, &log_cfg, &media_cfg);
    if (status != PJ_SUCCESS) {
	Error(_T("Error initializing library"), status);
	pjsua_destroy();
	PopUp_Hide(POPUP_REGISTRATION);
	return FALSE;
    }

    // Create one UDP transport
    PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Adding UDP transport..");
    pjsua_transport_id transport_id;
    pjsua_transport_config udp_cfg;

    pjsua_transport_config_default(&udp_cfg);
    udp_cfg.port = 0;
    status = pjsua_transport_create(PJSIP_TRANSPORT_UDP,
					&udp_cfg, &transport_id);
    if (status != PJ_SUCCESS) {
	Error(_T("Error creating UDP transport"), status);
	pjsua_destroy();
	PopUp_Hide(POPUP_REGISTRATION);
	return FALSE;
    }

    // Always instantiate TCP to support auto-switching to TCP when
    // packet is larger than 1300 bytes. If TCP is disabled when
    // no auto-switching will occur
    if (1) {
	// Create one TCP transport
	PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Adding TCP transport..");
	pjsua_transport_id transport_id;
	pjsua_transport_config tcp_cfg;

	pjsua_transport_config_default(&tcp_cfg);
	tcp_cfg.port = 0;
	status = pjsua_transport_create(PJSIP_TRANSPORT_TCP,
					&tcp_cfg, &transport_id);
	if (status != PJ_SUCCESS) {
	    Error(_T("Error creating TCP transport"), status);
	    pjsua_destroy();
	    PopUp_Hide(POPUP_REGISTRATION);
	    return FALSE;
	}
    }

    // Adjust codecs priority
    pj_str_t tmp;
    pjsua_codec_set_priority(pj_cstr(&tmp, "*"), 0);
    for (i=0; i<(unsigned)m_Cfg.m_Codecs.GetSize(); ++i) {
	CString codec = m_Cfg.m_Codecs.GetAt(i);
	char tmp_nam[80];

	pj_unicode_to_ansi((LPCTSTR)codec, codec.GetLength(),
			   tmp_nam, sizeof(tmp_nam));
	pjsua_codec_set_priority(pj_cstr(&tmp, tmp_nam), (pj_uint8_t)(200-i));
    }

    // Start!
    PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Starting..");
    status = pjsua_start();
    if (status != PJ_SUCCESS) {
	Error(_T("Error starting library"), status);
	pjsua_destroy();
	PopUp_Hide(POPUP_REGISTRATION);
	return FALSE;
    }

    // Add account
    PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Adding account..");
    char domain[80], username[80], passwd[80];
    char id[80], reg_uri[80];
    pjsua_acc_config acc_cfg;

    pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_Domain, m_Cfg.m_Domain.GetLength(),
		       domain, sizeof(domain));
    pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_User, m_Cfg.m_User.GetLength(),
		       username, sizeof(username));
    pj_unicode_to_ansi((LPCTSTR)m_Cfg.m_Password, m_Cfg.m_Password.GetLength(),
		       passwd, sizeof(passwd));

    snprintf(id, sizeof(id), "<sip:%s@%s>", username, domain);
    snprintf(reg_uri, sizeof(reg_uri), "sip:%s", domain);

    pjsua_acc_config_default(&acc_cfg);
    acc_cfg.id = pj_str(id);
    acc_cfg.reg_uri = pj_str(reg_uri);
    acc_cfg.cred_count = 1;
    acc_cfg.cred_info[0].scheme = pj_str("Digest");
    acc_cfg.cred_info[0].realm = pj_str("*");
    acc_cfg.cred_info[0].username = pj_str(username);
    acc_cfg.cred_info[0].data_type = 0;
    acc_cfg.cred_info[0].data = pj_str(passwd);

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
    acc_cfg.use_srtp = (m_Cfg.m_UseSrtp ? PJMEDIA_SRTP_OPTIONAL : PJMEDIA_SRTP_DISABLED);
    acc_cfg.srtp_secure_signaling = 0;
#endif

    acc_cfg.publish_enabled = m_Cfg.m_UsePublish;
    
    char route[80];
    if (m_Cfg.m_TCP) {
	snprintf(route, sizeof(route), "<sip:%s;lr;transport=tcp>", domain);
	acc_cfg.proxy[acc_cfg.proxy_cnt++] = pj_str(route);
    } else {
	snprintf(route, sizeof(route), "<sip:%s;lr>", domain);
	acc_cfg.proxy[acc_cfg.proxy_cnt++] = pj_str(route);
    }

    status = pjsua_acc_add(&acc_cfg, PJ_TRUE, &m_PjsuaAccId);
    if (status != PJ_SUCCESS) {
	Error(_T("Invalid account settings"), status);
	pjsua_destroy();
	PopUp_Hide(POPUP_REGISTRATION);
	return FALSE;
    }

    CString acc_text = m_Cfg.m_User + _T("@") + m_Cfg.m_Domain;
    m_AccId.SetWindowText(acc_text);

    PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE1, acc_text);
    PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE2, "Registering..");
    PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "");

    SetTimer(TIMER_ID, 100, NULL);
    return TRUE;
}


void CPocketPJDlg::PopUp_Show( PopUpType type, 
			        const CString& title1,
				const CString& title2,
				const CString& title3,
				const CString& btn1,
				const CString& btn2,
				unsigned userData)
{
    PJ_UNUSED_ARG(userData);

    if (!m_PopUpState[type])
	++m_PopUpCount;

    m_PopUpState[type] = TRUE;

    m_PopUpContent[type].m_Title1 = title1;
    m_PopUpContent[type].m_Title2 = title2;
    m_PopUpContent[type].m_Title3 = title3;
    m_PopUpContent[type].m_Btn1 = btn1;
    m_PopUpContent[type].m_Btn2 = btn2;

    m_PopUp->SetContent(m_PopUpContent[type]);
    m_PopUp->Show();
}

void CPocketPJDlg::PopUp_Modify(PopUpType type,
				PopUpElement el,
				const CString& text)
{
    switch (el) {
    case POPUP_EL_TITLE1:
	m_PopUpContent[type].m_Title1 = text;
	break;
    case POPUP_EL_TITLE2:
	m_PopUpContent[type].m_Title2 = text;
	break;
    case POPUP_EL_TITLE3:
	m_PopUpContent[type].m_Title3 = text;
	break;
    case POPUP_EL_BUTTON1:
	m_PopUpContent[type].m_Btn1 = text;
	break;
    case POPUP_EL_BUTTON2:
	m_PopUpContent[type].m_Btn1 = text;
	break;
    }

    m_PopUp->SetContent(m_PopUpContent[type]);
}

void CPocketPJDlg::PopUp_Hide(PopUpType type)
{
    if (m_PopUpState[type])
	--m_PopUpCount;

    m_PopUpState[type] = FALSE;

    if (m_PopUpCount == 0) {
	m_PopUp->Hide();
	UpdateWindow();
    } else {
	for (int i=POPUP_MAX_TYPE-1; i>=0; --i) {
	    if (m_PopUpState[i]) {
		m_PopUp->SetContent(m_PopUpContent[i]);
		break;
	    }
	}
    }
}

void CPocketPJDlg::OnCallState()
{
    pjsua_call_info ci;

    pjsua_call_get_info(0, &ci);
    
    switch (ci.state) {
    case PJSIP_INV_STATE_NULL:	    /**< Before INVITE is sent or received  */
	break;
    case PJSIP_INV_STATE_CALLING:   /**< After INVITE is sent		    */
	PopUp_Show(POPUP_CALL, "Calling..", ci.remote_info.ptr, "",
		   "", "Hangup", 0);
	break;
    case PJSIP_INV_STATE_INCOMING:  /**< After INVITE is received.	    */
	PopUp_Show(POPUP_CALL, "Incoming call..", ci.remote_info.ptr, "",
		   "Answer", "Hangup", 0);
	pjsua_call_answer(0, 180, NULL, NULL);
	if (m_Cfg.m_AutoAnswer)
	    OnPopUpButton(1);
	break;
    case PJSIP_INV_STATE_EARLY:	    /**< After response with To tag.	    */
    case PJSIP_INV_STATE_CONNECTING:/**< After 2xx is sent/received.	    */
    case PJSIP_INV_STATE_CONFIRMED:  /**< After ACK is sent/received.	    */
	{
	    CString stateText = ci.state_text.ptr;
	    PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE3, stateText);
	}
	break;
    case PJSIP_INV_STATE_DISCONNECTED:/**< Session is terminated.	    */
	PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE3, "Disconnected");
	PopUp_Hide(POPUP_CALL);
	break;
    }    
}

void CPocketPJDlg::on_call_state(pjsua_call_id call_id, pjsip_event *e)
{
    PJ_UNUSED_ARG(e);
    PJ_UNUSED_ARG(call_id);

    theDlg->OnCallState();
}

void CPocketPJDlg::on_call_media_state(pjsua_call_id call_id)
{
    pjsua_call_info call_info;

    pjsua_call_get_info(call_id, &call_info);
    if (call_info.media_status == PJSUA_CALL_MEDIA_ACTIVE) {
	pjsua_conf_connect(call_info.conf_slot, 0);
	pjsua_conf_connect(0, call_info.conf_slot);
    }
}

void CPocketPJDlg::on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
				    pjsip_rx_data *rdata)
{
    PJ_UNUSED_ARG(acc_id);
    PJ_UNUSED_ARG(call_id);
    PJ_UNUSED_ARG(rdata);
}

void CPocketPJDlg::OnRegState()
{
    pjsua_acc_info ai;
    pjsua_acc_get_info(m_PjsuaAccId, &ai);

    CString acc_text = m_Cfg.m_User + _T("@") + m_Cfg.m_Domain;

    if (ai.expires>0 && ai.status/100==2) {
	/* Registration success */
	HBITMAP old = m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_ONLINE)) );
	PJ_UNUSED_ARG(old);
	acc_text += " (OK)";
	m_AccId.SetWindowText(acc_text);
    } else if (ai.status/100 != 2) {
	acc_text += " (err)";
	Error(_T("SIP registration error"), PJSIP_ERRNO_FROM_SIP_STATUS(ai.status));
	m_AccId.SetWindowText(acc_text);
    }
    PopUp_Hide(POPUP_REGISTRATION);
}

void CPocketPJDlg::on_reg_state(pjsua_acc_id acc_id)
{
    PJ_UNUSED_ARG(acc_id);

    theDlg->OnRegState();
}

void CPocketPJDlg::on_buddy_state(pjsua_buddy_id buddy_id)
{
    PJ_UNUSED_ARG(buddy_id);

    theDlg->RedrawBuddyList();
}

void CPocketPJDlg::on_pager(pjsua_call_id call_id, const pj_str_t *from, 
			    const pj_str_t *to, const pj_str_t *contact,
			    const pj_str_t *mime_type, const pj_str_t *text)
{
    PJ_UNUSED_ARG(call_id);
    PJ_UNUSED_ARG(from);
    PJ_UNUSED_ARG(to);
    PJ_UNUSED_ARG(contact);
    PJ_UNUSED_ARG(mime_type);
    PJ_UNUSED_ARG(text);
}

/////////////////////////////////////////////////////////////////////////////
// CPocketPJDlg message handlers

BOOL CPocketPJDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	CenterWindow(GetDesktopWindow());	// center to the hpc screen
 
	// TODO: Add extra initialization here
	
	m_Cfg.LoadRegistry();
	//ShowWindow(SW_SHOW);
	m_AccId.SetWindowText(m_Cfg.m_User);

	CImageList *il = new CImageList;
	VERIFY(il->Create(16, 16, ILC_COLOR|ILC_MASK, 2, 4));

	CBitmap *bmp = new CBitmap;
	bmp->LoadBitmap(MAKEINTRESOURCE(IDB_BLANK));
	il->Add(bmp, RGB(255,255,255));
	bmp = new CBitmap;
	bmp->LoadBitmap(MAKEINTRESOURCE(IDB_ONLINE));
	il->Add(bmp, RGB(255,255,255));
	
	m_BuddyList.SetImageList(il, LVSIL_SMALL);

	if (m_Cfg.m_Domain.GetLength()==0 || Restart() == FALSE) {
	    for (;;) {
		CSettingsDlg dlg(m_Cfg);
		if (dlg.DoModal() != IDOK) {
		    EndDialog(IDOK);
		    return TRUE;
		}

		m_Cfg.SaveRegistry();

		if (Restart())
		    break;
	    }
	}

	RedrawBuddyList();
	return TRUE;  // return TRUE  unless you set the focus to a control
}



void CPocketPJDlg::OnBtnAcc() 
{
    CMenu menu;
    VERIFY(menu.LoadMenu(IDR_ACC_MENU));
    CMenu* pPopup = menu.GetSubMenu(0);
    ASSERT(pPopup != NULL);

    RECT r;
    m_BtnAcc.GetWindowRect(&r);
    pPopup->TrackPopupMenu(TPM_LEFTALIGN, r.left+4, r.top+4, this);
}

void CPocketPJDlg::OnBtnAction() 
{
    CMenu menu;
    VERIFY(menu.LoadMenu(IDR_URI_MENU));
    CMenu* pPopup = menu.GetSubMenu(0);
    ASSERT(pPopup != NULL);

    RECT r;
    this->m_BtnUrlAction.GetWindowRect(&r);
    pPopup->TrackPopupMenu(TPM_LEFTALIGN, r.left+4, r.top+4, this);
}

void CPocketPJDlg::OnSettings() 
{
    for (;;) {
	CSettingsDlg dlg(m_Cfg);
	if (dlg.DoModal() != IDOK) {
	    return;
	}

	m_Cfg.SaveRegistry();

	if (Restart())
	    break;
    }
}

void CPocketPJDlg::OnOK()
{
    if (AfxMessageBox(_T("Quit PocketPJ?"), MB_YESNO)==IDYES) {
	KillTimer(TIMER_ID);
	PopUp_Show(POPUP_REGISTRATION, "", "Shutting down..", "", "", "", 0);
	pjsua_destroy();
	CDialog::OnOK();
	PopUp_Hide(POPUP_REGISTRATION);
	m_Cfg.SaveRegistry();
	return;
    }
}

void CPocketPJDlg::OnTimer(UINT nIDEvent) 
{
    pjsua_handle_events(10);
    CDialog::OnTimer(nIDEvent);
}

int  CPocketPJDlg::FindBuddyInPjsua(const CString &Uri)
{
    char uri[80];
    pjsua_buddy_id  id[128];
    unsigned i, count = PJ_ARRAY_SIZE(id);

    if (pjsua_enum_buddies(id, &count) != PJ_SUCCESS)
	return PJSUA_INVALID_ID;
    if (count==0)
	return PJSUA_INVALID_ID;

    pj_unicode_to_ansi((LPCTSTR)Uri, Uri.GetLength(), uri, sizeof(uri));

    for (i=0; i<count; ++i) {
	pjsua_buddy_info bi;
	pjsua_buddy_get_info(id[i], &bi);
	if (pj_strcmp2(&bi.uri, uri)==0)
	    return i;
    }

    return PJSUA_INVALID_ID;
}

int  CPocketPJDlg::FindBuddyInCfg(const CString &uri)
{
    int i;
    for (i=0; i<m_Cfg.m_BuddyList.GetSize(); ++i) {
	if (m_Cfg.m_BuddyList.GetAt(0) == uri) {
	    return i;
	}
    }
    return -1;
}

void CPocketPJDlg::RedrawBuddyList()
{
    int i;

    m_BuddyList.DeleteAllItems();

    for (i=0; i<m_Cfg.m_BuddyList.GetSize(); ++i) {
	int isOnline;
	int id;

	id = FindBuddyInPjsua(m_Cfg.m_BuddyList.GetAt(i));
	if (id != PJSUA_INVALID_ID) {
	    pjsua_buddy_info bi;
	    pjsua_buddy_get_info(id, &bi);
	    isOnline = (bi.status == PJSUA_BUDDY_STATUS_ONLINE);
	} else {
	    isOnline = 0;
	}

	LVITEM lvi;
	memset(&lvi, 0, sizeof(lvi));
	lvi.mask = LVIF_TEXT  | LVIF_IMAGE;
	lvi.iItem = i;
	lvi.iImage = isOnline;
	lvi.pszText = (LPTSTR)(LPCTSTR)m_Cfg.m_BuddyList.GetAt(i);

	m_BuddyList.InsertItem(&lvi);
    }
}

void CPocketPJDlg::OnUriCall() 
{
    char tmp[120];
    CString uri;
    pj_status_t status;

    m_Url.GetWindowText(uri);
    pj_unicode_to_ansi((LPCTSTR)uri, uri.GetLength(), tmp, sizeof(tmp));
    if ((status=pjsua_verify_sip_url(tmp)) != PJ_SUCCESS) {
	Error("The URL is not valid SIP URL", status);
	return;
    }

    pj_str_t dest_uri = pj_str(tmp);
    pjsua_call_id call_id;

    status = pjsua_call_make_call(m_PjsuaAccId, &dest_uri, 0, NULL, NULL, &call_id);

    if (status != PJ_SUCCESS)
	Error("Unable to make call", status);
}

void CPocketPJDlg::OnUriAddBuddy() 
{
    int i;
    char tmp[120];
    CString uri;
    pj_status_t status;

    m_Url.GetWindowText(uri);
    pj_unicode_to_ansi((LPCTSTR)uri, uri.GetLength(), tmp, sizeof(tmp));
    if ((status=pjsua_verify_sip_url(tmp)) != PJ_SUCCESS) {
	Error("The URL is not valid SIP URL", status);
	return;
    }

    for (i=0; i<m_Cfg.m_BuddyList.GetSize(); ++i) {
	if (m_Cfg.m_BuddyList.GetAt(0) == uri) {
	    AfxMessageBox(_T("The URI is already in the buddy list"));
	    return;
	}
    }

    m_Cfg.m_BuddyList.Add(uri);
    RedrawBuddyList();
}

void CPocketPJDlg::OnUriDelBuddy() 
{
    CString uri;

    m_Url.GetWindowText(uri);
    int i = FindBuddyInCfg(uri);
    if (i<0) {
	/* Buddy not found */
	return;
    }

    m_Cfg.m_BuddyList.RemoveAt(i);
    RedrawBuddyList();
    AfxMessageBox(_T("Buddy " + uri + " deleted"));
}

void CPocketPJDlg::OnAccOnline() 
{
    pjsua_acc_set_online_status(m_PjsuaAccId, PJ_TRUE);
    m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_ONLINE)) );
}

void CPocketPJDlg::OnAccInvisible() 
{
    pjsua_acc_set_online_status(m_PjsuaAccId, PJ_FALSE);
    m_BtnAcc.SetBitmap(::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_INVISIBLE)) );
}

void CPocketPJDlg::OnPopUpButton(int btnNo)
{
    if (btnNo == 1) {
	pjsua_call_answer(0, 200, NULL, 0);
	PopUp_Modify(POPUP_CALL, POPUP_EL_BUTTON1, "");
    } else if (btnNo == 2) {
	// Hangup button
	PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE2, "Hang up..");
	PopUp_Modify(POPUP_CALL, POPUP_EL_TITLE3, "");
	pjsua_call_hangup(0, PJSIP_SC_DECLINE, 0, 0);
    }
}

void CPocketPJDlg::OnClickBuddyList(NMHDR* pNMHDR, LRESULT* pResult) 
{
    POSITION pos = m_BuddyList.GetFirstSelectedItemPosition();

    PJ_UNUSED_ARG(pNMHDR);

    if (pos != NULL) {
	int iItem = m_BuddyList.GetNextSelectedItem(pos);
	CString uri = m_BuddyList.GetItemText(iItem, 0);
	m_Url.SetWindowText(uri);
    }
    *pResult = 0;
}
