/************************************************************
 * Filename      : NavXSWebClient.js
 * Copyright     : 2006 NavXS.com
 * Author        : helge.timenes@navxs.com
 * Creation Date : 04.08.2006
 * Description   : Javascript for the NavXS Ajax Web Client
 * Depends on    : Cookie.js by Jason Davies: http://www.netspade.com/articles/2005/11/16/javascript-cookies
 *               : Google map API: http://maps.google.com/maps
 *
 ************************************************************/
 

    var logoutContainer;
    var contactContainer;
    var messageContainer;
    var popupContainer;
    var map = null;
    var onlineMapIcon;
    var onlineStationaryMapIcon;
    var offlineMapIcon;
    var sessionID = null;
    var user = null;
    var onlineContacts = null;
    var offlineContacts = null;
    var requestedContacts = null;
    var requestedContacts = null;
    var requestingContacts = null;
    var allContactPositions = null; // user + online + offline
    var allContactMarkers = null; // user + online + offline
    var allContacts = null; // user + online + offline
    var messages = null;
    var positionLoadIndex = 0;
    var autoCenterEmail = "";
    var firstPositionDownload = true;
    var synchLoopEnabled=false;
    var showMessageBubbles=true;
    
    function navxsInitPage(logoutDiv, contactDiv, messageDiv, popupDiv, googleMap){
    
        logoutContainer = logoutDiv;
        contactContainer = contactDiv;
        messageContainer = messageDiv;
        popupContainer = popupDiv;
        popupContainer.set_text('');
        
        // set up map
        map = googleMap;
        map.addControl(new GLargeMapControl());
        map.addControl(new GMapTypeControl());
        map.setCenter(new GLatLng(48.13, 11.6), 4);

        GEvent.addListener(
             map, 
             "click", 
             function(marker, point) {
                 displayContactInfo(marker);
             }
        );

        onlineMapIcon = new GIcon();
        onlineMapIcon.image = "./images/icon_online.png";
        onlineMapIcon.iconSize = new GSize(12, 12);
        onlineMapIcon.iconAnchor = new GPoint(6, 6);
        onlineMapIcon.infoWindowAnchor = new GPoint(6, 6);
        onlineStationaryMapIcon = new GIcon();
        onlineStationaryMapIcon.image = "./images/icon_online_stationary.png";
        onlineStationaryMapIcon.iconSize = new GSize(12, 12);
        onlineStationaryMapIcon.iconAnchor = new GPoint(6, 6);
        onlineStationaryMapIcon.infoWindowAnchor = new GPoint(6, 6);
        offlineMapIcon = new GIcon();
        offlineMapIcon.image = "./images/icon_offline.png";
        offlineMapIcon.iconSize = new GSize(12, 12);
        offlineMapIcon.iconAnchor = new GPoint(6, 6);
        offlineMapIcon.infoWindowAnchor = new GPoint(6, 6);
        
        // check if session ID exists in cookie
        sessionID = getCookie("NavXS_SessionID");

        if(sessionID==null){
            displayLogin();
        }
        else{
            contactContainer.set_text("Welcome back! Your contacts will be with you in just a few seconds ;-)");               

            // display logout link
            var html ='<u><span style="cursor:pointer;" title="Click to log out." onclick="wsLogout()">Logout</span></u>';
            logoutContainer.set_text(html);               

            wsGetUser();
        }

    }
    
    function displayLogin(){
        var html ='';
        html += '<center>';
        html += '<table style="border:1px;">';
        html += '<tr><td>E-mail:</td></tr>';
        html += '<tr><td><input type="text" value="" id="emailField" size="20" /></td></tr>';
        html += '<tr><td>Password:</td></tr>';
        html += '<tr><td><input type="password" value="" id="passwordField" size="20" /></tr></td>';
        html += '<tr><td><center><input type="button" onclick="wsLogin()" value="Login" /></center></tr></td>';
        html += '</table>';
        html += '</center>';
        html += '</div>';
        
        contactContainer.set_text(html);               
        
        messageContainer.set_text('<div class="padding">What? You don\'t have an account? Well then hurry up and <a href="http://navxs.com/en/register.aspx">register one</a>!</div>');               
    }

    function displayContacts(){
        var html = '';
        var onlineImgStr = '<img src="images/icon_online.png" alt="Online" width="12" height="12">';
        var onlineStationaryImgStr = '<img src="images/icon_online_stationary.png" alt="Online" width="12" height="12">';
        var offlineImgStr = '<img src="images/icon_offline.png" alt="Online" width="12" height="12">';
        var requestedImgStr = '<img src="images/icon_pending.png" alt="Online" width="12" height="12">';
        html += '<table class="padded">';
        html += '<tr><td colspan="2"><b>Logged in as:</b></td></tr>';
        var contactIndex = 0;
        var linkStyleStart = ' style="cursor:pointer" title="Click to center map on contact." onclick="centerOnContact(';
        var linkStyleEnd = ')"';
        if(user!=null){
            html += '<tr><td>'+onlineImgStr+'</td><td><u><span'+linkStyleStart+contactIndex+linkStyleEnd+'>'+user.Email+'</span></u></td></tr>';
            contactIndex++;
        }
        var addContactHtml = '&nbsp;<u><span style="cursor:pointer;" title="Click to search for other users." onclick="displayAddContactWindow()">Add</span></u>';
        var delContactHtml = '&nbsp;<u><span style="cursor:pointer;" title="Click to remove unwanted contacts form your list." onclick="displayRemoveContactWindow()">Remove</span></u>';

        html += '<tr><td colspan="2"><b>Contacts:</b>'+addContactHtml+delContactHtml+'</td></tr>';
        if(onlineContacts!=null ){
            for(var i=0; i<onlineContacts.length; i++){
                var imgStr = onlineImgStr;
                var index = getIndexForUid(onlineContacts[i].Id);
                if(index>=0 && index<allContactPositions.length && allContactPositions[index]!=null && allContactPositions[index].Source==0){
                   imgStr = onlineStationaryImgStr;
                }
                html += '<tr><td>'+imgStr+'</td><td><u><span'+linkStyleStart+contactIndex+linkStyleEnd+'>'+onlineContacts[i].Email+'</span></u></td></tr>';
                contactIndex++;
            }
        }
        if(offlineContacts!=null ){
            for(var i=0; i<offlineContacts.length; i++){
                html += '<tr><td>'+offlineImgStr+'</td><td><u><span'+linkStyleStart+contactIndex+linkStyleEnd+'>'+offlineContacts[i].Email+'</span></u></td></tr>';
                contactIndex++;
            }
        }
        if(requestedContacts!=null ){
            for(var i=0; i<requestedContacts.length; i++){
                html += '<tr><td>'+requestedImgStr+'</td><td>'+requestedContacts[i].Email+'</td></tr>';
            }
        }
        if(requestingContacts!=null && requestingContacts.length>0 ){
            html += '<tr><td colspan="2"><b>The following users wants to add you to their contact list:</b></td></tr>';
            for(var i=0; i<requestingContacts.length; i++){
                html += '<tr><td colspan="2">'+requestingContacts[i].Email+'&nbsp;<input type="button" onclick="wsAcceptRequest('+i+')" value="Accept" /><input type="button" onclick="wsRejectRequest('+i+')" value="Reject" /></td></tr>';
            }
        }
        html += '</table>';
        html += '<br />';
        html += 'Click on the email address of a contact to auto-center the map on this contact. Click <u><span style="cursor:pointer;" onclick="centerOnContact(-1)">here</span></u> to disable map auto-centering.';

        contactContainer.set_text(html);               
    }

    function displayAddContactWindow(){
        var html = '<div class="popup">';
        html += '<div class="popupbar">';
        html += '<u><span style="cursor:pointer;" title="Click to close window." onclick="disposePopupWindow()">Close</span></u>';
        html += '</div>';
        html += '<div class="padding">';
        html += '<b>Add Contact:</b><br />';
        html += 'Enter the e-mail address of the person you want to add to your contact list:<br />';
        html += '<center>';
        html += '<input type="text" id="findemail" value=""><br />';
        html += '<input type="button" id="search" value="Search" onclick="wsFindUser()">';
        html += '<input type="button" id="cancel" value="Cancel" onclick="disposePopupWindow()">';
        html += '</center>';
        html += '<div id="search_results"></div>';
        html += '</div>';
        html += '</div>';
        
        popupContainer.set_text(html);
    }
    
    function displayRemoveContactWindow(){
        var onlineImgStr = '<img src="images/icon_online.png" alt="Online" width="12" height="12">';
        var offlineImgStr = '<img src="images/icon_offline.png" alt="Online" width="12" height="12">';
        var html = '<div class="popup">';
        html += '<div class="popupbar">';
        html += '<u><span style="cursor:pointer;" title="Click to close window." onclick="disposePopupWindow()">Close</span></u>';
        html += '</div>';
        html += '<div class="padding">';
        html += '<b>Select Contact(s) to be removed from your contact list:</b>';
        html += '<table>';
        var index = 1;
        if(onlineContacts!=null ){
            for(var i=0; i<onlineContacts.length; i++){
                html += '<tr><td>'+onlineImgStr+'</td><td><input type="checkbox" id="contactCheck'+index+'">'+onlineContacts[i].Email+'</td></tr>';
                index++;
            }
        }
        if(offlineContacts!=null ){
            for(var i=0; i<offlineContacts.length; i++){
                html += '<tr><td>'+offlineImgStr+'</td><td><input type="checkbox" id="contactCheck'+index+'">'+offlineContacts[i].Email+'</td></tr>';
                index++;
            }
        }
        html += '</table>';
        html += '<center>';
        html += '<input type="button" id="send" value="Remove" onclick="wsRemoveContacts()">';
        html += '<input type="button" id="cancel" value="Cancel" onclick="disposePopupWindow()">';
        html += '</center>';
        html += '</div>';
        html += '</div>';
        
        popupContainer.set_text(html);
    }

    function displayMessages(){
        var html = '<div class="padding">';
        html += '<b>Messages:</b>';
        html += '&nbsp;<u><span style="cursor:pointer;" title="Click to open meessage composing window." onclick="displayComposeMessagePopup(-1)">Compose</span></u>';
        if(messages!=null && messages.length>0){
            html += '&nbsp;<u><span style="cursor:pointer;" title="Click to clear all messages in list." onclick="clearMessages()">Clear</span></u>';
        }
        html += '</div>';
        if(messages==null || messages.length==0){
            html += '<div class="padding">No new messages!</div>';
        }
        else{
            for(var i=messages.length-1; i>=0; i--){
                if(messages[i]==null){
                    html += '<div class="listelement">Message '+i+'=null</div>';
                }
                else{
                    var sender = getEmailForUid(messages[i].SendUid);
                    if(sender==null)sender='Null';
                    html += '<div class="listelement">';
                    html += '<div class="msgsender">'+sender+'</div>';
                    html += '<div class="msgtime">'+new Date(messages[i].Time).toLocaleString()+'</div>';
                    html += '<div class="msgtext">'+messages[i].Text+'</div>';
                    html += '</div>';
                }
            }
        }

        messageContainer.set_text(html);               
        
    }
    
    function clearMessages(){
        
        var really_delete = confirm('Permanently delete all messages in list?');
        if(really_delete){
            messages = null;
            displayMessages();
        }
    
    }
    
    function displayComposeMessagePopup(defaultCheck){
        var onlineImgStr = '<img src="images/icon_online.png" alt="Online" width="12" height="12">';
        var offlineImgStr = '<img src="images/icon_offline.png" alt="Online" width="12" height="12">';
        var html = '<div class="popup">';
        html += '<div class="popupbar">';
        html += '<u><span style="cursor:pointer;" title="Click to close window." onclick="disposePopupWindow()">Close</span></u>';
        html += '</div>';
        html += '<div class="padding">';
        html += '<b>Select Recipient(s):</b>';
        html += '<table>';
        var index = 1;
        if(onlineContacts!=null ){
            for(var i=0; i<onlineContacts.length; i++){
            	var checkedstr = "";
                if(defaultCheck == index) checkedstr =" checked";
                html += '<tr><td>'+onlineImgStr+'</td><td><input type="checkbox" id="contactCheck'+index+'"'+checkedstr+'>'+onlineContacts[i].Email+'</td></tr>';
                index++;
            }
        }
        if(offlineContacts!=null ){
            for(var i=0; i<offlineContacts.length; i++){
            	var checkedstr = "";
                if(defaultCheck == index) checkedstr =" checked";
                html += '<tr><td>'+offlineImgStr+'</td><td><input type="checkbox" id="contactCheck'+index+'"'+checkedstr+'>'+offlineContacts[i].Email+'</td></tr>';
                index++;
            }
        }
        html += '</table>';
        html += '<b>Message Text:<b><br />';
        html += '<center>';
        html += '<textarea id="message_text" rows="4" cols="45"></textarea><br />';
        html += '<input type="button" id="send" value="Send" onclick="wsSendMessage()">';
        html += '<input type="button" id="cancel" value="Cancel" onclick="disposePopupWindow()">';
        html += '</center>';
        html += '</div>';
        html += '</div>';
        
        popupContainer.set_text(html);
    }
    
    function showMessageBubble(senderId, msgText){
        if(allContacts==null) return;
        if(allContactMarkers==null) return;
        if(allContactPositions==null) return;
        var index = -1;
        var test = 0;
        for(var i=0; i<allContacts.length; i++){
            if(senderId == allContacts[i].Id){
            	index = i;
            	test++;
			}
        }
        
        // a test if the may be un-unique ids about
        if(test>1)alert("Warning: found "+test+" users with same ID!");
        
        if(index<0) return;
        if(index>=allContactMarkers.length) return;
        if(index>=allContactPositions.length) return;
        if(allContactMarkers[index]==null) return;
        if(allContactPositions[index]==null) return;
        
        var html = '<b>'+allContacts[index].Email+'</b> says:<br /><br />';
        html += msgText+'<br /><br />';
        html += '<div class="msgtime">Click <u><span style="cursor:pointer" onclick="displayComposeMessagePopup('+index+')">here</span></u> to reply.</div>';
        html += '<div class="msgtime">Click <u><span style="cursor:pointer" onclick="disableMessageBubbles()">here</span></u> to not show messages on the map like this.</div>';
        allContactMarkers[index].openInfoWindowHtml(html);
        map.setCenter(new GLatLng(allContactPositions[index].Latitude, allContactPositions[index].Longitude));
    
    }
    
    function disableMessageBubbles(){
        showMessageBubbles=false;
        alert("Message bubbles turned off, for now at least...");
    }

    
     function disposePopupWindow(){
        popupContainer.set_text('');
    }


    
    function getEmailForUid(uid){
        var email = 'Unknown User';
        
        if(allContacts!=null){
            for(var i=0; i<allContacts.length; i++){
                if(uid==allContacts[i].Id){
                    email = allContacts[i].Email;
                }
            }
        }
//        if(user!=null && uid==user.Id){
//            email = user.Email;
//        }
//        if(onlineContacts!=null){
//            for(var i=0; i<onlineContacts.length; i++){
//                if(uid==onlineContacts[i].Id){
//                    email = onlineContacts[i].Email;
//                }
//            }
//        }
//        if(offlineContacts!=null){
//            for(var i=0; i<offlineContacts.length; i++){
//                if(uid==offlineContacts[i].Id){
//                    email = offlineContacts[i].Email;
//                }
//            }
//        }
        
        return email;
    
    }
    
    function getIndexForUid(uid){
        var index = -1;
        
        if(allContacts!=null){
            for(var i=0; i<allContacts.length; i++){
                if(uid==allContacts[i].Id){
                    index = i;
                }
            }
        }
        return index;
    
    }
    
    function displayContactInfo(marker){
        if(marker==null){
            return;
        }
        if(allContactMarkers==null) return;
        if(allContactPositions==null) return;
        var index = -1;
        for(var i=0; i<allContactMarkers.length; i++){
            if(marker==allContactMarkers[i]) index = i;
        }
        if(index<0) return;
        if(index>=allContactMarkers.length) return;
        if(index>=allContactPositions.length) return;
        if(allContactMarkers[index]==null) return;
        if(allContactPositions[index]==null) return;
        
        var html = '<b>'+allContacts[index].Email+'</b><br />';
        html += 'Position: ('+allContactPositions[index].Latitude+', '+allContactPositions[index].Longitude+')<br />';
        html += 'Updated: '+new Date(allContactPositions[index].Time).toLocaleString()+'<br />';
        allContactMarkers[index].openInfoWindowHtml(html);
        
    }
    
    function centerOnContact(index){
    
        autoCenterEmail = allContacts[index].Email; // if index is negative, auto cenetring is off.
        
        if(index!=null && allContactPositions!=null && index>=0 && index<allContactPositions.length && allContactPositions[index]!=null){
            map.panTo(new GLatLng(allContactPositions[index].Latitude, allContactPositions[index].Longitude));
        }

    }

    function onRefreshContacts()
    {
        map.clearOverlays();
        wsGetContacts();  // will also trigger offline contact refresh and position refresh
        wsGetRequestingContacts();
    }
    
    function navxsExitPage(){
        if(messages!=null && messages.length>0){
            var text = "Note: Your messages will be permanently deleted when you leave this page.\n\n";
            text +=    "If you think this is a very very bad thing, write us at support@navxs.com\n";
            text +=    "and let us know. If enough people request it, we'll store messages locally\n";
            text +=    "on your machine as cookies. Maybe we will even offer to store messages on\n";
            text +=    "our server someday...\n\n";
            text +=    "If you find this message a very very bad thing, let us know and we'll shut up ;-).\n\n";
            text +=    "Sorry for the inconvenience...";
            alert(text);
        }
        user = null;
        onlineContacts = null;
        offlineContacts = null;
        requestedContacts = null;
        requestedContacts = null;
        requestingContacts = null;
        allContactPositions = null;
        allContactMarkers = null;
        allContacts = null;
        messages = null;
        positionLoadIndex = 0;
        autoCenterEmail = "";
        firstPositionDownload = true;
        synchLoopEnabled=false;
        showMessageBubbles=true;
    }


	/**********************************************************************
	* Login / Refresh chain start                                         *
	**********************************************************************/
    
	
	// Chained function: calls wsLoginCallback
    function wsLogin()
    {
        var emailField = new Sys.UI.TextBox($("emailField"));
        var passwordField = new Sys.UI.TextBox($("passwordField"));

        NavXS.ExchangeService.Login(
            emailField.get_text(), 
            passwordField.get_text(),
            "navxs.com/webclient",
            wsLoginCallback
        );
    }

	// Chained function: calls wsGetUser
    function wsLoginCallback(result){
        if(result==""){
            alert("Login Failed. Check your username / password!");
        }
        else{
            sessionID = result;
            
            // set seesion id as cookie, so that we don't have to login if we navigate away and back
            setCookie("NavXS_SessionID", sessionID);
            
            // display logout link
            var html ='<u><span style="cursor:pointer;" title="Click to log out." onclick="wsLogout()">Logout</span></u>';
            logoutContainer.set_text(html);               
    	    
            // trigger user data refresh
            wsGetUser();
        }
    }
    
	// Chained function: calls wsGetUserCallback
    function wsGetUser()
    {
    
        NavXS.ExchangeService.GetUserProfile(
            sessionID,
            wsGetUserCallback
        );
    }
    
	// Chained function: calls wsGetOnlineContacts
    function wsGetUserCallback(result)
    {
        if(result==""){
            alert("No User data. :-O");
            displayLogin();
        }
        else{
            user = result;
            displayContacts();
            selectedUserId = user.Id;

			// trigger online contacts refresh
            wsGetContacts();
        }
    }
    
//	// Chained function: calls wsGetOnlineContactsCallback
//    function wsGetOnlineContacts()
//    {
//        NavXS.ExchangeService.GetOnlineContacts(
//            sessionID,
//            wsGetOnlineContactsCallback 
//        );
//         
//    }
//    
//	// Chained function: calls wsGetOfflineContacts
//    function wsGetOnlineContactsCallback(result)
//    {
//        onlineContacts = result;
//        displayContacts();
//        
//        // trigger offline contacts refresh
//        wsGetOfflineContacts();
//        
//    }
//    
	// Chained function: calls wsGetOfflineContactsCallback
    function wsGetContacts()
    {
        NavXS.ExchangeService.GetContacts(
            sessionID,
            wsGetContactsCallback 
        );
         
    }
    
	// Chained function: calls wsGetRequestedContacts, wsGetSynchStatus, wsGetContactPositions
    function wsGetContactsCallback(result)
    {
        var numContacts = result.length+1; // others + me
        var numOnline = 0;
        var numOffline = 0;
        var numRequested = 0;
        for(var i=0; i<result.length; i++){
           if(result[i].Status == -1){
              numRequested++;
           }
           if(result[i].Status == 0){
              numOffline++;
           }
           if(result[i].Status == 1){
              numOnline++;
           }
        }
        onlineContacts = new Array(numOnline);
        offlineContacts = new Array(numOffline);
        requestedContacts = new Array(numRequested);
        requestingContacts = new Array(0);
        var numOnline = 0;
        var numOffline = 0;
        var numRequested = 0;
        for(var i=0; i<result.length; i++){
           if(result[i].Status == -1){
              requestedContacts[numRequested] = result[i];
              numRequested++;
           }
           if(result[i].Status == 0){
              offlineContacts[numOffline] = result[i];
              numOffline++;
           }
           if(result[i].Status == 1){
              onlineContacts[numOnline] = result[i];
              numOnline++;
           }
        }
        
        displayContacts();
        
        allContactPositions = new Array(numContacts);
        allContacts = new Array(numContacts);
        allContactMarkers = new Array(numContacts);
        
        // build arrays
        var index = 0;
        allContacts[index] = user;
        allContactMarkers[index] = new GMarker(new GLatLng(0,0), {icon: onlineMapIcon, clickable: true, title: allContacts[index].Email});
        map.addOverlay(allContactMarkers[index]);
        index++;
        
        if(onlineContacts!=null){
            for(var i=0; i<onlineContacts.length; i++){
            
                allContacts[index] = onlineContacts[i];
                allContactMarkers[index] = new GMarker(new GLatLng(0,0), {icon: onlineMapIcon, clickable: true, title: allContacts[index].Email});
                map.addOverlay(allContactMarkers[index]);
                index++;
            }
        }
        if(offlineContacts!=null){
            for(var i=0; i<offlineContacts.length; i++){
                
                allContacts[index] = offlineContacts[i];
                allContactMarkers[index] = new GMarker(new GLatLng(0,0), {icon: offlineMapIcon, clickable: true, title: allContacts[index].Email});
                map.addOverlay(allContactMarkers[index]);
                index++;
            }
        }
        
        // first at this point are user, allContacts array
        // is available: trigger contact position refresh
        positionLoadIndex = 0; // start with logged in user
        wsGetContactPosition();

		// get new messages
        wsGetNewMessages();
        
        // start synch loop if necessary
        if(synchLoopEnabled==false){
            synchLoopEnabled = true;
            wsGetSynchStatus(); // recursive with timeout
        }

        // trigger requesting contacts refresh
        wsGetRequestingContacts();
        
    }
    
//	// Chained function: calls wsGetRequestedContactsCallback
//    function wsGetRequestedContacts()
//    {
//        NavXS.ExchangeService.GetRequestedContacts(
//            sessionID,
//            wsGetRequestedContactsCallback
//        );
//         
//    }
//    
//	// Chained function: calls wsGetRequestingContacts
//    function wsGetRequestedContactsCallback(result)
//    {
//        requestedContacts = result;
//        displayContacts();
//        
//        // trigger requesting users refresh
//        wsGetRequestingContacts();
//    }
    
	// Chained function: calls wsGetRequestingContactsCallback
    function wsGetRequestingContacts()
    {
        NavXS.ExchangeService.GetContactRequests(
            sessionID,
            wsGetRequestingContactsCallback
        );
         
    }
    
	// End of function chain
    function wsGetRequestingContactsCallback(result)
    {
        requestingContacts = result;
        displayContacts();
        
    }


	/**********************************************************************
	* End of login / refresh chain                                        *
	**********************************************************************/
    
     function wsGetSynchStatus(){
     
     	if(synchLoopEnabled && sessionID!=null && sessionID.length>0){
    
	        NavXS.ExchangeService.GetSynchStatus(
    	        sessionID,
        	    wsGetSynchStatusCallback
	        );
	        
        }
         
    }
    
    function wsGetSynchStatusCallback(result){
    
    
        if(result.LoginChanged==true){
        	// reset all contact info an re-fetch it
	        onlineContacts = null;
	        offlineContacts = null;
	        requestedContacts = null;
	        requestedContacts = null;
	        requestingContacts = null;
	        allContactPositions = null;
	        allContactMarkers = null;
	        allContacts = null;
        
            wsGetContacts(); // starts the login/refresh chain at getOnlineContacts
            
            // Important: Stop the synch loop while contact list is refreshed
            synchLoopEnabled = false;
        }
       
        if(result.MessageAvailable==true){
            wsGetNewMessages();
        }
       
        if(result.ContactPositionChanged==true){
            positionLoadIndex = 0; // get all positions anew
            wsGetContactPosition();
        }
       
        // recurse
        if(synchLoopEnabled && sessionID!=null && sessionID.length>0){
            setTimeout("wsGetSynchStatus();",5000);
        }
    }

    

    function wsFindUser(){

        var textarea = new Sys.UI.TextBox($("findemail"));
        var email = textarea.get_text();
        
        if(email==null || email.length==0){
            alert("Please enter an e-mail address");
            return;
        }            
        NavXS.ExchangeService.FindUserByEmail(
            sessionID,
            email,
            wsFindUserCallback
        );
        var container = new Sys.UI.Label($("search_results"));
        container.set_text('<center>Searching...</center>');
        
    }
    
    function wsFindUserCallback(result){
        var container = new Sys.UI.Label($("search_results"));
        if(result==null || result.length==0){
            var textarea = new Sys.UI.TextBox($("findemail"));
            var email = textarea.get_text();
            var emailBody = "Dude, I want to know where you\'re at! Check out http://navxs.com.";
            var html = '<br /><center>';
            html += 'No users found.<br /><br />';
            html += 'Click <a href="mailto:'+email+'?subject=NavXS&body='+emailBody+'">this link</a> to send an e-mail notification to '+email+'.';
            html += '</center><br />';
            container.set_text(html);
        }
        else{
            var html = '<br /><center>1 user found.</center><br /><br />';
            html += 'Click the button below to send a contact request to <b>'+result[0].Email+'</b>. ';
            html += 'Only when he/she has accepted your request will you be able to see his/her position and exchange messages.<br /><br />';
            html += '<center><input type="button" id="adduser" value="Request Contact" onclick="wsRequestContact()"></center><br />';
            container.set_text(html);
        }
    }
    
    function wsRequestContact(){
        var textarea = new Sys.UI.TextBox($("findemail"));
        var email = textarea.get_text();
        NavXS.ExchangeService.RequestContact(
            sessionID,
            email,
            wsRequestContactCallback
        );
    }
    
    function wsRequestContactCallback(result){
        if(result==null || result==false){
            alert("Request failed :-O");
        }
        else{
            alert("Request sent.");
            disposePopupWindow();
        }
    }
    
    function wsRemoveContacts(){
        if(allContacts==null || allContacts.length==0){
            disposePopupWindow();
            return;
        }                

        for(var i=1; i<allContacts.length; i++){
            var checkbox = new Sys.UI.CheckBox($("contactCheck"+i));
            if(checkbox.get_checked()){
                NavXS.ExchangeService.RemoveContact(
                    sessionID,
                    allContacts[i].Email,
                    wsRemoveContactsCallback
                );
            }
        }
        disposePopupWindow();
    }
    
    function wsRemoveContactsCallback(result)
    {
    	// the synch status should trigger a contact list refresh on next poll.
    	// no need to do anything here...
    }

     function wsAcceptRequest(index)
    {
        NavXS.ExchangeService.AcceptContactRequest(
            sessionID,
            requestingContacts[index].Email,
            wsAcceptRequestCallback
        );
    }
    
    function wsAcceptRequestCallback(result){
    	// the synch status should trigger a contact list refresh on next poll.
    	// no need to do anything here...
    }
    
    function wsRejectRequest(index)
    {
        NavXS.ExchangeService.RejectContactRequest(
            sessionID,
            requestingContacts[index].Email,
            wsRejectRequestCallback
        );
    }
    
    function wsRejectRequestCallback(result){
    	// the synch status should trigger a contact list refresh on next poll.
    	// no need to do anything here...
    }
    
    function wsSendMessage(){
        var numSelected = 0;
        if(allContacts==null || allContacts.length==0){
            disposePopupWindow();
            return;
        }                

        var textarea = new Sys.UI.TextBox($("message_text"));
        var msgtxt = textarea.get_text();
        var time = new Date().getTime();
        
        for(var i=1; i<allContacts.length; i++){
            var checkbox = new Sys.UI.CheckBox($("contactCheck"+i));
            if(checkbox.get_checked()){
                NavXS.ExchangeService.SendMessage(
                    sessionID,
                    allContacts[i].Email,
                    time,
                    msgtxt,
                    wsSendMessageCallback
                );
                numSelected++;
            }
        }
        if(numSelected==0){
            alert("No recipients selected!");
            return;
        }
        else{
            disposePopupWindow();
            
            // add to message list
            var tmp = new Array(messages.length + 1);
            for(var i=0; i<messages.length; i++){
                tmp[i] = messages[i];
            }
            tmp[messages.length] = new Message();
			tmp[messages.length].mId = 0;
			tmp[messages.length].SendUid = user.Id;
			tmp[messages.length].RecipientUid = "";
          	tmp[messages.length].Time = new Date().getTime();
          	tmp[messages.length].Text = msgtxt;
            messages = tmp;
            displayMessages();
            
        }
    }
    
    function wsSendMessageCallback(result){
    }
    
    function wsGetNewMessages(){
    
        NavXS.ExchangeService.GetReceivedMessages(
            sessionID,
            wsGetNewMessagesCallback
        );
         
    }
    
    function wsGetNewMessagesCallback(result)
    {
        if(messages==null || messages.length==0){
            messages = result;
        }
        else{
            var tmp = new Array(messages.length + result.length);
            for(var i=0; i<messages.length; i++){
                tmp[i] = messages[i];
            }
            for(var i=0; i<result.length; i++){
                tmp[i+messages.length] = result[i];
            }
            
            messages = tmp;
        }
        displayMessages();
        
        // show a "talking-bubble" at the senders marker
        if(showMessageBubbles==true && result.length==1){
            showMessageBubble(result[0].SendUid, result[0].Text);
        }
    }
    
    function wsGetContactPosition(){
        if(allContactPositions==null) return;
        
        var uid = null;
        
        if(allContacts[positionLoadIndex]!=null){
            uid = allContacts[positionLoadIndex].Id;
        }
        
        if(uid!=null){
        
            NavXS.ExchangeService.GetContactPosition(
                sessionID,
                uid,
                wsGetContactPositionCallback
            );
        }
    }

    function wsGetContactPositionCallback(result){
    
    	if(allContacts == null) return;
        if(allContactMarkers == null) return;
        if(allContactPositions == null) return;
        if(allContacts.length<positionLoadIndex) return;
        if(allContactMarkers.length<positionLoadIndex) return;
        if(allContactPositions.length<positionLoadIndex) return;
        
        var oldPos = allContactPositions[positionLoadIndex];        
        
        allContactPositions[positionLoadIndex] = result;
        if(allContactMarkers[positionLoadIndex]!=null){
        
            allContactMarkers[positionLoadIndex].setPoint(new GLatLng(result.Latitude, result.Longitude));
 
            // update icon if position source has changed
            if(oldPos!=null && oldPos.Source!=allContactMarkers[positionLoadIndex].Source){
               if(allContacts[positionLoadIndex].Status == 1){ // online
                  if(allContactPositions[positionLoadIndex].Source == 0){ // Manual
                     // TODO find function for setIcon-->allContactMarkers[positionLoadIndex].setIcon({icon: onlineStationaryMapIcon, clickable: true, title: allContacts[positionLoadIndex].Email});
                  }
                  else if(allContactPositions[positionLoadIndex].Source == 1){ // Auto
                     // TODO find function for setIcon-->allContactMarkers[positionLoadIndex].setIcon({icon: onlineMapIcon, clickable: true, title: allContacts[positionLoadIndex].Email});
                  }
                  else alert("Unknown position source: "+allContactMarkers[positionLoadIndex].Source);
               }
            }
        }
        
        // center map on user
        if(firstPositionDownload && positionLoadIndex==0){
            // if at (0,0) ignore, no position has ben set...
            if(result.Latitude!=0.0 || result.Latitude!=0.0){
                map.setCenter(new GLatLng(result.Latitude, result.Longitude), 14);
            }
            firstPositionDownload = false;
        }
        
        if(allContacts[positionLoadIndex] != null && allContacts[positionLoadIndex].Email == autoCenterEmail){
            map.panTo(new GLatLng(result.Latitude, result.Longitude));
        }
        
        positionLoadIndex++;
        if(positionLoadIndex<allContactPositions.length){
            wsGetContactPosition();
        }
    }
    
    function wsLogout()
    {
        if(messages!=null && messages.length>0){
            var text = "Note: Your messages will be permanently deleted when you log out.\n\n";
            text +=    "If you think this is a very very bad thing, write us at support@navxs.com\n";
            text +=    "and let us know. If enough people request it, we'll store messages locally\n";
            text +=    "on your machine as cookies. Maybe we will even offer to store messages on\n";
            text +=    "our server someday...\n\n";
            text +=    "If you find this message a very very bad thing, let us know and we'll shut up ;-).\n\n";
            text +=    "Sorry for the inconvenience...";
            alert(text);
        }
        NavXS.ExchangeService.Logout(
            sessionID,
            wsLogoutCallback
        );
        deleteCookie("NavXS_SessionID");
        displayLogin();
        logoutContainer.set_text('Logging out...');               
        messageContainer.set_text('&nbsp;');               
        map.clearOverlays();
        disposePopupWindow();
        
        sessionID = null;
        user = null;
        onlineContacts = null;
        offlineContacts = null;
        requestedContacts = null;
        requestedContacts = null;
        requestingContacts = null;
        allContactPositions = null;
        allContactMarkers = null;
        allContacts = null;
        messages = null;
        positionLoadIndex = 0;
        autoCenterEmail = "";
        firstPositionDownload = true;
        synchLoopEnabled=false;
        
        
    }
    
    function wsLogoutCallback(result){
        logoutContainer.set_text('&nbsp;');               
    }
    
    
