////////////////////////////////////////
// SUDOKU - RAZZLE
////////////////////////////////////////
var Sudoku = function() {
	var Req, 
	    Data, 
	    ReturnObj = {
			failCount : 0
	   	};
	
	/////////////////////////////////////////////////////////////////////
	var init = function() {
		$("fl-reset").addEvent("click", function(event) {
			Sudoku.resetBoard();
			event.stop();
			return false;
		});
		$("fl-newgame").addEvent("click", function(event) {
			Sudoku.gutBoard();
			Sudoku.getSudoku();
			if (!!event) { event.stop(); }
			return false;
		});
		$("fl-print").addEvent("click", function(event) {
			Razzle.renderForPrint();
			event.stop();
			return false;
		});
		
		if (Razzle.puzzleJSON.length > 0) {
			parse(Razzle.puzzleJSON[0], !Browser.Engine.presto);
		} else {
			getSudoku();
		}
	};
	
	/////////////////////////////////////////////////////////////////////
	var getSudoku = function() {
		Req = new Request.JSON({ url : "/getSudoku/" + new Date().getTime(), method : "GET", secure : false });
		Req.addEvent("onComplete", function(sudoku) {
			if (!!sudoku && sudoku.length > 0) {
				Sudoku.parse(sudoku[0], !Browser.Engine.presto);
			} else if (Sudoku.failCount < 11) {
				Sudoku.failCount++;
				Sudoku.getSudoku();
			}
		});
		Req.get();
	};
	
	/////////////////////////////////////////////////////////////////////
	var parse = function(Fields, fadeIn) {
		Data = Fields;
		Data.current = Data.puzzle_grid.split("");
		Data.solution = Data.full_grid.split("");
		if (Data.current.length !== 81 || Data.solution.length !== 81) {
			Sudoku.failCount++;
			if (Sudoku.failCount < 11) {
				getSudoku();
			}
			return;
		}
		
		if (fadeIn) {
			$("puzzleBoard").setStyles({ "opacity" : 0.0, "visibility" : "hidden" });
		}
		
		if (!!$("sudokuGrid")) {
			$("sudokuGrid").dispose();
		}
		var sTable = "" + 
			"<table id='sudokuGrid'>" + 
			"	<tr>" + 
			"		<td id='s-0-0'>###</td><td id='s-0-1'>###</td><td id='s-0-2'>###</td>" + 
			"		<td id='s-0-3'>###</td><td id='s-0-4'>###</td><td id='s-0-5'>###</td>" + 
			"		<td id='s-0-6'>###</td><td id='s-0-7'>###</td><td id='s-0-8'>###</td>" + 
			"	</tr><tr>" + 
			"		<td id='s-1-0'>###</td><td id='s-1-1'>###</td><td id='s-1-2'>###</td>" + 
			"		<td id='s-1-3'>###</td><td id='s-1-4'>###</td><td id='s-1-5'>###</td>" + 
			"		<td id='s-1-6'>###</td><td id='s-1-7'>###</td><td id='s-1-8'>###</td>" + 
			"	</tr><tr>" + 
			"		<td id='s-2-0'>###</td><td id='s-2-1'>###</td><td id='s-2-2'>###</td>" + 
			"		<td id='s-2-3'>###</td><td id='s-2-4'>###</td><td id='s-2-5'>###</td>" + 
			"		<td id='s-2-6'>###</td><td id='s-2-7'>###</td><td id='s-2-8'>###</td>" + 
			"	</tr><tr>" + 
			"		<td id='s-3-0'>###</td><td id='s-3-1'>###</td><td id='s-3-2'>###</td>" + 
			"		<td id='s-3-3'>###</td><td id='s-3-4'>###</td><td id='s-3-5'>###</td>" + 
			"		<td id='s-3-6'>###</td><td id='s-3-7'>###</td><td id='s-3-8'>###</td>" + 
			"	</tr><tr>" + 
			"		<td id='s-4-0'>###</td><td id='s-4-1'>###</td><td id='s-4-2'>###</td>" + 
			"		<td id='s-4-3'>###</td><td id='s-4-4'>###</td><td id='s-4-5'>###</td>" + 
			"		<td id='s-4-6'>###</td><td id='s-4-7'>###</td><td id='s-4-8'>###</td>" + 
			"	</tr><tr>" + 
			"		<td id='s-5-0'>###</td><td id='s-5-1'>###</td><td id='s-5-2'>###</td>" + 
			"		<td id='s-5-3'>###</td><td id='s-5-4'>###</td><td id='s-5-5'>###</td>" + 
			"		<td id='s-5-6'>###</td><td id='s-5-7'>###</td><td id='s-5-8'>###</td>" + 
			"	</tr><tr>" + 
			"		<td id='s-6-0'>###</td><td id='s-6-1'>###</td><td id='s-6-2'>###</td>" + 
			"		<td id='s-6-3'>###</td><td id='s-6-4'>###</td><td id='s-6-5'>###</td>" + 
			"		<td id='s-6-6'>###</td><td id='s-6-7'>###</td><td id='s-6-8'>###</td>" + 
			"	</tr><tr>" + 
			"		<td id='s-7-0'>###</td><td id='s-7-1'>###</td><td id='s-7-2'>###</td>" + 
			"		<td id='s-7-3'>###</td><td id='s-7-4'>###</td><td id='s-7-5'>###</td>" + 
			"		<td id='s-7-6'>###</td><td id='s-7-7'>###</td><td id='s-7-8'>###</td>" + 
			"	</tr><tr>" + 
			"		<td id='s-8-0'>###</td><td id='s-8-1'>###</td><td id='s-8-2'>###</td>" + 
			"		<td id='s-8-3'>###</td><td id='s-8-4'>###</td><td id='s-8-5'>###</td>" + 
			"		<td id='s-8-6'>###</td><td id='s-8-7'>###</td><td id='s-8-8'>###</td>" + 
			"	</tr>" + 
			"</table>";
		
		var input = "<INPUT id='#ID#' type='text' class='s-input' maxlength='6' onkeyup='Sudoku.checkField(event);' onchange='Sudoku.checkField(event);' />";
		for (var row, col, i=0; i<81; i++) {
			row = Math.floor(i / 9);
			col = Math.floor(i % 9);
			if (Data.current[i] !== "0") {
				sTable = sTable.replace(/###/, Data.current[i]);
			//} else if (Data.current[i] === "0" && i < 78) {
			//	Data.current[i] = Data.solution[i];
			//	sTable = sTable.replace(/###/, Data.solution[i]);
			} else {
				sTable = sTable.replace(/###/, input.replace(/#ID#/, "s-input-" + row + "-" + col));
			}
		}
		$("puzzleBoard").set("html", sTable);
		
		if (fadeIn) {
			$("puzzleBoard").fade(1.0);
		}
		
		Razzle.setStatTimer((new Date()).getTime());
	};
	
	/////////////////////////////////////////////////////////////////////
	var resetBoard = function() {
		Data.current = Data.puzzle_grid.split("");
		parse(Data, false);
		$("messageScreen").setStyle("display", "none");
		$("messageBox").setStyle("display", "none").set("html", "");
		Razzle.setStatTimer(-1);
	};
	
	/////////////////////////////////////////////////////////////////////
	var gutBoard = function() {
		Sudoku.failCount = 0;
		Data = {};
		$("sudokuGrid").dispose();
		$("messageScreen").setStyle("display", "none");
		$("messageBox").setStyle("display", "none").set("html", "");
	};
	
	/////////////////////////////////////////////////////////////////////
	var checkField = function(event) {
		event = (!!event) ? new Event(event) : ((!!window.event) ? new Event(window.event) : {});
		if (/^(9|3[7-9]|40)$/.test(event.code)) return; // Tab + Arrow Keys
		
		var target = $(event.target).set("value", event.target.value.replace(/[^1-9]/g, "")), 
		    len = target.value.length, 
		    id = target.id.split("-");
		
		if (id.length !== 4 || /[^0-8]/.test(id[2]) || /[^0-8]/.test(id[3])) return;
		
		var row = parseInt(id[2]), 
		    col = parseInt(id[3]);
		
		Data.current[(row * 9) + col] = target.value;
		
		switch (len) {
			case 1:
				target.removeClass("s-input-small").removeClass("s-input-smaller");
				target.getParent().addClass("s-input-human-entry");
				break;
			case 2:
			case 3:
				target.removeClass("s-input-smaller").addClass("s-input-small");
				target.getParent().addClass("s-input-human-entry");
				break;
			case 4:
			case 5:
			case 6:
				target.removeClass("s-input-small").addClass("s-input-smaller");
				target.getParent().addClass("s-input-human-entry");
				break;
			case 0:
			default:
				target.removeClass("s-input-small").removeClass("s-input-smaller");
				target.getParent().removeClass("s-input-human-entry");
				return;
		}
		
		if (len === 1 && event.type === "keyup") { // Check for win:
			var solved = true;
			for (var i=0; i<81; i++) {
				if (Data.current[i] !== Data.solution[i]) {
					solved = false;
					break;
				}
			}
			if (solved) {
				target.blur();
				Razzle.updateStat("sudoku");
				Razzle.showMessage("Congratulations, you've solved the puzzle!", true);
			}
		}
	};
	
	ReturnObj.init = init;
	ReturnObj.getSudoku = getSudoku;
	ReturnObj.parse = parse;
	ReturnObj.resetBoard = resetBoard;
	ReturnObj.gutBoard = gutBoard;
	ReturnObj.checkField = checkField;
	
	return ReturnObj;
}();
