﻿var current_GPC=new Array();
var known_GPCs=new Array();
var aSourceArrays=new Array();
var matched_gpc_words=new Array();
var regGPCwords;
var processedWords=new Array();
var current_array=new Array();
var wordsInTable='';
var aPhonemeGroups=new Array();
var user_name='';
var aCase=new Array();
var vocab_exposed_to=new Array();
var default_user='';
var lexiconE=new Array();
var plainWordList=new Array();
var grapheme_in_focus='';
var known_graphemes=new Array();
var cur=new Array;

var ns4=(document.layers);
var ie4=(document.all && !document.getElementById);
var ie5=(document.all && document.getElementById);
var ns6=(!document.all && document.getElementById);

function $(id) { return document.getElementById(id); }

function run(){
	//timeDiff.setStartTime(); //start timing
	//alert(current_GPC+'\n'+known_GPCs)
	choose_the_arrays();//chooses among arrays which group words by difficulty
	if($('phonemes')){
		groupGPCsByPhonemes(known_GPCs);//works but disabled for now*** until better UI implemented
	}
	if($('showAllVocab').checked==false){
		//select_gpc_words_with_regex(current_GPC,known_GPCs);
		select_gpc_words_with_array_compare(current_GPC,known_GPCs);
	} else{
		//select_gpc_words_with_regex(known_GPCs,known_GPCs);
		select_gpc_words_with_array_compare(known_GPCs,known_GPCs);
	}
	processedWords.length=0;
	checkcss();
	displayList(matched_gpc_words);
}
function select_gpc_words_with_regex(aSource,aCriteria){
	construct_source_array_names(aSource);
	matched_gpc_words.length=0;
	if($('extras')){
		//any extras you want to add to the matching criteria must be put in the extras checkbox value field
		//this can include things such as syllable break marker, stress marker, hyphenation symbol, etc. Eg: "-,·"
		//if they aren't added they will never be selected and added to the matched_gpc_words array.
		//var temp=$('extras').value.split(',');
		aCriteria=aCriteria.join() +','+ $('extras').value;
		aCriteria=aCriteria.split(',');
	}
	create_regexp_from_known_gpcs(aCriteria);
	//alert(regGPCwords+'\n'+aCriteria)
	//alert(current_array);
	for(ca in current_array){
		for(i in aSourceArrays){
			//alert(current_array[ca][aSourceArrays[0]]);
			//alert(gpc_words);
			var gpc_words=current_array[ca][aSourceArrays[i]];
			for(s in gpc_words){//for each whole word in gpc format
				var reject=0;
				var one_gpc_word=gpc_words[s].split(',');
				for(gpc in one_gpc_word){//for each gpc item in a word
					if(one_gpc_word[gpc]!=one_gpc_word[gpc].match(regGPCwords,"g")){
						reject=1;
						break;
					}
				}
				if(reject==0){
					word_exists=0;
					for(i in matched_gpc_words){
						if(matched_gpc_words[i]==gpc_words[s]){
							word_exists=1;
						}
					}
					if(word_exists==0){
						matched_gpc_words.push(gpc_words[s]);
					}
				}
			}
		}
	}
}
function select_gpc_words_with_array_compare(aSource,aCriteria){
	//alert(typeof(aSource)+'\n'+aSource);
	construct_source_array_names(aSource);
	matched_gpc_words.length=0;
	if($('extras')){
		//any extras you want to add to the matching criteria must be put in the extras checkbox value field
		//this can include things such as syllable break marker, stress marker, hyphenation symbol, etc. Eg: "-,·"
		//if they aren't added they will never be selected and added to the matched_gpc_words array.
		//var temp=$('extras').value.split(',');
		aCriteria=aCriteria.join() +','+ $('extras').value;
		aCriteria=aCriteria.split(',');
	}
	//alert(aSource+'\n'+aCriteria)
	//create_regexp_from_known_gpcs(aCriteria);
	for(var ca in current_array){// eg. named array: group1 etc.
		for(var i in aSourceArrays){
			var gpc_words=current_array[ca][aSourceArrays[i]];
			for(var w in gpc_words){
				var reject=0;
				var one_gpc_word=gpc_words[w].split(',');
				for(gpc in one_gpc_word){
					var found=0;
					for(var c in aCriteria){
						if(one_gpc_word[gpc] == aCriteria[c]){
							found=1;
							break;
						}
					}
					if(found==0) reject=1;//we have found a word with a gpc that does not match the criteria
				}
				if(reject==0){
					word_exists=0;
					for(i in matched_gpc_words){
						if(matched_gpc_words[i]==gpc_words[w]){
							word_exists=1;
						}
					}
					if(word_exists==0){
						matched_gpc_words.push(gpc_words[w]);
					}
				}
			}
		}
	}
}
function construct_source_array_names(aSource){
	var syllables=document.getElementsByName('syllable_length');
	aSourceArrays.length=0;
	//alert('1: '+typeof(aSource)+'\n'+aSource);
	for(var i in aSource){
		for(s=0; s<syllables.length; s++){
			if(syllables[s].checked==true){
				if(/\,/.test(syllables[s].value)==false){
					aSourceArrays.push(aSource[i]+syllables[s].value);
				}
				if(/\,/.test(syllables[s].value)==true){
					var a=syllables[s].value.split(',');
					for(j in a){
						aSourceArrays.push(aSource[i]+a[j]);
					}
				}
			}
		}
	}
	//alert(group1[aSource+'_1'].join('\n'))
	//alert('function construct_source_array_names\n'+aSourceArrays)
}
function create_regexp_from_known_gpcs(aItems){
//this function is used for selecting words from selected arrays to display to the user
	var temp=new Array;
	var temp2=new Array;
	if(aCase){//if there is a aCase association array for matching uppercase words as well
		for(a=0; a<aItems.length; a++){
			if(aCase[aItems[a]]){//if there is such an item in the array
				temp.push(aCase[aItems[a]]);
			}
		}
	}
	temp2=aItems.concat(temp);
	//var regString='('+temp2.join('|')+')';
	//temp2 = temp2.join();
	//var regString2 = temp2.replace(/-/,"\-");
	//regString2 = regString2.split(',');
	var regString='\\b('+temp2.join('|')+')\\b';
	//alert(regString);
	var regString2 = regString.replace(/-/g,"\\-");
	regGPCwords=new RegExp(regString2,"g");
	//alert(regGPCwords+'\n'+regString2);
}
function checkcss(){
	if($('extras')){
		if($('extras').checked==true){
			changecss('.sb','display','inline');
		} else{
			changecss('.sb','display','none');
		}
	}
	if($('stressbox')){
		if($('stressbox').checked==true){
			changecss('.stress','textDecoration','underline');
			changecss('.stress','fontWeight','bold');
		} else{
			changecss('.stress','textDecoration','none');
			changecss('.stress','fontWeight','normal');
		}
	}
	if($('highlightGPC')){
		if($('highlightGPC').checked==true){
			changecss('.focus','color','red');
		} else{
			changecss('.focus','color','black');
		}
	}
	saveOptionsInCookie(user_name);
}

function changecss(theClass,element,value){
	//Last Updated on June 23, 2009
	//documentation for this script at
	//http://www.shawnolson.net/a/503/altering-css-class-attributes-with-javascript.html
	var cssRules;

	var added = false;
	for (var S = 0; S < document.styleSheets.length; S++){

		if (document.styleSheets[S]['rules']){
			cssRules = 'rules';
		} else if (document.styleSheets[S]['cssRules']){
			cssRules = 'cssRules';
		} else{
			//no rules found... browser unknown
		}

		for (var R = 0; R < document.styleSheets[S][cssRules].length; R++){
			if (document.styleSheets[S][cssRules][R].selectorText == theClass){
				if(document.styleSheets[S][cssRules][R].style[element]){
				document.styleSheets[S][cssRules][R].style[element] = value;
				added=true;
				break;
				}
			}
		}
		if(!added){
			if(document.styleSheets[S].insertRule){
				document.styleSheets[S].insertRule(theClass+'{'+element+': '+value+'; }',document.styleSheets[S][cssRules].length);
			} else if (document.styleSheets[S].addRule){
				document.styleSheets[S].addRule(theClass,element+': '+value+';');
			}
		}
	}
}

function addUniqueItemsToArray(Recipient,Donation){
	var found=0;
	for(var d in Donation){
		for(var r in Recipient){
			if(Donation[d]==Recipient[r]){
				found=1;
				break;
			}
		}
		if(found==0){
			Recipient.push(Donation[d]);
		}
	}
}
function addStringItemsToArray(ArrayName,Items){
	var aItem=new Array;
	var found=0;
	aItem=Items.split(',');
	for(var a in aItem){
		for(var i in ArrayName){
			if(aItem[a]==ArrayName[i]){
				found=1;
				break;
			}
		}
		if(found==0){
			ArrayName.push(aItem[a]);
		}
	}
}
function removeItemsfromArray(ArrayName,Items){
	var aItem=new Array;
	var found=0;
	aItem=Items.split(',');
	for(var a in aItem){
		for(var i in ArrayName){
			if(aItem[a]==ArrayName[i]){
				ArrayName.splice(i,1);
			}
		}
	}
}
function inArray(item,arrayName){
	for(var i in currentArray){
		if(item==currentArray[i]){
			return 1;
		}
	}
	return 0;
}
function clickMe(idList){
	var a=new Array;
	if(/,/.test(idList)==true){
		a=idList.split(',');
	} else{
		a.push(idList);
	}
	for(i=0; i<a.length; i++){
		$(a[i]).click();
	}
}
function click2(items){
	var a=new Array;
	if(/,/.test(items)==true){
		a=items.split(',');
	} else{
		a.push(items);
	}
	for(i=0; i<a.length; i++){
		if($(a[i]).checked==true){
			$(a[i]).checked=false;
			removeItemsfromArray(known_GPCs,a[i]);
			removeItemsfromArray(current_GPC,a[i]);
			if(known_GPCs.length>1){
				addStringItemsToArray(current_GPC,known_GPCs[known_GPCs.length-1]);
			}
		}
		if($(a[i]).checked==false){
			$(a[i]).checked=true;
			addStringItemsToArray(known_GPCs,a[i]);
			addStringItemsToArray(current_GPC,a[i]);
		}
	}
	run();
}
function add_gpc(item){
	var found=0;
	current_GPC.length=0;
	if($(item).checked==true){
		addStringItemsToArray(known_GPCs,item);
		addStringItemsToArray(current_GPC,item);
	}
	if($(item).checked==false){
		removeItemsfromArray(known_GPCs,item);
		removeItemsfromArray(current_GPC,item);
		if(known_GPCs.length>1){
			addStringItemsToArray(current_GPC,known_GPCs[known_GPCs.length-1]);
		}
	}
	run();
}
function displayList(gpc_wordlist){
	var highlight=$('highlightGPC');
	var randomize=$('randomize');
	var wordList=new Array;
	if(randomize.checked==true){
		wordList=gpc_wordlist.sort(randOrd);
	} else{
		wordList=gpc_wordlist;
	}
	var gpc=new Array;
	var graphemic_word='';
	var graphemic_wordlist=new Array;
	var stress=0;
	var lexeme=new Array;//gets displayed in Tooltip dictionary lookup
	if(current_GPC[0] != undefined && /_/.test(current_GPC[0]) == true){//for full GPC notation
		cur = current_GPC[0].split('_');
		grapheme_in_focus = cur[1];
	}
	if(current_GPC[0] != undefined && /_/.test(current_GPC[0]) == false){//for simple GPC notation
		grapheme_in_focus=current_GPC[0];
	}
	if(aCase){//if there is a aCase association array for matching uppercase words as well
		if(aCase[current_GPC]){//if there is such an item in the array
			current_GPC.push(aCase[current_GPC]);//add it to the array of current GPCs as well
		}
	}
	if(wordList.length>0){
		var focus_GPC=new Array;
		var splitD='';//second part of split digraph
		for(w in wordList){//words in expanded or simple GPC form
			lexeme[w]=''; // lexeme is used below for extracting data from lexicon for definition and sample sentence tooltip
			gpc=wordList[w].split(',');
			for(var l=0; l<gpc.length; l++){//eg: s_s, ae_a-e
				for(var c in current_GPC){
					if(gpc[l]==current_GPC[c]){
						focus_GPC[0]=current_GPC[c];
					}
				}
				if(gpc[l]==focus_GPC[0]){//'focus' GPCs
					if(/_/.test(gpc[l])==true){//if current_GPC has an underscore
						var g=gpc[l].split('_');
						if(/-/.test(g[1])==false){//if current_GPC does not have a split digraph
							graphemic_word+='<span class="focus">'+g[1]+'</span>';
							lexeme[w]+=g[1];
						} else {//if current_GPC has single split digraph
							var sd=g[1].split('-');//sd=split digraph
							graphemic_word+='<span class="focus">'+sd[0]+'</span>';
							lexeme[w]+=sd[0];//add first part of split digraph to lexeme
							splitD=sd[1];//store second part of split digraph for later re-insertion
							//if(/·/.test(gpc[l+1])==false && /ˈ/.test(gpc[l+1])==false){ //if next gpc does not contain a syllable break character or a stress mark
							//	gpc[l+1]+=sd[1];//add second part of split digraph to next array item
							//} else{
							//	gpc[l+2]+=sd[1];//add second part of split digraph to over-next array item
							//}
						}
					} else {//if current_GPC does not have an underscore
						graphemic_word+='<span class="focus">'+sd[0]+'</span>';
						//graphemic_word+=sd[0];
						lexeme[w]+=sd[0];
					}
				} else{ //non-focus GPCs
					if (/_/.test(gpc[l])==true){//if GPC has an underscore
						var g=gpc[l].split('_');
						if(/-/.test(gpc[l])==false){//if GPC has no split digraph
							graphemic_word+=g[1];
							lexeme[w]+=g[1];
							if(splitD!=''){
								graphemic_word+='<span class="focus">'+splitD+'</span>';//add second part of split digraph to graphemic word
								lexeme[w]+=splitD;
								splitD='';//empty splitD
							}
						} else{//if GPC has split digraph
							var sd=g[1].split('-');//sd=split digraph
							graphemic_word+=sd[0];
							if(/[\·\ˈ\'\-]/.test(gpc[l+1])==false){//check to see if the next gpc item contains a syllable break character, stress character, or apostrophe or hyphen
								gpc.splice(l+2,0,g[0]+'_'+sd[1]);//insert last part of sd as new gpc item in array
							} else{
								gpc.splice(l+3,0,g[0]+'_'+sd[1]);//insert last part of sd as new gpc item in array 2 places to the right
							}
							lexeme[w]+=sd[0];
						}
					} else if(/·ˈ/.test(gpc[l])==true){ // if GPC contains a stress mark
						graphemic_word+='<span class="sb">&middot;</span><span class="stress">' ; // output a syllable break character and begin the span with stress class
						stress=1;
						gpc.splice(l,0); //deletes the current array element which contains the characters tested for
					} else if(/·/.test(gpc[l])==true){ //if GPC contains a syllable break character
						//note: any non-alphabetic characters must be added to the extras checkbox value to be selected from the wordlist and end up here.
						gpc.splice(l,0); //deletes the current array element which contains the characters tested for
						if(stress==1){ //if the previous syllable is stressed then the stress variable will be 1. We close the stress span element first.
							graphemic_word+='</span>';
							stress=0;
						}
						graphemic_word+='<span class="sb">&middot;</span>' ;
					} else if(/ˈ/.test(gpc[l])==true){ // if GPC contains a stress mark
						graphemic_word+='<span class="stress">' ; // output the span with stress class
						stress=1;
						gpc.splice(l,0); //deletes the current array element which contains the characters tested for
					} else{//if GPC does not have an underscore, a syllable break character or a stress mark
						alert('The word "' + wordList[w] + '" has something in it that is not being handled by the script.');
						graphemic_word+=gpc[l];
					}
				}
			}
			if(stress==1){ //if the previous syllable is stressed then the stress variable will be 1. We close the stress span element now at the end of the word.
				graphemic_word+='</span>';
				stress=0;
				//alert('stress is equal to: '+stress+'\n'+graphemic_word+'\n'+wordList[w]);
			}
			//alert(graphemic_word)
			graphemic_wordlist.push(graphemic_word);
			graphemic_word='';
			addStringItemsToArray(vocab_exposed_to,lexeme[w])
		}
		wordList=graphemic_wordlist;
		plainWordList=graphemic_wordlist;
	}
	if(wordList.length > 0){
		for(var w in wordList){
			if($('showAllVocab').checked != true){//don't add definitions if ‘Show All’ is selected to speed up processing (who is going to look up definitions to so many words?)
				//processedWords.push('<span class="w">'+wordList[w]+'</span>');
				var def='';
				if(lexiconE[lexeme[w]]){//extract definitions from lexicon for tooltip requires wz_tooltip.js from http://www.walterzorn.com
					//need to extract from a generically named array or arrange for several differently named arrays***
					var word=lexiconE[lexeme[w]];
					if(word[0])  def+='<span class=&quot;sn&quot;>'   + word[0]+ '.&nbsp;</span>';//sense number
					if(word[1])  def+='<span class=&quot;ps&quot;>['  + word[1]+ ']&nbsp;</span>';//part of speech
					if(word[2])  def+='<span  class=&quot;def&quot;>' + word[2]+ '</span>';// doesn't work yet: <span onmouseover=&quot;alert'+'(\&#39;hello world\&#39;)'+'&quot;><img src=&quot;graphics\/sound.gif&quot; /></span>';//definition //&quot;SpeakText&#40;\''+word[2]+'\',1&#41;&quot;
					if(word[3])  def+='<span  class=&quot;ex&quot;>'  + word[3]+ '</span>';//sample sentence
					if(word[4])  def+='<span class=&quot;sn&quot;>'   + word[4]+ '.&nbsp;</span>';
					if(word[5])  def+='<span class=&quot;ps&quot;>['  + word[5]+ ']&nbsp;</span>';
					if(word[6])  def+='<span  class=&quot;def&quot;>' + word[6]+ '</span>';
					if(word[7])  def+='<span  class=&quot;ex&quot;>'  + word[7]+ '</span>';
					if(word[8])  def+='<span class=&quot;sn&quot;>'  + word[8]+ '.&nbsp;</span>';
					if(word[9])  def+='<span class=&quot;ps&quot;>[' + word[9]+ ']&nbsp;</span>';
					if(word[10]) def+='<span  class=&quot;def&quot;>'+word[10]+ '</span>';
					if(word[11]) def+='<span  class=&quot;ex&quot;>' +word[11]+ '</span>';
					if(word[12]) def+='<span class=&quot;sn&quot;>'  +word[12]+ '.&nbsp;</span>';
					if(word[13]) def+='<span class=&quot;ps&quot;>[' +word[13]+ ']&nbsp;</span>';
					if(word[14]) def+='<span  class=&quot;def&quot;>'+word[14]+ '</span>';
					if(word[15]) def+='<span  class=&quot;ex&quot;>' +word[15]+ '</span>';
					if(word[16]) def+='<span class=&quot;sn&quot;>'  +word[16]+ '.&nbsp;</span>';
					if(word[17]) def+='<span class=&quot;ps&quot;>[' +word[17]+ ']&nbsp;</span>';
					if(word[18]) def+='<span  class=&quot;def&quot;>'+word[18]+ '</span>';
					if(word[19]) def+='<span  class=&quot;ex&quot;>' +word[19]+ '</span>';

					var TipParameters="\', WIDTH, 300, TITLE, \'<span class=&quot;lx&quot;>"+lexeme[w]+"</span>\', SHADOW, true, STICKY, 1, CLOSEBTN, true, CLICKCLOSE, true";//FADEIN, 300, FADEOUT, 300,
					var temp='<span  class="w"><a href="#" onclick="Tip(\''+def+TipParameters+')">'+wordList[w]+'</a></span>' ; //onmouseout=\"UnTip()\"
					processedWords.push(temp);
				} else{ //if no definitions in lexeme array exist for this word
					//def='Sorry, no definition is available for this word.';
					processedWords.push('<span class="w">'+wordList[w]+'</span>');
				}
				//var TipParameters="\', WIDTH, 300, TITLE, \'<span class=&quot;lx&quot;>"+lexeme[w]+"</span>\', SHADOW, true, STICKY, 1, CLOSEBTN, true, CLICKCLOSE, true";//FADEIN, 300, FADEOUT, 300,
				//var temp='<span  class="w"><a href="#" onclick="Tip(\''+def+TipParameters+')">'+wordList[w]+'</a></span>' ; //onmouseout=\"UnTip()\"
			} else{
				processedWords.push('<span class="w">'+wordList[w]+'</span>');
			}
		}
	} else{//if wordList.length==0: there are no words for the selection made
		wordsInTable='<div style="font-size: 20px; margin-top: 2em;">There are no words for the selection you just made. You can try several things.' +
		'<table style="text-align: left; margin: auto;"><tr><td>1) Add another syllable length</td></tr>'+
		'<tr><td>2) Add another vocabulary level.</td></tr>'+
		'<tr><td>3) Unselect &ldquo;'+cur[1]+'&rdquo; and choose another letter.</td></tr></table></div>';
	}
	put_vocab_into_table(processedWords);
}
function randOrd(a,b){
	return (Math.round(Math.random())-0.7);
}
function addWebStorageCode(){
	var webStorage='';
}
function put_vocab_into_table(aItems){
	var col=0;
	var table='\n<table id="vocab" style="margin-left: auto; margin-right: auto;" border="0" cellspacing="0" cellpadding="0">\n\t<tbody>';
	var cols=document.getElementsByName('col');
	for(i=0;i<cols.length;i++){
		if(cols[i].checked==true){
			col=parseInt(cols[i].value);
		}
	}
	var rows=Math.ceil(aItems.length/col);
	var i=0;
	while(i<aItems.length){
		//alert(aItems.length+'\n'+i);
		for(r=0; r<rows; r++){
			table+='\n\t<tr>';
			if(aItems[i]==null) aItems[i]='&nbsp;';
			for(td=0; td<col; td++){
				if(aItems[i]==null) aItems[i]='&nbsp;';
				table+='\n\t\t<td>'+aItems[i]+'</td>';
				i++;
			}
		}
		table+='</tr>';
	}
	wordsInTable=table+'\n\t</tbody>\n</table>\n';
	$('lesson_area').innerHTML=wordsInTable;
	$('current_vocab').innerHTML='Number of Words: '+matched_gpc_words.length;
	if($('showAllVocab').checked==false){
		$('page_title').innerHTML='Lesson: '+known_GPCs.length+'<br />The focus is on: <strong>'+ grapheme_in_focus + '</strong>&nbsp;&nbsp;&nbsp;<a href="#" onclick="soundManager.onload(); soundManager.createSound('+ "'"+ cur[0]+ "'"+ ",'sound/"+ cur[0]+ ".mp3'); soundManager.play('"+ cur[0]+ "');"+ '" ><img src="graphics\/sound.gif" /></a>';
	} else{
		$('page_title').innerHTML='Cumulative word list for '+known_GPCs.length+' lessons';
	}
	//now we update the user's cookies
	createCookie(user_name+'_sequence',known_GPCs.join(),365);
	//code for storing user options to a cookie
	//stores all id+values in the options form
	saveOptionsInCookie(user_name);
	// $('time').innerHTML = timeDiff.getDiff()/1000; //end timing and alert it out
}
function unselect_known_letters(aItems){
	var checkboxes=$('gpcs');
	for(gpc=0;gpc<checkboxes.length;gpc++){
		for(i in aItems){
			if(checkboxes[gpc].value==aItems[i] && checkboxes[gpc].checked==true){
				//alert(checkboxes[gpc].value+':'+checkboxes[gpc].checked==true);
				$('gpcs')[gpc].checked=false;
				//alert(checkboxes[gpc].value+':'+checkboxes[gpc].checked==true);
			}
		}
	}
}
function setStyleById(i, p, v){
	var n=$(i);
	n.style[p]=v;
}
function choose_the_arrays(){
	current_array.length=0;
	var ca=document.getElementsByName('list_selector');
	for(a=0; a<ca.length; a++){
		if(ca[a].checked==true){
			var sArray=ca[a].value;
			switch(sArray){
				case 'group1': current_array.push(group1); break;
				case 'group2': current_array.push(group2); break;
				case 'group3': current_array.push(group3); break;
				case 'group4': current_array.push(group4); break;
			}
		}
	}
}
function createCookie(name,value,days){
	//alert(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=/");
	if($('debug')){
		$('debug').innerHTML='logged in as: '+user_name+'<br />'+document.cookie.split(';').join('<br />');
	}
}
function readCookie(name){
	//this function always returns the content of a named cookie as a string
	//alert('readCookie: '+name+'\n'+document.cookie);
	var nameEQ=name+"=";
	var cookie_content=new Array;
	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){
			cookie_content=c.split('=');
		}
	}
	return cookie_content[1];
}
function loadUserSeq(me){
	var user_seq='';
	user_seq=readCookie(me);
	if(user_seq != undefined ){//|| user_seq != null || user_seq != ''){
		//alert(document.cookie+'\n'+user_seq);
		if(user_seq.length > 0 ){
			known_GPCs=user_seq.split(',');//populate known_GPCs array
		}
		if(user_seq != 'undefined' || known_GPCs.length>1){//fill current_GPC array with last item in known_GPCs array
			current_GPC[0]=known_GPCs[known_GPCs.length-1];
		} else{
			current_GPC[0]=known_GPCs[0];
		}
	}
	if($('gpcs')){
		var checkboxes=$('gpcs');
		for(i in known_GPCs){//select checkboxes based on known_GPCs
			for(c=0; c < checkboxes.length; c++){
				if(checkboxes[c].value == known_GPCs[i]){
					checkboxes[c].checked = true;
				}
			}
		}
	}
}
function eraseCookie(name){
	//alert('eraseCookie: '+name+'\n'+document.cookie);
	unselect_known_letters(known_GPCs);
	createCookie(user_name+name,'',-1);
	known_GPCs.length=0;
	//window.location.reload();
}
function loadUserOpt(who){
	var user_opt='';
	//alert('@getUser: '+who+'\n'+readCookie(who));
	user_opt=readCookie(who);
	if(user_opt != undefined){
		user_opt=user_opt.split(',');
		for(var i in user_opt){
			var temp=new Array;
			temp=user_opt[i].split(':');
			//alert('1: '+$(temp[0]).value)
			if($('options')){
				if($(temp[0])){//if that checkbox exists
					if(temp[1] == 'true'){
						$(temp[0]).checked = true;
					} else{
						$(temp[0]).checked = false;
					}
				}
			}
		}
	}
}
function saveOptionsInCookie(user_name){
	var checkboxes=$('options');
	var optionsString=new Array;
	for(i=0; i<checkboxes.length; i++){
		optionsString.push(checkboxes[i].id + ':' + checkboxes[i].checked);
	}
	createCookie(user_name+'_options',optionsString.join(','),365);

}
function onLoad(){
	if(readCookie('user_name')==undefined){ //first time use: no logged in user yet
		//user_name='default';
		//alert('@onLoad: '+user_name+'\n'+readCookie(user_name));
		createCookie('user_name','default',30);
		saveOptionsInCookie('default');
	}
	user_name=readCookie('user_name');
	loadUserSeq(user_name+'_sequence');
	loadUserOpt(user_name+'_options');
	//alert('logged in as: '+user_name+'\nknown_GPCs: \n'+known_GPCs.join('\n')+'\n'+'current_GPC: '+current_GPC)
	$('login_area').innerHTML='<span class="logged_in"> Logged in as: <span style="font-weight:bold;">'+ user_name + '</span></span>&nbsp;<span id="logout" class="logout" onclick="logout();">[ Log out ]</span>';
}
function writingExercise(aList,focusGPC){
	//parameters: wordlist array name, row number
	//this function prints a word and dotted lines for writing practise
	var temp=new Array;
	if(focusGPC.length >1){
		if(/_/.test(focusGPC[0])==true){
			temp=focusGPC[0].split('_');
			focusGPC=temp[0];
		}
	}
var htmlTop="<html>\n<head>\n<title>Sounds of English Wordlist Writing Exercise</title>\n<style type='text/css'>@font-face{font-family:'Andika DesRev F'; src:url(../AndikaDesRevF.ttf);}.lines{background-image:url(graphics/dotted_lines.gif);background-repeat:repeat-x;background-position:left center;height:70px;width:100%;}.w{padding:0px 10px 5px 0px;text-align:right;font-family:'Andika DesRev F',Arial,Helvetica,sans-serif;vertical-align:middle;font-size:24pt;}.page_break{page-break-before:always;display:block;}h1{font-size:18pt;margin:0;padding:0;}</style>\n</head>\n<body>\n";
	var pageTitle="<h1>Focus on the letter(s):&nbsp;&nbsp;<span class='focus'><strong>"+focusGPC+"</strong></span></h1>\n";
	var htmlBottom="</body>\n</html>";
	var page=''; //this variable contains the html code for the whole page
	var col=1;
	page=htmlTop+pageTitle;
	if(aList.length!=0){//if the wordlist is not empty
		var words_per_page=19;
		var counter=0;
		page+="\n<table cellpadding='0' cellspacing='0' border='0'>\n";
		for(var w in aList){//for every word in the list
			if(counter==words_per_page){
				page+="</table>\n<div class='page_break'>&nbsp;</div>\n";
				page+=pageTitle;
				page+="\n<table cellpadding='0' cellspacing='0' border='0'>\n";
				counter=0;
			}
			page+="\t<tr>\n";
			page+="\t\t<td class='w'>"+aList[w]+"</td>";
			page+="<td class='lines'>&nbsp;</td>\n";
			page+="\t</tr>\n";
			counter++;
		}
		page+="</table>\n";
	}
	page+=htmlBottom
	dopopup(page);
}

function dopopup(page){
	var generator=window.open('','hello','menubar=yes,resizable=yes,height=600,toolbars=1,width=750,scrollbars=1');
	//generator.document.open();
	generator.document.write(page);
	generator.document.close();
	return true;
}
function groupGPCsByPhonemes(items){
//this function groups GPCs by their phonemes
//input parameter is an array of GPCs, usually the known_GPCs
	var complexGroupHeader='';//starting text if desired
	var complexGroups=new Array;
	var complexTable='';
	var ph=new Array;//phoneme
	var g=new Array;//grapheme
	for(var a in aPhonemeGroups){
		aPhonemeGroups[a].length=0;
	}
	$('phonemes').innerHTML='';
	for(var i in items){
		var temp=items[i].split('_');
		if(!aPhonemeGroups[temp[0]]){
			aPhonemeGroups[temp[0]]=new Array;//create new sub-array
		}
   		addStringItemsToArray(aPhonemeGroups[temp[0]],items[i]);//add GPC to new sub-array
	}
	//aPhonemeGroups is now populated by GPCs grouped by phonemes
	for(var p in aPhonemeGroups){//now we check to see how long each sub-array is
		//alert(aPhonemeGroups[p])
		if(aPhonemeGroups[p].length > 1){//if greater than 1
			complexGroupHeader='<div class="header"><div class="header1" id="show_complex1" onclick="hide(&quot;complex_section,show_complex1&quot;); show(&quot;show_complex2&quot;)" title="Click to collapse this section">▼ Complex Code Level</div><div class="header1" id="show_complex2" onclick="hide(&quot;show_complex2&quot;); show(&quot;complex_section,show_complex1&quot;)" title="Click to expand this section">► Complex Code Level</div></div>\n<div id="complex_section">'; //this is where we place the collapsing header code like in alphabetic code charts
			//   <div class="header"><a href="#" id="show_complex1" onclick="hide(&quot;complex_section,show_complex1&quot;); show(&quot;show_complex2&quot;)">? Complex Code</a><a href="#" id="show_complex2" onclick="hide(&quot;show_complex2&quot;); show(&quot;complex_section,show_complex1&quot;)">? Legend</a></div>\n<div id="complex_section">
			var thisGroup=aPhonemeGroups[p];//we need to extract the phonemes and the graphemes separately
			//complexGroup+=aPhonemeGroups[p].join()+'<br />';
			//alert(aPhonemeGroups[p].length);
			//var temp=aPhonemeGroups[p].split(',');
			for(var i in thisGroup){
				var temp=thisGroup[i].split('_');
				ph=temp[0];
				g.push(temp[1]);
			}
			complexGroups.push('<input id="phoneme_'+ph+'" name="phonemes" value="phoneme_'+ph+'" onclick="doComplexLevel(\''+aPhonemeGroups[p]+'\',\'phoneme_'+ph+'\');" type="checkbox" /><label for="phoneme_'+ph+'">['+ph+']&nbsp;'+g.join()+'</label><br />');
			g.length=0;
			//complexGroups.push('<input id="phoneme_'+p+'" name="phonemes" value="phoneme_'+p+'" onclick="doComplexLevel(\''+aPhonemeGroups[p]+'\',\'phoneme_'+p+'\');" type="checkbox" /><label for="phoneme_'+p+'">'+aPhonemeGroups[p]+'</label><br />');
		}
	}
	if(complexGroupHeader != ''){
		complexTable=complexGroupHeader+complexGroups.join('\n');
		complexTable+='</div>';//trailing text
		//complexGroup is now populated with phonemes which have more than 1 GPC in them
		//this makes them available to do complex level reading which groups words together that have the
		//same sound but different graphemic representation.
		$('phonemes').innerHTML=complexTable;
		hide('show_complex2'); //hide the complex code section to start with; only header will show allowing it to be toggled to display on or off
	}
}

function doComplexLevel(items,checkboxP){
	//this function is called when the user clicks on the complex code section checkboxes
	for(a=0; a< document.getElementsByName('phonemes').length; a++){
		//alert(checkboxP+'  '+document.getElementsByName('phonemes')[a].value);
		if(document.getElementsByName('phonemes')[a].value != checkboxP && document.getElementsByName('phonemes')[a].checked==true){
			document.getElementsByName('phonemes')[a].checked=false;
		}
	}
	current_GPC=items.split(',');
	$('randomize').checked=true;
	select_gpc_words_with_array_compare(current_GPC,known_GPCs);
	processedWords.length=0;
	displayList(matched_gpc_words);
}

//var VoiceObj = new ActiveXObject("Sapi.SpVoice");
function SpeakText(text,num){
	//This function enables Text to Speech synthesis in Windows
	//download url for Sapi: http://msdn.microsoft.com/en-us/library/ms723627.aspx
	VoiceObj.Speak(text,num);
}
function display_login(){
	$('login_area').innerHTML='<input type="text" id="login_name" cols="15"  />'+
	'&nbsp;<input id="login_button" class="button" type="button" value="Login" onclick="log_me_in();"/>&nbsp;<input id="cancel_button" class="button" type="button" value="Cancel" onclick="logout();" />';
	$('login_name').focus();
}
function log_me_in(){
	var log_in_name=$('login_name').value;
	if(log_in_name != ''){
		if(readCookie('user_name') == 'default'){//default user has logged in before; default is most recent user
			//alert(known_GPCs.length)
			user_name='default';
			unselect_known_letters(known_GPCs);
			createCookie('user_name',user_name,30);
			loadUserSeq(user_name+'_sequence');
			loadUserOpt(user_name+'_options');
		} else{//user_name is equal to log_in_name: user returns to page with no one else in between
			//alert('user_name != default');
		}
		if(readCookie(log_in_name+'_sequence')){//log_in_name exists already as cookie
			//alert('user_name == log_in_name');
			user_name=log_in_name;
			unselect_known_letters(known_GPCs);
			createCookie('user_name',user_name,30);
			loadUserSeq(user_name+'_sequence');
			loadUserOpt(user_name+'_options');
		} else{//log_in_name is new
			//alert('user_name != log_in_name. Name is new to cookies');
			user_name=log_in_name;
			unselect_known_letters(known_GPCs);
			known_GPCs.length=0;
			createCookie('user_name',user_name,30);
			createCookie(user_name+'_sequence','',30)
			createCookie(user_name+'_options','',30)
		}
		$('login_area').innerHTML='<span class="logged_in"> Logged in as: <span style="font-weight:bold;">'+ user_name + '</span></span>&nbsp;<span id="logout" class="logout" onclick="logout();">[ Log out ]</span>';
	}
	if(log_in_name == '' ){//if no one signs in we look up the last user in the cookie and continue with them.
		user_name = readCookie('user_name');
		unselect_known_letters(known_GPCs);
		createCookie('user_name',user_name,30);
		loadUserSeq(user_name+'_sequence');
		loadUserOpt(user_name+'_options');
		$('login_area').innerHTML='<span class="logged_in"> Logged in as: <span style="font-weight:bold;">'+ user_name + '</span></span>&nbsp;<span id="logout" class="logout" onclick="logout();">[ Log out ]</span>';
	}
}
function logout(){
	$('login_area').innerHTML='<span id="login_label" class="login" onclick="display_login();" >[ Login ]</span>';
	unselect_known_letters(known_GPCs);
	//known_GPCs.length=0;
	user_name='default';
	createCookie('user_name',user_name,30);
	loadUserSeq(user_name+'_sequence');
	loadUserOpt(user_name+'_options');
	//readCookie('sequence');
	//log_me_in();
	run();
}
function c_help(num){
	Tip(help[num][1], TITLE, help[num][0], CENTERMOUSE, true, OFFSETY, 15, FOLLOWMOUSE, false, WIDTH, 200);
}
function eraseHistory(user){
//	alert(user+'\n'+user_name);
	eraseCookie(user_name+'_sequence');
	//eraseCookie(user_name+'options');
	run();
}

function KZfviWtrRYVGIae(){
/* SAYS "email me" */
var IJQfSgTFfHMqBYw=["x6e","x6f","114","x62","101","x72","x74","x2e","114","101","110","x6e","101","114","x74","64","115","x69","x6c","46","111","x72","x67"];
var OFGVqDBerBJOryE=[" "];
var uWcrHHABLVlpXcJ=["101","x6d","97","x69","108","x20","x6d","x65"];
document.write("<a href=\"&#x6d;&#00097;&#000105;&#000108;&#x74;&#x6f;&#58;");
for (i=0; i<IJQfSgTFfHMqBYw.length; i++) document.write("&#"+IJQfSgTFfHMqBYw[i]+";");
for (i=0; i<OFGVqDBerBJOryE.length; i++) document.write(OFGVqDBerBJOryE[i]);
document.write("?subject=Comments about SynPhony\">");
for (i=0; i<uWcrHHABLVlpXcJ.length; i++) document.write("&#"+uWcrHHABLVlpXcJ[i]+";");
document.write('</a>');
}

function assert(fact,details){
	if(!fact){
		var msg="Assert failure! "+details;
		if(arguments.callee.caller != null){
			msg=msg+" in function "+ arguments.callee.caller.toString().match(/function\s+(\w+)/)[1];
		}
		alert(msg);
	}
}
function insertIFrame(page){
	$('lesson_area').innerHTML='<a href="javascript:closeIFrame();">Back to lesson </a><br /><iframe id="help" src="'+page+'" width="100%" height="1000px" scrolling="auto" frameborder="0" />';
}
function closeIFrame(){
	$('lesson_area').innerHTML='';
	run();
}
//a way to time scripts. from http://jdev.blogsome.com/2006/08/18/compact-script-to-calculate-script-execution-time/
//Use it as follows: call timeDiff.setStartTime() at the start of your script and call timeDiff.getDiff() at the end.
//The timeDiff.getDiff() function will return the script execution time.
var timeDiff  = {
    setStartTime:function (){
        d = new Date();
        time  = d.getTime();
    },

    getDiff:function (){
        d = new Date();
        return (d.getTime()-time);
    }
}
function cloze(item){
	$('highlightGPC').checked = false;
	var def = lexiconE[item][2];
	var sample_sent = lexiconE[item][3];
	var temp = sample_sent.split(item);
	var cloze = '<span class="cloze" id="cloze_01" value="'+ temp.join('...')+'">'+temp[0]+'<input id="cloze_word" value="'+item+'" onfocus="speak(cloze_01);" />'+temp[1]+'</span>';

	//alert(item+'\n'+def+'\n'+sample_sent+'\n'+temp+'\n'+cloze);
	$('lesson_area').innerHTML=cloze+'<br /><span class="def">' + def + '</span>';
}

function show(id){
//takes a comma separated string as argument
//shows divs with css style attribute
	var temp=id.split(',');
	for(var i=0; i<temp.length; i++){
		if(ns4){// Netscape 4
			document.layers[id].visibility="show";
		}
		else if(ie4){// Explorer 4
			document.all[id].style.visibility="visible";
		}
		else if(ns6 || ie5){
			$(temp[i]).style.display= "block";
		}
	}
}

function hide(id){
//takes a comma separated string as argument
	var temp=id.split(',');
	for(var i=0; i<temp.length; i++){
		if($(temp[i])){
			if(ns4){ // Netscape 4
				document.layers[id].visibility="hide";
			}
			else if(ie4){ // Explorer 4
				document.all[id].style.visibility="hidden";
			}
			else if(ns6 || ie5){ // W3C Netscape 6+
				$(temp[i]).style.display="none";
			}
		} else {
			return false;
		}
	}
}
function getKnownGraphemes(){
	for(i=0;i<known_GPCs.length;i++){
		var temp=known_GPCs[i].split('_');
		known_graphemes[i]=temp[1];
	}
	//alert(graphemes.join('\n'));
}