// pjsua_wince.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "pjsua_wince.h"
#include <commctrl.h>
#include <pjsua-lib/pjsua.h>

#define MAX_LOADSTRING 100

// Global Variables:
static HINSTANCE    hInst;
static HWND	    hMainWnd;
static HWND	    hwndCB;
static HWND	    hwndGlobalStatus, hwndURI, hwndCallStatus;
static HWND	    hwndActionButton, hwndExitButton;



//
// Basic config.
//
#define SIP_PORT	5060


//
// Destination URI (to make call, or to subscribe presence)
//
#define SIP_DST_URI	"sip:192.168.0.7:5061"

//
// Account
//
#define HAS_SIP_ACCOUNT	0	// 0 to disable registration
#define SIP_DOMAIN	"server"
#define SIP_REALM	"server"
#define SIP_USER	"user"
#define SIP_PASSWD	"secret"

//
// Outbound proxy for all accounts
//
#define SIP_PROXY	NULL
//#define SIP_PROXY	"sip:192.168.0.2;lr"


//
// Configure nameserver if DNS SRV is to be used with both SIP
// or STUN (for STUN see other settings below)
//
#define NAMESERVER	NULL
//#define NAMESERVER	"62.241.163.201"

//
// STUN server
#if 0
	// Use this to have the STUN server resolved normally
#   define STUN_DOMAIN	NULL
#   define STUN_SERVER	"192.168.0.2"
#elif 0
	// Use this to have the STUN server resolved with DNS SRV
#   define STUN_DOMAIN	"iptel.org"
#   define STUN_SERVER	NULL
#else
	// Use this to disable STUN
#   define STUN_DOMAIN	NULL
#   define STUN_SERVER	NULL
#endif

//
// Use ICE?
//
#define USE_ICE		1


//
// Globals
//
static pj_pool_t   *g_pool;
static pj_str_t	    g_local_uri;
static int	    g_current_acc;
static int	    g_current_call = PJSUA_INVALID_ID;
static int	    g_current_action;

enum
{
    ID_GLOBAL_STATUS	= 21,
    ID_URI,
    ID_CALL_STATUS,
    ID_POLL_TIMER,
};

enum
{
    ID_MENU_NONE	= 64,
    ID_MENU_CALL,
    ID_MENU_ANSWER,
    ID_MENU_DISCONNECT,
    ID_BTN_ACTION,
};


// Forward declarations of functions included in this code module:
static ATOM		MyRegisterClass	(HINSTANCE, LPTSTR);
BOOL			InitInstance	(HINSTANCE, int);
static void		OnCreate	(HWND hWnd);
static LRESULT CALLBACK	WndProc		(HWND, UINT, WPARAM, LPARAM);



/////////////////////////////////////////////////////////////////////////////

static void OnError(const wchar_t *title, pj_status_t status)
{
    char errmsg[PJ_ERR_MSG_SIZE];
    PJ_DECL_UNICODE_TEMP_BUF(werrmsg, PJ_ERR_MSG_SIZE);

    pj_strerror(status, errmsg, sizeof(errmsg));
    
    MessageBox(NULL, PJ_STRING_TO_NATIVE(errmsg, werrmsg, PJ_ERR_MSG_SIZE),
	       title, MB_OK);
}


static void SetLocalURI(const char *uri, int len, bool enabled=true)
{
    wchar_t tmp[128];
    if (len==-1) len=pj_ansi_strlen(uri);
    pj_ansi_to_unicode(uri, len, tmp, PJ_ARRAY_SIZE(tmp));
    SetDlgItemText(hMainWnd, ID_GLOBAL_STATUS, tmp);
    EnableWindow(hwndGlobalStatus, enabled?TRUE:FALSE);
}



static void SetURI(const char *uri, int len, bool enabled=true)
{
    wchar_t tmp[128];
    if (len==-1) len=pj_ansi_strlen(uri);
    pj_ansi_to_unicode(uri, len, tmp, PJ_ARRAY_SIZE(tmp));
    SetDlgItemText(hMainWnd, ID_URI, tmp);
    EnableWindow(hwndURI, enabled?TRUE:FALSE);
}


static void SetCallStatus(const char *state, int len)
{
    wchar_t tmp[128];
    if (len==-1) len=pj_ansi_strlen(state);
    pj_ansi_to_unicode(state, len, tmp, PJ_ARRAY_SIZE(tmp));
    SetDlgItemText(hMainWnd, ID_CALL_STATUS, tmp);
}

static void SetAction(int action, bool enable=true)
{
    HMENU hMenu;

    hMenu = CommandBar_GetMenu(hwndCB, 0);

    RemoveMenu(hMenu, ID_MENU_NONE, MF_BYCOMMAND);
    RemoveMenu(hMenu, ID_MENU_CALL, MF_BYCOMMAND);
    RemoveMenu(hMenu, ID_MENU_ANSWER, MF_BYCOMMAND);
    RemoveMenu(hMenu, ID_MENU_DISCONNECT, MF_BYCOMMAND);

    switch (action) {
    case ID_MENU_NONE:
	InsertMenu(hMenu, ID_EXIT, MF_BYCOMMAND, action, TEXT("None"));
	SetWindowText(hwndActionButton, TEXT("-"));
	break;
    case ID_MENU_CALL:
	InsertMenu(hMenu, ID_EXIT, MF_BYCOMMAND, action, TEXT("Call"));
	SetWindowText(hwndActionButton, TEXT("&Call"));
	break;
    case ID_MENU_ANSWER:
	InsertMenu(hMenu, ID_EXIT, MF_BYCOMMAND, action, TEXT("Answer"));
	SetWindowText(hwndActionButton, TEXT("&Answer"));
	break;
    case ID_MENU_DISCONNECT:
	InsertMenu(hMenu, ID_EXIT, MF_BYCOMMAND, action, TEXT("Hangup"));
	SetWindowText(hwndActionButton, TEXT("&Hangup"));
	break;
    }

    EnableMenuItem(hMenu, action, MF_BYCOMMAND | (enable?MF_ENABLED:MF_GRAYED));
    DrawMenuBar(hMainWnd);

    g_current_action = action;
}


/*
 * Handler when invite state has changed.
 */
static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
{
    pjsua_call_info call_info;

    PJ_UNUSED_ARG(e);

    pjsua_call_get_info(call_id, &call_info);

    if (call_info.state == PJSIP_INV_STATE_DISCONNECTED) {

	g_current_call = PJSUA_INVALID_ID;
	SetURI(SIP_DST_URI, -1);
	SetAction(ID_MENU_CALL);
	//SetCallStatus(call_info.state_text.ptr, call_info.state_text.slen);
	SetCallStatus(call_info.last_status_text.ptr, call_info.last_status_text.slen);

    } else {
	//if (g_current_call == PJSUA_INVALID_ID)
	//    g_current_call = call_id;

	if (call_info.remote_contact.slen)
	    SetURI(call_info.remote_contact.ptr, call_info.remote_contact.slen, false);
	else
	    SetURI(call_info.remote_info.ptr, call_info.remote_info.slen, false);

	if (call_info.state == PJSIP_INV_STATE_CONFIRMED)
	    SetAction(ID_MENU_DISCONNECT);

	SetCallStatus(call_info.state_text.ptr, call_info.state_text.slen);
    }
}


/*
 * Callback on media state changed event.
 * The action may connect the call to sound device, to file, or
 * to loop the call.
 */
static void 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);
    }
}


/**
 * Handler when there is incoming call.
 */
static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
			     pjsip_rx_data *rdata)
{
    pjsua_call_info call_info;

    PJ_UNUSED_ARG(acc_id);
    PJ_UNUSED_ARG(rdata);

    if (g_current_call != PJSUA_INVALID_ID) {
	pj_str_t reason;
	reason = pj_str("Another call is in progress");
	pjsua_call_answer(call_id, PJSIP_SC_BUSY_HERE, &reason, NULL);
	return;
    }

    g_current_call = call_id;

    pjsua_call_get_info(call_id, &call_info);

    SetAction(ID_MENU_ANSWER);
    SetURI(call_info.remote_info.ptr, call_info.remote_info.slen, false);
    pjsua_call_answer(call_id, 200, NULL, NULL);
}


/*
 * Handler registration status has changed.
 */
static void on_reg_state(pjsua_acc_id acc_id)
{
    PJ_UNUSED_ARG(acc_id);

    // Log already written.
}


/*
 * Handler on buddy state changed.
 */
static void on_buddy_state(pjsua_buddy_id buddy_id)
{
}


/**
 * Incoming IM message (i.e. MESSAGE request)!
 */
static void 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)
{
}


/**
 * Received typing indication
 */
static void on_typing(pjsua_call_id call_id, const pj_str_t *from,
		      const pj_str_t *to, const pj_str_t *contact,
		      pj_bool_t is_typing)
{
}


static BOOL OnInitStack(void)
{
    pjsua_config	    cfg;
    pjsua_logging_config    log_cfg;
    pjsua_media_config	    media_cfg;
    pjsua_transport_config  udp_cfg;
    pjsua_transport_config  rtp_cfg;
    pjsua_transport_id	    transport_id;
    pjsua_transport_info    transport_info;
    pj_str_t		    tmp;
    pj_status_t status;

    /* Create pjsua */
    status = pjsua_create();
    if (status != PJ_SUCCESS) {
	OnError(TEXT("Error creating pjsua"), status);
	return FALSE;
    }

    /* Create global pool for application */
    g_pool = pjsua_pool_create("pjsua", 4000, 4000);

    /* Init configs */
    pjsua_config_default(&cfg);
    pjsua_media_config_default(&media_cfg);
    pjsua_transport_config_default(&udp_cfg);
    udp_cfg.port = SIP_PORT;

    pjsua_transport_config_default(&rtp_cfg);
    rtp_cfg.port = 40000;

    pjsua_logging_config_default(&log_cfg);
    log_cfg.level = 5;
    log_cfg.log_filename = pj_str("\\pjsua.txt");
    log_cfg.msg_logging = 1;
    log_cfg.decor = pj_log_get_decor() | PJ_LOG_HAS_CR;

    /* Setup media */
    media_cfg.clock_rate = 8000;
    media_cfg.ec_options = PJMEDIA_ECHO_SIMPLE;
    media_cfg.ec_tail_len = 256;
    media_cfg.quality = 1;
    media_cfg.ptime = 20;
    media_cfg.enable_ice = USE_ICE;

    /* Initialize application callbacks */
    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;
    cfg.cb.on_typing = &on_typing;

    if (SIP_PROXY) {
	    cfg.outbound_proxy_cnt = 1;
	    cfg.outbound_proxy[0] = pj_str(SIP_PROXY);
    }
    
    if (NAMESERVER) {
	    cfg.nameserver_count = 1;
	    cfg.nameserver[0] = pj_str(NAMESERVER);
    }
    
    if (NAMESERVER && STUN_DOMAIN) {
	    cfg.stun_domain = pj_str(STUN_DOMAIN);
    } else if (STUN_SERVER) {
	    cfg.stun_host = pj_str(STUN_SERVER);
    }
    
    
    /* Initialize pjsua */
    status = pjsua_init(&cfg, &log_cfg, &media_cfg);
    if (status != PJ_SUCCESS) {
	OnError(TEXT("Initialization error"), status);
	return FALSE;
    }

    /* Set codec priority */
    pjsua_codec_set_priority(pj_cstr(&tmp, "pcmu"), 240);
    pjsua_codec_set_priority(pj_cstr(&tmp, "pcma"), 230);
    pjsua_codec_set_priority(pj_cstr(&tmp, "speex/8000"), 190);
    pjsua_codec_set_priority(pj_cstr(&tmp, "ilbc"), 189);
    pjsua_codec_set_priority(pj_cstr(&tmp, "speex/16000"), 180);
    pjsua_codec_set_priority(pj_cstr(&tmp, "speex/32000"), 0);
    pjsua_codec_set_priority(pj_cstr(&tmp, "gsm"), 100);


    /* Add UDP transport and the corresponding PJSUA account */
    status = pjsua_transport_create(PJSIP_TRANSPORT_UDP,
				    &udp_cfg, &transport_id);
    if (status != PJ_SUCCESS) {
	OnError(TEXT("Error starting SIP transport"), status);
	return FALSE;
    }

    pjsua_transport_get_info(transport_id, &transport_info);

    g_local_uri.ptr = (char*)pj_pool_alloc(g_pool, 128);
    g_local_uri.slen = pj_ansi_sprintf(g_local_uri.ptr,
				       "<sip:%.*s:%d>",
				       (int)transport_info.local_name.host.slen,
				       transport_info.local_name.host.ptr,
				       transport_info.local_name.port);


    /* Add local account */
    pjsua_acc_add_local(transport_id, PJ_TRUE, &g_current_acc);
    pjsua_acc_set_online_status(g_current_acc, PJ_TRUE);

    /* Add account */
    if (HAS_SIP_ACCOUNT) {
	pjsua_acc_config cfg;

	pjsua_acc_config_default(&cfg);
	cfg.id = pj_str("sip:" SIP_USER "@" SIP_DOMAIN);
	cfg.reg_uri = pj_str("sip:" SIP_DOMAIN);
	cfg.cred_count = 1;
	cfg.cred_info[0].realm = pj_str(SIP_REALM);
	cfg.cred_info[0].scheme = pj_str("digest");
	cfg.cred_info[0].username = pj_str(SIP_USER);
	cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
	cfg.cred_info[0].data = pj_str(SIP_PASSWD);

	status = pjsua_acc_add(&cfg, PJ_TRUE, &g_current_acc);
	if (status != PJ_SUCCESS) {
	    pjsua_destroy();
	    return PJ_FALSE;
	}
    }

    /* Add buddy */
    if (SIP_DST_URI) {
    	pjsua_buddy_config bcfg;
    
    	pjsua_buddy_config_default(&bcfg);
    	bcfg.uri = pj_str(SIP_DST_URI);
    	bcfg.subscribe = PJ_FALSE;
    	
    	pjsua_buddy_add(&bcfg, NULL);
    }

    /* Start pjsua */
    status = pjsua_start();
    if (status != PJ_SUCCESS) {
	OnError(TEXT("Error starting pjsua"), status);
	return FALSE;
    }

    return TRUE;
}


//////////////////////////////////////////////////////////////////////////////

int WINAPI WinMain(HINSTANCE hInstance,
		   HINSTANCE hPrevInstance,
		   LPTSTR    lpCmdLine,
		   int       nCmdShow)
{
    MSG msg;
    HACCEL hAccelTable;
    


    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow)) 
    {
	return FALSE;
    }
    
    hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_PJSUA_WINCE);
    
    
    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0)) 
    {
	if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
	{
	    TranslateMessage(&msg);
	    DispatchMessage(&msg);
	}
    }
    
    return msg.wParam;
}

static ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
    WNDCLASS wc;

    wc.style		= CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc	= (WNDPROC) WndProc;
    wc.cbClsExtra	= 0;
    wc.cbWndExtra	= 0;
    wc.hInstance	= hInstance;
    wc.hIcon		= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PJSUA_WINCE));
    wc.hCursor		= 0;
    wc.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName	= 0;
    wc.lpszClassName	= szWindowClass;

    return RegisterClass(&wc);
}


/* Callback upon NAT detection completion */
static void nat_detect_cb(void *user_data,
			  const pj_stun_nat_detect_result *res)
{
    PJ_UNUSED_ARG(user_data);

    if (res->status != PJ_SUCCESS) {
	char msg[250];
	pj_ansi_snprintf(msg, sizeof(msg), "NAT detection failed: %s",
			 res->status_text);
	SetCallStatus(msg, pj_ansi_strlen(msg));
    } else {
	char msg[250];
	pj_ansi_snprintf(msg, sizeof(msg), "NAT type is %s",
			 res->nat_type_name);
	SetCallStatus(msg, pj_ansi_strlen(msg));
    }
}


BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND	hWnd;
    TCHAR	szTitle[MAX_LOADSTRING];
    TCHAR	szWindowClass[MAX_LOADSTRING];

    hInst = hInstance;

    /* Init stack */
    if (OnInitStack() == FALSE)
	return FALSE;

    LoadString(hInstance, IDC_PJSUA_WINCE, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance, szWindowClass);

    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
	    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 200, 
	    NULL, NULL, hInstance, NULL);

    if (!hWnd)
    {	
	    return FALSE;
    }

    hMainWnd = hWnd;
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    if (hwndCB)
	CommandBar_Show(hwndCB, TRUE);

    SetTimer(hMainWnd, ID_POLL_TIMER, 50, NULL);

    pjsua_detect_nat_type(NULL, &nat_detect_cb);
    return TRUE;
}


static void OnCreate(HWND hWnd)
{
    enum 
    {
	X = 10,
	Y = 40,
	W = 220,
	H = 30,
    };

    DWORD dwStyle;

    hMainWnd = hWnd;

    hwndCB = CommandBar_Create(hInst, hWnd, 1);			
    CommandBar_InsertMenubar(hwndCB, hInst, IDM_MENU, 0);   
    CommandBar_AddAdornments(hwndCB, 0, 0);

    // Create global status text
    dwStyle = WS_CHILD | WS_VISIBLE | WS_DISABLED | ES_LEFT;  
    hwndGlobalStatus = CreateWindow(
                TEXT("EDIT"),   // Class name
                NULL,           // Window text
                dwStyle,        // Window style
                X,		// x-coordinate of the upper-left corner
                Y+0,            // y-coordinate of the upper-left corner
                W,		// Width of the window for the edit
                                // control
                H-5,		// Height of the window for the edit
                                // control
                hWnd,           // Window handle to the parent window
                (HMENU) ID_GLOBAL_STATUS, // Control identifier
                hInst,           // Instance handle
                NULL);          // Specify NULL for this parameter when 
                                // you create a control
    SetLocalURI(g_local_uri.ptr, g_local_uri.slen, false);


    // Create URI edit
    dwStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER;  
    hwndURI = CreateWindow (
                TEXT("EDIT"),   // Class name
                NULL,		// Window text
                dwStyle,        // Window style
                X,  // x-coordinate of the upper-left corner
                Y+H,  // y-coordinate of the upper-left corner
                W,  // Width of the window for the edit
                                // control
                H-5,  // Height of the window for the edit
                                // control
                hWnd,           // Window handle to the parent window
                (HMENU) ID_URI, // Control identifier
                hInst,           // Instance handle
                NULL);          // Specify NULL for this parameter when 
                                // you create a control

    // Create action Button
    hwndActionButton = CreateWindow( L"button", L"Action", 
                         WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 
                         X, Y+2*H, 
			 60, H-5, hWnd, 
                         (HMENU) ID_BTN_ACTION,
                         hInst, NULL );

    // Create exit button
    hwndExitButton = CreateWindow( L"button", L"E&xit", 
                         WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 
                         X+70, Y+2*H, 
			 60, H-5, hWnd, 
                         (HMENU) ID_EXIT,
                         hInst, NULL );


    // Create call status edit
    dwStyle = WS_CHILD | WS_VISIBLE | WS_DISABLED;  
    hwndCallStatus = CreateWindow (
                TEXT("EDIT"),   // Class name
                NULL,		// Window text
                dwStyle,        // Window style
                X,  // x-coordinate of the upper-left corner
                Y+3*H,  // y-coordinate of the upper-left corner
                W,  // Width of the window for the edit
                                // control
                H-5,  // Height of the window for the edit
                                // control
                hWnd,           // Window handle to the parent window
                (HMENU) ID_CALL_STATUS, // Control identifier
                hInst,           // Instance handle
                NULL);          // Specify NULL for this parameter when 
                                // you create a control
    SetCallStatus("Ready", 5);
    SetAction(ID_MENU_CALL);
    SetURI(SIP_DST_URI, -1);
    SetFocus(hWnd);

}


static void OnDestroy(void)
{
    pjsua_destroy();
}

static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    
    switch (message) {
    case WM_KEYUP:
	if (wParam==114) {
	    wParam = ID_MENU_CALL;
	} else if (wParam==115) {
	    if (g_current_call == PJSUA_INVALID_ID)
		wParam = ID_EXIT;
	    else
		wParam = ID_MENU_DISCONNECT;
	} else
	    break;

    case WM_COMMAND:
	wmId    = LOWORD(wParam); 
	wmEvent = HIWORD(wParam); 
	if (wmId == ID_BTN_ACTION)
	    wmId = g_current_action;
	switch (wmId)
	{
	case ID_MENU_CALL:
	    if (g_current_call != PJSUA_INVALID_ID) {
		MessageBox(NULL, TEXT("Can not make call"), 
			   TEXT("You already have one call active"), MB_OK);
	    }
	    pj_str_t dst_uri;
	    wchar_t text[256];
	    char tmp[256];
	    pj_status_t status;

	    GetWindowText(hwndURI, text, PJ_ARRAY_SIZE(text));
	    pj_unicode_to_ansi(text, pj_unicode_strlen(text),
			       tmp, sizeof(tmp));
	    dst_uri.ptr = tmp;
	    dst_uri.slen = pj_ansi_strlen(tmp);
	    status = pjsua_call_make_call(g_current_acc,
						      &dst_uri, 0, NULL,
						      NULL, &g_current_call);
	    if (status != PJ_SUCCESS)
		OnError(TEXT("Unable to make call"), status);
	    break;
	case ID_MENU_ANSWER:
	    if (g_current_call == PJSUA_INVALID_ID)
		MessageBox(NULL, TEXT("Can not answer"), 
			   TEXT("There is no call!"), MB_OK);
	    else
		pjsua_call_answer(g_current_call, 200, NULL, NULL);
	    break;
	case ID_MENU_DISCONNECT:
	    if (g_current_call == PJSUA_INVALID_ID)
		MessageBox(NULL, TEXT("Can not disconnect"), 
			   TEXT("There is no call!"), MB_OK);
	    else
		pjsua_call_hangup(g_current_call, PJSIP_SC_DECLINE, NULL, NULL);
	    break;
	case ID_EXIT:
	    DestroyWindow(hWnd);
	    break;
	default:
	    return DefWindowProc(hWnd, message, wParam, lParam);
	}
	break;

    case WM_CREATE:
	OnCreate(hWnd);
	break;

    case WM_DESTROY:
	OnDestroy();
	CommandBar_Destroy(hwndCB);
	PostQuitMessage(0);
	break;

    case WM_TIMER:
	pjsua_handle_events(1);
	break;

    default:
	return DefWindowProc(hWnd, message, wParam, lParam);
    }
   return 0;
}

