/**
 * Name:   Simple JavaScript pong game.
 * Author: FireFly (firefly.nu).
 * Date:   2009-08-09.
 */

var WIDTH = 800, HEIGHT = 600;	// Size of game area, in pixels.
var ball;	// Object that contains ball (see init).
var paddles;	// Array of paddle objects (see init).
	// vsComp is true if pad1 is player and pad2 is comp, false if both are player controlled.
var settings = { maxScore: 10, speed: 25, vsComp: true };
var gameInterval;
var isPlaying = false;

window.onload = init;

if (window.opera && opera.wiiremote)
	window.onmousemove = function() {
		if (isPlaying) updateCoords(); }
else
	window.onmousemove = function(ev) {
		if (isPlaying) paddles[0].moveTo(ev.pageY); }

function init() {
	WIDTH = window.innerWidth-60;
	HEIGHT = window.innerHeight-60;
	
	showNewGameBox();
}

	// For creating a new game.
function newGame() {
	settings.maxScore = parseInt(document.getElementById('settMaxPoints').value);
	settings.speed = parseInt(document.getElementById('settSpeed').value);
	settings.vsComp = document.getElementById('settVsComp').checked;
	
	ball = {	// Initialise ball object.
		x: 0, y: 0, speed: 0, width: 16, height: 16, acc: null,
		el: document.getElementById('ball'),
		update: function() {
			this.el.style.top = Math.round(this.y-this.height/2)+'px';
			this.el.style.left = Math.round(this.x-this.width/2)+'px';
		},
		move: function() {
			this.x += this.acc.x*this.speed;
			this.y += this.acc.y*this.speed;
			
			ball.speed += 0.01;
		},
		checkBorders: function() {
			if (this.x-this.width/2 < 0) {
				paddles[1].incScore();
				resetBall();
			}
			else if (this.x+this.width/2 > WIDTH) {
				paddles[0].incScore();
				resetBall();
			}
			if (this.y-this.height/2 < 0 || this.y+this.height/2 > HEIGHT)
				this.acc.y = -this.acc.y;
		},
		checkPlayers: function() {
			for (var i in paddles) {
				if (((this.x < WIDTH/2 && this.x < paddles[i].x && this.x-this.acc.x*this.speed > paddles[i].x) ||
					(this.x > WIDTH/2 && this.x > paddles[i].x && this.x-this.acc.x*this.speed < paddles[i].x))
					&& this.y-this.height/2 > paddles[i].y
					&& this.y+this.height/2 < paddles[i].y+paddles[i].height) {
					this.acc.x = -this.acc.x;
				}
			}
		}
	};
	
	paddles = [
		new Paddle(1, false, 30),
		new Paddle(2, settings.vsComp, WIDTH-30)
	];
	
	resetBall();	// Reset the ball initially.
	resumeGame();
}

	// Called if any player misses the ball (and therefore the opponent gains a point, and ball resets etc).
function resetBall() {
	ball.x = WIDTH/2;
	ball.y = HEIGHT/2;
	ball.speed = settings.speed;
	
	var startDirection = Math.random()*Math.PI*2;
	ball.acc = { x: Math.sin(startDirection), y: Math.cos(startDirection) };
	
	ball.update();
}

	// Called if any player wins, e.g. gains over 10p.
function resetGame() {
	for (var i in paddles) {
		paddles[i].score = 0;
		document.getElementById('score'+paddles[i].id).innerHTML = '0';
		
		paddles[i].height = Math.ceil(HEIGHT/5);
		paddles[i].el.style.height = Math.ceil(HEIGHT/5)+'px';
	}
}

function gameTick() {
	ball.move();
	ball.checkBorders();
	ball.checkPlayers();
	ball.update();
	
	for (var i in paddles)
		if (paddles[i].isComp)
			paddles[i].moveTo(ball.y);
}

function updateCoords() {
	for (var i=0, remote; i<2; i++) {
		remote = opera.wiiremote.update(i);
		if (remote.isEnabled && !paddles[i].isComp)
			paddles[i].moveTo(remote.dpdScreenY);
	}
}

	// Prototype for a paddle.
function Paddle(id, isComp, x) {
	this.x = x;
	this.y = 0;
	this.height = Math.ceil(HEIGHT/5);
	this.score = 0;
	this.id = id;
	this.el = document.getElementById('pad'+id);
	this.isComp = isComp;
	
	this.el.style.height = Math.round(this.height)+'px';
}
Paddle.prototype.moveTo = function(y) {
	this.y = y;
	this.el.style.top = y+'px';
	
	if (y < this.height/2)
		y = 0;
	else if (y > HEIGHT-this.height/2-6)
		y = HEIGHT-this.height-6;
	else
		y = y-this.height/2;
	
	this.y = y;
	this.el.style.top = y+'px';
}
Paddle.prototype.incScore = function() {
	this.score++;
	document.getElementById('score'+this.id).innerHTML = this.score;
	
	if (this.score >= settings.maxScore) {
		alert("Player "+this.id+" wins!");
		resetGame();
	}
	
		// For extra fun.
	this.height *= 0.96;
	paddles[this.id*-1+1] /= 0.96;
	this.el.style.height = Math.round(this.height)+'px';
}

	// Support for creating new game.
function showNewGameBox() {
	clearInterval(gameInterval);
	isPlaying = false;
	document.getElementById('newGameBox').style.visibility = 'visible';
}
function resumeGame() {
	document.getElementById('newGameBox').style.visibility = 'hidden';
	isPlaying = true;
	gameInterval = setInterval(gameTick, 20);
}
function incInputValue(id, value) {
	document.getElementById(id).value = parseInt(document.getElementById(id).value)+value;
}