(function () {
	
	/* A simple persitence layer for url hashes. 
	 * 
	 * @param callback Called on hash change 
	 */
	window.UrlHashManager = function (callback) {  
		 this.callback = callback;
		 this.hash = null; 
		 	 
		 this.value = function (key) { 
			 this.loadHash(); 
			 return this.hash[key];
		 }
		 
		 this.add = function (key, val) { 
			 this.loadHash();
			 this.hash[key] = val; 
			 this.writeHash();
			 this.callback(this.hash);
		 };
		 
		 this.rm = function (key) { 
			 this.loadHash(); 
			 delete this.hash[key];
			 this.writeHash();
			 this.callback(this.hash);
		 };
		 
		 this.loadHash = function () { 
			 if(this.hash === null) { 
				 this.hash = decode(currentHash());
			 }
			 return this.hash;
		 };
		 
		 this.writeHash = function () {
			 location.hash =  "#" + encode(this.hash);
		 };
		 
		 // normalized hash function
		 var currentHash = function () {
			 return ( location.hash.indexOf('#') > -1 ) ? location.hash.substr(1) : location.hash;
		 };
		 
		 var decode = function (hash) { 
			var components = hash.split(';');
			var result = new Array();
			var entry = null;
			
			for ( var i = 0; i < components.length; i++ ) {
				if (components[i] !== "") {
					var pair = components[i].split('=');
					result[pair[0]] = decodeValue(pair[1]);
				}
			}
			return result;
		 };
		 
		 var decodeValue = function (str) { 
			 if ( str.indexOf(',') > -1 ) {
				var components = str.split(',');
				return ( components[components.lenth - 1] === '') ? components.slice(-1) : components; 
			 }
			 return str;
		 };
		 
		function encode (hash) {
			var result = '';
			for (var i in hash) { 
				if (i !== undefined && hash.hasOwnProperty(i)) { 
					result += i + '='; 
					if (jQuery.isArray(hash[i])) {
						result += encodeArray(hash[i]);
					} else { 
						result += escape(hash[i]);
					}
					result += ';';
				}
			}
			return result;
		};
			
		function escape(str) { 
			return str.replace("#", "");
		};
		
		function encodeArray(arr) { 
			var result = '';
			for (var i = 0; i < arr.length; i++) {
				if(arr[i] !== undefined && arr[i] !== '') {
					result += arr[i] + ',';
				}
			}
			return result;
		}
		 
		this.loadHash();
		this.callback(this.hash, true);
	 };

})();
