var N=0,NNE=1,NE=2,ENE=3,E=4,ESE=5,SE=6,SSE=7,S=8,SSW=9,SW=10,WSW=11,W=12,WNW=13,NW=14,NNW=15,N2=16;
var flyingObjects=new Array(null,null,null,null);

		function direction(x,y) {
			this.horizontal = Math.abs(x);
			this.vertical   = Math.abs(y);
			this.move=1;
			this.hMove=new Array(0+signOf(x)*(this.horizontal>0),0+signOf(x)*(this.horizontal>1));
			this.vMove=new Array(0+signOf(y)*(this.vertical>0),0+signOf(y)*(this.vertical>1));
			}



		function manageFlights(flobArray) {							//an independent process to track the objects and bounce them off oeach other
			var loop1,loop2,flob1,flob2,xSep,ySep,xRatio,yRatio,xyc;
			for(loop1=4; loop1<flobArray.length;loop1++) {
				flob1=flobArray[loop1];				//object to compare
				for(loop2=0; loop2<flobArray.length; loop2++) { 
					if(loop1==loop2); else {					//skip if comparing object with itself
						flob2=flobArray[loop2];
						xSep=flob1.centreX-flob2.centreX;	//how far
						ySep=flob1.centreY-flob2.centreY;	//apart are the centres?
						xRatio=Math.abs(xSep)/(flob1.halfW+flob2.halfW);		// any X overlap?
						yRatio=Math.abs(ySep)/(flob1.halfH+flob2.halfH);		// any Y overlap? (yes if <=1)
						if(xRatio<=1 && yRatio<=1) {							//if both are true we have contact
							xyc=0*(xRatio==yRatio)+(xRatio>yRatio)-(yRatio>xRatio);
							switch(xyc) {
								case -1:  //top or bot
									if(ySep==Math.abs(ySep)) {
										flob1.topEdgeTouching=true;
									} else {
										flob1.bottomEdgeTouching=true;
									}
									break;
									
								case 0: // corner
									switch(ySep==Math.abs(ySep)) {
										case true:
											if(xSep==Math.abs(xSep)) {
												flob1.topEdgeTouching=flob1.leftEdgeTouching=true;
											} else {
												flob1.topEdgeTouching=flob1.rightEdgeTouching=true;
											}
											break;
										case false:
											if(xSep==Math.abs(xSep)) {
												flob1.bottomEdgeTouching=flob1.leftEdgeTouching=true;
											} else {
												flob1.bottomEdgeTouching=flob1.rightEdgeTouching=true;
											}
										}
										break;
								case 1: //left or right
									if(xSep==Math.abs(xSep)) {
										flob1.leftEdgeTouching=true;
									} else {
										flob1.rightEdgeTouching=true;
									}
								}
							flob1.bounce(); 
							flob1.leftEdgeTouching = flob1.topEdgeTouching = flob1.rightEdgeTouching = flob1.bottomEdgeTouching = false;
						} else {
							flob1.leftEdgeTouching = flob1.topEdgeTouching = flob1.rightEdgeTouching = flob1.bottomEdgeTouching = false;
					}}}}}
							


function shout(a,b,c,d){ if(!stop) {alert(a);alert(b);alert(c);alert(d);}	stop=true;}

		function allPoints() {
			this.compass = new Array(new direction(0,-2),  // N     0
									new direction(1,-2),   // NNE   1
									new direction(2,-2),   // NE    2
									new direction(2,-1),   // ENE   3
									new direction(2,0),    // E     4
									new direction(2,1),    // ESE   5
									new direction(2,2),    // SE    6
									new direction(1,2),    // SSE   7
									new direction(0,2),    // S     8
									new direction(-1,2),   // SSW   9
									new direction(-2,2),   // SW    10
									new direction(-2,1),   // WSW   11
									new direction(-2,0),   // W     12
									new direction(-2,-1),  // WNW   13
									new direction(-2,-2),  // NW    14
									new direction(-1,-2), // NNW   15
									new direction(0,0));   // Stationary 16
			}
			
		var Compass = new allPoints();


		
		function wander(o) {
			var c=Compass.compass[o.currentDir];
			var disty=c.vMove[c.move]*o.speed;
			var distx=c.hMove[c.move]*o.speed;
			var newX=distx+o.X, newY=disty+o.Y;
			o.Y=newY; o.X=newX;
			o.centreX+=distx; o.centreY+=disty;
			if(o.name.style) {
				o.name.style.top=newY+'px'; 
				o.name.style.left=newX+'px';
				} else {
				o.name.top=newY;
				o.name.left=newX;
				}
			c.move=Math.abs(c.move-1);
			}

		function Bounce() {
			switch(this.leadingEdge) {
				case 0: //LL
					switch(this.flagset()) {
						case 128: //left
							this.leadingEdge=rndInRange(2,4);
							this.currentDir=this.choice();
							return true;
						case 64: //top bumped
							this.leadingEdge=7;
							this.currentDir=this.choice();
							return true;
						case 32: //right bumped (behind)
							return true;
						case 16: // bottom bumped							 
							this.leadingEdge=3;
							this.currentDir=this.choice();
							return true;
						case 192: //top and left
							this.leadingEdge=5;
							this.currentDir=this.choice();
							return true;
						case 144: //bot and left
							this.leadingEdge=3;
							this.currentDir=this.choice();
							return true;
						case 96: //top and right
							this.leadingEdge=7;
							this.currentDir=this.choice();
							return true;
						case 48: //bot and right
							this.leadingEdge=1;
							this.currentDir=this.choice();
							return true;
						default:
							return true;
						}
				case 1: //LT
					switch(this.flagset()) {
						case 128: //left
							this.leadingEdge=rndInRange(2,3);
							this.currentDir=this.choice();
							return true;
						case 64: //top bumped
							this.leadingEdge=7*rndInRange(0,1);
							this.currentDir=this.choice();
							return true;
						case 32: //right bumped (behind)
							return true;
						case 16: // bottom bumped							 
							return true;
						case 192: //top and left
							this.leadingEdge=5;
							this.currentDir=this.choice();
							return true;
						case 144: //bot and left
							this.leadingEdge=3;
							this.currentDir=this.choice();
							return true;
						case 96: //top and right
							this.leadingEdge=7;
							this.currentDir=this.choice();
							return true;
						case 48: //bot and right
							this.leadingEdge=1;
							this.currentDir=this.choice();
							return true;
						default:
							return true;
						}
				case 2: //TT
					switch(this.flagset()) {
						case 128: //left
							this.leadingEdge=3;
							this.currentDir=this.choice();
							return true;
						case 64: //top bumped
							this.leadingEdge=rndInRange(4,8);
							if(this.leadingEdge==8) this.leadingEdge=0;
							this.currentDir=this.choice();
							return true;
						case 32: //right bumped
							this.leadingEdge=1;
							this.currentDir=this.choice();
							return true;
						case 16: // bottom bumped							 
							return true;
						case 192: //top and left
							this.leadingEdge=5;
							this.currentDir=this.choice();
							return true;
						case 144: //bot and left
							this.leadingEdge=3;
							this.currentDir=this.choice();
							return true;
						case 96: //top and right
							this.leadingEdge=7;
							this.currentDir=this.choice();
							return true;
						case 48: //bot and right
							this.leadingEdge=1;
							this.currentDir=this.choice();
							return true;
						default:
							return true;
						}
				case 3: //TR
					switch(this.flagset()) {
						case 128: //left
							this.leadingEdge=3;
							this.currentDir=this.choice();
							return true;
						case 64: //top bumped
							this.leadingEdge=rndInRange(4,5);
							this.currentDir=this.choice();
							return true;
						case 32: //right bumped
							this.leadingEdge=rndInRange(1,2);
							this.currentDir=this.choice();
							return true;
						case 16: // bottom bumped							 
							this.leadingEdge=rndInRange(2,3);
							this.currentDir=this.choice();
							return true;
						case 192: //top and left
							this.leadingEdge=5;
							this.currentDir=this.choice();
							return true;
						case 144: //bot and left
							this.leadingEdge=3;
							this.currentDir=this.choice();
							return true;
						case 96: //top and right
							this.leadingEdge=7;
							this.currentDir=this.choice();
							return true;
						case 48: //bot and right
							this.leadingEdge=1;
							this.currentDir=this.choice();
							return true;
						default:
							return true;
						}
				case 4: //RR
					switch(this.flagset()) {
						case 128: //left
							this.leadingEdge=rndInRange(3,5);
							this.currentDir=this.choice();
							return true;
						case 64: //top bumped
							this.leadingEdge=5;
							this.currentDir=this.choice();
							return true;
						case 32: //right bumped
							this.leadingEdge=rndInRange(6,10);
							if(this.leadingEdge>7) this.leadingEdge-=8;
							this.currentDir=this.choice();
							return true;
						case 16: // bottom bumped							 
							this.leadingEdge=3;
							this.currentDir=this.choice();
							return true;
						case 192: //top and left
							this.leadingEdge=5;
							this.currentDir=this.choice();
							return true;
						case 144: //bot and left
							this.leadingEdge=3;
							this.currentDir=this.choice();
							return true;
						case 96: //top and right
							this.leadingEdge=rndInRange(6,8);
							if(this.leadingEdge>7) this.leadingEdge-=8;
							this.currentDir=this.choice();
							return true;
						case 48: //bot and right
							this.leadingEdge=rndInRange(0,2);
							this.currentDir=this.choice();
							return true;
						default:
							return true;
						}
				case 5: //RB
					switch(this.flagset()) {
						case 128: //left
							this.leadingEdge=rndInRange(4,5);
							this.currentDir=this.choice();
							return true;
						case 64: //top bumped
							this.leadingEdge=rndInRange(5,6);
							this.currentDir=this.choice();
							return true;
						case 32: //right bumped
							this.leadingEdge=7;
							this.currentDir=this.choice();
							return true;
						case 16: // bottom bumped							 
							this.leadingEdge=3;
							this.currentDir=this.choice();
							return true;
						case 192: //top and left
							this.leadingEdge=5;
							this.currentDir=this.choice();
							return true;
						case 144: //bot and left
							this.leadingEdge=3;
							this.currentDir=this.choice();
							return true;
						case 96: //top and right
							this.leadingEdge=rndInRange(6,8);
							if(this.leadingEdge>7) this.leadingEdge-=8;
							this.currentDir=this.choice();
							return true;
						case 48: //bot and right
							this.leadingEdge=1;
							this.currentDir=this.choice();
							return true;
						default:
							return true;
						}
				case 6: //BB
					switch(this.flagset()) {
						case 128: //left
							this.leadingEdge=5;
							this.currentDir=this.choice();
							return true;
						case 64: //top bumped
							this.leadingEdge=rndInRange(5,7);
							this.currentDir=this.choice();
							return true;
						case 32: //right bumped
							this.leadingEdge=7;
							this.currentDir=this.choice();
							return true;
						case 16: // bottom bumped							 
							this.leadingEdge=2;
							this.currentDir=this.choice();
							return true;
						case 192: //top and left
							this.leadingEdge=5;
							this.currentDir=this.choice();
							return true;
						case 144: //bot and left
							this.leadingEdge=3;
							this.currentDir=this.choice();
							return true;
						case 96: //top and right
							this.leadingEdge=7;
							this.currentDir=this.choice();
							return true;
						case 48: //bot and right
							this.leadingEdge=1;
							this.currentDir=this.choice();
							return true;
						default:
							return true;
						}
				case 7: //BL
					switch(this.flagset()) {
						case 128: //left
							this.leadingEdge=6;
							this.currentDir=this.choice();
							return true;
						case 64: //top bumped
							this.leadingEdge=rndInRange(6,8);
							if(this.leadingEdge>7) this.leadingEdge-=8;
							this.currentDir=this.choice();
							return true;
						case 32: //right bumped
							this.leadingEdge=0;
							this.currentDir=this.choice();
							return true;
						case 16: // bottom bumped							 
							this.leadingEdge=rndInRange(0,1);
							this.currentDir=this.choice();
							return true;
						case 192: //top and left
							this.leadingEdge=rndInRange(5,6);
							this.currentDir=this.choice();
							return true;
						case 144: //bot and left
							this.leadingEdge=3;
							this.currentDir=this.choice();
							return true;
						case 96: //top and right
							this.leadingEdge=7;
							this.currentDir=this.choice();
							return true;
						case 48: //bot and right
							this.leadingEdge=1;
							this.currentDir=this.choice();
							return true;
						default:
							return true;
						}
					default:
						this.leadingEdge=rndInRange(0,7);
						this.currentDir=this.choice();
						return true;
					}}
							
					
			
		
		function flyingObject(x,y,w,h,divname,d,s) {
			this.X=x;
			this.Y=y;
			this.width=w;
			this.height=h;
			this.name=divname;
			this.currentDir=d;
			this.leadingEdge=5;
			this.choice = function() {
				switch(this.leadingEdge) {
					case 0: // LL
						return W;
					case 1: //LT
						return rndInRange(WNW,NNW);
					case 2: //TT
						return N;
					case 3: //TR
						return rndInRange(NNE,ENE);
					case 4: //RR
						return E;
					case 5: //RB
						return rndInRange(ESE,SSE);
					case 6: //BB
						return S;
					case 7: //BL
						return rndInRange(SSW,WSW)
				}}					
			this.flagset=function() {return (128*this.leftEdgeTouching + 64*this.topEdgeTouching + 32*this.rightEdgeTouching + 16*this.bottomEdgeTouching) };  //
			this.halfW=Math.floor(w/2);
			this.halfH=Math.floor(h/2);
			this.centreX=x+Math.round(w/2);
			this.centreY=y+Math.round(h/2);
			this.speed=s;
			this.bounce=Bounce;
		//	this.objBounce=bounceObj;
			this.leftEdgeTouching   = false;
			this.topEdgeTouching    = false;
			this.rightEdgeTouching  = false;
			this.bottomEdgeTouching = false;
			this.intID=null;
			}

	function updateSides() {
		var winD=getWinDims, winW=winD[0], winH=winD[1];
		if(document.documentElement && document.documentElement.clientWidth) {
			winW=document.documentElement.clientWidth; winH=document.documentElement.clientHeight;
		} else if(document.body) {
			winW=document.body.clientWidth; winH=document.body.clientHeight;
		} else {
			winW=window.innerWidth; winH=window.innerHeight;
		}
		flyingObjects[0]=new flyingObject(0,0,100,winH,"leftE",0,0);				//window edges treated as
		flyingObjects[1]=new flyingObject(0,0,winW,0,"topE",0,0);					//special non-flying
		flyingObjects[2]=new flyingObject(winW,0,0,winH,"rightE",0,0);			//flyingObjects to simplify
		flyingObjects[3]=new flyingObject(0,winH,winW,0,"bottomE",0,0);			//bouncing routine
		}		

function getAngle(this_x,this_y,that_x,that_y) {
	var r=360+Math.round(Math.atan2(that_y-this_y,that_x-this_x)/0.017453293);
	r-=360*(r>=360); return r;
	}	

function signOf(n) { var r=-1; if(n>=0) r=1; return r; }


function rndInRange(l,u) {	return (l+Math.floor(Math.random()*(++u-l))); }

function posneg() {return -1+2*Math.floor(Math.random()+.5)}
