/*
Copyright 2004 David Finch
Last updated May, 2008
Distributed under the Revised BSD License.
*/

var alive;
var arena;
var board;
var boards;
var color;
var colors;
var counter;
var cw,ch;
var cx,cy;
var dirty;
var divs;
var idiv;
var keys;
var lastcount;
var lastdeath;
var level;
var lives;
var nextframe;
var nshape;
var parena;
var pause;
var player;
var posscores;
var pscore;
var ptime,time,dt;
var rate;
var rndstate;
var rockcolor;
var rocks;
var scale;
var score;
var seed;
var shape;
var shapec;
var shapes;
var ship;
var shipcolor;
var shipexplode;
var shotcolor;
var shots;
var speed;
var sx,sy;
var timer;
var user;
var doc=document.all?document.body:document;


function OthelloPreInit() {
	document.write('<br><br>');
	board=[];
	boards=[];
	player=1;
	user=1;
	rndstate;
	colors=["White","#bbbb77","Black"];
	timer;
	seed;
	posscores=[
		[8],
		[-4,-4],
		[5,1,5],
		[2,1,2]
	];

	document.write("<div style='margin-left:30px;width:270px;text-align:center'>");
	document.write("<table bgcolor=#aaaa66 border=1>");
	for(var y=0;y<8;y++) {
		board[y]=[];
		document.write("<tr height=32>");
		for(var x=0;x<8;x++) {
			document.write("<td id=cel"+x+"d"+y+" width=32 style='background-color: brown' onclick='usermove("+x+","+y+")'><img width=0 height=0></td>");
		}
		document.write("</tr>");
	}
	document.write("</table>");
	document.write('<span id="score"></span>');
	document.write('<br>');
	document.write('<input type="button" value="Pass or Auto" onclick="userpass()">');
	document.write('</div>');
	
}

function OthelloInit() {
	//alert("Othello Init");
	newgame();
}

function newgame() {
	if(timer) {
		clearTimeout(timer);
		timer=0;
	}
	seed=Math.floor(Math.random()*8); //randomizes behavior
	for(var x=0;x<8;x++) {
		for(var y=0;y<8;y++) {
			board[y][x]=0;
		}
	}
	board[3][3]=-1;
	board[4][4]=-1;
	board[3][4]=1;
	board[4][3]=1;
	player=1;
	update();
}


function usermove(x,y) {
	if(player!=user) return;
	if(Omove(x,y,player)) {
		player=-player;
		update();
		timer=setTimeout("think()",100);
	} else {
		//alert("illegal move "+x+", "+y);
	}
}

function el(n) {
	if(document.all) return document.all[n];
	else return document.getElementById(n);
}

function update() {
	for(var x=0;x<8;x++) {
		for(var y=0;y<8;y++) {
			el("cel"+x+"d"+y).style.backgroundColor=colors[board[x][y]+1];
		}
	}
	score();
}

function push() {
	var b=board;
	boards.push(b);
	board=[];
	for(var x=0;x<8;x++) {
		board[x]=[];
		for(var y=0;y<8;y++) {
			board[x][y]=b[x][y];
		}
	}
}

function pop() {
	board=boards.pop();
}

function score() {
	var c=[0,0,0];
	for(var x=0;x<8;x++) {
		for(var y=0;y<8;y++) {
			c[board[x][y]+1]++;
		}
	}
	el("score").innerHTML="White: "+c[0]+" &nbsp; Left: "+c[1]+" &nbsp; Black: "+c[2];
	if(c[1]==0) {
		if(c[2]>c[0]) alert("You won");
		else if(c[0]>c[2]) alert("You lost");
		else alert("It was a tie");
		newgame();
	}
}

function Omove(x,y,color) {
	if(board[x][y]) {
		return false;
	}
	var a=false;
	a=toggle(x,y,-1,0,color)||a;
	a=toggle(x,y,-1,-1,color)||a;
	a=toggle(x,y,0,-1,color)||a;
	a=toggle(x,y,1,-1,color)||a;
	a=toggle(x,y,1,0,color)||a;
	a=toggle(x,y,1,1,color)||a;
	a=toggle(x,y,0,1,color)||a;
	a=toggle(x,y,-1,1,color)||a;
	if(a) {
		board[x][y]=color;
		return true;
	} else {
		return false;
	}
}

function scoremove(rounds) {
	var p;
	var movesleft=0;
	var score=0;
	var passes=0;
	for(var x=0;x<8;x++) {
		for(var y=0;y<8;y++) {
			if(board[x][y]==0) movesleft++;
		}
	}
	for(var i=0;i<rounds;i++) {
		push();
		p=-player;
		moves=movesleft;
		passes=0;
		while(moves>0&&passes<2) {
			rndstate=i+seed+moves; //somewhat arbritrary but consistant selection of rndstate
			rndstate=rndstate^6*(rndstate&1);
			if(move4(0,0,p)||
				move8(0,2,p)||
				move8(0,3,p)||
				move4(2,2,p)||
				move8(2,3,p)||
				move8(1,2,p)||
				move8(1,3,p)||
				move8(0,1,p)||
				move4(1,1,p)) {
				moves--;
				passes=0;
			} else passes++;
			p=-p;
		}
		for(var x=0;x<8;x++) {
			for(var y=0;y<8;y++) {
				score+=board[x][y];
			}
		}
		pop();
	}
	return score*player;
}


function posscore(x,y) {
	if(x>3) x=7-x;
	if(y>3) y=7-y;
	if(x>y) return posscores[x][y];
	else return posscores[y][x];
}

function think() {
	timer=0;
	push();
	var movesleft=0;
	for(var x=0;x<8;x++) {
		for(var y=0;y<8;y++) {
			if(board[x][y]==0) movesleft++;
		}
	}

	var ms=-10000000,mx=0,my=0;
	var s;
	var moves=0;
	rounds=Math.floor(4+66/(movesleft+2));
	if(rounds>8) rounds=8;
	for(var x=0;x<8;x++) {
		for(var y=0;y<8;y++) {
			if(Omove(x,y,player)) {
				moves++;
				s=scoremove(2)+2*posscore(x,y)*movesleft/20;
				if(s>ms) {
					ms=s;
					mx=x;
					my=y;
				}
				pop();
				push();
			}
		}
	}
	pop();
	if(moves==0 && player!=user) alert("pass");
	else {
		el("cel"+mx+"d"+my).style.backgroundColor="red";
		!Omove(mx,my,player);
	}
	player=-player;
	setTimeout("update()",150);
}

/*
	// 1/8th segment of board representing the order at which oldthink() tries to move.
	1
	89
	264
	375
*/

//note that think() is optimized against this.
//so the auto-move feature will lead you to doom.
function oldthink() {
	rndstate=Math.floor(Math.random()*8); //ensures some unpredictability
	if(move4(0,0,player)||
		move8(0,2,player)||
		move8(0,3,player)||
		move4(2,2,player)||
		move8(2,3,player)||
		move8(1,2,player)||
		move8(1,3,player)||
		move8(0,1,player)||
		move4(1,1,player)
		) {
		//if(player==user) alert("are you blind?");
		player=-player;
		update();
		return true;
	} else {
		if(player!=user) alert("pass");
		player=-player;
		return false;
	}
}

function userpass() {
	if(player!=user) return;
	oldthink();
	timer=setTimeout("think()",100);
}

function move8(x,y,c) {
	if(rndstate&1)
		return move4(x,y,c)||move4(y,x,c);
	else
		return move4(y,x,c)||move4(x,y,c);

}

function move4(x,y,c) {
	//some randomization in behavior
	if(rndstate&2) x=7-x;
	if(rndstate&4) y=7-y;
	return Omove(x,y,c)||Omove(7-x,y,c)||Omove(x,7-y,c)||Omove(7-x,7-y,c);
}

function test(x,y,xa,ya,color) {
	var i=0;
	for(;;) {
		x+=xa;
		y+=ya;
		if(x<0||x>7||y<0||y>7) return false;
		if(board[x][y]==0) return false;
		if(board[x][y]==color) {
			if(i>0) return true;
			else return false;
		}
		i++;
	}
}

function toggle(x,y,xa,ya,color) {
	if(!test(x,y,xa,ya,color)) return false;
	for(;;) {
		x+=xa;
		y+=ya;
		if(x<0||x>7||y<0||y>7) break;
		if(board[x][y]!=-color) break;
		board[x][y]=color;
	}
	return true;
}



function cleararena() {
	for(var x=0;x<10;x++) {
		arena[x]=[];
		if(!parena[x]) parena[x]=[];
		for(var y=0;y<20;y++) {
			arena[x][y]=0;
		}
	}
}


function color(n) {
	return "#"+((n&4)?"ff":"00")+((n&2)?"ff":"00")+((n&1)?"ff":"00");
}

function setcolor(x,y,n) {
	el("c"+x+"n"+y).style.backgroundColor=color(n);
}

function Bupdate() {
	for(var x=0;x<10;x++) {
		for(var y=0;y<20;y++) {
			if(arena[x][y]!=parena[x][y]) {
				setcolor(x,y,arena[x][y]);
				parena[x][y]=arena[x][y];
			}
		}
	}
}

function rendershape(s) {
	var h=["<table border=0 cellspacing=1 cellpadding=0>"];
	for(var y=0;y<s[0].length;y++) {
		h.push("<tr height=5>");
		for(var x=0;x<s.length;x++) {
			var c="";
			if(s[x][y]) c=" bgcolor="+color(s[x][y]);
			h.push("<td width=5"+c+"><img width=0 height=0></td>");
		}
		h.push("</tr>");
	}
	h.push("</table>");
	return h.join("");
}

function updatestate() {
	el("state").innerHTML="Score: "+score+"<br>Next:<br>"+rendershape(nshape);
}

function rotl() {
	var o=shape;
	var n=[];
	sx+=(o.length-1)>>1;
	sy+=(o[0].length-1)>>1;
	for(var x=0;x<o[0].length;x++) {
		n[x]=[];
		for(var y=0;y<o.length;y++) {
			n[x][y]=o[o.length-y-1][x];
		}
	}
	shape=n;
	sx-=(n.length-1)>>1;
	sy-=(n[0].length-1)>>1;
}

//unused for now
function rotr() {
	var o=shape;
	var n=[];
	sx+=(o.length-1)>>1;
	sy+=(o[0].length-1)>>1;
	for(var x=0;x<o[0].length;x++) {
		n[x]=[];
		for(var y=0;y<o.length;y++) {
			n[x][y]=o[y][o[0].length-x-1];
		}
	}
	shape=n;
	sx-=(n.length-1)>>1;
	sy-=(n[0].length-1)>>1;
}


function loadshape(i) {
	//tip: never put "return" alone on a line, because semicolons are optional
	// and do-nothing expressions are perfectly legal
	switch(i) {
	case 1:return [[0,i]
		,[i,i]
		,[i,0]];
		break;
	case 2:return [[i,0]
		,[i,i]
		,[0,i]];
		break;
	case 3:return [[i,i]
		,[i,i]];
		break;
	case 4:return [[i]
		,[i]
		,[i]
		,[i]];
		break;
	case 5:return [[i,i]
		,[0,i]
		,[0,i]];
		break;
	case 6:return [[i,i]
		,[i,0]
		,[i,0]];
		break;
	case 7:return [[0,i]
		,[i,i]
		,[0,i]];
		break;
	}
}

function canfit() {
	if(sx<0 || sy<0 || sx+shape.length>10 || sy+shape[0].length>20) return false;
	for(var x=0;x<shape.length;x++){
		for(var y=0;y<shape[x].length;y++) {
			var c=shape[x][y];
			if(c) {
				if(arena[sx+x][sy+y] && (arena[sx+x][sy+y]&8)==0) {
					return false;
				}
			}
		}
	}
	return true;
}

function drawshape() {
	for(var x=0;x<shape.length;x++){
		for(var y=0;y<shape[x].length;y++) {
			var c=shape[x][y];
			if(c) {
				arena[sx+x][sy+y]=c|8;
			}
		}
	}
}

function eraseshape() {
	for(var x=0;x<shape.length;x++){
		for(var y=0;y<shape[x].length;y++) {
			var c=shape[x][y];
			if(c) {
				arena[sx+x][sy+y]=0;
			}
		}
	}
}

function lockshape() {
	for(var x=0;x<shape.length;x++){
		for(var y=0;y<shape[x].length;y++) {
			var c=shape[x][y];
			if(c) {
				arena[sx+x][sy+y]&=7;
			}
		}
	}
}

function nextshape() {
	var a,b;
	a=Math.floor(Math.random()*7)+1;
	b=Math.floor(Math.random()*7)+1;
	if(shapec[b]<shapec[a]) a=b;
	shapec[a]=(shapec[a]+(++counter))/2;
	shape=nshape;
	nshape=loadshape(a);
	sy=0;
	sx=4;
	if(shape && !canfit()) {
		updatestate();
		alert("Game over\n\nYour score: "+score);
		cleararena();
		score=0;
		shapes=0;
	}
	shapes++;
	rate=600/(1+Math.sqrt(shapes)/5);
}

function removelines() {
	var k=19;
	var s=0;
	for(var y=19;y>=0;y--) {
		if(y!=k) {
			for(var x=0;x<10;x++) {
				arena[x][k]=arena[x][y];
			}
		}
		for(var x=0;x<10;x++) {
			if(arena[x][y]==0) {
				k--;
				break;
			}
		}
	}
	while(k>=0) {
		s++;
		for(var x=0;x<10;x++) {
			arena[x][k]=0;
		}
		k--;
	}
	return s;
}


function movedown() {
	var t=1*new Date();
	if(t>=nextframe) {
		if(nextframe+rate>t) t=nextframe;
		nextframe=t+rate;
		if(pause) return;
		eraseshape();
		sy++;
		if(!canfit()) {
			sy--;
			drawshape();
			lockshape();
			score++;
			var s=removelines();
			if(s) score+=Math.pow(2,s)*5;
			status="Score: "+score;
			nextshape();
			updatestate();
		} else {
			drawshape();
		}
		dirty=true;
	}
	if(dirty) Bupdate();
}

function keypress(e) {
	e=e||event;
	var k=e.which||e.keyCode;
	eraseshape();
	
	if(k==37) {
		sx--;
		if(!canfit()) sx++;
	} else if(k==39) {
		sx++;
		if(!canfit()) sx--;
	} else if(k==38) {
		if(canfit()) {
			rotl();
			while(!canfit()) rotl();
		}
	} else if(k==40) {
		while(canfit()) sy++;
		sy--;
	} else status=""+k;
	
	drawshape();
	dirty=true;
}


function BlocksInit() {
	//alert("Blocks Init");
	nextshape();
	nextshape();
	updatestate();
	setInterval("movedown()",1);
}

function onfocus() {
	if(pause) {
		status="resumed";
		pause=false;
	}
}

function onblur() {
	status="paused";
	pause=true;
}



function BlocksPreInit() {
	arena=[];
	parena=[];

	shape=[[]];
	shapec=[0,0,0,0,0,0,0,0];
	sx=0;
	sy=0;
	score=0;
	counter=0;
	rate=600;
	nshape=[[]];
	shapes=0;
	pause=false;
	dirty=false;
	nextframe=1*new Date()+rate;



	cleararena();

	document.write("<br><br><table border=0 cellspacing=1 bgcolor=#333333 cellpadding=0 style='margin-left:30px'>");
	document.write("<tr height=50>");
	document.write("<td id='state' colspan='10' style='font-family: arial, sans-serif; font-weight:700; font-size:8pt; color: white;' valign='top' align='center'>&nbsp;</td>");
	document.write("</tr>");

	for(var y=0;y<20;y++) {
		document.write("<tr height=12>");
		for(var x=0;x<10;x++) {
			document.write("<td id='c"+x+"n"+y+"' style='width:12px;height:12px;background-color:black'><img width=0 height=0></td>")
			parena[x][y]=0;
		}
		document.write("</tr>");
	}
	document.write("</table>");


	//doc.onload=init; //Mozilla would unpredictably not fire the onload event from here. Not sure why.
	doc.onkeydown=keypress;
	doc.onfocus=onfocus;
	doc.onblur=onblur;
}












//class Ship
function Ship() {
	this.x=cw/2;
	this.ax=0;
	this.y=ch/2;
	this.ay=0;
	this.w=scale*1.5; //w and h are only used for wrapping
	this.h=scale*1.5;
	this.d=0;
	this.ad=0;
	this.draw=drawship;
	this.move=moveobject;
	this.color=shipcolor;
}

//class Rock
function Rock(_x,_y,size) {
	this.x=_x;
	this.ax=0;
	this.y=_y;
	this.ay=0;
	this.w=size;
	this.h=size;
	this.draw=drawrock;
	this.move=moveobject;
	this.color=rndcolor("bb","66");
}

//class Shot
function Shot(_x,_y) {
	this.x=_x;
	this.ax=0;
	this.y=_y;
	this.ay=0;
	this.w=.1*scale;
	this.h=.1*scale;
	this.draw=drawshot;
	this.move=moveobject;
	this.color=shotcolor;
	this.life=30;
}




function show(e) {
	e.style.visibility="visible";
}

function hide(e) {
	e.style.visibility="hidden";
}

function startframe() {
	idiv=0;
}


function endframe() {
	//only shows or hides when needed

	var m=idiv<divs.length?idiv:divs.length;
	for(var i=lastcount;i<m;i++) {
		show(divs[i]);
	}
	while(m<lastcount) {
		hide(divs[m++]);
	}
	lastcount=idiv;
}

//returns next div in th store.
//fails gracefully by reusing every other div when it runs out
function ndiv() {
	var d=divs[idiv%divs.length];
	idiv=idiv+1+Math.floor(idiv/divs.length);
	return d;
}

function move(e,x,y,w,h) {
	//try {
	e.style.left=x;
	e.style.top=y;
	e.style.width=w;
	e.style.height=h;
	//} catch(e) {
	//alert([x,y,w,h].join(", "));
	//}
	e.style.backgroundColor=color;
}

//draws horizontal line with appropriate wrapping.
function hline(x,y,x2) {
	if(x2<x) return hline(x2,y,x); //the lazy swap
	y=wrap(y,ch);
	x=Math.floor(x);
	x2=Math.floor(x2);
	if(x2<0) {
		x=wrap(x,cw);
		x2=wrap(x2,cw);
	} else if(x<0) {
		hline(wrap(x,cw),y,cw-1);
		x=0;
	}
	if(x>=cw) {
		x=wrap(x,cw);
		x2=wrap(x2,cw);
	} else if(x2>=cw) {
		hline(0,y,wrap(x2,cw));
		x2=cw-1;
	}	
	move(ndiv(),x,y,x2-x+1,1);
}

function box(x,y,x2,y2) {
	//alert([x,y,x2,y2].join(":"));
	if(x2<x) return box(x2,y,x,y2); 
	if(y2<y) return box(x,y2,x2,y); 
	y=Math.floor(y);
	y2=Math.floor(y2);
	x=Math.floor(x);
	x2=Math.floor(x2);
	if(x2<0) {
		x=wrap(x,cw);
		x2=wrap(x2,cw);
	} else if(x<0) {
		box(wrap(x,cw),y,cw-1,y2);
		x=0;
	}
	if(x>=cw) {
		x=wrap(x,cw);
		x2=wrap(x2,cw);
	} else if(x2>=cw) {
		box(0,y,wrap(x2,cw),y2);
		x2=cw-1;
	}
	if(y2<0) {
		y=wrap(y,ch);
		y2=wrap(y2,ch);
	} else if(y<0) {
		box(x,wrap(y,ch),x2,ch-1);
		y=0;
	}
	if(y>=ch) {
		y=wrap(y,ch);
		y2=wrap(y2,ch);
	} else if(y2>=ch) {
		box(x,0,x2,wrap(y2,ch));
		y2=ch-1;
	}	
	move(ndiv(),x,y,x2-x+1,y2-y+1);
}

function rndcolor(a,b) {
	if(!a) a="ff";
	if(!b) b="00";
	var i=Math.floor(rnd(7))+1;
	return "#"+(i&4?a:b)+(i&2?a:b)+(i&1?a:b);

}

//a quick hack: if the top x's don't meet, it skips the first line
//forgot the name for this shape I learned in elementary school.
function section(x1,x2,y1, x3,x4,y2) {
	if(y1>y2) return section(x3,x4,y2,x1,x2,y1); //another lazy swap
	if(y1==y2) {
		hline((x1+x2)/2,y1,(x3+x4)/2);
		return;
	}
	for(var y=y1+((x1!=x2)?1:0);y<=y2;y++) {
		var a=(y-y1)/(y2-y1);
		hline(x1+(x3-x1)*a,y,x2+(x4-x2)*a);
	}
}

function triangle(x1,y1, x2,y2, x3,y3) {
	//more lazy swaps
	if(y1>y2) return triangle(x2,y2,x1,y1,x3,y3);
	if(y3<y2) return triangle(x1,y1,x3,y3,x2,y2);
	if(y3==y1) {
		var a=x1,b=x1;
		if(x2<a) a=x2;
		if(x3<a) a=x3;
		if(x2<b) b=x2;
		if(x3<b) b=x3;
		hline(a,y1,b);
		return;
	}
	//scanline renderer depends on these being integer
	y1=Math.floor(y1);	
	y2=Math.floor(y2);	
	y3=Math.floor(y3);	

	var x=x1+(x3-x1)*(y2-y1)/(y3-y1);
	section(x1,x1,y1, x,x2,y2);
	section(x,x2,y2, x3,x3,y3);
}

function wrap(x,m) {
	if(x<0) x+=m;
	else if(x>=m) x-=m;
	return x;
}

function wrapdist(a,b,m) {
	return (b-a+m*1.5)%m-m/2;
}

//performs reduced bounding rectangle test, taking
//into account that objects wrap around the screen.
//object x,y coordinates represent their centers.
function collides(a,b,r) {
	if(!r) r=0.8;
	return Math.abs(wrapdist(a.x,b.x,cw))<(a.w+b.w)*r/2
		&& Math.abs(wrapdist(a.y,b.y,cw))<(a.h+b.h)*r/2;
}

function mcollides(a,b) {
	for(i=0;i<b.length;i++) if(collides(a,b[i])) return true;
	return false;
}

function drawship() {
	color=this.color;
	var r=this.d*3.14159265/180;
	var s=Math.sin(r);
	var c=Math.cos(r);
	
	var x1=this.x+scale*s;
	var y1=this.y-scale*c;
	
	var x2=this.x-scale/2*s+scale/2*c;
	var y2=this.y+scale/2*c+scale/2*s;

	var x3=this.x-scale/2*s-scale/2*c;
	var y3=this.y+scale/2*c-scale/2*s;
	triangle(x1,y1,x2,y2,x3,y3);
}

function drawrock() {
	color=this.color;
	box(this.x-this.w/3,this.y-this.w/2,this.w/4+this.x,this.h/2+this.y);
	box(this.x-this.w/2,this.y-this.w/3,this.w/2+this.x,this.h/4+this.y);
}

function drawshot() {
	color=this.color;
	box(this.x-this.w/2,this.y-this.w/2,this.w/2+this.x,this.h/2+this.y);
}

function moveobject() {
	this.x=wrap(this.x+this.ax*dt,cw);
	this.y=wrap(this.y+this.ay*dt,ch);
	if(this.ad) {
		this.d=wrap(this.d+this.ad*dt,360); 
	}

}

function rnd(x,y) {
	if(!y) y=0;
	return Math.random()*(y-x)+x;
}

function updatehead() {
	var h="Score: "+("000000"+score).slice(-6)+"   Lives: "+lives+"   Level: "+level;
	el("heading").innerHTML=h;
}

function handlekeys() {
	var a=0;
	if(keys[37]) a--;
	if(keys[39]) a++;
	if(a*ship.ad<=0) ship.ad=0;
	ship.ad=(ship.ad*5+a*15*dt)/(5+dt);
	
	if(keys[38]) {
		var r=ship.d*3.14159265/180;
		var s=Math.sin(r);
		var c=Math.cos(r);
		ship.ax+=s*dt*.2;
		ship.ay-=c*dt*.2;
	}
}

function fireshot() {
	if(!alive) return;
	if(shots.length>=5) {
		return; //the following would delete the oldest shot instead
		//var m=0;
		//for(var i=1;shots[i];i++)
		//	if(shots[m].life>shots[i].life) m=i;
		//killshot(m);		
	}

	var a=rnd(dt);
	var r=(ship.d+ship.ad*a)*3.14159265/180;
	var s=Math.sin(r);
	var c=Math.cos(r);
	
	var x=ship.x+ship.ax*a+scale*s;
	var y=ship.y+ship.ay*a-scale*c;

	var shot=new Shot(x,y);
	shot.ax=s*6+ship.ax;
	shot.ay=-c*6+ship.ay;
	shot.x-=a*shot.ax;
	shot.y-=a*shot.ay;
	shots.push(shot);
}

function kill(a,i) {
	a[i]=a[a.length-1];
	a.pop();
}

function killshot(i) {
	kill(shots,i);
}

function killrock(i) {
	kill(rocks,i);
}

function splitrock(i) {
	var rock=rocks[i];
	killrock(i);
	if(rock.w>scale*1.5) {
		var ax=rnd(-1,1)*speed,ay=rnd(0.5,1)*speed;
		r1=new Rock(rock.x+ax*5,rock.y+ay*5,rock.w/2);
		r1.ax=rock.ax+ax;
		r1.ay=rock.ay+ay;
		r2=new Rock(rock.x-ax*5,rock.y-ay*5,rock.w/2);
		r2.ax=rock.ax-ax;
		r2.ay=rock.ay-ay;
		rocks.push(r1);
		rocks.push(r2);
	}
	score+=20*level;
	updatehead();

}


function newlevel() {
	ship=new Ship();
	speed=0.5+level/8;
	for(var i=0;i<8;i++) {
		rocks[i]=new Rock(rnd(cw/2)-cw/4,rnd(ch),4*scale);
		rocks[i].ax=speed*rnd(-1,1);
		rocks[i].ay=speed*rnd(-3,3);
	}
	level++;
	updatehead();
	shots=[];
}


function frame() {
	time=1*new Date();
	var tdt=(time-ptime)/50
	if(tdt>4) tdt=4;
	dt=(dt*4+tdt)/5;
	ptime=time;
	
	if(alive) handlekeys();
	
	if(Math.floor(score/10000)!=Math.floor(pscore/10000)) {
		lives++; //new life every 10000 points
		updatehead();
	}
	pscore=score;

	startframe();
	//check collisions

	for(var i=shots.length-1;i>=0;i--) {
		for(var j=rocks.length-1;j>=0;j--) {
			if(collides(shots[i],rocks[j],1)) {
				splitrock(j);
				killshot(i);
				break;
			}
		}
	}
	
	if(alive)
	for(var j=rocks.length-1;j>=0;j--) {
		if(collides(ship,rocks[j])) {
			splitrock(j);
			alive=false;
			ship=new Ship();
			var t=1*new Date();
			if(t>lastdeath+1000) lives--; //give them a second where they can't die
			lastdeath=t;
			updatehead();
		}
	}


	
	for(var i=shots.length-1;i>=0;i--) {
		if((shots[i].life-=dt)<0) killshot(i);
	}
	
	
	//move
	ship.move();
	
	for(var i=0;rocks[i];i++) {
		rocks[i].move();
	}
	for(var i=0;shots[i];i++) {
		shots[i].move();
	}
	
	if(!alive && lives>0) alive=!mcollides(ship,rocks);
	
	
	//draw

	for(var i=0;rocks[i];i++) {
		rocks[i].draw();
	}
	for(var i=0;shots[i];i++) {
		shots[i].draw();
	}
	if(alive) ship.draw();
	
	endframe();
	
	if(rocks.length==0) {
		score+=1000+level*1000;
		newlevel();
		updatehead();
	}

	timer=setTimeout("frame()",10);

}

function keydown(e) {
	e=e||event;
	key=e.which||e.keyCode;
	keys[key]=true;
	
	if(key==17 || key==32) fireshot();
	//status=key+" down";
}
function keyup(e) {
	e=e||event;
	key=e.which||e.keyCode;	
	keys[key]=false;
	//status=key+" up";
}
function Rkeypress(e) {
	e=e||event;
	key=e.which||e.keyCode;	
	//status=key+" pressed";
	if(String.fromCharCode(key)=="p") {
		if(timer) onblur();
		else onfocus();
	}
}
function Ronblur() {
	status="Paused";
	clearTimeout(timer);
	timer=0;
}
function Ronfocus() {
	if(!timer) {
		status="Resumed";
		ptime=1*new Date()-dt*50;
		frame();
	}
}



function RocksPreInit() {
	divs=[];
	scale=12;
	cx=50,cy=50;
	cw=400,ch=300;
	color="#44ff22";
	rockcolor="#bbaa33";
	shipcolor="#ffdddd";
	shipexplode="#ffff00";
	shotcolor="#ffff77";
	alive=true;
	lastcount=0;
	lastdeath=0;
	lives=3;
	timer=0;
	score=0;
	level=0;
	pscore=0;
	speed=0;

	rocks=[];
	shots=[];
	keys=[];
	ptime=1*new Date();
	time;
	dt=0;

	var pad=document.all?"<img width=0 height=0>":"";

	document.write("<div id='arena' style='position:absolute; height:"+ch+"; width:"+cw+"; top:"+cx+"; left:"+cy+"; background-color: black;"+(document.all?" clip:rect(0,"+cw+","+ch+",0);":"")+"'>");
	document.write("<span id='heading' style='font-family:courier new,terminal,courier,fixedsys,fixed; color: #44ff22; font-size: 10pt; font-weight:700'></span>");
	for(var i=0;i<92;i++) {
		document.write("<div id='d"+i+"' style='position:absolute; height:1; width:10; top:10; left:10; background-color: white; visibility:hidden;'>"+pad+"</div>");
		divs[i]=el("d"+i);
	}
	document.write("</div>");


	newlevel();



	doc.onkeydown=keydown;
	doc.onkeyup=keyup;
	doc.onkeypress=Rkeypress;
	doc.onfocus=Ronfocus;
	doc.onblur=Ronblur;
	if(document.all) {
		var arena=el("arena");
		arena.onfocus=Ronfocus;
		arena.onblur=Ronblur;
	}
}

function RocksInit() {
	//alert("Rocks Init");
	frame();
}


if(Math.random()<0.333) {
	BlocksPreInit();
	window.onload=BlocksInit;
} else if(Math.random()<0.5) {
	RocksPreInit();
	window.onload=RocksInit;
} else {
	OthelloPreInit();
	window.onload=OthelloInit;
}




