DAN ZEN EXPO - CODE EXHIBIT - A MILLION CLOUDS

package millionclouds {
    
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.*;
	import flash.text.TextField;
	import fl.transitions.Tween;
	import fl.transitions.TweenEvent;
	import fl.transitions.easing.*;	
	import flash.ui.Keyboard;
	import flash.filters.BlurFilter;	
	import flash.display.Bitmap;
	import flash.display.BitmapData;	
	import flash.utils.Timer;	
	import flash.media.Sound;
	import flash.media.SoundChannel;	
	import flash.net.URLRequest;
	import flash.media.SoundTransform;
	import flash.net.SharedObject;
	import flash.ui.Mouse;
		
	// import the ActionScript Physics Engine - APE	
	import org.cove.ape.*;
	
	// import Falcon data class
	import com.danzen.utilities.Falcon;
    
	public class MillionClouds extends MovieClip {		
		
		private var mySky:Sprite;
		private var myPhysics:Sprite;
		private var myGroup:Group;
		private var myJet:JetParticle;
		private var myClouds1:Array = []; 
		private var myClouds2:Array = []; 
		private var leftCheck:Boolean = false;
		private var rightCheck:Boolean = false;
		private var thrustCheck:Boolean = false;
		
		// initial conditions
		private var jetRadius = 5;
		private var angleInterval:Number = 2;
		private var speedInterval:Number = .2;
		private var speedMax:Number = 15;
		
		private var myUp:MovieClip;
		private var myDown:MovieClip;
		private var myFly:MovieClip;
		private var myFlyRight:Boolean = true;
		private var myFilter:Array;
		private var myEmptyFilter:Array;
		
		// sitting
		private var sitCheck:Boolean = false;
		private var sitDirection:Number;
		private var numClouds:Number = 5;
		private var myTimer:Timer;
		private var manState:String = "fly";
		private var flipTo:Number; 		
		private var lastSitX:Number;
		
		// sky moving
		private var skyDone:Boolean = true;
		private var skyTweening:Boolean = false;
		private var skyTweenX:Tween;
		private var skyTweenY:Tween;
		
		// clouds
		private var cloudRows:Number = 5;
		private var cloudCols:Number = 5;	
		private var cloudSpacingX:Number = 1500;
		private var cloudSpacingY:Number = 1000;
		
		// backing clouds
		private var backingClouds:Sprite;
		private var backingClouds2:Sprite;
		private var backingTimer:Timer;
		private var backingMin:Number = 10; // min seconds for cloud to go
		private var backingMax:Number = 60; // max seconds for cloud to go
		private var bcList:Array = new Array();
		private var bcObject:Array = new Array();
		private var bcNum:Number = 50 ;
		private var bcCount:Number = 0;
		private var cyclesY:Number = 0;
		private var cyclesX:Number = 0;
		
		// menu
		private var thoughtCheck:Boolean = false;
		
		// power
		private var powerMax:Number = 50;
		private var powerCount:Number = powerMax;
		private var powerTimer:Timer;
		private var powerAlert:Boolean = false;
		private var noThrust:Boolean = false;
		private var cloudsLeft:Number = cloudRows * cloudCols;
		private var fillCheck:Boolean = false;
		
		// sucking Cloud
		private var cloudToSuck:Cloud;
		private var cloudDistance:Number = 220; 
		private var cloudSuckingTime:Number = 10;
		private var closestCloudIndex:Number;
		
		// sound
		private var soundJet:Sound;
		private var soundFillUp:Sound;
		private var soundSuck1:Sound;
		private var soundSuck2:Sound;
		private var soundGlide:Sound;
		private var soundSwitch:Sound;
		private var soundThought:Sound;
		private var soundJetC:SoundChannel;
		private var soundGlideC:SoundChannel;
		private var soundFillUpChannel:SoundChannel
		private var soundJetCheck:Boolean = false;
		private var soundJetCutCheck:Boolean = false;
		private var soundFillUpCheck:Boolean = false;
		private var soundSuck1Check:Boolean = false;
		private var soundSuck2Check:Boolean = false;
		private var soundGlideCheck:Boolean = true;
		private var soundSwitchCheck:Boolean = false;		
		private var soundCheck:Boolean = true;	
				
		//DATA
		private var myFalcon:Falcon;
		private var myFalcon2:Falcon;
		private var myFalcon3:Falcon;
		private var myID:Number;
		private var mySO:SharedObject;				
		
		private var count:Number = 0;
								
		public function MillionClouds() {					
			
			stage.addEventListener(MouseEvent.MOUSE_MOVE, startClickTrack);
			stage.addEventListener(MouseEvent.CLICK, startWorld);
			Mouse.hide();
			
			mySO = SharedObject.getLocal("million", "/");
			if (mySO.data.id == null || mySO.data.id == undefined) {
				mySO.data.id = Math.floor(Math.random()*10000000);
				if (mySO.data.id == 1000000) {mySO.data.id++}
				mySO.data.soundCheck = true;
			}
			soundCheck = mySO.data.soundCheck;
			checkSound();
			myID = mySO.data.id;
			
			myFalcon = new Falcon("http://danzen.com/millionclouds/count.php?random="+Math.floor(Math.random()*100000));
			myFalcon.addEventListener(Event.COMPLETE, getData);	
	
		
			setSound();
	
			powerTimer = new Timer(1000);
			powerTimer.start();
			powerTimer.addEventListener(TimerEvent.TIMER, checkPower);
			
			mySky = new Sprite();
					
			myTimer = new Timer(50,1);
			myTimer.addEventListener(TimerEvent.TIMER, changeMan);					
			
			backingClouds = new Sprite();
			addChild(backingClouds);
			backingClouds2 = new Sprite();
			addChild(backingClouds2);			
			backingTimer = new Timer(randomBetween(backingMax, backingMin) * 1000, 1);
			backingTimer.addEventListener(TimerEvent.TIMER, sendBackingCloud);	
			backingTimer.start();
			makeBackingCloud(randomBetween(myBackground.width));
			makeBackingCloud(randomBetween(myBackground.width));
			makeBackingCloud(randomBetween(myBackground.width));	
			
			myFilter = [new BlurFilter(10, 10, 5)];
			myEmptyFilter = [];
				
			// x, y, radius, thrust, angle, fixed, mass, elasticity, friction
			myJet = new JetParticle(myBackground.width/2, myBackground.height/2, jetRadius*2);
						
			myPhysics = new Sprite(); 
			myPhysics.alpha = 0;
			mySky.addChild(myPhysics);		       

			stage.frameRate = 66;	
			APEngine.init(1/4);
			APEngine.damping = .97; 
			APEngine.container = myPhysics;
			APEngine.addMasslessForce(new Vector(0,3.5)); // gravity
			
			myGroup = new Group();
			myGroup.collideInternal = true;						
			APEngine.addGroup(myGroup);
						
			myGroup.addParticle(myJet);
			
			addClouds();			
			
			addEventListener(Event.ENTER_FRAME, runEngine);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, doKeyDown);
			stage.addEventListener(KeyboardEvent.KEY_UP, doKeyUp);
			
			addChild(mySky);			
			
			setChildIndex(myText, numChildren-1);
			setChildIndex(earplugs, numChildren-1);
			setChildIndex(earplugsRoll, numChildren-1);
			setChildIndex(myClick, numChildren-1);			
			
			earplugsRoll.buttonMode = true;
			earplugsRoll.addEventListener(MouseEvent.ROLL_OVER, earplugsRollOver);
			earplugsRoll.addEventListener(MouseEvent.ROLL_OUT, earplugsRollOut);			
			earplugsRoll.addEventListener(MouseEvent.CLICK, toggleSound);				
			
		}
		
		private function startClickTrack(e:MouseEvent) {			
			myClick.x = mouseX;
			myClick.y = mouseY;
		}
		
		private function startWorld(e:MouseEvent) {			
			myClick.x = -5000;
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, startClickTrack);
			stage.removeEventListener(MouseEvent.CLICK, startWorld);
			Mouse.show();
		}		
		
		
		
		private function earplugsRollOver(e:MouseEvent) {			
			earplugsRoll.alpha = 1;
		}
		
		private function earplugsRollOut(e:MouseEvent) {
			earplugsRoll.alpha = 0;
		}			
					
		private function toggleSound(e:MouseEvent) {
			soundCheck = !soundCheck;
			checkSound();
			mySO.data.soundCheck = soundCheck;
		}

		private function checkSound() {
			if (soundCheck) {
				earplugs.myText.text = "Earplugs";
			} else {
				earplugs.myText.text = "No Earplugs";
			}		
		}
		
		private function getData(e:Event) {	
			var tot:Number = 1000000 - Number(e.target.data.total); 
			myText.text = "a Millon Clouds now " + String(tot);	
		}		
		
		private function setSound() {

			soundJet = new Sound();
			soundJet.load(new URLRequest("jet.mp3"));				

			
			soundFillUp = new Sound();
			soundFillUp.load(new URLRequest("fillup.mp3"));			
						
			soundSuck1 = new Sound();
			soundSuck1.load(new URLRequest("suck1.mp3"));			
			
			soundSuck2 = new Sound();
			soundSuck2.load(new URLRequest("suck2.mp3"));			
			
			soundGlide = new Sound();
			soundGlide.load(new URLRequest("glide.mp3"));
			soundGlideC = new SoundChannel();
			if (soundCheck) {
				soundGlideC = soundGlide.play();				
			}
			soundGlideC.addEventListener(Event.SOUND_COMPLETE, soundGlideComplete);
			
			soundSwitch = new Sound();
			soundSwitch.load(new URLRequest("switch.mp3"));				
			
			soundThought = new Sound();
			soundThought.load(new URLRequest("thought2.mp3"));			
			
			soundJetC = new SoundChannel();
			soundFillUpChannel = new SoundChannel();			
			
		}
		
		private function checkPower(e:TimerEvent) {
			if (thrustCheck) {
				powerCount--;
			}
			if (powerCount < 0) {
				if (cloudsLeft > 0) {
					powerAlert = true;				
				} else {
					noThrust = true;
					powerTimer.stop();
					trace ("play falling sound");
				}				
			}
		
		}
		
		private function randomBetween(a:Number=10, b:Number=0) {
			return Math.min(a,b) + Math.floor(Math.random() * Math.abs(a-b));
		}
		
		// backing clouds
		
		private function sendBackingCloud(e:TimerEvent) {
			backingTimer.reset();
			backingTimer.delay = randomBetween(backingMax, backingMin) * 1000;
			backingTimer.start();
			makeBackingCloud();
			
		}
		
		private function makeBackingCloud(myX:Number = -400) {
			bcList[bcCount%bcNum] = new Cloud();			
			bcList[bcCount%bcNum].gotoAndStop(randomBetween(numClouds));
			var myY:Number;
			if (Math.random() > .66) {
				bcList[bcCount%bcNum].alpha = .3;
				bcList[bcCount%bcNum].filters = [new BlurFilter(1, 1, 4)];						
				myY = randomBetween(myBackground.height-220, myBackground.height-110);
				bcList[bcCount%bcNum].scaleX = bcList[bcCount%bcNum].scaleY = (.79 - myY / 1000) * .8; 				
				bcObject[bcCount%bcNum] = new MovingObject(bcList[bcCount%bcNum], .1+(myBackground.height-myY-10)/4000, 0, myX, myY);
				backingClouds.addChild(bcList[bcCount%bcNum]);
			} else { 
				bcList[bcCount%bcNum].alpha = .2;
				bcList[bcCount%bcNum].filters = [new BlurFilter(1, 1, 5)];						
				myY = randomBetween(myBackground.height-110, myBackground.height-10);
				bcList[bcCount%bcNum].scaleX = bcList[bcCount%bcNum].scaleY = (.79 - myY / 1000) * .8; 				
				bcObject[bcCount%bcNum] = new MovingObject(bcList[bcCount%bcNum], .1+(myBackground.height-myY-10)/4000, 0, myX, myY);
				backingClouds2.addChild(bcList[bcCount%bcNum]);
			}
			bcCount++;
		}
				
		
		// Cloud layers and men
		
		private function addClouds() {			
			makeCloudLayer(myClouds1, [new BlurFilter(3, 3, 5)], 1);	
			addFigures();	
			makeCloudLayer(myClouds2, [new BlurFilter(8, 8, 5)], .5);			
			
		}	
		
		private function makeCloudLayer(ca:Array, bf:Array, al:Number) {
			var i:uint; var j:uint; var num:uint;
			var startX = (myBackground.width - cloudSpacingX * cloudCols) / 2;
			var startY = (myBackground.height - cloudSpacingY * cloudRows) / 2;			
			for (i=0; i<cloudRows; i++) {
				for (j=0; j<cloudCols; j++) {
					num = cloudRows * i + j;
					ca[num] = new Cloud();
					ca[num].gotoAndStop(Math.floor(Math.random()*numClouds)+1);
					ca[num].x = startX + cloudSpacingX * i;
					ca[num].y = startY + cloudSpacingY * j;
					mySky.addChild(ca[num]);		
					ca[num].filters = bf;		
					ca[num].alpha = al;					
				}
			}
		}
		
		private function addFigures() {
			myFly = new Fly();
			mySky.addChild(myFly);			
			myUp = new Up();
			myUp.alpha = 0;
			mySky.addChild(myUp);
			myDown = new Down();
			myDown.alpha = 0;
			mySky.addChild(myDown);
		}
		
		private function doKeyDown(e:KeyboardEvent) {
			
			// tend to hold down left and right so handle motion in runEngine loop
			if (e.keyCode == Keyboard.LEFT && !thoughtCheck && !fillCheck) {
				leftCheck = true;
			} 
			if (e.keyCode == Keyboard.RIGHT && !thoughtCheck && !fillCheck) {   
				rightCheck = true;
			} 
			
			if ((e.keyCode == Keyboard.UP || e.keyCode == Keyboard.SPACE) && !thoughtCheck && !noThrust && !fillCheck) {
				thrustCheck = true;
				myFly.smoke.alpha = .5;				
				if (!soundJetCheck) {
					if (mySoundTween) {
						mySoundTween.stop();
					}
					if (soundCheck) {
						soundJetC = soundJet.play();					
					}
					soundJetCheck = true;
					if (soundGlideCheck) {
						reduceGlideSound(soundGlideC);
					}
				}
				if (sitCheck) {		
					menuBar(false);
					manState = "fly";
					thoughtCheck = false;
					myUp.myThought.btn_think.removeEventListener(MouseEvent.CLICK, thoughtSubmit);
					myUp.filters = myFilter;
					myDown.filters = myFilter;
					myTimer.reset();
					myTimer.start();										
				}
			} else if ((e.keyCode == Keyboard.UP || e.keyCode == Keyboard.SPACE) && !thoughtCheck && noThrust && !fillCheck) {
				if (soundCheck) {
					soundGlide.play();
				}
			}
		}	
		
		
		private function doKeyUp(e:KeyboardEvent) {			
			if (e.keyCode == Keyboard.LEFT && !thoughtCheck && !fillCheck) {
				leftCheck = false;
			} 
			if (e.keyCode == Keyboard.RIGHT && !thoughtCheck && !fillCheck) {
				rightCheck = false;
			} 
			if ((e.keyCode == Keyboard.UP || e.keyCode == Keyboard.SPACE) && !thoughtCheck && !fillCheck) {
				soundJetCheck = false;
				trace (soundJetC.position,  soundJet.length);
				if (soundJetC.position + 1000 < soundJet.length) {
					reduceSound(soundJetC);
				} else {
					var soundTimer:Timer = new Timer(300, 1);
					soundTimer.addEventListener(TimerEvent.TIMER, startFall);
					soundTimer.start();
				}
				thrustCheck = false;
				myJet.thrust = 0;
				myFly.smoke.alpha = 0;
			} 			
		}	
		
		// SOUND
		
		private function soundGlideComplete(e:Event) {
			//soundGlideC = soundGlide.play();
			soundGlideCheck = false;
		}
		
		private function startFall(e:TimerEvent) {
			if (soundCheck) {
				soundGlideC = soundGlide.play();
			}
			soundGlideCheck = true;
		}
		
		private var mySoundTween:Tween;
		private var mySoundTransform:SoundTransform;
		private function reduceSound(w:SoundChannel) {			
			mySoundTransform = w.soundTransform;
			mySoundTween = new Tween(mySoundTransform, "volume", Regular.easeInOut, mySoundTransform.volume, 0, .4, true);
			mySoundTween.addEventListener(TweenEvent.MOTION_CHANGE, reduceSound2);
		}
		
		private function reduceSound2(e:TweenEvent) {
            soundJetC.soundTransform = mySoundTransform;
		}		
		
		private var mySoundTween2:Tween;
		private var mySoundTransform2:SoundTransform;
		private function reduceGlideSound(w:SoundChannel) {			
			mySoundTransform2 = w.soundTransform;
			mySoundTween2 = new Tween(mySoundTransform2, "volume", Regular.easeInOut, mySoundTransform2.volume, 0, 1, true);
			mySoundTween2.addEventListener(TweenEvent.MOTION_CHANGE, reduceGlideSound2);
		}
		
		private function reduceGlideSound2(e:TweenEvent) {
            soundGlideC.soundTransform = mySoundTransform2;
		}

		
		
		
		
		
		// CHANGING MEN
        
		private function flipJet(w:Number) {
			if (soundCheck) {
				soundSwitch.play();
			}
			flipTo = w;
			manState = "switch";
			myFly.filters = myFilter;
			myTimer.reset();
			myTimer.start();	
		}
		
		private function sit(w:Number) {
			
			reduceGlideSound(soundGlideC);
				
			manState = "sit";
			sitDirection = w;
			myFly.filters = myFilter;
			myTimer.reset();
			myTimer.start();
			sitCheck = true;			
			
			if (!skyTweening) {
				var closest = closestCloud();
				if (closest) {
					skyTweening = true;
					skyTweenX = new Tween(mySky, "x", Regular.easeInOut, mySky.x, 500 - closest.x, 3, true);
					skyTweenY = new Tween(mySky, "y", Regular.easeInOut, mySky.y, 500 - closest.y, 3, true);
					skyTweenX.addEventListener(TweenEvent.MOTION_FINISH, stopSkyTween);							
				}			
			}			
		}
		
		// menubar functions
		
		private function menuBar(w:Boolean) {
			
			var barTween:Tween; var i:uint;
			var barList = ["lookup", "lookdown", "drinktea", "readbook", "sendthought"];
			if (w) {									
				setChildIndex(myMenuBar, numChildren-1);
				barTween = new Tween(myMenuBar, "alpha", Regular.easeInOut, myMenuBar.alpha, 1, 1, true);				
				for (i=0; i<barList.length; i++) {
					myMenuBar["btn_"+barList[i]].buttonMode = true;
					myMenuBar["btn_"+barList[i]].alpha = 0;
					myMenuBar["btn_"+barList[i]].addEventListener(MouseEvent.ROLL_OVER, barRollOver);
					myMenuBar["btn_"+barList[i]].addEventListener(MouseEvent.ROLL_OUT, barRollOut);
					myMenuBar["btn_"+barList[i]].addEventListener(MouseEvent.CLICK, barClick);
				}	  
			} else {
				barTween = new Tween(myMenuBar, "alpha", Regular.easeInOut, myMenuBar.alpha, 0, 1, true);
				for (i=0; i<barList.length; i++) {					
					myMenuBar["btn_"+barList[i]].removeEventListener(MouseEvent.ROLL_OVER, barRollOver);
					myMenuBar["btn_"+barList[i]].removeEventListener(MouseEvent.ROLL_OUT, barRollOut);
					myMenuBar["btn_"+barList[i]].removeEventListener(MouseEvent.CLICK, barClick);
				}					
			}	
		}
		
		private function barRollOver(e:MouseEvent) {			
			e.currentTarget.alpha = 1;
		}
		private function barRollOut(e:MouseEvent) {
			e.currentTarget.alpha = 0;
		}
		private function barClick(e:MouseEvent) {		
			thoughtCheck = false;
			myUp.myThought.btn_think.removeEventListener(MouseEvent.CLICK, thoughtSubmit);
			myUp.myThought.alpha = 0;
			myUp.myThought.x = 5000;
			myUp.myBook.alpha = 0;
			myUp.myCup.alpha = 0			
			if (e.currentTarget.name == "btn_lookup") {
				if (manState != "sit" && manState != "up") {
					manState = "up"					
					myDown.filters = myFilter;
					myTimer.reset();
					myTimer.start();	
				}
			} else if (e.currentTarget.name == "btn_lookdown") {
				if (manState != "down") {
					manState = "down"					
					myUp.filters = myFilter;
					myTimer.reset();
					myTimer.start();	
				}			
			} else {
				if (manState == "down") {
					manState = "up"					
					myDown.filters = myFilter;
					myTimer.reset();
					myTimer.start();						
				}
				if (e.currentTarget.name == "btn_drinktea") {				
					myUp.myThought.alpha = 0;
					myUp.myBook.alpha = 0;					
					var partTween = new Tween(myUp.myCup, "alpha", Regular.easeIn, myUp.myCup.alpha, 1, .6, true);
				} else if (e.currentTarget.name == "btn_readbook") {
					myUp.myThought.alpha = 0;
					var partTween2 = new Tween(myUp.myBook, "alpha", Regular.easeIn, myUp.myCup.alpha, 1, .6, true);
					myUp.myCup.alpha = 0
				} else if (e.currentTarget.name == "btn_sendthought") {
					myUp.myThought.x = lastSitX;
					var partTween3 = new Tween(myUp.myThought, "alpha", Regular.easeIn, myUp.myThought.alpha, 1, .6, true);
					myUp.myBook.alpha = 0;
					myUp.myCup.alpha = 0
					thoughtCheck = true;
					myUp.myThought.btn_think.buttonMode = true;
					myUp.myThought.btn_think.addEventListener(MouseEvent.CLICK, thoughtSubmit);
					myUp.myThought.btn_think.addEventListener(MouseEvent.ROLL_OVER, function(e:MouseEvent) {e.currentTarget.alpha = 1;});
					myUp.myThought.btn_think.addEventListener(MouseEvent.ROLL_OUT, function(e:MouseEvent) {e.currentTarget.alpha = 0;});
				}
			}
		}		
		
		var partTween5:Tween;
		private function thoughtSubmit(e:MouseEvent) {	

			partTween5 = new Tween(myUp.myThought, "alpha", Regular.easeIn, myUp.myThought.alpha, 0, .6, true);
			partTween5.addEventListener(TweenEvent.MOTION_FINISH, moveThoughtAway);		
			thoughtCheck = false;
			manState = "up"			
			
			if (myUp.myThought.thoughtText.text == "") {return;}
			
			var myThought:Object = {think:myUp.myThought.thoughtText.text, id:String(myID)};
			myUp.myThought.thoughtText.text = "";				
			myFalcon2 = new Falcon("http://www.danzen.com/millionclouds/think.php", Falcon.VARIABLES, myThought);	
			if (soundCheck) {
				soundThought.play();
			}			
		}
		private function moveThoughtAway(e:TweenEvent) {
			myUp.myThought.x = 5000;
		}		
		
		private function changeMan(e:TimerEvent) {
			
			trace ("change man = " + manState);
			
			if (manState == "sit") {
				if (sitDirection > 0) {
					myDown.x = myUp.x = currentCloud().x + currentCloud()["seat"+sitDirection].x
					myDown.y = myUp.y = currentCloud().y + currentCloud()["seat"+sitDirection].y
					myFly.y = 5000;
					myFly.filters = myEmptyFilter;						
					if (sitDirection == 1) {
						myUp.scaleX = -1;
						myUp.x += 100;
						myDown.scaleX = -1;
						myDown.x += 100;
						myUp.myThought.scaleX = -1;
						myUp.myThought.x = -3;
					} else {
						myUp.scaleX = 1;
						myUp.myThought.scaleX = 1;
						myDown.scaleX = 1;
						myUp.myThought.x = -23;
					}
					lastSitX = myUp.myThought.x;
					myUp.filters = myFilter;
					myUp.alpha = 1;				
					sitDirection = 0;
					myTimer.reset();
					myTimer.start();			
					
					menuBar(true);
					
				} else {
					myUp.filters = myEmptyFilter;				
				}
			} else if (manState == "fly") {
				if (sitCheck) {
					myUp.filters = myEmptyFilter;
					myUp.alpha = 0;
					myDown.filters = myEmptyFilter;
					myDown.alpha = 0;
					sitCheck = false;
					myFly.filters = myFilter;
					myTimer.reset();
					myTimer.start();
				} else {
					myFly.filters = myEmptyFilter;
				}				
			} else if (manState == "switch") {
				manState = "switch2";
				myFly.gotoAndStop(flipTo);
				myFly.smoke.gotoAndStop(flipTo);
				myTimer.reset();
				myTimer.start();
			} else if (manState == "switch2") {
				manState = "fly";
				myFly.filters = myEmptyFilter;					
			} else if (manState == "up") {
				manState = "up2";
				myDown.filters = myEmptyFilter;
				myDown.alpha = 0;
				myUp.filters = myFilter;
				myUp.alpha = 1;
				myTimer.reset();
				myTimer.start();
			} else if (manState == "up2") {
				manState = "sit";
				myUp.filters = myEmptyFilter;		
			} else if (manState == "down") {
				manState = "down2";
				myDown.filters = myFilter;
				myDown.alpha = 1;
				myUp.filters = myEmptyFilter;
				myUp.alpha = 0;
				myTimer.reset();
				myTimer.start();				
				myUp.myCup.alpha = 0;
				myUp.myBook.alpha = 0;
				myUp.myThought.alpha = 0;
				myUp.myThought.x = 5000;
			} else if (manState == "down2") {
				manState = "down";
				myDown.filters = myEmptyFilter;					
			}
			
		}		
		
		private function tweenSky(t:Boolean) {
			if (!t) {
				if (skyTweenX) {
					skyTweenX.stop();
					skyTweenY.stop();
				}
				skyTweening = false;				
			} else {		
				trace ("here");
				var closest = closestCloud();
				if (closest) {
					skyTweening = true;
					skyTweenX = new Tween(mySky, "x", Regular.easeInOut, mySky.x, 500 - closest.x, 6, true);
					skyTweenY = new Tween(mySky, "y", Regular.easeInOut, mySky.y, 500 - closest.y, 6, true);
					skyTweenX.addEventListener(TweenEvent.MOTION_FINISH, stopSkyTween);							
				}
			}
		}
		
		private function stopSkyTween(e:TweenEvent) {
			skyDone = true;
			skyTweening = false;
		}
		
		private function currentCloud() {
			for (var i:uint = 0; i< myClouds1.length; i++) {
				if (myClouds1[i].hitTestObject(myFly)) {
					return myClouds1[i];
				}
			}
			return myClouds1[0];
		}
		
		private function closestCloud() {
			var i:uint;
			for (i = 0; i< myClouds1.length; i++) {
				if (myClouds1[i].hitTestObject(myFly)) {
					closestCloudIndex = i;
					return myClouds1[i];
				}
			}
			if (powerAlert || myFlyRight) { // this will decide which side gets attention for closest cloud
				for (i = myClouds1.length-1; i>= 0; i--) {
					if (i>myClouds1.length-1) {break;} // strange glitch
					if (myClouds1[i].hitTestObject(myBackground)) {
						closestCloudIndex = i;
						return myClouds1[i];
					}
				}
			} else {
				for (i = 0; i< myClouds1.length; i++) {
					if (i>myClouds1.length-1) {break;}				
					if (myClouds1[i].hitTestObject(myBackground)) {
						closestCloudIndex = i;
						return myClouds1[i];
					}
				}				
			}
			return null;
		}		

		
		private var fillTweenX:Tween;
		private var fillTweenY:Tween;
		private var fillSkyTweenX:Tween;
		private var fillSkyTweenY:Tween;			
		private var fillTweenRotation:Tween;
		
			
		private function prepareToSuckCloud(c:Cloud) {			
			
			if (soundCheck) {
				soundFillUpChannel = soundFillUp.play();
			}
			var transformMe:SoundTransform = soundFillUpChannel.soundTransform;
			transformMe.volume = .4;
			soundFillUpChannel.soundTransform = transformMe;

			myFly.smoke.alpha = .5;
			rightCheck = false;
			leftCheck = false;			
			thrustCheck = false;			
			myJet.thrust = 0;						
			fillCheck = true;
			var r:Number;
			r = 50;
			myJet.angle = r;			
			
			fillTweenX = new Tween(myFly, "x", Regular.easeInOut, myFly.x, c.x-cloudDistance, 3, true);
			fillTweenY = new Tween(myFly, "y", Regular.easeInOut, myFly.y, c.y-cloudDistance, 3, true);
			fillSkyTweenX = new Tween(mySky, "x", Regular.easeInOut, mySky.x, myBackground.width/2 - c.x, 5, true);
			fillSkyTweenY = new Tween(mySky, "y", Regular.easeInOut, mySky.y, myBackground.height/2 - c.y, 5, true);			
			fillTweenRotation = new Tween(myFly, "rotation", Regular.easeInOut, myFly.rotation, r, 1, true);
			
			if (!myFlyRight) {
				flipTo = 1;
				manState = "switch"					
				myFly.filters = myFilter;
				myTimer.reset();
				myTimer.start();	
			}		
			
			cloudToSuck = c;
			fillTweenY.addEventListener(TweenEvent.MOTION_FINISH, suckCloud);
		}		
		
		
		private var fillTweenFill:Tween;
		private var fillCloud1Alpha:Tween;
		private var fillCloud2Alpha:Tween;
		private var fillTweenSmallerAlpha:Tween;		
		private var fillTweenSmallerX:Tween;
		private var fillTweenSmallerY:Tween;
		private var fillCloud1ScaleX:Tween;
		private var fillCloud1ScaleY:Tween;
		private var fillCloud1X:Tween;
		private var fillCloud1Y:Tween;
		private var fillCloud2ScaleX:Tween;
		private var fillCloud2ScaleY:Tween;
		private var fillCloud2X:Tween;
		private var fillCloud2Y:Tween;		
		
		private function suckCloud(e:TweenEvent) {				
			if (soundCheck) {
				soundSuck2.play();
			}
			var fillSoundTimer:Timer = new Timer((cloudSuckingTime-2)*1000, 1);			
			fillSoundTimer.addEventListener(TimerEvent.TIMER, endFillSound);
			fillSoundTimer.start();
			
			var cloudToSuck2:Cloud = myClouds2[closestCloudIndex];
			myFly.fill.scaleX = 1;
			fillTweenFill = new Tween(myFly.fill, "alpha", Regular.easeIn, myFly.fill.alpha, .5, 2, true);
			fillTweenFill.addEventListener(TweenEvent.MOTION_FINISH, increaseAlpha);
			fillTweenSmallerX = new Tween(myFly.fill, "scaleX", Regular.easeInOut, 1, .1, cloudSuckingTime, true);
			fillTweenSmallerY = new Tween(myFly.fill, "scaleY", Regular.easeInOut, 1, .1, cloudSuckingTime, true);			
			fillCloud1ScaleX = new Tween(cloudToSuck, "scaleX", Regular.easeInOut, 1, .1, cloudSuckingTime, true);
			fillCloud1ScaleY = new Tween(cloudToSuck, "scaleY", Regular.easeInOut, 1, .1, cloudSuckingTime, true);			
			fillCloud1X = new Tween(cloudToSuck, "x", Regular.easeInOut, cloudToSuck.x, cloudToSuck.x-cloudDistance+24, cloudSuckingTime, true);
			fillCloud1Y = new Tween(cloudToSuck, "y", Regular.easeInOut, cloudToSuck.y, cloudToSuck.y-cloudDistance+24, cloudSuckingTime, true);
			fillCloud1Alpha = new Tween(cloudToSuck, "alpha", Regular.easeInOut, cloudToSuck.alpha, 0, cloudSuckingTime, true);
			fillCloud2ScaleX = new Tween(cloudToSuck2, "scaleX", Regular.easeInOut, 1, .1, cloudSuckingTime, true);
			fillCloud2ScaleY = new Tween(cloudToSuck2, "scaleY", Regular.easeInOut, 1, .1, cloudSuckingTime, true);
			fillCloud2X = new Tween(cloudToSuck2, "x", Regular.easeInOut, cloudToSuck2.x, cloudToSuck2.x-cloudDistance+24, cloudSuckingTime, true);
			fillCloud2Y = new Tween(cloudToSuck2, "y", Regular.easeInOut, cloudToSuck2.y, cloudToSuck2.y-cloudDistance+24, cloudSuckingTime, true);
			fillCloud2Alpha = new Tween(cloudToSuck2, "alpha", Regular.easeInOut, cloudToSuck2.alpha, 0, cloudSuckingTime, true);						
			fillCloud2Alpha.addEventListener(TweenEvent.MOTION_FINISH, fillDone);
		}
		
		private function increaseAlpha(e:TweenEvent) {
			fillTweenSmallerAlpha = new Tween(myFly.fill, "alpha", Regular.easeIn, myFly.fill.alpha, 0, cloudSuckingTime-3, true);			
		}
		
		private function endFillSound(e:TimerEvent) {
			if (soundCheck) {
				soundSuck1.play();
			}
		}
		
		private function fillDone(e:TweenEvent) {			
			var fudge:Timer = new Timer(500, 1);			
			fudge.addEventListener(TimerEvent.TIMER, fudgeFix);
			fudge.start();
			myFlyRight = true;
		}
		
		private function fudgeFix(e:TimerEvent) {
			myClouds1[closestCloudIndex].x = -10000;
			myClouds2[closestCloudIndex].x = -10000;
			myJet.px = myFly.x;
			myJet.py = myFly.y;			
			myFly.smoke.alpha = 0;			
			fillCheck = false;
			var newCloudNum:Number = Number(myText.text.split("now ")[1]) - 1;
			myText.text = "a Millon Clouds now " + String(newCloudNum);
			
			var mySend:Object = {id:String(myID)};
			myFalcon3 = new Falcon("http://www.danzen.com/millionclouds/count.php", Falcon.VARIABLES, mySend);			
			
			if (soundCheck) {
				soundGlide.play();				
			}
			soundJetCheck = false;
			soundGlideCheck = true;			
			
		}		
		
		private function runEngine(e:Event) {						
		
			if (sitCheck || fillCheck) {return;}
		
			// update jet
			if (leftCheck) {						  
				myJet.angle -= angleInterval;
			} 
			if (rightCheck) {
				myJet.angle += angleInterval;
			}
			if (thrustCheck) {
				myJet.thrust += speedInterval;
				myJet.thrust = Math.min(speedMax, myJet.thrust);
				trace (myJet.thrust);
			} 									
			myFly.x = myJet.px;
			myFly.y = myJet.py;
	
			
			// sitting							
			if (!sitCheck && !thrustCheck && !myFlyRight && myFly.bum.hitTestObject(currentCloud().seat1) && myJet.velocity.y >= 0) {
				sit(1);
				return;
			}			
			if (!sitCheck && !thrustCheck && myFlyRight && myFly.bum.hitTestObject(currentCloud().seat2) && myJet.velocity.y >= 0) {
				sit(2);
				return;
			}			
			
			
			// flipping
			myFly.rotation = myJet.angle;
			if (myJet.angle > 360) {myJet.angle = 0;}
			if (myJet.angle < 0) {myJet.angle = 360 - myJet.angle;}
			if (myJet.angle > 180 && myFlyRight) {
				count = 0;
				flipJet(2);								
				myFlyRight = false;
			} else if (myJet.angle <= 180 && !myFlyRight) {
				count = 0;
				flipJet(1);
				myFlyRight = true;
			}		
					
			// sky movement
			var moveCheck:Boolean = false;
			if (mySky.x + myFly.x < 130) {
				mySky.x = 130 - myFly.x;
				moveCheck = true;
				skyDone = false;				
			}
			if (mySky.x + myFly.x > myBackground.width - 130) {
				mySky.x = myBackground.width - 130 - myFly.x;
				moveCheck = true;
				skyDone = false;
			}
			if (mySky.y + myFly.y < 130) {
				mySky.y = 130 - myFly.y;
				moveCheck = true;
				skyDone = false;
			}
			if (!noThrust && mySky.y + myFly.y > myBackground.height - 154) {
				mySky.y = myBackground.height - 154 - myFly.y;
				moveCheck = true;
				skyDone = false;
			}				
			if (moveCheck) {
				tweenSky(false);
			}
			if (!skyTweening && !moveCheck && !skyDone) {
				tweenSky(true)
			}
			
			
			// loop sky 
			if (mySky.y > (cloudRows / 2 + 1) * cloudSpacingY) {				
				mySky.y = - (cloudRows + 1) * cloudSpacingY;				
				myJet.py += (cloudRows + 1) * cloudSpacingY;
				cyclesY--;
				myFly.y += (cloudRows + 1) * cloudSpacingY;						
			} else if (mySky.y < - (cloudRows / 2) * cloudSpacingY) {								
				mySky.y = (cloudRows + 1) * cloudSpacingY;				
				myJet.py -= (cloudRows + 1) * cloudSpacingY;
				myFly.y -= (cloudRows + 1) * cloudSpacingY;
				cyclesY++;
			}
			if (mySky.x > (cloudCols / 2 + 1) * cloudSpacingX) {				
				mySky.x = - (cloudCols + 1) * cloudSpacingX;				
				myJet.px += (cloudCols + 1) * cloudSpacingX;
				myFly.x += (cloudCols + 1) * cloudSpacingX;								
				cyclesX--;
			} else if (mySky.x < - (cloudCols / 2) * cloudSpacingX) {								
				mySky.x = (cloudCols + 1) * cloudSpacingX;				
				myJet.px -= (cloudCols + 1) * cloudSpacingX;
				myFly.x -= (cloudCols + 1) * cloudSpacingX;
				cyclesX++;
			}			
			
			
			backingClouds.y = - (myFly.y + (cloudRows + 1) * cloudSpacingY * cyclesY) / 1000 * 50;
			backingClouds2.y = - (myFly.y + (cloudRows + 1) * cloudSpacingY * cyclesY) / 1000 * 25;
			backingClouds.x = - (myFly.x + (cloudCols + 1) * cloudSpacingX * cyclesX) / 1000 * 50;
			backingClouds2.x = - (myFly.x + (cloudCols + 1) * cloudSpacingX * cyclesX) / 1000 * 25;				
			
						
			
			// suck cloud
			if (powerAlert && !noThrust) {
				var i:uint;
				var currentCloud:Cloud = closestCloud()
				if (currentCloud) {
					prepareToSuckCloud(currentCloud);
					powerAlert = false;
					powerCount = powerMax;
				}				
			}			

			// draw world			
			APEngine.step();
			APEngine.paint();					
			
		}							
    }
    
} 

 package millionclouds {
    
        import flash.display.MovieClip;
        import flash.display.Sprite;
        import flash.events.*;
        import flash.text.TextField;
	import fl.transitions.Tween;
	import fl.transitions.TweenEvent;
	import fl.transitions.easing.*;	
	import flash.ui.Keyboard;
	
	// import the ActionScript Physics Engine - APE	
	import org.cove.ape.*;
    
    	public class JetParticle extends CircleParticle  {
        
								
		private var myX:Number;
		private var myY:Number;
		private var myRadius:Number;
		private var myThrust:Number;
		private var myAngle:Number;
		private var myFixed:Boolean;
		private var myMass:Number;
		private var myElasticity:Number;
		private var myFriction:Number;

		public function JetParticle (
					theX:Number,
					theY:Number,
					theRadius:Number,
					theThrust:Number = 10,
					theAngle:Number = 0,
					theFixed:Boolean = false,
					theMass:Number = 1,
					theElasticity:Number = .3,
					theFriction:Number = 0) {

			myX = theX;
			myY = theY;
			myRadius = theRadius;
			myThrust = theThrust;
			myAngle = theAngle;
			myFixed = theFixed;
			myMass = theMass;
			myElasticity = theElasticity;
			myFriction = theFriction;										
			
			super(myX, myY, myRadius, myFixed, myMass, myElasticity, myFriction);		
			
			thrust = myThrust;
			angle = myAngle;
		
		}		
		
		private function setVelocity(t, a) {
			var xThrust = t * Math.sin(angle * Math.PI / 180);
			var yThrust = - t * Math.cos(angle * Math.PI / 180);					
			velocity = new Vector(xThrust, yThrust);			
		}
		
		public function set thrust(t:Number) {
			myThrust = t;
			setVelocity(myThrust, myAngle);
		}
		
		public function get thrust() {
			return myThrust;
		}
		
		public function set angle(a:Number) {
			myAngle = a;
			setVelocity(myThrust, myAngle);
		}
		
		public function get angle() {
			return myAngle;
		}		
		  
    }
    
} 

 package millionclouds {
    
        import flash.display.MovieClip;
        import flash.display.Sprite;
        import flash.events.*;
        import flash.text.TextField;
	import fl.transitions.Tween;
	import fl.transitions.TweenEvent;
	import fl.transitions.easing.*;	
	import flash.ui.Keyboard;
	
	// import the ActionScript Physics Engine - APE	
	import org.cove.ape.*;
    
    	public class JetParticle extends CircleParticle  {
        
								
		private var myX:Number;
		private var myY:Number;
		private var myRadius:Number;
		private var myThrust:Number = 0;
		private var myAngle:Number = 0;
		private var myFixed:Boolean;
		private var myMass:Number;
		private var myElasticity:Number;
		private var myFriction:Number;	

		public function JetParticle (
					theX:Number,
					theY:Number,
					theRadius:Number,
					theFixed:Boolean = false,
					theMass:Number = 1,
					theElasticity:Number = .3,
					theFriction:Number = 0) {

			myX = theX;
			myY = theY;
			myRadius = theRadius;
			myFixed = theFixed;
			myMass = theMass;
			myElasticity = theElasticity;
			myFriction = theFriction;				
			
			super(myX, myY, myRadius, myFixed, myMass, myElasticity, myFriction);		
		
		}		
		
		private function setVelocity(t, a) {
			var xThrust = t * Math.sin(a * Math.PI / 180);
			var yThrust = - t * Math.cos(a * Math.PI / 180);					
			velocity = new Vector(xThrust, yThrust);			
		}
		
		public function set thrust(t:Number) {
			myThrust = t;
			if (myThrust > 0) {
				setVelocity(myThrust, myAngle);
			}
		}
		
		public function get thrust() {
			return myThrust;
		}
		
		private function setAngle(a) {
			if (myThrust > 0) {
				var xThrust = velocity.magnitude() * Math.sin(a * Math.PI / 180);
				var yThrust = - velocity.magnitude() * Math.cos(a * Math.PI / 180);					
				velocity = new Vector(xThrust, yThrust);				
			}
		}		
		
		public function set angle(a:Number) {
			myAngle = a;
			setAngle(myAngle);
		}
		
		public function get angle() {
			return myAngle;
		}		
		        
    }
    
}