DAN ZEN EXPO - CODE EXHIBIT - ORBITZOOM


package viewer {

	import flash.display.MovieClip;
	import flash.events.*;
	import flash.ui.Mouse;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.display.Sprite;
	import flash.display.InteractiveObject;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.net.URLRequest;
	import flash.display.StageScaleMode;
	import flash.display.StageAlign;	
	import flash.display.StageQuality;
	import fl.transitions.Tween;
	import fl.transitions.easing.*;
	import fl.transitions.TweenEvent;	
	import flash.utils.Timer;	
	import flash.geom.ColorTransform;
	import flash.geom.Transform;		
	import fl.controls.ColorPicker;
	import fl.events.ColorPickerEvent;	
	import flash.filters.DropShadowFilter;	
	import flash.net.URLRequest;	
	import flash.net.navigateToURL;	
	import flash.ui.Keyboard;
	
	// air packages
	import flash.desktop.Clipboard;
        import flash.desktop.ClipboardFormats;
        import flash.desktop.ClipboardTransferMode;
        import flash.desktop.NativeDragManager;
        import flash.events.NativeDragEvent;
        import flash.filesystem.File;
	import flash.desktop.NativeApplication;	
	import flash.display.StageDisplayState;
	import flash.system.Capabilities;
	import flash.display.NativeWindow;
	import flash.display.NativeWindowDisplayState;
	
	public class ViewerAir extends MovieClip {
		
		// air variables		
		private var myExtensions:Array = ["jpg", "jpeg", "jpe", "gif", "png"];
		private var myFile:String = "";
		private var myFileList:Array;				
		private var myFileNum:Number;		
		private var myTempFile:String;		
		private var myTempFileList:Array;
		private var myTempFileNum:Number;		
		private var instantCheck:Boolean = false;
		private var keyCheck:Boolean = false;
		private var fullCheck:Boolean = false;
		private var preFullX:Number;
		private var preFullY:Number;
		private var preFullW:Number;
		private var preFullH:Number;
		private var preFullType:String;
		private var firstCheck:Boolean = true;
		private var chromeEdge:Number;
		private var chromeTop:Number
		
		// show vars
		private var showCheck:Boolean = false;
		private var showForward:Boolean = true;
		private var showSpeed:Number = 5;
		private var showTimer:Timer;
		private var showTween:Tween;
		
		// fileName vars
		private var fileNameTimer:Timer;
		private var fileNameTween:Tween;				

		// loading vars		
		private var pic:Loader;
		private var myURL:String;
		private var theURL:String = "";
		
		// resize vars		
		private var myScale:Number;
		private var stageW:Number;
		private var stageH:Number;
		private var picW:Number;
		private var picH:Number;
		private var lastX:Number;// of the pic
		private var lastY:Number;
		private var lastW:Number;// of the stage
		private var lastH:Number;
		private var newWS:Number;
		private var newHS:Number;		
		private var toCount:Number = 0;	
		private var maxThreshW:Number = 800;
		private var minThreshW:Number = 600;
		private var maxThreshH:Number = 600;
		private var minThreshH:Number = 400;		

		// zoom pan vars		
		private var zoomFirstX:Number;
		private var zoomFirstY:Number;
		private var zoomFirstScale:Number;
		private var clickX:Number;
		private var clickY:Number;		
		private var zoomMax:Number = 3;
		private var sizeMax:Number = 8000;
		private var doubleQuick:Timer;
		private var singleQuick:Timer;

		private var myBackground:Sprite = new Sprite();
		private var myColorPicker:ColorPicker;
		private var colorCheck:Boolean = false;
		private var backgroundColor:Number = 0xFFFFFF;
		
		private var myCursor:Sprite;
		private var lastCursor:Object;
		private var cursorWait:CursorWait = new CursorWait();
		private var cursorPan:CursorPan = new CursorPan();
		private var cursorPanPress:CursorPanPress = new CursorPanPress();
		private var cursorZoom:CursorZoom = new CursorZoom();
		private var cursorRight:CursorRight = new CursorRight();
		private var cursorLeft:CursorLeft = new CursorLeft();		

		private var prevBut:Sprite;
		private var nextBut:Sprite;
		private var prevNextCheck:Boolean;		
				
		private var myTimer:Timer;
		private var myCursorAlpha:Number = 1;
		
		public function ViewerAir() {

			stageW = stage.stageWidth;
			stageH = stage.stageHeight;		
			stage.quality = StageQuality.BEST;
			
			myBackground.graphics.beginFill(backgroundColor);
			myBackground.graphics.drawRect(-50,-50, stageW+50, stageH+50);
			myBackground.graphics.endFill();
			addChild(myBackground);
			
			dropFiles.x = stageW / 2;
			dropFiles.y = stageH / 2 - 80;
			swapChildren(myBackground, dropFiles);
			
			myColorPicker = new ColorPicker()
			myColorPicker.showTextField = false;
			myColorPicker.colors = [ 
				0x000000,0x222222,0x444444,0x666666,0x888888,0xbbbbbb,0xdddddd,0xeeeeee,0xffffff
			];
			myColorPicker.addEventListener(Event.CLOSE, changeColor);
						
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;			
			
			pic = new Loader();
			pic.contentLoaderInfo.addEventListener(Event.COMPLETE, loadPic);	
			addChild(pic);

			stage.addEventListener(MouseEvent.MOUSE_DOWN, stageDown);
			
			//setCursor(cursorWait);
				
			
			showTimer = new Timer(showSpeed*1000);	
			showTimer.addEventListener(TimerEvent.TIMER, showNext);	
			setChildIndex(showText, numChildren-1);
			showText.alpha = 0;
			showText.x = 5000;
			
			fileNameTimer = new Timer(2*1000,1);
			fileNameTimer.addEventListener(TimerEvent.TIMER, endFileName);
			setChildIndex(fileNameText, numChildren-1);
			fileNameText.alpha = 0;
			fileNameText.x = 5000;		
			
			// air code
			
			stage.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, myDragEnter);
   			stage.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, myDragDrop);	
			// see if they have dropped a file on the application icon 
			NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, myInvoke);			
			
			stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown);			
			stage.addEventListener(Event.RESIZE, changeDim);
			
			chromeEdge = (stage.nativeWindow.width - stageW) / 2;
			chromeTop = stage.nativeWindow.height - stageH - chromeEdge;			

		}
		
		
		
		//---------- PREVIOUS NEXT
		
		function makePrevNext() {
			if (prevBut) {return;}
			prevBut = new Sprite();
			prevBut.graphics.beginFill(0,0);
			prevBut.graphics.drawRect(0,0,20,200);
			addChild(prevBut);
			nextBut = new Sprite();
			nextBut.graphics.beginFill(0,0);
			nextBut.graphics.drawRect(0,0,20,200);
			addChild(nextBut);
			addPrevNextEvents();
			setPrevNext();
		}
		function deletePrevNext() {
			removePrevNextEvents();
			if (prevBut) {
				removeChild(prevBut);
				removeChild(nextBut);
				prevBut = null;
				nextBut = null;
			}			
		}		
		function removePrevNextEvents() {
			if (!prevNextCheck || !prevBut) {return;}
			prevNextCheck = false;
			prevBut.removeEventListener(MouseEvent.MOUSE_OVER, prevNextOver);
			prevBut.removeEventListener(MouseEvent.MOUSE_OUT, prevNextOut);
			prevBut.removeEventListener(MouseEvent.CLICK, prevNextClick);			
			nextBut.removeEventListener(MouseEvent.MOUSE_OVER, prevNextOver);
			nextBut.removeEventListener(MouseEvent.MOUSE_OUT, prevNextOut);
			nextBut.removeEventListener(MouseEvent.CLICK, prevNextClick);			
		}
		function addPrevNextEvents() {	
			if (prevNextCheck || !prevBut) {return;}
			prevNextCheck = true;
			prevBut.addEventListener(MouseEvent.MOUSE_OVER, prevNextOver);
			prevBut.addEventListener(MouseEvent.MOUSE_OUT, prevNextOut);
			prevBut.addEventListener(MouseEvent.CLICK, prevNextClick);			
			nextBut.addEventListener(MouseEvent.MOUSE_OVER, prevNextOver);
			nextBut.addEventListener(MouseEvent.MOUSE_OUT, prevNextOut);
			nextBut.addEventListener(MouseEvent.CLICK, prevNextClick);			
		}		
		function setPrevNext() {
			var fromTop:Number = 30;
			prevBut.height = stageH-fromTop;
			prevBut.x = 0;
			prevBut.y = fromTop;
			nextBut.height = stageH-fromTop;
			nextBut.x = stageW-20;			
			nextBut.y = fromTop;
		}				
		private function prevNextOver(e:MouseEvent) {			
			if (e.target == nextBut) {
				changeCursor(cursorRight);				
			} else if (e.target == prevBut) {
				changeCursor(cursorLeft);
			}
			trace ("mi");
		}
		private function prevNextOut(e:MouseEvent) {
			if (pic.hitTestPoint(mouseX, mouseY)) {				
				changeCursor(cursorPan);				
			}	else {
				removeCursor();
			}
		}
		private function prevNextClick(e:MouseEvent) {
			if (showCheck) {
				showTimer.stop();
				showTimer.start();
			}
			if (e.target == nextBut) {
				nextFile();
			} else if (e.target == prevBut) {
				prevFile();				
			}
		}	
		
		private function prevFile() {			
			prevNextClear();
			var newFile = myFileNum - 1;
			if (newFile < 0) {
				newFile = myFileList.length-1;
			}
			myFile = myFileList[newFile].url;
			myFileNum = newFile;
			instantCheck = true;
			stopFileName();
			pic.load(new URLRequest(myFile));
			
		}
		private function nextFile() {
			prevNextClear();
			var newFile = myFileNum + 1;
			if (newFile > myFileList.length-1) {
				newFile = 0;
			}
			myFile = myFileList[newFile].url;
			myFileNum = newFile;
			instantCheck = true;
			stopFileName();
			pic.load(new URLRequest(myFile));			
		}				
		
		private function prevNextClear() {			
			stage.removeEventListener(MouseEvent.MOUSE_UP, picUp);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveMouse);
			//addLogoEvents();	
			if (myFileList.length > 1) {
				addPrevNextEvents();			
			}
			panCheck = true;
			singleCheck = false;		
			singleQuick.stop();
		}		
		
		
		//----------  KEYPRESSES
		
		private function myKeyDown(e:KeyboardEvent) {
			trace (e.keyCode);
			//return;
			
			if (e.keyCode == 37 && keyCheck && !firstCheck) {
				prevFile();
			} else if (e.keyCode == 72) { // h
				if (myCursor.alpha == 0) {
					myCursor.alpha = myCursorAlpha = 1;
				} else {
					myCursor.alpha = myCursorAlpha = 0;
				}
			} else if (e.keyCode == 39 && keyCheck && !firstCheck) {
				nextFile();
			} else if ((e.keyCode == 70 && e.ctrlKey) || e.keyCode == Keyboard.F11) {
				fullScreen();
			} else if (fullCheck && e.keyCode == Keyboard.ESCAPE) {
				fullScreen();
			} else if ((e.keyCode == 83 || e.keyCode == Keyboard.SPACE) && !firstCheck) {
				toggleShow();
			} else if (e.keyCode >= 48 && e.keyCode <= 57) {
				var s:Number = e.keyCode;
				if (s == 48) {s = 58;} // 0 is ten
				showSpeed = 10-(58 - s);
				if (e.ctrlKey) {showSpeed += 10;}
				if (e.shiftKey) {showSpeed += 20;}
				if (e.altKey) {showSpeed += 30;}
				showTimer.delay = showSpeed * 1000;				
				trace (showSpeed);
				showShowText();
			} else if (e.keyCode == 189 && !firstCheck) {
				showForward = false;
				showShowText();
			} else if (e.keyCode == 187 && !firstCheck) {
				showForward = true;
				showShowText();
			} else if (e.keyCode == 191 || e.keyCode == 78 && !firstCheck) { // ? or N 
				showFileName();
			} else if (e.keyCode == 65 && !firstCheck) { // A 
				prevNextClear();
				fit(false);
				changeCursor(cursorPan);
			} else if (e.keyCode == 70 && !firstCheck) { // F 
				prevNextClear();
				fit();
				changeCursor(cursorPan);
			} else if (e.keyCode == 82 && !firstCheck) { // R 
				if (e.ctrlKey) {
					rotate(-90);
				} else {
					rotate(90);
				}
			} else if (e.keyCode == 67) { // C
				var cArray:Array = [cursorWait, cursorPan, cursorPanPress, cursorZoom];
				var i:uint;
				if (Math.round(cursorWait.scaleX) == 1) {					
					for (i=0; i<cArray.length; i++) {
						cArray[i].scaleX = cArray[i].scaleY = 3;
					}
				} else {
					for (i=0; i<cArray.length; i++) {
						cArray[i].scaleX = cArray[i].scaleY = 1;
					}
				}
			}
		}				
				
		private function rotate(a) {			
			pic.rotation += a;
			if (Math.round(pic.rotation) == 0) {
				pic.content.x = 0;
				pic.content.y = 0;
			} else if (Math.round(pic.rotation) == 90) {
				pic.content.x = 0;
				pic.content.y = -pic.content.height;
			} else if (Math.round(pic.rotation) == 180 || Math.round(pic.rotation) == -180) {
				pic.content.x = -pic.content.width;
				pic.content.y = -pic.content.height;
			} else if (Math.round(pic.rotation) == -90) {
				pic.content.x = -pic.content.width;
				pic.content.y = 0;
			} 
			instantCheck = true;
			prevNextClear();
			fit();
			changeCursor(cursorPan);
			trace ("rotate" + pic.rotation);
			
		}
		
		//---------- SHOW		
		
		private function positionShow() {			
			showText.x = stageW - showText.width - 12;			
		}		
		
		private function showShowText(type:Boolean = true) {
			positionShow();
			if (type) {
				if (showForward) {
					showText.showText.text = String(showSpeed) + " >";
				} else {
					showText.showText.text = "< " + String(showSpeed);
				}		
			} else {				
				showText.showText.text = "0";						
			}
			if (showTween) {
				showTween.removeEventListener(TweenEvent.MOTION_FINISH, showTweenDone);
			}
			showTween = new Tween(showText, "alpha", Regular.easeInOut, showText.alpha, .4, 1, true);
			showTween.addEventListener(TweenEvent.MOTION_FINISH, showTweenDone);
		}
		
		private function showTweenDone(e:TweenEvent) {					
			showTween = new Tween(showText, "alpha", Regular.easeInOut, showText.alpha, 0, 1, true);
			showTween.addEventListener(TweenEvent.MOTION_FINISH, showTweenDone2);
		}
		
		private function showTweenDone2(e:TweenEvent) {					
			showText.x = 5000;
		}					
		
		private function toggleShow() {			
			if (showCheck) {
				showTimer.stop();				
			} else {
				showTimer.start();					
			}			
			showCheck = !showCheck;	
			showShowText(showCheck);			
		}
		
		private function showNext(e:TimerEvent) {
			if (showForward) {
				nextFile();
			} else {
				prevFile();
			}
		}			
		
		
		//---------- FILE NAME
		
		private function positionFileName() {			
			fileNameText.x = (stageW - fileNameText.width) / 2;			
		}		
		
		private function stopFileName() {			
			if (fileNameTween) {
				fileNameTween.removeEventListener(TweenEvent.MOTION_FINISH, fileNameTweenDone);
				fileNameTween.stop();
			}						
			fileNameTimer.stop();			
			fileNameText.x = 5000;
			fileNameText.alpha = 0;
		}
		
		private function showFileName(type:Boolean = true) {					
			//http://farm3.static.flickr.com/2170/2200337264_7ef0a990fa_b.jpg
			var fileNameArray:Array = myFile.split("\/");
			fileNameText.fileNameText.text = fileNameArray[fileNameArray.length-1];
			if (fileNameTween) {
				fileNameTween.removeEventListener(TweenEvent.MOTION_FINISH, fileNameTweenDone);
			}			
			positionFileName();
			fileNameTimer.stop();
			fileNameTween = new Tween(fileNameText, "alpha", Regular.easeInOut, fileNameText.alpha, .8, 1, true);
			fileNameTween.addEventListener(TweenEvent.MOTION_FINISH, fileNameTweenDone);
		}		
		
		private function fileNameTweenDone(e:TweenEvent) {			
			fileNameTimer.start();			
		}
		
		private function fileNameTweenDone2(e:TweenEvent) {			
			fileNameText.x = 5000;
		}		
		
		private function endFileName(e:TimerEvent) {		
			fileNameTween = new Tween(fileNameText, "alpha", Regular.easeInOut, fileNameText.alpha, 0, 1, true);
			fileNameTween.addEventListener(TweenEvent.MOTION_FINISH, fileNameTweenDone2);
		}						
		
		
		private function fullScreen() {
			
			//trace (Capabilities.screenResolutionX);
			
			if (fullCheck) {
				fullCheck = false;
				if (preFullType == NativeWindowDisplayState.MAXIMIZED) {
					stage.nativeWindow.x = preFullX+10;
					stage.nativeWindow.y = preFullY+10;
					stage.nativeWindow.width = preFullW-20;
					stage.nativeWindow.height = preFullH-20;					
				} else {
					stage.nativeWindow.x = preFullX;
					stage.nativeWindow.y = preFullY;
					stage.nativeWindow.width = preFullW;
					stage.nativeWindow.height = preFullH;
				}
			} else {
				toCount = 100;
				preFullX = stage.nativeWindow.x;
				preFullY = stage.nativeWindow.y;
				preFullW = stage.nativeWindow.width;
				preFullH = stage.nativeWindow.height;
				preFullType = stage.nativeWindow.displayState;
				fullCheck = true;
				
				if (stage.nativeWindow.displayState == NativeWindowDisplayState.MAXIMIZED) {
					stage.nativeWindow.x = -chromeEdge-3;
					stage.nativeWindow.width = Capabilities.screenResolutionX + chromeEdge*2;
				} else {
					stage.nativeWindow.x = -chromeEdge;
					stage.nativeWindow.width = Capabilities.screenResolutionX + chromeEdge*2;
				}
				stage.nativeWindow.y = -chromeTop;				
				stage.nativeWindow.height = Capabilities.screenResolutionY + chromeTop + chromeEdge;
				
			}

			return;			
			if (stage.displayState != StageDisplayState.FULL_SCREEN) {				
				stage.displayState = StageDisplayState.FULL_SCREEN;
			} else {
				stage.displayState = StageDisplayState.NORMAL;
			}
		}
		
		//----------  FILES WITH AIR
		
		
		private function myInvoke(e:InvokeEvent):void {
			if (e.arguments.length > 0) {
				var myArray:Array = [];
				// turn the array of strings into File objects so can process same way as drop
				for(var i:uint=0; i<e.arguments.length; i++) {
					myArray.push(new File(e.arguments[i]));
				}
				if (getFiles(myArray)) {
					instantCheck = true;
					loadMyFile();
					myTimer = new Timer(200,1);
					myTimer.start();
					myTimer.addEventListener(TimerEvent.TIMER, handleCursor);							
				}
			}					

		}
					
		private function myDragEnter(e:NativeDragEvent) {			
			// casting as Array(myData...) does not work because Array() is a global function
			var myArray:Array = e.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
			if (getFiles(myArray)) {
				// need to call this to accept the drop					
				NativeDragManager.acceptDragDrop(InteractiveObject(e.target));
			}
		}
		
		private function getFiles(myArray) {
			myTempFileList = [];		
			var i:uint;
			for(i=0; i<myArray.length; i++) {
				var file:File = myArray[i];
				if (file.isDirectory) {continue;}
				if (myExtensions.indexOf(file.extension.toLowerCase()) != -1) {
					myTempFileList.push(file);					
				}				
				
			}			
			if (myTempFileList.length > 0) {
				myTempFile = myTempFileList[0].url
				myTempFileNum = 0;				
				if (myTempFileList.length == 1) {
					// get other files in directory
					myTempFileList = getDirectoryFiles(myTempFileList[0]);
				}			
				return true;
			} else {				
				return false;
			}
			
		}
		
		private function getDirectoryFiles(f:File) {
			var directoryList:Array = f.parent.getDirectoryListing();		
			var addFiles:Array = [];
			var count = 0;
			for (var i:uint=0; i<directoryList.length; i++) {
				var file:File = directoryList[i];				
				if (file.isDirectory) {continue;}
				try {
					if (myExtensions.indexOf(file.extension.toLowerCase()) != -1) {
						if (f.url == file.url) {
							myTempFileNum = count;
						}
						addFiles.push(file);	
						count++;
					}
				} catch (e) {
				}
			}
			return addFiles;
		}
		
		private function myDragDrop(e:NativeDragEvent) {
			instantCheck = true;
			loadMyFile();	
		}		
		
		private function loadMyFile() {
			myFileList = myTempFileList;
			myFile = myTempFile;					
			myFileNum = myTempFileNum;
			pic.load(new URLRequest(myFile));
			if (myFileList.length > 1) {				
				if (keyCheck == false) {
					keyCheck = true;
				}
				makePrevNext();		
			} else {
				deletePrevNext();		
			}
		}				
		
		
		
		//---------- INIT 		
		
		private function init() {
						
			stage.addEventListener(Event.ENTER_FRAME, checkCursor);			
			pic.contentLoaderInfo.addEventListener(Event.COMPLETE, loadPic);			
			stageW = stage.stageWidth;
			stageH = stage.stageHeight;
			stage.doubleClickEnabled = true;
			pic.doubleClickEnabled = true;
			stage.addEventListener(MouseEvent.DOUBLE_CLICK, double);			
			pic.addEventListener(MouseEvent.MOUSE_DOWN, picDown);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, stageDown);
			
			singleQuick = new Timer(250,1);
			singleQuick.addEventListener(TimerEvent.TIMER, singleClear);
			
			doubleQuick = new Timer(250,1);
			doubleQuick.addEventListener(TimerEvent.TIMER, doubleClear);			
			
		}		
				
		private function loadPic(e:Event) {
			if (firstCheck) {				
				var myTransform:ColorTransform = new ColorTransform();
				myTransform.color = 0x000000;
				myBackground.transform.colorTransform = myTransform;		
				dropFiles.visible = false;
				//logoFadeOut();				
				firstCheck = false;
				stage.addEventListener(Event.ENTER_FRAME, checkCursor);							
				stageW = stage.stageWidth;
				stageH = stage.stageHeight;
				stage.doubleClickEnabled = true;
				pic.doubleClickEnabled = true;
				stage.addEventListener(MouseEvent.DOUBLE_CLICK, double);
				pic.addEventListener(MouseEvent.MOUSE_DOWN, picDown);				
				singleQuick = new Timer(250,1);
				singleQuick.addEventListener(TimerEvent.TIMER, singleClear);				
				doubleQuick = new Timer(250,1);
				doubleQuick.addEventListener(TimerEvent.TIMER, doubleClear);														

				
			} else {
				//changeCursor(cursorWait);						
			}
			
			pic.rotation = 0;
			
			fit();
			recordLast();
			
			if (pic.hitTestPoint(mouseX, mouseY)) {
				if (myFileList.length > 1 && (prevBut.hitTestPoint(mouseX, mouseY) || nextBut.hitTestPoint(mouseX, mouseY))) {
					return;
				}					
				changeCursor(cursorPan);				
			}	
		}		
		

		
		//---------- CURSOR

		private function handleCursor(e:Event) {			
			Mouse.hide();			
		}				
		
		private function checkCursor(e:Event) {
			if (colorCheck) {return;}
								
			if (pic.hitTestPoint(mouseX, mouseY)) {
				if (!myCursor) {
					setCursor(cursorPan);
				}
			} else if (prevNextCheck && prevBut.hitTestPoint(mouseX, mouseY)) {
			} else if (prevNextCheck && nextBut.hitTestPoint(mouseX, mouseY)) {
			} else {
				if (myCursor && panCheck) {
					removeCursor();
				}
			}
		
												
		}
		
		private function setCursor(cursorType) {
			myCursor = new Sprite();		
			myCursor.alpha = myCursorAlpha;
			myCursor.addChild(cursorType);
			addChild(myCursor);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, moveCursor);
			stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);				
			myCursor.x = mouseX;
			myCursor.y = mouseY;
			myCursor.visible = true;			
			Mouse.hide();
			lastCursor = cursorType;
			setChildIndex(myCursor, numChildren-1);
		}
		
		private function changeCursor(cursorType) {
			trace ("change cursor " + cursorType);

			if (myCursor && myCursor.numChildren > 0) {
				myCursor.removeChild(myCursor.getChildAt(0));
				myCursor.addChild(cursorType);
				lastCursor = cursorType;
				Mouse.hide();
			} else {
				setCursor(cursorType);
			}						
		}
		
		private function removeCursor() {
			trace ("remove cursor");
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveCursor);
			stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeave);
			if (myCursor) {
				removeChild(myCursor);
			}
			myCursor = null;
			Mouse.show();
		}
		
		private function moveCursor(e:MouseEvent) {
			myCursor.x = mouseX;
			myCursor.y = mouseY;
			myCursor.visible = true;
		} 				

		private function mouseLeave(e:Event) {			
			myCursor.visible = false;
		}


		
		//---------- COLOR
		
		private function showColor() {
			if (myCursor) {removeCursor();}	
			myColorPicker.move(mouseX, mouseY);
			addChild(myColorPicker);
			myColorPicker.open();
			colorCheck = true;
			stage.removeEventListener(MouseEvent.MOUSE_DOWN, stageDown);			
		}		
		
		private function changeColor(e:Event) {
			backgroundColor = e.target.selectedColor
			var myTransform:ColorTransform = new ColorTransform();
			myTransform.color = backgroundColor;
			myBackground.transform.colorTransform = myTransform;		
			stage.addEventListener(MouseEvent.MOUSE_DOWN, stageDown);
			myColorPicker.close();
			colorCheck = false;
			myColorPicker.move(-1000, -1000);
			if (!firstCheck && lastCursor) {
				setCursor(lastCursor);	
			}
				   
		}
		
		// ------ ZOOM AND PAN		
		
		private var panCheck:Boolean = true;
		private var singleCheck:Boolean = true;
		private var doubleCheck:Boolean = false;
		
		private function stageDown(e:MouseEvent) {
			if (doubleCheck) {return;}
			if (panCheck) {
				if (e.target == myBackground) {showColor();}
			} else {				
				stage.removeEventListener(MouseEvent.MOUSE_UP, picUp);
				stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveMouse);
				
				stage.addEventListener(MouseEvent.MOUSE_UP, prevNextUpEvent);
				panCheck = true;			
			}			
		}
		
		private function prevNextUpEvent(e:MouseEvent) {
			stage.removeEventListener(MouseEvent.MOUSE_UP, prevNextUpEvent);
			if (myFileList.length > 1) {
				var myPrevNextTimer:Timer = new Timer(200,1);
				myPrevNextTimer.start()
				myPrevNextTimer.addEventListener(TimerEvent.TIMER, myPrevNextTimerEvent);
			}					
		}
		
		private function myPrevNextTimerEvent(e:TimerEvent) {
			addPrevNextEvents();
		}		
		
		private function picDown(e:MouseEvent) {		
			if (myFileList.length > 1) {
					addPrevNextEvents();
			}		
			if (doubleCheck) {return;}
			if (panCheck) {					
				stage.addEventListener(MouseEvent.MOUSE_UP, picUp);
				stage.addEventListener(MouseEvent.MOUSE_MOVE, moveMouse);
				if (myFileList.length > 1) {
					removePrevNextEvents();
				}				

				clickX = mouseX;
				clickY = mouseY;							
				zoomFirstX = pic.x;
				zoomFirstY = pic.y;
				zoomFirstScale = pic.scaleX;				
				
				singleCheck = true;
				panCheck = true;
				singleQuick.start();
				changeCursor(cursorPanPress);
			} else {
				stage.removeEventListener(MouseEvent.MOUSE_UP, picUp);
				stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveMouse);
				panCheck = true;				
				changeCursor(cursorPan);
			}
			
		}		
		
		private function picUp(e:MouseEvent) {
			if (singleCheck) {
				panCheck = false;
				changeCursor(cursorZoom);
				if (myFileList.length > 1) {
					removePrevNextEvents();
				}
			} else {
				if (myFileList.length > 1) {
					addPrevNextEvents();
				}
			}							
			if (panCheck) {
				stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveMouse);
				changeCursor(cursorPan);
			}
			stage.removeEventListener(MouseEvent.MOUSE_UP, picUp);
		}				
				
		private function moveMouse(e:MouseEvent) {
			if (panCheck) {
				panMove();
			} else {
				zoomMove();			
			}				
		}
		
		function panMove() {	
			pic.x = zoomFirstX + (mouseX - clickX);
			pic.y = zoomFirstY + (mouseY - clickY);
			limits();
			toCount = 0;
		}		
		
		function zoomMove() {			
			toCount = 0;
			var centerX:Number = stageW / 2;
			var centerY:Number = stageH / 2;
			var zoomDistance:Number = stageW / 2;
			var dX:Number = mouseX - clickX;
			var dY:Number = mouseY - clickY;
			var d:Number = Math.sqrt(Math.pow(dX,2) + Math.pow(dY,2));	
			var zp:Number = d / zoomDistance;
			var zp2:Number = d / zoomDistance;	
			if (zp>=1) {zp2 = 1;}
			var scale:Number = zoomFirstScale + zp * zoomMax;		
			var lastScale = pic.scaleX;
			pic.scaleX = pic.scaleY = scale;
			if (pic.width > sizeMax || pic.height > sizeMax) {
				pic.scaleX = pic.scaleY = lastScale;
				return;
			}
			pic.x = clickX - scale / zoomFirstScale * (clickX-zoomFirstX) + zp2 * (centerX-clickX);
			pic.y = clickY - scale / zoomFirstScale * (clickY-zoomFirstY) + zp2 * (centerY-clickY);
		}


		function singleClear(e:TimerEvent) {
			singleCheck = false;
		}		
				
		function doubleClear(e:TimerEvent) {
			doubleCheck = false;
		}						
		
		private function double(e:MouseEvent) {
			doubleCheck = true;
			doubleQuick.start();
			stage.removeEventListener(MouseEvent.MOUSE_UP, picUp);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveMouse);
			if (!panCheck) {
				addPrevNextEvents();
			}
			panCheck = true;
			singleCheck = false;		
			singleQuick.stop();
			fit();
			recordLast();
			changeCursor(cursorPan);
		}		

		
		function limits() {
			var pw = pic.width;
			var ph = pic.height;
			var px = pic.x;
			var py = pic.y;
			var sw = stageW;
			var sh = stageH;
			
			// if width is < stageW
			if (pw < sw) {
				// then don't let right side off right if it was < right side
				if (zoomFirstX + pw < sw) {
					if (px + pw > sw) {pic.x = sw - pw;}
				} else {
					// else if it was > right side then don't let it move right
					if (px > zoomFirstX) {pic.x = zoomFirstX;}
				}				
				// or left side off left if it was > 0
				if (zoomFirstX < 0) {
					if (px < zoomFirstX) {pic.x = zoomFirstX;}
				} else {
					// if it was < 0 then do not let it move left
					if (px < 0) {pic.x = 0;}
				}					
			} else {
			// if width is > stageW then				
				// don't let left side > 0 if it was less than 0 
				if (zoomFirstX > 0) {
					if (px > zoomFirstX) {pic.x = zoomFirstX;}
				} else {
					// else don't let it move right
					if (px > 0) {pic.x = 0;}
				}					

				// don't let right side < stageW if it was > stageW
				if (zoomFirstX + pw < sw) {
					if (px < zoomFirstX) {pic.x = zoomFirstX;}
				} else {				
					// else don't let it move left
					if (px + pw < sw) {pic.x = sw - pw;}
				}
			}
			
			if (ph < sh) {
				if (zoomFirstY + ph < sh) {
					if (py + ph > sh) {pic.y = sh - ph;}
				} else {
					if (py > zoomFirstY) {pic.y = zoomFirstY;}
				}				
				if (zoomFirstY < 0) {
					if (py < zoomFirstY) {pic.y = zoomFirstY;}
				} else {
					if (py < 0) {pic.y = 0;}
				}					
			} else {
				if (zoomFirstY > 0) {
					if (py > zoomFirstY) {pic.y = zoomFirstY;}
				} else {
					if (py > 0) {pic.y = 0;}
				}
				if (zoomFirstY + ph < sh) {
					if (py < zoomFirstY) {pic.y = zoomFirstY;}
				} else {	
					if (py + ph < sh) {pic.y = sh - ph;}
				}
			}		
			
		}				
		
		
		// ------ STAGE RESIZE
		
		private function changeDim(e:Event) {
			
			stageW = stage.stageWidth;
			stageH = stage.stageHeight;

			if (firstCheck) {			
				if (showText.alpha > 0) {positionShow();}
				if (fileNameText.alpha > 0) {positionFileName();}
				return;
			}		
			
			var typeW:String; var typeH:String;
			if (stageW > lastW) {typeW = "bigger";} else {typeW = "smaller";}
			if (stageH > lastH) {typeH = "bigger";} else {typeH = "smaller";}
			
			var axisW:String; var axisH:String;
			if (pic.width <= stageW) {axisW = "inside";} else {axisW = "outside";}
			if (pic.height <= stageH) {axisH = "inside";} else {axisH = "outside";}				

			newWS = stageW / lastW;
			newHS = stageH / lastH;											
			
			var picOldW = pic.width;
			var picOldH = pic.height;			
									
			if ((axisW == "outside" && typeW == "smaller") || (axisH == "outside" && typeH == "smaller")) {								
				pic.scaleX *= Math.min(newWS, newHS); 
				pic.scaleY *= Math.min(newWS, newHS);				
			} else if ((axisW == "inside" && typeW == "bigger") || (axisH == "inside" && typeH == "bigger")) {		
				
				if (pic.width / stageW > pic.height / stageH) {
					pic.scaleX *= newWS;
					pic.scaleY *= newWS;										
				} else {
					pic.scaleX *= newHS;
					pic.scaleY *= newHS;							
				}
			} 						
			
			lastX = pic.x = pic.x - (pic.width - picOldW) / 2;
			lastY = pic.y = pic.y - (pic.height - picOldH) / 2;			
			
			var divertSpeed:Number = 4;
			toCount++;
			var moveToCenter:Boolean = (toCount > 8 || stageW/lastW > 1.2 || stageH/lastH > 1.2 || stageW/lastW < .8 || stageH/lastH < .8);
			if (moveToCenter) {
				toCount = 100;
				pic.x = (stageW - pic.width) / 2;
			} else {			
				pic.x += ((stageW - pic.width) / 2 - pic.x) / divertSpeed;
			}		
			if (moveToCenter) {
				toCount = 100;
				pic.y = (stageH - pic.height) / 2;
			} else {
				pic.y += ((stageH - pic.height) / 2 - pic.y) / divertSpeed;
			}								

			myBackground.graphics.beginFill(backgroundColor);
			myBackground.graphics.drawRect(-50,-50, stageW+50, stageH+50);
			myBackground.graphics.endFill();
			
			
			if (showText.alpha > 0) {positionShow();}
			if (fileNameText.alpha > 0) {positionFileName();}
			recordLast();
			
			if (myFileList.length > 1) {
				setPrevNext();
			}	

		}
		
		private function errorHandler(e:IOErrorEvent) {
			myError("Sorry, could not load the URL");
		}
		
		private function myError(e:String) {
			var myText:TextField = new TextField();
			myText.x = myText.y = 100;
			myText.autoSize = "left";
			var myFormat:TextFormat = new TextFormat();
			myFormat.color = 0xCC3300;
			myFormat.size = 20;
			myText.text = e;
			myText.setTextFormat(myFormat);
			addChild(myText);
		}

		
		private var myEnabled:Boolean = true;
		private var myFitTweenSX:Tween;
		private var myFitTweenSY:Tween;
		private var myFitTweenX:Tween;
		private var myFitTweenY:Tween;
		
		private function fit(fitWindow:Boolean=true) {
			
			myEnabled = false;			
			
			var fitScale:Number;
			var fitX:Number;
			var fitY:Number;
			if (fitWindow) {
				if ((pic.width/pic.scaleX) / (pic.height/pic.scaleY) > stageW / stageH) {
					fitScale = myScale = stageW / (pic.width/pic.scaleX);				
					fitX = 0;
					fitY = (stageH - (pic.height/pic.scaleY*fitScale)) / 2;
				} else {
					fitScale = myScale = stageH / (pic.height/pic.scaleY);			
					fitX  = (stageW - (pic.width/pic.scaleX*fitScale)) / 2;
					fitY  = 0;
				}
			} else {
				fitScale = 1;
				fitY = (stageH - (pic.height/pic.scaleY*fitScale)) / 2;
				fitX  = (stageW - (pic.width/pic.scaleX*fitScale)) / 2;
			}
			if (instantCheck) {
				instantCheck = false;
				pic.scaleX = fitScale;
				pic.scaleY = fitScale;
				pic.x = fitX;
				pic.y = fitY;				
			} else {
				myFitTweenSX = new Tween(pic, "scaleX", Strong.easeInOut, pic.scaleX, fitScale, .5, true);
				myFitTweenSY = new Tween(pic, "scaleY", Strong.easeInOut, pic.scaleY, fitScale, .5, true);
				myFitTweenX = new Tween(pic, "x", Strong.easeInOut, pic.x, fitX, .5, true);
				myFitTweenX = new Tween(pic, "y", Strong.easeInOut, pic.y, fitY, .5, true);			
				myFitTweenSX.addEventListener(TweenEvent.MOTION_FINISH, fitFinished);
			}
			setScale();
		}
		
		private function fitFinished(e:TweenEvent) {
			myEnabled = true;
		}
		
		private function setScale() {
			toCount = 0;
		}
		
		private function recordLast() {
			lastX = pic.x;
			lastY = pic.y;
			lastW = stage.stageWidth;
			lastH = stage.stageHeight;
		}
	
		
	}
}