
package com.bit101.components{
	import com.bit101.components.VBox;
	import com.netgrind.core.Scheduler;
	import com.netgrind.core.Utils;
	import com.greensock.TweenLite;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.IBitmapDrawable;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	/**
	 * ...
	 * @author netgrind
	 */
	public class OrderableList extends VBox {
		
		public var list:Array;
		private var _target:Bitmap;
		private var _targetIndex:int;
		
		public function OrderableList(parent:DisplayObjectContainer,x:Number,y:Number,objects:Array) {
			super(parent, x, y);
			list = [];
			for (var i:int = 0; i < objects.length; i++) {
				addChild(objects[i]);
			}
		}
		
		override public function addChild(child:DisplayObject):DisplayObject {
			list.push(child);
			child.addEventListener(MouseEvent.MOUSE_DOWN, grabObject);
			return super.addChild(child);
		}
		
		override public function removeChild(child:DisplayObject):DisplayObject {
			list.splice(list.indexOf(child), 1);
			child.removeEventListener(MouseEvent.MOUSE_DOWN, grabObject);
			if(!Scheduler.invoking(reorder))Scheduler.invokeIn(reorder);
			return super.removeChild(child);
		}
		
		private function grabObject(e:MouseEvent):void {
			_targetIndex = list.indexOf(e.currentTarget);
			if (_targetIndex == -1) return;
			stage.addEventListener(MouseEvent.MOUSE_MOVE, moveObject);
			stage.addEventListener(MouseEvent.MOUSE_UP, releaseObject);
			reorder();
		}
				
		private function moveObject(e:MouseEvent):void {
			if (!_target) {
				_target = new Bitmap(new BitmapData(list[_targetIndex].width, list[_targetIndex].height, true, 0));
				_target.bitmapData.draw(list[_targetIndex] as IBitmapDrawable);
				parent.addChild(_target);
				_target.x = x-5;
				_target.y = mouseY + y;
				alpha = .6;
			}
			TweenLite.to(_target, .2, { y:mouseY+y } );
			var t:*;
			trace(_targetIndex);
			if (_targetIndex!=0&&_target.y <= list[_targetIndex - 1].y) {
				t = list[_targetIndex];
				list[_targetIndex] = list[_targetIndex - 1];
				list[_targetIndex - 1] = t;
				_targetIndex--;
				reorder();
			}else if (_targetIndex != list.length - 1 && _target.y >= list[_targetIndex + 1].y) {
				t = list[_targetIndex];
				list[_targetIndex] = list[_targetIndex + 1];
				list[_targetIndex + 1] = t;	
				_targetIndex++;
				reorder();
			}
		}
		
		private function releaseObject(e:MouseEvent):void {
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveObject);
			stage.removeEventListener(MouseEvent.MOUSE_UP, releaseObject);
			alpha = 1;
			if (!_target) return;
			_target.bitmapData.dispose();
			parent.removeChild(_target);
			_target = null;
		}
		
		public function reorder():void {
			dispatchEvent(new Event(Event.CHANGE));
			for (var i:int = list.length-1; i >=0; i--) {
				setChildIndex(list[i], 0);
			}
			super.draw();
		}
		
		public function get selected():DisplayObject {
			if (_targetIndex < 0 || _targetIndex >= list.length ) {
				return null;
			}
			return list[_targetIndex];
		}
		
		public function cleanup():void {
			releaseObject(null);
			Utils.removeChild(this);
			Scheduler.cancel(reorder);
			list = null;
			
		}
		
	}
	
}