var hexNum = { 0:1, 1:1, 2:1, 3:1, 4:1, 5:1, 6:1, 7:1, 8:1, 9:1, A:1, B:1, C:1, D:1, E:1, F:1, a:1, b:1, c:1, d:1, e:1, f:1 };
var jEscape = { 0:1, b:1, t:1, n:1, v:1, f:1, r:1 };
var decDigit = { 0:1, 1:1, 2:1, 3:1, 4:1, 5:1, 6:1, 7:1, 8:1, 9:1 };

function convertDecNCR2CP(inputstring) {
	var CPstring = '';
	var textString = inputstring + ' ';
	var tempString = '';
	var charStr = '';
	
	// first convert whole string to characters
	for (var i=0; i < textString.length-1; i++) {   
		if (i < textString.length - 3 && textString.charAt(i) == '&' && textString.charAt(i+1) == '#' && textString.charAt(i+2) in decDigit) { // &#1
			tempString = '';
			i += 2;
			while (i < textString.length - 1 && textString.charAt(i) in decDigit) { 
				tempString += textString.charAt(i); 
				i++;
			}
			if (textString.charAt(i) == ';') { 
				charStr += convertCP2Char(parseInt(tempString).toString(16));
			} else { 
				charStr += '&#' + tempString; i--;
			}
		} else { 
			charStr += textString.charAt(i);
		}
	} 
		
	CPstring = getCPfromChar(charStr); 
	CPstring = CPstring.substring(0, CPstring.length-1);

	return convertCP2jEsc(CPstring);
}

function convertCP2Char (textString) {
	var outputString = '';
	textString = textString.replace(/^\s+/, '');
	if (textString.length == 0) { 
		return ""; 
	}
	textString = textString.replace(/\s+/g, ' ');
	var listArray = textString.split(' ');
	for (var i = 0; i < listArray.length; i++) {
		var n = parseInt(listArray[i], 16);
		if (n <= 0xFFFF) {
			outputString += String.fromCharCode(n);
		} else if (n <= 0x10FFFF) {
			n -= 0x10000
			outputString += String.fromCharCode(0xD800 | (n >> 10)) + String.fromCharCode(0xDC00 | (n & 0x3FF));
		} else {
			outputString += 'convertCP2Char error: Code point out of range: ' + dec2hex(n);
		}
	}
	return(outputString);
}

function getCPfromChar ( textString ) {
	var codepoint = "";
	var haut = 0;
	var n = 0; 
	for (var i = 0; i < textString.length; i++) {
		var b = textString.charCodeAt(i); 
		if (b < 0 || b > 0xFFFF) {
			codepoint += 'Error: Initial byte out of range in getCPfromChar: ' + dec2hex(b);
		}
		if (haut != 0) { // we should be dealing with the second part of a supplementary character
			if (0xDC00 <= b && b <= 0xDFFF) {
				codepoint += dec2hex(0x10000 + ((haut - 0xD800) << 10) + (b - 0xDC00)) + ' ';
				haut = 0;
				continue;
			} else {
				codepoint += 'Error: Second byte out of range in getCPfromChar: ' + dec2hex(haut);
				haut = 0;
			}
		}
		if (0xD800 <= b && b <= 0xDBFF) { //b is the first part of a supplementary character
			haut = b;
		} else { // this is not a supplementary character
			codepoint += b.toString(16).toUpperCase()+' ';
		}
	} 
	return codepoint;
}

function convertCP2jEsc (textString) {
	var outputString = '';
	if (textString == '') { return ""; }
	var listArray = textString.split(' ');
	for ( var i = 0; i < listArray.length; i++ ) {
		code = parseInt(listArray[i], 16);

		switch (code) {
			case 0: outputString += '\\0'; break;
			case 8: outputString += '\\b'; break;
			case 9: outputString += '\\t'; break;
			case 10: outputString += '\\n'; break;
			case 13: outputString += '\\r'; break;
			case 11: outputString += '\\v'; break;
			case 12: outputString += '\\f'; break;
			case 34: outputString += '\\\"'; break;
			case 39: outputString += '\\\''; break;
			case 92: outputString += '\\\\'; break;
			default: if (code > 0x1f && code < 0x7F) { outputString += String.fromCharCode(code); }
					else if (code > 0xFFFF) { 
						code -= 0x10000
						outputString += '\\u'+ dec2hex4(0xD800 | (code >> 10)) +'\\u'+ dec2hex4(0xDC00 | (code & 0x3FF));
						}
					else { 
						pad = '';
						if (listArray[i].length == 1) { pad = '000'; }
						else if (listArray[i].length == 2) { pad = '00'; }
						else if (listArray[i].length == 3) { pad = '0'; }
						outputString += '\\u'+pad+listArray[i]; 
						}
			}
		}
	return( outputString );
	}
