﻿//(C) 2006 by R. Andrew Lamonica

AttachEvent(window, "load", ReversaOnDocumentLoad);

var reversaXMLCollector = null;
var reversaBoard = null;

function ReversaOnDocumentLoad()
{
	var board = document.getElementById("reversaBoard");
	var data = document.getElementById("reversaData");
	var pictureList = {
		"X " : "white.png", 
		"O " : "black.png", 
		". " : "blank.png",
		"X+" : "whiteJustPlayed.png",
		"O+" : "blackJustPlayed.png",
		".p" : "whitePossiblePlays.png"};
	var clickUpdateFunction = spaceClicked;

	var gridDataHolder = new GridDataHolder(data, 8, 8,
		". . . . . . . . " + 
		". . . . . . . . " + 
		". . . . . . . . " + 
		". . . X O . . . " + 
		". . . O X . . . " + 
		". . . . . . . . " + 
		". . . . . . . . " + 
		". . . . . . . . ",
		2, ".e");
	reversaBoard = new DynamicBoard(clickUpdateFunction, board, gridDataHolder, pictureList);
	reversaBoard.ComputerMoved = computerMoved;
	reversaBoard.RequestMove = requestMove;
	reversaBoard.ScoreOf = scoreOf;
	reversaBoard.NewGame = newGame;
	
	//Prepare StatusBAr and it's accessor
	reversaBoard.StatusBar = document.getElementById("StatusBar");
	reversaBoard.SetStatus = setStatus;
	
	//Prepare Possible Move Showing Capbility
	reversaBoard.ShowPossibleMoves = false;
	reversaBoard.ToggleShowPossibleMoves = toggleShowPossibleMoves;
	reversaBoard.DisplayPossibleMoves = displayPossibleMoves;	
	
	reversaBoard.NewGame();
}

function toggleShowPossibleMoves()
{
	this.ShowPossibleMoves = !this.ShowPossibleMoves;
	if(this.ShowPossibleMoves)
		this.DisplayPossibleMoves();
	else
	{
		for(var r=0; r<8; r++)
		{
			for(var c=0; c<8; c++)
			{
				if(this.Data.Get(r,c)==".p")
					this.Data.Set(r,c, ". ");
			}
		}	
	}
	this.Refresh();
}

function displayPossibleMoves()
{
	if(this.ShowPossibleMoves)
	{
		for(var i=0; i<this.PossibleMoves.length; i++)
		{
			this.Data.Set(
				this.PossibleMoves[i].Row, 
				this.PossibleMoves[i].Column,
				".p");
		}
	}
}

function setStatus(statusText, statusLink)
{
	var theBar = this.StatusBar;
	var info = null;
	
	if(statusLink==null)
	{
		info = document.createTextNode(statusText);
	}
	else
	{
		info = document.createElement("a");
		info.href = statusLink;
		info.appendChild(document.createTextNode(statusText));
	}
	
	
	if(theBar.childNodes.length==0)
		theBar.appendChild(info);
	else
		theBar.replaceChild(info, theBar.childNodes[0]);
}

function newGame()
{
	this.LastComputerMove = null;
	reversaBoard.PossibleMoves = new Array(
		{"Row" : 2, "Column" : 4},
		{"Row" : 3, "Column" : 5},
		{"Row" : 4, "Column" : 2},
		{"Row" : 5, "Column" : 3});
	this.Data.Reset();
	this.Refresh();
	this.SetStatus("You play white and go first.  Click on the board to move or click here to go second.", "javascript:reversaBoard.RequestMove()");
}

function scoreOf(player)
{
	var data = this.Data.GetValue();
	var score = 0;
	for(var i=0; i<data.length; i++)
		if(data.charAt(i)==player)
			score++;
	return score;
}

function requestMove()
{
	var board = this;
	board.SetStatus("The computer is thinking.");
	reversaXMLCollector = new XMLHttpRequest(); 
	reversaXMLCollector.onreadystatechange = function() {board.ComputerMoved()};
	reversaXMLCollector.open("GET", "get_computers_move.php?Board=" + 
		board.Data.GetValue().replace(/([^.XO])/g, ""), true);
    reversaXMLCollector.send(null);    
}

function computerMoved()
{
	if(reversaXMLCollector.readyState == 4)
	{
		if(reversaXMLCollector.status!=200)
		{
			alert("Problem getting Computer's Move (Code=" + reversaXMLCollector.status + ")");
		}
		else
		{
			var xmldoc = reversaXMLCollector.responseXML;
			var root_node = xmldoc.getElementsByTagName('Board').item(0);

			var newBoard = root_node.firstChild.data;
			this.Data.SetValue( newBoard.replace(/([XO.])/g, "$1 ") );
						
			var possMoves = xmldoc.getElementsByTagName('PossibleMove');
			var numberOfMoves = possMoves.length;
			this.PossibleMoves = new Array(numberOfMoves);
			for(var i=0; i<numberOfMoves; i++)
			{
				var move = possMoves.item(i);
				var row = parseInt(dataFromChild(move, "Row"),10);
				var col = parseInt(dataFromChild(move, "Column"),10);
				this.PossibleMoves[i] = {"Row" : row, "Column" : col};
			}
			
			var computerMadeAMove = (xmldoc.getElementsByTagName('Move').length==1);
			if(computerMadeAMove)
			{
				var move = xmldoc.getElementsByTagName('Move').item(0);
				this.LastComputerMove = new Object();
				this.LastComputerMove.Row = parseInt(dataFromChild(move, "Row"),10);
				this.LastComputerMove.Column = parseInt(dataFromChild(move, "Column"),10);
				this.Data.Set(this.LastComputerMove.Row,this.LastComputerMove.Column,"O+");			
			}
			
			this.DisplayPossibleMoves();
			//Changes have been made refresh the board.
			this.Refresh();
			
			//If user has no moves
			if(numberOfMoves==0)
			{
				var boardData = this.Data.GetValue();
				var newGameURL = "javascript:reversaBoard.NewGame()";
				
				//If there are no spaces left or the compter also has no moves
				//Then the game is over show who wins
				if(boardData.indexOf(".")==-1 || !computerMadeAMove)
				{
					var myscore = this.ScoreOf("X");
					var computerscore = this.ScoreOf("O");
					if(myscore > computerscore)
						this.SetStatus("You Win.  Click here to play again.",newGameURL);
					else if(computerscore > myscore)
						this.SetStatus("You Lose.  Click here to play again.",newGameURL);
					else
						this.SetStatus("We Tied.  Click here to play again.",newGameURL);						
					
				}
				else if(boardData.indexOf("O")==-1)
					this.SetStatus("You Win.  Click here to play again.",newGameURL);			
				else if(boardData.indexOf("X")==-1)
					this.SetStatus("You Lose.  Click here to play again.",newGameURL);			
				else
				{
					this.SetStatus("You have no legal moves.  Click here to Pass.", 
								"javascript:reversaBoard.RequestMove()");
				}
			}
			else if(numberOfMoves==1)
				this.SetStatus("You have " + numberOfMoves + " legal move.", "javascript:reversaBoard.ToggleShowPossibleMoves()");	
			else
				this.SetStatus("You have " + numberOfMoves + " legal moves.", "javascript:reversaBoard.ToggleShowPossibleMoves()");				
		}
		reversaXMLCollector = null;
	}
}


function makeMove(row, col, data)
{
	var changesMade = false;
	var rdelta, cdelta, curR, curC;
	for(rdelta=-1; rdelta<2; rdelta++)
	{
		for(cdelta=-1; cdelta<2; cdelta++)
		{
			if(cdelta!=0 || rdelta!=0)
			{
				curR = row+rdelta;
				curC = col+cdelta;
				if(data.Get(curR,curC).charAt(0)=="O")
				{
					do
					{
						curR+=rdelta;
						curC+=cdelta;				    
					}while(data.Get(curR,curC).charAt(0)=="O");
					
					if(data.Get(curR,curC).charAt(0)=="X")
					{
						changesMade = true;
						while(data.Get(curR,curC).charAt(0)!=".")
						{
							data.Set(curR,curC,"X ");
							curR-=rdelta;
							curC-=cdelta;				    
						}
					}
				}
			}
		}
	}
	if(changesMade)
		data.Set(row,col,"X+");
	return changesMade;
}

function spaceClicked(current_value, row, col, data, tableCell, theBoard)
{
	if(reversaXMLCollector!=null || current_value.charAt(0)!=".")
		return current_value;
	if(makeMove(row,col,data))
	{
		//Remove the Computer's "Last Played" marker
		if(theBoard.LastComputerMove!=null && 
			data.Get(theBoard.LastComputerMove.Row,theBoard.LastComputerMove.Column)=="O+")
		{
			data.Set(theBoard.LastComputerMove.Row,theBoard.LastComputerMove.Column,"O ");	
		}
		//Remove All our "possible move" markers
		data.SetValue(data.GetValue().replace(/[.]p/g,". "));
		//Start request for other guy's move.
		theBoard.RequestMove();
		return null;
	}
	else
		return current_value;
}

function dataFromChild(node, childName)
{
	return node.getElementsByTagName(childName).item(0).firstChild.data;
}
