History.implement(new Options);History.implement({options:{separator:";"},routes:[],register:function(a){this.routes.push(a)==1&&this.addEvent("changed",this.match)},unregister:function(a){this.routes.remove(a)},match:function(a,b,c){c||this.routes.each(Function.methodize("match",this.state))},generate:function(){return this.routes.map(Function.methodize("generate")).clean().join(this.options.separator)},update:function(){return this.setState(this.generate())}}); History.Route=new Class({Implements:[Events,Options],options:{skipDefaults:true,defaults:[],pattern:null,flags:"",generate:function(a){return a[0]},onMatch:$empty},initialize:function(a){this.setOptions(a);this.pattern=this.options.pattern||"(.*)";if($type(this.pattern)=="string")this.pattern=new RegExp(this.pattern,this.options.flags);this.values=this.defaults=this.options.defaults.slice();History.register(this);return this},setValues:function(a){if(this.values.toString()==a.toString())return this; this.values=a;History.update();return this},setValue:function(a,b){if(this.values[a]==b)return this;this.values[a]=b;History.update();return this},build:function(a){var b=this.values.slice();this.values=a;a=History.generate();this.values=b;return a},destroy:function(){History.unregister(this)},generate:function(){if(this.options.skipDefaultMatch&&String(this.values)==String(this.defaults))return null;return this.options.generate.call(this,this.values)},match:function(a){a=a.match(this.pattern);var b= this.defaults;if(a){a.splice(0,1);for(var c=0,d=a.length;c<d;c++)a[c]=$pick(a[c],b[c]||null);if(String(a)!=String(b))this.values=a}else this.values=this.defaults.slice();this.fireEvent("onMatch",[this.values,this.defaults])}});Function.methodize=function(a){var b=Array.slice(arguments,1);return function(c){return c[a].apply(c,b)}};
