function init(graphic_context){
	var version = navigator.userAgent;
	re = /(Firefox|Iceweasel)\/(\d)\./;
	var result = re.exec(version);
	if(!result){
		alert('I\'m sorry, you need firefox');
		return;
	}
	if( result[2] != '3'){
		var msg = 'I\'m sorry you need version 3 of firefox\n';
		msg += 'looks at the firefox homepage ';
		msg += '(it\'s a beta, use at your own risk!!!)\n\n';
		msg += 'http://www.mozilla.com/en-US/firefox/all-beta.html\n\n';
		msg += 'Debian users can look at experimental repository';
		alert(msg);
		return;
	}
	gct = graphic_context;
	Score = new score(gct);
	document.onkeydown = handle_key_down;
	document.onkeyup = handle_key_up;
	banner(gct);
	init_level(level, Score.blocks, Score);
}

function main_loop(){
	if(Score.blocks.length == 0){
		fx.ct = gct;
		fx.timeout_id = setInterval('fx.fx()',100);
		return;
	}
	Score.update_all();
	Score.draw_all();
	timeout_id = setTimeout('main_loop()',50);
}

/*this update the scene*/
function update_all(){
	Pad.update();
	bolide.update();
}

/*this draw the scene*/
function draw_all(ct){
	clear_all(ct.canvas);
	Score.blocks.forEach(function(b){b.draw(ct);});
	bolide.draw(ct);
	Pad.draw(ct);
	Score.draw(ct);
}

function clear_all(canvas){
	gct.save();
	gct.fillStyle = 'rgb(255,255,255)';
	gct.fillRect(0, 0, 400, 400);
	gct.restore();
}

function block(x, y, color, father){
	this.color = color;
	this.alpha = 0.8;
	this.x = x;
	this.y = y;
	this.width = 40;
	this.height = 15;
	/*about collision*/
	this.points = 15;
	this.hitx;
	this.hity;
	this.is_live = true;
	/*refernce to main object*/
	this.score = father;

	this.draw = function(ct){
		ct.save();
		ct.fillStyle = 'rgba(255, 0, 0,'+this.alpha+')';
		ct.fillRect(this.x, this.y, this.width, this.height);
		if(!this.is_live){
			this.alpha -= .1;
			ct.fillStyle = 'rgba(0, 0, 0,'+this.alpha+')';
			ct.translate(this.hitx, this.hity -= 5);
			ct.mozDrawText(this.points);
			if(this.alpha < 0.1)
			this.score.blocks.splice(this.score.blocks.indexOf(this),1);
		}else /*default black*/
		ct.strokeRect(this.x, this.y, this.width, this.height);
		ct.restore();
	}

	this.handle_collision = function(x, y){
		this.is_live = false;
		Score.update(this.points);
		this.hitx = x;
		this.hity = y;
	}
}

/*ball handle collision*/
function ball(prnt){
	this.x = 300;
	this.y = 300;
	this.oldx;
	this.oldy;
	this.vx = 2;
	this.vy = -2;
	this.radius = 5;
	this.color = 'rgba(0, 0, 200, .8)';
	this.score = prnt;
	this.is_on_pad = true;
	this.draw = function(ct){
		ct.save();
		ct.fillStyle = this.color;
		ct.beginPath();
		ct.arc(this.x, this.y, this.radius, 0, 2*Math.PI, false);
		ct.fill();
		ct.restore();
	}

	this.is_right_border_into_brick = function(brick){
		return (
				(this.x + this.radius) < (brick.x + brick.width)
				&&
				(this.x + this.radius) > (brick.x)
		       )
	}
	this.is_left_border_into_brick = function(brick){
		return (
				(this.x - this.radius) < (brick.x + brick.width)
				&&
				(this.x - this.radius) > (brick.x)
		       )
	}
	this.is_up_border_into_brick = function(brick){
		return(
				(this.y + this.radius) > (brick.y)
				&&
				(this.y + this.radius) < (brick.y + brick.height)
		      )
	}
	this.is_down_border_into_brick = function(brick){
		return (
				(this.y - this.radius) > (brick.y)
				&&
				(this.y - this.radius) < (brick.y + brick.height)
		       )
	}
	this.is_into_brick = function(brick){
		return(
				(	this.is_right_border_into_brick(brick)
					|| 
					this.is_left_border_into_brick(brick)
				)&&(
					this.is_up_border_into_brick(brick)
					|| 
					this.is_down_border_into_brick(brick))
		      )
	}
	this.check_collision = function(brick){
		/*check for boundary ball and boundary brick*/
		if(this.is_into_brick(brick)){
			/*very poor collision response*/
			if( 
					((this.oldx - brick.x) < 0 ) 
					|| 
					(this.oldx - (brick.x + brick.width)) > 0 
					)/*to the right*/
				this.vx = -this.vx;

			if( 
					( (this.oldy - brick.y) < 0 )
					|| 
					((this.oldy - (brick.y + brick.height)) > 0 ) 
					)
				this.vy = -this.vy;
			brick.handle_collision(this.x, this.y);
			/*you can collide with only one brick at times*/
			return true;
		}
	}

	/*update position and check for collision*/
	this.update = function(){
		if(this.is_on_pad){
			this.x = this.score.pad.x + this.score.pad.width/2;
			this.y = this.score.pad.y - this.score.pad.height/2;
			return;
		}
		if( (this.x+this.radius) > 400 || (this.x -this.radius) < 0 )
			this.vx = -this.vx;
		if( (this.y+this.radius) > 400 )
			this.score.lose_live();

		if( (this.y -this.radius) < 0 )
						this.vy = -this.vy;
		/*loop over bricks for collisions*/
		var someone_hit = false;
		for(i = 0 ; (i < this.score.blocks.length) && !someone_hit ; i++)
			someone_hit = this.check_collision(this.score.blocks[i]);
		/*check for collision with pad*/
		this.check_collision(this.score.pad);
		/*save old position*/
		this.oldx = this.x;
		this.oldy = this.y;
		/*update the ball*/
		this.x += this.vx;
		this.y += this.vy;
	}
}

/*controlled by user*/
function pad(score){
	this.x = 200;
	this.y = 350;
	this.vx = 0;
	this.width= 50;
	this.height = 10;
	this.score = score;
	this.draw = function(ct){
		ct.save();
		ct.fillStyle = 'rgba(0, 255, 0, .8)';
		ct.beginPath();
		ct.moveTo(this.x, this.y);
		ct.lineTo(this.x + this.width, this.y);
		ct.arc(this.x + this.width, this.y + this.height/2, this.height/2, 3*Math.PI/2,1/2*Math.PI, false);
		ct.arc(this.x , this.y + this.height/2, this.height/2, Math.PI/2,3/2*Math.PI, false);
		ct.closePath();
		ct.fill();
		ct.strokeStyle = 'rgba(0, 0, 0, .8)';
		ct.stroke();
		ct.restore();
	}
	this.update = function(){
		if(this.x < 0 )
			this.x -= this.x;
		else if(this.x + this.width > this.score.context.canvas.width)
			this.x -= this.x + this.width - this.score.context.canvas.width;
		else
			this.x += this.vx;
	}
	this.handle_collision = function(){
	}
	this.init = function(){
		this.x = this.score.context.canvas.width/2 - this.width/2;
	}
}

function handle_key_down(e){
	var keycode;

	if( e == null )
		keycode = window.event.KeyCode;
	else
		keycode = e.keyCode;

	switch(keycode){
		/*left*/
		case 37:
			Score.pad.vx = -5;
			break;
			/*right*/
		case 39:
			Score.pad.vx = 5;
			break;
		/*p*/
		case 80:
			if(!timeout_id)
				timeout_id = setTimeout('main_loop()',50);
			else{
				clearTimeout(timeout_id);
				timeout_id = null;
				banner(gct);
			}
			break;
		/*space*/
		case 32:
			Score.ball.is_on_pad = false;
			break;
	}
}

function handle_key_up(e){
	var keycode;

	if( e == null )
		keycode = window.event.KeyCode;
	else
		keycode = e.keyCode;

	switch(keycode){
		/*left*/
		case 37:
			Score.pad.vx = 0;
			break;
		case 39:
			Score.pad.vx = 0;
			break;
	}
}

timeout_id = null;
/*declare the bricks's array*/
var blocks = [];
var bolide = new ball();
var Pad = new pad();
var Score;
var gct;
var fx = new text_fx(gct, "Level 1 Completed");

