/**
 * © Conjectrure corporation 2008
 *
 * jQuery textarea autogrowth plugin 
 *
 * created by Artyom Tsinko
 * 
 */

(function($) {
	
	//public part
	
	$.fn.extend(
	{
		autogrow : function(options) 
		{
			return this.each(function() {
				//no sense to use autogrow for non-TA elements
				if ($(this).attr('tagName') !== 'TEXTAREA')
					 	return false;
			 	
			 	if (!options)
			 	 options = {
			 	   minHeight:0,
			 	   maxHeight:Infinity
			 	 }
			  Internal.init($(this),options);
			  
			});
		}
	});
	
	//private part
	
	Internal = {
	
		data:[],
		
		//TA content size detection div
		createSizeDetector : function(obj){
			
		//default lineHeight is wrong in Opera - .css method returns wrong value 
		if ($.browser.opera && !obj[0].style.lineHeight) 
			obj.css('lineHeight','normal'); 
		
		//bad width in IE fix
		var width = obj.css('width');
		if ( $.browser.msie && width === "auto" )
			width = obj[0].clientWidth + parseInt(obj.css('paddingLeft')) + parseInt(obj.css('paddingRight'));
		
		var d = $(document.createElement('pre')).css({
									position:'absolute',
									left:'-10000px',
									top:'-10000px',
									fontSize:obj.css('fontSize'),
									fontFamily:obj.css('fontFamily'),
									
									width: width,
									overflow:'hidden',
									
									lineHeight:obj.css('lineHeight'),
									backgroundColor:"#FCF",
									
									borderLeft:obj.css('borderLeft'),
									borderRight:obj.css('borderRight'),
									paddingLeft:obj.css('paddingLeft'),
									paddingRight:obj.css('paddingRight'),
									
									borderLeftStyle:'solid',
									borderRightStyle:'solid',
									borderColor:'#000'
							}).attr("wrap","soft")[0];
			
			if ($.browser.opera)
				d.style.whiteSpace ="-o-pre-wrap";

			if ($.browser.msie)
				d.style.wordWrap = "break-word";

			$('body').prepend(d);
			return d;
		},
		
		getSizeDetector : function(obj) {
			return Internal.data[obj.attr('_autogrow')].detector;
		},
		
		onRealChange : function(event){
			Internal.applySize($(this),event.info._new);
		},
		
		applySize:function(obj,str)	{
			
		  if (!str)
		    str = '';
		  
			var size = Internal.detectHtmlSize(obj,str);
			var inc = parseInt(obj.css('borderTopWidth')) + 
								parseInt(obj.css('borderBottomWidth')) +
								parseInt(obj.css('paddingTop')) +
								parseInt(obj.css('paddingBottom'));

			var opt = Internal.data[obj.attr('_autogrow')].options;
			
      if (opt._defaultOverflow === undefined) {
        opt._defaultOverflow = obj.css('overflow');
        if ($.browser.msie && opt._defaultOverflow === 'scroll')
          opt._defaultOverflow = 'auto';
      }
			var height, overflow = 'hidden';
			if (size < opt.minHeight) 
			  height = opt.minHeight;
			else {
			  if (size > opt.maxHeight){
			    overflow = opt._defaultOverflow;
			    height = opt.maxHeight;
			  } else 
          height = size + inc;
			}
		  
		  obj.css({
				height: height, overflow:overflow
			});
			
		},
		
		detectHtmlSize : function(obj,str){
			
			//ff & opera
			if ( ($.browser.mozilla || $.browser.opera) ){ 
			  if (str && str.charAt(str.length - 1) == '\n')
          str += '\x20';
			}
			
			if (!$.browser.msie && !str)
        str = '\x20';
			
		 	//ie
			if ($.browser.msie)	{
				str = str.replace(/\r\n/g,'\r'); //ie
				if (str.charAt(str.length - 1) === '\r')
					str += '\x20';
			}
			
			var d = $(Internal.getSizeDetector(obj));
			d.text(str);
			
			return d.height();
			
		},
		
  	init: function(obj, options) {
      if (!obj.attr('_autogrow')){
        var d = Internal.createSizeDetector(obj);
    		var i = Internal.data.push({options:options,detector:d}) - 1;
    		obj.attr('_autogrow',i);
  	   	obj.realchange(Internal.onRealChange);  
      } else 
        Internal.data[obj.attr('_autogrow')].options = options;
	   	
	   	Internal.applySize(obj,obj.attr("value"));
  	}
  	
  	
		
	}
	
})(jQuery);