$(document).ready(function() {
	var jChess = new ChessBoard();
	var moveNumber = null;

	$("#GameSearch").field();
	$("#GameUsername").field();
	$("#GameOpponent").field();

	$("#GameSearchForm").submit(function() {
		$(this).attr("action", "/games/" + $("#GameSearch").val());
		
		$(this).submit();
		
		return false;
	});

	$("#GameNewGameForm input[type='submit']").click(function() {
		if (($("#GameNewGameForm input[name='data[Game][opponent]']").val() == "Twitter Name") || ($("#GameNewGameForm input[name='data[Game][username]']").val() == "Twitter Name")) {
			alert("You must specify an opponent by providing a Twitter username");
			return false;
		}
	});

	$("#logout .admin .apply-move").click(function() {
		return confirm("Are you sure you wish to apply the mode suggested move to the current community game?");
	});

	$("#accept-draw").click(function() {
		if ($("#Type").val() == "private") {
			$("#MoveVoteText").val("@ChessTweets @" + $("#Opponent").val() + " 1/2-1/2 ");
		} else {
			$("#MoveVoteText").val("@ChessTweets 1/2-1/2 ");
		}

		$("#MoveVoteText").tweet("setCursor", ($("#MoveVoteText").val().length), 2);

		return false;
	});

	$("#offer-draw").click(function() {
		if (/@ChessTweets\s+\S+/.test($("#MoveVoteText").val())) {
			if ($("#Type").val() == "private") {
				$("#MoveVoteText").val().match(/(@ChessTweets\s+\S+\s+)(\S+)(.*)/);
			} else {
				$("#MoveVoteText").val().match(/(@ChessTweets\s+)(\S+)(.*)/);
			}

			var pre_move = RegExp.$1;
			var move = RegExp.$2;
			var post_move = RegExp.$3;

			if (move) {
				$("#MoveVoteText").val(pre_move + move + "=" + post_move);
				$("#MoveVoteText").tweet("setCursor", ($("#MoveVoteText").val().length), 2);
			} else {
				alert("Please specify a move before offering a draw.");
			}
		} else {
			alert("Please specify a move before offering a draw.");
		}

		return false;
	});

	$("#resign").click(function() {
		if (/[wW]/.test($("#Turn").val())) {
			if ($("#Type").val() == "private") {
				$("#MoveVoteText").val("@ChessTweets @" + $("#Opponent").val() + " 0-1 ");
			} else {
				$("#MoveVoteText").val("@ChessTweets 0-1 ");
			}
		} else {
			if ($("#Type").val() == "private") {
				$("#MoveVoteText").val("@ChessTweets @" + $("#Opponent").val() + " 1-0 ");
			} else {
				$("#MoveVoteText").val("@ChessTweets 1-0 ");
			}
		}

		$("#MoveVoteText").tweet("setCursor", ($("#MoveVoteText").val().length), 2);

		return false;
	});

	$("#commentsubmit").click(function() {
		if (/@ChessTweets\s+\S+/.test($("#MoveCommentText").val())) {
			if ($("#GameBoard").val() != "") {
				if (($("#Player").val() == $("#" + $("#Turn").val()).val()) || ($("#" + $("#Turn").val()).val() == "ChessTweets")) {
					var MoveChecker = new ChessBoard();
					MoveChecker.setBoard($("#GameBoard").val());

					if ($("#Type").val() == "private") {
						$("#MoveCommentText").val().match(/@ChessTweets\s+\S+\s+(\S+)/);
					} else {
						$("#MoveCommentText").val().match(/@ChessTweets\s+(\S+)/);
					}

					var move = RegExp.$1;
					var moves = MoveChecker.parseMove(move);

					if (moves) {
						if (moves.length > 0) {
							if (moves.length == 1) {
								$("#MoveCommentCreateForm").submit();
							} else {
								alert("Given move \"" + move + "\" is ambiguous. Please re-check that you are not commenting on a move that can't be made.");
							}
						} else {
							alert("Given move \"" + move + "\" is not a valid move. Please re-check that you are not commenting on a move that can't be made.");
						}
					} else {
						alert("Given move \"" + move + "\" is not in algebraic notation. Please re-check your move syntax.");
					}
				} else {
					alert("Comments are not allowed at this time.");
				}
			} else {
				alert("You may not make a comment on a non-existent game.");
			}
		} else {
			alert("Given tweet is not in the correct format: \"@ChessTweets Move Comments\"");
		}

		return false;
	});

	$("#submit").click(function() {
		if (/@ChessTweets\s+\S+/.test($("#MoveVoteText").val())) {
			if ($("#GameBoard").val() != "") {
				if (($("#Player").val() == $("#" + $("#Turn").val()).val()) || ($("#" + $("#Turn").val()).val() == "ChessTweets")) {
					var MoveChecker = new ChessBoard();
					MoveChecker.setBoard($("#GameBoard").val());

					if ($("#Type").val() == "private") {
						$("#MoveVoteText").val().match(/@ChessTweets\s+\S+\s+(\S+)/);
					} else {
						$("#MoveVoteText").val().match(/@ChessTweets\s+(\S+)/);
					}

					var move = RegExp.$1;
					var moves = MoveChecker.parseMove(move);

					if (moves) {
						if (moves.length > 0) {
							if (moves.length == 1) {
								$("#MoveVoteCreateForm").submit();
							} else {
								alert("Given move \"" + move + "\" is ambiguous. Please specify a rank or file to denote a source square.");
							}
						} else {
							alert("Given move \"" + move + "\" is not a valid move. Please re-check that you are not moving the wrong piece or attempting to move into check.");
						}
					} else {
						alert("Given move \"" + move + "\" is not in algebraic notation. Please re-check your move syntax.");
					}
				} else {
					alert("It's not your turn. Please make sure you are logged in as the correct user.");
				}
			} else {
				alert("You may not make a move on a non-existent game.");
			}
		} else {
			alert("Given tweet is not in the correct format: \"@ChessTweets Move Comments\"");
		}

		return false;
	});

	if ($("#MoveVoteText").length > 0) {
		$("#MoveVoteText").tweet({counter: "#tweetchars"});
	}

	if ($("#MoveCommentText").length > 0) {
		$("#MoveCommentText").tweet({counter: "#commentchars"});
	}

	$("#game-moves a").click(function() {

		jChess.setBoard($(this).attr("board"));
		placePieces();

		$("#game-moves a").css({"background-color": "#ffffff"});
		$(this).css({"background-color": "#ffff00"});

		$("#tweet .tweeter-image").html("<a href=\"/games/" + $(this).attr("player").toLowerCase() + "\"><img src=\"" + $(this).attr("player_image") + "\" alt=\"" + $(this).attr("player") + "\" /></a>");
		
		if (/\.2/.test($(this).attr("number"))) {
			$("#tweet .tweet-title").html("<a href=\"/games/" + $(this).attr("player").toLowerCase() + "\">" + $(this).attr("player") + "</a> <span>" + $(this).attr("number").substr(0, $(this).attr("number").length - 1) + " ... " + $(this).attr("move") + "</span> (" + $(this).attr("time_since") + ")");
		} else {
			$("#tweet .tweet-title").html("<a href=\"/games/" + $(this).attr("player").toLowerCase() + "\">" + $(this).attr("player") + "</a> <span>" + $(this).attr("number").substr(0, $(this).attr("number").length - 1) + " " + $(this).attr("move") + " ...</span> (" + $(this).attr("time_since") + ")");
		}

		$("#tweet .captured-pieces").html(getCapturedPieces());

		if (/@ChessTweets\s+\S+\s+/.test($(this).attr("tweet_text"))) {
			$("#tweet .tweet-text").html($(this).attr("tweet_text"));
		} else {
			$("#tweet .tweet-text").html("@ChessTweets " + $(this).attr("move") + " " + $(this).attr("tweet_text"));        
		}

		$("#fen").html("<strong>FEN</strong>: " + $(this).attr("board"));

		$("#CurrentMove").val($(this).attr("number"));

		return false;
	});

	if ($("#game-moves a[number='" + $("#CurrentMove").val() + "']").length > 0) {
		$("#game-moves a[number='" + $("#CurrentMove").val() + "']").trigger("click");
		moveNumber = $("#CurrentMove").val();
	} else if ($("#GameBoard").length > 0) {
		if ($("#GameBoard").val() != "") {
			jChess.setBoard("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
			placePieces();
			moveNumber = "1.1";
		}
	}

	$("#game-controls a[title='Start']").click(function() {
		$("#game-moves a[number='" + $(this).attr("number") + "']").trigger("click");
		$("#CurrentMove").val($(this).attr("number"));

		return false;
	});
	
	$("#game-controls a[title='Prev']").click(function() {
		var number = $("#CurrentMove").val();
		
		if (/\.2/.test(number)) {
			number = Math.round((parseFloat(number) - .1) * 100) / 100;
		} else {
			number = Math.round((parseFloat(number) - .9) * 100) / 100;
		}
		
		if (number > $("#game-controls a[title='End']").attr("number")) {
			number = $("#game-controls a[title='End']").attr("number");
		}

		if ($("#game-moves a[number='" + number + "']").length > 0) {
			$("#game-moves a[number='" + number + "']").trigger("click");
			$("#CurrentMove").val(number);
		}
		
		return false;
	});

	$("#game-controls a[title='Next']").click(function() {
		var number = $("#CurrentMove").val();

		if (/\.2/.test(number)) {
			number = Math.round((parseFloat(number) + .9) * 100) / 100;
		} else {
			number = Math.round((parseFloat(number) + .1) * 100) / 100;
		}

		if (number < $("#game-controls a[title='Start']").attr("number")) {
			number = $("#game-controls a[title='Start']").attr("number");
		}

		if ($("#game-moves a[number='" + number + "']").length > 0) {
			$("#game-moves a[number='" + number + "']").trigger("click");
			$("#CurrentMove").val(number);
		}

		return false;
	});
	
	$("#game-controls a[title='End']").click(function() {
		$("#game-moves a[number='" + $(this).attr("number") + "']").trigger("click");
		$("#CurrentMove").val($(this).attr("number"));
		
		return false;
	});

	$("#comment-list .paginator a").click(function() {
		return loadComments($(this), $("#comment-list"));
	});

	$("#move-comments.tabs").tabs({selected: 0, show: function(evt, ui) {
		$("#MoveCommentText").val("@ChessTweets " + $(ui.tab).text()  + " ");
	}});

	function loadComments(anchor, container) {
		var href = anchor.attr("href");

		$("#tweet").after('<span class="spinner" style="float:right;"><img src="/img/busy.gif" /></span>');

		container.slideUp(500, function() {
			$("#game-moves a[number='" + anchor.attr("number") + "']").trigger("click");

			$.ajax({
				method: "get",
				url: href,

				success: function(html) {
					container.html(html);

					$("#comment-list .paginator a").click(function() {
						return loadComments($(this), $("#comment-list"));
					});

					$("#move-comments.tabs").tabs({selected: 0, show: function(evt, ui) {
						$("#MoveCommentText").val("@ChessTweets " + $(ui.tab).text()  + " ");
					}});

					container.slideDown(250, function() {
						$(".spinner").remove();
						$.scrollTo($("#move-comments"), 500, {offset: -10});
					});
				}
			});
		});

		return false;
	}

	function getCapturedPieces() {
		var pieceArray = new Array();
		var capturedPieces = "";

		pieceArray["p"] = 0;
		pieceArray["r"] = 0;
		pieceArray["n"] = 0;
		pieceArray["b"] = 0;
		pieceArray["q"] = 0;
		pieceArray["P"] = 0;
		pieceArray["R"] = 0;
		pieceArray["N"] = 0;
		pieceArray["B"] = 0;
		pieceArray["Q"] = 0;

		for (var i = 0; i < jChess.board.length; i++) {
			if (/[prnbqkPRNBQK]/.test(jChess.board[i])) {
				pieceArray[jChess.board[i]]++;
			}
		}

		capturedPieces = capturedPieces + getCapturedImage(8, pieceArray["P"], "WP");
		capturedPieces = capturedPieces + getCapturedImage(2, pieceArray["N"], "WN");
		capturedPieces = capturedPieces + getCapturedImage(2, pieceArray["B"], "WB");
		capturedPieces = capturedPieces + getCapturedImage(2, pieceArray["R"], "WR");
		capturedPieces = capturedPieces + getCapturedImage(1, pieceArray["Q"], "WQ");

		capturedPieces = capturedPieces + getCapturedImage(8, pieceArray["p"], "BP");
		capturedPieces = capturedPieces + getCapturedImage(2, pieceArray["n"], "BN");
		capturedPieces = capturedPieces + getCapturedImage(2, pieceArray["b"], "BB");
		capturedPieces = capturedPieces + getCapturedImage(2, pieceArray["r"], "BR");
		capturedPieces = capturedPieces + getCapturedImage(1, pieceArray["q"], "BQ");

		return capturedPieces;
	}

	function getCapturedImage(total, onBoard, pieceImage) {
		if (total - onBoard > 0) {
			if (total - onBoard > 1) {
				if ((pieceImage == "WP") || (pieceImage == "BP")) {
					return '<li><img src="/img/' + pieceImage + '.png" width="16" height="16" /><sup style="margin-left:-4px">x' + (total - onBoard) + '</sup></li>';
				} else if ((pieceImage == "WB") || (pieceImage == "BB")) {
					return '<li><img src="/img/' + pieceImage + '.png" width="16" height="16" /><sup style="margin-left:-3px">x' + (total - onBoard) + '</sup></li>';
				} else if ((pieceImage == "WN") || (pieceImage == "BN") || (pieceImage == "WR") || (pieceImage == "BR")) {
					return '<li><img src="/img/' + pieceImage + '.png" width="16" height="16" /><sup style="margin-left:-2px">x' + (total - onBoard) + '</sup></li>';
				} else if ((pieceImage == "WQ") || (pieceImage == "BQ")) {
					return '<li><img src="/img/' + pieceImage + '.png" width="16" height="16" /><sup>x' + (total - onBoard) + '</sup></li>';
				}
			} else {
				return '<li><img src="/img/' + pieceImage + '.png" width="16" height="16" /></li>';
			}
		}
		
		return "";
	}

	function placePieces() {
		var pieceArray = new Array();

		$("#game-board .square").droppable("destroy");
		$("#game-board .square").removeClass("legal");

		for (var i = 0; i < jChess.board.length; i++) {
			var square = $("#" + jChess.getSquareId(i));
				
			if (/[prnbqkPRNBQK]/.test(jChess.board[i])) {
				if (jChess.board[i] == square.attr("pieceChar")) {
					pieceArray[square.attr("pieceId")] = "";
				} else if (square.attr("pieceId") > 0) {
					pieceArray[square.attr("pieceId")] = square.attr("pieceChar");
					square.attr("pieceId", 0);
					square.attr("pieceChar", "");
				}
			} else if (square.attr("pieceId") > 0) {
				pieceArray[square.attr("pieceId")] = square.attr("pieceChar");
				square.attr("pieceId", 0);
				square.attr("pieceChar", "");
			}
		}

		for (var i = 0; i < jChess.board.length; i++) {        
			var square = $("#" + jChess.getSquareId(i));
			var pieceId = 1;

			if (/[prnbqkPRNBQK]/.test(jChess.board[i])) {
				if (jChess.board[i] != square.attr("pieceChar")) {
					for (pieceId; pieceId < 65; pieceId++) {                   
						if (typeof pieceArray[pieceId] == "undefined") {                        
							square.append(pieceImage(jChess.board[i], pieceId, jChess.getSquareId(i)));
							square.attr("pieceId", pieceId);
							square.attr("pieceChar", jChess.board[i]);

							$("#P" + pieceId).attr("square", jChess.getSquareId(i));
							$("#P" + pieceId).css({opacity: 0, top: square.position().top + 5, left: square.position().left + 6});
							$("#P" + pieceId).animate({opacity: 1}, 400, "linear", null);

							bindDrag(pieceId);
							pieceArray[pieceId] = "";
							break;
						} else {                       
							if (pieceArray[pieceId] == jChess.board[i]) {
								square.attr("pieceId", pieceId);
								square.attr("pieceChar", jChess.board[i]);

								$("#P" + pieceId).attr("square", jChess.getSquareId(i));
								$("#P" + pieceId).animate({top: square.position().top + 5, left: square.position().left + 6}, 400, "linear", null);

								bindDrag(pieceId);
								pieceArray[pieceId] = "";
								break;
							}
						}
					}
				}
			}
		}

		for (var pieceId in pieceArray) {
			if (pieceArray[pieceId] != "") {
				$("#P" + pieceId).animate({opacity: "hide"}, 400, "linear", function() {
					$(this).remove();
				});
			}
		}
	}

	function bindDrag(pieceId) {    
		$("#P" + pieceId).draggable({
			revert: "invalid",

			start: function(event, ui) {            
				var fromSquare = $("#" + $(this).attr("square"));
				var squareIndex = fromSquare.attr("index");

				var moves = jChess.getPieceMoves(squareIndex, true);
				var moveList = getMoveList(moves);

				var pawnPromotionChar = null;

				if (moveList != "") {
					$(moveList).addClass("legal");

					$(moveList).droppable({
						hoverClass: "hover",

						drop: function(event, ui) {                           
							updateSquare(ui.draggable.attr("square"), 0, "");

							if ($(this).attr("pieceId") > 0) {
								$("#P" + $(this).attr("pieceId")).animate({opacity: "hide"}, 400, "linear", function() {
									$(this).remove();
								});

								updateSquare($(this).attr("id"), 0, "");
							}

							updateSquare($(this).attr("id"), ui.draggable.attr("pieceId"), ui.draggable.attr("pieceChar"));

							ui.draggable.attr("square", $(this).attr("id"));
							ui.draggable.animate({top: $(this).position().top + 5, left: $(this).position().left + 6}, 400, "linear", null);

							if ((ui.draggable.attr("pieceChar") == "P") && ($(this).attr("index") == jChess.enPassant)) {
								removeEnPassantPawn(parseInt($(this).attr("index")) + 10);
							} else if ((ui.draggable.attr("pieceChar") == "p") && ($(this).attr("index") == jChess.enPassant)) {
								removeEnPassantPawn(parseInt($(this).attr("index")) - 10);
							} else if ((ui.draggable.attr("pieceChar") == "P") && (/8/.test($(this).attr("id")))) {
								promotePawn($(this).attr("index"), ui.draggable.attr("pieceId"), (pawnPromotionChar = "Q"));
							} else if ((ui.draggable.attr("pieceChar") == "p") && (/1/.test($(this).attr("id")))) {
								promotePawn($(this).attr("index"), ui.draggable.attr("pieceId"), (pawnPromotionChar = "q"));
							}

							if ((fromSquare.attr("id") == "e1") && ($(this).attr("id") == "g1") && (ui.draggable.attr("pieceChar") == "K")) {
								castleKingSide($("#h1").attr("pieceId"), "R", 1);
							} else if ((fromSquare.attr("id") == "e1") && ($(this).attr("id") == "c1") && (ui.draggable.attr("pieceChar") == "K")) {
								castleQueenSide($("#a1").attr("pieceId"), "R", 1);
							} else if ((fromSquare.attr("id") == "e8") && ($(this).attr("id") == "g8") && (ui.draggable.attr("pieceChar") == "k")) {
								castleKingSide($("#h8").attr("pieceId"), "r", 8);
							} else if ((fromSquare.attr("id") == "e8") && ($(this).attr("id") == "c8") && (ui.draggable.attr("pieceChar") == "k")) {
								castleQueenSide($("#a8").attr("pieceId"), "r", 8);
							}

							if ($("#CurrentMove").val() == moveNumber) {
								if (($("#Player").val().toLowerCase() == "chesstweets") || ($("#" + $("#Turn").val()).val() == $("#Player").val())) {
									if ($("#Type").val() == "private") {
										$("#MoveVoteText").val("@ChessTweets @" + $("#Opponent").val() + " " + jChess.getAlgebraicMove(fromSquare.attr("index"), $(this).attr("index"), pawnPromotionChar) + " ");
									} else {
										$("#MoveVoteText").val("@ChessTweets " + jChess.getAlgebraicMove(fromSquare.attr("index"), $(this).attr("index"), pawnPromotionChar) + " ");
									}

									$("#MoveVoteText").tweet("setCursor", ($("#MoveVoteText").val().length), 2);
								}
							}

							$("#game-moves a").css({"background-color": "#ffffff"});
							$("#CurrentMove").val("1.0");

							jChess.applyMove(fromSquare.attr("index"), $(this).attr("index"), pawnPromotionChar);
						}
					});
				}
			},

			stop: function(event, ui) {
				$("#game-board .square").droppable("destroy");                
				$("#game-board .square").removeClass("legal");
			}
		});
	}

	function updateSquare(squareId, pieceId, pieceChar) {
		$("#" + squareId).attr("pieceId", pieceId);
		$("#" + squareId).attr("pieceChar", pieceChar);
	}

	function removeEnPassantPawn(index) {
		var capturedSquare = $("#game-board .square[index=" + index + "]");
		var capturedPiece = $("#P" + capturedSquare.attr("pieceId"));
		
		updateSquare(capturedSquare.attr("id"), 0, "");
		
		capturedPiece.animate({opacity: "hide"}, 400, "linear", function() {
			$(this).remove();
		});
	}

	function promotePawn(index, pieceId, pieceChar) {
		var promotedSquare = $("#game-board .square[index=" + index + "]");

		updateSquare(promotedSquare.attr("id"), pieceId, pieceChar);

		$("#P" + pieceId).animate({opacity: "hide"}, 400, "linear", function() {
			$(this).remove();

			promotedSquare.append(pieceImage(pieceChar, pieceId, promotedSquare.attr("id")));

			$("#P" + pieceId).css({opacity: 0, top: promotedSquare.position().top + 5, left: promotedSquare.position().left + 6});
			$("#P" + pieceId).animate({opacity: 1}, 400, "linear", null);

			bindDrag(pieceId);
		});
	}

	function castleKingSide(rookId, rookChar, row) {
		updateSquare("h" + row, 0, "");
		updateSquare("f" + row, rookId, rookChar);

		$("#P" + rookId).attr("square", "f" + row);
		$("#P" + rookId).animate({top: $("#f" + row).position().top + 5, left: $("#f" + row).position().left + 6}, 400, "linear", null);
	}

	function castleQueenSide(rookId, rookChar, row) {
		updateSquare("a" + row, 0, "");
		updateSquare("d" + row, rookId, rookChar);

		$("#P" + rookId).attr("square", "d" + row);
		$("#P" + rookId).animate({top: $("#d" + row).position().top + 5, left: $("#d" + row).position().left + 6}, 400, "linear", null);
	}

	function pieceImage(pieceChar, pieceId, square) {
		if (/[prnbqkPRNBQK]/.test(pieceChar)) {
			return "<img id=\"P" + pieceId + "\" class=\"piece\" src=\"/img/" + (/[PRNBQK]/.test(pieceChar) ? "W" : "B") + pieceChar.toUpperCase() + ".png\" pieceId=\"" + pieceId + "\" pieceChar=\"" + pieceChar + "\" square=\"" + square + "\" />";
		} else {
			return null;
		}
	}

	function getMoveList(moves) {
		for (var i = 0; i < moves.length; i++) {
			moves[i] = "#" + jChess.getSquareId(moves[i]);
		}
		
		return moves.join(", ");
	}
});