﻿(function(){
  anch = document.location.hash, handlers = [];
    
  jQuery.extend({
    anchor: {
      addMapping: function(regexp, callback) {
        if (typeof(regexp) == 'object') {
          jQuery.map(regexp, function(arg){
            args = {r: arg[0], cb: arg[1]};});}
        else  args = {r: regexp, cb: callback};
        handlers.push(args);
        return jQuery.anchor;
      },
      update: function(key, value) {
        if(anch == '') {
            document.location.hash = anch = '#' + key + '=' + value;
            return jQuery.anchor;
        }
        var arrHash = anch.substring(1).split('&');
        var foundKey = false;
        
        jQuery.each(arrHash, function(i,n) {
            var kv = n.split('=');
            if(jQuery.inArray(key, kv) == 0) {
                if(value == null)
                    arrHash.splice(i, 1);
                else
                    arrHash[i] = key + '=' + value;
                document.location.hash = anch = '#' + arrHash.join("&");
                foundKey = true;
                return false;
            }
        });
        
        if(foundKey == false && value != null) {
            document.location.hash = anch += '&' + key + '=' + value;
        }
        
        return jQuery.anchor;
      },
      query: function(key) {
        var arrHash = anch.substring(1).split('&');
        var val = null;
        jQuery.each(arrHash, function(i,n) {
            var kv = n.split('=');
            if(jQuery.inArray(key, kv) == 0) {
                val = kv[1];
                return false;
            }
        });
        
        return val;
      }
    }
  })(document).ready(function(){
    jQuery.map(handlers, function(handler){
      match = anch.match(handler.r) && anch.match(handler.r)[0] || false;
      if (match) handler.cb.apply(this, [match, (anch || false)]);});});
})();
