var	pawn = 1;
var	knight = 2;
var	king = 3;
var	bishop = 5;
var	rook = 6;
var	queen = 7;
var	empty = null;

var white = 0;
var black = 1;
var enemy = [1,0];

var pieceCode = {'p':1, 'n':2, 'k':3, 'b':5, 'r':6, 'q':7};
var pieceLetter = [0, 'p', 'n', 'k', 0, 'b', 'r', 'q'];
var pieceCodeToName = [0, 'pawn', 'knight', 'king', 0, 'bishop', 'rook', 'queen'];
var pieceCount = 0;			// Number of pieces on the board

var moveOffset =
    [
     [-15, -16, -17, 0],	// Black pawn
     [17, 16, 15, 0],		// White pawn
     [ 18, 33, 31, 14, -18, -33, -31, -14, 0 ],  // knight motion
     [ 1, 17, 16, 15, -1, -17, -16, -15, 0 ],    // king motion
     0,
     [ 17, 15, -17, -15, 0 ],                    // bishop and pawn capture
     [ 1, 16, -1, -16, 0 ],                      // rook
     [ 1, 17, 16, 15, -1, -17, -16, -15, 0 ]     // queen motion
    ];

var diagrams = new Array();
var diagNmbr = 0;
var squareSize = 0;
var theBoard;
var board = new Array(128);
var castlingRights = [3, 3];
var pieces = new Array();
var sideToMove;
var epSquare = -1;
var moveList = new Array();
var clicked = 0x08;
var movesDepth = new Array();
var FENs = new Array();
var moveIndex = 0;



///////////////////////////////////////////////////////
var squareColors =
	[
	 ['black', 'white'],			// Normal
	 ['blackmarked', 'whitemarked']		// Highlighted
	];


function setSquareBg(square, highlight) {
	var tcol = (square & 0x0F) + 1;
	var trow = 8 - (square >> 4);
	var rows = theBoard.getElementsByTagName('tr');
	var row = rows[trow].getElementsByTagName('td');
	var col = row[tcol];
	if(highlight) {
		col.className = squareColors[1][(square + trow) & 0x01];
	} else {
		col.className = squareColors[0][(square + trow) & 0x01];
	}
}


//////////////////////////////////////////////
function expandFEN(FEN) {
	var i;
	var ones = new Array ('', '1' ,'11', '111', '1111', '11111', '111111', '1111111', '11111111');
	var theFEN = '';
	for(i = 0; i < FEN.length; i++) {
		if(FEN.charAt(i) > '1' && FEN.charAt(i) < '9') {
			theFEN += (ones[Number(FEN.charAt(i))]);
		} else {
			theFEN = theFEN + '' +  FEN.charAt(i);
		}
	}
	return theFEN.replace(/\//g, "");                     // Leave only pieces and empty squares
}

function FENToBoard(FEN) {
	var FENItems = new Array();
	var pieceNbr;
	var pieceColor;
	var i;
	for(i = 0; i <= 127; i++) {
		board[i] = null;
	}
	pieces[white] = new Array();
	pieces[black] = new Array();
	var j = 111;
	for(i = 0; FEN.charAt(i) != ' '; i++) {
		if(FEN.charAt(i) >= '1' && FEN.charAt(i) <= '8') {
			j += parseInt(FEN.charAt(i));
		} else if(FEN.charAt(i) == '/') {
			j -= 24;
		} else {
			j++;
			if(FEN.charAt(i).toLowerCase() != FEN.charAt(i)) {
				pieceColor = white;
			} else {
				pieceColor = black;
			}
			pieceNbr = pieces[pieceColor].length;
			pieces[pieceColor][pieceNbr] = new Object();
			pieces[pieceColor][pieceNbr].pieceValue = pieceCode[FEN.charAt(i).toLowerCase()];
			pieces[pieceColor][pieceNbr].pieceColor = pieceColor;
			pieces[pieceColor][pieceNbr].pieceLocation = j;
			board[j] = pieces[pieceColor][pieceNbr];
		}
	}
	FENItems = FEN.split(' ');
	if(FENItems[1] == 'w') {
		sideToMove = white;
	} else {
		sideToMove = black;
	}
	castlingRights[0] = 0;
	castlingRights[1] = 0;
	if(FENItems[2] != '-') {
		j = 0;
		for(i = 0; i < FENItems[2].length; i++) {
			if(FENItems[2].charAt(i).toLowerCase() == FENItems[2].charAt(i)) {
				j = 1;
			}
			if(FENItems[2].charAt(i).toLowerCase() == 'k') {
				castlingRights[j] |= 1;
			} else {
				castlingRights[j] |= 2;
			}
		}
	}
	if(FENItems[3] == '-') {
		epSquare = -1;
	} else {
		epSquare = (FENItems[3].charCodeAt(0) - 'a'.charCodeAt(0));
		epSquare = epSquare + (FENItems[3].charAt(1) - 1) * 16;
	}
	return;
}

function validFEN(FEN) {	// Is the FEN string valid (draft, needs improvement)? No pawn on 1st/8th, castling, ep
	var FENItems = new Array();
	if(FEN.length < 17 || FEN.length > 150) {
		return false;
	}
	FENItems = FEN.split(' ');
	if(FENItems[0].length < 17 || FENItems.length < 2) {
//		alert('FEN: Too short');
		return false;
	}
	var ExpFEN = expandFEN(FENItems[0]);
	if(ExpFEN.length != 64) {		// There are 64 squares on a chessboard
//		alert('FEN: Piece placement field length not 64');
		return false;
	}
	var count = {'K':0, 'k':0, 'Q':0, 'q':0, 'R':0, 'r':0, 'B':0, 'b':0, 'N':0, 'n':0, 'P':0, 'p':0, '1':0};
	var c;
	for(var i=0; i < 64; i++) {
		c = ExpFEN.charAt(i);
		if(!count[c]) {
			count[c] = 1;
		} else {
			count[c]++;
		}
	}
	if(count['K'] != 1 || count['k'] != 1) {	// One white and one black king?
//		alert('FEN: Wrong number of kings');
		return false;
	}
	var total = count['K'] + count['k'] + count['Q'] + count['q'] + count['R'] + count['r'];
	total += count['B'] + count['b'] + count['N'] + count['n'] + count['P'] + count['p'] + count['1'];
	if(total != 64) { // Any unknown pieces?
//		alert('FEN: Unknown piece(s). Total: ' + total + ' ' + ExpFEN);
		return false;
	}
	pieceCount = total - count['1'];
	return true;
}

function XpieceToImageFile(piece, pieceColor) {
	var color;
	if(pieceColor == white) {
		color = 'white';
	} else {
		color = 'black';
	}
	return 'images/beholder/' + color + '_' + pieceCodeToName[piece] + '.gif';
}

function pieceToImageFile(piece, pieceColor) {
	var color;
	if(pieceColor == white) {
		color = 'w';
	} else {
		color = 'b';
	}
	var path = '/diagrams/pieces/';
	if(squareSize == '26px') {
		path = path + '24/';
	}
	return  path + color + pieceLetter[piece] + '.png';
}

function setSquare(square, piece) {
	var s;
	var row, rows;
	var img = new Array();

	var rank = square >> 4;
	var file = square & 0x0F;

	rows = theBoard.getElementsByTagName('tr');
	row = rows[8 - rank].getElementsByTagName('td');

	var sqr = row[file + 1];
	img = sqr.getElementsByTagName('img');
	if(piece !== null) {		// Non-empty square
		s = pieceToImageFile(piece, board[square].pieceColor);
		if(img.length > 0) {
			img[0].src = s;
//			sqr.replaceChild(pieceNodes[piece][board[square].pieceColor].cloneNode(false), img[0]);
		} else {
			var newImg = document.createElement('img');
			newImg.src = s;
			newImg.alt = pieceCodeToName[piece];
			newImg.className = 'chessman';
			sqr.appendChild(newImg);
//			sqr.appendChild(pieceNodes[piece][board[square].pieceColor].cloneNode(false));
		}
	} else if(img.length > 0) {
		sqr.removeChild(img[0]);
	}
	return;
}

function displaySideToMove(color) {
	var visibility = ['hidden', 'visible'];
	var row = theBoard.getElementsByTagName('tr')[0];
	var col = row.getElementsByTagName('td')[9];
	var marker = col.firstChild;
	marker.style.visibility = visibility[color];
	color = 1 - color;
	row = theBoard.getElementsByTagName('tr')[9];
	col = row.getElementsByTagName('td')[9];
	marker = col.firstChild;
	marker.style.visibility = visibility[color];
}

function displayBoard(sideToMove) {
	var i, j;
	for(i = 0; i <= 127; i++) {
		if(!(i & 0x88) && board[i] === null) {
			setSquare(i, null);
		}
	}
	for(j = white; j <= black; j++) {
		for(i = 0; i < pieces[j].length; i++) {
			setSquare(pieces[j][i].pieceLocation, pieces[j][i].pieceValue);
		}
	}
	displaySideToMove(sideToMove);
}

function displayDiagrams() {
	var divs = document.getElementsByTagName('div');
	var i;
	var theFEN;
	for(i = 0; i < divs.length; i++) {
		if(divs[i].className != 'fen') {
			continue;
		}
		if(divs[i].firstChild.nodeType == 3) {	// Is it the FEN string?
			theFEN = divs[i].firstChild.data;
		} else if(divs[i].firstChild.firstChild.nodeType == 3) {
			theFEN = divs[i].firstChild.firstChild.data + divs[i].lastChild.data;	// It's inside a highlighted search string div-em-/em-/div
		} else {
			continue;
		}
		if(validFEN(theFEN)) {
			FENToBoard(theFEN);
			var aBoard = DOMChessboard();
			theBoard = aBoard;
			if(squareSize == 0) {
				var tRow = theBoard.getElementsByTagName('tr')[1];
				if(window.getComputedStyle) {
					squareSize = window.getComputedStyle(tRow, null).height;
				} else if(tRow.currentStyle) {
					squareSize = tRow.currentStyle.height;
				}
			}
			displayBoard(sideToMove);
			divs[i].appendChild(theBoard);

			diagrams[diagNmbr] = new Object;
			diagrams[diagNmbr].theBoard = aBoard;						// The DOM board object
			var j;
			diagrams[diagNmbr].board = new Array();
			for(j = 0; j < board.length; j++) {
				diagrams[diagNmbr].board[j] = board[j];					// The board representation
			}
			diagrams[diagNmbr].castlingRights = new Array();			// Castling rights
			diagrams[diagNmbr].castlingRights[0] = castlingRights[0];
			diagrams[diagNmbr].castlingRights[1] = castlingRights[1];
			diagrams[diagNmbr].pieces = new Array();
			for(j = 0; j < pieces.length; j++) {
				diagrams[diagNmbr].pieces[j] = pieces[j];				// The pieces on the board
			}
			diagrams[diagNmbr].sideToMove = sideToMove;					// The side to move
			diagrams[diagNmbr].epSquare = epSquare;						// The e.p. square
			diagrams[diagNmbr].clicked = clicked;						// Click status
			diagrams[diagNmbr].movesDepth = new Array();				// Depth of variation
			diagrams[diagNmbr].FENs = new Array();						// FENs for all positions in the game
			diagrams[diagNmbr].moveIndex = 0;							// The current move
//			alert('theFEN: ' + theFEN);
			diagrams[diagNmbr].FENs[0] = theFEN;
			diagNmbr = diagNmbr + 1;
			divs[i].style.display = 'block';							// DJ 2005-7-4
//			divs[i].appendChild(DOMBoardButtons());
		}
	}
}


function DOMChessboard() {	// Returns a DOM object for a chessboard
	var innerBorder = '2px solid #eee';

	// not styled with CSS: inner border, color of whosmove

	var whosMove = document.createElement('div');
	whosMove.className = 'whosmove';
	whosMove.style.backgroundColor = '#000';
	whosMove.style.visibility = 'hidden';
//	whosMove.appendChild(document.createTextNode('\240'));	// Non-breaking space (Also Unicode '\u00a0')
	whosMoveWhite = whosMove.cloneNode(false);

	var tblBoard = document.createElement('table');
	tblBoard.cellPadding = '0';
	tblBoard.className = 'chessboard';

	var tbody = document.createElement('tbody');
	tblBoard.appendChild(tbody);

	var i, j;
	for(j = 0; j < 10; j++) {	// Rows, starting from the top row
		var row = document.createElement('tr');
		if(j === 0 || j == 9) {
			row.className = 'border';
		}
		for(i = 0; i < 10; i++) {	// Columns, left to right
			var cell = document.createElement('td');	// Create a new cell
			if(i > 0 && i < 9 && j > 0 && j < 9) {	// Squares on the chessboard
				if((i + j) & 1) {	// Black square
					cell.className = 'black';
				} else {			// White square
					cell.className = 'white';
				}
				
			} else {	// Border
				if(i === 0 || i == 9) {		// CSS class
					cell.className = 'border';
				}

				if(j === 0) {		// Top border
					if(i == 9) {	// Top-left or top-right cells
						cell.appendChild(whosMove);
					} else if(i > 0) {
						cell.style.borderBottom = innerBorder;
					}

				} else if(j < 9) {
					if(i === 0) {	// Ranks on left border
						cell.appendChild(document.createTextNode(9 - j));
						cell.style.borderRight = innerBorder;
					} else if(j < 9) {
							cell.style.borderLeft = innerBorder;
					}
				} else if(i > 0) {	// j == 9
					if(i < 9) {
						cell.appendChild(document.createTextNode(String.fromCharCode('a'.charCodeAt(0) + i - 1)));
						cell.style.borderTop = innerBorder;
					} else {
						whosMoveWhite.style.background = '#FFF';
						cell.appendChild(whosMoveWhite);
					}
				}
			}
			row.appendChild(cell);
		}
		tbody.appendChild(row);
	}
	return tblBoard;
}

function createPieceNode(piece, pieceColor) {
	var pieceNode = document.createElement('img');
	pieceNode.src = pieceToImageFile(piece, pieceColor);
	pieceNode.alt = pieceCodeToName[piece];
	pieceNode.className = 'chessman';
	return pieceNode;
}

var pieceNodes = new Array();

function createPieceNodes() {
	var piece;
	var pieceColor;
	var p;
	for(p in pieceCode) {
		piece = pieceCode[p];
		pieceNodes[piece] = new Array();
		for(pieceColor = white; pieceColor <= black; pieceColor++) {
			pieceNodes[piece][pieceColor] = createPieceNode(piece, pieceColor);
		}
	}
}

function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}

addLoadEvent(displayDiagrams);
createPieceNodes();

//window.onload = function () {
//	displayDiagrams();
//};