/**
 * Propagates hashchange events in the form of states to the controllers.
 * Constrollers can subscribe for events by calling subscribe(controller).
 * To manually trigger the hash change event call trigger().
 * 
 * The state object has the following form:
 * <code>
 * 	state = { page: "[the page identifier]",
 * 			  hash: "[raw hash value]",
 * 			  args: {[parameters]},
 * 			  isPage: [function],
 * 			  hasArg: [function]}				 
 * </code>
 * @constructor
 */
function PastelStateChangeNotifier() {
 
	this._controllers = new Array();
	
	/**
	 * Subscribe for hash change events
	 * @param {PastelBaseController} controller
	 */
	this.subscribe = function(controller) {
		this._controllers.push(controller);
	};
 
	this._parseState = function(hash) {
		
		var state = { page: "#",
    				  hash: hash,
			  	 	  args : {},
			  	 	  isPage : function(pageName) {
			  	 		if (pageName == "" || 
			  	 				pageName == null ||
			  	 				pageName == undefined) {
				  	 			return false;
				  	 		}
			  	 		if (this.page != pageName) {
			  				return false;
			  			}
			  	 		return true;
			  	 	  },
					  hasArg : function(argName) {
			  	 		if (argName == "" || 
			  	 			argName == null ||
			  	 			argName == undefined) {
			  	 			return false;
			  	 		}
			  	 		  
			  	 		if (this.args[argName] == undefined) {
			  				return false;
			  			}
			  	 		return true;
			  	 	  }
					};
		
		var params = hash.split("/"); 
		state.page = params[0];
		var argsStartIdx = 1;
		 
		var paramsLen = params.length;
		var argIdx = argsStartIdx;
		while(argIdx < paramsLen) {
			var paramName = params[argIdx++];
			var paramVal = params[argIdx++];
			state.args[paramName] = paramVal;
		}
		
		return state;
	};
	
	var lastState = null;
	this._onHashChange = function(hash) {
		if(hash == "") {
			return;
		}
		
		var currState = this._parseState(hash);	
		for(var i = 0; i<this._controllers.length; i++) {
			this._controllers[i].setState(currState, lastState);
		}
		lastState = currState;
	};
	
	/**
	 * Manualy trigger the hash change event
	 */
	this.trigger = function() {
		$(window).trigger( 'hashchange' );
	};
	
	$(window).bind( 'hashchange', $.proxy(function(){
		var hash = location.hash.replace(/^.*#/, '');
		this._onHashChange(hash);
     }, this));
}
