var moves = new Array(0,0 );  // to be filled in with the moves in pairs of integers (0=a8, 63=h1)
var names = new Array( );
var base = -1;				// to initialize only
var pieces = "KQNBR ";
var nMoves = 0;
var EmptyWhitePath = "w.gif";
var EmptyBlackPath = "b.gif";
var basename = "board";
var hasStartedMove = false;
var isWhitesMove = true;
var frm=0;
totalMoves = 0;

// load all images into cache while modem connected
im = new Image;
im= "wqb.gif"; im= "wkw.gif"; im= "bqw.gif"; im= "bkb.gif";
im= "fwpw";im= "fwbw";im= "fwnw";im= "fwrw";im= "fwqw";im= "fwkw";
im= "fwpb";im= "fwbb";im= "fwnb";im= "fwrb";im= "fwqb";im= "fwkb";
im= "fbpw";im= "fbbw";im= "fbnw";im= "fbrw";im= "fbqw";im= "fbkw";
im= "fbpb";im= "fbbb";im= "fbnb";im= "fbrb";im= "fbqb";im= "fbkb";

// Function to find which image on the page begins the chess board
function SyncPicture( )
{	if ( base > -1 )
		 return base;  // this function only really needed once

	for ( i=0; i < document.images.length; i++ )
	{	if ( document.images[i].name != "" )
			if ( document.images[i].name == basename )
				return i;
			else
				i+= 63;
	}
	return -1;
}

// record the move from square "f" (from) to "t" (to)
function RecordMove(f, t) 
{
	moves[2*nMoves] = f;
	moves[2*nMoves+1] = t;
	//alert("move "+(nMoves)+" = "+moves[2*nMoves]+", "+moves[2*nMoves+1]);
}

// Function either to start or finish a move
function Move(sqNum)
{  	
	if(hasStartedMove)
     	{	//Time to complete a move
		to =  sqNum;
		// delete the 'f' so that it stops flashing
		gif = document.images[base+frm].src;
		len = gif.length;
	     	document.images[base+frm].src =gif.substring(0,len-8) + gif.substring(len-7,len);

		// If moving back to square moved from, cancel the move
   	     	hasStartedMove = false;
		if(to != frm)
		{	// Okay, call it a legal move, even if taking ones own piece

			//Before recording it, check to see if it is queening
			movingPiece = gif.substring(len-6,len-5);
			f=0;	// used as a flag to note if castling or en passant
			t=0;
			if( movingPiece == 'p')
			{	if( ( to<8 && isWhitesMove) ||	( to>55 && !isWhitesMove) )
				{ 	//Somebody probably wants another queen, but let's make sure
					piece = prompt("Enter name of piece you'd like", "queen").substring(0,1);
					setBits = 0x80;	// Queen is default
					if (piece == "r")
						 setBits = 0x200; 
					else if (piece == "b")
						 setBits = 0x180;
					else if (piece == "k" || piece == "n" || piece == "h")
						 setBits = 0x100;
					frm |= setBits;
				}
				// Now check for en passant
				if( (to-frm)%8 != 0 )
				{	// The pawn is capturing.  If it is capturing to an empty square then e.p.
					gif = document.images[base+to].src;
					len = gif.length;
	     				if(gif.substring(len-6,len-5) == '/')
					{	// Aha!  The square is empty!  That's en passant
						f = frm+64; // Calculate as if the empty square moves to capture piece
						t = isWhitesMove? to+8: to-8;
					}
				}
			}

			RecordMove(frm, to);

			//Check to see if castling
			if(frm == 4 && movingPiece == 'k')
			{	if(to == 6)
				{	f = 71;  // Black kingside
					t = 5;
				}
				else if(to == 2)
				{	f = 64; // Black queenside
					t = 3;
				}
			}
			if(frm == 60 && movingPiece == 'k')
			{	if(to == 62)
				{	f = 127;
					t = 61;
				}
				else if(to == 58)
				{	f = 120;
					t = 59;
				}
			}
			if(f>0 )
			{	//En passant or castling: add an extra move
				isWhitesMove = !isWhitesMove;	// toggle an extra time
				totalMoves = nMoves+1;  // if a correction, throw away everything hereafter
				MoveForward( );
				moves[2*nMoves] = f;
				moves[2*nMoves+1] = t;
			}
			totalMoves = nMoves+1;  	// if a correction, throw away everything hereafter
			return MoveForward( );		// increments Moves
		}
       }
      else
      {	// Time to Start a Move
     		base = SyncPicture( ); // really only called the first time
            frm = sqNum;
            gif = document.images[base+frm ].src;
		len = gif.length;

		// Make sure there is a piece to move of the correct color
		wORb = gif.substring(len-7,len-6);
		if(wORb != 'w' && wORb != 'b')
			return; //  unoccupied square, but let's not punish them

		if( isWhitesMove && wORb == 'b')
		{	alert ("It is white's turn to move.");
			return;
		}
		else if( !isWhitesMove && wORb == 'w')
		{	alert ("It is black's turn to move");
			return;
		}
		
		// Insert an "f" into the source name to display the flashing version
		var fgif = gif.substring(0,len-7) + "f" + gif.substring(len-7,len);
            document.images[base+ frm ].src=fgif;
            hasStartedMove = true;
      }
 		return GetMoveString( );  // return current move string
}

function GoStart( )
{	
	while ( nMoves > 0 )
		MoveBack( );

	return "";
}

function GoEnd( )
{	
	while ( nMoves < totalMoves )
		MoveForward( );

	return GetMoveString( );
}

function MoveForward( )
{	
	if ( nMoves < totalMoves )
	{	var n = nMoves*2;
		var from = moves[ n ] & 0x3f;  // Values over 63 reserved for double move (castling or e.p.)
		var to = moves[ n+1 ] & 0x3f;
		names[ n   ] = document.images[ base + from ].src;
		names[ n+1 ] = document.images[ base + to ].src;
		var len = names[n].length;
		var nn = (Math.floor(( to / 8 )) + ( to % 8 ));
		var dest = ( nn % 2 ) == 1 ? "b" : "w";

		// The piece that will land on the square is usually the same as the one being moved
		var piece = names[n].substring(len-6,len-5);

		//But in the case of pawn promotion, it becomes a new piece
		newPieceBits = moves[ n ] & 0x380;
		if (newPieceBits == 0x80 )
			piece = "q";
		else if (newPieceBits == 0x100 )
			piece = "n";
		else if (newPieceBits == 0x180 )
			piece = "b";
		else if (newPieceBits == 0x200 )
			piece = "r";

		document.images[ base + to ].src = names[n].substring(0,len-6) + piece + dest + 				names[n].substring(len-4,len);
		nn = (Math.floor(( from / 8 )) + ( from % 8 ));
		if (( nn % 2 ) == 1 )
			document.images[ base + from ].src = EmptyBlackPath;
		else
			document.images[ base + from ].src = EmptyWhitePath;
		nMoves++;
		isWhitesMove = !isWhitesMove;

		// Check for castling or en passant
		if ( nMoves < totalMoves && ( moves[ nMoves*2 ] & 0x40 ) == 0x40 )
		{	isWhitesMove = !isWhitesMove;	// toggle an extra time
			MoveForward( );
		}
	}
	return GetMoveString( );
}

function MoveBack( )
{	
	if ( nMoves > 0 )
	{	nMoves--;
		isWhitesMove = !isWhitesMove;
		var from = moves[ nMoves*2 ] & 0x3f;
		var to = moves[ nMoves*2+1 ] & 0x3f;
		document.images[ base + from ].src = names[ nMoves*2 ];
		document.images[ base + to ].src = names[ nMoves*2+1 ];
		if (( moves[ nMoves*2 ] & 0x40 ) == 0x40 )
		{	isWhitesMove = !isWhitesMove;	// toggle an extra time
			MoveBack( );
		}
	}
	return GetMoveString( );
}

function GetMoveString( )
{	
	if ( nMoves > 0 && nMoves <= totalMoves )
	{	var n = (nMoves-1)*2;
		var from = moves[ n ] & 0x3f;
		var to = moves[ n+1 ] & 0x3f;
		var len = document.images[ base + to ].src.length;
		var piece = document.images[ base + to ].src.substring(len-6,len-5);
		if ( piece == "q" )
			piece = pieces.substring(1,2);
		else if ( piece == "r" )
			piece = pieces.substring(4,5);
		else if ( piece == "b" )
			piece = pieces.substring(3,4);
		else if ( piece == "n" )
			piece = pieces.substring(2,3);
		else if ( piece == "k" )
			piece = pieces.substring(0,1);
		else piece = pieces.substring(5,6);
		var piece2 = "";
		if (( moves[ n ] & 0x380 ) == 0x80 )
			piece2 = pieces.substring(1,2);
		else if (( moves[ n ] & 0x380 ) == 0x100 )
			piece2 = pieces.substring(2,3);
		else if (( moves[ n ] & 0x380 ) == 0x180 )
			piece2 = pieces.substring(3,4);
		else if (( moves[ n ] & 0x380 ) == 0x200 )
			piece2 = pieces.substring(4,5);
		var lines = "abcdefgh";
		var rows = "87654321";
		var fromLine = from%8;
		var fromRow = Math.floor(from/8);
		var toLine = to%8;
		var toRow = Math.floor(to/8);
		var off=1;  // used to track a double move (castling or en passant)
		for ( i=0; i <= n; i += 2 )
			if (( moves[i] & 0x40 ) == 0x40 )
				off = off+1;
		var result = (Math.floor((nMoves-off)/2)+1).toString() + ". ";
		if ( document.images[ base + to ].src.substring(len-7,len-6) == "b" )
			result = result + "... ";
		if ( n >= 2 && (( moves[n] & 0x40 ) == 0x40 ))
		{	if (( moves[n-1] == 62 ) || ( moves[n-1] == 6 ))
				result = result + "0-0"
			else if (( moves[n-1] == 2 + 7 * 8 ) || ( moves[n-1] == 2 + 0 * 8 ))
				result = result + "0-0-0"
			else // it's not castling so it must be en passant
			{	var sep = "x";
				from = moves[ n-2 ] & 0x3f;
				to = moves[ n-1 ] & 0x3f;
				fromLine = from%8;
				fromRow = Math.floor(from/8);
				toLine = to%8;
				toRow = Math.floor(to/8);
				result = result	+ lines.substring( fromLine, fromLine+1 ) + rows.substring( fromRow, 						fromRow+1 )	+ sep + lines.substring( toLine, toLine+1 ) 
						+ rows.substring( toRow, toRow+1 ) + piece2 + " ep";
			}
		}
		else
		{	var len = names[ n+1 ].length;
			var substr = names[ n+1 ].substring( len-6, len );
			var sep = (( substr == "/w.gif" ) || ( substr == "\\w.gif" ) ||
						  ( substr == "/b.gif" ) || ( substr == "\\b.gif" )) ? "-" : "x";
			if ( piece2 != "" ) piece = "";
			result = result + piece.toUpperCase() + lines.substring( fromLine, fromLine+1 ) 
				+ rows.substring( fromRow, fromRow+1 ) + sep + lines.substring( toLine, toLine+1 )
				+ rows.substring( toRow, toRow+1 ) + piece2;
		}
		return result;
	}
	return "";
}

function outGame(g )
{	// Output the game to a new browser window
	nW = window.open(' ')
	nW.document.write('<HTML><HEAD><TITLE>Chess Game<\/TITLE>')
	nW.document.writeln('<SCRIPT language="JavaScript" type="text\/javascript">')
	//nW.document.writeln(' <!-- Hide from old browsers')
	nW.document.write('var moves = new Array('+moves[0])
	for(i=1; i<moves.length; i++)
		nW.document.write(', '+moves[i])

	nW.document.writeln(' )')
	nW.document.writeln('var basename = "board" <\/SCRIPT>')
	nW.document.write(' <SCRIPT language="JavaScript" type="text\/javascript" src="chess_game.js">')
	//nW.document.writeln(' hiding done from non Java Browsers -->')
	nW.document.writeln(' <\/SCRIPT>')

	// Repeat the Javascript, but TOTALLY Hidden, because the above one was executed!
	nW.document.writeln('<FAKESCRIPT language="JavaScript" type="text\/javascript" ')
	nW.document.write('var moves = new Array('+moves[0])
	for(i=1; i<moves.length; i++)
		nW.document.write(', '+moves[i])

	nW.document.writeln(' )')
	nW.document.writeln('var basename = "board" ><\/FAKESCRIPT>')
	nW.document.write(' <FAKESCRIPT language="JavaScript" type="text\/javascript" src="chess_game.js">')
	nW.document.writeln(' <\/FAKESCRIPT>')

	nW.document.writeln('<\/HEAD><BODY><CENTER><H1>Chess Game<\/H1>')
	nW.document.writeln('<B> White: ' +g.white.value+ '.<\/B><BR>')
	//The "." after the name is so it doesn't look like last name is Black to search engine results lists
	nW.document.writeln('<B> Black: ' +g.black.value+ '.<\/B><BR>')
	nW.document.writeln('Date: '+g.date.value+'<\/CENTER>')
	nW.document.writeln('<P>')
	nW.document.writeln('<CENTER><TABLE border=4><TR><TD><IMG SRC="brw.gif"')
	nW.document.writeln('name="board"><IMG SRC="bnb.gif"><IMG SRC="bbw.gif"><IMG')
	nW.document.writeln('SRC="bqb.gif"><IMG SRC="bkw.gif"><IMG SRC="bbb.gif"><IMG')
	nW.document.writeln('SRC="bnw.gif"><IMG SRC="brb.gif"><BR><IMG SRC="bpb.gif"><IMG')
	nW.document.writeln('SRC="bpw.gif"><IMG SRC="bpb.gif"><IMG SRC="bpw.gif"><IMG')
	nW.document.writeln('SRC="bpb.gif"><IMG SRC="bpw.gif"><IMG SRC="bpb.gif"><IMG')
	nW.document.writeln('SRC="bpw.gif"><BR><IMG SRC="w.gif"><IMG SRC="b.gif"><IMG')
	nW.document.writeln('SRC="w.gif"><IMG SRC="b.gif"><IMG SRC="w.gif"><IMG SRC="b.gif"><IMG')
	nW.document.writeln('SRC="w.gif"><IMG SRC="b.gif"><BR><IMG SRC="b.gif"><IMG SRC="w.gif"><IMG')
	nW.document.writeln('SRC="b.gif"><IMG SRC="w.gif"><IMG SRC="b.gif"><IMG SRC="w.gif"><IMG')
	nW.document.writeln('SRC="b.gif"><IMG SRC="w.gif"><BR><IMG SRC="w.gif"><IMG SRC="b.gif"><IMG')
	nW.document.writeln('SRC="w.gif"><IMG SRC="b.gif"><IMG SRC="w.gif"><IMG SRC="b.gif"><IMG')
	nW.document.writeln('SRC="w.gif"><IMG SRC="b.gif"><BR><IMG SRC="b.gif"><IMG SRC="w.gif"><IMG')
	nW.document.writeln('SRC="b.gif"><IMG SRC="w.gif"><IMG SRC="b.gif"><IMG SRC="w.gif"><IMG')
	nW.document.writeln('SRC="b.gif"><IMG SRC="w.gif"><BR><IMG SRC="wpw.gif"><IMG')
	nW.document.writeln('SRC="wpb.gif"><IMG SRC="wpw.gif"><IMG SRC="wpb.gif"><IMG')
	nW.document.writeln('SRC="wpw.gif"><IMG SRC="wpb.gif"><IMG SRC="wpw.gif"><IMG')
	nW.document.writeln('SRC="wpb.gif"><BR><IMG SRC="wrb.gif"><IMG SRC="wnw.gif"><IMG')
	nW.document.writeln('SRC="wbb.gif"><IMG SRC="wqw.gif"><IMG SRC="wkb.gif"><IMG')
	nW.document.writeln('SRC="wbw.gif"><IMG SRC="wnb.gif"><IMG')
	nW.document.writeln('SRC="wrw.gif"><\/TD><\/TR><\/TABLE><BR>')
	nW.document.writeln('<FORM><INPUT type=text name="movStr" VALUE=" Click &gt;" SIZE=16>')
	nW.document.writeln('<INPUT type=button value=" Start " onClick="movStr.value=GoStart( )">')
	nW.document.writeln('<INPUT type=button value=" &lt; " onClick="movStr.value=MoveBack( )">')
	nW.document.writeln('<INPUT type=button value=" &gt; " onClick="movStr.value=MoveForward( )">')
	nW.document.writeln('<INPUT type=button value=" End " onClick="movStr.value=GoEnd( )">')
	nW.document.writeln('<\/FORM><\/CENTER>')

	//Now write the moves out, so it can be printed.
	GoStart( );
	realMoveNum = 0;
	while (nMoves < totalMoves)
	{	
		s = MoveForward( );
		if(isWhitesMove)
		{	//if it was black's move on the last move, replace " . . ." with ","
			realMoveNum++;
			nW.document.write(', '+s.substring(realMoveNum>9? 8: 7, s.length)+'. ');
		}
		else
			nW.document.write(s);  // write White's move
	}
	nW.document.writeln('<\/BODY><\/HTML> ')
	nW.document.close( );
}