	// setStyleByClass: given an element type and a class selector,
	// style property and value, apply the style.
	// args:
	//  t - type of tag to check for (e.g., SPAN)
	//  c - class name
	//  p - CSS property
	//  v - value
	var ie = (document.all) ? true : false;
	
	var curMove = -1;

	function setStyleByClass(t,c,p,v){
		var elements;
		if(t == '*') {
			// '*' not supported by IE/Win 5.5 and below
			elements = (ie) ? document.all : document.getElementsByTagName('*');
		} else {
			elements = document.getElementsByTagName(t);
		}
		for(var i = 0; i < elements.length; i++){
			var node = elements.item(i);
			for(var j = 0; j < node.attributes.length; j++) {
				if ((node.attributes.item(j).nodeName == 'class') || (node.attributes.item(j).nodeName == 'CLASS')) {
					if(node.attributes.item(j).nodeValue == c) {
						eval('node.style.' + p + " = '" +v + "'");
					}
				}
			}
		}
	}
	
	function setClassByClass(t,c,n){
		var elements;
		if(t == '*') {
			// '*' not supported by IE/Win 5.5 and below
			elements = (ie) ? document.all : document.getElementsByTagName('*');
		} else {
			elements = document.getElementsByTagName(t);
		}
		for(var i = 0; i < elements.length; i++){
			var node = elements.item(i);
			for(var j = 0; j < node.attributes.length; j++) {
				if ((node.attributes.item(j).nodeName == 'class') || (node.attributes.item(j).nodeName == 'className')) {
					if(node.attributes.item(j).nodeValue == c) {
						eval('node.style.' + p + " = '" +v + "'");
					}
				}
			}
		}
	}
	
	// reset board to the opening position
	function InitializeBoard() {
		// empty squares are -
		for (var i=1;i<=8;i++) {
			for (var j=1;j<=8;j++) {
				board[i][j] = "-";
			}
		}	
		
		// place all the pieces
		board[1][1] = "R"; board[2][1] = "N"; board[3][1] = "B"; board[4][1] = "Q"; board[5][1] = "K"; board[6][1] = "B"; board[7][1] = "N"; board[8][1] = "R";
		board[1][2] = "P"; board[2][2] = "P"; board[3][2] = "P"; board[4][2] = "P"; board[5][2] = "P"; board[6][2] = "P"; board[7][2] = "P"; board[8][2] = "P";
		board[1][8] = "r"; board[2][8] = "n"; board[3][8] = "b"; board[4][8] = "q"; board[5][8] = "k"; board[6][8] = "b"; board[7][8] = "n"; board[8][8] = "r";
		board[1][7] = "p"; board[2][7] = "p"; board[3][7] = "p"; board[4][7] = "p"; board[5][7] = "p"; board[6][7] = "p"; board[7][7] = "p"; board[8][7] = "p";	

	}
	
	// move to the indicated move
	function ChangeMove(movenum) {	
		if (movenum >= movelist.length) {
			movenum = movelist.length - 1;
		}
		InitializeBoard();
		for (var i=0;i<=movenum;i++) {
			MakeMove(movelist[i]);
		}
		curMove = movenum;
		UpdateBoard();
	}
	
	// change the current move number
	function AddToMoveNum(value) {
		movenum = curMove + value;
		if (movenum < 0) {
			curMove = -1;
			InitializeBoard();
			UpdateBoard();
		}
		else {
			if (movenum >= movelist.length) {
				movenum = movelist.length - 1;
			}
			curMove = movenum;
			ChangeMove(movenum);
		}
	}
	
	// gets a move from the movelist and makes it on the board
	function MakeMove(move) {
		var strMove = String(move);	
		// move the piece
		var origX = strMove.substr(0,1);
		var origY = strMove.substr(1,1);
		var destX = strMove.substr(2,1);
		var destY = strMove.substr(3,1);
		
		// check for en passant
		if (board[origX][origY] == "p") {
			// pawn not on the same file, so it captures
			if (origX != destX) {
				// there's no piece currently on the destination square...must be en passant
				if (board[destX][destY] == "-") {
					// remove the piece one square in back  of dest square
					board[destX][destY + 1] = "-"
				}
			}
		}
		if (board[origX][origY] == "P") {
			// pawn not on the same file, so it captures
			if (origX != destX) {
				// there's no piece currently on the destination square...must be en passant
				if (board[destX][destY] == "-") {
					// remove the piece one square in back  of dest square
					board[destX][destY - 1] = "-"
				}
			}
		}
		
		board[destX][destY] = board[origX][origY];
		board[origX][origY] = "-";
		
		
		
		// check for castling -- if so, move rook as well
		if ((board[destX][destY] == "k") && (move == 5878)) {
			MakeMove(8868);
		}
		else if ((board[destX][destY] == "k") && (move == 5838)) {
			MakeMove(1848);
		}
		else if ((board[destX][destY] == "K") && (move == 5171)) {
			MakeMove(8161);
		}
		else if ((board[destX][destY] == "K") && (move == 5131)) {
			MakeMove(1141);
		}
		
		// check for promotion -- if so, replace the pawn
		if (strMove.length > 4) {
			switch (strMove.substr(4,1)) {
				case "1":
					if (destY == 1) {
						board[destX][destY] = "q";
					}
					else {
						board[destX][destY] = "Q";
					}
					break;				
				case "2":
					if (destY == 1) {
						board[destX][destY] = "r";
					}
					else {
						board[destX][destY] = "R";
					}
					break;			
				case "3":
					if (destY == 1) {
						board[destX][destY] = "b";
					}
					else {
						board[destX][destY] = "B";
					}
					break;				
				case "4":
					if (destY == 1) {
						board[destX][destY] = "n";
					}
					else {
						board[destX][destY] = "N";
					}
					break;				
				default:
					if (destY == 1) {
						board[destX][destY] = "q";
					}
					else {
						board[destX][destY] = "Q";
					}
					break;
			}
		}
		
	}
	
	function UpdateBoard() {
		// move the pieces
		for (var i=1;i<=8;i++) {
			for (var j=1;j<=8;j++) {
				switch (board[i][j]) {
					case "-":
						document.getElementById(String(i) + String(j)).style.backgroundImage="url()";
						break;
					case "K":
						document.getElementById(String(i) + String(j)).style.backgroundImage="url('./images/chess/K.gif')";
						break;
					case "Q":
						document.getElementById(String(i) + String(j)).style.backgroundImage="url('./images/chess/Q.gif')";
						break;
					case "R":
						document.getElementById(String(i) + String(j)).style.backgroundImage="url('./images/chess/R.gif')";
						break;
					case "B":
						document.getElementById(String(i) + String(j)).style.backgroundImage="url('./images/chess/B.gif')";
						break;
					case "N":
						document.getElementById(String(i) + String(j)).style.backgroundImage="url('./images/chess/N.gif')";
						break;
					case "P":
						document.getElementById(String(i) + String(j)).style.backgroundImage="url('./images/chess/P.gif')";
						break;
					case "k":
						document.getElementById(String(i) + String(j)).style.backgroundImage="url('./images/chess/bk.gif')";
						break;
					case "q":
						document.getElementById(String(i) + String(j)).style.backgroundImage="url('./images/chess/bq.gif')";
						break;
					case "r":
						document.getElementById(String(i) + String(j)).style.backgroundImage="url('./images/chess/br.gif')";
						break;
					case "b":
						document.getElementById(String(i) + String(j)).style.backgroundImage="url('./images/chess/bb.gif')";
						break;
					case "n":
						document.getElementById(String(i) + String(j)).style.backgroundImage="url('./images/chess/bn.gif')";
						break;
					case "p":
						document.getElementById(String(i) + String(j)).style.backgroundImage="url('./images/chess/bp.gif')";
						break;
				}
			}
		}
		
		// also update the game status (whose turn, move num)
		var strTurn = "";
		var theID = "";
		if (curMove % 2 == 0) {
			strTurn = "Black to play, move ";
			theID = "B";
		}
		else {
			strTurn = "White to play, move ";
			theID = "W";
		}
		
		strTurn += String( (Math.round( (curMove + 2) / 2 ) ) );
		theID += String( (Math.round( (curMove + 2) / 2 ) ) );
		
		document.getElementById('turnStatus').innerHTML = strTurn;
		// highlight the current move as well.  Set all the other moves to normal weight, and emphasize the current move
		setStyleByClass('div','chessGameMove','fontWeight','normal');
		document.getElementById(theID).fontWeight = 'bold';
	}