
var unreserved = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.~";
var reserved = "!*'();:@&=+$,/?%#[]";
var allowed = unreserved + reserved;
var hexchars = "0123456789ABCDEFabcdef";


function gethex(decimal) {
	return "%" + hexchars.charAt(decimal >> 4) + hexchars.charAt(decimal & 0xF);
}
function encode_to_utf8 (data){

	var decoded = data;
	var encoded = "";
	
	for (var i = 0; i < decoded.length; i++ ) {
		var ch = decoded.charAt(i);
	// Check if character is an unreserved character:
		if (unreserved.indexOf(ch) != -1) {
			encoded = encoded + ch;
		} else {
			var charcode = decoded.charCodeAt(i);

			// Position 0 - 127 is equal to percent-encoding with an ASCII character encoding:
			if (charcode < 128) {
				encoded = encoded + gethex(charcode);
			}

			// Position 128 - 2047: two bytes for UTF-8 character encoding.
			if (charcode > 127 && charcode < 2048) {
			  // First UTF byte: Mask the first five bits of charcode with binary 110X.XXXX:
			    encoded = encoded + gethex((charcode >> 6) | 0xC0);
			      // Second UTF byte: Get last six bits of charcode and mask them with binary 10XX.XXXX:
				encoded = encoded + gethex((charcode & 0x3F) | 0x80);
			}

			// Position 2048 - 65535: three bytes for UTF-8 character encoding.
			if (charcode > 2047 && charcode < 65536) {
			// First UTF byte: Mask the first four bits of charcode with binary 1110.XXXX:
				encoded = encoded + gethex((charcode >> 12) | 0xE0);
			// Second UTF byte: Get the next six bits of charcode and mask them binary 10XX.XXXX:
				encoded = encoded + gethex(((charcode >> 6) & 0x3F) | 0x80);
			// Third UTF byte: Get the last six bits of charcode and mask them binary 10XX.XXXX:
				encoded = encoded + gethex((charcode & 0x3F) | 0x80);
			}

			// Position 65536 - : four bytes for UTF-8 character encoding.
			if (charcode > 65535) {
			// First UTF byte: Mask the first three bits of charcode with binary 1111.0XXX:
			encoded = encoded + gethex((charcode >> 18) | 0xF0);
			// Second UTF byte: Get the next six bits of charcode and mask them binary 10XX.XXXX:
			encoded = encoded + gethex(((charcode >> 12) & 0x3F) | 0x80);
			// Third UTF byte: Get the last six bits of charcode and mask them binary 10XX.XXXX:
			encoded = encoded + gethex(((charcode >> 6) & 0x3F) | 0x80);
			// Fourth UTF byte: Get the last six bits of charcode and mask them binary 10XX.XXXX:
			encoded = encoded + gethex((charcode & 0x3F) | 0x80);
			}

		}

	}
return encoded;
}


function decode_to_utf8(data){

// Some variables:
	var encoded = data;
	var decoded = "";
	// Remember characters that are not allowed in a URL:
	var notallowed = "";
	// Remember illegal percent encoding:
	var illegalencoding = "";
	// UTF-8 bytes from left to right:
	var byte1, byte2, byte3, byte4 = 0;
	var i = 0;

	if (!encoded) encoded = false; 

	while (i < encoded.length && encoded) {
		var ch = encoded.charAt(i);
		// Check for percent-encoded string:
		if (ch == "%") {

			// Check for legal percent-encoding of first byte:
			if (getdec(encoded.substr(i,3)) < 255) {

				// Get the decimal values of all (potential) UTF-bytes:
				byte1 = getdec(encoded.substr(i,3));
				byte2 = getdec(encoded.substr(i+3,3));
				byte3 = getdec(encoded.substr(i+6,3));
				byte4 = getdec(encoded.substr(i+9,3));

				// Check for one byte UTF-8 character encoding:
				if (byte1 < 128) {
					decoded = decoded + String.fromCharCode(byte1);
					i = i + 3;
				}

				// Check for illegal one byte UTF-8 character encoding:
				if (byte1 > 127 && byte1 < 192) {
				decoded = decoded + encoded.substr(i,3);
				illegalencoding = illegalencoding + encoded.substr(i,3) + " ";
				i = i + 3;
				}

				// Check for two byte UTF-8 character encoding:
				if (byte1 > 191 && byte1 < 224) {
					if (byte2 > 127 && byte2 < 192) {
					decoded = decoded + String.fromCharCode(((byte1 & 0x1F) << 6) | (byte2 & 0x3F));
					} else {
					decoded = decoded + encoded.substr(i,6);
					illegalencoding = illegalencoding + encoded.substr(i,6) + " ";
					}
				i = i + 6;
				}

				// Check for three byte UTF-8 character encoding:
				if (byte1 > 223 && byte1 < 240) {
					if (byte2 > 127 && byte2 < 192) {
						if (byte3 > 127 && byte3 < 192) {
							decoded = decoded + String.fromCharCode(((byte1 & 0xF) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F));
						} else {
							decoded = decoded + encoded.substr(i,9);
							illegalencoding = illegalencoding + encoded.substr(i,9) + " ";
						}
					} else {
						decoded = decoded + encoded.substr(i,9);
						illegalencoding = illegalencoding + encoded.substr(i,9) + " ";
					}
					i = i + 9;
				}

					// Check for four byte UTF-8 character encoding:
					if (byte1 > 239) {
						if (byte2 > 127 && byte2 < 192) {
							if (byte3 > 127 && byte3 < 192) {
								if (byte4 > 127 && byte4 < 192) {
									decoded = decoded + String.fromCharCode(((byte1 & 0x7) << 18) | ((byte2 & 0x3F) << 12) | ((byte3 & 0x3F) << 6) | (byte4 & 0x3F));
								} else {
									decoded = decoded + encoded.substr(i,12);
									illegalencoding = illegalencoding + encoded.substr(i,12) + " ";
								}			
							} else {
								decoded = decoded + encoded.substr(i,12);
								illegalencoding = illegalencoding + encoded.substr(i,12) + " ";
							}
						} else {
							decoded = decoded + encoded.substr(i,12);
							illegalencoding = illegalencoding + encoded.substr(i,12) + " ";
						}
						i = i + 12;
					}

					} else {  // the first byte is not legally percent-encoded
					decoded = decoded + encoded.substr(i,3);
					illegalencoding = illegalencoding + encoded.substr(i,3) + " ";
					i = i + 3;
					}

				} else {  // the string is not percent encoded
					// Check if character is an allowed character:
					if (allowed.indexOf(ch) == -1) notallowed = notallowed + ch + " ";
						decoded = decoded + ch;
						i++;
				}
			}  // end of while ...
			var warning = "";
			//if (notallowed != "") warning = warning + "Characters not allowed in a URL:\n" + notallowed + "\n\n";
			//if (illegalencoding != "") warning = warning + "Illegal percent-encoding (for UTF-8):\n" + illegalencoding  + "\n\n";
			//if (warning != "") alert("Warning: Illegal characters/strings in encoded text!\n\n" + warning);
	
	return decoded;

}

function getdec(hexencoded) {
	if (hexencoded.length == 3) {
		if (hexencoded.charAt(0) == "%") {
			if (hexchars.indexOf(hexencoded.charAt(1)) != -1 && hexchars.indexOf(hexencoded.charAt(2)) != -1) {
				return parseInt(hexencoded.substr(1,2),16);
			}
		}		
	}
return 256;
}







