var oCurrentPlayingSquare;

function ChangeBoard(iNewHeight)
{
var oCtl;
var iX;
var iY;
var iSize;
var OuterSize;

oCtl = document.getElementById('sudokutable');

if (iNewHeight==0)
	{

switch (oCtl.height) {
	case '405' :
	case '405px' :
	iSize = 36
	OuterSize='324px';
	break;

	case '324' :
	case '324px' :
	iSize = 56
	OuterSize='504px';
	break;

	case '504' :
	case '504px' :
	iSize = 45
	OuterSize='405px';
	break;
	
	default :
	iSize = 56
	OuterSize='504px';
	break;
}
	}
	else
	{
	OuterSize=iNewHeight;
	}

switch (OuterSize) {
	case '324px' :
	case '324' :
	iSize = 36;
	break;

	case '504px' :
	case '504' :
	iSize = 56;
	break;

	case '405px' :
	case '405' :
	iSize = 45;
	break;
}

	oCtl.height=OuterSize;
	oCtl.style.height=OuterSize;
	document.getElementById('sudokutableBox').style.width=OuterSize;
	document.getElementById('sudokutableBox').style.height=OuterSize;
	document.getElementById('Numbertable').style.width=OuterSize;
	document.getElementById('Numbertable').style.height=iSize;

SetCellSize(oCtl,iSize);
SetCellSize(document.getElementById('Numbertable'),iSize-2);
}

function SetCellSize(oCtl,iSize)
{
var iX;
var iY;

for (iX=0;iX<=oCtl.rows[0].cells.length-1;iX++)
	{
	for (iY=0;iY<=oCtl.rows.length-1;iY++)
		{
		if (oCtl.rows[iY].cells[iX].childNodes[0].alt)
			{
			oCtl.rows[iY].cells[iX].childNodes[0].style.height=(iSize-10) + 'px';
			oCtl.rows[iY].cells[iX].childNodes[0].style.width=(iSize-10) + 'px';
			}
		oCtl.rows[iY].cells[iX].height=iSize + 'px';
		oCtl.rows[iY].cells[iX].style.height=iSize + 'px';
		}
	}
}


function PicNumGet(oCtl)
{
if (oCtl.innerHTML.toUpperCase()=='&NBSP;')
	return 0;
if (oCtl.style.fontSize !='')
	return oCtl.innerHTML;
	else
	{
	return parseInt(oCtl.childNodes[0].alt);
	}
}

function PicNumPlace(oCtl,iNum)
{
oCtl.innerHTML ='<img style="width:' + (oCtl.height-10) + ';height:' + (oCtl.height-10) + '" alt="' + iNum + '" border=0 src="'+ sNumPics[iNum] + '" >';
}

function PermSquare(oCtl)
{
if (oCtl.bgColor == sGridBGColor)
	return true;
	else
	return false;
}

function KeyGet(e)
{
var keycode;
if (e) keycode=e.which;
     else keycode=window.event.keyCode;
   return String.fromCharCode(keycode);
}

function XBrowserAddHandler(target,eventName,handlerName) { 
  if ( target.addEventListener ) { 
    target.addEventListener(eventName, function(e){target[handlerName](e);}, false);
  } else if ( target.attachEvent ) { 
    target.attachEvent("on" + eventName, function(e){target[handlerName](e);});
  } else { 
    var originalHandler = target["on" + eventName]; 
    if ( originalHandler ) { 
      target["on" + eventName] = function(e){originalHandler(e);target[handlerName](e);}; 
    } else { 
      target["on" + eventName] = target[handlerName]; 
    } 
  } 
}

function trimString (str) {
  while (str.charAt(0) == ' ')
    str = str.substring(1);
  while (str.substring(0,6) == '&nbsp;')
    str = str.substring(6);
  while (str.charAt(str.length - 1) == ' ')
    str = str.substring(0, str.length - 1);
  return str;
}

function IsKeyOK(sChar)
{
var sOKChars='1234567890';
if (sOKChars.indexOf(sChar)==-1)
	return false;
	else return true;
}

function CurNumSelect(e) 
{
var iNewNum;
if (PermSquare(this) ==false)
	{
	iNewNum= PicNumGet(this);
	MoveNum(iNewNum);
	}
}

function MoveNum(iNewNum)
{
if (iNewNum==iCurNum)
	return true;

var oNumCtl;
oNumCtl = document.getElementById('Num' + iCurNum);
oNumCtl.bgColor='';

if (iCurNum==0)
	{ oNumCtl.innerHTML = '&nbsp;'; }
	else 
	{ oNumCtl.bgColor = ''; }

oNumCtl = document.getElementById('Num' + iNewNum);
if (oNumCtl.innerHTML.toUpperCase()!='&NBSP;')
	{ 
	oNumCtl.bgColor = sBGColor;
	}
iCurNum = iNewNum;
}

function ShowFullSolution()
{
var iC;

if ( document.getElementById('btnFullSol').value=='Show Solution')
	{
	document.getElementById('btnFullSol').value='Hide Solution';
	for (iC=0;iC<iGridSolved.length;iC++)
		{
 		oControl=document.getElementById('T' + iC);
		oControl.bgColor='';
		if (PicNumGet(oControl)==0)
			{ iPlayerMoves[iC]=0; }
			else
			{ 
			if (oControl.style.fontSize=='')
				{ iPlayerMoves[iC]='N'; }
				else { iPlayerMoves[iC]='P' }

			iPlayerMoves[iC]=iPlayerMoves[iC]  + oControl.innerHTML;
			}
 
		if (iGridUnsolved[iC]==0)
			{ PicNumPlace(oControl,iGridSolved[iC])}
			else 
			{ oControl.bgColor = sGridBGColor; }

		TDSettings(oControl,false);
		}
	}
	else
	{
	document.getElementById('btnFullSol').value='Show Solution';
	for (iC=0;iC<iGridSolved.length;iC++)
		{
 		oControl=document.getElementById('T' + iC);
		oControl.bgColor='';
		if (iPlayerMoves[iC]==0)
			{ oControl.innerHTML ='&nbsp;' ; }
			else 
			{ if (iGridUnsolved[iC]==0)
				{ 
				if (iPlayerMoves[iC].substring(0,1)=='P' )
					{
					TDSettings(oControl,true);
					}		
					oControl.innerHTML =iPlayerMoves[iC].substring(1);
				}
				else { oControl.bgColor = sGridBGColor; }
			}
		}
	}
}

function TDSettings(oCtl,bPossibilityOn)
{
if (bPossibilityOn==true)
	{
	oCtl.style.fontSize='10px';
	oCtl.style.textAlign='right';
	oCtl.vAlign='top';
	}
	else
	{
	oCtl.style.fontSize='';
	oCtl.style.textAlign='center';
	oCtl.vAlign='center';
	}
}

function ResetBoard()
{
var iC;
var oControl;
for (iC=0;iC<iGridUnsolved.length;iC++)
	{
 	oControl=document.getElementById('T' + iC);
	TDSettings(oControl,false);
	if (iGridUnsolved[iC]!=0)
		{ PicNumPlace(oControl,iGridUnsolved[iC]);
		  oControl.bgColor = sGridBGColor; }
		else
		{ oControl.innerHTML ='&nbsp;';
		  oControl.bgColor=''; }
	}
}

function ResetPoss()
{
var iC;
var oControl;
for (iC=0;iC<iGridUnsolved.length;iC++)
	{
 	oControl=document.getElementById('T' + iC);
	if (oControl.style.fontSize!='')
		{
		TDSettings(oControl,false);
		oControl.innerHTML ='&nbsp;';
		}
	}
}


function CheckSolution(bOnlyCheckFinished)
{
var iStatus;

iStatus = CheckSolutionBoard(bOnlyCheckFinished,false);

switch (iStatus) {
	case 0 :
		if (bOnlyCheckFinished==true)
			{ 		
			sCongratsMsg = 'Correct - Congratulations!';
			ShowPrize();
			}
		break;
	case 1 :
		if (bOnlyCheckFinished==false)
			{ alert('All moves so far are correct.'); }
		break;
	default :
		if (bOnlyCheckFinished==false)
			{ 
			if (confirm('Some numbers were incorrect.\n\nWould you like to see which ones?'))
				{
				CheckSolutionBoard(bOnlyCheckFinished,true);
				}
			 } 
		}
	

}

function CheckSolutionBoard(bOnlyCheckFinished,bShowIncorrect)
{
var iC;
var sValue;
var oControl;
var iStatus;
var iIndex;

iStatus = 0;

for (iC=0;iC<iGridSolved.length;iC++)
	{
 	oControl=document.getElementById('T' + iC);
	sValue =PicNumGet(oControl);
	if (PermSquare(oControl) ==false && (sValue!=iGridSolved[iC] || oControl.style.fontSize!='') )
		{
		if (sValue == 0 || oControl.style.fontSize!='')
			{ if (iStatus==0) { iStatus=1;} }
			
		else 	{
			if (bOnlyCheckFinished==false && bShowIncorrect==true)
				{ oControl.bgColor='ff7f7f'; }

			FlashSquareCheck(oControl,-1);
			
			iStatus=2;
			}
		}
	}

return iStatus;
}

function FlashSquareCheck(oControl,iCurNum)
{
var sID;
var sOldChars;

	if (iCurNum!=-1)
		{
		sOldChars =SaveGameSquare(oControl, oControl.innerHTML);
		PicNumPlace(oControl,iCurNum);
		TDSettings(oControl,false);
		} else
		{
		sOldChars = '&nbsp;';
		}

	if (iCurNum!=iGridSolved[parseInt(oControl.id.replace('T',''))] && document.getElementById('AllowIncorrectMoves').checked==false)
		{
		sID =oControl.id;
		sID = sID.replace('T','')
		iIndex = parseInt(sID);
		if (IntervalTimes[iIndex][2]<=0) 
			{
			IntervalTimes[iIndex][3]=sOldChars;
			IntervalTimes[iIndex][2]=6;
			IntervalTimes[iIndex][1] = setInterval("FlashSquare(" + iIndex + ")", 300);
			}
		return true;
		} else
		{ return false; }
}

function FlashSquare(iIndex)
{
var oControl;

 	oControl=document.getElementById('T' + iIndex);
	
	if (IntervalTimes[iIndex][2] % 2 == 0 )
		{ oControl.bgColor='ff7f7f'; }
		else
		{ oControl.bgColor='ffffff'; }
	

	IntervalTimes[iIndex][2]--;


	if (IntervalTimes[iIndex][2]<=0)
		{ 
		oControl.innerHTML ='&nbsp;';
		clearInterval(IntervalTimes[iIndex][1]);
		LoadGameSquare(oControl,IntervalTimes[iIndex][3])
		}

}

function KeyboardPlaceNumber(e)
{
var iNewNum;
var sChar;

sChar=KeyGet(e);
if (IsKeyOK(sChar)==false)
	return true;

iNewNum=parseInt(sChar);
MoveNum(iNewNum)

if (oCurrentPlayingSquare!=undefined)
	PlaceNumber(oCurrentPlayingSquare);
}


function MousePlaceNumber(e)
{
if (PermSquare(this)==true)
	{
	alert ("This is already allocated.");
	return true;
	}

if (typeof(oCurrentPlayingSquare)!='undefined')
	oCurrentPlayingSquare.bgColor='';

oCurrentPlayingSquare = this;

if (document.getElementById("HighlightCurrSquare").checked==true)
	oCurrentPlayingSquare.bgColor='#e7ffd5';

if (document.getElementById("PlaceMovesWithMouse").checked==true)
	PlaceNumber(oCurrentPlayingSquare);
}

function PlaceNumber(oCtl) 
{ 
var sSorted;

	SaveUndo();
	this.bgColor='';
	if (iCurNum==0)
		{
		oCtl.innerHTML='&nbsp;';
		oCtl.style.fontSize='';
		}
		else
		{
		if ((PicNumGet(oCtl)+'').indexOf(iCurNum)!=-1)
			{
			if (!document.getElementById('PossibilityMode').checked && oCtl.style.fontSize!='')
				{
				if (FlashSquareCheck(oCtl,iCurNum) == false)
					{
					RemovePossibieNumbers(oCtl);
					} 
					CheckSolution(true);
				}
				else
				{
				if (oCtl.style.fontSize!='')
					{
					oCtl.innerHTML=oCtl.innerHTML.replace(iCurNum,'');
					oCtl.innerHTML=trimString(oCtl.innerHTML);
					if (oCtl.innerHTML=='')
						{
						TDSettings(oCtl,false);
						oCtl.innerHTML='&nbsp;';
						}
					} else
					oCtl.innerHTML='&nbsp;';
				}
			}
		else
			{
			if (document.getElementById('PossibilityMode').checked)
				{
				TDSettings(oCtl,true);
				sSorted = oCtl.innerHTML + ' ' + iCurNum;
				sSorted = SortPoss(sSorted);
				sSorted = trimString(sSorted);
				oCtl.innerHTML=sSorted;
				}
				else
				{
				if (FlashSquareCheck(oCtl,iCurNum) == false)
					{
					RemovePossibieNumbers(oCtl);
					} 
					CheckSolution(true);
				}
			}
		}
} 

function SortPoss(sOrigPoss)
{
var Poss= new Array(9);
var iC;
var iX;
var sRet;
iX=0;
sRet='';

for (iC=0;iC<sOrigPoss.length;iC++)
	{
	if (sOrigPoss.substring(iC,iC+1)==parseInt(sOrigPoss.substring(iC,iC+1)))
		{
		Poss[iX] = sOrigPoss.substring(iC,iC+1);
		iX = iX +1;
		}
	}
Poss.sort();
for (iC=0;iC<iX;iC++)
	{
	sRet = sRet + Poss[iC] + ' ';
	}
return sRet;
}

function RemovePossibieNumbers(oSquare)
{
var iCurrSize;


if (document.getElementById("RemovePossibilties").checked == false)
	return;

var iID;
var iIDLeft;
var iIDTop;
var iChosenNum;
var iNewID;
var iXStart;
var iYStart;
var iX;
var iY;

iCurrSize = document.getElementById('sudokutable').rows.length;

iChosenNum = oSquare.innerHTML;

iID = parseInt( oSquare.id.substring(1));
iIDLeft = Math.floor(iID/iCurrSize) * iCurrSize;

for (iNewID=iIDLeft; iNewID <=(iIDLeft+(iCurrSize-1));iNewID++)
	RemoveNumber(iNewID, iChosenNum);

iIDTop = iID % iCurrSize;

for (iNewID=iIDTop; iNewID <=(iCurrSize*iCurrSize-1);iNewID=iNewID+iCurrSize)
	RemoveNumber(iNewID, iChosenNum);

switch (iCurrSize) {
	case 9 :
		iYStart = Math.floor(iIDLeft/9/3) * 3;
		iXStart = Math.floor(iIDTop/3) * 3;

		for (iY=iYStart; iY <=iYStart+2;iY++)
			{
			for (iX=iXStart; iX <=iXStart+2;iX++)
				{
				iNewID = iY * 9 + iX;
				RemoveNumber(iNewID, iChosenNum);
				}
			}
		break;
	case 6 :
		iYStart = Math.floor(iIDLeft/6/3) * 3;
		iXStart = Math.floor(iIDTop/2) * 2;

		for (iY=iYStart; iY <=iYStart+2;iY++)
			{
			for (iX=iXStart; iX <=iXStart+1;iX++)
				{
				iNewID = iY * 6 + iX;
				RemoveNumber(iNewID, iChosenNum);
				}
			}
		break;
	case 4 :
		iYStart = Math.floor(iIDLeft/4/2) * 2;
		iXStart = Math.floor(iIDTop/2) * 2;

		for (iY=iYStart; iY <=iYStart+1;iY++)
			{
			for (iX=iXStart; iX <=iXStart+1;iX++)
				{
				iNewID = iY * 4 + iX;
				RemoveNumber(iNewID, iChosenNum);
				}
			}
		break;
	
	}


}

function RemoveNumber(iNewID, iChosenNum)
{
var oNewSquare;
oNewSquare = document.getElementById("T" + iNewID)

if (oNewSquare.style.fontSize!='')
	{
	oNewSquare.innerHTML=oNewSquare.innerHTML.replace(iChosenNum,'');
	oNewSquare.innerHTML=trimString(oNewSquare.innerHTML);
	if (oNewSquare.innerHTML=='')
		{
		oNewSquare.innerHTML='&nbsp;';
		TDSettings(oNewSquare,false);
		}
	}

}

function PlayInit()
{

document.onkeypress = KeyboardPlaceNumber;
if (document.layers)
document.captureEvents(Event.KEYPRESS); 

document.getElementById('Num1').bgColor=sBGColor;

var iC;
var oControl;

for (iC=0;iC<=document.getElementById('sudokutable').rows.length;iC++)
	{
 	oControl=document.getElementById('Num' + iC);
    	oControl.ClickHandler =  CurNumSelect; 
    	XBrowserAddHandler(oControl,"click","ClickHandler");
	if (iC>0)
		PicNumPlace(oControl,iC);
	}

for (iC=0;iC<iGridUnsolved.length;iC++)
	{
 	oControl=document.getElementById('T' + iC);
	if (iGridUnsolved[iC]!=0)
		{ PicNumPlace(oControl,iGridUnsolved[iC]);
			oControl.bgColor = sGridBGColor; }

    	oControl.ClickHandler = MousePlaceNumber; 
    	XBrowserAddHandler(oControl,"click","ClickHandler");
	}


}

function getCookieVal (offset) {
var endstr = document.cookie.indexOf (";", offset);
if (endstr == -1)
endstr = document.cookie.length;
return unescape(document.cookie.substring(offset, endstr));
}

function GetCookie (name,DefaultVal) {
var arg = name + "=";
var alen = arg.length;
var clen = document.cookie.length;
var i = 0;
while (i < clen) {
var j = i + alen;
if (document.cookie.substring(i, j) == arg)
return getCookieVal (j);
i = document.cookie.indexOf(" ", i) + 1;
if (i == 0) break; 
}
return DefaultVal;
}  

function SetCookie (name, value) {
var argv = SetCookie.arguments;
var argc = SetCookie.arguments.length;
var expires = (argc > 2) ? argv[2] : null;
var path = (argc > 3) ? argv[3] : null;
var domain = (argc > 4) ? argv[4] : null;
var secure = (argc > 5) ? argv[5] : false;
document.cookie = name + "=" + escape (value) +
((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
((path == null) ? "" : ("; path=" + path)) +
((domain == null) ? "" : ("; domain=" + domain)) +
((secure == true) ? "; secure" : "");
}

function SetDefaults()
{
var expdate = new Date ();
expdate.setTime (expdate.getTime() + (24 * 60 * 60 * 1000 * 31));

	SetCookie("ckRemovePossibilties",document.getElementById("RemovePossibilties").checked,expdate);
	SetCookie("ckAllowIncorrectMoves",document.getElementById("AllowIncorrectMoves").checked,expdate);
	SetCookie("ckPlaceMovesWithMouse",document.getElementById("PlaceMovesWithMouse").checked,expdate);
	SetCookie("ckHighlightCurrSquare",document.getElementById("HighlightCurrSquare").checked,expdate);
	SetCookie("sudokutableHeight",document.getElementById('sudokutable').height,expdate);

}

function ReadDefaults()
{
	document.getElementById("RemovePossibilties").checked= (GetCookie("ckRemovePossibilties","false")=="true") ;
	document.getElementById("AllowIncorrectMoves").checked=(GetCookie("ckAllowIncorrectMoves","true")=="true");
	document.getElementById("PlaceMovesWithMouse").checked=(GetCookie("ckPlaceMovesWithMouse","true")=="true");
	document.getElementById("HighlightCurrSquare").checked=(GetCookie("ckHighlightCurrSquare","true")=="true");
	ChangeBoard(GetCookie("sudokutableHeight",0));

}

function SaveGame()
{
var SBoard;

SBoard = sGetBoardString();

var expdate = new Date ();
expdate.setTime (expdate.getTime() + (24 * 60 * 60 * 1000 * 31));

	SetCookie(sDiffSetting + sSourceName + "_SavedBoard",SBoard,expdate);
	alert("The current Game has been saved.");

}

function sGetBoardString()
{
var iC;
var sValue;
var oControl;
var sBoard;

sBoard = '';

for (iC=0;iC<iGridSolved.length;iC++)
	{
 	oControl=document.getElementById('T' + iC);
	sValue = oControl.innerHTML.toUpperCase();
	if (sValue == '' || sValue == '&NBSP;')
		{}
		else
		{
		sBoard = sBoard + SaveGameSquare(oControl,sValue);
		}
	sBoard = sBoard + "|";
	}
return sBoard;
}

function SaveGameSquare(oControl,sValue)
{
	sValue = sValue.replace('<B>','');
	sValue = sValue.replace('</B>','');

	if (oControl.style.fontSize!='')
		{return 'P' + sValue;}
		else
		{return sValue;}

}

function LoadGame()
{
var sBoard;

sBoard =  GetCookie( sDiffSetting + sSourceName + "_SavedBoard","NoSave");

if (sBoard=="NoSave") 
	{
	alert("There is no saved game for this puzzle (clearing cookies will erase saved games).");
	return true;
	}

LoadBoardFromString(sBoard);

}

function LoadBoardFromString(sBoard)
{
var iC;
var sValue;
var oControl;

ResetBoard();

for (iC=0;iC<iGridSolved.length;iC++)
	{
 	oControl=document.getElementById('T' + iC);
	sValue = sBoard.split('|')[iC];
	if (sValue !='')
		{
		LoadGameSquare(oControl,sValue);
		}
	}
}

function LoadGameSquare(oControl,sValue)
{
	if (oControl.bgColor=='')
		{
		if (sValue.substring(0,1)=="P")
			{
			TDSettings(oControl,true);
			sValue = sValue.substring(1);
			}
		oControl.innerHTML = sValue;
		}
}

var curOpac;
var IE = document.all;
var oPrizeInverval;
var sCongratsMsg;

function ShowPrize()
{
var iNewSize;
iNewSize = document.getElementById('sudokutable').height;

document.getElementById('hideDiv').style.MozOpacity = '0.0';
document.getElementById('hideDiv').style.height = iNewSize;
document.getElementById('hideDiv').style.width= iNewSize;
document.getElementById('hideDiv').style.position = 'relative';
document.getElementById('hideDiv').style.top = -iNewSize;
document.getElementById('hideDiv').style.display = '';
document.getElementById('Grabber').style.position = 'relative';
document.getElementById('Grabber').style.top =-iNewSize;
document.getElementById('sudokutable').style.MozOpacity = '1.0';
document.getElementById('PrizePic').style.height = iNewSize;
document.getElementById('PrizePic').style.width = iNewSize;

curOpac = 0;
oPrizeInverval = setInterval("ShowPrizeGrad()",10)
}

function ShowPrizeGrad()
{
document.getElementById('PrizePic').style.display = '';

curOpac++;

if (curOpac>90)
	{
	clearInterval(oPrizeInverval);
	document.getElementById('hideDiv').style.MozOpacity = '1.0';
	document.getElementById('sudokutable').style.MozOpacity = '0.0';
	alert(sCongratsMsg);
	var replacemewithhearts;
	return true;
	}
	
IE?document.getElementById("hideDiv").style.filter="alpha(opacity="+curOpac+")":document.getElementById("hideDiv").style.MozOpacity=curOpac/90.1;

IE?document.getElementById("sudokutable").style.filter="alpha(opacity="+(90-curOpac)+")":document.getElementById("sudokutable").style.MozOpacity=(90-curOpac)/90.1;

}

function ShareGame()
{
var sBoard;
sBoard = sGetBoardString();
document.getElementById("ShareStuff").style.display='inline';
document.getElementById("txtShareStuffCode").value=sBoard;
}

function LoadSharedGame()
{
var sBoard;
sBoard = document.getElementById("txtShareStuffCode").value;
LoadBoardFromString(sBoard);
document.getElementById("ShareStuff").style.display='none';
}

function SaveUndo()
{
Undos[UndosCurr]=sGetBoardString();
if (UndosCurr==Undos.length)
	alert('The limit of the Undos has been reached, no more can be saved.');
else
	UndosCurr=UndosCurr+1;
}

function LoadUndo()
{
if (UndosCurr==1)
	alert('No moves have been made');
else
	{
	UndosCurr=UndosCurr-1;
	LoadBoardFromString(Undos[UndosCurr]);
	}
}

