/* Playing field information */
var fieldobj;
var fieldLeft = 150;
var fieldTop = 300;
var fieldWidth = 250;
var fieldHeight = 450;
var gameRunning = 0;
var gamePaused = 0;
var levelThresholdY = 100;
var spawnThresholdY = 50;
var blockThresholdY = 400;

/* Individual ship information */
var shipWidth = 5;
var shipHeight = 5;
var shipSpeed = 3;
var maxSpawnDelay = 5000; /* ms */

/* Ship aggregate information */
var shipCount = 30;
var activeShips;
var shipsY;
var shipsX;
var shipobjs;

/* User ship information */
var myobj;
var myWidth = 5;
var myHeight = 5;
var myX = 0;
var myY = 0;
var myDX = 0;
var myDY = -1;
var mySpeed = 2;
var myActive = 0;

/* Level */
var levelobj;
var currLevel = 1;
var maxLevel = 10;

/* Score */
var scoreobj;
var scoreinc = 1;
var currScore = 0;
var scoredata; /* XML */

/* Controls */
var uprightobj;
var upleftobj;
var downrightobj;
var uprightobj;

/* Info board */
var infoobj;

/* Menu */
var menuobj;

/* The name of the player */
var inputobj;
var playernameobj;
var playername;

/* Highscore display */
var highscoreobj;
var hsheader;

// Initialize the game field (one time only)
function initGame( gameField )
{
	fieldobj = document.getElementById(gameField);
	shipobjs = new Array();
	activeShips = new Array();
	shipsX = new Array();
	shipsY = new Array();

	var i;
	for( i = 1; i <= shipCount; ++i )
	{
		fieldobj.innerHTML += '<div class="ship" id="ship' + i + '"></div>';
	}

	/* Get the object references of key elements */
	myobj = document.getElementById('game_me');
	infoobj = document.getElementById('game_info');
	levelobj = document.getElementById('game_level');
	scoreobj = document.getElementById('game_score');
	menuobj = document.getElementById('game_menu');
	highscoreobj = document.getElementById('game_highscores');
	inputobj = document.getElementById('game_input');
	playernameobj = document.getElementById('game_playername');

	uprightobj = document.getElementById('game_upright');
	upleftobj = document.getElementById('game_upleft');
	downrightobj = document.getElementById('game_downright');
	downleftobj = document.getElementById('game_downleft');

	/* Activate the motion functions via the mouse control 
	pads and key strokes */
	document.onkeydown = moveByKey;
	uprightobj.onmouseover = moveMeUpRight;
	upleftobj.onmouseover = moveMeUpLeft;
	downrightobj.onmouseover = moveMeDownRight;
	downleftobj.onmouseover = moveMeDownLeft;

	document.getElementById('game_playgame').onclick = startGame;
	document.getElementById('game_viewscores').onclick = showScores;
	infoobj.onclick = togglePause;
	highscoreobj.onclick = showMenu;

	menuobj.style.display = 'block';

	setInterval( 'moveObjects()', 50 );
}

// Reset the field and start a new game
function startGame()
{
	resetGame();
	resetDisplay();
	gameRunning = 1;
}

// Toggle the "paused" status of a game
function togglePause()
{
	if( gamePaused == 1 ) // Resume a paused game
	{
		resetDisplay();
		gameRunning = 1;
		gamePaused = 0;
	}
	else if( gameRunning == 1 ) // Pause a running game
	{
		infoobj.innerHTML = 'Game<br />Paused';
		showInfo();
		gameRunning = 0;
		gamePaused = 1;
	}
	else
	{
		showInput();
	}
}

// Show the top scores
function showScores()
{
	menuobj.style.display = 'none';
	infoobj.style.display = 'none';
	inputobj.style.display = 'none';
	highscoreobj.style.display = 'block';
}

// Show the menu
function showMenu()
{
	menuobj.style.display = 'block';
	infoobj.style.display = 'none';
	inputobj.style.display = 'none';
	highscoreobj.style.display = 'none';
}

// Show the info box
function showInfo()
{
	menuobj.style.display = 'none';
	infoobj.style.display = 'block';
	inputobj.style.display = 'none';
	highscoreobj.style.display = 'none';
}

// Show the name input form
function showInput()
{
	menuobj.style.display = 'none';
	infoobj.style.display = 'none';
	inputobj.style.display = 'block';
	highscoreobj.style.display = 'none';
	playernameobj.focus();
}

// Reset all dialog boxes
function resetDisplay()
{
	menuobj.style.display = 'none';
	infoobj.style.display = 'none';
	inputobj.style.display = 'none';
	highscoreobj.style.display = 'none';
}

// Stop the game
function endGame()
{
	gameRunning = 0;
}

// Reset all game information
function resetGame()
{
	infoobj.style.display = 'none';
	levelobj.innerHTML = 'Level: 1';
	scoreobj.innerHTML = 'Score: 0';
	currLevel = 1;
	currScore = 0;
	scoreinc = 1;
	shipSpeed = 3;
	placeMe();

	var blue;
	var red;
	var green;
	for( i = 1; i <= shipCount; ++i )
	{
		shipobjs[i] = document.getElementById( 'ship' + i );
		
		/* Get a random color */
		red = Math.round(Math.random() * 256);
		green = Math.round(Math.random() * 256);
		blue = Math.round(Math.random() * 256);
		shipobjs[i].style.backgroundColor = 'rgb( ' + red + ', ' + green + ', ' + blue + ' )';

		placeRandObj( i );
	}
}

// Place an enemy ship at a random location on the 
// top of the screen
function placeRandObj( ship )
{
	activeShips[ship] = 0;

	shipsX[ship] = Math.round(Math.random() * (fieldWidth - shipWidth));
	shipsY[ship] = spawnThresholdY;
	shipobjs[ship].style.left = shipsX[ship] + 'px';
	shipobjs[ship].style.top = shipsY[ship] + 'px';
	shipobjs[ship].style.visibility = 'hidden';

	setTimeout( 'initObjMove( ' + ship + ' )', Math.random() * maxSpawnDelay );
}

// Start a ship moving
function initObjMove( ship )
{
	activeShips[ship] = 1;
	shipobjs[ship].style.visibility = 'visible';
}

// Put the user's ship in a random starting location
function placeMe()
{
	myX = Math.round(Math.random() * (fieldWidth - myWidth));
	myY = fieldHeight - myHeight;
	myobj.style.left = myX + 'px';
	myobj.style.top = myY + 'px';
	myobj.style.visibility = 'hidden';

	setTimeout( 'initMe()', 0 );
}

// Make my ship visible
function initMe()
{
	myobj.style.visibility = 'visible';
}

// Move all enemy ships, move my ship, detect collisions and 
// react accordingly, update the score
function moveObjects()
{
	if( gameRunning == 1 )
	{
		moveShips();
		moveMe();
		if( detectCollision() == 1 )
		{
			youLost();
			endGame();
		}
		if( myY + shipHeight < blockThresholdY )
		{
			currScore += scoreinc;
			scoreobj.innerHTML = 'Score: ' + currScore;
		}
	}
}

// Move enemy ships
function moveShips()
{
	var i;
	for( i = 1; i <= shipCount; ++i )
	{
		if( activeShips[i] == 0 )
			continue;
		shipsY[i] += shipSpeed;

		shipobjs[i].style.top = shipsY[i] + 'px';
		if( shipsY[i] + shipHeight > blockThresholdY )
			placeRandObj( i );
	}
}

// Move my ship
function moveMe()
{
	if( myX + myDX < 0 || myX + myWidth + myDX > fieldWidth || myY + myHeight + myDY > fieldHeight )
		return;

	myX += myDX;
	myY += myDY;

	if( myY <= levelThresholdY )
	{
		increaseLevel();
		placeMe();
	}

	myobj.style.top = myY + "px";
	myobj.style.left = myX + "px";
}

// Update my current course
function setMyCoords( x, y )
{
	myDX = x;
	myDY = y;
}

// Check to see if my ship collided with any enemy ships
function detectCollision()
{
	for( i = 1; i <= shipCount; ++i )
	{
		if( myX <= shipsX[i] + shipWidth && myX + myWidth >= shipsX[i] 
				&& myY <= shipsY[i] + shipHeight && myY + myHeight >= shipsY[i] )
			return 1;
	}
	return 0;
}

// Increment the current level
function increaseLevel()
{
	if( ++currLevel > maxLevel )
	{
		youWon();
		endGame();
	}
	levelobj.innerHTML = 'Level: ' + currLevel;
	++scoreinc;
	++shipSpeed;
}

// Indicate to the user that they won the game
function youWon()
{
	infoobj.innerHTML = "You<br />Won!";
	infoobj.style.display = 'block';
}

// Indicate to the user that they lost the game
function youLost()
{
	infoobj.innerHTML = "Game<br />Over";
	infoobj.style.display = 'block';
}

// Set coords to top-right
function moveMeUpRight( evt )
{
	uprightobj.style.backgroundColor = 'navy';
	upleftobj.style.backgroundColor = '#000000';
	downrightobj.style.backgroundColor = '#000000';
	downleftobj.style.backgroundColor = '#000000';
	setMyCoords( mySpeed, -mySpeed );
}

// Set coords to top-left
function moveMeUpLeft( evt )
{
	upleftobj.style.backgroundColor = 'navy';
	uprightobj.style.backgroundColor = '#000000';
	downrightobj.style.backgroundColor = '#000000';
	downleftobj.style.backgroundColor = '#000000';
	setMyCoords( -mySpeed, -mySpeed );
}

// Set coords to bottom-right
function moveMeDownRight( evt )
{
	downrightobj.style.backgroundColor = 'navy';
	uprightobj.style.backgroundColor = '#000000';
	upleftobj.style.backgroundColor = '#000000';
	downleftobj.style.backgroundColor = '#000000';
	setMyCoords( mySpeed, mySpeed );
}

// Set coords to bottom-left
function moveMeDownLeft( evt )
{
	downleftobj.style.backgroundColor = 'navy';
	uprightobj.style.backgroundColor = '#000000';
	upleftobj.style.backgroundColor = '#000000';
	downrightobj.style.backgroundColor = '#000000';
	setMyCoords( -mySpeed, mySpeed );
}

// Check the key that was pressed, and call the 
// appropriate handler
function moveByKey( evt )
{
	var evt = (evt) ? evt : (window.event) ? event : null;

	if( evt.keyCode )
	{
		var key = evt.keyCode;
		switch( key )
		{
			case 87: // 'W'
				moveMeUpLeft( evt );
				break;
			case 69: // 'E'
				moveMeUpRight( evt );
				break;
			case 83: // 'S'
				moveMeDownLeft( evt );
				break;
			case 68: // 'D'
				moveMeDownRight( evt );
				break;
		}
	}
}

