/*
	Javascript functions 
	(C)2006 Dustin Spicuzza
*/

// create special objects
var center = new dispObj('img/s/center.png','','','',0,1);
var boom = new dispObj('img/s/boom.png','','','',0,1);
var rocket = new dispObj('img/s/rocket.png','','','',0,1);
var tail = new dispObj('img/s/tail.png','','','',0,1);
var bullet = new dispObj('img/s/bullet.png','','','',0,1);
var bspot = new dispObj('img/s/bspot.png','','','',0,1);
var mine = new dispObj('img/s/mine.png','','','',0,1);
boom.loadImg();

var paint = new Array();
paint[0] = new dispObj('img/s/paint0.png','','','',0,1);
paint[1] = new dispObj('img/s/paint1.png','','','',0,1);
paint[2] = new dispObj('img/s/paint2.png','','','',0,1);
paint[3] = new dispObj('img/s/paint3.png','','','',0,1);

var pspot = new Array();
pspot[0] = new dispObj('img/s/pspot0.png','','','',0,1);
pspot[1] = new dispObj('img/s/pspot1.png','','','',0,1);
pspot[2] = new dispObj('img/s/pspot2.png','','','',0,1);
pspot[3] = new dispObj('img/s/pspot3.png','','','',0,1);



function dispObj(src,title,description,href,adType,isPNG){
	
	this.image = null;

	if (!adType){
		this.isSeq = 0;
		this.isDual = 0;
	}else if (adType == 1){
		this.isSeq = 0;
		this.isDual = 1;
	}else{
		this.isSeq = adType;
		this.isDual = 0;
	}
	
	this.src = src;
	this.title = title;
	this.description = description;
	this.href = href;

	this.isPNG = isPNG;
	this.loadImg = function(){
		if (!this.image){
			this.image = new Image();
			this.image.src = this.src;
		}
	};
}

// linked list item
function llItem(item,type){
	this.item = item;
	this.type = type;

	this.next = null;
		
	this.id = 'bb' + unique.next();			// id of container
	this.imgId = this.id + '-img';			// id of image (div/img)
	this.divCreated = 0;
	
	if (bbDirection == 1 || type == 2){
		this.count = 0;
	}else{
		this.count = 149;
	}
	
	this.zIndex = this.count;
	this.w = 1;
	this.h = 1;
	this.l = 1;
	this.t = 1;
	this.r = 0;		// ratio used for scoring
	
	// update animation parameters
	this.update = function(){
		// ratio used for scoring
		this.r = paths[this.type][this.count][0];
		var x = parseInt(this.item.image.width * paths[this.type][this.count][0],10);
		!x ? this.w = 1 : this.w = x;
		
		this.l = parseInt(bbStartX[this.type] + paths[this.type][this.count][1] - (bbMoveEdge[this.type] ? x : 0),10);
		
		x = parseInt(this.item.image.height * paths[this.type][this.count][0],10);
		!x ? this.h = 1 : this.h = x;
		
		this.t = parseInt(bbStartY[this.type] + paths[this.type][this.count][2] - x,10);
	}

	this.hits = 0;
	this.eInit = 0;
	this.eNode = null;
	
	this.explode = function(x,y){
		// if not initialized, then initialize our lil node :)
		if (!this.eInit){
			this.eInit = 1;
			this.eNode = new boomItem(this,x,y);	
		}
		return animate(this.eNode);
	}
	
	// detonate the item -- x,y are relative to the element
	this.detonate = function(x,y){
		o = document.getElementById(this.id);
		addBoom(this.id + 'b',boom.src,1,this.id);
		o.boom = 1;
		o.boomX = x;
		o.boomY = y;
		
		updateScore(this.score());
	}
	
	// detect whether the 'shot' hit or not -- ignore transparency :(
	// if z = -1, its ignored
	this.detect = function(x,y,z){
		if ((this.zIndex >= z || this.zIndex == -1) && x >= this.l && x <= this.l + this.w && y >= this.t && y <= this.t + this.h){
			return 1;
		}
		return 0;
	}
	
	this.doAction = function(){
		// do some specific actions now
		if (this.type == 2){
			if (this.count == paths[this.type].length - 1){
				updateScore(-(this.score()/2));
				return 1;	
			}
			this.count += 1;
			this.zIndex += 1;
		}else{
			// remove item if necessary
			if ((bbDirection == 1 && this.count == paths[type].length - 1) || (bbDirection == -1 && this.count === 0)){
				// remove points
				if (this.type < 2){
					updateScore(-this.score());
				}
				
				return 1;
			}
			
			// special billboard stuff
			if (this.type < 2){
				if ((bbDirection == 1 && this.count == 75) || (bbDirection == -1 && this.count == 130)){
					document.getElementById(bbCaption[this.type]).innerHTML = 
						'<h5><a href="' + this.item.href + '">' + this.item.title + '</a></h5>' +
						this.item.description;
				}
			}
			
			// increment count
			this.count += bbDirection;
			this.zIndex += bbDirection;
		}
		return 0;
	}
	
	// calculate current score for this object
	this.score = function(){
		var s = (150000 - this.item.image.height * this.item.image.width)/10;
		var rt = this.r;
		if (rt > 1.5){
			rt = 1.5;
		}
		s = ((s - s * (rt/2))/2);
		if (s < 0){
			s = 1;
		}
		return s;
	}
	
	this.hitit = function(x,y){
		this.hits += 1;
		if (this.hits > 2){
			this.detonate(x - this.l, y - this.t);
		}
	}
}

// special items
function boomItem(parent,x,y){

	this.parent = parent;
	this.item = boom;
	this.type = 4;
		
	this.id = parent.id + 'b';					// id of container
	this.imgId = this.id + '-img';				// id of image (div/img)
	this.divCreated = 1;
	
	this.count = 0;
	
	this.xo = x;		// right offset
	this.yo = y;		// top offset
	
	this.zIndex = parent.zIndex + 1;
	this.w = 1;
	this.h = 1;
	this.l = 1;
	this.t = 1;
	
	// update animation parameters
	this.update = function(){
		var mult = (this.count / 10) * paths[this.parent.type][this.parent.count][0];
		
		var x = parseInt(this.item.image.width * mult,10);
		!x ? this.w = 1 : this.w = x;
		
		this.l = this.xo - (x/2);
		
		x = parseInt(this.item.image.height * mult,10);
		!x ? this.h = 1 : this.h = x;
		
		this.t = parseInt(this.yo - this.parent.h - x/2,10);
	}
	
	// do some item-specific action
	this.doAction = function(){
		if (this.count == 15)
			return 2;		// signify to insert a new item instead of waiting
		this.count += 1;
		this.zIndex += bbDirection;
		return 0;
	}
}

// special items
function rocketItem(x,y){

	this.item = rocket;
	this.type = 4;
		
	this.id = 'rk' + unique.next();				// id of container
	this.imgId = this.id + '-img';				// id of image (div/img)
	
	this.divCreated = 0;
	this.next = null;
	
	this.xo = x;		// destination x coord
	this.yo = y;		// destination y coord

	if (this.yo < 100){
		this.scale = 5;
	}else if (this.yo < 200){
		this.scale = 10;
	}else{
		this.scale = 20;
	}
	
	this.count = 150;
	this.zIndex = this.count;
	this.w = 1;
	this.h = 1;
	this.l = 1;
	this.t = 1;
	
	this.hit = 0;
	
	// update animation parameters
	this.update = function(){
		
		// add a tail
		addToQueue(new tailItem(this.l - this.w/2,this.t - this.h/2,this.h,this.w,this.zIndex));
		
		// incrementally animate scale counts
		for (var i = 0;i< this.scale;i++){
			
			this.count -= 1;
			this.zIndex -= 1;
			
			if (this.count < 0){
				return;
			}
		
			var d = (150 - this.count) / 13;
			// piecewise function
			var r = 2 / d;
			//paths[1][i] = [r, 300/d, 109/d ];
			
			this.h = r * this.item.image.height;
			this.w = r * this.item.image.width;
			
			this.l = this.xo - this.w/2;
			this.t = this.yo - this.h/2;
		
			// for each position/z-index, detect whether or not we hit something
			// if type = airplane, ignore x-index (-1)
			var parentNode = animationList;
			var curNode = animationList.next;
			while (curNode){
				// if it hits a valid object...
				if (curNode.type < 3 && curNode.detect(this.l - this.w/2,this.t - this.h/2,this.zIndex)){
					curNode.detonate(this.l - curNode.l, this.t - curNode.t);
					this.hit = 1;
					break;
				}
				
				parentNode = curNode;
				curNode = parentNode.next;
			}
			
			if (this.hit){
				break;
			}
		}
	}
	
	// do some item-specific action
	this.doAction = function(){
		this.count -= 1;
		if (this.count < 0 || this.hit ){
			// dont subtract if we hit an object
			if (!this.hit){
				updateScore(-5000);
			}
			return 2;		// signify to insert a new item instead of waiting
		}
		
		this.zIndex += bbDirection;
		return 0;
	}
}

// special items
function projectile(x,y,ptype){

	this.ptype = ptype;
	this.idx = Math.floor(Math.random()*paint.length);	// random paint
	
	// select the type
	switch(ptype){
		case 0:
			this.item = paint[this.idx];
			break;
		case 1:
			this.item = bullet;
			break;
		case 2:
			this.item = mine;
			break;
	}
	
	this.type = 4;
		
	this.id = 'rk' + unique.next();				// id of container
	this.imgId = this.id + '-img';				// id of image (div/img)
	
	this.divCreated = 0;
	this.next = null;
	
	this.xo = x;		// destination x coord
	this.yo = y;		// destination y coord

	if (this.yo < 100){
		this.scale = 5;
	}else{ //if (this.yo < 200){
		this.scale = 10;
	}
	
	if (this.ptype == 1){
		this.scale = this.scale * 4;
	}
	
	this.count = 150;
	this.zIndex = this.count;
	this.w = 1;
	this.h = 1;
	this.l = 1;
	this.t = 1;
	
	this.hit = 0;
	
	// update animation parameters
	this.update = function(){
		
		// incrementally animate scale counts
		for (var i = 0;i< this.scale;i++){
			
			this.count -= 1;
			this.zIndex -= 1;
			
			if (this.count < 0){
				return;
			}
		
			if (this.ptype == 0 && (!(this.count % 5))){
				this.yo += 2;
			}	
		
			var d = (150 - this.count) / 13;
			// piecewise function
			var r = 2 / d;
			//paths[1][i] = [r, 300/d, 109/d ];
			
			this.h = r * this.item.image.height;
			this.w = r * this.item.image.width;
			
			this.l = this.xo - this.w/2;
			this.t = this.yo - this.h/2;
		
			// for each position/z-index, detect whether or not we hit something
			// if type = airplane, ignore x-index (-1)
			var parentNode = animationList;
			var curNode = animationList.next;
			while (curNode){
				// if it hits a valid object... then attach something, unless there are a lot of hits -- then it should explode
				if (curNode.type < 3 && curNode.detect(this.l - this.w/2,this.t - this.h/2,this.zIndex)){
					updateScore(curNode.score()/4);
					document.getElementById('boomright').innerHTML = 
			'<h5><a href="' + curNode.item.href + '">' + curNode.item.title + '</a></h5>' + curNode.item.description;
					if (this.ptype == 1){
						// do hits, no points
						curNode.hitit(this.l - this.w/2,this.t - this.h/2);
					}
					addToQueue(new spot(curNode,this.l - this.w/2,this.t - this.h/2,this.ptype,this.idx));
					this.hit = 1;
					break;
				}
				
				parentNode = curNode;
				curNode = parentNode.next;
			}
			
			if (this.hit){
				break;
			}
		}
	}
	
	// do some item-specific action
	this.doAction = function(){
		this.count -= 1;
		if (this.count < 0 || this.hit ){
			// dont subtract if we hit an object
			if (!this.hit){
				updateScore(-5000);
			}
			return 2;		// signify to insert a new item instead of waiting
		}
		
		this.zIndex += bbDirection;
		return 0;
	}
}


// special items
function tailItem(x,y,h,w,z){

	this.item = tail;
	this.type = 4;
		
	this.id = 'rk' + unique.next();				// id of container
	this.imgId = this.id + '-img';				// id of image (div/img)
	
	this.divCreated = 0;
	this.next = null;
	
	this.count = 0;
	this.zIndex = z;
	this.w = w;
	this.h = h;
	this.l = x - w/2;
	this.t = y - h/2;
	
	// update animation parameters
	this.update = function(){
		this.t -= 1;
	}
	
	// do some item-specific action
	this.doAction = function(){
		
		this.count += 1;
		if (this.count >= 5 )
			return 2;		// signify to insert a new item instead of waiting
		
		this.zIndex += bbDirection;
		return 0;
	}
}

// special items
function spot(parent,x,y,ptype,idx){

	switch(ptype){
		case 0:
			this.item = pspot[idx];
			break;
		case 1:
			this.item = bspot;
			break;
		case 2: 
			this.item = mine;
			break;
	}
	this.ptype = ptype;
	this.type = 4;
	this.parent = parent;
	this.pid = parent.id;
		
	this.id = 'ps' + unique.next();				// id of container
	this.imgId = this.id + '-img';				// id of image (div/img)
	
	this.divCreated = 0;
	this.next = null;
	
	this.px = (x - this.parent.l) / this.parent.r;
	this.py = (y - this.parent.t) / this.parent.r;

	this.h = 1;
	this.w = 1;
	this.l = x;
	this.t = y;
	this.dead = 0;
	
	this.count = 0;
	
	// update animation parameters
	this.update = function(){
		if (!document.getElementById(this.pid)){
			this.l = 800;
			this.dead = 1;
			return;
		}
		// move everything in a manner consistant with the parent
		this.h = this.item.image.height * this.parent.r;
		this.w = this.item.image.width * this.parent.r;
		this.l = this.parent.l + (this.px * this.parent.r);
		this.t = this.parent.t + (this.py * this.parent.r);
		this.zIndex = this.parent.zIndex+2;
		
		this.pl = this.parent.l;
		this.pt = this.parent.t;
	}
	
	// do some item-specific action
	this.doAction = function(){
		if (this.dead){
			return 1;		// signify to insert a new item instead of waiting
		}
		this.count += 1;
		if (this.ptype == 2 && this.count > 20){
			this.parent.detonate(this.l - this.w/2 - this.parent.l,this.t - this.h/2 - this.parent.t);
			return 1;
		}
		return 0;
	}
}





