/**********************************************************
Invaiders, ©Copyright 2006 - bezumie.com. All rights reserved
Íàøåñòâåíèöè, ©Copyright 2006 - bezumie.com. Âñè÷êè ïðàâà çàïàçåíè
***********************************************************/
var ship = null;
var shipw = 20;
var shiph = 20;
var shipx = 0;
var shipy = 0;
var shipdir = 0;
var shipstep = 4;
var shipsafe = 0;
var shipsafecnt = 40;

var arena = null;
var arenaw = 400;
var arenah = 250;

var running = false;
var terminate = false;

var speed = 50;

var maxfires = 4;
var firew = 8;
var fireh = 8;
var fires = new Array();
var firestep = 6;

var fire = false;

var alienw = 20;
var alienh = 20;
var aliens = new Array();
var alienstep = 3;
var alienspace = 10;
var aliendir = 2;
var alienmaxx = 0;
var alienminx = 0;
var alienmaxy = 0;
var alienstepdown = 10;

var afires = new Array();
var maxafires = 5;

var abooms = new Array();

var level = 1;
var wave = 1;
var lives = 3;

var inloop = false;

function rand(n) {
	return Math.round(Math.random() * n);
}

function delFires() {
	n = fires.length;
	for (i = 0; i < n; i ++) {
		tmp = arena.removeChild(fires[i]);
		delete tmp;
	}
	fires.length = 0;
}

function delAliens() {
	n = aliens.length;
	for (i = 0; i < n; i ++) {
		tmp = arena.removeChild(aliens[i]);
		delete tmp;
	}
	aliens.length = 0;
	alienmaxx = 0;
	alienminx = 0;
	alienmaxy = 0;
}

function delABooms() {
	n = abooms.length;
	for (i = 0; i < n; i ++) {
		t = abooms[i];
		tmp = arena.removeChild(t.el);
		delete tmp;
		delete t;
	}
	abooms.length = 0;
}

function delAFires() {
	n = afires.length;
	for (i = 0; i < n; i ++) {
		tmp = arena.removeChild(afires[i]);
		delete tmp;
	}
	afires.length = 0;
}

function findminmax() {
	alienminx = 10000;
	alienmaxy = -10000;
	alienmaxx = -10000;
	
	n = aliens.length;
	for (i = 0; i < n; i ++) {
		x = parseInt(aliens[i].style.left);
		y = parseInt(aliens[i].style.top);
		if (x < alienminx) alienminx = x;
		if (y > alienmaxy) alienmaxy = y;
		if (x > alienmaxx) alienmaxx = x;
	}
}

function makeAliens() {
	y = alienspace;
	if (level == 1) { rows = 3; cols = 4;}
	else if (level == 2) {rows = 3; cols = 6;}
	else {rows = 4; cols = 6;}
	for (j = 0; j < rows; j ++) {
		x = alienspace;
		for (i = 0; i < cols; i ++) {
			tmp = document.createElement("div");
			tmp.className = "alien";
			tmp.style.left = x + 'px';
			tmp.style.top = y + 'px';
			arena.appendChild(tmp);
			aliens.push(tmp);
			x += alienw + alienspace;
		}
		y += alienh;
	}
	
	findminmax();
}

function reset() {
	if (arena == null) {
		arena = document.getElementById('arena');
	}
	if (ship == null) {
		ship = document.createElement("div");
		ship.className = 'ship';
		arena.appendChild(ship);
	}
	shipx = Math.round((arenaw - shipw) / 2);
	shipy = (arenah - shiph);
	ship.style.left = shipx + 'px';
	ship.style.top = shipy + 'px';
	
	delFires();
	delAliens();
	delABooms();
	makeAliens();
	delAFires();
	
	maxafires = wave;
	aliendir = 2;
	shipdir = 0;
	
	shipsafe = shipsafecnt;
	ChangeShipOpacity(30);
	
	updateScore();
	showMessage(msgLevel + ' ' + ((wave - 1) * 3 + level), msgEnterToContinue);
	
	running = false;
	terminate = false;
}

function chdir(n) {
	switch (n) {
		case 1: shipdir = 1; break;
		case 2: shipdir = 2; break;
	}
}

function moveship() {
	switch (shipdir) {
		case 1: shipx -= shipstep; break;
		case 2: shipx += shipstep; break;
	}
	
	if (shipx < 0) shipx = 0;
	else if (shipx > (arenaw - shipw)) shipx = arenaw - shipw;
	
	ship.style.left = shipx + 'px';
	ship.style.top = shipy + 'px';
}

function movefires() {
	n = fires.length;
	
	for (i = 0; i < n; i ++) {
		fires[i].style.top = parseInt(fires[i].style.top) - firestep + 'px';
	}
	
	if (fire && (n < maxfires)) {
		tmp = document.createElement("div");
		tmp.className = 'myfire';
		tmp.style.left = shipx + Math.round((shipw - firew) / 2) + 'px';
		tmp.style.top = shipy - fireh + 'px';
		arena.appendChild(tmp);
		fires.push(tmp);
		n ++;
	}
	fire = false;
}

function removefire(i, n) {
	var tmp = arena.removeChild(fires[i]);
	delete tmp;
	if (n > 1)
		fires[i] = fires[n - 1];
	fires.pop();
}

function removeafire(i, n) {
	var tmp = arena.removeChild(afires[i]);
	delete tmp;
	if (n > 1)
		afires[i] = afires[n - 1];
	afires.pop();
}

function removealien(i, n) {
	var tmp = arena.removeChild(aliens[i]);
	delete tmp;
	if (n > 1)
		aliens[i] = aliens[n - 1];
	aliens.pop();
	findminmax();
}

function checkABooms() {
	n = abooms.length;
	i = 0;
	while (i < n) {
		t = abooms[i];
		t.life = t.life - 1;
		if (t.life <= 0) {
			tmp = arena.removeChild(t.el);
			delete tmp;
			delete t;
			if (n > 1) abooms[i] = abooms[n - 1];
			abooms.pop();
			i --;
			n --;
		}
		i++;
	}
}

function makeABoom(left, top) {
	var tmp = document.createElement('div');
	tmp.className = 'aboom';
	tmp.style.left = left;
	tmp.style.top = top;
	arena.appendChild(tmp);
	var obj = new Object();
	obj.el = tmp;
	obj.life = 20;
	abooms.push(obj);
}

function checkCollisions() {
	n = fires.length;
	i = 0;
	while (i < n) {
		x = parseInt(fires[i].style.left);
		y = parseInt(fires[i].style.top);
		
		an = aliens.length;
		foundi = -1;
		for (ai = 0; ai < an; ai++) {
			ax = parseInt(aliens[ai].style.left);
			ay = parseInt(aliens[ai].style.top);
			if ((x < (ax + alienw)) && (y < (ay + alienh)) && (x > (ax - firew)) && (y > (ay - fireh))) {
				foundi = ai;
				break;
			}
		}
		
		foundfi = -1;
		if (foundi < 0) {
			fn = afires.length;
			for (fi = 0; fi < fn; fi++) {
				fx = parseInt(afires[fi].style.left);
				fy = parseInt(afires[fi].style.top);
				if ((x < (fx + firew)) && (y < (fy + fireh)) && (x > (fx - firew)) && (y > (fy - fireh))) {
					foundfi = fi;
					break;
				}
			}
		}
		
		if (foundi >= 0) {
			removefire(i, n);
			
			makeABoom(aliens[foundi].style.left, aliens[foundi].style.top);
			
			removealien(foundi, an);
			
			n --;
			i --;
		} else if (foundfi >= 0) {
			makeABoom(parseInt(afires[foundfi].style.left) + Math.round((firew - 20) / 2) + 'px', afires[foundfi].style.top);
			removefire(i, n);
			removeafire(foundfi, fn);
			n --;
			i --;
		} else if (y < 0) {
			removefire(i, n);
			n --;
			i --;
		}
		i ++;
	}
	
	n = afires.length;
	i = 0;
	while (i < n) {
		x = parseInt(afires[i].style.left);
		y = parseInt(afires[i].style.top);
		
		if ((x < (shipx + shipw)) && (y < (shipy + shiph)) && (x > (shipx - firew)) && (y > (shipy - fireh))) {
			if (shipsafe <= 0) {
				lives --;
				updateScore();
				shipsafe = shipsafecnt;
				makeABoom(shipx + 'px', shipy + 'px');
				ChangeShipOpacity(30);
			}
			
			removeafire(i, n);
			n --;
			i --;
		} else if (y > (arenah - fireh)) {
			removeafire(i, n);
			n --;
			i --;
		}
		
		i ++;
	}
}

function moveAliens() {
	switch (aliendir) {
		case 1: step = -alienstep; break;
		case 2: step = alienstep; break;
		default: step = 0; break;
	}
	minx = alienminx + step;
	maxx = alienmaxx + step;
	stepdown = false;
	if (minx < 0) {
		aliendir = 2;
		step = alienstep;
		stepdown = true;
	} else if (maxx > (arenaw - alienw)) {
		aliendir = 1;
		step = -alienstep;
		stepdown = true;
	}
	
	n = aliens.length;
	for (i = 0; i < n; i ++) {
		aliens[i].style.left = parseInt(aliens[i].style.left) + step + 'px';
		if (stepdown) {
			aliens[i].style.top = parseInt(aliens[i].style.top) + alienstepdown + 'px';
		}
	}
	
	if (stepdown) alienmaxy += alienstepdown;
	
	alienminx += step;
	alienmaxx += step;
}

function alienfire() {
	if ((aliens.length > 0) && (afires.length < maxafires)) {
		i = Math.round(Math.random() * (aliens.length - 1));
		tmp = document.createElement("div");
		tmp.className = 'alienfire';
		tmp.style.left = parseInt(aliens[i].style.left) + Math.round((alienw - firew) / 2) + 'px';
		tmp.style.top = parseInt(aliens[i].style.top) + alienh + 'px';
		arena.appendChild(tmp);
		afires.push(tmp);
	}
}

function moveafires() {
	n = afires.length;
	
	for (i = 0; i < n; i ++) {
		afires[i].style.top = parseInt(afires[i].style.top) + firestep + 'px';
	}
}

function moveobjects() {
	movefires();
	moveship();
	alienfire();
	moveafires();
	moveAliens();
	checkCollisions();
}

function hideMessage() {
	var msg = document.getElementById('message');
	msg.style.display = 'none';
}

function showMessage(s1, s2) {
	var msg = document.getElementById('message');
	msg.innerHTML = '<span class="big">' + s1 + '</span><br><span class="small">' + s2 + '</span>';
	msg.style.display = 'block';
}

function updateScore() {
	var score = document.getElementById('score');
	score.innerHTML = msgShips + ': ' + lives + ',  ' + msgLevel + ': ' + ((wave - 1) * 3 + level);
}

function newgame() {
	wave = 1;
	level = 1;
	lives = 3;
	reset();
}

function checkGameState() {
	var res = false
	if (alienmaxy >= 190) {
		lives --;
		res = true;
	}
	if (lives <= 0) {
		terminate = true;
		updateScore();
		showMessage(msgGameOver, '<a href="javascript:newgame();">' + msgNewGame + '</a>')
		return;
	}
	if (aliens.length <= 0) {
		level ++;
		if (level > 3) {
			level = 1;
			wave++;
			if ((wave % 3) == 1) lives ++;
		}
		
		res = true;
	}
	if (res) reset();
}

function ChangeShipOpacity(n) {
	if (n == 100) src = "myship.png";
	else src = "myship-sf.png";
	if (ship.filters) {
		ship.filters(0).src = src;
	} else {
		ship.style.background = "url('" + src + "')";
	}
}

function loop() {
	if (!running) return;
	if (terminate) return;
	if (!terminate)
		var id = setTimeout("loop()", speed);
	if (inloop) return;
	inloop = true;
	
	moveobjects();
	checkABooms();
	checkGameState();
	if (!running) clearTimeout(id);
	
	if (shipsafe > 0) shipsafe--;
	if (shipsafe == 0) {
		ChangeShipOpacity(100);
		shipsafe = -1;
	}
	
	inloop = false;
}

function dofire() {
	if (terminate) return;
	
	if (!running) run();
	else fire = true;
}

function run() {
	if (!running) {
		hideMessage();
		running = true;
		loop();
	}
}

function onkey(event) {
	switch (event.keyCode) {
		case 37: chdir(1); break; //left
		case 39: chdir(2); break; //right
		
		case 32: ;
		case 13: dofire(); break;
		
		case 80: 
			if (!terminate) {
				if (running) {
					running = false;
					showMessage(msgPause, msgResume);
				}
				else {
					run();
				}
			}
			break;
	}
	
	if (event.preventDefault) event.preventDefault();
    else event.returnValue = false;
}