/**************
Based on the fantastic Astroids game by Erik Rothoff.
//http://erkie.github.com/
*****************************/


//(function() {
		  		  
function SpaceShip(gscope) {
	
	/*******************************************************************************/
	//CLASSES FOR VECTOR AND LINE, MUST BE FIRST IN THE CODE
	/*******************************************************************************/
	function Vector(x, y) {
		if ( typeof x == 'Object' ) {
			this.x = x.x;
			this.y = x.y;
		} else {
			this.x = x;
			this.y = y;
		}
	};
	
	Vector.prototype = {
		cp: function() {
			return new Vector(this.x, this.y);
		},
		
		mul: function(factor) {
			this.x *= factor;
			this.y *= factor;
			return this;
		},
		
		mulNew: function(factor) {
			return new Vector(this.x * factor, this.y * factor);
		},
		
		add: function(vec) {
			this.x += vec.x;
			this.y += vec.y;
			return this;
		},
		
		addNew: function(vec) {
			return new Vector(this.x + vec.x, this.y + vec.y);
		},
		
		sub: function(vec) {
			this.x -= vec.x;
			this.y -= vec.y;
			return this;
		},
		
		subNew: function(vec) {
			return new Vector(this.x - vec.x, this.y - vec.y);
		},
		
		// angle in radians
		rotate: function(angle) {
			var x = this.x, y = this.y;
			this.x = x * Math.cos(angle) - Math.sin(angle) * y;
			this.y = x * Math.sin(angle) + Math.cos(angle) * y;
			return this;
		},
		
		// angle still in radians
		rotateNew: function(angle) {
			return this.cp().rotate(angle);
		},
		
		// angle in radians... again
		setAngle: function(angle) {
			var l = this.len();
			this.x = Math.cos(angle) * l;
			this.y = Math.sin(angle) * l;
			return this;
		},
		
		// RADIANS
		setAngleNew: function(angle) {
			return this.cp().setAngle(angle);
		},
		
		setLength: function(length) {
			var l = this.len();
			if ( l ) this.mul(length / l);
			else this.x = this.y = length;
			return this;
		},
		
		setLengthNew: function(length) {
			return this.cp().setLength(length);
		},
		
		normalize: function() {
			var l = this.len();
			this.x /= l;
			this.y /= l;
			return this;
		},
		
		normalizeNew: function() {
			return this.cp().normalize();
		},
		
		angle: function() {
			return Math.atan2(this.x, this.y);
		},
		
		collidesWith: function(rect) {
			return this.x > rect.x && this.y > rect.y && this.x < rect.x + rect.width && this.y < rect.y + rect.height;
		},
		
		len: function() {
			var l = Math.sqrt(this.x * this.x + this.y * this.y);
			if ( l < 0.005 && l > -0.005) return 0;
			return l;
		},
		
		is: function(test) {
		
			return typeof test == 'object' && this.x == test.x && this.y == test.y;
		},
		
		toString: function() {
			return '[Vector(' + this.x + ', ' + this.y + ') angle: ' + this.angle() + ', length: ' + this.len() + ']';
		}
	};
	
	function Line(p1, p2) {
		this.p1 = p1;
		this.p2 = p2;
	};
	
	Line.prototype = {
		shift: function(pos) {
			this.p1.add(pos);
			this.p2.add(pos);
		},
		
		intersectsWithRect: function(rect) {
			var LL = new Vector(rect.x, rect.y + rect.height);
			var UL = new Vector(rect.x, rect.y);
			var LR = new Vector(rect.x + rect.width, rect.y + rect.height);
			var UR = new Vector(rect.x + rect.width, rect.y);
			
			if (
				this.p1.x > LL.x && this.p1.x < UR.x && this.p1.y < LL.y && this.p1.y > UR.y &&
				this.p2.x > LL.x && this.p2.x < UR.x && this.p2.y < LL.y && this.p2.y > UR.y
			) return true;

			if ( this.intersectsLine(new Line(UL, LL)) ) return true;
			if ( this.intersectsLine(new Line(LL, LR)) ) return true;
			if ( this.intersectsLine(new Line(UL, UR)) ) return true;
			if ( this.intersectsLine(new Line(UR, LR)) ) return true;
			return false;
		},
		
		intersectsLine: function(line2) {
			var v1 = this.p1, v2 = this.p2;
			var v3 = line2.p1, v4 = line2.p2;
			
			var denom = ((v4.y - v3.y) * (v2.x - v1.x)) - ((v4.x - v3.x) * (v2.y - v1.y));
		    var numerator = ((v4.x - v3.x) * (v1.y - v3.y)) - ((v4.y - v3.y) * (v1.x - v3.x));
		
		    var numerator2 = ((v2.x - v1.x) * (v1.y - v3.y)) - ((v2.y - v1.y) * (v1.x - v3.x));
			
			if ( denom == 0.0 ) {
				return false;
			}
			var ua = numerator / denom;
			var ub = numerator2 / denom;
			
			return (ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0);
		}
	};
	/*******************************************************************************/

	//Set scope
	var that = this;
	var globalScope = gscope
	
	/*******************************************************************************/
	//SET UP
	/*******************************************************************************/	
	var enemyWords = new Array()
	
	if(globalScope.lang == "en") {
		enemyWords[0] = "PROJECTOR IS A DIGITAL ADVERTISING AGENCY THAT BELIEVES IN INTERACTION"
		enemyWords[1] = "WE ACTIVATE BRANDS"
		enemyWords[2] = "OUR MARKETING IS BUILT ON CONVICTION"
		enemyWords[3] = "YOU SEEM TO BE THE TRIGGER HAPPY TYPE :)"
	} else {
		enemyWords[0] = "PROJECTOR ÄR EN DIGITAL REKLAMBYRÅ SOM TROR PÅ INTERAKTION"
		enemyWords[1] = "VI AKTIVERAR VARUMÄRKEN"
		enemyWords[2] = "VÅR REKLAM BYGGER PÅ ÖVERTYGELSE"
		enemyWords[3] = "DU VERKAR VARA EN VÄLDIGT SKJUTGLAD TYP :)"
	}
	
	var isIE = !!window.ActiveXObject; 
	var FPS = isIE ? 50 : 50;
	
	// configuration directives are placed in local variables
	var w = document.documentElement.clientWidth, h = document.documentElement.clientHeight;
	var playerWidth = 20, playerHeight = 30;
	
	//Create canvas
	this.canvas = document.createElement('div');
	with ( this.canvas.style ) {
		width = w + "px";
		height = (h - 50) + "px";
		position = "absolute";
		top = "0px";
		left = "0px";
		bottom = "0px";
		right = "0px";
		zIndex = "1000";
		//backgroundColor = "#EEEEEE"
	}
	$("#start").append(this.canvas)

	//Canvas for particle explosions
	this.explCanvas = document.createElement('canvas');
	this.explCanvas.setAttribute('width', w);
	this.explCanvas.setAttribute('height', h-50);
	with ( this.explCanvas.style ) {
		width = w + "px";
		height = (h - 50) + "px";
		position = "absolute";
		top = "0px";
		left = "0px";
		bottom = "0px";
		right = "0px";
		zIndex = "999";
		//backgroundColor = "#CCCCFF"
	}
	
	if ( typeof G_vmlCanvasManager != 'undefined' ) {
		this.explCanvas = G_vmlCanvasManager.initElement(this.explCanvas);
		if ( ! this.explCanvas.getContext ) {
			//alert("So... you're using IE?  Please join me at http://github.com/erkie/erkie.github.com if you think you can help");
		}
	} else {
		if ( ! this.explCanvas.getContext ) {
			//alert('This program does not yet support your browser. Please join me at http://github.com/erkie/erkie.github.com if you think you can help');
		}
	}

	$("#start").append(this.explCanvas);
	this.ctx = this.explCanvas.getContext("2d");

	$("#spaceship").css("left", (w*.5 - 19) + "px")
	
	//Set vars
	this.pos = new Vector($("#spaceship").position().left, $("#spaceship").position().top);
	this.vel = new Vector(0, 0);
	this.dir = new Vector(0, -1);
	
	// units/second
	var acc           = 300;
	var maxSpeed      = 600;
	var rotSpeed      = 360; // one rotation per second
	var bulletSpeed   = 200;
	var particleSpeed = 400;
	
	var timeBetweenFire = 250; // how many milliseconds between shots
	var timeBetweenBlink = 250; // milliseconds between enemy blink
	var timeBetweenEnemyUpdate = 400;
	var bulletRadius = 2;
	var maxParticles = isIE ? 10 : 40;
	var maxBullets = isIE ? 10 : 10;
	
	this.firedAt = false;
	this.isFiring = false
	this.bullets = [];
	this.particles = [];
	this.scrollPos = new Vector(0, 0);
	
	var isRunning = false;
	var lastUpdate = new Date().getTime();
	var hasKilled = false;
	
	// Enemies lay first in this.enemies, when they are shot they are moved to this.dieing
	this.enemies = [];
	this.dieing = [];
	this.totalEnemies = 0;
	this.lastX
	
	
	var enemyHeadlineNr = 0
	function createEnemies() {
		$("#spaceenemies").css("display", "none")
		$("#spaceenemies").empty()
		this.dieing = []
		var wordArr = enemyWords[enemyHeadlineNr].split(" ")
		for(var i=0; i< wordArr.length; i++) {
			$("#spaceenemies").append("<span>" + wordArr[i] + "</span> ")
		}
		Cufon.replace('#spaceenemies');
		
		enemyHeadlineNr++
		if(enemyHeadlineNr == enemyWords.length) {
			enemyHeadlineNr = 0
		}
		
		$("#spaceenemies:hidden:first").fadeIn(200)
	}
	
	createEnemies()
	
	function updateEnemyIndex() {
		for ( var i = 0, enemy; enemy = that.enemies[i]; i++ ) {
			removeClass(enemy, "ASTEROIDSYEAHENEMY");
		}

		var all = $("#spaceenemies").children() 

		that.enemies = [];
		for ( var i = 0; i < all.length; i++ ) {
			if(all[i].tagName == "SPAN") {
				all[i].aSize = size(all[i]);
				that.enemies.push(all[i]);				
				addClass(all[i], "ASTEROIDSYEAHENEMY");
				
				// this is only for enemycounting
				if ( ! all[i].aAdded ) {
					all[i].aAdded = true;
					that.totalEnemies++;
				}
			}
		}
	};
	//wait for cufon to genereta "enemy tags"
	setTimeout(updateEnemyIndex, 1000)
	
	this.updated = {
		enemies: new Date().getTime(), // the time before the enemyIndex was last updated
		flame: new Date().getTime(), // the time the flame was last updated
		blink: {time: 0, isActive: false}
	};
		
	//Create the ship
	$("#spaceship").bind('mouseover', showinfo);	
	$("#spaceship").bind('mouseout', hideinfo);	
	$("#spaceship").bind('mousedown', startDrag);				
	$("#spaceship").bind('mouseup', stopDrag);	
	$("#spaceship").draggable({ axis: 'x' });
	
	function showinfo(e) {		
		globalScope.showGameInfo()
	}
	
	function hideinfo(e) {		
		globalScope.hideGameInfo()
	}
	
	
	function startDrag(e) {		
	
		if(isIpadComp) {
			globalScope.showGameInfo()
		}
		globalScope.isPlayingGame = true
		this.lastX = $("#spaceship").position().left
		that.isFiring = true
	}
	
	function stopDrag(e) {
		if(this.lastX == $("#spaceship").position().left)
		fireShot()
		that.isFiring = false
		globalScope.isPlayingGame = false
	}
	
	function init() {
		$("body").bind('mouseup', function() {that.isFiring = false;globalScope.isPlayingGame = false});	
		isRunning = true
		setTimeout(updateFunc, 16);
	}
	this.init = init;

	
	/*******************************************************************************/
	//Handle events
	/*******************************************************************************/
	// Taken from:
	// http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html
	function addEvent( obj, type, fn ) {
		if (obj.addEventListener)
			obj.addEventListener( type, fn, false );
		else if (obj.attachEvent) {
			obj["e"+type+fn] = fn;
			obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
			obj.attachEvent( "on"+type, obj[type+fn] );
		}
	}

	function removeEvent( obj, type, fn ) {
		if (obj.removeEventListener)
			obj.removeEventListener( type, fn, false );
		else if (obj.detachEvent) {
			obj.detachEvent( "on"+type, obj[type+fn] );
			obj[type+fn] = null;
			obj["e"+type+fn] = null;
		}
	}
	

	var eventResize = function() {
		w = document.documentElement.clientWidth;
		h = document.documentElement.clientHeight;
		
		that.explCanvas.setAttribute('width', w);
		that.explCanvas.setAttribute('height', h-50);
	
		that.explCanvas.style.width = w + "px";
		that.explCanvas.style.height = (h-50) + "px"
		
		that.canvas.style.height = (h-50)  + "px"
		that.canvas.style.width = w  + "px"
		
	};
	addEvent(window, 'resize', eventResize);
	
	/*******************************************************************************/
	//MISC FUNCTIONS
	/*******************************************************************************/	
	function size(element) {
		var el = element, left = 0, top = 0;
		do {
			left += el.offsetLeft || 0;
			top += el.offsetTop || 0;
			el = el.offsetParent;
		} while (el);

		return {x: left, y: top, width: element.offsetWidth || 10, height: element.offsetHeight || 10};				
	};
	
	// taken from MooTools Core
	function addClass(element, className) {
		if ( element.className.indexOf(className) == -1)
			element.className = (element.className + ' ' + className).replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '');
	};
	
	// taken from MooTools Core
	function removeClass(element, className) {
		element.className = element.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1');
	};
		
	var shakeInterval;
	var shakeCount = 4
	var shakeElement;
	
	function shake(el,count) {
		el.style.position = "relative"
		el.style.left = "0px"
		el.style.top =  "0px"
		shakeElement = el
		if (shakeCount <=0 ) shakeCount = 4;
		setTimeout(MovePos,20, el);
	}
	
	function MovePos(el) {
		el = shakeElement
		//el.style.left = (parseInt(el.style.left) + 3) + "px"
		el.style.top = (parseInt(el.style.top) - 2) + "px"
		setTimeout(MoveNeg,20, el);
	}
	
	function MoveNeg(el) {
		el = shakeElement
		//el.style.left = (parseInt(el.style.left) - 3) + "px"
		el.style.top = (parseInt(el.style.top) + 2) + "px"
		
		if (--shakeCount > 0) {
		  setTimeout(MovePos,20, el);
		}
	}
	
	function addParticles(startPos) {
		var time = new Date().getTime();
		var amount = maxParticles;
		for ( var i = 0; i < amount; i++ ) {
			that.particles.push({
				// random direction
				dir: (new Vector(Math.random() * 20 - 10, Math.random() * 20 - 10)).normalize(),
				pos: startPos.cp(),
				oPos: startPos.cp(),
				cameAlive: time
			});
		}
	};
	
	/***********************
	// CANVAS DRAWING
	*********************************************/
	this.ctx.clear = function() {
		this.clearRect(0, 0, w, h);
	};	
	this.ctx.clear();
	
	this.ctx.drawLine = function(xFrom, yFrom, xTo, yTo) {
		this.beginPath();
		this.moveTo(xFrom, yFrom);
		this.lineTo(xTo, yTo);
		this.closePath();
		this.stroke();
	};
	
	this.ctx.drawRect = function(rect) {
		var old = this.strokeStyle;
		this.strokeStyle = "#00c8fa";
		this.strokeRect(rect.x, rect.y, rect.width, rect.height);
		this.strokeStyle = old;
	};
	
	this.ctx.drawLineFromLine = function(line) {
		var oldC = this.strokeStyle;
		this.strokeStyle = "green";
		this.drawLine(line.p1.x, line.p1.y, line.p2.x, line.p2.y);
		this.strokeStyle = oldC;
	};
	
	this.ctx.drawParticle = function(particle) {
		var oldColor = this.strokeStyle;
		this.strokeStyle = "#00c8fa" //randomParticleColor();
		this.drawLine(particle.pos.x, particle.pos.y, particle.pos.x - particle.dir.x * 10, particle.pos.y - particle.dir.y * 10);
		this.strokeStyle = oldColor;
	};

	/*******************************************************************************/
	// FIRE
	/*******************************************************************************/

	function fireShot() {
		
		if(isIpadComp) {
			globalScope.showGameInfo()
		}

		if(hasSound)
		shotSound.play();

			var nowTime = new Date().getTime();
		//if(nowTime - this.firedAt > timeBetweenFire) {
			that.bullets.push({
				'el': createBullet(),			  
				'dir': that.dir.cp(),
				'pos': new Vector(that.pos.x + 15, that.pos.y - 4), //that.pos.cp(),
				'startVel': that.vel.cp(),
				'cameAlive': nowTime
			});
	
			that.firedAt = nowTime;
			
			if ( that.bullets.length > maxBullets ) {
				that.canvas.removeChild(that.bullets[0].el)
				arrayRemove(that.bullets, 0);
			}
			
			
		//}
	}
	
	function createBullet() {
		var bullet = document.createElement('div');
		with ( bullet.style ) {
			width = "5px";
			height = "10px";
			position = "absolute";
			top = "0px";
			left = "0px";
			backgroundColor = "#FFFFFF";
		}
		$(that.canvas).append(bullet)
		return bullet;
		
	}	

	/*******************************************************************************/
	//AUDIO
	/*******************************************************************************/
	var hasSound = false

	if((typeof Audio == "function" || typeof Audio == "object") && !isIpadComp) {		
		
		
		hasSound  = true

		var shotSound = new Audio();		
		var canOgg = shotSound.canPlayType("audio/ogg");
		
		if(canOgg )
		shotSound.src = "/_site/sounds/shot.ogg"
		else
		shotSound.src = "/_site/sounds/shot.wav"

		
		var hitSound = new Audio();
		
		if(canOgg )
		hitSound.src = "/_site/sounds/hit.ogg"
		else
		hitSound.src = "/_site/sounds/hit.wav"
		
		var killSound  = new Audio();
		
		if(canOgg )
		killSound.src = "/_site/sounds/explode.ogg"
		else
		killSound.src = "/_site/sounds/explode.wav"
		
	}
	
	/*******************************************************************************/
	//TICKER
	/*******************************************************************************/
	var FRAME_TIMES = [];
	var ctr = 0;
	var clearCanvas = false
	this.update = function() {
		
		if(isRunning) {
			var forceChange = false;
			var nowTime = new Date().getTime();
			var tDelta = (nowTime - lastUpdate) / 1000;
			lastUpdate = nowTime;
			
			this.pos.x = $("#spaceship").position().left
			this.pos.y = $("#spaceship").position().top
			
			// update positions of bullets
			for ( var i = 0; i < this.bullets.length; i++ ) {
				// bullets should only live for 2 seconds
				if ( nowTime - this.bullets[i].cameAlive > 2000 ) {
					that.canvas.removeChild(this.bullets[i].el)
					arrayRemove(this.bullets, i);				
					i--;
					forceChange = true;
					continue;
				}						
				
				var bulletVel = this.bullets[i].dir.setLengthNew(bulletSpeed * tDelta).add(this.bullets[i].startVel.mulNew(tDelta));
				this.bullets[i].pos.add(bulletVel);
	
				var ray = new Line(this.bullets[i].pos.cp(), this.bullets[i].pos.addNew(bulletVel));
				ray.shift(this.scrollPos);
				
				this.bullets[i].pos.add(bulletVel);
				//boundsCheck(this.bullets[i].pos);
				
				// check collisions
		
				var didKill = false;
				var currSize;
				for ( var x = 0, enemy; enemy = this.enemies[x]; x++ ) {
					if ( ray.intersectsWithRect(enemy.aSize) ) {
						hasKilled = true;
						
						// move to dieing
						if(enemy.style.fontSize == "")
						currSize = 50
						else
						currSize = parseInt(enemy.style.fontSize)
						
						if(currSize > 20) {
							enemy.style.fontSize = (currSize - 6) + "px";	
							shake(enemy)
							Cufon.replace('#spaceenemies');
							
							if(hasSound)
							hitSound.play();
						
						} else {
							this.dieing.push(enemy);
							$(enemy).parent()[0].removeChild(enemy)
							arrayRemove(this.enemies, x);
							
							this.ctx.clear()
							this.particles = []
							addParticles(this.bullets[i].pos);
							
							if(this.totalEnemies == this.dieing.length)
							setTimeout(createEnemies, 1000)
							
							if(hasSound)
							killSound.play();
						}
						
						// the shot was a kill
						didKill = true;
						
						break;
					}
				}
				
				// If it hit something the bullet should go down with it
				if ( didKill ) {
					that.canvas.removeChild(this.bullets[i].el)
					arrayRemove(this.bullets, i);
					i--;
					continue;
				}
		
			}
			
			// update particles position
			for ( var i = 0; i < this.particles.length; i++ ) {
				this.particles[i].pos.add(this.particles[i].dir.mulNew(particleSpeed * tDelta * Math.random()));
				
				if ( nowTime - this.particles[i].cameAlive > 500 ) {
					arrayRemove(this.particles, i);
					this.ctx.clear()
					i--;
					forceChange = true;
					continue;
				}
			}
			
			if ( forceChange || this.bullets.length != 0 || this.particles.length != 0 || ! this.pos.is(this.lastPos) || this.vel.len() > 0 ) {
				
				// draw bullets						
				for (i = this.bullets.length-1; i >= 0; i-- ) { 
					this.bullets[i].el.style.top = this.bullets[i].pos.y + "px"
					this.bullets[i].el.style.left = this.bullets[i].pos.x + "px"
				}		
				
				// draw particles			
				if(this.particles.length > 0)
				this.ctx.clearRect(this.particles[0].oPos.x - 100, this.particles[0].oPos.y - 100, 200, 200);
				
				for ( var i = 0; i < this.particles.length; i++ ) {
					this.ctx.drawParticle(this.particles[i]);
				}
			} 
			
			updateEnemyIndex()
	
			setTimeout(updateFunc, 16);
		}
		
	}
	// Start timer
	var updateFunc = function() {
		that.update.call(that);
	};

	/*******************************************************************************/
	//CLEAR ALL
	/*******************************************************************************/
	function destroy() {
		$("body").unbind('mouseup', function() {that.isFiring = false;globalScope.isPlayingGame = false});
		$("#gameinstructions").css("visibility", "hidden")
		isRunning = false;
	};
	this.destroy = destroy;
	
	/*******************************************************************************/
	//Utility funcs
	/*******************************************************************************/
	function arrayRemove(array, from, to) {
		var rest = array.slice((to || from) + 1 || array.length);
		array.length = from < 0 ? array.length + from : from;
		return array.push.apply(array, rest);
	};
	
	/*******************************************************************************/
	//MATHS
	/*******************************************************************************/
	function random(from, to) {
		return Math.floor(Math.random() * (to + 1) + from);
	};	
	
	function hideCanvas()
	{
		$(this.explCanvas).hide()
		destroy()
	}
	this.hideCanvas = hideCanvas;
	
	function showCanvas()
	{
		$(this.explCanvas).show()
		init()
	}
	this.showCanvas = showCanvas;
}

function initSpaceShip(gscope) {
	
	gscope.miniGame  = new SpaceShip(gscope);
	startTheGame()
	
	/*
	if ( window.ActiveXObject ) {
		try {
			var xamlScript = document.createElement('script');
			xamlScript.setAttribute('type', 'text/xaml');
			xamlScript.textContent = '<?xml version="1.0"?><Canvas xmlns="http://schemas.microsoft.com/client/2007"></Canvas>';
			document.getElementsByTagName('head')[0].appendChild(xamlScript);
		} catch ( e ) {}
		
		var script = document.createElement("script");
		script.setAttribute('type', 'text/javascript');
		script.onreadystatechange = function() {
			if ( script.readyState == 'loaded' || script.readyState == 'completed' ) {				
				gscope.miniGame = new SpaceShip(gscope);					
				startTheGame()
			}
		};
		script.src = "_site/js/excanvas.js";    
		document.getElementsByTagName('head')[0].appendChild(script);
	}
	else  {
		gscope.miniGame  = new SpaceShip(gscope);
		startTheGame()
	}
	*/
}



