/**
 * Inserts a new list
 * 
 * setup:
 * - type (string): accepts 'ordered' or 'unordered'
 */

action.performWithContext = function(context, outError) {
	// Grab our selected range, and snag the entire line if no selection
	var range = context.selectedRanges[0],
		recipe = new CETextRecipe(),
		numerical = (action.setup.type.toLowerCase() === 'ordered' ? true : false), position = 1;
	if (range.length === 0) {
		range = context.lineStorage.lineRangeForIndex(range.location);
		// If the line is empty then we just need to insert the list element immediately before the cursor
		if (/^\s*$/.test(context.substringWithRange(range))) {
			recipe.insertAtIndex(context.selectedRanges[0].location, (numerical ? position + '. ' : '* '));
			return context.applyTextRecipe(recipe);
		}
	} else {
		range = context.lineStorage.lineRangeForRange(range);
	}
	// Split the selected text into lines, maintaining the linebreaks
	var lines = context.substringWithRange(range).match(/^.*((?:\r\n|\r|\n)|$)/gm),
		// Compile the regex for quicker action on lots of lines
		parser = /^(\s*)(.*?)(\s*([\n\r]+)?)$/,
		// Loop variables
		content = null, targetIndex, targetZone, offset = range.location, line,
		listMarkerSelector = new SXSelector('list.element > punctuation.definition.begin'),
		orderedMarkerSelector = new SXSelector('list.element.ordered > punctuation.definition.begin');
	// Loop over our lines, and add our list markers
	for (var i = 0, count = lines.length; i < count; i++) {
		line = lines[i];
		content = parser.exec(line);
		// Only convert the line to a list item if there's some content
		if (content !== null && content[2] !== '') {
			// Determine where the marker is being inserted
			targetIndex = offset + content[1].length;
			// Check to see if there is a list marker here already
			targetZone = context.syntaxTree.zoneAtCharacterIndex(targetIndex);
			if (listMarkerSelector.matches(targetZone)) {
				// If we are creating an ordered list and the marker is unordered, swap it out
				if (numerical && !orderedMarkerSelector.matches(targetZone)) {
					recipe.replaceRange(targetZone.range, position + '.');
				} else if (!numerical && orderedMarkerSelector.matches(targetZone)) {
					recipe.replaceRange(targetZone.range, '*');
				}
			} else {
				// Insert our marker
				recipe.insertAtIndex(targetIndex, (numerical ? position + '. ' : '* '));
			}
			// Update our position if working with a numerical list
			if (numerical) {
				position++;
			}
		}
		// Update our offset
		offset += line.length;
	}
	// Insert our list elements!
	return context.applyTextRecipe(recipe);
};
