﻿/* Copyright (c) 2006 Mathias Bank (http://www.mathias-bank.de)
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
* 
* Thanks to Hinnerk Ruemenapf - http://hinnerk.ruemenapf.de/ for bug reporting and fixing.
*/
function URLEncode(unencodedValue) {
	// The Javascript escape and unescape functions do not correspond
	// with what browsers actually do...
	var SAFECHARS = "0123456789" + 				// Numeric
					"ABCDEFGHIJKLMNOPQRSTUVWXYZ" + // Alphabetic
					"abcdefghijklmnopqrstuvwxyz" +
					"-_.!~*'()"; 				// RFC2396 Mark characters
	var HEX = "0123456789ABCDEF";

	var plaintext = unencodedValue;
	var encoded = "";
	for (var i = 0; i < plaintext.length; i++) {
		var ch = plaintext.charAt(i);
		if (ch == " ") {
			encoded += "+"; 			// x-www-urlencoded, rather than %20
		} else if (SAFECHARS.indexOf(ch) != -1) {
			encoded += ch;
		} else {
			var charCode = ch.charCodeAt(0);
			if (charCode > 255) {
				alert("Unicode Character '"
                        + ch
                        + "' cannot be encoded using standard URL encoding.\n" +
				          "(URL encoding only supports 8-bit characters.)\n" +
						  "A space (+) will be substituted.");
				encoded += "+";
			} else {
				encoded += "%";
				encoded += HEX.charAt((charCode >> 4) & 0xF);
				encoded += HEX.charAt(charCode & 0xF);
			}
		}
	} // for

	return encoded;
};

function URLDecode(encodedValue) {
	// Replace + with ' '
	// Replace %xx with equivalent character
	// Put [ERROR] in output if %xx is invalid.
	var HEXCHARS = "0123456789ABCDEFabcdef";
	var encoded = encodedValue
	var plaintext = "";
	var i = 0;
	while (i < encoded.length) {
		var ch = encoded.charAt(i);
		if (ch == "+") {
			plaintext += " ";
			i++;
		} else if (ch == "%") {
			if (i < (encoded.length - 2)
					&& HEXCHARS.indexOf(encoded.charAt(i + 1)) != -1
					&& HEXCHARS.indexOf(encoded.charAt(i + 2)) != -1) {
				plaintext += unescape(encoded.substr(i, 3));
				i += 3;
			} else {
				alert('Bad escape combination near ...' + encoded.substr(i));
				plaintext += "%[ERROR]";
				i++;
			}
		} else {
			plaintext += ch;
			i++;
		}
	} // while
	return plaintext;
};


var Url = {
	// public method for url encoding
	encode: function(string) {
		return escape(this._utf8_encode(string));
	},

	// public method for url decoding
	decode: function(string) {
		return this._utf8_decode(unescape(string));
	},

	// private method for UTF-8 encoding
	_utf8_encode: function(string) {
		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
	_utf8_decode: 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;
	}

}

jQuery.extend({
	/**
	* Returns get parameters.
	*
	* If the desired param does not exist, null will be returned
	*
	* @example value = $.getURLParam("paramName");
	*/
	getURLParameter: function(url, strParamName) {
		var strReturn = "";
		var strHref = url;
		var bFound = false;

		var cmpstring = strParamName + "=";
		var cmplen = cmpstring.length;

		if (strHref.indexOf("?") > -1) {
			var strQueryString = strHref.substr(strHref.indexOf("?") + 1);
			var aQueryString = strQueryString.split("&");
			for (var iParam = 0; iParam < aQueryString.length; iParam++) {
				if (aQueryString[iParam].substr(0, cmplen) == cmpstring) {
					var aParam = aQueryString[iParam].split("=");
					strReturn = URLDecode(aParam[1]); //should decode url string
					bFound = true;
					break;
				}

			}
		}
		if (bFound == false) return null;
		return strReturn;
	}
});

jQuery.extend({
	setURLParameter: function(url, parameterName, parameterValue) {
	return url + "?" + URLEncode(parameterName) + "=" + URLEncode(parameterValue);
	}
});

jQuery.extend({
	appendURLParameter: function(url, parameterName, parameterValue) {
	return url + "&" + URLEncode(parameterName) + "=" + URLEncode(parameterValue);
	}
});
