(function($)
{	
	 $.fn.autosize = function(options) {
		
		// Just some abstracted details,
		// to make plugin users happy:
		var settings = $.extend({
			onResize : function(){},
			animate : true,
			animateDuration : 150,
			animateCallback : function(){},
			extraSpace : 20,
			limit: 1000
		}, options);
		
		// Only textarea's auto-resize:
		return this.each(function(){
			
			if( $(this).data() && $(this).data().autosize && $(this).data().autosize.active == true ){
				return $(this);
			} else {
				// Get rid of scrollbars and disable WebKit resizing:
				var textarea = $(this).css({resize:'none','overflow-y':'hidden'});
				
				// Cache original height, for use later:
				var origHeight = textarea.height();
					
				// Need clone of textarea, hidden off screen:
				var clone = (function(){					
					// Properties which may effect space taken up by chracters:
					var props = ['height','width','lineHeight','textDecoration','letterSpacing', 'font-family', 'font-size', 'font-width', 'line-height', 'padding-top', 'padding-bottom', 'padding-left', 'padding-right', 'border-top-width', 'border-top-color', 'border-top-style', 'border-bottom-width', 'border-bottom-color', 'border-bottom-style', 'border-left-width', 'border-left-color', 'border-left-style', 'border-right-width', 'border-right-color', 'border-right-style', 'background-color'],
						propOb = {};
						
					// Create object of styles to apply:
					$.each(props, function(i, prop){
						propOb[prop] = textarea.css(prop);
					});
					
					// Clone the actual textarea removing unique properties
					// and insert before original textarea:
					return textarea.clone().removeAttr('id').removeAttr('name').removeAttr('class').css({
						position: 'absolute',
						top: 0,
						left: -9999
					}).css(propOb).attr('tabIndex','-1').insertBefore(textarea);
				})();
				
				var lastScrollTop = null;
				var updateSize = function() {
					
					// Prepare the clone:
					clone.height(0).val($(this).val()).scrollTop(10000);
					
					// Find the height of text:
					var scrollTop = Math.max(clone.scrollTop(), origHeight) + settings.extraSpace,
						toChange = $(this).add(clone);
						
					// Don't do anything if scrollTip hasen't changed:
					if (lastScrollTop === scrollTop) { return; }
					lastScrollTop = scrollTop;
					
					// Check for limit:
					if ( scrollTop >= settings.limit ) {
						$(this).css('overflow-y','');
						return;
					}
					// Fire off callback:
					settings.onResize.call(this);
					
					// Either animate or directly apply height:
					settings.animate && textarea.css('display') === 'block' ?
						toChange.stop().animate({height:scrollTop}, settings.animateDuration, settings.animateCallback)
						: toChange.height(scrollTop);
				};
				
				textarea.data('autosize', {'active': true});
				
				// Bind namespaced handlers to appropriate events:
				textarea
					.unbind('.dynSiz')
					.bind('keyup.dynSiz', updateSize)
					.bind('keydown.dynSiz', updateSize)
					.bind('change.dynSiz', updateSize);
			}
			
		});
		
	};
	

	
})(jQuery);
