define(['jQuery'],

	function($) {
		//Global should not have any dependencies
		var utilities = {},
			headerHeight,
			footerHeight;

		utilities.flattenLinks = function(object) {
			var links = object.get('link');
			if (typeof links !== 'undefined') {
				size = links.length;
				for (var i=0; i<size; i++) {
					if (links[i].title) {
						object.set(links[i].title,links[i]);
					} else {
						object.set('self',links[i]);
					}
				}
				object.unset('link');
			}
		};

		utilities.globalInit = function(app) {
			if (app.user) {
				if (!app.provider) {
					utilities.checkROA(app);
				}
				utilities.resizePanes();
				$(window).resize(utilities.resizePanes);
			}
			
			$('body').on('pageshow',function(event, ui) {
				var prevPage = $(ui.prevPage);
				if (prevPage.hasClass('ui-dialog')) {
					prevPage.remove();
				}
					
				utilities.resizePanes(app.customHeight || 0);
				utilities.registerLoadingSpinner(app.spinnerOptions || 0);
			});
		};

		utilities.slidePrimary = function(selector) {
			var $moveContent = $(selector || '#content-primary');
			if ($moveContent.hasClass('closed')) {
                $moveContent.removeAttr('style').toggleClass('closed');
			} else {
                $moveContent.animate({
					left: '0'
				}, 300, function() {
                    $moveContent.addClass('closed');
				});
			}
		};

		utilities.resizePanes = function(customHeight) {
			if (typeof headerHeight === 'undefined' && $('#main .ui-header').height() !== null) {
				headerHeight = customHeight || 42;
				footerHeight = 86;
			}
			//header and footer have lost relevence in soc
			$('#main .scrollable').height($(window).height() - headerHeight - footerHeight);
			utilities.eventAggregator.trigger('footer');
		};

		utilities.checkROA = function(app) {
			var rightOfAccessAccepted = true;
			if (typeof app.user !== 'undefined' && app.user.id) {
                rightOfAccessAccepted = typeof app.user.rightOfAccessAccepted !== 'undefined' ? app.user.rightOfAccessAccepted : app.user.attributes.rightOfAccessAccepted;
				if (!rightOfAccessAccepted) {
					window.location = utilities.getReferencePath() + '../../MobileHealthPlatformWeb/roa/index.html?url=' + window.location.pathname;
				}
			}
		};

		utilities.writeToStorage = function(key, value) {
			if (value) {
				try {
					window.localStorage[key] = JSON.stringify(value);
				} catch (e) {
					if (e == QUOTA_EXCEEDED_ERR) {
						var message = 'Local-Storage Quota exceeded!';
						if (window.console && window.console.log) {
							console.log(message);
						} else {
							alert(message);
						}
					}
				}
			}
		};

		utilities.readFromStorage = function(key) {
			var value = null;
			if (typeof(window.localStorage) != 'undefined') {
				value = JSON.parse(window.localStorage[key] || null);
			}
			return value;
		};

		utilities.checkEULA = function(prevHash, modifiedDate) {
			var url = window.location.pathname,
				value = utilities.readFromStorage(url + "eula");

        if (value === null || new Date(modifiedDate).getTime() > value.dateAccepted) {
				return "#eula";
			} else {
				return prevHash;
			}
		};

		utilities.getReferencePath = function() {
			var referencePath = window.location.protocol + "//" + window.location.host + window.location.pathname;
			var index = referencePath.indexOf("index.html");
			if (index !== -1) {
				referencePath = referencePath.substring(0, index);
			}
			return referencePath;
		};

        //Get the path to MobileHealthPlatformWeb, which may not be the ReferencePath for other independent apps (Wellness, Immunizations, etc)
        utilities.getMhpReferencePath = function() {
            var referencePath = window.location.protocol + "//" + window.location.host + "/MobileHealthPlatformWeb";
            return referencePath;
        };

        utilities.getReferencePathWithHash = function() {
			return encodeURI(utilities.getReferencePath() + window.location.hash);
		};

            utilities.deleteCookie = function(cookieName) {
			document.cookie = encodeURIComponent(cookieName) + "=deleted; expires=" + new Date(0).toUTCString();
		};
		
		utilities.cleanUpSession = function() {
			window.sessionStorage.token = null;
			$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
				jqXHR.setRequestHeader("Authorization", "");
			});
			utilities.deleteCookie('JSESSIONID');
		};
		
		utilities.findMessage = function(errMsg) {
			var lines = errMsg.split('\n');
			
			for (var i=0; i<lines.length; i++) {
				if (lines[i].indexOf('Message:') >= 0) {
					return lines[i];
				}
			}
			return errMsg;
		};
		
		utilities.parseTokenAndRegisterOauthHandler = function() {
			var params = {}, queryString = location.search.substring(1),
			regex = /([^&=]+)=([^&]*)/g, m;
			while (m = regex.exec(queryString)) {
				params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
			}

			var token = params['token'];

			if(typeof token !== 'undefined' && token !== 'undefined' && token !== null && token !== 'null'){
				window.sessionStorage['token']=JSON.stringify(token);
			}
			
			var storedToken = window.sessionStorage['token'];
			
			if(typeof storedToken !== 'undefined' && storedToken !== 'undefined' && storedToken !== null && storedToken !== 'null'){
				$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
					var currentToken = JSON.parse(storedToken);
					jqXHR.setRequestHeader("Authorization", "Bearer " + currentToken);
				});
			} else {
				utilities.cleanUpSession();
			}

			$(document).ajaxError(function(e, jqxhr, settings, exception) {
				if ( jqxhr.status == 0 || jqxhr.status == 200 || jqxhr.status == 400 || jqxhr.status == 404) {
					
				} else if (jqxhr.status == 403) {
					utilities.cleanUpSession();
					window.location = utilities.getReferencePath() + '../oauthlogin?redirect_uri=' + utilities.getReferencePathWithHash();
				} else if (jqxhr.status == 401) {
					if (jqxhr.responseText.indexOf('invalid_token') > 0) {
						utilities.cleanUpSession();
						$.ajax(settings);
					}
				} else {
					alert('unknown error at url: ' + settings.url + '\nstatus code: ' + jqxhr.status + ' \nerror:\n' + utilities.findMessage(jqxhr.responseText));
					//alert('unknown error in: ' + settings.url + '\nstatus code: ' + jqxhr.status + ' \nerror:\n' + jqxhr.responseText);
				}
			});
			
		};
		utilities.parseTokenAndRegisterOauthHandler();
		
		utilities.registerLoadingSpinner = function(options) {
			$(document)
			.ajaxStart(function(event, xhr, settings) {
				$.mobile.loading('show', options || 0);
			})
			.ajaxStop(function() {
				$.mobile.loading('hide');
			})
			.ajaxError(function() {
				$.mobile.loading('hide');
			});
		};
		
		utilities.create = function(page) {
			try {
				page.page("destroy");
			} catch (err) {
				// if page has not been initialized yet, destroy is not necessary
			}
			page.page();
		};
		
		utilities.eventAggregator = _.extend({}, Backbone.Events);
		utilities.eventAggregator.on("logout", function() {
			utilities.cleanUpSession();
		});
		
		return {
			getUtilities: function() {
				return utilities;
			}
		};
	}
);
