/**
 * License info: http://kmi.open.ac.uk/technologies/msg/developer/licenses/ 
 */
 
/**
 * Find if user is already logged in or not
 */
function checkLogin(){
	if (MSGAPIconf.maxLoginAttempts > 0){
	    //do JSON request to get the presence of current user 
	    request = MSGAPIconf.msg_jabberurl + "?command=getstatus&callback=checkLoginCallback";
	    aObj = new JSONscriptRequest(request);
	    aObj.buildScriptTag();
	    aObj.addScriptTag();
	}   
}

/**
 * Process response from checkLogin() command
 */
function checkLoginCallback(jData){
    if (jData == null) {
        // There was a problem parsing search results
        return;
    }
    
    // if error then user offline so log them in
    if (jData.children[0].attributes.tag == 'error'){
       		// user offline so log them in
        	myMSG.loginUser();
        	return;
    } 
        
      // check jid returned is same as current jid
      var tempJid = jData.children[0].attributes.jid.split('/')[0];
      
      if (conf_currentUserId != null && tempJid != conf_currentUserId){
      	  //log current MSG user out, then log in again as the current actual user of this page
      	  logoutUser();
      	  myMSG.loginUser();
      	  return;
      }
      
      // user online so display relevant presence icon 
      var status = jData.children[0].attributes.state;
      
      // update icon generally on the page
      updateState(conf_currentUserId,status);
      
      // update the peekID
      peekID = jData.children[0].attributes.lasteventid;
      conf_currentUserLat = jData.children[0].attributes.lat;
      conf_currentUserLng = jData.children[0].attributes.lng;
      
      // find if there are new messages
      messagesUnread = jData.children[0].attributes.unreadmessages;
      
      // messagesUnread is 1 then get the sender
      if (messagesUnread == 1){
          getMessageSender();
      }
     
      // update personal icon
      updatePresenceIcon(status);

		if (conf_displayNickName == true){
			showUserName(jData.children[0].attributes.nickname,jData.children[0].attributes.jid);
		}
		myMSG.zoomToLocation();
		myMSG.initStates();
		   
		monitorPersonalOnline();
     
}

/**
 * Log current user in to MSG
 */
function loginUser(){

	// check that conf_currentuserid isn't null and if not null then try to log user in
	if (conf_currentUserId != null){
		request = MSGAPIconf.msg_jabberurl + "?command=connect";
		request = request + "&nickname=" + encodeURIComponent(currentUserNickName) +"&host=" + encodeURIComponent(MSGAPIconf.msg_host) + "&callback=loginUserCallback";
		
		// add each conf_authConfigArr item to the array
		for (var key in conf_authConfigArr){
			request = request + "&" + encodeURIComponent(key) + "=" + encodeURIComponent(conf_authConfigArr[key]);
		}
	    aObj = new JSONscriptRequest(request);
	    aObj.buildScriptTag();
	    aObj.addScriptTag();
    }
}

/**
 * Process response from loginUser()
 */
function loginUserCallback(jData){
    if (jData == null) {
        // There was a problem parsing search results
        return;
    }
    if (jData.children[0].attributes.tag == 'error'){
        // set presence to be online
        updatePresenceIcon('offline');
        MSGAPIconf.maxLoginAttempts--;
    } else {
        // set presence to be online
        updatePresenceIcon('online');
        // now call getStatus again (!) to get the peekID and no of unread messages
        setTimeout(checkLogin,MSGAPIconf.checkLoginTimeout);
    }
}

/**
 * Log current user out of MSG
 */
function logoutUser(){
	request = MSGAPIconf.msg_jabberurl + "?command=disconnect&callback=logoutUserCallback";	
	aObj = new JSONscriptRequest(request);
	aObj.buildScriptTag();
	aObj.addScriptTag();
}

/**
 * Log current user out of MSG
 */
function logoutUserCallback(){
	// do nothing!
}

/**
 * Update presence icon in banner with correct links/mouse over/status etc
 */
function updatePresenceIcon(status){
    var presenceNode = document.getElementById("msg_widget_icon");

    if(status){
        currentStatus = status;   
    } 

    var oldAnchor = presenceNode.firstChild;
    var newAnchor = oldAnchor.cloneNode(true);

    // update the anchor href
    if (messagesUnread == 1){
        // open the chat window
        newAnchor.href = "javascript:readMessageClick();";
        newAnchor.title = MSGAPIconf.str_oneMessageUnread;
    } else {
       // open contacts window
        newAnchor.href="javascript:launchClick();"; 
        if (messagesUnread == 0){
            newAnchor.title = MSGAPIconf.stateText[currentStatus];
            closeMessageNotification();
        } else {
            newAnchor.title = messagesUnread + MSGAPIconf.str_messagesUnread;
            openMessageNotification(messagesUnread + MSGAPIconf.str_messagesUnread);
        } 
    }
      
    // update the icon
    var oldIcon = newAnchor.firstChild;
    var newIcon = oldIcon.cloneNode(false);
    
    var extension = ".png";
    if(messagesUnread > 0){
        extension = "bang.png";
    }
    
    newIcon.src = MSGAPIconf.imgroot + "/" + currentStatus + extension;
    if (messagesUnread == 1){
        newIcon.title = MSGAPIconf.str_oneMessageUnread;
        newIcon.alt = MSGAPIconf.str_oneMessageUnread;
        openMessageNotification(MSGAPIconf.str_oneMessageUnread);
    } else {
        if (messagesUnread == 0){
            newIcon.title = MSGAPIconf.stateText[currentStatus];
            newIcon.alt = MSGAPIconf.stateText[currentStatus];
            closeMessageNotification();
        } else {
            newIcon.title = messagesUnread + MSGAPIconf.str_messagesUnread;
            newIcon.alt = messagesUnread + MSGAPIconf.str_messagesUnread;
            openMessageNotification(messagesUnread + MSGAPIconf.str_messagesUnread);
        }  
    }
    newAnchor.replaceChild(newIcon,oldIcon);
    presenceNode.replaceChild(newAnchor,oldAnchor); 
    
    //if maps page and status now offline
    if(status=='offline'){
    	closeMessageNotification();
    	myMSG.disconnected();
    	
    }
}


/**
 * Generate the correct URL to go to to chat to another user, 
 * depending on whether the current user is logged in or not
 */
function clickToChat(evt,id){
	
	if(id != null){
		chatToId = id;
	} else {
		if(evt.target){
			var name = evt.target.name;
		} else {
			var name = evt.srcElement.name;
		}
		// extract the chat to id from the name
	    chatToId = name.replace('img_msg_online_','');
    }
   
    var openChatId = chatToId;
    //send message to self to open chat
    request = MSGAPIconf.msg_jabberurl + "?command=chat&to=" + encodeURIComponent(conf_currentUserId) + "&message=openchat%3A"+ encodeURIComponent(openChatId) + "&callback=clickToChatCallback";
    aObj = new JSONscriptRequest(request);
    aObj.buildScriptTag();
    aObj.addScriptTag();
}

/**
 * Process the response from the click to chat function
 */
function clickToChatCallback(jData){
    if (jData == null){
        return;
    }
    
    var isOpen = jData.children[0].attributes['clientopen'];
    // if return value is true then just need to focus on the window, otherwise 
    if (isOpen && isOpen == 'true'){
    	// don't need to do anything as message has already been sent to client and will open chat window & focus
    } else {
    	// now launch MSG window
    	url = MSGAPIconf.msg_jabberui + "/contacts.html?homeurl=dead.html";
    	openWindow(url);
    }
}



/**
 * Determines what to do when the user clicks on the launch MSG window button - where is takes them to will depend on
 * whether they are already logged in or not
 */
function launchClick(){
	
    //send message to self to open contacts
    request = MSGAPIconf.msg_jabberurl + '?command=chat&to=' + encodeURIComponent(conf_currentUserId) + '&message=open&callback=launchClickCallback'
    aObj = new JSONscriptRequest(request);
    aObj.buildScriptTag();
    aObj.addScriptTag();

}


/**
 * Process the response from the launchClick function
 */
function launchClickCallback(jData){
    if (jData == null){
        return;
    }
    
    var isOpen = jData.children[0].attributes['clientopen'];
    // if return value is true then just need to focus on the window, otherwise 
    if (isOpen && isOpen == 'true'){
    	// don't need to do anything as message has already been sent to client and will open chat window & focus
    } else {
    	// now launch MSG window
    	url = MSGAPIconf.msg_jabberui + "/contacts.html?homeurl=dead.html";
    	openWindow(url);
    }
}



/**
 * Open window if user has clicked to read their messages
 */
function readMessageClick(){
        
    //send message to self to open chat
    request = MSGAPIconf.msg_jabberurl + "?command=chat&to=" + encodeURIComponent(conf_currentUserId) + "&message=openchat%3A"+ messageFrom + "@" + MSGAPIconf.msg_host + "&callback=readMessageClickCallback";
    
    aObj = new JSONscriptRequest(request);
    aObj.buildScriptTag();
    aObj.addScriptTag(); 
}

/**
 * Process response from readMessageClick function
 */
function readMessageClickCallback(jData){
    if (jData == null){
        return;
    }
    
    var isOpen = jData.children[0].attributes['clientopen'];
    // if return value is true then just need to focus on the window, otherwise 
    if (isOpen && isOpen == 'true'){
    	// don't need to do anything as message has already been sent to client and will open chat window & focus
    } else {
    	// now launch MSG window
    	url = MSGAPIconf.msg_jabberui + "/contacts.html?homeurl=dead.html";
    	openWindow(url);
    }
    
    //set unread messages back to zero
    messagesUnread = 0;
    updatePresenceIcon();
}

/**
 *   Find the sender of a particular message
 */
function getMessageSender(){
    request = MSGAPIconf.msg_jabberurl + "?command=peek&since=-1&callback=getMessageSenderCallback";
    aObj = new JSONscriptRequest(request);
    aObj.buildScriptTag();
    aObj.addScriptTag();  
}

function getMessageSenderCallback(jData){
    if (jData == null) {
        // There was a problem parsing search results
        return;
    }
   
    var events = jData.children[0].children;
    
    // loop through all the events
    for (i=0; i<events.length;i++){
        if (events[i].attributes.tag == 'message' && events[i].children[0].children[0]){
            // get the message sender
            messageFrom = events[i].children[0].children[0].substring(0,events[i].children[0].children[0].indexOf('@'));  
        } 
    }
    
    
}

/**
 * Get the number of contacts online 
 */
function monitorGlobalOnline(){
    if (MSGAPIconf.global_online_counter_id){
        request = MSGAPIconf.global_online_url + "&callback=monitorGlobalOnlineCallback";
        aObj = new JSONscriptRequest(request);
        aObj.buildScriptTag();
        aObj.addScriptTag();
    } 
}

/**
 * Process the request to update number of global contacts online
 */
function monitorGlobalOnlineCallback(jData){
    if (jData == null){
        return;
    }
    if (jData.children[0].attributes.tag != 'error'){
	    var sessions = jData.children[0].children;
	    
	  	if (document.getElementById(MSGAPIconf.global_online_counter_id)){
	    	document.getElementById(MSGAPIconf.global_online_counter_id).innerHTML = sessions.length;
	    }
    } 
    monitorTotalOnline();
}

/**
 * Get the  total no of contacts for the whole system
 */
function monitorTotalOnline(){
    if (MSGAPIconf.global_online_counter_id){
        request = MSGAPIconf.global_total_url + "&callback=monitorTotalOnlineCallback";
        aObj = new JSONscriptRequest(request);
        aObj.buildScriptTag();
        aObj.addScriptTag();
    } 
}

/**
 * Process the request to update number of global contacts off line
 */
function monitorTotalOnlineCallback(jData){
    if (jData == null){
        return;
    }
    if (jData.children[0].attributes.tag != 'error'){
	    var totalCount = jData.children[0].attributes['user-count'];
	
	    if (document.getElementById(MSGAPIconf.global_counter_id)){
	    	document.getElementById(MSGAPIconf.global_counter_id).innerHTML = totalCount;
	    }
    } 
    setTimeout(monitorGlobalOnline, MSGAPIconf.global_online_refresh_rate);
}


/**
 * Get the number of contacts online and total no of contacts for user
 */
function monitorPersonalOnline(){
    if (MSGAPIconf.personal_online_counter_id){   
    	// update the number online (direct from MSG server)
        request = MSGAPIconf.msg_jabberurl + "?command=presences&callback=monitorPersonalOnlineCallback";
        aObj = new JSONscriptRequest(request);
        aObj.buildScriptTag();
        aObj.addScriptTag();       
    }
}

/**
 * Process the request to update number of online personal contacts 
 */
function monitorPersonalOnlineCallback(jData){
    if (jData == null){
        return;
    }
    
    if (jData.children[0].attributes.tag != 'error'){
	    // loop through all the returned presence states
	    var users = jData.children[0].children;
	    var total = jData.children[0].attributes.totalcontacts;
	    
	    // set the number of online users
	    var pOnline = document.getElementById(MSGAPIconf.personal_online_counter_id);
	    if(pOnline){
	        pOnline.innerHTML = users.length;
	    }
	    // set total no of users
	    if(document.getElementById(MSGAPIconf.personal_counter_id)){
	    	document.getElementById(MSGAPIconf.personal_counter_id).innerHTML = total;
	    }
    }
    setTimeout(monitorPersonalOnline,MSGAPIconf.personal_online_refresh_rate);
}

/**
 * Find if any new messages or status changes have come in
 */
function peek(){ 
    request = MSGAPIconf.msg_jabberurl + "?command=peek&since=" + peekID + "&callback=peekCallback";
    aObj = new JSONscriptRequest(request);
    aObj.buildScriptTag();
    aObj.addScriptTag();
}

/**
 * Process response from peek()
 */
function peekCallback(jData){
    
    if (jData == null) {
        // There was a problem parsing search results
        return;
    }
    
    // if error was returned (eg disconnected) then log user in again
    if(jData.children[0].attributes.code == '2003'){
        checkLogin();
        return;
    } 
    
    // find out if interrupted or not
    if (jData.children[0].attributes.interrupted || jData.children[0].attributes.code){
        peekTimeout = MSGAPIconf.peekTimeoutInterrupt; 
    } else {
        peekTimeout = MSGAPIconf.peekTimeoutNoInterrupt;   
    }
    
    var events = jData.children[0].children;
    
    // loop through all the events
    for (i=0; i<events.length;i++){
        // update the peekID
        peekID = events[i].attributes.id;
        
        if (events[i].attributes.tag == 'presence'){
            // deal with presence changes
            var id = events[i].attributes.from;
            var status = events[i].attributes.status;
            updateState(id,status);

        } else if (events[i].attributes.tag == 'message' && events[i].children[0].children){
            // deal with new messages (add to messagesUnread then update presence icon)  
            messagesUnread++;
            updatePresenceIcon();
            // get the message sender
            messageFrom = events[i].children[0].children[0].substring(0,events[i].children[0].children[0].indexOf('@'));
            
        } else if (events[i].attributes.tag == 'status'){
            // update your own status
             var status = events[i].attributes.status;
             updatePresenceIcon(status);
             updateState(conf_currentUserId,status); 
        }
    }

    // set the wait to be called again
    setTimeout(peek, peekTimeout);
}

/**
 * repeating call to update the states when page is first loaded
 */
function initStates(){
    request = MSGAPIconf.msg_jabberurl + "?command=presences&callback=initStatesCallback";
    aObj = new JSONscriptRequest(request);
    aObj.buildScriptTag();
    aObj.addScriptTag();
}

/**
 * process the returned object from initStates call
 */
function initStatesCallback(jData){
    if (jData == null) {
        return;
    }
        
    // loop through all the returned presence states
    var users = jData.children[0].children;
    for(var i=0; i<users.length; i++){
        if (users[i].attributes.id){
            var id = users[i].attributes.id;
            var state= 'offline';
            for(var c=0; c<users[i].children.length; c++){
                if(users[i].children[c].attributes.tag == 'connections'){
                   state = users[i].children[c].children[0].attributes.status;
                }
            }
            
            // loop through the monitorStatesArr
            for(var j=0; j<monitorStatesArr.length;j++){
            	
                if (monitorStatesArr[j] == id){
                    updateState(id, state);
                }
            }
        }  
    } 
    
    myMSG.jData = jData;
    myMSG.mapUsersSetStates();
    
    // now start to peek for changes
    setTimeout(peek, peekTimeout);
}

function userSetStates(){
	// do nothing
}

function disconnected(){
	// do nothing
}

function updateMarkerState(){
	// do nothing
}

function zoomToLocation(){
	// do nothing
}