var addressManager =function(){
	 var priv = {
			 useHistory : true,
			 changeHandler : null,
			 encodeUrlParam : function(param) {
			    	return encodeURI(param).replace(/&/g, "%26");
			 },   
			 decodeUrlParam : function(param) {
		    	return param.replace(/%26/g, "&");
		    }
	 }		 
			 
	// Public methods
	return {	
		 onChangeAddress : function(parameter){
		 	priv.historyValue=parameter;
		 	if(priv.useHistory) {
		        jQuery.address.value(priv.historyValue);
		    }else{
		    	var param=urlParser.getParams(priv.historyValue);
		    	priv.changeHandler(param.parameters);
		    }
	 	},
		 
		onHistoryChange : function(event) {
	 		priv.changeHandler(event.parameters);
		},
			
		onHistoryInit : function(event) {
			addressManager.onHistoryChange(event);
		},
	
		setUseHistory : function(booleanValue) {
			priv.useHistory = booleanValue;
		},
		
		setChangeHandler : function(handler){
			priv.changeHandler = handler;
		}
	};
}();


var urlEncoder = function() {
	  var priv = {
	    // private method for UTF-8 encoding
	    utf8Encode : function(string) {
	    	if (string == undefined) {
	    		return "";
	    	}
	      string = string.replace(/\r\n/g, "\n");
	      var utftext = "";

	      for ( var n = 0; n < string.length; n++) {

	        var c = string.charCodeAt(n);

	        if (c < 128) {
	          utftext += String.fromCharCode(c);
	        } else if ((c > 127) && (c < 2048)) {
	          utftext += String.fromCharCode((c >> 6) | 192);
	          utftext += String.fromCharCode((c & 63) | 128);
	        } else {
	          utftext += String.fromCharCode((c >> 12) | 224);
	          utftext += String.fromCharCode(((c >> 6) & 63) | 128);
	          utftext += String.fromCharCode((c & 63) | 128);
	        }

	      }

	      return utftext;
	    },

	    // private method for UTF-8 decoding
	    utf8Decode : function(utftext) {
	      var string = "";
	      var i = 0;
	      var c = c1 = c2 = 0;

	      while (i < utftext.length) {

	        c = utftext.charCodeAt(i);

	        if (c < 128) {
	          string += String.fromCharCode(c);
	          i++;
	        } else if ((c > 191) && (c < 224)) {
	          c2 = utftext.charCodeAt(i + 1);
	          string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
	          i += 2;
	        } else {
	          c2 = utftext.charCodeAt(i + 1);
	          c3 = utftext.charCodeAt(i + 2);
	          string += String.fromCharCode(((c & 15) << 12)
	              | ((c2 & 63) << 6) | (c3 & 63));
	          i += 3;
	        }

	      }

	      return string;
	    }
	  };

	  return {
	    // public method for url encoding
	    encode : function(string) {
	      return escape(priv.utf8Encode(string));
	    },

	    // public method for url decoding
	    decode : function(string) {
	      return priv.utf8Decode(unescape(string));
	    }
	  };
}();

var urlParser = function() {
  var priv = {
    getParams : function(urlArg) {
      var eventObjStub = {};
      eventObjStub['parameters'] = {};

      urlArr = urlArg.split("\?");
      if(urlArr.length != 2) {
        return eventObjStub;
      }
      urlParamsArr = urlArr[1].split("\&");
      
      if(urlParamsArr.length == 0) {
        return eventObjStub; 
      }
      
      urlParamsKeyValue = {};
      for(var i = 0; i< urlParamsArr.length; i++) {
        var tempArr = urlParamsArr[i].split("=");
        if(tempArr.length == 2) {
          eventObjStub.parameters[urlEncoder.decode(tempArr[0])] = urlEncoder.decode(tempArr[1]);
        }
        
      }
      return eventObjStub;
    }
  };

  return {
    // public method for url encoding
    getParams : function(urlArg) {
      return priv.getParams(urlArg);
    }
  };
}();
