API Docs for:
Show:

File: js/script.js

/**
Main module
@module Main
**/

/**
Main methods
This is not actually a class, but a necessary convention to get YUIdoc to document standalone items.
@class Main
*/


var board;
var promotionCoor;
var selectedPiece;
var game_id = 0;
var drawOffer = "none";
var userId;
var timerId;
var topClock = 0;
var bottomClock = 0;

 /**
 * Recursively calls ajax request to check for the start of the game
 * @method reqGame
 * @return {Object} ajax result
 */
function reqGame() {
	return $.ajax({
		url: "server.php?action=requestGame",
		datatype: 'json'
	}).then(function (result) {
		if(result.data.game_id != null) {
			board.setBoard(result.data);
			board.drawPieces();
			displayDrawOffer(result.data.draw_offer)
			game_id 	= result.data.game_id;
			setClock(result.data.white_clock, result.data.black_clock);
			$('#pre-post-game').hide();
			
			if(board.side != result.data.side_to_move) {
				reqMove(result.data.game_id).done();
			} else {
				$('#buttons').fadeIn("fast");
			}
			
			$('#bottom-clock').show();
			$('#top-clock').show();
			return;
		} else {
    		return reqGame();
		}
    });
}

/**
 * Recursively calls ajax request to check for an opponent move
 * @method reqGame
 * @param {Number} game_id the id of the game
 * @return {Object} ajax result
 */
function reqMove(game_id) {
	return $.ajax({
		url:"server.php?action=requestMove&game_id=" + game_id,
		datatype: 'json',
	}).then(function(result){
		if(result.data.game_state != "in progress") {
			finishGame(result.data.game_state, result.data.game_finished);
			return;
		}
		
		if(board.side == result.data.side_to_move) {
			if(result.data.draw_offer == "none") {
				$('#buttons').fadeIn("fast");
			}
			setClock(result.data.white_clock, result.data.black_clock);
			board.setBoard(result.data);
			board.drawPieces();
			displayDrawOffer(result.data.draw_offer);
			requestHistory(game_id).then(function(res){
				updateHistoryTable(res);
			});
			
			return;
		} else {
    		return reqMove(game_id).done();
		}
    });
}

/**
 * Sends ajax request to submit a move
 * @method submitMove
 * @param {Number} game_id the id of the game
 * @param {String} fen Forsyth–Edwards notation of the current state of the chess game
 * @param {String} move notation representation of the move
 * @param {String} castling valid values are 'long', 'short' or 'none'
 * @param {String} enpassant the notation coordinates of the pawn which can be taken en passant
 * @param {Number} draw_moves number of moves to finish a game under 50 moves rule
 * @param {String} wlc white long castling right, valid values 'true' and 'false'
 * @param {String} wsc white short castling right, valid values 'true' and 'false'
 * @param {String} blc black short castling right, valid values 'true' and 'false'
 * @param {String} bsc black short castling right, valid values 'true' and 'false'
 * @param {String} result the result of the game in case the game has finished, valid values are 'white', 'black or 'draw'
 * @param {String} gameFinished the reason to finish the game
 */
function submitMove(game_id, fen, move, castling, enpassant, draw_moves, wlc, wsc, blc, bsc, result, gameFinished) {
	$('#opponent-draw-offer').hide();
	$('#cancel-a-draw').hide();
	$('#offer-a-draw').show();
	$('#buttons').fadeOut("fast");
	
	return $.ajax({
		url:"server.php?action=submitMove",
		data: {
			game_id			:game_id, 
			fen				:fen,
			move			:move,
			castling		:castling,
			enpassant		:enpassant,
			draw_moves		:draw_moves,
			wlc				:wlc,
			wsc				:wsc,
			blc				:blc,
			bsc				:bsc,
			draw_offer		:drawOffer,
			result			:result,
			game_finished	:gameFinished
		}
	}).then(function(res){	
		updateHistoryTable(res);
		reqMove(game_id);
	});
}

/**
 * ajax request to retrieve game history
 * @method requestHistory
 * @param {Number} game_id the id of the game
 * @return {Object} ajax result
 */
function requestHistory(game_id) {
	return $.ajax({
		url:"server.php?action=requestHistory&game_id="+game_id,
		datatype: 'json',
	}).promise();
}

/**
 * ajax request to submit the result of the game
 * @method submitResult
 * @param {String} result the result of the game, valid values are 'black', 'white' or 'draw'
 * @param {String} game_finished the reason to finish the game
 * @return {Object} ajax result
 */
function submitResult(result, game_finished) {
	return $.ajax({
		url:"server.php?action=finishGame&game_id="+game_id+"&result="+result+"&game_finished="+game_finished,
		datatype: 'json',
	}).promise();
}

/**
 * ajax request to connect to the server
 * @method connect
 * @return {Object} ajax result
 */
function connect() {
	return $.ajax({
		url:"server.php?action=connect",
		datatype: 'json',
	}).promise();
}

/**
 * ajax request to stop the search for the game
 * @method stopSearch
 * @return {Object} ajax result
 */
function stopSearch() {
	return $.ajax({
		url:"server.php?action=stopSearch",
		datatype: 'json'
	}).promise();
}

/**
 * renders the chess board in case of initial window load or window resize events
 * @method render
 */
function render(){ 
    var c = $('#chess-board');
    c.attr('width', $(c).parent().width()); 
    c.attr('height', $(c).parent().height());
    
    var c2 = $('#chess-pieces'); 
    c2.attr('width', $(c2).parent().width()); 
    c2.attr('height', $(c2).parent().height());
    
    var c3 = $('#legal-moves');  
    c3.attr('width', $(c3).parent().width()); 
    c3.attr('height', $(c3).parent().height());
    
    var c4 = $('#field-highlight');  
    c4.attr('width', $(c4).parent().width()); 
    c4.attr('height', $(c4).parent().height());
	
	var c5 = $('#promote-pawn');
    c5.attr('width', $(c4).parent().width()); 
    c5.attr('height', $(c4).parent().height());
	
	board.drawBoard();
	board.drawPieces();
}

/**
 * document.load event
 * @method load
 */
$(function() {	
    $(window).resize(render);
    $('#field-highlight').mousemove(mousemove);
    $('#field-highlight').mouseleave(mouseleave);
    $('#field-highlight').click(click);
	$('#promote-pawn').hide();
	$('#promote-pawn').click(clickPromote);
	$('#cancel-search').hide();
	$('#play-again').hide();
	$('#bottom-clock').hide();
	$('#top-clock').hide();
	$('#white-to-promote').hide();
	$('#black-to-promote').hide();
	$('#opponent-draw-offer').hide();
	$('#buttons').hide();
	$('#start-search-button').click(requestGame);
	$('#cancel-search-button').click(cancelGame);
	$('#play-again-button').click(playAgain);
	$('#offer-a-draw').click(offerDrawClick);
	$('#cancel-a-draw').click(cancelDrawClick);
	$('#accept-a-draw').click(acceptDrawClick);
	$('#resign').click(resignClick);
	
	connect().done(function(res){
		userId = res.data.user_id;
	});
	
	board = new Board();
	render();
});

/**
 * hides #play-again div, shows #cancel-search and requests for the game
 * @method requestGame
 */
function requestGame() {
	$('#play-again').hide();
	$('#start-search').fadeOut('slow').promise().done(function(){
		$('#cancel-search').fadeIn('slow');
	});
	reqGame().done();
}

/**
 * hides #cancel-search div, shows #start-search and sends stop search request to the server
 * @method cancelGame
 */
function cancelGame() {
	$('#play-again').hide();
	$('#cancel-search').fadeOut('slow').promise().done(function(){
		$('#start-search').fadeIn('slow');
	});
	stopSearch().then(function(){});
}

/**
 * hides #start-search div, shows #cancel-search and requests for the game
 * @method playAgain
 */
function playAgain() {
	$('#start-search').hide();
	$('#play-again').fadeOut('slow').promise().done(function(){
		$('#cancel-search').fadeIn('slow');
	});
	reqGame().done();
}

/**
 * updates history table 
 * @param {Object} res data to be colected from the requestHistory ajax request
 * @method updateHistoryTable
 */
function updateHistoryTable(res){
	$("#target-to-update tr").remove();
	for(var i = 0; i < res.data.length; i++) {
		if((i)%2==0) {
			if(i != res.data.length - 1) continue;
			else {
				var w = res.data[i].move;
				$('#target-to-update tbody').append('<tr><td>'+((i/2)+1)+'</td><td>'+w+'</td><td></td></tr>');
				break;
			}
		}
		var w = res.data[i-1].move;
		var b = res.data[i].move;
		$('#target-to-update tbody').append('<tr><td>'+((i+1)/2)+'</td><td>'+w+'</td><td>'+b+'</td></tr>');
	}
	var h = 99999;
	$('#table').slimScroll({ scrollTo : h });
}

/**
 * display draw offer menu 
 * @param {String} offer offer side, valid values are 'white', 'black' or 'none'
 * @method displayDrawOffer
 */
function displayDrawOffer(offer) {
	$('#cancel-a-draw').fadeOut('fast').promise().done(function(){
		$('#offer-a-draw').fadeIn('fast').css("display","inline-block");
	});
	
	if(offer == "none") {
		$('#opponent-draw-offer').hide();
		drawOffer = "none";
		return;
	}
	if(offer != board.side) {
		$('#buttons').fadeOut("fast");
		$('#cancel-a-draw').fadeOut('fast');
		$('#offer-a-draw').fadeOut('fast');
		$('#opponent-draw-offer').fadeIn('fast');
	}
}

/**
 * displays the game result and prompts user to start new game
 * @param {String} result result of the game, valid values are 'white', 'black' or 'draw'
 * @param {String} message the reason to finish the game
 * @method finishGame
 */
function finishGame(result, message) {
	if(result == "white") {
		$('#game-summary').html(message);
		$('#game-result').html("1 - 0");
	}
	
	if(result == "black") {
		$('#game-summary').html(message);
		$('#game-result').html("0 - 1");
	}
	
	if(result == "draw") {
		$('#game-summary').html(message);
		$('#game-result').html("&#x00BD; - &#x00BD;");
	}
	
	$('#play-again').show();
	$('#cancel-search').hide();
	$('#pre-post-game').fadeIn();
	
	$('#bottom-clock').hide();
	$('#top-clock').hide();
	clearInterval(timerId);
}

/**
 * sets a clock
 * @param {Number} wc white side clock
 * @param {Number} bc black side clock
 * @method setClock
 */
function setClock(wc,bc){
	
	if(board.side == "white") {
		topClock = bc;
		bottomClock = wc;
	} else {
		topClock = wc;
		bottomClock = bc;
	} 
	
	clearInterval(timerId);
	timerId = setInterval(function() {
		if(board.sideToMove == board.side) {
			bottomClock--;
		} else {
			topClock--;
		}
		
		if(bottomClock <= 0) {
			if(board.side == "white") {
				submitResult("black", "White lost on time");
				finishGame("black", "White lost on time");
				clearInterval(timerId);
			} else {
				submitResult("white", "Black lost on time");
				finishGame("white", "Black lost on time");
				clearInterval(timerId);
			}
		}
		
		if(topClock <= 0) {
			if(board.side == "white") {
				submitResult("white", "Black lost on time");
				finishGame("white", "Black lost on time");
				clearInterval(timerId);
			} else {
				submitResult("black", "White lost on time");
				finishGame("black", "White lost on time");
				clearInterval(timerId);
			}
		}
		
		$("#top-clock").text(unixTimeStampToTimerString(topClock));
		$("#bottom-clock").text(unixTimeStampToTimerString(bottomClock));
		
	},1000)
}