/*
Converts unicode characters in selection (or character preceding the cursor)
into various types of ASCII strings

action.setup:
	- type (string): 'named' (default; generates named HTML entities), 'numeric' (generates numeric HTML entities), 'hex' (hexadecimal encoding)
	- wrap (string): if type is 'hex', $HEX in this string will be replaced with the hex value. For example '\\u$HEX' will result in something like \u0022
*/

var utils = loadLibrary('tea-utils');

action.performWithContext = function(context, outError) {
	var ranges = context.selectedRanges;
	// Behavior: convert everything in selection, or else the single character prior to the cursor
	if (ranges.length === 1 && ranges[0].length === 0) {
		// We have a single empty range; make sure it is not at the beginning of the document
		if (ranges[0].location > 0) {
			// Set the new target to the character before the cursor
			ranges[0] = new Range(ranges[0].location - 1, 1);
		} else {
			// Nothing to convert if we are at doc's beginning
			return false;
		}
	}
	
	// Configure our options
	var type = 'named';
	if (action.setup.type) {
		type = action.setup.type.toLowerCase();
	}
	var wrap = (action.setup.wrap ? action.setup.wrap : '$HEX');
	
	// Handle our insertion(s)
	var insertions = new CETextRecipe();
	var count = ranges.length;
	var range, text;
	for (var i = 0; i < count; i++) {
		range = ranges[i];
		text = context.string.substringWithRange(range);
		// Handle based on type of conversion
		if (type === 'named') {
			text = utils.unicodeToNamedEntities(text);
		} else if (type === 'numeric') {
			text = utils.unicodeToNumericEntities(text);
		} else if (type === 'hex') {
			text = text.replace(utils.validCharsRegex, function(c) {
				var hex = c.charCodeAt(0).toString(16);
				// Make sure that we always have a four character hex code
				while(hex.length < 4) {
					hex = '0' + hex;
				}
				return wrap.replace('$HEX', hex);
			});
		}
		insertions.replaceRange(range, text);
	}
	// Set the undo name
	if (action.setup.undoName) {
		insertions.undoActionName = action.setup.undoName;
	}
	return context.applyTextRecipe(insertions);
};