// Encoding derived from ISO Standard 8879:1986//ENTITIES Numeric and Special Graphic//EN
function encode() {
	var form = document.forms['encodingform'];
	form.percent.value = '';
	form.percent_u.value = '';
	form.amp_hash.value = '';
	form.amp_hash_x.value = '';

	form.escape.value = escape(form.input.value);
	form.unescape.value = unescape(form.input.value);
	form.basic_amp.value = '';
	form.basic_amp_decoded.value = basic_amp_decode(form.input.value);
	form.fully_decoded.value = basic_amp_decode(form.unescape.value);

	for (var i = 0; i < form.input.value.length; i++) {
		sChar = form.input.value.charAt(i);
		iCharCode = sChar.charCodeAt(0);
		bEncode = !form.partial.checked || form.input_partial.value.indexOf(sChar) > -1;

		form.basic_amp.value      += isAlphaNum(sChar) ? sChar : ampEncodeChar(sChar);
		form.percent.value        += bEncode ? percentageEncodeChar(iCharCode) : sChar;
		form.percent_u.value      += bEncode ? percentage_uEncodeChar(iCharCode) : sChar;
		form.amp_hash.value       += bEncode ? amp_hashEncodeChar(iCharCode) : sChar;
		form.amp_hash_x.value     += bEncode ? amp_hash_xEncodeChar(iCharCode) : sChar;
	}
}

function percentageEncodeChar(iCharCode) { return '%' + toByteHex(iCharCode); }
function percentage_uEncodeChar(iCharCode) { return '%u' + toWordHex(iCharCode); }
function amp_hashEncodeChar(iCharCode) { return '&#' + iCharCode + ';'; }
function amp_hash_xEncodeChar(iCharCode) { return '&#x' + toWordHex(iCharCode) + ';'; }
function ampEncodeChar(sChar) {
	switch (sChar) {
		case '<' : return '&lt;';
		case '>' : return '&gt;';
		case '&' : return '&amp;';
		case '"' : return '&quot;';
	}
	return sChar;
}

alphaChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
numChars = '0123456789';
function isAlphaNum(sChar) { return alphaChars.indexOf(sChar) > -1 || numChars.indexOf(sChar) > -1}
function isNum(sChar) { return numChars.indexOf(sChar) > -1 }

hex_encoding = '0123456789ABCDEF';
function toByteHex(iDec) {
	sHex = toHex(iDec);
	while (sHex.length < 2) sHex = '0' + sHex;
		return sHex;
}
function toWordHex(iDec) {
	sHex = toHex(iDec);
	while (sHex.length < 4) sHex = '0' + sHex;
		return sHex;
}
function toHex(iDec) {
	sHex = '';
	do {
		sHex = hex_encoding.charAt(iDec % 16) + sHex;
		iDec >>= 4; // (shr 4 = div 16)
	} while (iDec>0)
	return sHex;
}

function basic_amp_decode(sString) {
	sResult = '';
	for (i=0; i<sString.length; i++) {
		switch (true) {
			case (sString.substr(i, 4) == '&lt;') :   i+=3; sResult += '<'; break;
			case (sString.substr(i, 4) == '&gt;') :   i+=3; sResult += '>'; break;
			case (sString.substr(i, 5) == '&amp;') :  i+=4; sResult += '&'; break;
			case (sString.substr(i, 6) == '&quot;') : i+=5; sResult += '"'; break;
			case (sString.substr(i, 2) == '&#') :
				sNum = '';
				for (j=i+2; j<i+7 && isNum(sString.substr(j, 1)); j++) {
					sNum+=sString.substr(j, 1);
				}
				if (sString.substr(j, 1) == ';') {
					i=j;
					sResult += String.fromCharCode(sNum);
				} else {
					sResult += sString.substr(i, 1);
				}
				break;
			default : sResult += sString.substr(i, 1);
		}
	}
	return sResult;
}