(function(n, w){
	var data,
	params,
	parts,
	location,
	unmatched,
	ctr = w[n] = function(path, fn){
		return new ctr.prototype.init(path, fn);
	},
	testpath = function(location, path){
		if('string' == typeof(path)){
			path = new RegExp('^[\/]?'+path);
		}
		
		if (!(path instanceof RegExp)){
			throw 'Path is not a String or RegExp';
		}
		
		var remains = location.replace(path, '');
		if(remains != location){
			return remains;
		}
		return false;
	}

	ctr.prototype = {
		init: function(path, fn){
			var remains = testpath(unmatched, path);
			if(false !== remains){
				var orig_unmatched = unmatched;
				unmatched = remains;
				fn.call({
					'path': parts,
					'params': params
				}, data);
				unmatched = orig_unmatched;
			}
			return ctr;
		},
		location: function(path){
			if(!path) return location;
			location = unmatched = path;
			params = {};
			parts = path.match(/[a-zA-Z0-9_-]+/g);
			var q = /.*[\^?](.*)[\^#]/.exec(path);
			if(!q || !q[1]){
				return this;
			}
			q = q[1].split('&');
			var l = q.length;
			for(var i=0; i<l; i++){
				var p = q[i].split('=');
				var n = p[0];
				if('[' == n[n.length-2] && ']' == n[n.length-1]){
					n = n.substr(0,n.length-2);
					if(!params[n]){ 
						params[n] = [];
					}
					params[n].push(p[1]);
				}else{
					params[n] = p[1];
				}
			}
			return this;
		},
		data: function(obj){
			if(!obj) return data;
			data = obj;
			return this;
		},
		version:0.1
	}
	ctr.prototype.init.prototype = ctr.prototype;
	
	for(var p in ctr.prototype){
		if('function' == typeof(ctr.prototype[p])){
			ctr[p]=ctr.prototype[p];
		}
	}
	ctr.location(w.location.pathname+w.location.search);
})('frontal', window);
