/**
 * Esse código Javascript é (c) 2005 Tiago Serafim
 * Proibida a reprodução total ou parcial, sob as penas da Lei
 */

	var _clock = new Clock();
	
	var errorMsg6 = "<p class=\"mensagemOK\">Pronto! Pode começar... boa sorte</p>";
	var errorMsg0 = "<p class=\"mensagemOK\">Tudo está certo até agora! Ainda restam {0} para o fim!</p>";
	var errorMsg1 = "<p class=\"mensagemErro\">Há um ou mais erros visíveis(marcados em vermelho)... <a href=\"#erros\" class=\"pequeno\">(+ informações)</a></p>";
	var errorMsg2 = "<p class=\"mensagemAlerta\">Há erro(s) de lógica em {0} quadradinho(s)...(marcados em vermelho) <a href=\"#erros\" class=\"pequeno\">(+ informações)</a></p>";
	var errorMsg3 = "<p class=\"mensagemAlerta\">Há erro(s) de lógica em {0} quadradinho(s)... <a href=\"#erros\" class=\"pequeno\">(+ informações)</a></p>";
	var errorMsg4 = "<p class=\"mensagemOK\">Tudo <em>parece</em> estar certo...Ainda restam {0} para o fim!</p>";
	var errorMsg5 = "<p class=\"mensagemOK\">Parabéns! Você terminou o puzzle. Seu tempo foi: {0}</p>";
	

	var ERRORS_LEVEL = { EASY : 1, MEDIUM: 2, EXPERT: 3 };
	var _errorLevel = ERRORS_LEVEL.MEDIUM;

	function setErrorLevel(errorLevel) {
		_errorLevel = errorLevel;
	}

	function getErrorLevel() {
		return _errorLevel;
	}


	var _puzzle, _solution, _level, _index;
	
	function getPuzzle() {
		return _puzzle;
	}

	function getSolution() {
		return _solution;
	}

	function getNivel() {
		return _nivel;
	}

	function getIndex() {
		return _index;
	}

	function setPuzzle(puzzle, solution, level, index) {

		_puzzle = fromSpaguettiToArray(puzzle);
		_solution = fromSpaguettiToArray(solution);
		_level = level;
		_index = index;
	
	}
		
	var myrules = {
		'.quadradinho' : function (el) {
			el.onclick = function(){
				this.select();
				return false;
			};
			el.onkeypress = function(e) {
				
				if ( ! e ) e = window.event;
				
				var kc = e.keyCode ? e.keyCode : e.charCode;

				if ( ( kc >= 49 && kc <= 57 ) || kc == 8 || kc == 46 ) {
					// does nothing
				} else if (kc == 13) {

					hitEnter();

				} else {
					return false;
				}
				
			}
		},
		
		'.controles #progress' : function (el) {
			el.onclick = function(){
				comoEstouIndo();
				return false;
			};
		},

		'.controles #reset' : function (el) {
			el.onclick = function(){
				
				if ( confirm("Tem certeza que deseja recomeçar esse jogo?") ) {

					resetPuzzle();

				}

				return false;
			};
		},

		'.controles #print' : function (el) {
			el.onclick = function(){
				printPuzzle();
				return false;
			};
		},
		
		'.controles2 #newPuzzle' : function (el) {
			el.onclick = function() {
				newPuzzle();
				return false;
			}
		},

		'.optionTipo' : function ( el ) {
			el.onclick = function() {
				setErrorLevel(parseInt(this.value));
				return true;
			}
		}

	};

	Behaviour.register(myrules);

	


	function displayMessage(message) {
		$('mensagens').innerHTML = message;
	}	

	var _allSquareFields = null;

	function getSquareFields() {
		
		if ( _allSquareFields == null ) {
			
			_allSquareFields = [];
			
			for ( var i = 1; i <= 9*9; i++ ) {
				_allSquareFields.push($("t" + i));
			}

		}
		
		return _allSquareFields;

	}

	function getField(index) {
		return getSquareFields()[index - 1];
	}


	eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[(function(e){return d[e]})];e=(function(){return'\\w+'});c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('1z 2(k,r,t){3 a=[];R(3 i=0;i<t;i++){a.1h(k+(r*i))}E a}3 X=[2(4,1,9),2(10,1,9),2(19,1,9),2(8,1,9),2(6,1,9),2(h,1,9),2(g,1,9),2(b,1,9),2(5,1,9)];3 C=[2(4,9,9),2(f,9,9),2(e,9,9),2(j,9,9),2(m,9,9),2(7,9,9),2(d,9,9),2(l,9,9),2(c,9,9)];3 D=[[4,f,e,10,11,12,19,1r,1q],[j,m,7,13,14,15,1o,1p,1w],[d,l,c,16,17,18,1a,w,o],[8,W,V,6,T,s,h,1c,P],[O,G,M,L,n,I,J,1u,1s],[1e,1f,1m,1k,1v,1x,z,y,1b],[g,v,u,b,Y,F,5,K,S],[1t,1g,1j,1y,1d,x,q,Q,N],[H,Z,1l,p,A,U,1i,B,1n]];',62,98,'||pa|var|01|73|37|06|28|||64|09|07|03|02|55|46||04|a1|08|05|41|27|70|76||39||57|56|26|69|53|52|71|80|colunas|caixas|return|66|32|61|42|49|74|40|33|78|31|48|77|for|75|38|72|30|29|linhas|65|62|||||||||||25|54|47|68|34|35|59|push|79|60|43|63|36|81|22|23|21|20|51|58|50|44|24|45|67|function'.split('|'),0,{}))













	function highlightSquares(squaresArray) {
		
		var classes = ['quadradinho', 'quadradinhoErro1', 'quadradinhoErro2', 'quadradinhoErro3', 'quadradinhoLocked', 'quadradinhoErro1Locked', 'quadradinhoErro2Locked', 'quadradinhoErro3Locked'];

		var fields = getSquareFields();

		squaresArray.each (
			function ( e, index ) {

				var field = getField(e);
				
				field.className = classes[classes.indexOf(field.className) + 1];

			}
		);
	
	}

	function lowlightSquares() {
		
		var fields = getSquareFields();

		fields.each (
			function ( e ) {
				e.className = (e.className.indexOf("Locked") > 0) ? "quadradinhoLocked" : "quadradinho";
			}
		);

	}

	function clearSquares() {
		
		var fields = getSquareFields();

		fields.each (
			function ( e ) {
				e.value = "";
				e.readOnly = false;
			}
		);

	}

	function fillSquares(puzzleArray) {
		
		var fields = getSquareFields();

		puzzleArray.each (
			function ( e, index ) {
				
				if ( e == 0 || index == 0) return;
				
				fields[index-1].className = "quadradinhoLocked";
				fields[index-1].readOnly = true;
				fields[index-1].value = e;

			}
		);

	}


	function fromSpaguettiToArray(p) {
		var t = p.length;
		var r = [];
		r.push(-1);
		for ( var i = 0; i < t; i++ ) {
			r.push(p.charAt(i));
		}
		return r;
	}

	function fromFormToArray() {
		
		var fields = getSquareFields();

		var r = fields.map ( 
					function ( e ) {
						var t = e.value;
						return (t.length == 0) ? 0 : parseInt(t);
					}
				);
		
		r.unshift(-1);		
		
		return r;

	}


	function valuesFromIndexArray(bigArray, indexArray) {

		var r = indexArray.map (
					function ( e ) {
						return bigArray[e];
					}
				);

		return r;

	}


	function hasDuplicatesSquares(a) {
		
		var temp = a.remove(0, true);

		return temp.hasDuplicates();

	}
	

	function getRemainingSquares(userPuzzleArray) {
		
		var temp = userPuzzleArray.remove(0, true);

		return 9*9 + 1 - temp.length;

	}

	function getErrorsFromSquares(userPuzzleArray, squareArray) {

		var retorno =	squareArray.map ( 
							function ( e, index ) {
								
								var values = valuesFromIndexArray(userPuzzleArray, e);
								
								if ( hasDuplicatesSquares(values) )
									return index;
								else
									return -1;

							}
						);
		
		retorno =	retorno.filter (
						function ( e ) {
							return (e != -1);
						}
					);

		return retorno;

	}

//getlogicalErrors..
eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[(function(e){return d[e]})];e=(function(){return'\\w+'});c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('5 b(7,6){d 4=6.a(5(e,3){8(e==0||3==0)2-1;8(7[3]!=e){2 3}c{2-1}});4=4.9(5(e){2(e!=-1)});2 4}',15,15,'||return|index|retorno|function|userPuzzleArray|completePuzzleArray|if|filter|map|getLogicalErrors|else|var|'.split('|'),0,{}))

	


	function checkErrors(completePuzzleArray, userPuzzleArray) {
		
		var visibleErrors = [];
		var logicalErrors = [];
		var errors;

			errors = getErrorsFromSquares(userPuzzleArray, linhas);
			if ( errors.length != 0 ) {
				visibleErrors.merge(linhas[errors[0]]);
			}
			errors = getErrorsFromSquares(userPuzzleArray, colunas);
			if ( errors.length != 0 ) {
				visibleErrors.merge(colunas[errors[0]]);
			}
			errors = getErrorsFromSquares(userPuzzleArray, caixas);
			if ( errors.length != 0 ) {
				visibleErrors.merge(caixas[errors[0]]);
			}
		
			errors = getLogicalErrors(completePuzzleArray, userPuzzleArray);
			if ( errors.length != 0 ) {
				logicalErrors = errors;
			}
			

		showErrors({visible: visibleErrors, logical:logicalErrors}, userPuzzleArray);
		
		if ( visibleErrors.length == 0 && logicalErrors.length == 0 ) {
			
			var remaining = getRemainingSquares(userPuzzleArray);

			if ( remaining == 0 ) {

				finishedPuzzle();				

			}

		}


	}
	


	function showErrors(errors, userPuzzleArray) {

		var errorLevel = getErrorLevel();

		switch (errorLevel) {
			case ERRORS_LEVEL.EASY:
				showErrorLevel1(errors, userPuzzleArray);
				break;
			case ERRORS_LEVEL.MEDIUM:
				showErrorLevel2(errors, userPuzzleArray);
				break;
			case ERRORS_LEVEL.EXPERT:
				showErrorLevel3(errors, userPuzzleArray);
				break;
		}

	}


	function showErrorLevel1(errors, userPuzzleArray) {
	
		if ( errors.visible.length != 0 ) {
			highlightSquares(errors.visible);
			displayMessage(errorMsg1);
			return;
		}

		if ( errors.logical.length != 0 ) {
			highlightSquares(errors.logical);
			displayMessage(errorMsg2.subArgs(errors.logical.length));
			return;
		}

		var remaining = getRemainingSquares(userPuzzleArray);

		displayMessage(errorMsg0.subArgs(remaining));

	}

	function showErrorLevel2(errors, userPuzzleArray) {

		if ( errors.visible.length != 0 ) {
			highlightSquares(errors.visible);
			displayMessage(errorMsg1);
			return;
		}

		if ( errors.logical.length != 0 ) {
			displayMessage(errorMsg3.subArgs(errors.logical.length));
			return;
		}
		
		var remaining = getRemainingSquares(userPuzzleArray);

		displayMessage(errorMsg0.subArgs(remaining));

	}

	function showErrorLevel3(errors, userPuzzleArray) {

		if ( errors.visible.length != 0 ) {
			highlightSquares(errors.visible);
			displayMessage(errorMsg1);
			return;
		}

		var remaining = getRemainingSquares(userPuzzleArray);

		displayMessage(errorMsg4.subArgs(remaining));

	}
	
	
	function loadPuzzle() {
		
		_clock.start();

		clearSquares();
		fillSquares(getPuzzle());

		displayMessage(errorMsg6);

		Element.hide($("controles2"));

	}
	
	function resetPuzzle() {
		
		lowlightSquares();
		loadPuzzle();

	}
	
	function finishedPuzzle() {
		
		displayMessage(errorMsg5.subArgs(_clock.getStringTime()));

		Element.hide($("controles"));
		Element.show($("controles2"));

	}

	function comoEstouIndo() {
		
		var userPuzzle = fromFormToArray();
		var solution = getSolution();
		
		lowlightSquares();

		checkErrors(solution, userPuzzle);

	}

	function printPuzzle() {
		
		alert("Descupe, mas a função de imprimir em uma nova janela ainda não está pronta...");

	}

	function newPuzzle() {

		document.location.href = "/jogar/";
		
	}

	function hitEnter() {
		
		comoEstouIndo();

	}