"use strict";
(function (window, undefined) {
	var addEvent = System.addEvent,
		hasClass = System.hasClass,
		addClass = System.addClass,
		removeClass = System.removeClass,
		unselectable = System.unselectable,
		jsApiRequest = System.jsApiRequest,

		viewport = document.getElementById('viewport'),
		instructionSet = document.getElementById('instructionSet'),
		dragInstruction = {
			dragging:false,
			element:document.getElementById('dragInstruction'),
			source:null
		},
		code = [[], [], []],
		INSTRUCTION_CLASSES = ['none', 'go', 'jump', 'left', 'right', 'switch', 'func1', 'func2'],
		functionStack = [], 	// { f = (0 == Main / 1 == Func 1 / 2 == Func 2), i = 0 }
		button = {
			go:document.querySelector('.button.go'),
			step:document.querySelector('.button.step'),
			fast:document.querySelector('.button.fast'),
			reset:document.querySelector('.button.reset')
		};

	window['Game'] = {
		// Variables
		robot:{
			x:0,
			y:0,
			dir:0
		},

		executionSpeed:0,

		score:{
			used:0,				// Used Instructions
			executed:0,			// Executed Instructions
			invalid:0,			// Invalid Instructions
			getScore:function () {
				return (1027 - ((Game.score.used * 8) + Game.score.executed + (Game.score.invalid * 4)));
			}
		},

		// Constants
		DIR:{
			YP:0,
			XP:1,
			YN:2,
			XN:3
		},

		SPEED:{
			NORMAL:0,
			SINGLE_STEP:-1,
			FAST_FORWARD:1
		},

		// Functions
		initialized:function (type) {
			if (type === 'Level') {
				if (!Level.setLevel(isNaN(parseInt(document.location.hash.substr(1), 10)) ? 0 : parseInt(document.location.hash.substr(1), 10))) {
					alert('Level not available.');
				}
				Draw.initLevel();
				Draw.resetLevel();
			}
		},

		nextInstruction:function () {
			if (functionStack[functionStack.length - 1].i === (functionStack[functionStack.length - 1].f === 0 ? 11 : 7)) {
				functionStack.pop();
				Game.nextInstruction();
				return;
			}
			if (functionStack.length > 0) {
				functionStack[functionStack.length - 1].i++;

				if (Game.executionSpeed === Game.SPEED.SINGLE_STEP) { return; }
				processInstruction();
			}
		},

		stopExecution:function () {
			if (Draw.animTimeout !== null) {
				clearTimeout(Draw.animTimeout);
				Draw.animTimeout = null;
			}
			if (document.querySelector('.instructionBorder.active')) {
				removeClass(document.querySelector('.instructionBorder.active'), 'active');
			}
			removeClass(button.go, 'running');
			removeClass(button.step, 'active');
			removeClass(button.fast, 'active');
			Draw.resetLevel(Level.id);
		},

		checkSolved:function () {
			var x, y;

			for (y = 0; y < Level.height; y++) {
				for (x = 0; x < Level.width; x++) {
					if (hasClass(Draw.getFloorElem(x, y), 'off')) {
						return false;
					}
				}
			}
			return true;
		}
	};

	// Initialization
	(function () {
		var i, x, y, pElem, nElem, elem, pos;

		unselectable(viewport);

		for (i = 1; i < 8; i++) {
			elem = document.createElement('div');
			elem.className = 'instruction ' + INSTRUCTION_CLASSES[i];
			elem.style.left = (((i - 1) << 5) + 8) + 'px';
			addEvent(elem, 'mousedown', dragStart);
			instructionSet.appendChild(elem);
		}

		for (i = 0; i < 12; i++) {
			pElem = document.createElement('div');
			pElem.className = 'instructionBorder';

			elem = document.createElement('div');
			elem.className = 'instruction none';
			addEvent(elem, 'mousedown', dragStart);
			addEvent(pElem, 'mouseup', dragEnd);
			code[0][i] = pElem.appendChild(elem);

			nElem = document.createElement('div');
			nElem.className = 'instructionNumber';
			nElem.style.backgroundPosition = '0 -' + (i << 3) + 'px';
			addEvent(nElem, 'click', function (e) {
				e.target.parentNode.querySelector('.instruction').className = 'instruction none';
			});
			pElem.appendChild(nElem);

			document.getElementById('codeMain').appendChild(pElem);
		}

		for (i = 0; i < 8; i++) {
			pElem = document.createElement('div');
			pElem.className = 'instructionBorder';

			elem = document.createElement('div');
			elem.className = 'instruction none';
			addEvent(elem, 'mousedown', dragStart);
			addEvent(pElem, 'mouseup', dragEnd);
			code[1][i] = pElem.appendChild(elem);

			nElem = document.createElement('div');
			nElem.className = 'instructionNumber';
			nElem.style.backgroundPosition = '0 -' + (i << 3) + 'px';
			addEvent(nElem, 'click', function (e) {
				e.target.parentNode.querySelector('.instruction').className = 'instruction none';
			});
			pElem.appendChild(nElem);

			document.getElementById('codeFunc1').appendChild(pElem);

			pElem = document.createElement('div');
			pElem.className = 'instructionBorder';

			elem = document.createElement('div');
			elem.className = 'instruction none';
			addEvent(elem, 'mousedown', dragStart);
			addEvent(pElem, 'mouseup', dragEnd);
			code[2][i] = pElem.appendChild(elem);

			nElem = document.createElement('div');
			nElem.className = 'instructionNumber';
			nElem.style.backgroundPosition = '0 -' + (i << 3) + 'px';
			addEvent(nElem, 'click', function (e) {
				e.target.parentNode.querySelector('.instruction').className = 'instruction none';
			});
			pElem.appendChild(nElem);

			document.getElementById('codeFunc2').appendChild(pElem);
		}

		addEvent(viewport, 'mousemove', dragMove);
		addEvent(viewport, 'mouseup', dragEnd2);

		addEvent(button.go, 'click', function (e) {
			var i;

			if (hasClass(button.go, 'disabled')) {
				return;
			}

			if (hasClass(button.go, 'running')) {
				Game.stopExecution();
				return;
			}

			addClass(button.go, 'running');

			Game.score.used = 0;
			Game.score.executed = 0;
			Game.score.invalid = 0;
			for (i = 0; i < 12; i++) {
				if (!hasClass(code[0][i], 'none')) {
					Game.score.used++;
				}
			}
			for (i = 0; i < 8; i++) {
				if (!hasClass(code[1][i], 'none')) {
					Game.score.used++;
				}
				if (!hasClass(code[2][i], 'none')) {
					Game.score.used++;
				}
			}

			functionStack = [{ f:0, i:0 }];
			Game.executionSpeed = Game.SPEED.NORMAL;
			processInstruction();
		});
		addEvent(button.fast, 'click', function (e) {
			var i;

			if (hasClass(button.go, 'disabled')) {
				return;
			}

			if (hasClass(button.go, 'running')) {
				if (hasClass(button.fast, 'active')) {
					Game.executionSpeed = Game.SPEED.NORMAL;
					removeClass(button.fast, 'active');
					return;
				} else if (hasClass(button.step, 'active')) {
					if (Draw.animTimeout !== null) {
						return;
					}
					removeClass(button.step, 'active');
					Game.executionSpeed = Game.SPEED.FAST_FORWARD;
					processInstruction();
				} else {
					Game.executionSpeed = Game.SPEED.FAST_FORWARD;
				}
				addClass(button.fast, 'active');
				return;
			}

			addClass(button.go, 'running');
			addClass(button.fast, 'active');

			Game.score.used = 0;
			Game.score.executed = 0;
			Game.score.invalid = 0;
			for (i = 0; i < 12; i++) {
				if (!hasClass(code[0][i], 'none')) {
					Game.score.used++;
				}
			}
			for (i = 0; i < 8; i++) {
				if (!hasClass(code[1][i], 'none')) {
					Game.score.used++;
				}
				if (!hasClass(code[2][i], 'none')) {
					Game.score.used++;
				}
			}

			functionStack = [{ f:0, i:0 }];
			Game.executionSpeed = Game.SPEED.FAST_FORWARD;
			processInstruction();
		});
		addEvent(button.step, 'click', function (e) {
			var i;

			if (hasClass(button.step, 'disabled')) {
				return;
			}

			if (hasClass(button.go, 'running')) {
				if (!hasClass(button.step, 'active')) {
					Game.executionSpeed = Game.SPEED.SINGLE_STEP;
					addClass(button.step, 'active');
					removeClass(button.fast, 'active');
					return;
				}
				if (Draw.animTimeout !== null) {
					return;
				}
			} else {
				addClass(button.go, 'running');
				addClass(button.step, 'active');

				Game.score.used = 0;
				Game.score.executed = 0;
				Game.score.invalid = 0;
				for (i = 0; i < 12; i++) {
					if (!hasClass(code[0][i], 'none')) {
						Game.score.used++;
					}
				}
				for (i = 0; i < 8; i++) {
					if (!hasClass(code[1][i], 'none')) {
						Game.score.used++;
					}
					if (!hasClass(code[2][i], 'none')) {
						Game.score.used++;
					}
				}

				functionStack = [{ f:0, i:0 }];
			}

			Game.executionSpeed = Game.SPEED.SINGLE_STEP;
			processInstruction();
		});
		addEvent(button.reset, 'click', function (e) {
			var i;

			if (hasClass(button.reset, 'disabled')) {
				return;
			}

			resetInstructions();
		});

		function dragStart(e) {
			if (hasClass(button.go, 'running')) {
				Game.stopExecution();
			}
			if (e.button === 0 && e.target.className !== 'instruction none') {
				dragInstruction.dragging = true;
				dragInstruction.element.style.left = e.pageX + 'px';
				dragInstruction.element.style.top = e.pageY + 'px';
				dragInstruction.element.style.display = 'block';
				dragInstruction.source = e.target;
				dragInstruction.element.className = dragInstruction.source.className;
				if (dragInstruction.source.parentNode !== instructionSet) {
					dragInstruction.source.className = 'instruction none';
				}
			}

			e.preventDefault();
			e.stopPropagation();
		}

		function dragEnd(e) {
			var elem = e.target;
			if (hasClass(elem, 'instructionBorder')) {
				elem = elem.querySelector('.instruction');
			} else if (hasClass(elem, 'instructionNumber')) {
				elem = elem.parentNode.querySelector('.instruction');
			}
			if (e.button === 0 && dragInstruction.dragging) {
				elem.className = dragInstruction.element.className;
			}
			dragEnd2(e, elem);
		}

		function dragEnd2(e, elem) {
			elem = elem || e.target;

			if (e.button === 0 && dragInstruction.dragging) {
				dragInstruction.dragging = false;
				dragInstruction.element.style.display = 'none';
				if (elem !== dragInstruction.source && dragInstruction.source.parentNode !== instructionSet) {
					dragInstruction.source.className = 'instruction none';
				}

				setButtonState();
			}

			e.preventDefault();
			e.stopPropagation();
		}

		function dragMove(e) {
			if (dragInstruction.dragging) {
				dragInstruction.element.style.left = e.pageX + 'px';
				dragInstruction.element.style.top = e.pageY + 'px';
			}

			e.preventDefault();
			e.stopPropagation();
		}


		addEvent(window, 'keydown', function (e) {
			if (e.target.nodeName.toUpperCase() === 'INPUT') {
				return;
			}

			switch (e.keyCode) {
				case 37: // Left
					if (hasClass(button.go, 'running')) {
						Game.stopExecution();
					}
					Draw.rotation = (Draw.rotation + 90) % 360;
					Draw.initLevel();
					Draw.resetLevel();
					break;
				case 39: // Right
					if (hasClass(button.go, 'running')) {
						Game.stopExecution();
					}
					Draw.rotation = (Draw.rotation + 270) % 360;
					Draw.initLevel();
					Draw.resetLevel();
					break;
			}

			e.preventDefault();
			e.stopPropagation();
		});
		addEvent(window, 'keyup', function (e) {
			if (e.target.nodeName.toUpperCase() === 'INPUT') {
				return;
			}

			switch (e.keyCode) {
				case 27:	// ESC
					if (hasClass(button.go, 'running')) {
						Game.stopExecution();
					}
					break;
				case 123:	// F12
					if (hasClass(button.go, 'running')) {
						Game.stopExecution();
					}
					setInstructionCode(prompt('Your program code:', getInstructionCode()));
					break;
			}

			e.preventDefault();
			e.stopPropagation();
		});

		addEvent(document.getElementById('levelSolvedSubmit'), 'click', function () {
			if (hasClass(document.getElementById('levelSolvedSubmit'), 'disabled')) {
				return;
			}
			addClass(document.getElementById('levelSolvedSubmit'), 'disabled');

			jsApiRequest('http://robotrace.de/db/set_leaderboard.json?level=' + Level.id + '&used=' + Game.score.used + '&executed=' + Game.score.executed + '&invalid=' + Game.score.invalid + '&score=' + Game.score.getScore() + '&solution=' + getInstructionCode() + '&name=' + encodeURIComponent(document.getElementById('levelSolvedName').value), function (json) {
				if (typeof(json.error) !== 'undefined') {
					alert('Error: ' + json.error + '\n' + json.errmsg);
					return;
				}

				document.getElementById('levelSolvedRank').innerHTML =	i18n.levelSolvedRank.replace('[ranking]', json.ranking);
				
				var score = 0, rank = 0, out = '';
				if (typeof(json.top100) === 'object') {
					for (var i = 0; i < json.top100.length; i++) {
						if (json.top100[i].score > score) {
							rank++;
							score = json.top100[i].score;
						}
						out += rank + '. ' + json.top100[i].name + ' (Score: ' + json.top100[i].score + ')<br />';
					}
				}
				document.getElementById('levelSolvedList').innerHTML = out;

				removeClass(document.getElementById('levelSolvedSubmit'), 'disabled');
			});
		});
		addEvent(document.getElementById('levelSolvedNextLevel'), 'click', function () {
			resetInstructions();
			Level.setLevel(Level.idx + 1);
			Draw.rotation = 0;
			Draw.initLevel();
			Draw.resetLevel();

			document.getElementById('levelSolved').style.display = 'none';
			document.getElementById('overlay').style.display = 'none';
		});
		addEvent(document.getElementById('levelSolvedHide'), 'click', function () {
			Draw.resetLevel(Level.id);

			document.getElementById('levelSolved').style.display = 'none';
			document.getElementById('overlay').style.display = 'none';
		});
	})();

	function resetInstructions() {
		var i;

		if (hasClass(button.go, 'running')) {
			Game.stopExecution();
		}

		for (i = 0; i < 12; i++) {
			code[0][i].className = 'instruction none';
		}

		for (i = 0; i < 8; i++) {
			code[1][i].className = 'instruction none';
			code[2][i].className = 'instruction none';
		}
		
		setButtonState();
	}

	function processInstruction() {
		var instruction = code[functionStack[functionStack.length - 1].f][functionStack[functionStack.length - 1].i],
			i;

		if (hasClass(instruction, INSTRUCTION_CLASSES[0])) { // none
			Game.nextInstruction();
			return;
		}

		Game.score.executed++;

		if (document.querySelector('.instructionBorder.active')) {
			removeClass(document.querySelector('.instructionBorder.active'), 'active');
		}
		addClass(instruction.parentNode, 'active');

		if (hasClass(instruction, INSTRUCTION_CLASSES[1])) { // go
			switch (Game.robot.dir) {
				case 0:
					if ((Game.robot.y < Level.height - 1) && (Level.getFloorHeight(Game.robot.x, Game.robot.y + 1) == Level.getFloorHeight(Game.robot.x, Game.robot.y))) {
						Draw.animate(Draw.ANIM.YP);
						return;
					}
					break;
				case 1:
					if ((Game.robot.x < Level.width - 1) && (Level.getFloorHeight(Game.robot.x + 1, Game.robot.y) == Level.getFloorHeight(Game.robot.x, Game.robot.y))) {
						Draw.animate(Draw.ANIM.XP);
						return;
					}
					break;
				case 2:
					if ((Game.robot.y > 0) && (Level.getFloorHeight(Game.robot.x, Game.robot.y - 1) == Level.getFloorHeight(Game.robot.x, Game.robot.y))) {
						Draw.animate(Draw.ANIM.YN);
						return;
					}
					break;
				case 3:
					if ((Game.robot.x > 0) && (Level.getFloorHeight(Game.robot.x - 1, Game.robot.y) == Level.getFloorHeight(Game.robot.x, Game.robot.y))) {
						Draw.animate(Draw.ANIM.XN);
						return;
					}
					break;
			}
		} else if (hasClass(instruction, INSTRUCTION_CLASSES[2])) { // jump
			switch (Game.robot.dir) {
				case 0:
					if ((Game.robot.y < Level.height - 1) && (
						(Level.getFloorHeight(Game.robot.x, Game.robot.y + 1) < Level.getFloorHeight(Game.robot.x, Game.robot.y)) ||
						(Level.getFloorHeight(Game.robot.x, Game.robot.y + 1) == Level.getFloorHeight(Game.robot.x, Game.robot.y) + 1)
					)) {
						Draw.animate(Draw.ANIM.YP_JUMP, Level.getFloorHeight(Game.robot.x, Game.robot.y + 1) - Level.getFloorHeight(Game.robot.x, Game.robot.y));
						return;
					}
					break;
				case 1:
					if ((Game.robot.x < Level.width - 1) && (
						(Level.getFloorHeight(Game.robot.x + 1, Game.robot.y) < Level.getFloorHeight(Game.robot.x, Game.robot.y)) ||
						(Level.getFloorHeight(Game.robot.x + 1, Game.robot.y) == Level.getFloorHeight(Game.robot.x, Game.robot.y) + 1)
					)) {
						Draw.animate(Draw.ANIM.XP_JUMP, Level.getFloorHeight(Game.robot.x + 1, Game.robot.y) - Level.getFloorHeight(Game.robot.x, Game.robot.y));
						return;
					}
					break;
				case 2:
					if ((Game.robot.y > 0) && (
						(Level.getFloorHeight(Game.robot.x, Game.robot.y - 1) < Level.getFloorHeight(Game.robot.x, Game.robot.y)) ||
						(Level.getFloorHeight(Game.robot.x, Game.robot.y - 1) == Level.getFloorHeight(Game.robot.x, Game.robot.y) + 1)
					)) {
						Draw.animate(Draw.ANIM.YN_JUMP, Level.getFloorHeight(Game.robot.x, Game.robot.y - 1) - Level.getFloorHeight(Game.robot.x, Game.robot.y));
						return;
					}
					break;
				case 3:
					if ((Game.robot.x > 0) && (
						(Level.getFloorHeight(Game.robot.x - 1, Game.robot.y) < Level.getFloorHeight(Game.robot.x, Game.robot.y)) ||
						(Level.getFloorHeight(Game.robot.x - 1, Game.robot.y) == Level.getFloorHeight(Game.robot.x, Game.robot.y) + 1)
					)) {
						Draw.animate(Draw.ANIM.XN_JUMP, Level.getFloorHeight(Game.robot.x - 1, Game.robot.y) - Level.getFloorHeight(Game.robot.x, Game.robot.y));
						return;
					}
					break;
			}
			Draw.animate(Draw.ANIM.JUMP);
			return;
		} else if (hasClass(instruction, INSTRUCTION_CLASSES[3])) { // left
			switch (Game.robot.dir) {
				case 0: Draw.animate(Draw.ANIM.ROTATE_03); break;
				case 1: Draw.animate(Draw.ANIM.ROTATE_10); break;
				case 2: Draw.animate(Draw.ANIM.ROTATE_21); break;
				case 3: Draw.animate(Draw.ANIM.ROTATE_32); break;
			}
			return;
		} else if (hasClass(instruction, INSTRUCTION_CLASSES[4])) { // right
			switch (Game.robot.dir) {
				case 0: Draw.animate(Draw.ANIM.ROTATE_01); break;
				case 1: Draw.animate(Draw.ANIM.ROTATE_12); break;
				case 2: Draw.animate(Draw.ANIM.ROTATE_23); break;
				case 3: Draw.animate(Draw.ANIM.ROTATE_30); break;
			}
			return;
		} else if (hasClass(instruction, INSTRUCTION_CLASSES[5])) { // switch
			if (hasClass(Draw.getFloorElem(Game.robot.x, Game.robot.y), 'on')) {
				Draw.animate(Draw.ANIM.SWITCH_OFF, Level.getFloorHeight(Game.robot.x, Game.robot.y));
				return;
			} else if (hasClass(Draw.getFloorElem(Game.robot.x, Game.robot.y), 'off')) {
				Draw.animate(Draw.ANIM.SWITCH_ON, Level.getFloorHeight(Game.robot.x, Game.robot.y));
				return;
			}
		} else if (hasClass(instruction, INSTRUCTION_CLASSES[6])) { // func1
			functionStack.push({ f:1, i:0 });
			processInstruction();
			return;
		} else if (hasClass(instruction, INSTRUCTION_CLASSES[7])) { // func2
			functionStack.push({ f:2, i:0 });
			processInstruction();
			return;
		}
		
		Game.score.invalid++;
		Draw.animate(Draw.ANIM.INVALID);
	}

	function setButtonState() {
		var i;

		for (i = 0; i < 12; i++) {
			if (code[0][i].className !== 'instruction none') {
				removeClass(button.go, 'disabled');
				removeClass(button.step, 'disabled');
				removeClass(button.fast, 'disabled');
				removeClass(button.reset, 'disabled');
				return true;
			}
		}
		addClass(button.go, 'disabled');
		addClass(button.step, 'disabled');
		addClass(button.fast, 'disabled');
		addClass(button.reset, 'disabled');
		return false;
	}

	function getInstructionCode() {
		var i, code0 = '', code1 = '', code2 = '';
		for (i = 0; i < 12; i++) {
			if (hasClass(code[0][i], INSTRUCTION_CLASSES[0])) { // none
				code0 += '0';
			} else if (hasClass(code[0][i], INSTRUCTION_CLASSES[1])) { // go
				code0 += '1';
			} else if (hasClass(code[0][i], INSTRUCTION_CLASSES[2])) { // jump
				code0 += '2';
			} else if (hasClass(code[0][i], INSTRUCTION_CLASSES[3])) { // left
				code0 += '3';
			} else if (hasClass(code[0][i], INSTRUCTION_CLASSES[4])) { // right
				code0 += '4';
			} else if (hasClass(code[0][i], INSTRUCTION_CLASSES[5])) { // switch
				code0 += '5';
			} else if (hasClass(code[0][i], INSTRUCTION_CLASSES[6])) { // func1
				code0 += '6';
			} else if (hasClass(code[0][i], INSTRUCTION_CLASSES[7])) { // func2
				code0 += '7';
			}
		}
		for (i = 0; i < 8; i++) {
			if (hasClass(code[1][i], INSTRUCTION_CLASSES[0])) { // none
				code1 += '0';
			} else if (hasClass(code[1][i], INSTRUCTION_CLASSES[1])) { // go
				code1 += '1';
			} else if (hasClass(code[1][i], INSTRUCTION_CLASSES[2])) { // jump
				code1 += '2';
			} else if (hasClass(code[1][i], INSTRUCTION_CLASSES[3])) { // left
				code1 += '3';
			} else if (hasClass(code[1][i], INSTRUCTION_CLASSES[4])) { // right
				code1 += '4';
			} else if (hasClass(code[1][i], INSTRUCTION_CLASSES[5])) { // switch
				code1 += '5';
			} else if (hasClass(code[1][i], INSTRUCTION_CLASSES[6])) { // func1
				code1 += '6';
			} else if (hasClass(code[1][i], INSTRUCTION_CLASSES[7])) { // func2
				code1 += '7';
			}
			if (hasClass(code[2][i], INSTRUCTION_CLASSES[0])) { // none
				code2 += '0';
			} else if (hasClass(code[2][i], INSTRUCTION_CLASSES[1])) { // go
				code2 += '1';
			} else if (hasClass(code[2][i], INSTRUCTION_CLASSES[2])) { // jump
				code2 += '2';
			} else if (hasClass(code[2][i], INSTRUCTION_CLASSES[3])) { // left
				code2 += '3';
			} else if (hasClass(code[2][i], INSTRUCTION_CLASSES[4])) { // right
				code2 += '4';
			} else if (hasClass(code[2][i], INSTRUCTION_CLASSES[5])) { // switch
				code2 += '5';
			} else if (hasClass(code[2][i], INSTRUCTION_CLASSES[6])) { // func1
				code2 += '6';
			} else if (hasClass(code[2][i], INSTRUCTION_CLASSES[7])) { // func2
				code2 += '7';
			}
		}
		
		return code0.replace(/0*$/, '') + ';' + code1.replace(/0*$/, '') + ';' + code2.replace(/0*$/, '');
	}

	function setInstructionCode(sourceCode) {
		if (typeof(sourceCode) !== 'string') {
			return false;
		}

		var sCode = sourceCode.split(';'), i;

		if (sCode.length !== 3) {
			return false;
		}

		if (hasClass(button.go, 'running')) {
			Game.stopExecution();
			return false;
		}

		resetInstructions();

		for (i = 0; i < sCode[0].length; i++) {
			code[0][i].className = 'instruction ' + INSTRUCTION_CLASSES[sCode[0][i]];
		}
		for (i = 0; i < sCode[1].length; i++) {
			code[1][i].className = 'instruction ' + INSTRUCTION_CLASSES[sCode[1][i]];
		}
		for (i = 0; i < sCode[2].length; i++) {
			code[2][i].className = 'instruction ' + INSTRUCTION_CLASSES[sCode[2][i]];
		}
		
		setButtonState();

		return true;
	}
})(window);
