Application.HashManager = (function() {
	var instance = null;
	
	function Singleton() {
		this._timeOut = 250;
		this._hash = '';
	}
	
	Singleton.inherits(Observable);
	
	Singleton.prototype.startObserving = function() {
		setTimeout(this._observeHash.bind(this), this._timeOut);
	}
	
	Singleton.prototype.setHash = function(hash, options) {
		
		if (options !== null && typeof(options) == 'object') {
			var opt = [];
			for (x in options) {
				opt.push(x + '=' + escape(options[x]));
			}
			
			hash = hash + '?' + opt.join('&');
		}
		window.location.hash = hash;
	}
	
	Singleton.prototype.parseHash = function(hash) {
		var returnValue = {};
		var hashParts = hash.split('?');
		
		returnValue.hash = hashParts[0].replace(/^#/, '');
		
		if (hashParts.length == 2) {
			returnValue.options = {};
			
			var options = hashParts[1].split('&');
			for (var i=0; i<options.length; i++) {
				var optionParts = options[i].split('=');
				
				if (optionParts.length == 2) {
					returnValue.options[optionParts[0]] = optionParts[1];
				} else {
					returnValue.options[optionParts[0]] = true;
				}
			}
		}
		
		return returnValue;
	}
	
	Singleton.prototype._observeHash = function() {
		var currentHash = window.location.hash;
		
		if (this._hash != currentHash) {
			this._hash = currentHash;
			this.fire('hashChanged', this.parseHash(this._hash));
		}
		
		setTimeout(this._observeHash.bind(this), this._timeOut);
	}
	
	return new function() {
		this.getInstance = function() {
			if (instance == null) {
				instance = new Singleton();
				instance.constructor = null;
			}
			return instance;
		}
	}
})();
