/*

WARNING: EXPERIMENTAL CODE!!!

*/

(function() {
	//a system for mapping changes in url hash state to javascript actions.
	//each "state" has a list of one or more things to do when that state inits
	//plus a list of one or more things to do when that state finalizes
	//state detection is done based on RegExp matching
	var states = {};
	var compileds = {};//for performance to contained compiled reg exps
	/**
	Setup a listener for hash state changes. Finalizer(s) for a previous state
	are guaranteed to run before initializer(s) for a new state.

	@param pattStr - A regular expression in string form
	@param initFunc - A function to execute when the hash changes to something matching pattStr.
		The function's arguments will be the results of the string.match() method.
		The function's "this" object will be the target of the hash, if it exists, otherwise the window object.
		An array of functions can also be provided which will be executed in order.
	@param finalizeFunc - A function to execute when the hash changes away from something matching pattStr.
		The function's arguments will be the results of the string.match() method.
		The function's "this" object will be the target of the hash, if it exists, otherwise the window object.
		An array of functions can also be provided which will be executed in order.
	*/
	function addHashStateListener(pattStr, initFunc, finalizeFunc){
		if (!(initFunc instanceof Array)) {
			initFunc = [initFunc];
		} else if (!initFunc) {
			initFunc = [];
		}
		if (!(finalizeFunc instanceof Array)) {
			finalizeFunc = [finalizeFunc];
		} else if (!finalizeFunc) {
			finalizeFunc = [];
		}
		states[pattStr] = {"init":initFunc,"finalize":finalizeFunc};
	};
	reg.preSetup(function(){
		var prevHash = null;
		var location = window.location;
		window.setInterval(function(){
			if (location.hash !== prevHash) {
				//this branch will execute on page load and on all subsequent
				//changes to location.hash
				for (var pattStr in states) {
					var patt = compileds[pattStr];
					if (!patt) {
						patt = new RegExp(pattStr);
						compileds[pattStr] = patt;
					}
					var pMat=(prevHash!==null)?prevHash.match(patt):null;
					var mat=location.hash.match(patt);
					for (var i=0;i<states[pattStr]["finalize"].length&&pMat;i++){
						var func = states[pattStr]["finalize"][i];
						if (func) { func.apply(gebi(prevHash.substring(1)), pMat); }
					}
					for (var i=0;i<states[pattStr]["init"].length&&mat;i++){
						var func = states[pattStr]["init"][i];
						if (func) { func.apply(gebi(location.hash.substring(1)), mat); }
					}
				}
				prevHash = location.hash;
			}
		},100);
	});

	window.addHashStateListener = addHashStateListener;

})();

