
	
	var squareSize = 60;
	var numSquares = 9;
	var currRow = 0, currCol = 0;
	var prevRow = 0, prevCol = 0;

	// 2D array that holds the numbers on the board
	var boardMap;

	// 2D array which specifies which cells the user can edit 
	// (can=-1		can't=0)
	// Computer placed numbers can't be edited
	// Depending on the difficulty, user can(not) replace numbers already placed
	// Currently, only easy mode is active
	var boardEditMap;				

	// 1 = Easy, 2 = Difficult
	var difficulty = 1;

	var squareColor = 'red';
	var boardContext, markerContext;
	var canvasSize = numSquares * squareSize;
	var mode;

	var boardLeft = 300;
	var boardTop = 0;

	var imagesToLoad = numSquares;
	var imagesLoaded = 0;
	var numberImages = {};

	function startLoadingImages()
	{
		for (var temp=1; temp<numSquares + 1; temp++)
		{
			numberImages[temp] = new Image();
			numberImages[temp].onload = function()
			{
				imagesLoaded++;
			}
			numberImages[temp].src = [temp, '.png'].join('');
		}
	}

	function setupBoardMap()
	{
		var prePlacedNumbers = 20;
		boardMap = new Array();
		boardEditMap = new Array();

		for(var tempRow = 0; tempRow < numSquares; tempRow++)
		{
			boardMap[tempRow] = new Array();
			boardEditMap[tempRow] = new Array();
			for(var tempCol = 0; tempCol < numSquares; tempCol++)
			{
				boardMap[tempRow][tempCol] = -1;
				boardEditMap[tempRow][tempCol] = -1;
			}
		}

		var randNumber;
		var totalSquares = numSquares * numSquares;
		var row, col;
		for(var temp = 0; temp<prePlacedNumbers; temp++)
		{
			do{
				randNumber = Math.random() * totalSquares;
				row = parseInt(randNumber / numSquares);
				col = parseInt(randNumber % numSquares);

				if(!boardMap[row])
					alert('row:' + row + '\ncol:' + col);
			}while(boardMap[row][col] != -1);

			do{
				randNumber = parseInt(Math.random() * numSquares + 1);
			}while (!isNumberSuitable(row, col, randNumber));

			putNumberOnBoard(row, col, randNumber, true);
			boardEditMap[row][col] = 0;
		}
	}


	function drawBoard()
	{
		boardContext.clearRect(0, 0, canvasSize, canvasSize);

		var tempRow, tempCol;
		for(tempRow=0; tempRow<numSquares; tempRow++)
		{
			for(tempCol=0; tempCol<numSquares; tempCol++)
			{
				boardContext.strokeStyle="blue";
				boardContext.lineWidth = 1;
				boardContext.strokeRect(tempCol * squareSize, tempRow * squareSize , squareSize, squareSize);
			}
		}

		boardContext.strokeStyle = 'red';
		boardContext.lineWidth = 2;
		boardContext.strokeRect(0, 0, squareSize * 3, squareSize * 9);
		boardContext.strokeRect(squareSize * 6, 0, squareSize * 3, squareSize * 9);
		boardContext.strokeRect(0, 0, squareSize * 9, squareSize * 3);
		boardContext.strokeRect(0, squareSize * 6, squareSize * 9, squareSize * 3);

		focusCell(currRow, currCol);
	}

	function focusCell(row, col)
	{
		currRow = row;
		currCol = col;
		markerContext.clearRect(0, 0, canvasSize, canvasSize);
		markerContext.fillRect(col * squareSize, row * squareSize, squareSize, squareSize);
	}

	function putNumberOnBoard(row, col, numberToPut, computerAssigned)
	{
		boardContext.drawImage(numberImages[numberToPut], 3 + col * squareSize, 3 + row * squareSize);
		boardMap[row][col] = numberToPut;

		if(computerAssigned)
		{
			boardContext.fillStyle = "rgba(100, 100, 100, 0.3)";
			boardContext.fillRect(col * squareSize, row * squareSize, squareSize, squareSize);
		}
	}

	function isNumberSuitable(row, col, numberToCheck)
	{
		var temp;
		for(temp=0; temp<numSquares; temp++)
			if( (boardMap[row][temp] == numberToCheck) || (boardMap[temp][col] == numberToCheck) )
				return false;
		
		// find out start x and y of group
		row = parseInt(row / 3) * 3;
		col = parseInt(col / 3) * 3;

		var tempRow, tempCol;
		for(tempRow = row; tempRow < row + 3; tempRow++)
			for(tempCol = col; tempCol < col + 3; tempCol++)
				if(boardMap[tempRow][tempCol] == numberToCheck)
					return false;
		
		return true;
	}

	function registerEventHandlers()
	{
		window.onkeypress = function(event)
		{
			if(event.keyCode == 37)
				currCol > 0 ? currCol-- : currCol;
			else if(event.keyCode == 38)
				currRow > 0 ? currRow-- : currRow;
			else if(event.keyCode == 39)
				currCol < numSquares - 1 ? currCol++ : currCol;
			else if(event.keyCode == 40)
				currRow < numSquares - 1 ? currRow++ : currRow;
			else
			{
				if(event.which >= 49 && event.which <= 57)
					if(boardEditMap[currRow][currCol] != 0)
						if(isNumberSuitable(currRow, currCol, event.which - 48))
						{
							putNumberOnBoard(currRow, currCol, event.which - 48);
						
							if(difficulty == 2)
								boardEditMap[currRow][currCol] = 0;
						}
				return;
			}
			event.preventDefault();
			focusCell(currRow, currCol);
		}

		document.getElementById('markerOverlay').oncontextmenu = function(event)
		{
			// for old fashioned debugging
			alert('[DEBUG] boardMap: ' + boardMap[currRow][currCol]); 
			alert('[DEBUG] boardEditMap: ' + boardEditMap[currRow][currCol]); 
			event.preventDefault();
		}

		document.getElementById('markerOverlay').onclick = function(event)
		{
			var x = event.pageX - boardLeft;
			var y = event.pageY - boardTop;

			var row = parseInt(y/squareSize);
			var col = parseInt(x/squareSize);

			if(row > -1 && row < numSquares && col > -1 && col < numSquares)
				focusCell(row, col);
		}

	}

/*
	function waitForImagesToLoadAndSetupBoard()
	{
		alert("called");
		if(imagesLoaded < imagesToLoad)
		{
			setTimeout('waitForImagesToLoadAndSetupBoard()', 10000);
			return;
		}
		alert(document.getElementById('markerOverlay'));
		registerEventHandlers();	
		drawBoard();
		setupBoardMap();

	}
*/

function showGame(trueFalse)
{
	if(trueFalse)
	{
		document.getElementById('bodyMaskDiv').style.display = 'block';
		document.getElementById('containerDiv').style.display = 'block';
	}
	else
	{
		document.getElementById('bodyMaskDiv').style.display = 'none';
		document.getElementById('containerDiv').style.display = 'none';
	}
}


function showHelp()
{
	var msg = ['Use arrow keys or mouse to move to different grid positions.\n',
		'The initial board is random and is not populated by Sudoku rules.\n',
		'So the game may be unsolvable.\n\n',
		'If you see a grid with no numbers, probably the images did not ',
		'finish loading. Refresh the page and try again. And do let me know ',
		'if you have come across a working way of loading images "synchronously".\n\n'].join('');

		alert(msg);
}

function changeDifficulty(diff)
{
	difficulty = diff;
}

function initGame()
{
	var board = document.getElementById('board'); 
	var overlay = document.getElementById('markerOverlay');

	if(!board.getContext)
	{
		var message = ['Your browser does not support graphics contexts!\n',
						'This script has been tested on Firefox 2.0.0.6.'].join('');
		alert(message);
	}
	else
	{
		if(imagesLoaded < imagesToLoad)
		{
			var msg = ['All images have not been loaded completely. Please refresh the ',
						'page and wait a moment before hitting Play.\n\n',
						'If you have come across any way of loading images synchronously, ',
						'do let me know.'].join('');

			//alert(msg);
			//return false;
		}

		

		boardContext = board.getContext('2d');
		markerContext = overlay.getContext('2d');
		markerContext.fillStyle = "rgba(255, 255, 0,0.5)";
		
		drawBoard();
		setupBoardMap();
		registerEventHandlers();
	}
}
