var debug = 0;
var horizondal_line_width = 350;
var vertical_line_height = 370;
var default_number_per_box = 4;
var repeated_at = ""; 
var compleated = 0;   

var active_stylesheet="classic-style"; 
var selected_cell; 
var timer_started = 0;
var timer_clock;
var timer_element;
var timer_seconds = 0;
var timer_paused = 0;


var xy = new Array(9);
for(var i=0;i<9;i++) {
	xy[i] = new Array(9);
}
var cells = new Array(9);
for(var i=0;i<9;i++) {
	cells[i] = new Array(9);
}


var puzzles = new Array(
"abc.gdefihdeif.hagcbfgh.cibade.bf.iehdcg.ae.acbf.gid.hghdiace.bficgdabhefh.b.f.cg.eaidde.ahfibcg", //15
"a.bfhiec.g.ddcg.fbai.heiehdg.cabfdegi.hc.fabai.cb.df.eghhf.be.agcidbfi.edhgcac.adgf.iheb.g.hebcaf.di", //19
"bfi.edhgcac.adgf.iheb.g.hebcaf.dia.b.fhiec.g.ddcg.fbai.heiehdg.cabfdegi.hc.fabai.cb.df.eghhf.be.agcid", //20
"ib.ad.c.g.efhe.hc.fbiagd.fg.daehcibbhcgd.faiegf.ei.ab.dchdai.hcebfgfgdcai.he.bbeahd.gc.ifih.c.e.bf.gda", //21
"aeh.dfi.cgbcf.b.e.hgiad.gidc.abfeh.fc.g.b.aeihdb.eifdha.gchda.ig.cebfg.bfhd.aeic.dcegi.f.hbaah.ibce.dfg",
"dah.iegfcbbigfd.cehae.fchab.gi.dbh.fe.gacidcedi.bhgaf.ag.i.d.cfbh.egb.ch.dea.f.ihf.e.aci.d.gbid.a.fbgceh",
"cf.b.ag.eidhhd.eif.cbaga.g.ibdh.fceg.acb.ifhe.d.dehgcafb.i.ifbe.hdg.acdc.iebg.f.haegf.ahd.cibhba.ci.f.deg",
"chfgeai.d.be.gdib.hcf.ab.iacf.dh.gefa.d.hcg.ebigic.bd.eahfeb.hfa.i.gdcd.gh.bica.fe.fei.hagd.cb.a.cbdefihg",
"adbfheig.c.icfba.gdeh.he.gcidfa.bcb.ide.ah.fgag.dh.fbei.cefhigcbd.abi.he.cd.gafg.de.fbach.i.acf.g.hid.b.e",
"ied.a.bfghchcfgeia.b.dagbh.cdi.efb.ied.ca.f.ghcga.ef.hdib.fd.hbig.cae.hdie.fg.cabb.a.e.ihcf.dggfcd.b.aehi",
"h.g.bc.ea.idfa.ci.bf.dgehfe.dih.gcbab.fi.ehg.acdh.dcfabi.geag.edc.ib.fhdah.gbe.ficebf.ci.ad.hggi.ch.df.e.ab",
".e.cadbhfgi.fbhegiad.cg.di.afch.bei.h.fba.g.cd.e.badhceif.g.ec.g.dif.b.hag.ibhe.da.fc.chagifde.bfedcabi.g.h",
"ge.c.h.i.fdabaif.bg.d.echdh.bae.cf.gic.he.fbdig.a.dbageifh.c.ifgca.hb.deb.dh.efg.acicf.e.ia.bhdggia.h.c.d.ebf",
"deb.cg.a.ihff.ah.dbi.egccgi.h.fe.bda.gcdf.bihae.a.fb.hd.ec.i.geihg.acfb.dbi.ca.d.hefgge.dbc.fi.haah.f.ie.gdcb"
);

var chosen = 0;
var this_puzzle = ""; 
var orginal_game = ""; 


var sudoku_fingerprint = getCookie("sudoku_fingerprint"); 	 
if (sudoku_fingerprint == null || sudoku_fingerprint == "") sudoku_fingerprint=""; 
function getCookie(name) {
	var start = document.cookie.indexOf( name + "=" );
	var len = start + name.length + 1;
	if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
		return null;
	}
	if ( start == -1 ) return null;
	var end = document.cookie.indexOf( ";", len );
	if ( end == -1 ) end = document.cookie.length;
	return unescape( document.cookie.substring( len, end ) );
}
function setCookie(name, value) {
	var today = new Date();
	today.setTime( today.getTime() );
	var expires = 28;
	expires = expires * 1000 * 60 * 60 * 24;
	var expires_date = new Date( today.getTime() + (expires) );
	document.cookie = name+"="+escape( value ) +
		( ( expires ) ? ";expires="+expires_date.toGMTString() : "" )
}

function selectStyleSheet() {
	$(active_stylesheet).disabled=true;
	active_stylesheet = $("style-selector").value;
	$(active_stylesheet).disabled=false;
}

function $(id) { return document.getElementById(id); }
function addEvent(elm, evType, fn) {
	if (elm.addEventListener) {
		elm.addEventListener(evType, fn, false);
		return true;
	}
	else if (elm.attachEvent) {
		var r = elm.attachEvent('on' + evType, fn);
		return r;
	}
	else {
		elm['on' + evType] = fn;
	}
}
function removeEvent(elm, evType, fn) {
	if (elm.removeEventListener) {
		elm.removeEventListener(evType, fn, false);
		return true;
	}
	else if (elm.detachEvent) {
		var r = elm.detachEvent('on' + evType, fn);
		return r;
	}
	else {
		elm['on' + evType] = '';
	}
}

function findTarget(e) {
	var element;
	if (!e) var e = window.event;
	if (e.target) element = e.target;
	else if (e.srcElement) element = e.srcElement;
	if (element.nodeType == 3) element = element.parentNode;// defeat Safari bug
	return element;
}


function hex2num(hex) {
	if(hex.charAt(0) == "#") {	
		hex = hex.slice(1);
	}
	hex = hex.toUpperCase();
	var hex_alphabets = "0123456789ABCDEF";
	var value = new Array(3);
	var k = 0;
	var int1,int2;
	for(var i=0;i<6;i+=2) {
		int1 = hex_alphabets.indexOf(hex.charAt(i));
		int2 = hex_alphabets.indexOf(hex.charAt(i+1)); 
		value[k] = (int1 * 16) + int2;
		k++;
	}
	return(value);
}
function num2hex(triplet) {
	var hex_alphabets = "0123456789ABCDEF";
	var hex = "#";
	var int1,int2;
	for(var i=0;i<3;i++) {
		int1 = triplet[i] / 16;
		int2 = triplet[i] % 16;

		hex += hex_alphabets.charAt(int1) + hex_alphabets.charAt(int2); 
	}
	return(hex);
}

function fadeColor(id,start_hex,stop_hex,difference,delay,color_background) {

	if(!difference) difference = 20;
	if(!delay) delay = 100;
	if(!start_hex) start_hex = "#FFFFFF";
	if(!stop_hex) stop_hex = "#000000";
	if(!color_background) color_background = "c";
	
	var ele = document.getElementById(id);
	if(!ele) return;
	var start= hex2num(start_hex);
	var stop = hex2num(stop_hex);
	

	for(var i=0;i<3;i++) {
		start[i] = Number(start[i]);
		stop[i] = Number(stop[i]);
	}

	for(var i=0;i<3;i++) {
		if (start[i] < stop[i]) {
			start[i] += difference;
			if(start[i] > stop[i]) start[i] = stop[i];
		}
		else if(start[i] > stop[i]) {
			start[i] -= difference;
			if(start[i] < stop[i]) start[i] = stop[i];
		}
	}
	
	var color = "rgb("+start[0]+","+start[1]+","+start[2]+")";
	if(color_background == "b") {
		ele.style.backgroundColor = color;
	} else {
		ele.style.color = color;
	}

	if((start[0] == stop[0]) && (start[1] == stop[1]) && (start[2] == stop[2])) return;

	start_hex = num2hex(start);

	window.setTimeout("fadeColor('"+id+"','"+start_hex+"','"+stop_hex+"',"+difference+","+delay+",'"+color_background+"')",delay);
}

function getIndex(x,y) {
	var index = (y*3) + x - 3;
	return index;
}

function getXY(index) {
	var x=1,y=1;
	switch (index) { 
		case 1: y=1; x=1; break;
		case 2: y=1; x=2; break;
		case 3: y=1; x=3; break;
		case 4: y=2; x=1; break;
		case 5: y=2; x=2; break;
		case 6: y=2; x=3; break;
		case 7: y=3; x=1; break;
		case 8: y=3; x=2; break;
		case 9: y=3; x=3; break;
	}
	return Array(x,y);
}

function rand() {
	var number = Math.round(Math.random()*10);
	while (number < 1 || number > 9) { //If the number is 0 or 10, get another number.
		number = Math.round(Math.random()*10);
	}
	return number; 
}


function uniqueRand(list) {
	var number = rand();

	for(var a=0;a<list.length;a++) {
		if(list[a] == number) { 
			number = rand(); 
			a=-1; 
		}
	}
	return number;
}

function show(data,color) {
	document.getElementById("display_area").innerHTML = data + "<br>\n";
	document.getElementById("display_area").style.color = color;
}


function helpLineV(line) {
	var item = document.getElementById("lv-"+line).style;
	if(item.position == "absolute") {
		item.position = "relative";
		item.height = "10px";
	} else {   
		item.position = "absolute";
		item.height = vertical_line_height + "px";
	}
}

function helpLineH(line) {
	var item = document.getElementById("lh-"+line).style;
	if(item.position == "absolute") {
		item.position = "relative";
		item.width = "5px";
	} else {
		item.position = "absolute";
		item.width = horizondal_line_width + "px";
	}
}


function isHorizondal(box,check_in) {
	if((box == 1 || box == 2 || box == 3) & (check_in == 1 || check_in == 2 || check_in == 3)) return true;
	if((box == 4 || box == 5 || box == 6) & (check_in == 4 || check_in == 5 || check_in == 6)) return true;
	if((box == 7 || box == 8 || box == 9) & (check_in == 7 || check_in == 8 || check_in == 9)) return true;
	return false;
}


function isVertical(box,check_in) {
	if((box == 1 || box == 4 || box == 7) & (check_in == 1 || check_in == 4 || check_in == 7)) return true;
	if((box == 2 || box == 5 || box == 8) & (check_in == 2 || check_in == 5 || check_in == 8)) return true;
	if((box == 3 || box == 6 || box == 9) & (check_in == 3 || check_in == 6 || check_in == 9)) return true;
	return false;
}

function checkForUnique(box,cell,full_check) {
	box ++;
	cell++;

	var number = cells[box-1][cell-1].value;


	if(box>1 || full_check) {
	var boxes_to_check = new Array(); 
	switch (box) {
		case 1 : if(full_check) {
				 	boxes_to_check.push(2,3,4,7);
				 }
			   	 break;
		case 2 : boxes_to_check.push(1);
			   	 if(full_check) {
				 	boxes_to_check.push(3,5,8);
				 }
			   	 break;
		case 3 : boxes_to_check.push(1,2);
			   	 if(full_check) {
				 	boxes_to_check.push(6,9);
				 }
				 break;
		case 4 : boxes_to_check.push(1);
			   	 if(full_check) {
				 	boxes_to_check.push(5,6,7);
				 }
				 break;
		case 5 : boxes_to_check.push(2,4);
			   	 if(full_check) {
				 	boxes_to_check.push(6,8);
				 }
				 break;
		case 6 : boxes_to_check.push(3,4,5);
			   	 if(full_check) {
				 	boxes_to_check.push(9);
				 }
				 break;
		case 7 : boxes_to_check.push(1,4);
			   	 if(full_check) {
				 	boxes_to_check.push(8,9);
				 }
				 break;
		case 8 : boxes_to_check.push(2,5,7);
			   	 if(full_check) {
				 	boxes_to_check.push(9);
				 }
				 break;
		case 9 : boxes_to_check.push(3,6,7,8);break;
	}

	var value="",xy_coods,cell_to_check;
	next_box:
	for(var i=0;i<boxes_to_check.length;i++) {
		xy_coods = getXY(cell);
		var check_box = boxes_to_check[i];
		for(var j=1; j<=3; j++) {

			if(isHorizondal(box,check_box)) {

				if(!full_check) {
					if(box==1 || box==4 || box==7) continue next_box;
					else if(box==5 && check_box==6) continue next_box;
					else if(box==8 && check_box==9) continue next_box;
				}

				cell_to_check = getIndex(j,xy_coods[1]);
				value = cells[(check_box-1)][cell_to_check-1].value;
										
				if(value == number) {
					repeated_at = "c" + check_box + cell_to_check;
					return false; 
				}


			} else {
				if(!full_check) {
					if(box<4) continue;
					else if(box==4 && check_box==7) continue next_box;
					else if(box==5 && check_box==8) continue next_box;
					else if(box==6 && check_box==9) continue next_box;
				}

 				cell_to_check = getIndex(xy_coods[0],j);
 				value = cells[check_box-1][cell_to_check-1].value;
 				
 				if(value == number) {
 					repeated_at = "c" + check_box + cell_to_check;
 					return false; 
 				}
			}
		}
	}
	}

	for(var k=0;k<9;k++) {
		var val = cells[box-1][k].value;
		if(number == val && (k+1 != cell)) { 
			repeated_at = "c"+box+(k+1);
			return false;
		}
	}

	return true;
}


function insert(id,value) {
	var ele = document.getElementById(id);
	ele.style.color="";
	ele.value = value
	if(value)
		ele.disabled = true; 
	else 
		ele.disabled = false; 
}


function clearer() {
	var id = ""
	document.f.reset(); 
	for(var i=0; i<9; i++) {
		for(var j=0; j<9; j++) {
			cells[i][j].disabled = false;
		}
	}

}

function discolorCells(cell1,cell2) {
	document.getElementById(cell1).style.background = "#fff";
	if(cell2) document.getElementById(cell2).style.background = "#fff";
}


function recordPosition() {
	var value=0;
	for(var a=0;a<9;a++) {
		for(var b=0;b<9;b++) {
			value = cells[a][b].value;
			if(!isNaN(value) && value.length==1) {
				xy[a][b] = value;
			} else {
				xy[a][b] = 0;
			}
		}
	}
}

function pos2str(action) {
	var str = "";
	var zero_count = 0;
	var alpha = " abcdefghijklmnopqrstuvwxyz";

	if(action) {
		recordPosition();
	}

	for(var a=0;a<9;a++) {
		for(var b=0;b<9;b++) {
			if(xy[a][b]) {
				if(zero_count) {
					str += alpha.charAt(zero_count); 
					zero_count = 0;
				}
				str += xy[a][b];
			} else {
				zero_count++; 
			}
		}
	}

	return str;
}

function str2pos(str) {
	var zero_flag = 0;
	var alpha = "abcdefghijklmnopqrstuvwxyz";
	var pos = 0;

	var a = 0;
	var b = 0;
	str = str.replace(/\./g,"");

	while(a<9) {
		ch = str.charAt(pos);
		id = "c" + (a+1) + (b+1);

		if(!isNaN(ch) && !zero_flag) {
			insert(id,ch);
		} else if(zero_flag) {
			insert(id,"");
			zero_flag--;
		} else {
			insert(id,"");
			zero_flag = alpha.indexOf(ch);
		}


		if(!zero_flag) {
			pos++;
		}


		b++;
		if(b>=9) {
			b=0;
			a++;
		}
	}
}

function makeCookieString() {
	var str = "";
	var puzzle_cells = new Array(0);

	for(var a=0;a<9;a++) {
		for(var b=0;b<9;b++) {
			value = cells[a][b].value;
			if(cells[a][b].disabled) {
				value = "."+value;
			}
			puzzle_cells.push(value);
		}
	}
	str = puzzle_cells.join(';');

	return str;
}

function checkCell(e) {
	var cell = findTarget(e);
	var val = cell.value;
	if(val<1 || val>9 || isNaN(val)) {
		tagProblemCell(cell,1);
		if(val.length > 1) {
			cell.className += " possibilities-entry";
		}
		return 0;
	} else {
		if(cell.className.indexOf("possibilities-entry")) {
			cell.className = cell.className.replace(/ possibilities\-entry/g,"");
			cell.className = cell.className.replace(/ problem\-cell/g,"");
			cell.style.color = "#000";
		}
		if($("live-hints").checked) {
			var id = cell.id;
			var a =  Number(id.charAt(1)) - 1;
			var b =  Number(id.charAt(2)) - 1;
		
			if(!checkForUnique(a,b,true)) {
				cell.style.background = "#696969";
				$(repeated_at).style.background = "#696969"; 
				setTimeout("discolorCells('"+repeated_at+"','"+id+"')",2000);
				return 0;
			}
		}
	}
	tagProblemCell(cell,0);
	return 1;
}
function makeProblemCell(id) {
	$(id).className += " problem-cell";
}

function tagProblemCell(cell,on) {
	var current_classes = cell.className.toString();
	var have_problem = 0;
	if(current_classes.indexOf("problem-cell") >= 0) have_problem = 1;
	if(on) {
		if(!have_problem) cell.className += " problem-cell";
	} else {
		if(have_problem) cell.className = current_classes.replace(" problem-cell","");
	}
}

function save() {
	var str = makeCookieString();
	setCookie("sudoku_fingerprint",str);
	alert("Hra byla uložena.");
}

function load() {

	clearer();


	var str = getCookie("sudoku_fingerprint");
	if(str == "" || str == null) {
		alert("Žádné hry nebyly uloženy.")
		return false;
	}

	compleated = 0;
	var index = 0;
	var puzzle_cells = str.split(";");
	for(var a=0;a<9;a++) {
		for(var b=0;b<9;b++) {
			number = puzzle_cells[index];
			if(number.charAt(0) == ".") { 
				number = number.charAt(1);
				cells[a][b].disabled = true;
			}

			cells[a][b].value = number;
			index++;
		}
	}
}



function timer() {
	if(!timer_seconds) timer_seconds = 0;
	timer_seconds++;

	var secs = timer_seconds % 60;
	var mins = Math.floor(timer_seconds/60);
	if(secs<10) secs = "0" + secs;
	if(mins<10) mins = "0" + mins;  

	timer_element.innerHTML = mins + ":" + secs;
	timer_clock = window.setTimeout("timer()",1000);
}

function stopTimer() {
	if(timer_clock) clearTimeout(timer_clock);
}

function toggleTimer() {
	if(!timer_paused) { 
		clearTimeout(timer_clock);
		timer_element.style.color = "#f00";
		$("timer_control").value = "Pokračovat";
		timer_paused = 1;
		
		
		var edit_mask = $("pause-hider");
		edit_mask.style.display="block";
		
	
		if(!timer_seconds) timer_seconds = 0;

		var secs = timer_seconds % 60;
		var mins = Math.floor(timer_seconds/60);
		if(secs<10) secs = "0" + secs;
		if(mins<10) mins = "0" + mins;  

		edit_mask.innerHTML = "<br /><strong>Hra zastavena v "+mins+":"+secs+"</strong><br /><br />" +
			"<a onclick='toggleTimer()' style='cursor:hand;'>Klikni pro pokračování.</a>";
		
	} else { 
		$("timer_control").value = "Stop";
		timer_element.style.color = "#000";
		timer_paused = 0;
		timer();
		
	
		var edit_mask = $("pause-hider");
		edit_mask.style.display="none";
	}
}


function checker() {
	var found = 0;
	
	show("Opravuji hru...","#000000");
	loop:
	for(var a=0;a<9;a++) {
		for(var b=0;b<9;b++) {
			var ele = cells[a][b];
			var id = "c" + (a+1) + (b+1);
			var value = ele.value
			if(isNaN(value) || value<1 || value>9) {
				if(value == "") {
					show("Nalezen prázdný čtverec.","#000000");
				} else {
					show("Nalezeno špatné číslo.","#000000");
				}
				found = 1;

				ele.style.background = "#ff0000"; 
				setTimeout("discolorCells('"+id+"')",2000);

				break loop;
			}
			else if(value) {
				if(!checkForUnique(a,b,false)) {
					ele.style.background = "#ff0000"; 
					document.getElementById(repeated_at).style.background = "#ff0000";

					show("Byla nalezená stejná čísla.","#000000");
					setTimeout("discolorCells('"+repeated_at+"','"+id+"')",2000);
					found++;
					break loop;
				}
			} else {
				show("Nalezeny prázné čtverečky. Prosím doplňte.","#000000");
				ele.style.background = "#696969"; 
				setTimeout("discolorCells('"+id+"')",2000);
				found = 1;
				break loop;
			}  
		}
	}

	if(!found) {
		if(compleated)
			alert("Nepodvádějte :-) !");
		else
			alert("Gratulujeme ! Úspěšně jste vyřešili SUDOKU. \nDěkujeme za Vaší přízeň a přejeme příjemný den!");

		stopTimer();
		show("Hotovo","#696969"); 
	}
}


function reloadGame() {
	str2pos(orginal_game); 
}


function solve() {
	show("Hledám výsledky hry...");
	if(confirm("Opravdu chcete automaticky dopnit? \nNechcete to dohrát?\n")) {
		str2pos(this_puzzle);
		compleated = 1;
		show("Sudoku vyřešeno.");
		stopTimer();
	}
}



function checkStatus() {
	var invalid_cells = 0;
	var empty_cells = 0;
	for(var a=0;a<9;a++) {
		for(var b=0;b<9;b++) {
			var ele = cells[a][b];
			var value = ele.value

			if(isNaN(value) || value<1 || value>9) {
				if(value == "") {
					empty_cells ++;
				} else {
					invalid_cells ++;
				}
			}

			else if(value) {
				if(!checkForUnique(a,b,true)) {
					ele.style.background = "#696969"; 
					var id = "c" + (a+1) + (b+1);
					$(repeated_at).style.background = "#696969"; 
					setTimeout("discolorCells('"+repeated_at+"','"+id+"')",2000);
					return;
				}
			} else {
				empty_cells ++;
			}  
		}
	}

	show("You are doing fine so far. You have "+(invalid_cells+empty_cells) + " more cells to fill.","#006600");
	fadeColor("display_area","#ffff00","#ffffff",30,100,"b");
}


var pen_selected_digit = 1;
function putSelectedDigit(e) {
	var cell = findTarget(e);
	cell.value = pen_selected_digit;
	checkCell();
	cell.blur();
}
function monitorKeyboard(e) {
	if (!e) var e = window.event;
	if (e.keyCode) code = e.keyCode;
	else if (e.which) code = e.which;
	var character = String.fromCharCode(code);

	if(!isNaN(character)) {
		var number = Number(character);
		if(number) pickPenDigit(number);
	}
}

function pickPen() {
	for(var i=0;i<9;i++) {
		for(var j=0;j<9;j++) {
			var this_cell = cells[i][j];
			if(this_cell.className.indexOf("pen-picked") == -1) this_cell.className+= "pen-picked";
			addEvent(this_cell,"click",putSelectedDigit); 
		}
	}
	addEvent(document,"keypress",monitorKeyboard);
	$("pen-picks").style.display="inline";
}
 
function downPen() {
	for(var i=0;i<9;i++) {
		for(var j=0;j<9;j++) {
			var this_cell = cells[i][j];
			if(this_cell.className) {
				var classes = this_cell.className.toString();
				this_cell.className = classes.replace(/pen\-picked/g,"");
			}
			removeEvent(this_cell,"click",putSelectedDigit);
		}
	}
	removeEvent(document,"keypress",monitorKeyboard);
	$("pen-picks").style.display="none";
}

function pickPenDigit(number) {
	pen_selected_digit = number;
	$("selected-pen-number").firstChild.nodeValue = number; 
}

function cellClicked(e) {
	selected_cell = findTarget(e);
}

function revealCell() {
	if(!selected_cell) return;
 
	var str = this_puzzle.replace(/\./g,"");
	var c_xy = selected_cell.id.split(""); 
	var box = c_xy[1]-1;
	var cell= c_xy[2]-1;
	var rest = str.substr(box*9);
	var number = rest.charAt(cell); 
	selected_cell.value = number;

	fadeColor(selected_cell.id,"#ffffff","#000000",10,100,"c");
}


function makeNewOrder(str) {

	var alpha = " abcdefghijklmnopqrstuvwxyz";
	var new_order = "";


	numbers = new Array("0");
	for(j=0;j<9;j++) {
		new_numbers = uniqueRand(numbers); 
		numbers.push(new_numbers);
	}


	for(i=0;i<str.length;i++) {
		if(str.charAt(i)=="." || str.charAt(i)=="*" || str.charAt(i)=="x" || 
				str.charAt(i)=="_" || str.charAt(i)=="-" || str.charAt(i)=="+") {
			new_order += "."
		} else {
			new_order += numbers[alpha.indexOf(str.charAt(i))]
		}
	}

	return new_order;
}


function newGame() {
	chosen = Math.floor((Math.random()*10) / (10/puzzles.length));
	this_puzzle = makeNewOrder(puzzles[chosen]);
	show("");
	

	compleated = 0;
	clearer();

	var last_box_ended_at = 0;
	var extra_number_count = 0;
	
	default_number_per_box = $("difficulty").value;
 
	for(var i=0;i<9;i++) {

		var b=0,location_of_fixed_number=0;
		var arr_b = new Array();

	
		var limit = 9;
		var this_box = "";
		var dot_count = 0;
		for(var j=last_box_ended_at; j<last_box_ended_at+limit; j++) {
			if(this_puzzle.charAt(j) == ".") {
				limit++;
				dot_count++;
			}
			this_box = this_box + this_puzzle.charAt(j);
		}
		last_box_ended_at = last_box_ended_at + limit;

	
		number_of_numbers = default_number_per_box - extra_number_count;
		extra_number_count = 0;

		
		if (dot_count > number_of_numbers) {
			if(rand() > 5) {
				extra_number_count = dot_count - number_of_numbers;
			} 
			number_of_numbers = dot_count;
		}

		
		arr_b = new Array();
	
		for(b=0;b<number_of_numbers;b++) {
			location_of_fixed_number = this_box.indexOf(".");

			if(location_of_fixed_number + 1) {

				this_box =  this_box.substring(0,location_of_fixed_number) +
							this_box.substring(location_of_fixed_number+1,this_box.length);
			
			} else { 
				location_of_fixed_number = uniqueRand(arr_b);
				location_of_fixed_number--;
			}

			arr_b.push(location_of_fixed_number+1);

	
			insertion_number = this_box.charAt(location_of_fixed_number);

			location_of_fixed_number++;

			id = "c" + (i+1) + location_of_fixed_number

			insert(id,insertion_number); 
		}
	}
	orginal_game = pos2str(2);


	stopTimer();
	timer_seconds = 0;
	$("timer").innerHTML="00:00";


	timer();
	timer_started = 1;
}

function init() {

	var cell_ref; 
	for(var i=1;i<=9;i++) {
		for(var j=1;j<=9;j++) {
			cell_ref = document.getElementById("c"+i+j);
			addEvent(cell_ref,"change",checkCell);
			addEvent(cell_ref,"click",cellClicked);
			cells[i-1][j-1] = cell_ref;
		}
	}

	var new_style_sheet = getCookie("sudoku_options_stylesheet");
	if($(new_style_sheet)) {
		$(active_stylesheet).disabled=true;
		active_stylesheet = new_style_sheet;
		$(active_stylesheet).disabled=false;
		$("style-selector").value = new_style_sheet;
	}

	var hinting = getCookie("sudoku_options_live_hint");
	if(hinting) {
		$("live-hints").checked = hinting; 
	}
	timer_element = $("timer");

	newGame();
}

function exit() {
	setCookie("sudoku_options_stylesheet",active_stylesheet);
	if($("live-hints").checked) {
		setCookie("sudoku_options_live_hint",true);
	} else {
	  	setCookie("sudoku_options_live_hint",false);
	}
}
window.onload=init;
window.onunload=exit;

