// MazeExplorer Script
// (c) 8/1997 - 5/2004 N. Landsteiner, mass:werk - media environments, www.masswerk.at

// sound ctrl vars

var soundsAvailable=false;
var soundApp=null;
var useSound=false;
var soundVolume=50;
var moveSound=0;

// sound dummy functions (NS4)
function playSound() {}


// cross browser api

var apiDOM=false;
var apiIE4=false;
var apiNS4=false;
var apiNS3=false;
var apiCompatible=false;

var setimg, setSprite, showLayer, hideLayer, moveLayer;
var divisions, sprite;

function setimg(img,spr) {
	document.images[img].src=sprite[spr].src
}
function setSprite_DOM(lr,img,spr) {
	document.images[img].src=sprite[spr].src
}
function setSprite_NS4(lr,img,spr) {
	divisions[lr].document.images[img].src=sprite[spr].src
}
function showLayer_NS4(lr) {
	divisions[lr].visibility='show'
}
function hideLayer_NS4(lr) {
	divisions[lr].visibility='hide'
}
function showLayer_DOM(lr) {
	divisions[lr].style.visibility='visible'
}
function hideLayer_DOM(lr) {
	divisions[lr].style.visibility='hidden'
}
function moveLayer_NS4(lr,x,y) {
	divisions[lr].moveTo(x,y)
}
function moveLayer_DOM(lr,x,y) {
	divisions[lr].style.left=x;
	divisions[lr].style.top=y
}
function moveLayer_IE4(lr,x,y) {
	divisions[lr].style.pixelLeft=x;
	divisions[lr].style.pixelTop=y
}

function setAPI() {
	var divNames=new Array('gLr1','gLr2','gLr3','gLr4','shipLr','shotLr','gameOver');
	divisions=new Array();
	if (document.images) apiNS3=true;
	if (document.getElementById) {
		apiDOM=true;
		for (var i=0; i<divNames.length; i++) divisions[divNames[i]]=document.getElementById(divNames[i]);
		setSprite=setSprite_DOM;
		showLayer=showLayer_DOM;
		hideLayer=hideLayer_DOM;
		moveLayer=moveLayer_DOM
	}
	else if (document.all) {
		apiIE4=true;
		for (var i=0; i<divNames.length; i++) divisions[divNames[i]]=document.all[divNames[i]];
		setSprite=setSprite_DOM;
		showLayer=showLayer_DOM;
		hideLayer=hideLayer_DOM;
		moveLayer=moveLayer_IE4
	}
	else if (document.layers) {
		apiNS4=true;
		for (var i=0; i<divNames.length; i++) divisions[divNames[i]]=document.layers[divNames[i]];
		setSprite=setSprite_NS4;
		showLayer=showLayer_NS4;
		hideLayer=hideLayer_NS4;
		moveLayer=moveLayer_NS4
	};
	apiCompatible= ((apiDOM || apiIE4 || apiNS4));
	if (apiCompatible) {
		for (var i=0; i<divNames.length; i++) {
			if (divisions[divNames[i]] == null) return false;
		};
		return true
	}
	else {
		alert('Sorry\nThis script is not compatible to your browser.\n');
		return false
	}
}

function getMazePos() {
	var el='MazeTop';
	var x=0;
	var y=0;
	if (apiDOM) {
		// DOM
		var obj=document.getElementById(el);
		x=obj.offsetLeft;
		y=obj.offsetTop;
		while (obj.offsetParent) {
			obj=obj.offsetParent;
			x+=obj.offsetLeft;
			y+=obj.offsetTop;
		}
	}
	else if (apiIE4) {
		// MS IE 4/win5.0
		var obj=document.all[el];
		x=obj.offsetLeft;
		y=obj.offsetTop;
		if (obj.offsetParent) {
			// IE 5
			while (obj.offsetParent) {
				obj=obj.offsetParent;
				x+=obj.offsetLeft;
				y+=obj.offsetTop;
			}
		}
		else {
			// IE 4
			while (obj.parentElement) {
				obj=obj.parentElement;
				if (obj.offsetLeft) x+=obj.offsetLeft;
				if (obj.offsetTop) y+=obj.offsetTop;
			}
		}
	}
	else if (apiNS4) {
		var obj=document.layers.MazeTopLr;
		x=obj.pageX;
		y=obj.pageY;
	};
	mazeX=x+1;
	mazeY=y+3;
}

// preloading

function preLoad() {
	var imgpath='me_images/';
	var imgnames=new Array(
		'shipd', 'shipl', 'shipr', 'shipu', 'shipx1', 'shipx2', 'shipx3', 'shipx4', 'shipx5',
		'n0', 'n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7', 'n8', 'n9', 'nn',  'pp',
		'on', 'off', 'ns', 'nb', 'box', 'exp', 'shot', 'gameover'
	);
	var i,k;
	sprite=new Array();
	for (i=0; i<21; i++) {
		var n='tile'+i;
		sprite[n]=new Image();
		sprite[n].src=imgpath+n+'.gif';
	};
	for (i=0; i<imgnames.length; i++) {
		var n=imgnames[i];
		sprite[n]=new Image();
		sprite[n].src=imgpath+n+'.gif';
	};
	for (i=1; i<4; i++) {
		var n='inv'+i;
		sprite[n]=new Image();
		sprite[n].src=imgpath+n+'.gif'
	}
};

if (document.images) preLoad();

// constructors

function Ghost() {
	this.r= 0;
	this.c= 0;
	this.s= 0;
	this.d= 0;
	this.p= 0;
	this.pn= 0;
	this.z= 0;
	this.osx=0;
	this.osy=0;
	this.posx=0;
	this.posy=0
}

function Player() {
	this.r= 0;
	this.c= 0;
	this.dir= 0;
	this.md= 0;
	this.dx= 0;
	this.dy= 0;
	this.osx=0;
	this.osy=0;
	this.posx=0;
	this.posy=0
}

function Bullet() {
	this.r= 0;
	this.c= 0;
	this.s= 0;
	this.d= 0;
	this.osx=0;
	this.osy=0;
	this.posx=0;
	this.posy=0
}

// ship def

var g= new Array();
	for (var i=1; i<=4; i++) g[i]=new Ghost;
var ship= new Player();
var shot= new Bullet();
var movedir=0;
var runThru=false;
var gameOn= false;
var nShots= 0;
var food= 0;
var nLevel= 0;
var nLife=0;
var aSpeed=300;
var aStep=6;

var mazeX=0;
var mazeY=0;

var aSpan= new Array();
var shipStr= new Array();

shipStr[1]="r"; shipStr[2]="l";
shipStr[4]="u"; shipStr[8]="d";
shipStr[0]="d";

var mazeCode= new Array();
var mazeGrid= new Array();
var mazeDir0= new Array();

mazeDir0[0]=3;
mazeCode[0] = new Array(
	"ahhhhhdxbhhdxbhhhhhc",
	"v               p  v",
	"v am lc lhhm lhhhc v",
	"v op  o      ahhcv v",
	"v   k   qttr bhcvv v",
	"v n   n vxxv   vvv v",
	"d bm lg vxxv k obd b",
	"x     o bhhd       x",
	"c acn    x   lhc n a",
	"v vvbc n lc ahhd v v",
	"v vbhd v  v vnp  v v",
	"v bhhm bm o bd lhd v",
	"v p                v",
	"bhhhhhcxahhcxahhhhhd"
);
mazeGrid[0]= new Array(
	"00000000000000000000",
	"01007009000090000020",
	"00000000000000000000",
	"00018205000060000000",
	"05060506000000000000",
	"00037400000050200000",
	"00000000000000000000",
	"09008200000050807090",
	"00000378700740000000",
	"00000000000000000000",
	"00000000320000104000",
	"00000000000000000000",
	"03000087080870800040",
	"00000000000000000000"
);
mazeDir0[1]=3;
mazeCode[1]= new Array(
	"ahhhhhihhhhhhdxoxbhc",
	"v p   o            v",
	"d ahc   lhhm ac ac b",
	"x vxehc      bd bd x",
	"c bidxv qttr   p   a",
	"v  vxxv vxxv ac ac v",
	"ec bhhd vxxv bd bd v",
	"eg      bhhd       v",
	"ed lhhc  x   n ahm v",
	"d    pv lm lhg v   b",
	"x ahc v      v vpn x",
	"c bhd o lhhm o v o a",
	"v              v   v",
	"bhhhhhhhhhhhhcxvxahd"
);
mazeGrid[1]= new Array(
	"00000000000000000000",
	"01000201000070878020",
	"00000306000000000000",
	"06000005000060000050",
	"00000000000050090060",
	"03200000000000000000",
	"00000000000000000000",
	"00500006000050780060",
	"00000005007040000000",
	"01800200000000001060",
	"06000005008020000050",
	"00000000000000000000",
	"03000808000080605040",
	"00000000000000000000"
);
mazeDir0[2]=3;
mazeCode[2]= new Array(
	"ahdxbhihhhhhhihdxbhc",
	"vp    o      o    pv",
	"d aim   lhhm   lic b",
	"x bg  n      n  ed x",
	"c  o ag qttr ec o  a",
	"em   bg vxxv ed   lg",
	"v  n  o vxxv o  n  v",
	"v lfm   bhhd   lfm v",
	"v     n  x   n     v",
	"d lhhid lhhm bihhm b",
	"     o        o     ",
	"c lm   k lm k   lm a",
	"vp   n        n   pv",
	"bhcxafhhhhhhhhfcxahd"
);
mazeGrid[2]= new Array(
	"00000000000000000000",
	"01080201000020108020",
	"00000506000050600000",
	"06001405000060320050",
	"03200000000000000140",
	"00506000000000050600",
	"01403200000000140320",
	"00000506000050600000",
	"05000405000060300060",
	"00000000000000000000",
	"09002018700782010090",
	"00005060000005060000",
	"03074030800804037040",
	"00000000000000000000"
);
mazeDir0[3]=3;
mazeCode[3]= new Array(
	"nxaidxbhhgxbdxbhmxlc",
	"v bdp    v         v",
	"v     lm o lhm ahcpv",
	"v lhm          vkv v",
	"d     n qttrlm bhd b",
	"x ahc v vxxv       x",
	"c vkv v vxxv am lc a",
	"d bhd o bhhd v   o b",
	"x        x   o n   x",
	"c lhc lhhm n   o n a",
	"v   o      v n  pv v",
	"v n   n lm o bm ld v",
	"v ecp v            v",
	"oxbfcxehhcxacxahmxld"
);
mazeGrid[3]= new Array(
	"00000000000000000000",
	"00001900205008700820",
	"05008600000000000000",
	"00000507808000600000",
	"05000600000000000000",
	"06000000000010870090",
	"00000000000000000000",
	"00000000000000182000",
	"09000908007060005090",
	"00000000000050600000",
	"05020507006000374000",
	"00037600000000000000",
	"00003603009087080740",
	"00000000000000000000"
);
mazeDir0[4]=3;
mazeCode[4]= new Array(
	"ahhhdxbhhhhhhdxoxbhc",
	"v p                v",
	"v ahc ahhm lhc ahm v",
	"v bhd v      v vp  v",
	"d     v qttr o o n b",
	"x ahm o vxxv     v x",
	"c v     vxxv n lhd a",
	"d o ahc bhhd o     b",
	"x   vkv  x     n n x",
	"c n bhd lhhihm v o a",
	"v vp       v   v   v",
	"v bhm lhhm o k ehm v",
	"v          p   v   v",
	"bhhhcxahhhhhhcxvxahd"
);
mazeGrid[4]= new Array(
	"00000000000000000000",
	"01000900007000908020",
	"00000000000000000000",
	"00000001008020001060",
	"05000600000000000000",
	"06000000000050904050",
	"00010806000000000000",
	"00000000000000507060",
	"09060005000080600050",
	"00000000000000000000",
	"00030708002010603060",
	"00000000000000000000",
	"03000900008080601040",
	"00000000000000000000"
);

var tileRef= new Array(
	'h', 'tile3', 'v', 'tile12', 'a', 'tile9', 'b', 'tile5', 'c', 'tile10', 'd', 'tile6',
	'e', 'tile13', 'f', 'tile7', 'g', 'tile14', 'i', 'tile11', 'k', 'tile16', 't', 'tile18',
	'l', 'tile1', 'm', 'tile2', 'n', 'tile8', 'o', 'tile4', 'q', 'tile17', 'r', 'tile19',
	'x', 'tile0'
);
var tileCode= new Array();
for (var i=0; i<tileRef.length; i+=2) tileCode[tileRef[i]]=tileRef[i+1];

var f1= new Array();
	for (var i=1; i<=14; i++) f1[i]=new Array();
var f2= new Array();
	for (var i=1; i<=14; i++) f2[i]=new Array();

var t1= new Array();
t1[0]=0;
t1[1]= 9; // rd
t1[2]=10; // ld
t1[3]= 5; // ru
t1[4]= 6; // lu
t1[5]=13; // rdu
t1[6]=14; // ldu
t1[7]=11; // rld
t1[8]= 7; // rlu
t1[9]=15; // rlud

var tx= new Array();
var ty= new Array();
tx[0]=0;  ty[0]=0;
tx[1]=1;  ty[1]=0;  //r
tx[2]=-1; ty[2]=0;  //l
tx[4]=0;  ty[4]=-1; //u
tx[8]=0;  ty[8]=1;  //d

var t2 = new Array();
t2[1]= [1];
t2[2]= [2];
t2[4]= [4];
t2[8]= [8];
t2[3]= [1, 2];
t2[9]= [1, 8];
t2[10]=[2, 8];
t2[12]=[4, 8];
t2[5]= [1, 4];
t2[6]= [2, 4];
t2[7]= [1, 2, 4];
t2[11]=[1, 2, 8];
t2[13]=[1, 4, 8];
t2[14]=[2, 4, 8];
t2[15]=[1, 2, 4, 8];

var t3 = new Array();
t3[0]=0; t3[1]=2; t3[2]=1; t3[4]=8; t3[8]=4;

g[1].rh=6; g[1].ch=10;
g[2].rh=6; g[2].ch=11;
g[3].rh=7; g[3].ch=10;
g[4].rh=7; g[4].ch=11;


// setup

function buildMaze(a) {
	food=0;
	for (var r=1; r<=14; r++) {
		for (var c=1; c<=20; c++) {
			f1[r][c]=0;
			f2[r][c]=t1[parseInt(mazeGrid[a][r-1].charAt(c-1),10)];
			var z=mazeCode[a][r-1].charAt(c-1);
			if (z==' ') {
				if (getRand(10)==0) {
					setTile(r,c,'box');
					f1[r][c]=8;
					food++
				}
				else if (getRand(70)==0) {
					setTile(r,c,'tile20');
					f1[r][c]=9;
				}
				else setTile(r,c,'tile0');
			}
			else if (z=='p') {
				setTile(r,c,'tile20');
				f1[r][c]=9
			}
			else {
				setTile(r,c,tileCode[z])
			}
		}
	}
}

function setSpan() {
	for (n=1-aStep; n<aStep; n++) {
		if (n==0) aSpan[0]=0
		else aSpan[n]=Math.round(n*27/aStep)
	};
	limitOffsets(ship, aStep);
	for (var i=1; i<=4; i++) limitOffsets(g[i], aStep);
	if (shot.s>0) limitOffsets(shot, aStep);
}

function limitOffsets(obj,limit) {
	if (obj.osx>=limit) obj.osx=limit-1;
	if (obj.osy>=limit) obj.osy=limit-1;
	if (obj.osx<=-limit) obj.osx=1-limit;
	if (obj.osy<=-limit) obj.osy=1-limit;
}

// display

function setTile(r,c,n) {
	setimg('r'+r+'c'+c, n)
}

// =========== game play

function newGame() {
	var ready=setAPI();
	if (ready==false) return;
	getMazePos();
	window.onresize=getMazePos;
	hideLayer('gameOver');
	setSprite('gameOver','go_i','gameover');
	nShots=0;
	setimg("sh1","ns");
	for (n=1; n<=8; n++) setimg("sh"+n,"nb");
	nLife=3;
	setimg('life1','shipd');
	setimg('life2','shipd');
	setimg('life3','shipd');
	nLevel=0;
	gameTimer= setTimeout("doNull()",1000);
	clearTimeout(gameTimer);
	startLevel()
}

function startLevel() {
	gameOn=false;
	hideShot();
	hideLayer('shipLr');
	hideLayer('shotLr');
	for (var i=1; i<=4; i++) hideLayer('gLr'+i);
	runThru=false;
	nLevel++;
	showLevel();
	buildMaze((nLevel-1)%5);
	setSpan();
	for (var i=1; i<=4; i++) gHome(i);
	pHome();
	showLayer('shipLr');
	gameOn=true;
	if (food>0) doMove()
	else {
		nLevel--;
		startLevel()
	}
}

function gHome(i) {
	with (g[i]) {
		r=rh; c=ch;
		osx=0; osy=0;
		s=0; p=1;
		z=0; pn=1;
		setGhost(i,r,c,'inv'+p)
	};
	showLayer('gLr'+i)
}

function pHome() {
	hideShot();
	movedir=0;
	with (ship) {
		r=9; c=10;
		osx=0; osy=0;
		md=0; dir= mazeDir0[(nLevel-1)%5];
		dx=0; dy=0;
		//setimg('life'+nLife, 'r0');
		setShip(r,c,'d');
	};
	if (nShots==0) {
		nShots=1;
		setimg("sh1","ns")
	}
	playSound('guck');
}

function getRand(x) {
	return Math.floor(Math.random() * x)
}

function tileFree(n, r,c) {
	var tpx=24*(c-1);
	var tpy=24*(r-1);
	for (var i=1; i<=4; i++) {
		if (i==n) continue;
		if ((g[i].r==r) && (g[i].c==c)) return false;false;
		if (isCollision(g[i].posx,g[i].posy, tpx,tpy, 12)) return false;
	};
	return true
}

function isCollision(x1,y1,x2,y2, radius) {
	return (Math.abs(x1-x2)+Math.abs(y1-y2)<radius)
}

function trunkBy(v,m) {
	v%=m;
	if (v==0) v=m;
	return v
}

function showLevel() {
	var lStr= (nLevel<10)? 'n'+nLevel : ''+nLevel;
	setimg('l1', 'n'+lStr.charAt(0));
	setimg('l2', 'n'+lStr.charAt(1))
}


// =========== main

function move(x) {
	movedir=x
}

function doMove() {
	clearTimeout(gameTimer);
	dateA=new Date();
	if (shot.s>0) moveShot();
	with (ship) {
		if (osx+osy==0) pMove();
		if (runThru) {
			osx+=dx;
			osy+=dy;
			if ((c+dx)%21==0) osx=0;
			if ((r+dy)%15==0) osy=0;
			osx%=aStep;
			osy%=aStep;
			if (osx==0) c=trunkBy(c+dx,20);
			if (osy==0) r=trunkBy(r+dy,14);
			setShip(r,c,shipStr[md]);
			if (osx+osy==0) {
				if (moveSound==1) playSound('movesnd');
				if (f2[r][c]) dir=f2[r][c];
			}
		};
		if (f1[r][c]>=8) {
			setTile(r,c,'tile0');
			if (f1[r][c]==8) {
				playSound('pick1');
				food--
			}
			else if ((f1[r][c]==9) && (nShots<8)) {
				playSound('pick2');
				nShots++;
				setimg('sh'+nShots,'ns')
			};
			f1[r][c]=0;
			if (food==0) {
				playSound('haha');
				setTimeout("startLevel()",150);
				return
			}
		}
	};
	if (shot.s>0) moveShot();
	gmove();
	testCrash("doMoveFinal()")
}

function doMoveFinal() {
	clearTimeout(gameTimer);
	if (gameOn) {
		dateB=new Date();
		mTO= dateA.getTime()-dateB.getTime();
		mTO+=Math.round(aSpeed/aStep);
		if (mTO<5) mTO=5;
		gameTimer=setTimeout("doMove()",mTO)
	}
}

// =========== Ship

function pMove() {
	with (ship) {
		if (dir&movedir) md= dir&movedir
		else {
			md&=dir;
			if (md==0) runThru=false;
		};
		if (md) {
			runThru=true;
			dx=(md&3);
			dy=(md&12);
			if (dx) {
				dir=3;
				dx=tx[dx]
			};
			if (dy) {
				dir=12;
				dy=ty[dy]
			}
		}
	}
}

function setShip(r,c,s) {
	ship.posx=24*(c-1)+aSpan[ship.osx];
	ship.posy=24*(r-1)+aSpan[ship.osy];
	moveLayer('shipLr', mazeX+ship.posx, mazeY+ship.posy);
	setSprite('shipLr','ship_i','ship'+s)
}

// =========== Ghost


function gmove() {
	for (i=1; i<=4; i++) {
		if (gameOn) {
			with (g[i]) {
				p+=pn;
				if (p==1) pn=1;
				if (p==3) pn=-1;
				if (s==2) gMove2(i)
				else if (s==1) gMove1(i)
				else gMove0(i);
			}
		};
		displayGhost(i)
	}
}

function displayGhost(i) {
	with (g[i]) {
		setGhost(i,r,c,'inv'+p)
	}
}

function setGhost(i,r,c,s) {
	var glr='gLr'+i;
	g[i].posx=24*(c-1)+aSpan[g[i].osx];
	g[i].posy=24*(r-1)+aSpan[g[i].osy];
	moveLayer(glr, mazeX+g[i].posx, mazeY+g[i].posy);
	setSprite(glr,'g_i'+i,s)
}

function gMove0(i) {
	with (g[i]) {
		if ((tileFree(i,5,c)) && ((ship.dx+ship.dy)!=0)) {
			if ((z>40) || (getRand(30)<1)) {
				playSound('sneek');
				s++;
				r=5;
				osy=2;
			}
			else z++
		}
	}
}

function gMove1(i) {
	with (g[i]) {
		if (tileFree(i,4,c)) {
			if (osy==2) osy--
			else {
				osy--;
				if (osy==-aStep) {
					r=4;
					osy=0;
					d=(getRand(2))? 1:2;
					g[i].s++
				}
			}
		}
	}
}

function gMove2(i) {
	with (g[i]) {
		if (osx+osy==0) {
			var x= f2[r][c];
			if (x>0) {
				var gdm= x&(15^t3[d]);
				if (getRand(2+nLevel)>0) gmoveStrat(i,gdm)
				else gmoveRand(i,gdm)
			};
			if (d>0) {
				if (tileFree(i,trunkBy(r+ty[d],14),trunkBy(c+tx[d],20))) gSet(i)
				else reverseStuck(i,x)
			}
		}
		else gSet(i);
	}
}

function gSet(i) {
	with (g[i]) {
		osy+=ty[d];
		osx+=tx[d];
		osx%=aStep;
		osy%=aStep;
		if (((c==1) && (tx[d]==-1)) || ((c==20) && (tx[d]==1))) osx=0;
		if (((r==1) && (ty[d]==-1)) || ((r==14) && (ty[d]==1))) osy=0;
		if (osx==0) c=trunkBy(c+tx[d],20);
		if (osy==0) r=trunkBy(r+ty[d],14);
	}
}

function gmoveRand(i,k) {
	g[i].d=t2[k][getRand(t2[k].length)]
}

function gmoveStrat(i,gdm) {
	var desx=ship.c-g[i].c;
	var desy=ship.r-g[i].r;
	g[i].d=0;
	if (desx!=0) g[i].d= (desx>0)? 1:2;
	if (desy!=0) g[i].d|= (desy>0)? 8:4;
	g[i].d&=gdm;
	if (g[i].d>0) gmoveRand(i,g[i].d)
	else gmoveRand(i,gdm)
}

function reverseStuck(i,x) {
	with (g[i]) {
		if (x==0) {
			if (tileFree(i,trunkBy(r-ty[d],14),trunkBy(c-tx[d],20))) d=t3[d]
		}
		else {
			var vd= t2[x][getRand(t2[x].length)];
			if (tileFree(i,r+ty[vd],c+tx[vd])) {
				d=vd;
				gSet(i)
			}
		}
	}
}

// =========== Shot

function newShot(){
	with (ship) {
		if ((md>0) && (shot.s==0) && (nShots>0)) {
			if (((f2[r][c]==0) || (f2[r][c]&md)) && (((c-1)%19>0) && ((r-1)%13>0))) {
				if ((f2[r+ty[md]][c+ty[md]]==0) || (f2[r+ty[md]][c+ty[md]]&md)) {
					setimg("sh"+nShots,"nb");
					nShots--;
					shot.r=r+ty[md];
					shot.c=c+tx[md];
					shot.osx=osx;
					shot.osy=osy;
					shot.d=md;
					shot.s=1;
					playSound('shoot');
					setShot();
					showLayer("shotLr");
					setSprite('shotLr', 'shot_i', 'shot');
					for (i=1; i<=4; i++) {
						var zx=Math.abs(g[i].posx-posx);
						var zy=Math.abs(g[i].posy-posy);
						if (zx+zy<22) {
							newGhost(i);
							hideShot()
						}
					}
				}
			}
		}
	}
}

function moveShot() {
	with (shot) {
		if (osx+osy==0) {
			if ((c<0) || (c>19) || (r<0) || (r>13)) {
				hideShot();
				return;
			}
			if (f2[r][c]>0) {
				if ((f2[r][c]&d)==0) {
					playSound('dock');
					hideShot();
				}
			}
			if (((c-1)%19==0) || ((r-1)%13==0)) hideShot();
		};
		if (s>0) {
			osy+=ty[d];
			osx+=tx[d];
			osx%=aStep;
			osy%=aStep;
			if (osx==0) c+=tx[d];
			if (osy==0) r+=ty[d];
			setShot()
		}
	}
}

function hideShot() {
	shot.s=0;
	hideLayer('shotLr')
}

function setShot() {
	shot.posx=24*(shot.c-1)+aSpan[shot.osx];
	shot.posy=24*(shot.r-1)+aSpan[shot.osy];
	moveLayer('shotLr', mazeX+shot.posx, mazeY+shot.posy);
}

// =========== Crash

function testCrash(tos) {
	var crash=0;
	for (i=1; i<=4; i++) {
		var zx,zy;
		if ((shot.s>0) && (isCollision(g[i].posx,g[i].posy, shot.posx,shot.posy, 22))) newGhost(i);
		if (isCollision(g[i].posx,g[i].posy, ship.posx,ship.posy, 22)) crash=i;
	};
	if (crash>0) {
		playSound('breakship');
		crashShip(1,crash);
	}
	else gameTimer= setTimeout(tos,1)
}

function newGhost(i) {
	shot.s=0;
	playSound('plink');
	setSprite('shotLr', 'shot_i', 'exp');
	gHome(i);
	setTimeout("hideShot()",aSpeed)
}

function crashShip(i,g) {
	setShip(ship.r,ship.c,"x"+i);
	if (i==5) {
		hideLayer('gLr'+g);
		setTimeout("newShip()","800")
	}
	else {
		i++;
	 	setTimeout("crashShip("+i+","+g+")","300")
	 }
}
	
function newShip() {
	setimg("life"+nLife,"tile0");
	nLife--;
	if (nLife>0) {
		nShots=0;
		for (n=1; n<=8; n++) setimg("sh"+n,"nb");
		for (k=1; k<=4; k++) gHome(k);
		pHome();
		doMove()
	}
	else gameOver()
}

// =========== general2

function gameOver() {
	moveLayer('gameOver',mazeX+24*7,mazeY+24*8);
	showLayer('gameOver');
	gameOn=false;
	nLevel=0;
	clearTimeout(gameTimer)
}

function doPause() {
	if (gameOn) {
		gameOn=false;
		clearTimeout(gameTimer);
		setimg('l1','pp');
		setimg('l2','nn');
	}
	else {
		if (nLevel>0) {
			gameOn=true;
			showLevel();
			gameTimer= setTimeout("doMove()",100);
		}
	}
}

function setSpeed(nSpeed) {
	setimg('speed'+aSpeed,'off');
	aSpeed= nSpeed;
	setimg('speed'+aSpeed,'on')
}

function setSmoothness(nStep) {
	setimg('step'+aStep,'off');
	aStep= nStep;
	setSpan();
	setimg('step'+aStep,'on')
}

function doNull() {}


// ======= keyboard control

var defKey = new Array('i', 'j', 'l', 'k');

function showKeySet() {
	return	"\'"+defKey[0]+"\' ... up\n"+
			"\'"+defKey[3]+"\' ... down\n"+
			"\'"+defKey[1]+"\' ... left\n"+
			"\'"+defKey[2]+"\' ... right\n"
}

function setKeys(keyset) {
	var keyConflict=false;
	var keyUndef=false;
	for (var i=0; i<4; i++) {
		if (defKey[i]) {
			keyset[i]=keyset[i].charAt(0);
			keyset[i]=keyset[i].toLowerCase();
			if ((keyset[i]=="n") || (keyset[i]=="p") || (keyset[i]==" ")) keyConflict=true;
			if ((keyset[i]>="0") && (keyset[i]<="9")) keyConflict=true;
		}
		else {
			alert("A key was left undefined!\nNo changes were applied.\n");
			return
		}
	};
	if (keyConflict) {
		alert("A conflict with reserved keys occurred!\nNo changes were applied.\n")
	}
	else {
		for (var i=0; i<4; i++) defKey[i]=keyset[i];
		alert("New key set applied:\n\n"+
			"\'"+defKey[0]+"\' ... up\n"+
			"\'"+defKey[3]+"\' ... down\n"+
			"\'"+defKey[1]+"\' ... left\n"+
			"\'"+defKey[2]+"\' ... right\n"+
			"-------\n\n");
	}
}

function configKeys() {
	var wargs='width=400,height=300,location=0,menubar=0,resizable=1,scrollbars=0,status=0,toolbar=0';
	if (self.screenX!=null) {
		var w=(self.outerWidth)? parseInt(self.outerWidth) : parseInt(self.width);
		wargs+= ',screenX='+(parseInt(self.screenX)+Math.floor((w-400)/2)) +',screenY='+(parseInt(self.screenY)+40);
	}
	else if ((document.body) && (document.body.clientTop) && (document.body.clientWidth)) {
		wargs+= ',left='+(parseInt(document.body.clientLeft)+Math.floor((parseInt(document.body.clientWidth)-400)/2)) +',top='+(parseint(document.body.clientTop)+40);
	}
	else if ((self.screen) && (self.screen.availWidth)) {
		wargs+= ',left='+Math.floor((parseInt(self.screen.availWidth)-400)/2)+',top='+Math.floor((parseInt(self.screen.availHeight)-400)/2);
	};
	var w=window.open('','jspac_keys',wargs);
	w.document.open()
	w.document.write('<HTML>\n<HEAD>\n<TITLE>MazeExplorer: Key Settings<\/TITLE>\n'+
		'<style type="text\/css">\n'+
		'td { font-family: arial,helvetica,sans-serif; font-size: 12px; }\n'+
		'form.input { font-family: arial,helvetica,sans-serif; font-size: 12px; }\n'+
		'.textbox { font-family: arial,helvetica,sans-serif; font-size: 12px; color: #000000; background: #ffffff; padding-left: 2px; }\n'+
		'+<\/STYLE>\n<\/HEAD>\n'+
		'<body bgcolor="#f8f8f8" text="#202020">\n<center>\n<table border="0" cellspacing="0" cellpadding="3">\n'+
		'<form method="get" action="#" onsubmit="if ((self.opener) && (self.opener.closed==false)) { self.opener.setKeys([this.up.value, this.left.value, this.right.value, this.down.value]); }; window.setTimeout(\'self.close()\',1); return false;">\n'+
		'<tr><td align="center" colspan="3"><b>Optional Key Settings<\/B><\/TD><\/TR>\n'+
		'<tr><td align="center" colspan="3">Figures, &quot;n&quot;, &quot;p&quot;, space are reserved.<br>Cursor keys and numeric keypad are always active.<br>&nbsp;<\/TD><\/TR>\n'+
		'<tr><td align="center" colspan="3"><input type="text" name="up" size="2" value="'+defKey[0]+'" class="textbox"><\/TD><\/TR>\n'+
		'<tr><td align="center" colspan="3"><table border="0" cellspacing="0" cellpadding="3"><tr>\n'+
		'<td align="right"><input type="text" name="left" size="2" value="'+defKey[1]+'" class="textbox"><\/TD>\n'+
		'<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/TD>\n'+
		'<td align="left"><input type="text" name="right" size="2" value="'+defKey[2]+'" class="textbox"><\/TD>\n'+
		'<\/TR><\/TABLE><\/TD><\/TR>\n'+
		'<tr><td align="center" colspan="3"><input type="text" name="down" size="2" value="'+defKey[3]+'" class="textbox"><\/TD><\/TR>\n'+
		'<tr><td align="center" colspan="3">&nbsp;<br><input type="button" value="cancle" onclick="self.close()"> &nbsp; <input type="submit" value="set keys"><\/TD><\/TR>\n'+
		'<\/FORM>\n<\/TABLE>\n<\/BODY>\n<\/HTML>');
	w.document.close();
	if (w.opener==null) w.opener=self;
	if (window.focus) w.focus();
}

function doKeys(keyCode,mkey) {
	mkey=mkey.toLowerCase();
	if ((mkey=="8") || (mkey==defKey[0]) || (keyCode==30)) movedir=4
	else if ((mkey=="4") || (mkey==defKey[1]) || (keyCode==28)) movedir=2
	else if ((mkey=="6") || (mkey==defKey[2]) || (keyCode==29)) movedir=1
	else if ((mkey=="5") || (mkey==defKey[3]) || (keyCode==31)) movedir=8
	else if ((mkey=="2") || (keyCode==98)) movedir=8
	else if ((mkey==" ")  || (mkey=="0") || (keyCode==13)) newShot()
	else if ((mkey=="p") || (keyCode==27)) {
		doPause()
	}
	else if (mkey=="n") {
		if (gameOn) {
			var hadTimer=false;
			if (gameTimer) {
				clearTimeout(gameTimer);
				hadTimer=true;
			}
			if (confirm("End the current game to start a new one?")) {
				gameTimer=setTimeout('newGame()',1)
			}
			else {
				if (hadTimer) gameTimer= setTimeout("doMove()",100);
			}
		}
		else newGame()
	}
}

var IE4_keyref;

function IE4_makeKeyref() {
	IE4_keyref= new Array();
	var hex= new Array('A','B','C','D','E','F');
	for (var i=0; i<=15; i++) {
		var high=(i<10)? i:hex[i-10];
		for (var k=0; k<=15; k++) {
			var low=(k<10)? k:hex[k-10];
			var cc=i*16+k;
			if (cc>=32) IE4_keyref[cc]=unescape("%"+high+low);
		}
	}
}

function _ie4_strfrchr(cc) {
	return (cc!=null)? IE4_keyref[cc] : '';
}

function enableKeyboard() {
	if (!String.fromCharCode) {
		IE4_makeKeyref();
		String.fromCharCode=_ie4_strfrchr
	};
	if (document.addEventListener) document.addEventListener("keypress", keyHandler, true)
	else {
		if ((self.Event) && (self.Event.KEYPRESS)) document.captureEvents(Event.KEYPRESS);
		document.onkeypress = keyHandler
	};
	window.document.onkeydown=keyIEFix
}

function keyIEFix() {
	if (window.event) {
		if ((window.event.ctrlKey) || (window.event.metaKey) || (window.event.altKey)) return true;
		var ch=window.event.keyCode;
		if (ch==8) keyHandler({which:8})
		else if (ch==37) keyHandler({which:28})
		else if (ch==39) keyHandler({which:29})
		else if (ch==38) keyHandler({which:30})
		else if (ch==40) keyHandler({which:31})
		//else if (ch==27) keyHandler({which:27})
		else if ((ch>=57373) && (ch<=57376)) {
			if (ch==57373) keyHandler({which:30})
			else if (ch==57374) keyHandler({which:31})
			else if (ch==57375) keyHandler({which:28})
			else if (ch==57376) keyHandler({which:29});
		}
		else {
			window.event.cancleBubble=false;
			return true
		};
		if ((window.event) && (window.event.preventDefault)) window.event.preventDefault();
		if ((window.event) && (window.event.stopPropagation)) window.event.stopPropagation();
		window.event.cancleBubble=true;
		return false
	}
}

function keyHandler(e) {
	var ch;
	var ctrl=false;
	if (e) {
		ch=e.which;
		ctrl=((e.ctrlKey) || (e.metaKey) || (e.altKey) || (e.modifiers))
	}
	else if (window.event) {
		ch=window.event.keyCode;
		ctrl= ((window.event.ctrlKey) || (window.event.altKey) || (window.event.metaKey))
	}
	else return true;
	if (ctrl)  return true;
	if ((window.event) && (window.event.preventDefault)) window.event.preventDefault()
	else if ((e) && (e.preventDefault)) e.preventDefault();
	if ((window.event) && (window.event.stopPropagation)) window.event.stopPropagation()
	else if ((e) && (e.stopPropagation)) e.stopPropagation();
	if (ch=='') {
		// map specials
		if (e==null) e=window.event;
		if ((e.charCode==0) && (e.keyCode)) {
			if (e.keyCode==37) ch=28
			else if (e.keyCode==39) ch=29
			else if (e.keyCode==38) ch=30
			else if (e.keyCode==40) ch=31
			else if (e.keyCode==27) ch=27;
		}
	};
	var mkey= ((ch>=32) && (ch<127))? String.fromCharCode(ch):'';
	doKeys(ch,mkey);
	if (window.event) window.event.cancleBubble=true;
	return false
}

// eof