/*<script>*/
/****************************************************************************
Name    : Online Sudoku
Version : 1.03.A Beta
Author  : Binny V A
E-Mail  : binnyva (at) hotmail (dot) com
Website : http://www.geocities.com/binnyva
This code is Copyright (c) 2005 Binny V Abraham
All rights reserved.
License is granted to user to reuse this code on other Web site
if, and only if, this entire copyright notice is included. The Web Site
containing this script must be a not-for-profit(non-commercial) web site 
unless I gave permission for the use of the script.
Exclusive permission must be obtained from me before using this script.
End copyright - This must be retained and posted as is to use this script
along with a link to the original location.
****************************************************************************/
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 xy = new Array(9);
for(i=0;i<9;i++) {
	xy[i] = new Array(9);
}
var puzzles = new Array(
"abc.gdefihdeif.hagcbfgh.cibadebf.iehdcg.ae.acbf.gid.hghdiace.bficgdabhefh.b.f.cg.eaidde.ahfibcg", //14
"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 bites = document.cookie.split(";");
var sudoku_fingerprint = getCookie("sudoku_fingerprint");
if (sudoku_fingerprint == null || sudoku_fingerprint == "") sudoku_fingerprint="";
function getCookie(cookie) {
	for (i=0; i < bites.length; i++) {
		nextbite = bites[i].split("=");
		if (nextbite[0] == cookie)
			return unescape(nextbite[1]);
	}
	return null;
}
var today = new Date();
var expiry = new Date(today.getTime() + 28 * 24 * 60 * 60 * 1000);
function setCookie(name,value) {
	if((value!=null) && (value!="")) document.cookie = name + "=" + escape(value) + "; expires=" + expiry.toGMTString();
	bites = document.cookie.split(";");
}
function getIndex(x,y) {
	var index = (x*3) + y - 3;
	return index;
}
function getXY(index) {
	var x=1,y=1;
	switch (index) { 
		case 1: x=1; y=1; break;
		case 2: x=1; y=2; break;
		case 3: x=1; y=3; break;
		case 4: x=2; y=1; break;
		case 5: x=2; y=2; break;
		case 6: x=2; y=3; break;
		case 7: x=3; y=1; break;
		case 8: x=3; y=2; break;
		case 9: x=3; y=3; break;
	}
	var xy_coods = new Array(x,y);
	return xy_coods;
}
function rand() {
	var number = Math.round(Math.random()*10);
	while (number < 1 || number > 9) { 
		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";
	}
}
//Display the Horizondal Help line
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 checkForUnique(box,cell,number) {
	if(box>1) {
	var boxes_to_check = new Array(); 
	switch (box) {
		case 2 : boxes_to_check.push(1);break;
		case 3 : boxes_to_check.push(1,2);break;
		case 4 : boxes_to_check.push(1);break;
		case 5 : boxes_to_check.push(2,4);break;
		case 6 : boxes_to_check.push(3,4,5);break;
		case 7 : boxes_to_check.push(1,4);break;
		case 8 : boxes_to_check.push(2,5,7);break;
		case 9 : boxes_to_check.push(3,6,7,8);break;
	}

	var id="", value="";
	for(i=0;i<boxes_to_check.length;i++) {
		xy_coods = getXY(cell);
		for(j=1; j<=3; j++) {
			if(box==2 || box==3 || box==5 || box==6 || box==8 || box==9) { 
				if(box==5 && boxes_to_check[i]==2);
				else if(box==6 && boxes_to_check[i]==3);
				else if(box==8 && (boxes_to_check[i]==2 || boxes_to_check[i]==5));
				else if(box==9 && (boxes_to_check[i]==3 || boxes_to_check[i]==6));
				else {
					cell_to_check = getIndex(xy_coods[0],j);
					id = "c" + boxes_to_check[i] + cell_to_check;
					value = document.getElementById(id).value;

					if(value == number) {
						repeated_at = id;
						return false; 
					}
				}
			}
			if(box>=4) {
				if(box==5 && (boxes_to_check[i]==4)); 
				else if(box==6 && (boxes_to_check[i]==4 || boxes_to_check[i]==5));
				else if(box==8 && boxes_to_check[i]==7);
				else if(box==9 && (boxes_to_check[i]==7 || boxes_to_check[i]==8));
				else {
					cell_to_check = getIndex(j,xy_coods[1]);
					id = "c" + boxes_to_check[i] + cell_to_check;
					value = document.getElementById(id).value;

					if(value == number) {
						repeated_at = id;
						return false;
					}
				}
			}
		}
	}
	}
	for(k=1;k<=9;k++) {
		id = "c" + box + k;
		if(number == document.getElementById(id).value && k != cell) { 
			repeated_at = id;
			return false;
		}
	}

	return true;
}
function insert(id,value) {
	document.getElementById(id).value = value
	if(value)
		document.getElementById(id).disabled = true;
	else 
		document.getElementById(id).disabled = false;
}
function clearer() {
	var id = ""
	document.f.reset();
	for(var i=1; i<=9; i++) {
		for(var j=1; j<=9; j++) {
			id = "c"+i+j;
			document.getElementById(id).disabled = false;
		}
	}
}
function discolorCells(cell1,cell2) {
	document.getElementById(cell1).style.background = "#fff";
	document.getElementById(cell2).style.background = "#fff";
}
function recordPosition() {
	var value=0;
	for(a=0;a<9;a++) {
		for(b=0;b<9;b++) {
			value = document.getElementById("c"+(a+1)+(b+1)).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(a=0;a<9;a++) {
		for(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(a=0;a<9;a++) {
		for(b=0;b<9;b++) {
			value = document.getElementById("c"+(a+1)+(b+1)).value;
			if(document.getElementById("c"+(a+1)+(b+1)).disabled) {
				value = "."+value;
			}
			puzzle_cells.push(value);
		}
	}
	str = puzzle_cells.join(';');
	alert(str);

	return str;
}
function save() {
	var str = makeCookieString();
	setCookie("sudoku_fingerprint",str);
	alert("Game saved.");
}
function load() {
	clearer();
	var str = getCookie("sudoku_fingerprint");
	if(str == "" || str == null) {
		alert("No saved games found!")
		return false;
	}
	var index = 0;
	var puzzle_cells = str.split(";");
	for(a=0;a<9;a++) {
		for(b=0;b<9;b++) {
			id = "c"+(a+1)+(b+1);
			number = puzzle_cells[index];
			if(number.charAt(0) == ".") {
				number = number.charAt(1);
				document.getElementById(id).disabled = true;
			}
			if(number) {
			}
			document.getElementById(id).value = number;
			index++;
		}
	}
}
function checker() {
	var found = 0;

	show("Checking game...","#a84efa");
	loop:
	for(a=1;a<=9;a++) {
		for(b=1;b<=9;b++) {
			id = "c"+a+b;
			if(document.getElementById(id).value) {
				if(!checkForUnique(a,b,document.getElementById(id).value)) {
					document.getElementById(id).style.background = "red"; 
					document.getElementById(repeated_at).style.background = "red";

					setTimeout("discolorCells(repeated_at,id)",2000);
					found++;
					break loop;
				}
			} else {
				show("Hay casillas vacías. Por favor completa el the puzzle.","#f89768");
				found = 1;
				break;
			}  
		}
	}
	if(!found) {
		if(compleated)
			alert("Lo siento - no puedes ganar después de rendirte.");
		else
			alert("¿Felicidades! - Has completado el puzzle.");
		show("Fin del juego","#000000"); 
	}
}

var donestr = ""; 
var origstr = "";
var correctstr = "";
var c_num = 0;
var m_num = 0;
var b_num = 0;
function helpcheck() {
  var numundone = 0;
	var numdone = 0;
	var mistakes = 0;
  donestr = "";
	loop:
	for(a=1;a<=9;a++) {
		for(b=1;b<=9;b++) {
			id = "c"+a+b;
			if(document.getElementById(id).value) {
			donestr = (donestr + document.getElementById(id).value)
			}
			else {donestr = (donestr + "0")}
    }
  } 
	for(a=0;a<=81;a++) {
	if (donestr.charAt(a) == 0){
	   numundone++;
	}
	else {
	   if (donestr.charAt(a) == correctstr.charAt(a)){numdone++;}
		 else {mistakes++;}
		}
	}
	if (mistakes>0) {;}
	else {
	   numundone--;
	   if (numundone>0) {;}
     else {alert( "Felicidades, has resuelto el puzzle!")}
	}
document.formr.c_num.value = numdone;;
document.formr.m_num.value = mistakes;
document.formr.b_num.value = (81-numdone);
}

function origkeep() {
  var strlen = this_puzzle.length;
	var strptr = 0;
  correctstr = "";
  origstr = "";
	loop:
	for(a=1;a<=9;a++) {
		for(b=1;b<=9;b++) {
			id = "c"+a+b;
			if(document.getElementById(id).value) {
			origstr = (origstr + document.getElementById(id).value)
			}
			else {origstr = (origstr + "0")}
    }
  }  
}

function correctkeep() {
  var strlen = this_puzzle.length;
	var strptr = 0;
//  correctstr = "";
  correctstr = "";

	for(a=0;a<=strlen;a++) {
	  if (this_puzzle.charAt(a) != ".") {
		  correctstr=(correctstr + this_puzzle.charAt(a));
      strptr++;
		}
	}
}
function reloadGame() {
	str2pos(orginal_game);
}
function solve() {
	show("Buscando la solución del juego...");
	if(confirm("Esto resolverá el puzzle automáticamente.\n¿Estás seguro?\n")) {
		str2pos(this_puzzle);
		compleated = 1;
		show("Puzle resuelto.");
	}
}
	var new_order = "";
function makeNewOrder(str) {
	new_order = "";
	var alpha = " abcdefghijklmnopqrstuvwxyz";
	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 init() {
	chosen = Math.floor((Math.random()*10) / (10/puzzles.length)); //'chosen' puzzle should be random
	this_puzzle = makeNewOrder(puzzles[chosen]);
	compleated = 0;
	clearer();
	var last_box_ended_at = 0;
	var extra_number_count = 0;
	for(var i=0;i<9;i++) { //Change 1 to 9 :DEBUG:
		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);
			
		}
	}
	origkeep();
	correctkeep();
	orginal_game = pos2str(2);
	helpcheck();
}
