
// Copyright 2007, Steve McLaughlin. All rights reserved.
// iPhoneSudoku.com

var sboard = '';
var sboardstatus = '';
var ssolution = '';
var resume = false;

var board = MultiDimensionalArray(9,9);
var initialboard = MultiDimensionalArray(9,9);
var answerboard = MultiDimensionalArray(9,9);

var level = 1;
var minid = 1;
var difflevel = 0;
var totalscore = 0;
var playing = false;
var nsel = 10;

var gamestart;
var priortime;

function MultiDimensionalArray(iRows, iCols)
{
	var i;
	var j;
	var a = new Array(iRows);
	for (i=0; i < iRows; i++)
	{
		a[i] = new Array(iCols);
		for (j=0; j < iCols; j++)
		{
			a[i][j] = "";
		}
	}
	return a;
}

// function called when player clicks a number
// on the sudoku game board
function cellclick(cell)
{
	
	if(!playing)
		return;
		
	var thisCell = document.getElementById('cl' + cell);
	
	// only allow click here if this is not on the initial board
	
	var r = String(cell).substring(0,1);
	var c = String(cell).substring(2,1);
	
	if(initialboard[r][c] != '0')
	{
		return;
	}
	
	clear_board_background();

	// select this cell if it is not a puzzle cell
	
	thisCell.bgColor ="#ffff00";
	
	// set the value of the cell to the currently selected number
	n = parseInt(nsel);
	s = n.toString();
	if(n == 10)
	{
		n = 0;
		s = "&nbsp;";
	}
	board[r][c] = n;
	
	thisCell.innerHTML = s;
	
	// see if we won the game
	if(is_won())
	{
		alert('Congratulations! You Won!');
	}
		
}

function is_won()
{
	for(var r = 0; r < 9; r++)
	{
		for(var c=0;c<9;c++)
		{
			if(board[r][c] != answerboard[r][c])
				return false;
		}
	}
	playing = false;
	eraseCookie('playingid');
	return true;
}

function clear_board_background()
{
	// unselect all the cells
	for(var r = 0; r < 9; r++)
	{
		for(var c=0;c<9;c++)
		{
			var cl = document.getElementById('cl' + r.toString() + c.toString() );
			cl.bgColor = "";
		}
	}
}

// function called when player clicks a number on the 
// selector
function numclick(cell)
{

	if(!playing && cell != 10)
		return;
		
	var thisCell = document.getElementById('num' + cell);
	
	clear_number_background();

	// select this cell if it is not a puzzle cell
	
	thisCell.bgColor ="#ffff00";
	
	nsel = cell;
	
}

function clear_number_background()
{
	// unselect all the cells

	for(var c=1;c<=10;c++)
	{
		var cl = document.getElementById('num' + c.toString() );
		cl.bgColor = "";
	}
}

/* The following function creates an XMLHttpRequest object... */

function createRequestObject(){
	var request_o; //declare the variable to hold the object.
	var browser = navigator.appName; //find the browser name
	if(browser == "Microsoft Internet Explorer"){
		/* Create the object using MSIE's method */
		request_o = new ActiveXObject("Microsoft.XMLHTTP");
	}else{
		/* Create the object using other browser's method */
		request_o = new XMLHttpRequest();
		request_o.overrideMimeType('text/xml');
	}
	return request_o; //return the object
}

/* You can get more specific with version information by using 
	parseInt(navigator.appVersion)
	Which will extract an integer value containing the version 
	of the browser being used.
*/
/* The variable http will hold our new XMLHttpRequest object. */
var http = createRequestObject(); 


function getpuzzle()
{
	var sURL = 'Puzzle.php';
				
	http.open('post', sURL);
	http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	
	/* Define a function to call once a response has been received. This will be our
		handleProductCategories function that we define below. */
	http.onreadystatechange = handleReceivePuzzle; 
	/* Send the data. We use something other than null when we are sending using the POST
		method. */
			
	var postdata ='cmd=ws_getpuzzle&level=' + level + '&minid2=' + minid ;
	
	// commenting out--this does not work on IE. Be sure that server sets mime type to text/xml
	//http.overrideMimeType('text/xml');
	http.send(postdata);
}

function handleReceivePuzzle()
{
	/* Make sure that the transaction has finished. The XMLHttpRequest object 
		has a property called readyState with several states:
		0: Uninitialized
		1: Loading
		2: Loaded
		3: Interactive
		4: Finished */
	if(http.readyState == 4){ //Finished loading the response
		/* We have got the response from the server-side script,
			let's see just what it was. using the responseText property of 
			the XMLHttpRequest object. */
		//confirm('in there');
				
		if(http.status != 200)
		{
			alert("There was a problem retrieving the XML data " + req.statusText);	
		}
		
		//var dom = http.responseXML.documentElement;
		
		var sdata = http.responseText;
				
		var data = sdata.split("/t");
		
		sboard = data[0];
		difflevel = data[1];
		totalscore = data[2];
		minid = data[3];
		
		// save the minid in a cookie so we don't give them the same games next time they come
		createCookie('lastid',minid,365);
		
		
		ssolution = data[4];
		
		seedpuzzle();
		
		renderpuzzle();
		
		if(resume)
		{
			//alert('Resuming your game...' + minid);
			deserializeboard();
		}
		else
			startTime();
		
		playing = true;
	
		goTime();
	}
}

function seedpuzzle()
{
	
	var ch=0;
	
	// populate the array
	for(r=0;r<9;r++)
	{
		for(c=0;c<9;c++)
		{
			ch = r*9 +c;
			board[r][c] = sboard.substr(ch,1);
			initialboard[r][c] = board[r][c];
			
			answerboard[r][c] = ssolution.substr(ch,1);
		}
	}
	
}

function renderpuzzle()
{
	// set the cells on the board
	for(r=0;r<9;r++)
	{
		for(c=0;c<9;c++)
		{
			var cl = document.getElementById('cl' + r.toString() + c.toString() );
				
			s = board[r][c].toString();
			if(s=='0')
			{
				s = '&nbsp;';
			}
			else
			{
				s = '<b>' + s + '</b>';
			}
				
			cl.innerHTML = s;
		}
	}
}

function serializeboard()
{
	sboardstatus = '';
	for(r=0;r<9;r++)
	{
		for(c=0;c<9;c++)
		{
			s = board[r][c].toString();
			sboardstatus = sboardstatus + s;
		}
	}
}

function deserializeboard()
{
	// set the cells on the board that the user had set last time they were playing
	var ch=0;
	
	// populate the array
	for(r=0;r<9;r++)
	{
		for(c=0;c<9;c++)
		{
			var cl = document.getElementById('cl' + r.toString() + c.toString() );
			
			ch = r*9 +c;
			board[r][c] = sboardstatus.substr(ch,1);
			
			// Plot it on the grid
			if(board[r][c] != initialboard[r][c])
			{
				s = board[r][c].toString();
				if(s=='0')
				{
					s = '&nbsp;';
				}
					
				cl.innerHTML = s;
				
			}
		}
	}
}

function showanswer()
{
	clear_board_background();
	clear_number_background();
	
	// set the cells on the board
	for(r=0;r<9;r++)
	{
		for(c=0;c<9;c++)
		{
			var cl = document.getElementById('cl' + r.toString() + c.toString() );
				
			if(answerboard[r][c] == initialboard[r][c])
			{
				s = '<b>' + answerboard[r][c].toString() + '</b>';
			}
			else if(answerboard[r][c] == board[r][c])
			{
				s = '<font color=green><b>' + answerboard[r][c].toString() + '</b></font>';
			}
			else
				s = '<font color=red><b>' + answerboard[r][c].toString() + '</b></font>';
			
				
			cl.innerHTML = s;
		}
	}
	
	playing = false;
	
	eraseCookie('playingid');
	eraseCookie('priortime');
}

function newgamebutton()
{
	eraseCookie('playingid');
	eraseCookie('level');
	newgame();
}

function newgame()
{
	var mylev = document.getElementById("difficulty");
	level = mylev.selectedIndex + 1;
	
	clear_board_background();
	clear_number_background();
		
	numclick(10);
	
	resume = resumegame();
		
	getpuzzle();	
	
	if(!resume)
		startTime();		
}

// Save the game for continuing later--this is helpful for when the person clicks a link to leave inadvertently and comes back
// store it in cookies

function savegame()
{
	// store the id of the current game
	createCookie('playingid', minid, 365);
	
	// save the level of current game
	createCookie('level', level, 365);
	
	// store the current state of player moves

	serializeboard();
	
	createCookie('sboardstatus', sboardstatus, 365);
	
	// save the amount of time elapsed
	var now = new Date;
	priortime = now.getTime() - gamestart;
	
	createCookie('priortime',priortime, 365);
	
}

// resume a saved game if one exists
function resumegame()
{
	// BROKEN, so for now, don't resume
	//return false;
	
	var id = readCookie('playingid');
	if(id == null)	// no cookie for playing, so set the number from the cookie of last game they saw
	{
		minid = readCookie('lastid');
		if(minid == null)
			minid = 1;
		return false;
	}
	
	// hide the help popup
	hidehelp();
	//showresume();
		
	sboardstatus = readCookie('sboardstatus');
	
	level = readCookie('level');
	if(level == null)
		level = 1;
	else
		level = parseInt(level);
			
	// move to prior id so we get this one again...
	minid = parseInt(id) -1;
		
	// reset the gamestart so it includes the prior elapsed time
	priortime = readCookie('priortime');
		
	if(priortime == null)
		priortime=0;
	
	var now = new Date;
	gamestart = now.getTime() - priortime;
	
	
	return true;
}

function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}

function showhelp()
{
	var obj = document.getElementById('help');
	obj.style.visibility = "visible";
}

function hidehelp()
{
	var obj = document.getElementById('iphone');
	obj.style.visibility = "hidden";
	
	var obj = document.getElementById('help');
	obj.style.visibility = "hidden";
}

function showresume()
{
	var obj = document.getElementById('resume');
	obj.style.visibility = "visible";
}

function hideresume()
{
	var obj = document.getElementById('resume');
	obj.style.visibility = "hidden";
	
}



function startTime()
{
	// number of milliseconds since Jan 1, 1970
	var now = new Date;
	gamestart = now.getTime();
}

function goTime()
{
	var now = new Date;
	var elapsed = now.getTime() - gamestart;
	
	s = Math.round(elapsed + 1000) / 1000;
	d = Math.round(s / 86400);
	s %= 86400;
	h = Math.floor(s / 3600);
	s %= 3600;
	m = Math.floor(s / 60);
	s %= 60;
	s = Math.round(s);
	
	// add a zero in front of numbers < 10
	m=checkTime(m);
	s=checkTime(s);
	var c = "";
	if(h > 0)
		c += h + ":";
	
	c += m + ":" + s;
	document.getElementById('timer').innerHTML = c;
	if(playing)
		t=setTimeout('goTime()',500);
}

function checkTime(i)
{
	if(i<10)
	{
		i="0" + i;
	}
	return i;
}