
jQuery.fn.dynamic = function (plus, minus, options){
	if (jQuery(this).length > 1) return;

	var	$source = jQuery(this),
		id = jQuery(this).get(0).id || 'dynamic_rndm',
		selector = id,
		$selector = jQuery('.' + selector),
		$plus = jQuery(plus),
		$minus = jQuery(minus),
		$minusInside = $('div.dynamic-remove a', this),
		fields = 'input, checkbox, select, textarea',
		defaults = {};
		
	if (!$source.hasClass(selector)) $source.addClass(selector);
		
	var $template = $source.clone(true),
		count = $selector.length;
	
	options = $.extend(defaults, options);
	
	if ($minusInside.length) {
		$minusInside.hide();
		$minus.remove();
	}

	if (count == 1) $minus.hide();
	
	$selector.each(function(){
		var $parent = jQuery(this);
		jQuery('div.dynamic-remove a', this).click(function(e){
			hide(e, $parent);
		});
	});

	function normalization(elmnt, nr, update){
		var time = new Date().getTime() + Math.floor(Math.random() * 11);

		elmnt.find(fields).each(function(){
			var	attrname = jQuery(this).attr('name'), 
				attrid = jQuery(this).attr('id'),
				name = attrname.split('[');

			jQuery(this).attr('name',  name[0] + '[' + nr + ']');

		if (attrid && update) {
			jQuery('label[for=' + attrid + ']', elmnt).each(function(){
				jQuery(this).attr('for', attrid + time);
			});
				
			jQuery(this).attr('id', attrid + time);
		}

		if(this.type == 'radio' && update) {
			$(this.parentNode).html('<input id="' + (attrid + time) + '" type="radio" name="' + (name[0] + '[' + nr + ']') + '" value="' + this.value + '" />');		
		}
        });
    };
	
	function hide(event, $self){
		event.preventDefault();
		
		$self.fadeOut('fast', function(){
			$self.remove();
			
			count--;
		
			$('.' + selector).each(function(i){
				normalization(jQuery(this), i, 0);
			});
			
			if (count == 1) $minus.hide();
			$plus.show();
		});
	}
	
	$plus.click(function(event){	
		var	clone,
			$cur = count == 1 ? $source : $('.' + selector + ':last');
		
		event.preventDefault();
		
		if (count == 1) $minus.show();

		clone = $template.clone(true).insertAfter($cur);
		
		$('div.dynamic-remove a', clone).click(function(e){
			hide(e, clone);
		});
		
		normalization(clone, count, 1);
		
		clone
			.removeAttr('id')
			.css({ display:'none' })
			.fadeIn();
		
		count++;
		
		if (options.limit && options.limit <= count) $plus.hide();
	});
	
	$minus.click(function(event){
		event.preventDefault();
		
		var	$cur = $('.' + selector + ':last');
		
		$cur.fadeOut('fast', function(){ $cur.remove(); });
		
		count--;
		
		if (count == 1) $minus.hide();
		$plus.show();
	});
};
