/**
* ...
* @author Default
* @version 0.1
*/

package classes.matuto.ui.combobox.classic {
	
	import classes.matuto.ui.scroll.MtScrollBar;
	
	import classes.com.greensock.TweenLite;
	
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.utils.Timer;
	
	public class ComboBox extends Sprite{
		
		public var _txt		:Object;
		public var _seta	:MovieClip;
		public var alvo		:MovieClip;
		public var opened	:Boolean = false;
		
		public static var stageRoot	:Stage;
		public var _scroll	:MtScrollBar;
		public var _label	:String;
		
		private var timer	:Timer;
		
		private var itemClass			:Class;
		private var posy				:int = 0;
		public var max_itens			:int = 6;
		public var distance				:Number;
		public var ease					:Function;
		public var time					:Number;
		public var delay				:Number;
		public var distance_x_scroll	:Number;
		public var distance_y_scroll	:Number;
		
		public var value	:Object = null;
		
		public var _itens	:Array;
		
		public var onSelect	:Function;
		
		/**
		 *
		 * @param	objects Os parâmetros obrigatórios, 'item', 'seta', 'scroll', 'item'. A classe 'item' deve extender a classe ItemCombobox
		 */
		public function ComboBox( objects :Object, item :Class, distance_x_scroll :Number = 0, distance_y_scroll :Number = 0, distance :Number = 0, ease :Function = null, time :Number = 1, delay :Number = 40 ) {
			
			if(stageRoot)
			{
				
				this.distance 	= distance;
				this.ease		= ease;
				this.time		= time;
				this.delay		= delay;
				this.distance_x_scroll = distance_x_scroll;
				this.distance_y_scroll = distance_y_scroll;
				this.itemClass	= item;
				
				var arr_str :Array = [ "seta", "scroll" ];
				
				for ( var i :int = 0; i < arr_str.length; i++ )
				{
					
					if ( !objects[ arr_str[i] ] ) throw new Error( "#ERROR COMBOBOX: OBJETO NULO" );
					
				}
				
				
				if ( !objects.item ) _txt 	= new itemClass();
				else _txt = objects.item;
				_seta 	= objects.seta;
				_scroll = objects.scroll;
				
				alvo 	= new MovieClip();
				_itens 	= new Array();
				
				alvo.cacheAsBitmap 	= true;
				_txt.enabled		= false;
				
				timer = new Timer(3000);
				timer.addEventListener(TimerEvent.TIMER, para);
				
				_txt.x			= _seta.x - _txt.width - distance_x_scroll;
				_txt.y			= _seta.y;
				alvo.x			= _txt.x;
				alvo.y 			= _txt.y + _txt.height + distance;
				_scroll.y 		= alvo.y;
				_scroll.alpha 	= 0;
				
				_seta.addEventListener(MouseEvent.CLICK, open);
				this.addEventListener(MouseEvent.ROLL_OUT, out);
				this.addEventListener(MouseEvent.ROLL_OVER, function(event :MouseEvent) :void { timer.stop() } );
				
				stageRoot.addEventListener( "click", function( event :MouseEvent ) :void {
					
					if ( opened && !hitTestPoint( root.mouseX, root.mouseY, true ) ) para();
					
				} );
				
				addChild( _txt as DisplayObject );
				addChild( alvo );
				addChild( _seta );
				
			}else throw new Error("#ERROR COMBOBOX: REFERENCIA DO STAGE VAZIA");
			
		}
		
		
		public static function init( stageRoot :Stage ) :void
		{
			
			ComboBox.stageRoot = stageRoot;
			
		}
		
		
		public override function set width(valor :Number) :void
		{
			
			_txt.width		= valor;
			_seta.x 		= _txt.width;
			_scroll.x		= _seta.x;
			
			var total :int 	= _itens.length;
			
			for (var i:uint = 0; i < total; i++ )
			{
				
				var item :Object = _itens[i];
				
				item.width = _txt.width;
				
			}
			
			
		}
		
		public function habilita():void
		{
			
			_seta.addEventListener(MouseEvent.MOUSE_UP, open);
			this.addEventListener(MouseEvent.ROLL_OUT, out);
			this.addEventListener(MouseEvent.ROLL_OVER, function(event :MouseEvent) :void{ timer.stop() });
			
		}
		
		public function desabilita():void
		{
			
			_seta.removeEventListener(MouseEvent.MOUSE_UP, open);
			this.removeEventListener(MouseEvent.ROLL_OUT, out);
			this.removeEventListener(MouseEvent.ROLL_OVER, function(event :MouseEvent) :void{ timer.stop() });
			
		}
		
		/*public override function set height(valor :Number) :void
		{
			
			trace("asauu");
			
		}*/
		
		
		
		public function set label(valor :String) :void
		{
			
			_label = valor;
			
			_txt.setItem( {label:valor} );
		}
		
		
		public function get label() :String
		{
			
			return _txt._txt.text;
			
		}
		
		/**
		 *
		 * @param	Obj, recebe 'label' e 'value'. ex: { label:"lorem ipsum", value:5 }
		 */
		public function addItem(obj :Object) :void
		{
			
			var item :Object = new itemClass();
			
			item.setItem(obj);
			item.width 	= _txt.width;
			item.y 		= posy;
			//item.addEventListener(CMSEvent.SELECT, select);
			item.addEventListener(MouseEvent.CLICK, click_handle);
			
			posy = item.y + item.height + distance;
			
			_itens.push(item);
			
		}
		
		
		
		
		public function open(event :MouseEvent) :void
		{
			
			TweenLite.killTweensOf(_scroll);
			
			if (!opened && _itens.length>0) {
				
				opened = true;
				
				var total :int = _itens.length;
				
				for (var i:uint = 0; i < total; i++ )
				{
					
					var item :Object = _itens[i];
					
					item.alpha = 0;
					item.enabled = true;
					
					TweenLite.killTweensOf(item);
					
					TweenLite.to(item, time, {alpha:1, ease:ease, delay:i/delay, onComplete:null});
					
					alvo.addChild( item as DisplayObject );
					
				}
				
				
				var tam	:Number = _itens[0].height * max_itens;
				
				if(tam<_itens[0].height*_itens.length){
					if (!getChildByName(_scroll.name)) addChild(_scroll);
					
					
					TweenLite.to(_scroll, time, {alpha:1, ease:ease, delay:.2});
					
					_scroll.height = tam - distance_y_scroll;
					_scroll.startScroll(alvo, alvo.width, tam, 22 );
				}
				
			}else if(_itens.length>0){
				
				close();
				
			}
			
		}
		
		
		
		public function close() :void
		{
			
			opened = false;
			
			var inicial	:int;
			if (getChildByName(_scroll.name)) inicial = _scroll.rect.y;
			else inicial = 0;
			
			var final	:int = inicial + _itens[0].height * max_itens;
			
			var total :int = _itens.length;
			
			var h :int = 0;
			
			//trace(inicial);
			
			for (var i:uint = 0; i < total; i++ )
			{
				
				var item :Object = _itens[i];
				
				item.enabled = false;
				
				if(item.y+item.height>inicial && item.y<final){
				
					TweenLite.to(item, time, { alpha:0, ease:ease, delay:(max_itens - h) / delay, onCompleteParams:[item], onComplete:function(_item :ItemCombobox) :void {
						
						if(alvo.getChildByName(_item.name)) alvo.removeChild(_item);
						
					}});
					
					h++;
					
				}else {
					
					if(alvo.getChildByName(item.name)) alvo.removeChild( item as DisplayObject );
					
				}
					
				
			}
			
			TweenLite.to(_scroll, time, { alpha:0, ease:ease, delay:0, onComplete:function() :void {
				
				try{
					
					removeChild(_scroll);
					
				}catch(e:Error){
					
				}
				
			}});
			
			timer.stop();
			
		}
		
		
		
		public function para(event :TimerEvent = null) :void
		{
			
			//close();
			

			try{
				close();
			}catch (e :Error)
			{
				
			}
			
		}
		
		public function limpaDados():void
		{
			
			for(var u:uint = 0; u < _itens.length ; u++)
			{
				
				if(alvo.getChildByName(_itens[u].name)) alvo.removeChild(_itens[u]);
				
			}
			
			_itens = new Array();
			posy = 0;
			
		}
		
		
		private function out(event :MouseEvent ) :void
		{
			
			//timer.start();
			
		}
		
		
		
		private function click_handle(e :MouseEvent) :void
		{
			
			try {
				
				value = e.currentTarget.value;
				this.label = e.currentTarget.label;
				//this.dispatchEvent( new CMSEvent( CMSEvent.SELECT, value ) );
				onSelect(value);
				para();
				close();
				
			}catch (e :Error )
			{
				//trace(e);
			}
			
		}
		
		
		
		public function getSelectedItem() :Object
		{
			
			return value;
			
		}
		
		
		public function select(index :int) :void
		{
			_itens[index].dispatchEvent(new MouseEvent(MouseEvent.CLICK));
		}
		
		
	}
	
}
