//
// Copyright 2007 emopunk.net
//

var wi_spaceship_speed = 70;
var wi_spaceship_move_step_width = 10;

var wi_spaceship_missile_speed = 35;
var wi_spaceship_missile_move_step_height = 9;
var wi_spaceship_missile_height = 15;


var wi_alien_speed = 270;
var wi_alien_step_width = 10;
var wi_alien_step_height = 16;



function wi_message(msg){

	var div = document.createElement("div");
	div.style.width = wi_surface.offsetWidth + "px";
	div.style.height = wi_surface.offsetHeight + "px";
	div.style.textAlign = "center";
	div.innerHTML = msg;
	wi_surface.appendChild(div);
}

function wi_error(err){
	wi_message("<span style=\"color:red;\">"+err+"</span>");
}

function wi_end_game(){

	if(wi_moving_alien)
		window.clearInterval( wi_moving_alien );

	if(document.detachEvent){
		document.detachEvent('onkeydown', wi_keydown);
		document.detachEvent('onkeyup', wi_keyup);
	}
	else if(document.removeEventListener){
		document.removeEventListener('keydown', wi_keydown, false);
		document.removeEventListener('keyup', wi_keyup, false);
	}
}

function wi_game_over(){
	wi_end_game();
	wi_message("<span style=\"font-size:16px;font-weight:bold;\">GAME OVER</span>");
}

function wi_victory(){
	wi_end_game();
	wi_message("<span style=\"font-size:16px;font-weight:bold;\">YOU WIN</span>");
}


//
// aliens bewegen
var wi_alien_box_min_left_pos;
var wi_alien_box_max_left_pos;
var wi_alien_box_max_top_pos;
function wi_alien_mover(){


	var new_hor_pos = wi_alien_box.offsetLeft + wi_alien_step_width * wi_alien_current_direction;


	// checken ob dieser nächste schritt die grenzen sprengen würde.
	// wenn ja, bewegen wir die aliens einen schritt nach unten, statt zur seite
	// und checken auf game over
	if(	( wi_alien_current_direction > 0 && new_hor_pos > wi_alien_box_max_left_pos ) ||
		( wi_alien_current_direction < 0 && new_hor_pos < wi_alien_box_min_left_pos ) ) {

		// richtung ändern
		wi_alien_current_direction *= -1;

		// aliens einen schritt runter
		wi_alien_box.style.top = ( wi_alien_box.offsetTop + wi_alien_step_height )+ "px";

		// game over
		if( wi_alien_box.offsetTop >= wi_alien_box_max_top_pos )
			wi_game_over();
	}
	// aliens einen schritt seitwärts bewegen
	else
		wi_alien_box.style.left = new_hor_pos +"px";
}



//
// aliens an den extreme-positionen
// sie bestimmen die bewegungsgrenzen der alien-box, die selber ihre größe nicht ändert
var wi_most_left_alien = null;
var wi_most_right_alien = null;
var wi_most_bottom_alien = null;
function wi_get_most_left_alien(){

	for( var i = 0; i < wi_aliens.length; i++ ){
		if( !wi_most_left_alien || wi_aliens[i].offsetLeft < wi_most_left_alien.offsetLeft )
			wi_most_left_alien = wi_aliens[i];
	}

	wi_alien_box_min_left_pos = wi_most_left_alien.offsetLeft * -1;
}

function wi_get_most_right_alien(){

	for( var i = 0; i < wi_aliens.length; i++ ){
		if( !wi_most_right_alien || ( wi_aliens[i].offsetLeft + wi_aliens[i].offsetWidth ) > ( wi_most_right_alien.offsetLeft + wi_most_right_alien.offsetWidth ) ){
			wi_most_right_alien = wi_aliens[i];
		}
	}

	wi_alien_box_max_left_pos = wi_alien_box.offsetWidth - wi_most_right_alien.offsetLeft - wi_most_right_alien.offsetWidth;
}

function wi_get_most_bottom_alien(){

	for( var i = 0; i < wi_aliens.length; i++ ){
		if( !wi_most_bottom_alien || ( wi_aliens[i].offsetTop + wi_aliens[i].offsetHeight ) > ( wi_most_bottom_alien.offsetTop + wi_most_bottom_alien.offsetHeight ) )
			wi_most_bottom_alien = wi_aliens[i];
	}

	wi_alien_box_max_top_pos = wi_alien_box.offsetHeight - wi_most_bottom_alien.offsetTop - wi_most_bottom_alien.offsetHeight - wi_spaceship.offsetHeight;
}







function wi_spaceship_mover_left(){
	wi_spaceship_position -= wi_spaceship_move_step_width;
	if( wi_spaceship_position < wi_spaceship_min_position )
		wi_spaceship_position = wi_spaceship_min_position;
	wi_spaceship.style.left = wi_spaceship_position + "px";
}

function wi_spaceship_mover_right(){
	wi_spaceship_position += wi_spaceship_move_step_width;
	if( wi_spaceship_position > wi_spaceship_max_position )
		wi_spaceship_position = wi_spaceship_max_position;
	wi_spaceship.style.left = wi_spaceship_position + "px";
}

var wi_moving_spaceship_left = false;
var wi_moving_spaceship_right = false;

function wi_move_spaceship_left(){

	if( wi_moving_spaceship_left )
		return;

	if( wi_moving_spaceship_right )
		wi_stop_spaceship_right();

	wi_moving_spaceship_left = window.setInterval("wi_spaceship_mover_left()", wi_spaceship_speed);
	wi_spaceship_mover_left(); // ???
}

function wi_move_spaceship_right(){

	if( wi_moving_spaceship_right )
		return;

	if( wi_moving_spaceship_left )
		wi_stop_spaceship_left();

	wi_moving_spaceship_right = window.setInterval("wi_spaceship_mover_right()", wi_spaceship_speed);
	wi_spaceship_mover_right();
}

function wi_stop_spaceship_left(){
	if( wi_moving_spaceship_left ){
		window.clearInterval( wi_moving_spaceship_left );
		wi_moving_spaceship_left = false;
	}
}

function wi_stop_spaceship_right(){
	if( wi_moving_spaceship_right ){
		window.clearInterval( wi_moving_spaceship_right );
		wi_moving_spaceship_right = false;
	}
}



//
// aliens beschleunigen
// und zwar um einen faktor abhängig von der menge der aliens
function wi_speedup_aliens(){

	var a = wi_aliens.length;
	var b = a + 1;

	wi_alien_speed = Math.ceil( a / b * wi_alien_speed );

	if(wi_moving_alien)
		window.clearInterval( wi_moving_alien );
	wi_moving_alien = window.setInterval("wi_alien_mover()", wi_alien_speed );
}



function wi_hit_alien(i){

	var dead_alien = wi_aliens[i];
	wi_clear_spaceship_missile();
	wi_alien_box.removeChild( dead_alien );

	for(; i < (wi_aliens.length - 1); i++)
		wi_aliens[i] = wi_aliens[i + 1];

	wi_aliens.length--;

	if( wi_aliens.length == 0 )
		wi_victory();

	if( dead_alien == wi_most_bottom_alien ){
		wi_most_bottom_alien = null;
		wi_get_most_bottom_alien();
	}

	if( dead_alien == wi_most_left_alien ){
		wi_most_left_alien = null;
		wi_get_most_left_alien();
	}

	if( dead_alien == wi_most_right_alien ){
		wi_most_right_alien = null;
		wi_get_most_right_alien();
	}

	wi_speedup_aliens();
}


function wi_clear_spaceship_missile(){

	if( wi_moving_spaceship_missile )
		window.clearInterval( wi_moving_spaceship_missile );
	wi_moving_spaceship_missile = false;

	wi_surface.removeChild( wi_spaceship_missile );
}

function wi_spaceship_missile_mover(){

	wi_spaceship_missile_top_position -= wi_spaceship_missile_move_step_height;

	if( wi_spaceship_missile_top_position < 0 )
		wi_clear_spaceship_missile();
	else{
		// überprüfen ob eines der aliens getroffen wurde
		if( wi_spaceship_missile_top_position <= ( wi_most_bottom_alien.offsetTop + wi_most_bottom_alien.offsetHeight + wi_alien_box.offsetTop ) ){

			var alienOffsetLeft, alienOffsetTop;
			var spaceship_missile_top_plus_height = wi_spaceship_missile_top_position + wi_spaceship_missile_height;
			for( var i = (wi_aliens.length - 1); i >= 0; i-- ){

				alien = wi_aliens[i];

				alienOffsetLeft = alien.offsetLeft + wi_alien_box.offsetLeft;

				if( !( alienOffsetLeft <= wi_spaceship_missile_left_position ) )
					continue;

				if( !( wi_spaceship_missile_left_position <= ( alienOffsetLeft + alien.offsetWidth ) ) )
					continue;

				alienOffsetTop = alien.offsetTop + wi_alien_box.offsetTop;

				if( !( wi_spaceship_missile_top_position <= ( alienOffsetTop + alien.offsetHeight ) ) )
					continue;

				if( !( alienOffsetTop <= spaceship_missile_top_plus_height ) )
					continue;

				wi_hit_alien( i );
				break;
			}
		}

		wi_spaceship_missile.style.top = wi_spaceship_missile_top_position + "px";
	}
}

var wi_moving_spaceship_missile = false;
function wi_spaceship_fire(){

	if( wi_moving_spaceship_missile )
		return;

	wi_moving_spaceship_missile = true;

	wi_spaceship_missile_left_position = ( wi_spaceship_position + wi_spaceship_missile_launch_position_offset );
	wi_spaceship_missile_top_position = wi_spaceship.offsetTop - wi_spaceship_missile_height;

	wi_spaceship_missile = document.createElement("div");
	wi_spaceship_missile.style.position = "absolute";
	wi_spaceship_missile.style.left = wi_spaceship_missile_left_position + "px";
	wi_spaceship_missile.style.top = wi_spaceship_missile_top_position + "px";
	wi_spaceship_missile.style.height = wi_spaceship_missile_height + "px";
	wi_spaceship_missile.style.width = "1px";
	wi_spaceship_missile.style.backgroundColor = "lime";

	wi_surface.appendChild( wi_spaceship_missile );

	wi_moving_spaceship_missile = window.setInterval("wi_spaceship_missile_mover()", wi_spaceship_missile_speed);
}





function wi_keydown(e){

	if( !e )
		return;

	if( e.keyCode == 37 )
		wi_move_spaceship_left();

	else if( e.keyCode == 39 )
		wi_move_spaceship_right();

	else if( e.keyCode == 32 )
		wi_spaceship_fire();
}
function wi_keyup(e){

	if( !e )
		return;

	if( e.keyCode == 37 )
		wi_stop_spaceship_left();

	else if( e.keyCode == 39 )
		wi_stop_spaceship_right();
}


function wi_init(){

	alert("keys: left-key, right-key, spacebar");

	if(typeof(wi_surface) == "undefined"){
		alert("err1");
		return;
	}

	if(typeof(wi_aliens) == "undefined"){
		wi_error("err3");
		return;
	}


	if( !wi_surface.style.position || wi_surface.style.position != "absolute" )
		wi_surface.style.position = "relative";

	wi_surface.style.width = wi_surface.offsetWidth + "px";
	wi_surface.style.height = wi_surface.offsetHeight + "px";
	wi_surface.style.overflow = "hidden";


	wi_spaceship = document.createElement("div");
	wi_spaceship.style.position = "absolute";
	wi_spaceship_position = wi_surface.offsetWidth >> 1;
	wi_spaceship.style.left = wi_spaceship_position + "px";
	wi_spaceship.style.bottom = "0px";
	wi_spaceship.style.width = "40px";
	wi_spaceship.style.height = "15px";
	wi_spaceship.style.backgroundColor = "lime";

	wi_surface.appendChild(wi_spaceship);

	wi_spaceship_min_position = 0;
	wi_spaceship_max_position = wi_surface.offsetWidth - wi_spaceship.offsetWidth;
	wi_spaceship_missile_launch_position_offset = wi_spaceship.offsetWidth >> 1;


	wi_alien_box = document.createElement("div");
	wi_alien_box.style.position = "absolute";
	wi_alien_box.style.left = "0px";
	wi_alien_box.style.top = "0px";

	// für den browser ist es effizienter alle aliens in eine box zu packen und diese dann zu bewegen, statt jedes einzelne alien zu bewegen
	wi_alien_box.style.width = wi_surface.offsetWidth + "px";
	wi_alien_box.style.height = wi_surface.offsetHeight + "px";
	wi_surface.appendChild(wi_alien_box);

	var alien;
	var node;
	var offsetLeft;
	var offsetTop;
	//
	// es ist nicht sicher, ob die aliens bereits absolut positioniert sind und wie sie die umgebende seite beeinflussen.
	// daher müssen wir sie aus ihrem alten context herausholen, ohne diesen zu beeinflussen und die aliens beweglich machen.
	//
	// also ermitteln wir zunächst die position jedes einzelnen aliens in bezug auf den surface
	// dann kopieren wir das alien: wir positionieren eine kopie des aliens auf die gleich position, diesmal aber sicher _absolute_
	// und direkt unterhalb des surfaces. das ursprüngliche alien verstecken wir mit hidden, damit der context nicht beeinflusst wird.
	for(var i = 0; i < wi_aliens.length; i++){

		node = wi_aliens[i];

		offsetLeft = 0;
		offsetTop = 0;

		// wir hangeln uns nach oben, bis zum surface und addieren dabei die offsets
		// sind wir beim surface angelangt, haben die genaue position des aliens in bezug auf den surface
		while( node != wi_surface ){

			if( node.nodeType != 1 )
				break;

			offsetLeft += node.offsetLeft;
			offsetTop += node.offsetTop;

			node = node.offsetParent;
		}

		// das alien war nicht unterhalb des surfaces positioniert, das geht natürlich nicht
		if( node != wi_surface ){
			wi_error("err4");
			return;
		}

		// alien kopieren
		alien = wi_aliens[i].cloneNode(true);
		alien.style.position = "absolute";
		alien.style.left = offsetLeft + "px";
		alien.style.top = offsetTop + "px";
		//wi_surface.appendChild( alien );
		wi_alien_box.appendChild(alien);

		// original verstecken
		wi_aliens[i].style.visibility = "hidden";

		// ursprüngliches alien im array ersetzen
		wi_aliens[i] = alien;
	}




	// die extreme aliens bestimmen
	// dabei werdem gleichzeitig die grenz-position der alien-box bestimmt
	wi_get_most_left_alien();
	wi_get_most_right_alien();
	wi_get_most_bottom_alien();




	wi_alien_current_direction = 1; // 1 oder -1
	wi_moving_alien = window.setInterval("wi_alien_mover()", wi_alien_speed );


	if(document.attachEvent){
		document.attachEvent('onkeydown', wi_keydown);
		document.attachEvent('onkeyup', wi_keyup);
	}
	else if(document.addEventListener){
		document.addEventListener('keydown', wi_keydown, false);
		document.addEventListener('keyup', wi_keyup, false);
	}
	else{
		wi_error("err4");
		return;
	}
}
