/*
 * jQuery duplicate plugin
 * @requires jQuery v1.1.3 or later
 */
(function($) {
/**
 * duplicate() clones a set of objects and increments numbers in attributes and
 * text in and of each object and its descendents. This is most useful when you
 * have a form with fields that can be repeated a variable amount of times
 *
 * Returns the original object. It was too difficult to return the set of
 * duplicated elements. To access them after duplication, use next().
 * e.g. $('#item_1').duplicate().next() <- now the clone is selected
 *
 * @example $('#item_1').duplicate({
 *             incStr: ['0', 'Text 1'],
 *             attrs: ['id', 'name', 'for', 'href']
 *          });
 * @before
 * <li id="item_0">
 * 	<label for="text_0">Text 1</label>
 * 	<input type="text" name="text_0" id="text_0" />
 *    <a href="help_0.html">Help</a>
 * </li>
 * @result
 * <li id="item_0">
 * 	<label for="text_0">Text 1</label>
 * 	<input type="text" name="text_0" id="text_0" />
 *    <a href="help_0.html">Help</a>
 * </li>
 * <li id="item_1">
 * 	<label for="text_1">Text 2</label>
 * 	<input type="text" name="text_1" id="text_1" />
 *    <a href="help_1.html">Help</a>
 * </li>
 *
 * @name     duplicate
 * @author   Ian Obermiller (ianobermiller.com)
 * @type     jQuery
 * @param    options Hash with the following options:
 *
 *              incStr:  Array of increment strings to be found incremented.
 *                       ex. ['1', 'Item 12', 'item_0']
 *                       For each increment string, duplicate replaces any integer with its
 *                       successor. e.g. '1' => '2', 'Item 12' => 'Item 13', 'item_0' => 'item_1'
 *                       [Note: If '1' is specified as an increment strings, you do not need to add
 *                          'Item 1' or 'item_1']
 *                       default: ['1']
 * 
 *              attrs:   Array of attributes that will be searched for inStr's.
 *                       e.g. ['id', 'name', 'for', 'href']
 *                       default: ['id', 'name', 'for']
 *
 * @cat      Plugins/Form
 * @return   jQuery
 */
$.fn.duplicate = function(options)
{
	// default options
	options = jQuery.extend({
		incStr: ['1'],
		attrs: ['id', 'name', 'for']
	}, options);
	
	// regex to find a number
	var r = /(\d+)/g;
	
	return $(this).each(function()
	{
		var $clone = $(this).clone();
		
		// loop through the increment strings
		for (i = 0; i < options.incStr.length; i++)
		{
			// generate the string to replace the increment string
			var incNext = options.incStr[i].replace(r, parseInt(r.exec(options.incStr[i])[0]) + 1);
			
			// loop through the attributes, searching for the increment string
			for (a = 0; a < options.attrs.length; a++)
			{
				$clone.filter('[@' + options.attrs[a] + '*=' + options.incStr[i] + ']') // check the parent element
				.add($clone.find('[@' + options.attrs[a] + '*=' + options.incStr[i] + ']')) // check its descendents
				.each(function(){
					// replace the attribute
					$(this).attr(options.attrs[a], $(this).attr(options.attrs[a]).replace(options.incStr[i], incNext));
				});
			}
			
			// replace the html (this should work for attributes in the descendent elements, but it doesnt)
			$clone.each(function(){
				$(this).html($(this).html().replace(options.incStr[i], incNext));
			});
		}
		
		// insert the clone after the original
		$clone.insertAfter($(this));
	});
}
})(jQuery);