function congratulate() {
	printMsg("CONGRATULATIONS!");
}

function valAns(pzl) {
	var validated = true;
	for (var i=0; i < solAy[pzl].length && validated; i++) {
		if (solAy[pzl][i] != 
			document.forms[pzl].elements[i].value) {
			validated = false;
		}
	}
	return validated;
}

function valTopDone() {
	if (solvedCnt < (clueCnt - 1) ) {
		document.forms[getNextPzl(-1)].elements[0].focus();
		return false;
	}
	return true;
}

function valLet(pzl,sol,key) {
	
	if (pzl == (clueCnt - 1)) {
		if (!valTopDone()) {
			return;
		}
	}
	var solLetter = (String.fromCharCode(key)).toUpperCase();
	var nxBlank = sol;
	var nxPzl = pzl;
	if (key == 37) { //left arrow
		nxBlank = getLastId(pzl,sol);
	} else if (key == 39 || key == 9) {  //right arrow or tab
		nxBlank = getNextId(pzl,sol);
	} else if (key == 38) { //up arrow
		nxBlank = 0;
		nxPzl = getLastPzl(pzl);
	} else if (key == 40) { //down arrow
		nxBlank = 0;
		nxPzl = getNextPzl(pzl);
	} else if (solvedAy[pzl]) {
		document.forms[pzl].elements[sol].value =
			solAy[pzl][sol];
		return;
	} else if (filledAy[pzl][sol] != '') {  // there was a char
		if (filledAy[pzl][sol] == solLetter) { //no change
			document.forms[pzl].elements[sol].value = 
				solLetter;
			nxBlank = getNextId(pzl,sol);
		} else { //change in character
			if (ltrIsInClues(pzl,solLetter)) { //use clue
				putBackInClue(pzl,
					filledAy[pzl][sol]);
				document.forms[pzl].elements[sol].value = 
					solLetter;
				filledAy[pzl][sol] = solLetter;
				if (usedCntAy[pzl] >= 
					solAy[pzl].length &&
		    			valAns(pzl)) { //pzl done
					solvedAy[pzl] = true;
					solvedCnt++;
					reveal(pzl);
					nxPzl = getNextPzl(pzl);
					nxBlank=0;
				} else {
					nxBlank = getNextId(pzl,sol);
				}
			} else if (ltrIsInAnswers(pzl,
					sol,solLetter)) { // swap
				document.forms[pzl].elements[sol].value = 
					solLetter;
				if (usedCntAy[pzl] >= 
					solAy[pzl].length &&
		    			valAns(pzl)) { //pzl done
					solvedAy[pzl] = true;
					solvedCnt++;
					reveal(pzl);
					nxPzl = getNextPzl(pzl);
					nxBlank=0;
				} else {
					nxBlank = getNextId(pzl,sol);
				}
			} else {  //invalid ltr
				document.forms[pzl].elements[sol].value =
					'';
			}
		}
	} else { // space was blank
		if (ltrIsInClues(pzl,solLetter)) { //use clue
			document.forms[pzl].elements[sol].value = 
					solLetter;
			filledAy[pzl][sol] = solLetter;
			if (usedCntAy[pzl] >= 
			      solAy[pzl].length &&
		    	      valAns(pzl)) { //pzl done
				solvedAy[pzl] = true;
				solvedCnt++;
				reveal(pzl);
				nxPzl = getNextPzl(pzl);
				nxBlank=0;
			} else {
				nxBlank = getNextId(pzl,sol);
			}
		} else if (ltrIsInAnswers(pzl,
					sol,solLetter)) { // swap
			document.forms[pzl].elements[sol].value = 
				solLetter;
			if (usedCntAy[pzl] >= 
			      solAy[pzl].length &&
		    	      valAns(pzl)) { //pzl done
				solvedAy[pzl] = true;
				solvedCnt++;
				reveal(pzl);
				nxPzl = getNextPzl(pzl);
				nxBlank=0;
			} else {
				nxBlank = getNextId(pzl,sol);
			}
		} else {  //invalid ltr
			document.forms[pzl].elements[sol].value = '';
		}
	}

	if (solvedCnt == clueCnt) {
		congratulate();
	} else {
		document.forms[nxPzl].elements[nxBlank].focus();
	}
}

function printMsg(str) {
	document.forms[clueCnt].elements[0].value = str;
}

function getNextId(pzl,sol) {
	var nxa = sol + 1;
	if (solAy[pzl].length <= nxa) {
		nxa=0;
	}
	return nxa;
}

function getLastId(pzl,sol) {
	var pva = sol - 1;
	if (pva < 0) {
		pva = solAy[pzl].length - 1;
	}
	return pva;
}

function getNextPzl(pzl) {
	var gotNext = false;
	var nxPzl = -1;
	for (var i=pzl+1; !gotNext; i++) {	
		if (i==pzl) {
			gotNext = true;
		} else if (i >= clueCnt) {
			i = -1;
		} else if (!solvedAy[i]) {
			nxPzl = i;
			gotNext = true;
		} 
	}
	if (nxPzl == -1) {
		return pzl;
	}
	return nxPzl;
}

function getLastPzl(pzl) {
	var nxPzl = -1;
	for (var i=pzl-1; !gotNext; i--) {
		if (i==pzl) {
			gotNext = true;
		} else if (i < 0) {
			i = clueCnt;
		} else if (!solvedAy[i]) {
			nxPzl = i;
			gotNext = true;
		} 
	}
	if (nxPzl == -1) {
		return pzl;
	}
	return nxPzl;
}

function putBackInClue(puz,let) {
	retBool = false;
	for (var i=0; i < clueAy[puz].length && !retBool; i++) {
		if (clueAy[puz][i] == let &&
			usedAy[puz][i] == true) {
			usedAy[puz][i] = false;
			usedCntAy[puz]--;
			retBool = true;
			fadein(puz,i);
		}
	}
}

function ltrIsInClues(puz,let) {
	retBool = false;
	for (var i=0; i < clueAy[puz].length && (!retBool); i++) {
		if (clueAy[puz][i] == let && (! usedAy[puz][i])) {
			retBool = true;
			usedAy[puz][i] = true;
			usedCntAy[puz]++;
			fadeout(puz,i);
		}
	}
	return retBool;
}

function ltrIsInAnswers(puz,ans,let) {
	retBool = false;
	for (var i=0; i < filledAy[puz].length && !retBool; i++) {
		if (i != ans) {
			if (filledAy[puz][i] == let) {
				if (filledAy[puz][ans] != '') {
					putBackInClue(puz,
						filledAy[puz][ans]);
				}
				filledAy[puz][ans] = let;
				document.forms[puz].elements[ans].value = let;
				filledAy[puz][i] = '';
				document.forms[puz].elements[i].value = '';
				retBool = true;
			}
		}
	}
	return retBool;
}

function fadeout(puz,index) { 
	var eId = "p" + puz + "c" + index;
	if(redAy[puz][index] > redout) { //If color is not dark yet
		redAy[puz][index] -= 9; // increase red darkness
		greenAy[puz][index] -= 15; // increase green darkness
		blueAy[puz][index] -= 5; // increase blue darkness
		document.getElementById(eId).style.color =
			"rgb(" + 
			redAy[puz][index] + "," +
			greenAy[puz][index] + "," +
			blueAy[puz][index] + ")";
		setTimeout("fadeout(" + puz + "," + index + ")",15); 
	} else {
		redAy[puz][index]=redout //reset hex value
		greenAy[puz][index]=greenout //reset hex value
		blueAy[puz][index]=blueout //reset hex value
		document.getElementById(eId).style.color =
			"rgb(" + 
			redAy[puz][index] + "," +
			greenAy[puz][index] + "," +
			blueAy[puz][index] + ")";
	}
}

function fadein(puz,index) { 
	var eId = "p" + puz + "c" + index;
	if(redAy[puz][index] < redin - 15) { //If color is not light yet
		redAy[puz][index] += 9; // increase red darkness
		greenAy[puz][index] += 15; // increase green darkness
		blueAy[puz][index] += 5; // increase blue darkness
		document.getElementById(eId).style.color =
			"rgb(" + 
			redAy[puz][index] + "," +
			greenAy[puz][index] + "," +
			blueAy[puz][index] + ")";
		setTimeout("fadein(" + puz + "," + index + ")",15); 
	} else {
		redAy[puz][index]=redin //reset hex value
		greenAy[puz][index]=greenin //reset hex value
		blueAy[puz][index]=bluein //reset hex value
		document.getElementById(eId).style.color =
			"rgb(" + 
			redAy[puz][index] + "," +
			greenAy[puz][index] + "," +
			blueAy[puz][index] + ")";
	}
}
function allSolved() {
        var solved = true;
	for (var i=0; i<solvedAy.length; i++) {
		if (!solvedAy[i]) {
			solved = false;
		}
	}
	return solved;
}
