package com.netgrind.core {
	import com.greensock.data.TweenMaxVars;
	import com.greensock.TweenLite;
	import com.greensock.TweenMax;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import com.netgrind.core.Scheduler
	import flash.ui.Mouse;
	
	/**
	 * ...
	 * @author netgrind
	 */
	public class Mouse {
		
		private static var _stage:Stage;
		
		public static var leftPressed:Boolean;
		public static var leftJustPressed:Boolean;
		public static var leftJustReleased:Boolean
		public static var rightPressed:Boolean;
		public static var rightJustPressed:Boolean;
		public static var rightJustReleased:Boolean;
		public static var deltaY:int;
		public static var deltaX:int;
		private static var lastPoint:Point;
		
		private static var _functions:Array = [];
		private static const LEFT_UP:int = 1;
		private static const MOVE_X:int = 2;
		private static const MOVE_Y:int = 3;
		
		public static function init(s:Stage):void {
			_stage = s;
			s.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
			s.addEventListener(MouseEvent.MOUSE_UP, onUp);
			s.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
			s.addEventListener(Event.ENTER_FRAME, onFrame);
			lastPoint = new Point(s.mouseX, s.mouseY);
			s.addEventListener(MouseEvent.RIGHT_MOUSE_DOWN, onRightDown);
			s.addEventListener(MouseEvent.RIGHT_MOUSE_UP, onRightUp);
		}
		static private function onFrame(e:Event):void {
			deltaX = _stage.mouseX -lastPoint.x;
			deltaY = _stage.mouseY -lastPoint.y;
			lastPoint.x = _stage.mouseX;
			lastPoint.y = _stage.mouseY;
		}	
		
		static private function onMove(e:MouseEvent):void {
			callFunctions(MOVE_X);
			callFunctions(MOVE_Y);
		}
		
		static public function bindFunctionToLeftPress(func:Function, ...args):void {
			_functions.push(func, LEFT_UP, args);
		}
		
		static public function bindVarToMouse(obj:Object, vars:Object, bindToX:Boolean=true, min:Number=0, max:Number=1, smoothTime:Number=.5):void {
			_functions.push([function(obj:Object):void {
				for (var o:* in vars) {
					vars[o] = (bindToX?(_stage.mouseX / _stage.width):(_stage.mouseY / _stage.height)) * (max - min) + min;
				}
				TweenMax.to(obj, smoothTime, vars );
			},bindToX?MOVE_X:MOVE_Y,[obj]]);
		}
		static public function unbindVarToMouse(obj:Object):void {
			for (var i:int = 0; i < _functions.length; i++) {
				if(_functions[i][2][0] == obj) {
					_functions.splice(i, 1);
					return;
				}
			}
		}
		
		static public function hide():void {
			(flash.ui.Mouse).hide();
		}
		
		static public function show():void {
			(flash.ui.Mouse).show();
		}
		
		static private function onUp(e:MouseEvent):void {
			leftPressed = false;
			leftJustReleased = true;
			Scheduler.invokeIn(function():void { leftJustReleased = false },2 );
		}
		
		static private function onDown(e:MouseEvent):void {
			leftPressed = true;
			leftJustPressed = true;
			callFunctions(LEFT_UP);
			Scheduler.invokeIn(function():void { leftJustPressed = false } );
		}
		
		static private function onRightUp(e:MouseEvent):void {
			rightPressed = false;
			rightJustReleased = true;
			Scheduler.invokeIn(function():void { rightJustReleased = false } );
		}
		
		static private function onRightDown(e:MouseEvent):void {
			rightPressed = true;
			rightJustReleased = true;
			Scheduler.invokeIn(function():void { rightJustReleased = false } );
		}
		
		static private function callFunctions(type:int):void {
			for (var i:int = 0; i < _functions.length; i++) {
				if (_functions[i][1] == type) {
					_functions[i][0].apply(null, _functions[i][2]);
				}
			}
		}
		
	}
	
}