
package classes.matuto.mtween{
	
	import classes.matuto.events.FormEvent;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.text.TextField;
	import flash.utils.clearInterval;
	import flash.utils.getTimer;
	import flash.utils.setInterval;

	public class TextLetter {
		
		private static var _dispatcher		:EventDispatcher = new EventDispatcher();
		
		public static var _currentTimes		:Object = new Object();
		
		private static var alfabeto :Array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
												"M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "X", "Y", "Z",
												"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
		
		//private static var numerais	:Array = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
		
		public static function sort( field :TextField, text :String, time :Number, timeRotate :Number = 10, characters :int = 1, distance :int = 1, delay :Number = 0, text_default :String = null ) :void
		{
			
			var text_f		:String = "";			
			//text = text.substr( text_f.length );			
			var text_field	:Array 	= text.split("");
			var pos			:int = 0;
			var limit 		:int = int( getTimer() + time_l );
			var time_l		:Number = (time*1000) / text_field.length;
			
			if (text == "") {
				text_f = !text_default ? field.text : text_default;
				text_f = text_f.substr(0, text_f.length - 1);
				pos = text_f.length;
				time_l = (time * 1000) / text_f.length;
			}
			
			
			timeRotate = time_l < timeRotate ? time_l : timeRotate;
			
			
			var tempo :Number = setInterval( function() :void { 
				
				if ( _currentTimes[field.name] ) clearInterval( _currentTimes[field.name] );
				
				_currentTimes[field.name] = setInterval( function() :void {
					
					var str :String = "";
					
					if ( text == "" && text_f.length < distance ) distance = distance - (distance-text_f.length);
					
					for (var i :int = 0; i < distance; i++ )
					{
						if ( ( text != "" && (text_f.length + str.length) < text_field.length) ) str += alfabeto[ int(Math.random() * alfabeto.length) ];
						str += alfabeto[ int(Math.random() * alfabeto.length) ];
					}
					
					field.htmlText = text_f + str;
					
					if ( getTimer() > limit ) {
						
						dispatchEvent( new FormEvent( FormEvent.UPDATE, field) );
						
						if (text != "") {
							
							str = "";
							
							for ( i = 0; i < characters; i++ )
							{
								var text_t :String = text_field[pos + i];
								
								if (!text_t) continue;
								
								str += text_field[pos+i];
							}
							
							text_f += str;
							pos+=characters;
						}else {
							text_f = text_f.substr(0, text_f.length - characters);
							pos-=characters;
						}
						
						limit = getTimer() + time_l;
						
						if ( (text != "" && pos >= text_field.length) || (text == "" && pos == 0) ) {
							field.htmlText = text_f;
							clearInterval( _currentTimes[field.name] );
							dispatchEvent( new FormEvent( FormEvent.COMPLETE, field) );
						}
						
					}
					
				}, timeRotate );
				
				
				clearInterval(tempo);
				
			}, delay*1000 );
			
		}
		
		
		public static function stopAll() :void
		{
			
			for (var i in _currentTimes)
			{
				clearInterval( _currentTimes[i] );
				_currentTimes[i] = null;
			}
			
		}
		
		
		
		//##############################################
		// EVENT CONTROLS
		//##############################################
		
		
		public static function addEventListener(type :String, listener :Function, useCapture :Boolean = false, priority :int = 0, useWeakReference :Boolean = false) :void
		{
			_dispatcher.addEventListener(type, listener, useCapture, priority);
		}
		
		public static function dispatchEvent(evt :Event) :Boolean
		{
			return _dispatcher.dispatchEvent(evt);
		}
		
		public static function hasEventListener(type :String) :Boolean
		{
			return _dispatcher.hasEventListener(type);
		}
		
		public static function removeEventListener(type :String, listener :Function, useCapture :Boolean = false) :void
		{
			_dispatcher.removeEventListener(type, listener, useCapture);
		}
		
		public static function willTrigger(type :String) :Boolean 
		{
			return _dispatcher.willTrigger(type);
		}
		
		
	}
	
}
