//Globals
var tickInt = 50;  
var PIon180 = Math.PI / 180;

function pos(x, y){
	this.x = Math.round(x);
	this.y = Math.round(y);
}

function animation(id, path, steps){
	this.elem = document.getElementById(id);
	this.active = 0;
	this.timer = null;
	this.path = path;      // pointer to path object
	this.pathIdx = 0;      // step counter
	this.numSteps = steps; // total steps, 0 = go forever
}

animation.prototype.start = function(){

	if (this.active)
		return;
	
	var saveThis = this;
	
	this.step();
	this.active = 1;
	this.timer = setInterval(function(){ saveThis.step() }, tickInt);

}

animation.prototype.stop = function(){

	if (!this.timer)
		return false;
	clearInterval(this.timer);
	this.active = 0;

}

animation.prototype.step = function(){

	var nextPos = this.path.nextStep(this.pathIdx);
	
	this.moveTo(nextPos.x, nextPos.y);
	if ((this.numSteps > 0) && (this.pathIdx >= this.numSteps))
		this.stop();
	else
		this.pathIdx++;

}

animation.prototype.moveTo = function(x, y){
	this.elem.style.top = y + 'px';
	this.elem.style.left = x + 'px';
}

function size(w, h){
	this.width = w;
	this.height = h;
}

function getElementSize(id){
	var docObj = document.getElementById(id);
	
	var w = docObj.offsetWidth;   // value in pixels
	var h = docObj.offsetHeight;
	
	return new size(w, h);
}

function boundary(left, top, width, height, reflect){
	this.left = left;
	this.right = left + width;
	this.top = top;
	this.bottom = top + height;
	this.reflect = reflect;    // bounce off wall else disappear
}

function flyPath(id, initPos, slope, speed, walls){
	var px_mm = 2;
	var vel = speed * px_mm * tickInt;
	
	this.elemSize = getElementSize(id);       // size object
	this.currX = initPos.x;
	this.currY = initPos.y;
	this.xVel = vel * Math.cos(slope * PIon180);
	this.yVel = vel * Math.sin(slope * PIon180);
	this.walls = walls;
	this.gravity = 0.0098 * px_mm * tickInt * tickInt;
}

flyPath.prototype.nextStep = function(index){

	var x, y;    // new pos candidate
	
	this.yVel += 0.02 * this.gravity;
	x = this.currX + this.xVel;
	y = this.currY + this.yVel;
	if (x > this.walls.right - this.elemSize.width){
		x = this.walls.right - this.elemSize.width;
		this.xVel *= -1.2;    // lossy reflection next step
	}
	if (x < this.walls.left){
		x = this.walls.left;
		this.xVel *= -0.8;    // lossy reflection next step
	}
	if (y > this.walls.bottom - this.elemSize.height){
		y = this.walls.bottom - this.elemSize.height;
		if (Math.abs(this.yVel) < this.gravity){
			// Now if velocity is less than g, let the g term be the loss mechanism
			this.gravity *= 0.2;
			this.yVel *= -1.0;
			this.xVel *= 0.95;   // introduce rolling friction for x motion
		}else
			this.yVel *= -1.2;    // lossy reflection next step
	}
	if (y < this.walls.top){
		y = this.walls.top;
		this.yVel = -0.8 * this.yVel;    // lossy reflection next step
	}
	
	this.currX = x;
	this.currY = y;
	return new pos(this.currX, this.currY);

}

var pxPerEm = 10;

function getBoxSize(id, emWidth){

	var obj = document.getElementById(id);
	var w = obj.offsetWidth;   // value in pixels
	var h = obj.offsetHeight;
	
	pxPerEm = w/emWidth;
	
	box.left = 0;
	box.top = 0;
	box.right = w;
	box.bottom = h;

}

function randomInt(first, last){
	var nVals = last - first + 1;
	return Math.floor(Math.random() * nVals + first);
}

function fly_away(){

	var startPos = new pos(4 * pxPerEm, 3 * pxPerEm);
	var startAngle = 3 * randomInt(0, 11);
	var speed = 0.5;
	
    flyAnim = new animation("fly", null, 74);
    box = new boundary(0, 0, 0, 0, true);
	getBoxSize("flyArena", 74);
	flyAnim.path = new flyPath("fly", startPos, startAngle, speed, box);
	flyAnim.moveTo(startPos.x, startPos.y);
	flyAnim.pathIdx = 0;
	flyAnim.start();

}