var UvumiTextarea = Class({
	Implements:Options,
	options:{
		selector:'textarea',
		maxChar:1000,
		minChar : 0,		
		resizeDuration:250,	
		minSize:false,		
		catchTab:false,
		classPrefix:'tb'
	},

	initialize: function(options){
		this.setOptions(options);
		this.tbDummies =[];
		this.tbCounters =[];
		this.tbProgress = [];
		this.tbProgressBar = [];
		window.addEvent('domready',this.domReady.bind(this));
	},
	
	domReady: function(){
		if($(this.options.selector)){
			this.options.selector = $(this.options.selector);
		}
		this.textareas=$$(this.options.selector);
		this.textareas.each(this.buildProgress,this);
		if(this.options.maxChar){
			this.tbProgressEffects = new Fx.Elements(this.tbProgressBar,{
				duration:'short',
				link:'cancel'
			});
		}
		this.tbEffects = new Fx.Elements(this.textareas,{
			duration:this.options.resizeDuration,
			link:'cancel'
		});
		this.textareas.each(function(el,i){
			var value = el.get('value').length;
			
			if(this.options.useWords == true){
				var value = this.textareas[i].get('value').split(" ").length;
			}
			if(value == 1) value = 0;
			this.previousLength = value;
			if(this.options.maxChar){
				if(this.previousLength > this.options.maxChar){
					value = value.substring(0, this.options.maxChar);
					this.previousLength = value;
					el.set('value', value);
				}
				var count = this.options.maxChar - this.previousLength;
				var percentage = (count * this.tbProgress[i].getSize().x / this.options.maxChar).toInt();
				percentage =  this.tbProgress[i].getSize().x - percentage;
				this.tbProgressBar[i].setStyle('width',percentage);
				this.tbCounters[i].set('text',this.writeCounter(count));
			}
			this.tbDummies[i].set('value',value);
			var height = (this.tbDummies[i].getScrollSize().y>this.options.minSize?this.tbDummies[i].getScrollSize().y:this.options.minSize);
			if(this.tbDummies[i].retrieve('height')!=height){
				this.tbDummies[i].store('height',height);
				el.setStyle('height',height);
			}
		},this);
	
	},
	writeCounter:function(count){
		
		if(this.options.useWords){
			var placeE = 'word';
			var placeM = 'words';
		}else{
			var placeE = 'character';
			var placeM = 'characters';
		}
		if((this.options.minChar) != 0)  var ct = 'Minimal '+this.options.minChar+' '+placeM+' - ';
		if(!count){
			ct = ct + 'No '+placeE+' left';
		}else if(count == 1){
			ct = ct + '1 '+placeE+' left';
		}else{
			ct = ct + count + ' '+placeM+' left';
		}	
		return ct;
	},
	//this functions builds all the new HTML elements and assigns events
	buildProgress: function(textbox,i){
		textbox.setStyle('overflow','hidden');
		if(!this.options.minSize){
			this.options.minSize = textbox.getSize().y;
		}
		this.tbDummies[i] = textbox.clone().setStyles({
				'width':textbox.getStyle('width').toInt(),
				'position':'absolute',
				'top':0,
				'height':this.options.minSize,
				'left':-3000
		}).store('height',0).inject($(document.body));
		
		textbox.addEvents({
			'keydown':this.onKeyPress.bindWithEvent(this,[i,this.options.catchTab]), 
			'keyup':this.onKeyPress.bindWithEvent(this,i),
			'focus':this.startObserver.bind(this,i),
			'blur':this.stopObserver.bind(this)
		});
		
		if(this.options.maxChar){
			this.tbProgress[i]=new Element('div',{
				'class':this.options.classPrefix+'Progress',
				'styles':{
					'position':'relative',
					'overflow':'hidden',
					'display':'block',
					'height': '20px',
					'position':'relative',
					'width':textbox.getSize().x-1,
					'margin':'5px 0px 5px 0px'
				}
			}).inject(textbox,'after');
			this.tbProgressBar[i]=new Element('div',{
				'class':this.options.classPrefix+'ProgressBar',
				'styles':{
					'position':'absolute',
					'top':0,
					'left':0,
					'height':'100%',
					'width':'100%'
				}
			}).inject(this.tbProgress[i]);
			this.tbCounters[i] = new Element('div', {
				'class':this.options.classPrefix+'Counter',
				'styles':{
					'position':'absolute',
					'top':0,
					'left':0,
					'height':'100%',
					'width':'100%',
					'text-align':'center'
				}
			}).inject(this.tbProgress[i]);
			this.update = this.updateCounter;
		}else{
			this.update = this.updateNoCounter;
		}
	},
	
	onKeyPress: function(event,i,tab) {
		if(tab && event.key == "tab"){
			event.preventDefault();
			this.insertTab(i);
		}
		if(!event.shift && !event.control && !event.alt && !event.meta){
			this.update(i);
		}
		this.startObserver(i);
	},
	
	startObserver:function(i){
		$clear(this.observer);
		this.observer = this.observe.periodical(500,this,i);
	},
	
	stopObserver:function(){
		$clear(this.observer);
	},
	
	observe:function(i){
		if(this.textareas[i].get('value').length != this.previousLength){
			this.previousLength = this.textareas[i].get('value').length;
			this.update(i);
		}
	},

	updateCounter: function(i) {
		var value = this.textareas[i].get('value').length;
	
		if(this.options.useWords == true){
			var value = this.textareas[i].get('value').split(" ").length;
			
				if(value == 1) value = 0;
		}
		
		if(value > this.options.maxChar){
			if(this.options.useWords == true){
				var words = this.textareas[i].get('value').split(" ");
				var val = '';
				words.each(function(item,index){
					if(index < this.options.maxChar){
						val = val + item +' ';
					}
				}.bind(this));
				val = val.substring(0,val.length-1);
				this.textareas[i].set('value',val);
			}else{
					value =  value.substring(0, this.options.maxChar);
			}
		
			
		}
		
		if(value < this.options.minChar){
			$$('.tbProgressBar').setStyle('background-color','red');
		}else{
			$$('.tbProgressBar').setStyle('background-color','green');
		}
		
		this.previousLength = value;
		var count = this.options.maxChar - this.previousLength;
		var percentage = (count * this.tbProgress[i].getSize().x / this.options.maxChar).toInt();
		percentage =  this.tbProgress[i].getSize().x - percentage;
		
		var effect = {};
		effect[i]={'width':percentage};
		this.tbProgressEffects.start(effect);
		
		this.tbCounters[i].set('text',this.writeCounter(count));
		wordsCount = this.textareas[i].get('value');
		this.updateHeight(i,wordsCount);
	},
	
	updateNoCounter:function(i){
		var value = this.textareas[i].get('value');
		this.previousLength = value.length;
		wordsCount = this.textareas[i].get('value');
		this.updateHeight(i,wordsCount);
	},
	
	updateHeight: function(i,value){
		
		this.tbDummies[i].set('value',value);
		var height = (this.tbDummies[i].getScrollSize().y>this.options.minSize?this.tbDummies[i].getScrollSize().y:this.options.minSize);
		
		if(this.tbDummies[i].retrieve('height')!=height){
			this.tbDummies[i].store('height',height);
			effect = {};
			effect[i]={'height':height};
			this.tbEffects.start(effect);
		}
	},
	
	insertTab: function(i){
		if(Browser.Engine.trident) {
			var range = document.selection.createRange();
			range.text = "\t";
		}else{
			var start = this.textareas[i].selectionStart;
			var end = this.textareas[i].selectionEnd;
			var value = this.textareas[i].get('value');
			this.textareas[i].set('value', value.substring(0, start) + "\t" + value.substring(end, value.length));
			start++;
			this.textareas[i].setSelectionRange(start, start);
		}
	}
});