var squareObjects = new Array();
	var level = 1;	// 1 is lowest level
	var countSquares = [36,36,34,32,31,30];
	var gameFinished = false;
	function shuffleBoard()
	{
		for(var counter=0;counter<30;counter++){
			var number1 = Math.ceil(Math.random()*9);
			var number2 = Math.ceil(Math.random()*9);
			while(number2==number1){
				number2 = Math.ceil(Math.random()*9);
			}	

			var tmpObjects1 = new Array();
			var tmpObjects2 = new Array();
			
			for(var no=0;no<squareObjects.length;no++){					
				var txtObj = squareObjects[no].getElementsByTagName('SPAN')[0];						
				if(txtObj.innerHTML == number1)tmpObjects1.push(txtObj);	
				if(txtObj.innerHTML == number2)tmpObjects2.push(txtObj);
			}
			
			for(var no=0;no<tmpObjects1.length;no++){
				tmpObjects1[no].innerHTML = number2;	
				tmpObjects2[no].innerHTML = number1;	
			}
		}
		resetVisibleNumberArray();
		showColumnsInGroup();
	}
	
	function resetVisibleNumberArray()
	{
		for(var no=0;no<=9;no++){
			visibleNumberArray[no] = 0;
		}		
	}
	
	function newGame()
	{
		var obj = document.getElementById('sudoku');
		var subObjects = obj.getElementsByTagName('DIV');
		for(var no=0;no<subObjects.length;no++){
			if(subObjects[no].className=='sudokuSquare'){
				subObjects[no].style.backgroundColor='';	
				var spans = subObjects[no].getElementsByTagName('SPAN');
				spans[0].style.display='none';
				spans[1].innerHTML = '';
			}
		}	
		
	}
	
	var visibleNumberArray = new Array();

	function randomizeArray(a,b){
		return Math.random() - Math.random();
	}
		
	function showCell(inputDiv)
	{
		var span = inputDiv.getElementsByTagName('SPAN')[0];
		span.style.display='';
		inputDiv.style.backgroundColor='#DDD';
		span.style.color='#317082';
		var typingSpan = inputDiv.getElementsByTagName('SPAN')[1];
		typingSpan.style.display='none';			
		
	}
	
	function showColumnsInGroup(){		
		var object = document.getElementById('sudoku');
		var cellsRevealed = new Array();
		var numberArray = new Array();
		var groupCountArray = new Array();
		var maxInGroup=5;
		if(level<=0)level=1;
		if(level==1)maxInGroup=4;
		for(var no=0;no<countSquares[level];no++){			
			do{
				var row = Math.floor(Math.random()*9);
				var col = Math.floor(Math.random()*9);
				var obj = document.getElementById('square_' + row + '_' + col);
				var parentID = obj.parentNode.id;
				var span = obj.getElementsByTagName('SPAN')[0];	
				if(!numberArray[span.innerHTML])numberArray[span.innerHTML]=0;
				if(!groupCountArray[parentID])groupCountArray[parentID]=0;
			}while(cellsRevealed[row + '_' + col] || numberArray[span.innerHTML]>(3+Math.ceil(level/2)) || groupCountArray[parentID]>=maxInGroup);
			cellsRevealed[row + '_' + col] = true;
			if(!numberArray[span.innerHTML])numberArray[span.innerHTML]=0;
			numberArray[span.innerHTML]++;
			groupCountArray[parentID]++;
			showCell(obj);
			
		}
	}
	var higlightedCell;
	function highlightSquare(e,inputObj){
		document.getElementById('hintDiv').style.display='none';
		if(!inputObj)inputObj = this;	
		if(inputObj.style.backgroundColor)return;
		if(gameFinished)return;
		inputObj.className='sudokuSquareHighlighted';
		if(higlightedCell && higlightedCell!=inputObj)higlightedCell.className='sudokuSquare';
		higlightedCell = inputObj;
		if(document.all)inputObj.focus();
		
	}
	
	
	function isGameFinished()
	{
		var obj = document.getElementById('sudoku');
		var subDivs = obj.getElementsByTagName('DIV');
		var allOk = true;
		for(var no=0;no<subDivs.length;no++){
			if(subDivs[no].className.indexOf('sudokuSquare')>=0 && !subDivs[no].style.backgroundColor){
				var spans = subDivs[no].getElementsByTagName('SPAN');
				if(spans[0].innerHTML != spans[1].innerHTML){
					allOk=false;
					break;
				}
			}	
		}
		
		if(allOk)alert('Gefeliciteerd! U heeft deze sudoku correct opgelost.');
		
	}
	
	function initSudoku()
	{
		gameFinished = false;
		document.getElementById('hintDiv').style.display='none';
		var matrix = new Array();
		for(var rowCounter=0;rowCounter<9;rowCounter++){
			matrix[rowCounter] = new Array();
			for(var colCounter=0;colCounter<9;colCounter++){
				var number = colCounter/1 + 1 + (rowCounter*3) + Math.floor(rowCounter/3)%3;
				if(number>9)number = number % 9;
				if(number==0)number=9;
				matrix[rowCounter][colCounter] = number;				
			}			
		}
		
		// Switching rows
		
		for(var no=0;no<9;no+=3){
			
			for(var no2=0;no2<3;no2++){
				row1 = Math.floor(Math.random()*3);	
				row2 = Math.floor(Math.random()*3);	
				while(row2==row1){
					row2 = Math.floor(Math.random()*3);	
				}
				row1 = row1 + no;
				row2 = row2 + no;			
				var tmpMatrix = new Array();
				tmpMatrix = matrix[row1];
				matrix[row1] = matrix[row2];
				matrix[row2] = tmpMatrix; 				
			}			
		}
		
		// Switching columns
		
		for(var no=0;no<9;no+=3){
			for(var no2=0;no2<3;no2++){
				col1 = Math.floor(Math.random()*3);	
				col2 = Math.floor(Math.random()*3);	
				while(col2==col1){
					col2 = Math.floor(Math.random()*3);	
				}
				col1 = col1 + no;
				col2 = col2 + no;			

				var tmpMatrix = new Array();
				for(var no3=0;no3<matrix.length;no3++){
					tmpMatrixValue = matrix[no3][col1];
					matrix[no3][col1] = matrix[no3][col2];				
					matrix[no3][col2] = tmpMatrixValue;				
				}
			}	
		}
		
		
		for(var no=0;no<matrix.length;no++){
			for(var no2=0;no2<matrix[no].length;no2++){				
				var obj = document.getElementById('square_' + no + '_' + no2);
				var spanObjects = obj.getElementsByTagName('SPAN');
				
				var span = spanObjects[0];
				span.innerHTML = matrix[no][no2];		
				span.style.display='none';	
				
				spanObjects[1].innerHTML = '';
				spanObjects[1].style.display = '';
				spanObjects[1].style.color='#000';	

				obj.onclick = highlightSquare;
						
				squareObjects.push(obj);						
			}			
		}
		if(document.all){
			document.body.onkeydown = insertNumber;
		}else{
			document.documentElement.onkeydown = insertNumber;
		}

		newGame();
		shuffleBoard();
	}
	function insertNumber(e)
	{
		document.getElementById('hintDiv').style.display='none';

		if(document.all)e = event;
		if(!higlightedCell)return;
		if(gameFinished)return;
		if (e.keyCode) code = e.keyCode; else if (e.which) code = e.which;
		var span = higlightedCell.getElementsByTagName('SPAN')[1];
		
		var numbers = higlightedCell.id.split('_');

		var row = numbers[1]/1;
		var col = numbers[2]/1;
		var nextObject = false;
			
		if(code==39){ // Right arrow
			if(col<8){
				nextObject = document.getElementById('square_' + row + '_' + (col/1+1));
				if(nextObject.style.backgroundColor){
					while(col<8 && nextObject.style.backgroundColor){
						col = col+1;
						nextObject = document.getElementById('square_' + row + '_' + col);
					}
				}				
			}
		}
		if(code==37){ // Left arrow
			if(col>0){
				nextObject = document.getElementById('square_' + row + '_' + (col/1-1));
				if(nextObject.style.backgroundColor){
					while(col>0 && nextObject.style.backgroundColor){
						col = col-1;
						nextObject = document.getElementById('square_' + row + '_' + col);
					}
				}
				if(nextObject.style.backgroundColor)nextObject = false;
			}
		}
		if(code==38){
			if(row>0){
				nextObject = document.getElementById('square_' + (row-1) + '_' + col);
				if(nextObject.style.backgroundColor){
					while(row>0 && nextObject.style.backgroundColor){
						row = row-1;
						nextObject = document.getElementById('square_' + row + '_' + col);
					}
				}				
			}
		}		
		if(code==40){
			if(row<8){
				nextObject = document.getElementById('square_' + (row+1) + '_' + col);
				if(nextObject.style.backgroundColor){
					while(row<8 && nextObject.style.backgroundColor){
						row = row+1;
						nextObject = document.getElementById('square_' + row + '_' + col);
					}
				}	
			}
		}
		
		if(nextObject){
			highlightSquare(false,nextObject);
		}
		
		if(code==46 || code==8){	// Delete
			span.innerHTML = '';
			if(code==8)return false;
		}
		if(code>96 && code<=105)code-=48;
		if(code>48 && code<=57){				
			var theChar = String.fromCharCode(code);
			span.innerHTML = theChar;
		}		
		
		isGameFinished();
	}	
	
	function helpMe()
	{
		if(gameFinished)return false;
		
		if(confirm('Weet u zeker dat u de juiste oplossing wilt zien?')){
			var allreadyRevealed = true;
			var counter = 0;
			do{
				var row = Math.floor(Math.random()*9);
				var col = Math.floor(Math.random()*9);
				
				var el = document.getElementById('square_'+row+'_'+col);	
				
				var spans = el.getElementsByTagName('SPAN');
				if(spans[1].innerHTML.length==0){
					spans[1].innerHTML = spans[0].innerHTML;
					spans[1].style.color='#FF0000';
					allreadyRevealed =  false;					
				}	
				if(el.style.backgroundColor)allreadyRevealed=true;
				counter++
			}while(allreadyRevealed && counter<500);		
		}
		
		isGameFinished();
		
	}
		
	function isCorrect(divObj)
	{
		var spans = divObj.getElementsByTagName('SPAN');
		if(spans[0].innerHTML==spans[1].innerHTML || spans[1].innerHTML.length==0)return true;
		return false;		
	}
	
	function getTopPos(inputObj)
	{
		
	  var returnValue = inputObj.offsetTop;
	  while((inputObj = inputObj.offsetParent) != null){
	  	returnValue += inputObj.offsetTop;
	  }
	  return returnValue;
	}
	
	function getLeftPos(inputObj)
	{
	  var returnValue = inputObj.offsetLeft;
	  while((inputObj = inputObj.offsetParent) != null)returnValue += inputObj.offsetLeft;
	  return returnValue;
	}
		
	function getPossibleNumbers(inputObj)
	{
		var noArray = new Array();
		var countNumbers = 0;
		var spans = inputObj.getElementsByTagName('SPAN');
		if(spans[0].innerHTML ==spans[1].innerHTML)return 0;
		
		var parentDiv = inputObj.parentNode;
		var subDivs = parentDiv.getElementsByTagName('DIV');
		for(var no=0;no<subDivs.length;no++){
			if(subDivs[no]!=inputObj){
				var spans = subDivs[no].getElementsByTagName('SPAN');
				if(spans[0].innerHTML == spans[1].innerHTML || subDivs[no].style.backgroundColor.length>1){
					if(!noArray[spans[0].innerHTML]){
						noArray[spans[0].innerHTML] = true;		
						countNumbers++;
					}		
				}
			}	
		}
	
		var numbers = inputObj.id.split('_');
		var row = numbers[1];
		var col = numbers[2];
		
		for(var no=0;no<9;no++){			
			
			var obj = document.getElementById('square_' + row + '_' + no);
			if(obj!=inputObj){
				var spans = obj.getElementsByTagName('SPAN');	
				if(spans[0].innerHTML == spans[1].innerHTML || !spans[0].style.display){
					if(!noArray[spans[0].innerHTML]){
						noArray[spans[0].innerHTML] = true;		
						countNumbers++;
					}			
				}
			}
			
			var obj = document.getElementById('square_' + no + '_' + col);
			if(obj!=inputObj){
				var spans = obj.getElementsByTagName('SPAN');	
				if(spans[0].innerHTML == spans[1].innerHTML || !spans[0].style.display){
					if(!noArray[spans[0].innerHTML]){
						noArray[spans[0].innerHTML] = true;	
						countNumbers++;
					}				
				}
			}
		}	

		return countNumbers;
	}
	
	function showHint()
	{
		var hintDiv = document.getElementById('hintDiv');
		var hintDivInner = hintDiv.getElementsByTagName('DIV')[0];
		var maxExistingNo = 0;	
		var objectToTry =false;	
		for(var row=0;row<9;row++){
			for(var col=0;col<9;col++){
				var obj = document.getElementById('square_' + row + '_' + col);
				if(obj.style.backgroundColor)continue;
				if(!isCorrect(obj)){
					hintDivInner.innerHTML = 'Deze is niet goed';
					hintDiv.style.left = getLeftPos(obj) + 'px';
					hintDiv.style.top = getTopPos(obj) - 50 + 'px';
					hintDiv.style.display='block';		
					return;			
				}	
				
				var existingNumbers = getPossibleNumbers(obj);	
				if(existingNumbers>maxExistingNo){
					maxExistingNo = existingNumbers;
					objectToTry = obj;					
				}	
			}
		}
		
		if(objectToTry){
			hintDivInner.innerHTML = 'Probeer deze eens';
			hintDiv.style.left = getLeftPos(objectToTry) + 'px';
			hintDiv.style.top = getTopPos(objectToTry) - 50 + 'px';
			hintDiv.style.display='block';				
			
		}
		
		
	}
	
	
	function revealAll()
	{
		for(var row=0;row<9;row++){
			for(var col=0;col<9;col++){
				var obj =document.getElementById('square_'+row+'_'+col);
				var spans = obj.getElementsByTagName('SPAN');
				spans[0].style.display='';
				spans[1].style.display='none';	
				spans[1].style.color='#000000';	
			}
		}
		gameFinished=true;
	}
	
	function switchLevel(initLevel,linkObj)
	{
		var confirmSwitch = gameFinished;
		if(!confirmSwitch)confirmSwitch = confirm('Klik op OK om de huidige sudoku te beëindigen');
		if(confirmSwitch){
			var parentObj = linkObj.parentNode.parentNode;
			var links = parentObj.getElementsByTagName('A');
			for(var no=0;no<links.length;no++){
				links[no].style.color='#001331';
			}
			linkObj.style.color = '#ff6700';
			level = initLevel;
			setTimeout('initSudoku()',20);		
		}
	}
	

	
	window.onload = initSudoku;
