////////////////////////////////////////
// HANGMAN - RAZZLE
////////////////////////////////////////
var Hangman = function() {
	var Req, 
	    Data, 
	    ReturnObj = {
	    	failCount : 0
	    };
	
	/////////////////////////////////////////////////////////////////////
	var init = function() {
		if (!renderCanvas()) return;
		
		$("fl-reset").addEvent("click", function(event) {
			Hangman.resetBoard();
			event.stop();
			return false;
		});
		$("fl-newgame").addEvent("click", function(event) {
			Hangman.gutBoard();
			Hangman.getHangman();
			if (!!event) { event.stop(); }
			return false;
		});
		$("fl-print").setStyle("color", "#ccc").addEvent("click", function(event) {
			var IEFix = 1;
			event.stop();
			return false;
		});
		
		if (Razzle.puzzleJSON.length > 0) {
			parse(Razzle.puzzleJSON[0], true);
		} else {
			getHangman();
		}
	};
	
	/////////////////////////////////////////////////////////////////////
	var getHangman = function() {
		Req = new Request.JSON({ url : "/getHangman/" + new Date().getTime(), method : "GET", secure : false });
		Req.addEvent("onComplete", function(hangman) {
			if (!!hangman && hangman.length > 0) {
				Hangman.parse(hangman[0], true);
			} else if (Hangman.failCount < 11) {
				Hangman.failCount++;
				Hangman.getHangman();
			}
		});
		Req.get();
	};
	
	/////////////////////////////////////////////////////////////////////
	var parse = function(Fields, fadeIn) {
		Data = Fields;
		if (!Data.word.length || Data.word.length < 1 || /\-/.test(Data.word)) {
			Hangman.failCount++;
			if (Hangman.failCount < 11) {
				getHangman();
			}
			return;
		}
		
		if (fadeIn) {
			$("hangmanWord").setStyles({ "opacity" : 0.0, "visibility" : "hidden" });
		}
		
		Data.word = Data.word.toUpperCase();
		Data.letters = Data.word.split("");
		Data.remaining = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
		Data.right = [];
		Data.wrong = [];
		$("hangmanMisguessed").set("html", "");
		
		var inlineStyles = (Browser.Engine.gecko18) ? "display:-moz-inline-box;height:" + ((Data.letters.length > 10) ? "29" : "44") + "px;" : "display:inline-block;", 
		    letterBox = "<SPAN id='#ID#' class='letterBox" + ((Data.letters.length > 10) ? " letterBoxSmall" : "") + "' style='" + inlineStyles + "'>&nbsp;</SPAN>", 
		    html = [], 
		    htmlL = 0;
		
		for (var i=0, len=Data.letters.length; i<len; i++) {
			html[htmlL++] = letterBox.replace(/#ID#/, "letterBox-" + i);
		}
		$("hangmanWord").set("html", html.join(""));
		
		renderLetterList();
		
		if (fadeIn) {
			$("hangmanWord").fade(1.0);
		}
		document.addEvent("keyup", Hangman.doKeyUp);
		Razzle.setStatTimer((new Date()).getTime());
	};
	
	/////////////////////////////////////////////////////////////////////
	var doKeyUp = function(event) {
		if (event.code < 65 || event.code > 90) return;
		if (!!event.target && /input/i.test(event.target.tagName)) return;
		parseKey(event.key.toUpperCase());
	};
	
	/////////////////////////////////////////////////////////////////////
	var doClick = function(letter) {
		if (!letter || letter.length !== 1 || /[^A-Z]/.test(letter)) return;
		parseKey(letter);
	};
	
	/////////////////////////////////////////////////////////////////////
	var parseKey = function(key) {
		if (!Data.remaining.contains(key)) return; // An already guessed letter
		if (Data.right.length === Data.letters.length || Data.wrong.length === 6) return;
		
		Data.remaining[Data.remaining.indexOf(key)] = "&nbsp;";
		renderLetterList();
		
		if (Data.letters.contains(key)) {
			for (var i=0, len=Data.letters.length; i<len; i++) {
				if (Data.letters[i] === key && !!$("letterBox-" + i)) {
					$("letterBox-" + i).set("html", key);
					Data.right.push(key);
				}
			}
			if (Data.right.length === Data.letters.length) {
				document.removeEvent("keyup", Hangman.doKeyUp);
				var href = "http://dictionary.reference.com/browse/" + Data.word.toLowerCase();
				var msg = "Congratulations, you've solved the puzzle!<br />See the definition of <a id='definitionLink' href='" + href + "' target='_blank'>" + Data.word + "</a>";
				Razzle.updateStat("hangman");
				Razzle.showMessage(msg, true);
			}
		} else {
			Data.wrong.push(key);
			$("hangmanMisguessed").set("html", Data.wrong.join(""));
			drawCanvas(Data.wrong.length);
			if (Data.wrong.length === 6) {
				document.removeEvent("keyup", Hangman.doKeyUp);
				var href = "http://dictionary.reference.com/browse/" + Data.word.toLowerCase();
				var msg = "Darn, you lost this round.<br />See the definition of <a id='definitionLink' href='" + href + "' target='_blank'>" + Data.word + "</a>";
				Razzle.showMessage(msg, true);
			}
		}
	};
	
	/////////////////////////////////////////////////////////////////////
	var renderLetterList = function() {
		if (!!$("letterList")) $("letterList").dispose();
		var inlineSpan = "<span class=\"letter\" onclick=\"Hangman.doClick(this.innerHTML);\"";
		inlineSpan += " onmouseover=\"Hangman.toggleHover(this, 'underline');\"";
		inlineSpan += " onmouseout=\"Hangman.toggleHover(this, 'none');\"";
		inlineSpan += " style=\"display:" + ((Browser.Engine.gecko18) ? "-moz-inline-box" : "inline-block") + ";\">";
		var html = inlineSpan + Data.remaining.join("</span>" + inlineSpan) + "</span>";
		new Element("DIV", { "id" : "letterList", "html" : html }).inject($("hangmanWord"));
	};
	
	/////////////////////////////////////////////////////////////////////
	var toggleHover = function(letterLink, which) {
		if (!letterLink) return;
		
		var html = letterLink.innerHTML;
		if (html.length !== 1 || /[^A-Z]/.test(html)) return;
		
		$(letterLink).setStyle("text-decoration", which);
	};
	
	/////////////////////////////////////////////////////////////////////
	var renderCanvas = function() {
		try {
			var canvas = document.createElement("canvas");
			if (Browser.Engine.trident) {
				G_vmlCanvasManager.initElement(canvas);
				canvas.style.width = "340px";
				canvas.style.height = "400px";
			} else {
				canvas.setAttribute("width", "340");
				canvas.setAttribute("height", "400");
			}
			canvas.id = "hangmanCanvas";
			$("hangmanPicture").set("html", "").appendChild(canvas);
			var ctx = canvas.getContext("2d");
			
			ctx.strokeStyle = "#000000";
			ctx.fillStyle = "#000000";
			ctx.fillRect(20, 360, 300, 15);
			ctx.fillRect(50, 30, 15, 330);
			ctx.fillRect(40, 40, 220, 15);
			ctx.fillRect(215, 55, 5, 30);
			return true;
		} catch (e) {
			Razzle.showMessage("Sorry, but this page requires technology that this browser does not have. Please try another browser.", false);
			Razzle.shutdownFunctions(false);
			return false;
		}
	};
	
	/////////////////////////////////////////////////////////////////////
	var drawCanvas = function(stage) {
		var canvas = document.getElementById("hangmanCanvas");
		var ctx = canvas.getContext("2d");
		ctx.strokeStyle = "#1831a0";
		ctx.fillStyle = "#1831a0";
		
		switch (stage) {
			case 1: // Head:
				ctx.beginPath();
				for (var i=0; i<10; i++) {
					ctx.arc(217, 115, 30 - i, 0, Math.PI * 2, false);
					ctx.stroke();
				}
				break;
			case 2: // Body:
				ctx.fillRect(212, 145, 10, 100);
				break;
			case 3: // Left arm:
				ctx.beginPath();
				ctx.moveTo(212, 180);
				ctx.lineTo(152, 140);
				ctx.lineTo(152, 150);
				ctx.lineTo(212, 190);
				ctx.fill();
				break;
			case 4: // Right arm:
				ctx.beginPath();
				ctx.moveTo(222, 180);
				ctx.lineTo(282, 140);
				ctx.lineTo(282, 150);
				ctx.lineTo(222, 190);
				ctx.fill();
				break;
			case 5: // Left leg:
				ctx.beginPath();
				ctx.moveTo(212, 235);
				ctx.lineTo(157, 295);
				ctx.lineTo(167, 295);
				ctx.lineTo(217, 245);
				ctx.fill();
				break;
			case 6: // Right leg:
				ctx.beginPath();
				ctx.moveTo(222, 235);
				ctx.lineTo(277, 295);
				ctx.lineTo(267, 295);
				ctx.lineTo(217, 245);
				ctx.fill();
				break;
		}
	};
	
	/////////////////////////////////////////////////////////////////////
	var resetBoard = function() {
		renderCanvas();
		document.removeEvent("keyup", Hangman.doKeyUp);
		parse(Data, false);
		$("messageScreen").setStyle("display", "none");
		$("messageBox").setStyle("display", "none").set("html", "");
		Razzle.setStatTimer(-1);
	};
	
	/////////////////////////////////////////////////////////////////////
	var gutBoard = function() {
		Hangman.failCount = 0;
		Data = {};
		renderCanvas();
		document.removeEvent("keyup", Hangman.doKeyUp);
		$("messageScreen").setStyle("display", "none");
		$("messageBox").setStyle("display", "none").set("html", "");
	};
	
	ReturnObj.init = init;
	ReturnObj.getHangman = getHangman;
	ReturnObj.parse = parse;
	ReturnObj.doKeyUp = doKeyUp;
	ReturnObj.doClick = doClick;
	ReturnObj.toggleHover = toggleHover
	ReturnObj.renderCanvas = renderCanvas;
	ReturnObj.drawCanvas = drawCanvas;
	ReturnObj.resetBoard = resetBoard;
	ReturnObj.gutBoard = gutBoard;
	
	return ReturnObj;
}();
