$(document).ready(function() {
	mpnSession.init();
});

var mpnSession = {};

mpnSession.init = function() {
	$.ajax({
	    url: "/mpn/session/properties",
	    data: {}, 
	    type: 'GET',
	    contentType: "text/xml",
	    dataType: "text",
	    success: function (data, status, xhr) {
	    	mpnSession.log("Initializing session timer.");
	    	mpnSession.log(data);
	    	
	    	mpnSession.pollLogoutTimerDelay = mpnSession.valueFromXml("SessionTimerResponse > LogoutTimer > Delay", data);
	    	mpnSession.pollWarningTimerDelay = mpnSession.valueFromXml("SessionTimerResponse > WarningTimer > Delay", data);;
	    	mpnSession.logoutTimerUrl = mpnSession.valueFromXml("SessionTimerResponse > LogoutTimer > Url", data);
	    	mpnSession.warningTimerUrl = mpnSession.valueFromXml("SessionTimerResponse > WarningTimer > Url", data);
	    	mpnSession.logoutUrl = mpnSession.valueFromXml("SessionTimerResponse > LogoutUrl", data);
	    	mpnSession.isActive = false;
	    	mpnSession.currentState = null;
	    	mpnSession.debug = false;
	    	
	    	$(document).on(
	    		"mousemove keydown DOMMouseScroll mousewheel mousedown", 
	    		null,
	    		null, 
	    		function (event) {
	    			mpnSession.isActive = true;
	    		});
	    	
	    	$('#sessionModal').on('hide.bs.modal', function (e) {
	    		mpnSession.log("Session timer hidden.");
	    		mpnSession.isActive = true;
	    		mpnSession.transition(mpnSession.states.pollingWarningTimer);
	    	});
	    	
	    	mpnSession.log("Session timer is active.");
	    	
	    	//Kick off timer.
	    	mpnSession.transition(mpnSession.states.pollingWarningTimer);
	    },
	    error: function (xhr, ajaxOptions, error) {  
	        mpnSession.log(xhr.status);          
	        mpnSession.log(error);
	    } 
	});
};

mpnSession.log = function(message) {
	if (mpnSession.debug === true && window.console) {
		console.log(message);
	}
};

mpnSession.logout = function() {
	//Returns a jQuery Deferred which will trigger a "done" callback
	//once all in-progress requests are complete.
	function ajaxDeferred() {
	    var future = $.Deferred();

	    function pollOrbeonRequestsInProgress() {
	        var requestPending = false;
	        
	        if(typeof(ORBEON) != "undefined") {
	        	requestPending = ORBEON.xforms.Globals.requestInProgress 
	            	|| ORBEON.xforms.Globals.eventQueue.length > 0;
	        }
	        
	        if (requestPending) {
	            setTimeout(pollOrbeonRequestsInProgress, 100);
	        }
	        else {
	            future.resolve();
	        }
	    }

	    setTimeout(pollOrbeonRequestsInProgress, 100);
	    return future;
	}
	
	
	if($('.fr-save-button button')[0]) {
		//Attempt to save FB form.
		$('.fr-save-button button')[0].click();
	}
	else if($('.fr-save-final-button button')[0]) {
		//Attempt to save FR form.
		$('.fr-save-final-button button')[0].click();
	}
	
	//Register callback to logout when save is complete.
	ajaxDeferred().done(function() {
		//Redirect to logout page.
		window.location = mpnSession.logoutUrl;
	});	
};

mpnSession.pollLogoutTimer = function(onLogout) {
	mpnSession.log("pollLogoutTimer() entered.");
	
	$.ajax({
	    url: mpnSession.logoutTimerUrl,
	    data: {}, 
	    type: 'POST',
	    contentType: "text/xml",
	    dataType: "text",
	    success: function (data, status, xhr) {
	    	mpnSession.log("Processing Logout Timer Response.");
	    	mpnSession.log(data);
	    	
	    	if(mpnSession.shouldLogout(data)) {
	    		onLogout();	
	    	}
	    },
	    error: function (xhr, ajaxOptions, error) {  
	        mpnSession.log(xhr.status);          
	        mpnSession.log(error);
	    } 
	});
};

mpnSession.pollWarningTimer = function(onWarning) {
	mpnSession.log("pollWarningTimer() - mpnSession.isActive: " + mpnSession.isActive);
	
	$.ajax({
	    url: mpnSession.warningTimerUrl,
	    data: 
	    	"<SessionTimerRequest>"
	    		+ "<IsUserActive>" + mpnSession.isActive + "</IsUserActive>"
	    	+ "</SessionTimerRequest>", 
	    type: 'POST',
	    contentType: "text/xml",
	    dataType: "text",
	    success: function (data, status, xhr) {
	    	mpnSession.log("Processing Warning Timer Response.");
	    	mpnSession.log(data);
	    	
	    	if(mpnSession.shouldShowWarning(data)) {
	    		onWarning();
	    	}
	    },
	    error: function (xhr, ajaxOptions, error) {  
	        mpnSession.log(xhr.status);          
	        mpnSession.log(error);
	    } 
	});
	
	mpnSession.isActive = false;
};

mpnSession.shouldLogout = function(xmlString) {
	var value, result;
	value = mpnSession.valueFromXml("ShouldLogout", xmlString);
	result = (value === 'true');
	mpnSession.log("shouldLogout: " + result);
	return result;
};

mpnSession.shouldShowWarning = function(xmlString) {
	var value, result;
	value = mpnSession.valueFromXml("ShouldShowTimer", xmlString);
	result = (value === 'true');
	mpnSession.log("shouldShowWarning: " + result);
	return result;
};

mpnSession.showWarning = function() {
	$('#sessionModal').modal('show');
};

mpnSession.start = function () {
	mpnSession.transition(mpnSession.states.pollingWarningTimer);
};

mpnSession.states = {
    pollingWarningTimer: {
    	intervalId: null,
    	execute: function () {
    		mpnSession.log("Polling warning timer...");
    		mpnSession.states.pollingWarningTimer.intervalId = setInterval(
    			function () {
    				mpnSession.pollWarningTimer(
    					function () {
    						mpnSession.showWarning();
    						mpnSession.transition(mpnSession.states.pollingLogoutTimer);
    					});
    			},
    			mpnSession.pollWarningTimerDelay
    		);
    	},
    	onExit: function() {
    		clearInterval(mpnSession.states.pollingWarningTimer.intervalId);
    	}
    },
    pollingLogoutTimer: {
    	intervalId: null,
    	execute: function () {
    		mpnSession.log("Polling logout timer...");
    		mpnSession.states.pollingLogoutTimer.intervalId = setInterval(
    			function () {
    				mpnSession.pollLogoutTimer(
    					function() {
    						mpnSession.transition(mpnSession.states.loggingOut);
    					});
    			},
    			mpnSession.pollLogoutTimerDelay
    		);
    	},
    	onExit: function() {
    		clearInterval(mpnSession.states.pollingLogoutTimer.intervalId);
    	}
    },
    loggingOut: {
    	execute: function () {
    		mpnSession.log("Logging out...");
    		mpnSession.logout();
    	},
    	onExit: function() {
    		//No-op
    	}
    },
    stopped: {
    	execute: function () {
    		mpnSession.log("Session timer stopped.");
    	},
    	onExit: function() {
    		//No-op
    	}
    }
};

mpnSession.stop = function () {
	mpnSession.transition(mpnSession.states.stopped);
};

mpnSession.transition = function(newState) {
	if(mpnSession.currentState) {
		mpnSession.currentState.onExit();
	}
	
	mpnSession.currentState = newState;
	mpnSession.currentState.execute();
};

mpnSession.valueFromXml = function(selector, xmlString) {
	var xmlDoc, xmlObj, result, node;
	xmlDoc = $.parseXML(xmlString);
	xmlObj = $(xmlDoc);
	node = xmlObj.find(selector);
	return node.text();
};
