function GImages() { }

var gimages = null;

/*
 * Initialization: set parameters, retrieve languages, etc.
 */
function onDocumentLoad_Always() {
    gimages = new GImages();
        
    // query parameters
	var queryParams = parseQueryString(window.location.search);
    gimages.sourceWord = queryParams["word"];
    gimages.langID = queryParams["lang"];
    gimages.deepSearch = queryParams["deep"];
    gimages.initialSense = queryParams["initialSense"];
   	gimages.userid = getUserID();
   	gimages.username = getUserName();
    
    gimages.AJAXURLs = new Array();
    gimages.loc = new Array();

    if (gimages.sourceWord == undefined)
    	gimages.sourceWord = "";
    if (gimages.langID == undefined)
    	gimages.langID = -1;
    if (gimages.userid == null || gimages.userid == "null"){
    	gimages.userid = 0;
    }    
    if (gimages.username == null || gimages.username == "null"){
    	gimages.username = "";
    }
        
    /* advanced interface stuff.  obsolete. ~ono
     * readded per oren's request ~chris */
    var advancedElement = document.getElementById("advanced");
    if(advancedElement.value=="true") {
    	gimages.advanced=true;
    } else {
    	gimages.advanced=false;
    }
    /**/
    
    // fill in the inputs with the HTTP parameters
    document.searchPanel.setSearchLanguageID(gimages.langID);
    document.searchPanel.setQueryText(gimages.sourceWord);
    document.searchPanel.setDeepSearch(gimages.deepSearch);
    
    // grab the name of the selected language
    gimages.languageName = document.searchPanel.getLanguageText();
    
	var oldClick = (document.onclick) ? document.onclick : function () {};
	document.onclick = function(e) {
		oldClick(e);
		onDocumentClick(e);
	};
	if (document.captureEvents) document.captureEvents(Event.CLICK);
    gimages.numTranslationsChecked = 0;
    gimages.queryParams = queryParams;
    
    gimages.addingTranslation = new Array();
    gimages.addingTranslation[0] = false;
    gimages.addingTranslation[1] = false;
    gimages.addingTranslation[2] = false;
    gimages.addingTranslation[3] = false;
    gimages.addingTranslation[4] = false;
    gimages.removingTranslation = false;
    gimages.maxLanguageLength = new Array();
    gimages.showingMoreTranslations = new Array();
    //gimages.checkingMoreTranslations = new Array();
    //gimages.numMoreTranslations = new Array();
    gimages.showingEditTranslations = false;
    gimages.showingHighConfTranslations = false;
    gimages.showingMediumConfTranslations = false;
    gimages.showingLowConfTranslations = false;
    
    
    languageCallback = function ( responseText ) {
    	var json = responseText.parseJSON(null);
    	gimages.majorLanguages = json.major;
    	gimages.minorLanguages = json.minor;
    	gimages.searchLanguages = json.searchable;
    }
    
    // download the searchable languages
    var url = "MajorLanguagesXML";
    AjaxClient.invokeGet(url, false, languageCallback); 
}

function onDocumentLoad_Search() {
	document.getElementById("resultsTable").style.display="none";
	document.getElementById("hideMeWhileSearching").style.display="none";
	document.getElementById("hideMeWhileSearching2").style.display="none";
	
	onDocumentLoad_Always();
	gimages.getEngViaXMLHttp( );
}

function onDocumentLoad_NoSearch() {
	document.getElementById("resultsTable").style.display="none";
	/* advanced interface stuff.  presumed obsolete. ~ono
	 * readded per oren's request */
	if (document.getElementById("advanced").value == "true") {
		document.getElementById("btnShowTranslations1").style.display="none";
		document.getElementById("btnShowTranslations2").style.display="none";
	}
	/**/
	onDocumentLoad_Always();
}

function printSearchLanguageOptions() {
	for (var i = 0; i < gimages.searchLanguages.length; i++) {
		document.write("<option value=\"" + gimages.searchLanguages[i].id + "\">" + gimages.searchLanguages[i].name + "</option>");
	}
}

/*
 * Search for translations while displaying a "loading..." message.
 */
GImages.prototype.getEngViaXMLHttp = function( ) {
	var messagesDiv = document.getElementById("messagesDiv2");

	messagesDiv.innerHTML = getUIString("loading");

	messagesDiv.style.display="block";

    this.waiting = true;
    var waitTimer = -1;
    var me = this;
    var dots = 0;
    var waitFunc = function( ) {
        if ( me.waiting && dots <= 85) {
        	messagesDiv.innerHTML += ".";
        	dots++;
        } else {
        	if (dots > 85)
        		// This error message isn't strictly true.  The website
        		// will continue to wait for the transaction to complete
        		// but, since it probably won't, it's nice to tell the
        		// client something went wrong.
        		messagesDiv.innerHTML += "connection timed out!"
 
        	window.clearInterval(waitTimer);
        	waitTimer = -1;
        }
    }
    waitTimer = window.setInterval(waitFunc, 500);

   	gimages.searchForTranslation();
}

/*
 * Retrieve possible word senses
 */
GImages.prototype.searchForTranslation = function( ) {    	
    var encodedWord = encodeURIComponent( gimages.sourceWord );
    //var deepSearch = document.searchPanel.isDeepSearch();

/* old main results.  obsolete.  ~ono 8/6/2008  
    var url = "WiktionaryWrapper?word=" + encodedWord + "&sourceLanguage=" + gimages.langID + (deepSearch ? "&maxPathLength=3&minWordProbability=0.55" : "");

   	if ( document.debugParameters ) {
   		for ( var i = 0; i < document.debugParameters.length; i++ ) {
   			if ( document.debugParameters[i].checkbox.checked )
	   			url += "&" + document.debugParameters[i].key + "=" + encodeURIComponent(document.debugParameters[i].textbox.value);
   		}
   	}
*/  	
	var url = "GetSenses?word="+encodedWord+"&language="+gimages.langID;
    url += "&stamp=" + (new Date()).getTime();
    AjaxClient.invokeGet(url, true, this.onTranslationComplete);
}

/*
 * Process the retrieved word senses; if none exist, check for other translations
 */
GImages.prototype.onTranslationComplete = function( responseText ) {
	try {

		// should exclude special commands for cache --updated 6/17/2007 by Tian Sang
		if (responseText.substr(0, 7) == 'Message') {
			var messagesDiv = document.getElementById("messagesDiv2");
			messagesDiv.innerHTML = "<p>" + responseText + ".</p><br>\n";
			return;
		}
		
		gimages.info = responseText.parseJSON(null);
				
		// Something went wrong.  Let's abort without printing an
		// error message because this is probably just a back button
		// press or a similar interrupt
		if (gimages.info == null || gimages.info.senses == null) {
			return;
		}	
		
		gimages.info.other = null;
		
		if (gimages.info.senses.length == 0) {
			//If no PanDictTranslations are found, check for other translations		
   			showOtherTranslations();		
	
			// If no translations are found:
			// Ask if the user want to add the word.
			if (gimages.info.other.length == 0) {
				document.getElementById("messagesDiv2").innerHTML="";
				var messagesDiv = document.getElementById("messagesDiv");
				messagesDiv.innerHTML="";
				if(gimages.sourceWord.trim().search(/ /)!=-1) {
					messagesDiv.innerHTML = "<p><font color='red'>"+getUIString("multiwordMessage")+"</font></p>";
				}
				if(gimages.langID==-1) {
					messagesDiv.innerHTML += "<p>"+getUIString("cannotFindWord").replace("[word]",gimages.sourceWord)+"<br />" /*+
											getUIString("addWordQuestion")+" "+
											"<span id='AddNewWord' style='cursor:pointer;text-decoration:underline;color:blue'>"+getUIString("yes")+"</span>&nbsp; " +
											"<span id='CancelAddNewWord' style='cursor:pointer;text-decoration:underline;color:blue'>"+getUIString("no")+"</span></p>"*/;
				} else {
					messagesDiv.innerHTML += "<p>"+getUIString("cannotFindWordInLanguage").replace("[word]",gimages.sourceWord).replace("[language]",gimages.languageName)+"<br />" /*+
											getUIString("addWordQuestion")+" "+
											"<span id='AddNewWord' style='cursor:pointer;text-decoration:underline;color:blue'>"+getUIString("yes")+"</span>&nbsp; " +
											"<span id='CancelAddNewWord' style='cursor:pointer;text-decoration:underline;color:blue'>"+getUIString("no")+"</span></p>"*/;
				}
				
				return;
			} else {
				document.getElementById("editMeanings").style.display = "none";
			}
		}
		
		// We have senses, so iterate through them and build html
		else {
			showResults();
		}
		
		document.getElementById("loginBar").style.display = "";

	} catch (e) {
	    gimages.waiting = false;	// I don't think this is needed
	    throw e;
	    window.alert(x.message +" 4225");
	}
}

/*does not appear to actually be called from anywhere. presumed obsolete. ~ono
GImages.prototype.onOKTranslationComplete = function( responseText ) {
	try {
		gimages.waiting = false;

		gimages.info = responseText.parseJSON(null);
		
		// Something went wrong.  Let's abort without printing an
		// error message because this is probably just a back button
		// press or a similar interrupt
		if (gimages.info == null || gimages.info.senses == null) {
			return;
		}

		var addWord = document.addLanguagePanelEnd.getQueryText();
		var addLanguageID = document.addLanguagePanelEnd.getSearchLanguageID();
		
		// var displayLanguage = document.getElementById("displang").childNodes[0].data;

		var sourceLanguageID = gimages.langID;
		var word = gimages.sourceWord;
			
		//We remove the "other translations" sense (we assume it is the last sense)
		var hasOtherTranslations = false;
		for(var i=0; i<gimages.info.senses.length; i++) {
			if(gimages.info.senses[i].is_garbage==true) {
				hasOtherTranslations = true;				
			}
		}
		if(hasOtherTranslations) gimages.info.senses.splice(gimages.info.senses.length-1, 1);
			
		if (gimages.info.senses.length <=1) {
			
		    if(gimages.info.senses.length == 0) {
		    	//The translation does not occur in any MegaSense other than possibly the "other translations" sense.
		    	//So we create a new sense.
		    	gimages.AJAXURLs.push(createURLAddNewSense(addWord, addLanguageID, word, sourceLanguageID));
		    }
		    else {
		    	if(gimages.info.senses[0].size > 2) {
		    		//The translation occurs in only one MegaSense (other than possibly the "other translations" sense)
		    		//This MegaSense has a dominant sense larger than size 2, so we add the new translation to that sense.
		    		gimages.AJAXURLs.push(createURLAddTranslation(addWord, addLanguageID, word, sourceLanguageID, gimages.info.senses[0].senseID));
		    	}
		    	else {
		    		//The translation occurs in only one MegaSense (other than possibly the "other translations" sense)
		    		//This MegaSense has a dominant sense size <= 2, so we create a new sense using the hack.
		    		gimages.AJAXURLs.push(createURLAddHack(addWord, addLanguageID, word, sourceLanguageID, gimages.info.senses[0]));
		    	}
		    }
	    	gimages.whenAJAXDone = reloadPage;
	    	doAJAX();
			return;	
			
		}
		else {
			var okTranslationSpan = document.getElementById("OKTranslation");
			if(okTranslationSpan.style.color=="black") return; //make sure "yes" is only active when blue
			okTranslationSpan.style.color="black";
			okTranslationSpan.style.textDecoration="none";
			okTranslationSpan.style.cursor="text";
			var cancelTranslationSpan = document.getElementById("CancelTranslation");
			cancelTranslationSpan.style.color="black";
			cancelTranslationSpan.style.textDecoration="none";
			cancelTranslationSpan.style.cursor="text";
			
			var temp = document.getElementById("cmbAddMissingLanguagePanel");
			temp.disabled=true;
			temp = document.getElementById("txtAddMissingLanguagePanel");
			temp.disabled=true;

			var statusMessage = document.getElementById("statusMessage");
				statusMessage.innerHTML=getUIString("selectSense");
				statusMessage.style.color="red";

			var messagesDiv = document.getElementById("messagesDiv");
			temp = document.createElement("div");
			temp.innerHTML=								
				"<span id='ChooseWordSenseMessage'>"+getUIString("addWordToSense").replace("[word1]",word).replace("[word2]",addWord)+"</span>" +
				"	<span id='FinalOK' style='cursor:pointer;text-decoration:underline;color:blue'>"+getUIString("ok")+"</span>&nbsp; " +
				"	<span id='FinalCancel' style='cursor:pointer;text-decoration:underline;color:blue'>"+getUIString("cancel")+"</span>" +
				"	<span id='alertMessage' style='color:red' />";
					
			messagesDiv.appendChild(temp);
		}			
		
		// We have senses, so iterate through them and build html
		showWhichSense();
		
	} catch (x) {
	    gimages.waiting = false;	// I don't think this is needed
	    window.alert(x.message +" 4225");
	}
}
*/

/* creates results tables for all senses. old version, not in use.  ~ono 8/11/2008
function showResults() {
	try {
		var sensesPanel1 =
			"\t\t\t\t\t\t\t\t\t<table class='ks-List' cellpadding='0' cellspacing='0'>\n" +
			"\t\t\t\t\t\t\t\t\t<tbody>\n";
		var sensesTable = new StringBuffer();
		var sensesPanel2 =
			"\t\t\t\t\t\t\t\t\t</tbody>\n" +
			"\t\t\t\t\t\t\t\t\t</table>\n";
		var hiddenMajorTranslationTables = new StringBuffer();
		var hiddenAllTranslationTables = new StringBuffer();
		//translations to be checked
		var hiddenNewTranslationTables = new StringBuffer();
				
		var initialDisplaySense = 0;
		
		var search_one = getUIString("SearchImagesWithOneTranslation");
		var add_translation = getUIString("addTranslation");
		var x_translations_string = getUIString("XTranslations");
		var cls = "ks-SinkItem";
					
		for ( var senseIndex = 0; senseIndex < gimages.info.senses.length; senseIndex++ ) {
			gimages.maxLanguageLength[senseIndex]=0;
			gimages.numMoreTranslations[senseIndex]=0;
			gimages.info.senses[senseIndex].senseIndex = senseIndex;
			var sense = gimages.info.senses[senseIndex];
			if(gimages.initialSense != undefined && gimages.initialSense == sense.senseID) 
				initialDisplaySense=senseIndex;
			var x_translations = x_translations_string.replace("[X]", sense.translationCount); 	
			sensesTable.append(
				"\t\t\t\t\t\t\t\t\t\t<tr>\n" +
				"\t\t\t\t\t\t\t\t\t\t\t<td style='vertical-align: top;' align='left'>\n" +
				"\t\t\t\t\t\t\t\t\t\t\t\t<div id='sense" + senseIndex + "LinkDiv' style='position: static; cursor:default' class='" + cls + "'> " +
				"<a href='javascript: if (gimages.currentlyDisplayedState != " + senseIndex + ") displaySense(" + senseIndex + ");'> " +
				(senseIndex + 1) + ". " + ((sense.description == null || sense.description =="null") ? "   " : sense.description) + 
				" (" + x_translations + ")</a></div>\n" +
				"\t\t\t\t\t\t\t\t\t\t\t</td>\n" +
				"\t\t\t\t\t\t\t\t\t\t</tr>\n");
			
			var majorTranslationsForSense = new StringBuffer(
				"<div id='s" + senseIndex + "MajorTranslations' style='white-space: normal; display: none;' class='gwt-HTML'>\n" + 
				"\t<table id='s" + senseIndex + "MajorTranslationsTable' class='sense-table'>\n" +
				"\t<tbody>\n");

			var allTranslationsForSense = new StringBuffer(
				"<div id='s" + senseIndex + "AllTranslations' style='white-space: normal; display: none;' class='gwt-HTML'>\n" +
				"\t<table id='s" + senseIndex + "AllTranslationsTable' class='sense-table' style='width:100%'>\n" +
				"\t<tbody>\n");
				
			//translations to be checked for this sense	
/* "translations to check" pane not in use.  ~ono 7/21/2008
			var newTranslationsForSenseShort = new StringBuffer(
				"<div id='s" + senseIndex + "NewTranslationsShort' style='white-space: normal; display: none;' class='gwt-HTML'>\n" +
				"\t<table id='s" + senseIndex + "NewTranslationsShortTable' class='sense-table' style='width:100%;'>\n" +
				"\t<tbody>\n");
*\/
				
			//var doneChecking = false;
			for ( var languageIndex = 0; languageIndex < sense.standard.length; languageIndex++ ) {
				gimages.info.senses[senseIndex].standard[languageIndex].senseIndex = senseIndex;
				gimages.info.senses[senseIndex].standard[languageIndex].languageIndex = languageIndex;
				var language = sense.standard[languageIndex];

				var translationsString = new StringBuffer();

				//Determine whether this is a "major" or "minor" language (or neither)
				var inMajor = false, ar = gimages.majorLanguages, val = language.id;
				for (var i = 0; i < ar.length; i++) {
					if (ar[i].id == val) {
						inMajor = true;
						break;
					}
				}
				var inMinor = false, ar = gimages.minorLanguages, val = language.id;
				if (!inMajor){
					for (var i = 0; i < ar.length; i++) {
						if (ar[i].id == val) {
							inMinor = true;
							break;
						}
					}
				}
				
				//Counting the number of other translations in the sense that we aren't displaying.
				if( !inMajor && !inMinor ) {
					gimages.numMoreTranslations[senseIndex]++;
				}
				
				
				//This finds the length of the longest language in the "All Languages" section
				if ( inMinor ) {
					if(language.englishName.length>gimages.maxLanguageLength[senseIndex]) 
						gimages.maxLanguageLength[senseIndex]=language.englishName.length;
				}

				for ( var translationIndex = 0; translationIndex < language.translations.length; translationIndex++) {				
					gimages.info.senses[senseIndex].standard[languageIndex].translations[translationIndex].senseIndex = senseIndex;
					gimages.info.senses[senseIndex].standard[languageIndex].translations[translationIndex].languageIndex = languageIndex;
					gimages.info.senses[senseIndex].standard[languageIndex].translations[translationIndex].translationIndex = translationIndex;
					var translation = language.translations[translationIndex];
					if( inMinor || inMajor ) {
						translationsString.append("\t\t<tr>\n");
					} else {
						translationsString.append("\t\t<tr class='other' style='display:none'>\n");
					}
					if ( translationIndex == 0 ) {
						translationsString.append(
							"\t\t\t<td class='translation-language'><span id='s" + senseIndex + "l" + languageIndex + "'><nobr>" + language.englishName + "</nobr></span></td>\n");
					} else {
						translationsString .append(
							"\t\t\t<td class='translation-language'>&nbsp;</td>\n");
					}
					// preselect appropriate translation
					//I don't know how to make check= true work, so instead I'm doing checked which I know experimentally
					//works. Temporary fix/hack.
					var checked = "";
					
					// if we have not yet made our one default check and the current language
					/*if (!doneChecking) { 
						var searchLang = gimages.queryParams["lang"];
						
						// see if the language is a major language
						// but not the current language
						
						
						var checkMajor = false, ar = gimages.majorLanguages, lang = language.language, langId = searchLang;
						

						for (var i = 0; i < ar.length; i++) {
							if (ar[i].name == lang && ar[i].id != langId || gimages.info.senses[0].languages.length==1) {
								checkMajor = true;
								break;
							}
						}
				
						if (checkMajor) {
							checked = "checked";
							// doneChecking = true; // don't do any more
						}
						
					}
					*\/
					
					var singleTransQuery =	"searchLang="+gimages.langID+
											"&searchTerm="+encodeURIComponent(gimages.sourceWord)+
											"&showLang="+language.id+
											"&showTerm="+encodeURIComponent(translation.translation)+
											"&senseIndex="+senseIndex+
											"&previous=" + encodeURIComponent("GImages.jsp?word="+gimages.sourceWord+"&lang="+gimages.langID);

					translationsString.append(
						"\t\t\t<td class='translation-value'>" +
						"<table style='width: 100%;' cellpadding='2' cellspacing='0'><tbody><tr>" +
						"<td style='width:100%'>" +
						/*advanced interface stuff. obsolete ~ono 7/31/2008
						 * readded per Oren's request ~chris
						 */
						/*(gimages.advanced ? "<input id='s" + senseIndex + "l" + languageIndex + "t" + translationIndex + "checkbox' type='checkbox' " + checked + " >" : "") +

						"<a class='translation-span' href=\"showresults.jsp?"+singleTransQuery+"\" title='" + search_one + "' id='s" 
							+ senseIndex + "l" + languageIndex + "t" + translationIndex + "'>" 
							+ translation.translation +
						"</a>" +
						"</td>"); */
						/* old translation editing.  ~ono 7/31/2008				
						"<td style='text-align:right;'>" +
						"<nobr><span id='s" + senseIndex + "l" + languageIndex + "t" + translationIndex + "ConfirmRemoveTranslation' style='cursor:pointer;text-decoration:underline;color:blue;display:none'>"+getUIString("ok")+"</span>" +
						"<WBR><span id='s" + senseIndex + "l" + languageIndex + "t" + translationIndex + "Space' style='display:none'>&nbsp;&nbsp;</span><WBR>" +
						"<span id='s" + senseIndex + "l" + languageIndex + "t" + translationIndex + "CancelRemoveTranslation' style='cursor:pointer;text-decoration:underline;color:blue;display:none'>"+getUIString("cancel")+"</span></nobr>" +
						"</td>" +
						
						"<td style='text-align:right'>"*\/
						
					/* old translation editing ~ono 7/31/2008
					if(gimages.langID != language.id || gimages.sourceWord != translation.translation) {
						translationsString.append("<span id='s" + senseIndex + "l" + languageIndex + "t" + translationIndex + "RemoveTranslation' class='RemoveTranslation' style='color:#FF7777;cursor:pointer;display:none' title='"+getUIString("removeTranslation")+"'>X</span>");
					}
					*\/
					translationsString.append(
						/*"</td>" +*\/
						"</tr></tbody></table>" +
						"</td>\n");
					translationsString.append("\t\t</tr>\n");						
				}
				
				if ( inMajor ) {
					majorTranslationsForSense.append(translationsString.toString());
				} else {
					allTranslationsForSense.append(translationsString.toString());
				}
			}
			
			//checkTranslationsShort
/* "translations to check" pane not in use.  ~ono  7/21/2008
			for (var translationIndex = 0; translationIndex < sense.checkShort.length; translationIndex++){
				var language = sense.checkShort[translationIndex].language;
				var translationsString = new StringBuffer();		
				var translation = sense.checkShort[translationIndex].translation;
				
				translationsString.append(
								"\t\t\t<td class='translation-language'><span id='s" + senseIndex + "l" + languageIndex + "'><nobr>" + language.englishName + "</nobr></span></td>\n");
				
				var search_one = getUIString("SearchImagesWithOneTranslation");
					
				var singleTransQuery =	"searchLang="+gimages.langID+
										"&searchTerm="+encodeURIComponent(gimages.sourceWord)+
										"&showLang="+language.id+
										"&showTerm="+encodeURIComponent(translation)+
										"&senseIndex="+senseIndex+
										"&previous=" + encodeURIComponent("GImages.jsp?word="+gimages.sourceWord+"&lang="+gimages.langID);
				translationsString.append(
					"\t\t\t<td class='translation-value'>" +
					"<table style='width: 100%;' cellpadding='2' cellspacing='0'><tbody><tr>" +
					"<td style='width:100%'>" +
					"<a class='translation-span' href=\"showresults.jsp?"+singleTransQuery+"\" title='" + search_one + "' " +
					"id='s" + senseIndex + "t" + translationIndex + "'>" + translation + "" +
					"</a>" +
					"</td>" +
					"<td style='text-align:right;'>" +
					"<nobr><span id='s" + senseIndex + "t" + translationIndex + "ConfirmRemoveTranslation' style='cursor:pointer;text-decoration:underline;color:blue;display:none'>"+getUIString("ok")+"</span>" +
					"<WBR><span id='s" + senseIndex + "t" + translationIndex + "Space' style='display:none'>&nbsp;&nbsp;</span><WBR>" +
					"<span id='s" + senseIndex + "t" + translationIndex + "CancelRemoveTranslation' style='cursor:pointer;text-decoration:underline;color:blue;display:none'>"+getUIString("cancel")+"</span></nobr>" +
					"</td>" +
					"<td style='text-align:right'>");
				translationsString.append(
					"</td>" +
					"</tr></tbody></table>" +
					"</td>\n");
				translationsString.append("\t\t</tr>\n");
			
				newTranslationsForSenseShort.append(translationsString);
			}
*\/			

			
			majorTranslationsForSense.append(
				"<tr id='s"+senseIndex+"AddTranslationEndRow1'>\n" +
					"<td class='translation-language' id='s"+senseIndex+"OtherLanguageLanguage1'>" +
						"<span id='s"+senseIndex+"OtherLanguageSpan1' style='text-decoration:underline;color:blue;cursor:pointer;'>" +
							"<nobr>"+add_translation+"</nobr>" +
						"</span>" +
					"</td>\n" +
					"<td class='translation-value' id='s"+senseIndex+"OtherLanguageTranslation1' style='width:100%'>&nbsp;" +
					"</td>" +
				"</tr>\n");
				
			allTranslationsForSense.append(
				"<tr id='s"+senseIndex+"AddTranslationEndRow2'>\n" +
					"<td class='translation-language' id='s"+senseIndex+"OtherLanguageLanguage2'>" +
						"<span id='s"+senseIndex+"OtherLanguageSpan2' style='text-decoration:underline;color:blue;cursor:pointer;'>" +
							"<nobr>"+add_translation+"</nobr>" +
						"</span>" +
					"</td>\n" +
					"<td class='translation-value' id='s"+senseIndex+"OtherLanguageTranslation2' style='width:100%'>&nbsp;" +
					"</td>" +
				"</tr>\n");
/* "translations to check" pane not in use.  ~ono 7/21/2008
			newTranslationsForSenseShort.append(
				"<tr id='s"+senseIndex+"AddTranslationEndRow3'>\n" +
					"<td class='translation-language' id='s"+senseIndex+"OtherLanguageLanguage3'>" +
						"<span id='s"+senseIndex+"OtherLanguageSpan3' style='text-decoration:underline;color:blue;cursor:pointer;'>" +
							"<nobr>"+getUIString("addTranslation")+"</nobr>" +
						"</span>" +
					"</td>\n" +
					"<td class='translation-value' id='s"+senseIndex+"OtherLanguageTranslation3' style='width:100%'>&nbsp;" +
					"</td>" +
				"</tr>\n");
*\/
			
			majorTranslationsForSense.append(
				"\t</tbody>\n" +
				"\t</table>\n" +
				"</div>\n");
			allTranslationsForSense.append(
				"\t</tbody>\n" +
				"\t</table>\n" +
				"</div>\n");
/* "translations to check" pane not in use. ~ono  7/21/2008
			newTranslationsForSenseShort.append(
				"\t</tbody>\n" +
				"\t</table>\n" +
				"</div>\n");
*\/			
			hiddenMajorTranslationTables.append(majorTranslationsForSense.toString());
			hiddenAllTranslationTables.append(allTranslationsForSense.toString());
			//hidden table of new translations
/* "translations to check" pane not in use.  ~ono  7/21/2008
			hiddenNewTranslationTables.append(newTranslationsForSenseShort.toString());
*\/			
			
			if(gimages.numMoreTranslations[senseIndex]<4 || gimages.maxLanguageLength[senseIndex]==0) {
				gimages.showingMoreTranslations[senseIndex]=-1;
			} else {
				gimages.showingMoreTranslations[senseIndex]=0;
			}
			gimages.checkingMoreTranslations[senseIndex]=0;
		}
		
		sensesTable.append(
				"\t\t\t\t\t\t\t\t\t\t<tr>\n" +
				"\t\t\t\t\t\t\t\t\t\t\t<td style='vertical-align: top;' align='left'>\n" +
				"\t\t\t\t\t\t\t\t\t\t\t\t<div id='sense" + senseIndex + "LinkDiv' style='position: static; cursor:default' class='" + cls + "'> " +
				"<a href='javascript: if (gimages.currentlyDisplayedState != " + senseIndex + ") showOtherTranslations();'> " +
				(senseIndex + 1) + ". " + getUIString("OtherTranslations") +"</a></div>\n" +
				"\t\t\t\t\t\t\t\t\t\t\t</td>\n" +
				"\t\t\t\t\t\t\t\t\t\t</tr>\n");
		
		var sensesPanel = sensesPanel1 + sensesTable.toString() + sensesPanel2;

		var sensesHolder = document.getElementById("sensesHolder");
		var majorTranslationsHolder = document.getElementById("majorTranslationsHolder");
		var allTranslationsHolder = document.getElementById("allTranslationsHolder");
		var newTranslationsHolder = document.getElementById("newTranslationsHolder");
		var resultsTable = document.getElementById("resultsTable");
		
		// Actually render the html	
		sensesHolder.innerHTML = sensesPanel;
		majorTranslationsHolder.innerHTML = hiddenMajorTranslationTables.toString();
		allTranslationsHolder.innerHTML = hiddenAllTranslationTables.toString();
		newTranslationsHolder.innerHTML = hiddenNewTranslationTables.toString();

		
		/* advanced interface stuff.  obsolete. ~ono
		 * readded per Oren's request ~chris
		 */ /*
		if(gimages.advanced) {
			showAllLanguages();
		} else {
			initializeMoreLanguages();
		}
		if(gimages.advanced) showXs();

		resultsTable.style.visible = ""; */

/*advanced interface stuff.  obsolete. ~ono
 * readded per oren's request */
	/*	//Update the 'onclick' method of all the checkboxes
		if (gimages.advanced) {
			for ( var senseIndex = 0; senseIndex < gimages.info.senses.length; senseIndex++ ) {
				var sense = gimages.info.senses[senseIndex];
				for ( var languageIndex = 0; languageIndex < sense.languages.length; languageIndex++ ) {
					var language = sense.languages[languageIndex];
					for ( var translationIndex = 0; translationIndex < language.translations.length; translationIndex++) {
						var checkboxID = "s" + senseIndex + "l" + languageIndex + "t" + translationIndex + "checkbox";
						var checkbox = document.getElementById(checkboxID);
						checkbox.onclick = onClickCheckbox;
					}
				}
			}
		}
		
		displaySense(initialDisplaySense);

		var messagesDiv = document.getElementById("messagesDiv2");
		messagesDiv.style.display="none";
		//messagesDiv = document.getElementById("messagesDiv");
		//messagesDiv.style.display="none";
		var resultsTable = document.getElementById("resultsTable");
		resultsTable.style.display="block";
		var internationalDiv = document.getElementById("hideMeWhileSearching");
		internationalDiv.style.display="block";
		document.getElementById("hideMeWhileSearching2").style.display="block";

	} catch (x) {
	    gimages.waiting = false;	// I don't think this is needed
	    window.alert(x.message +" 825");
	}
} */
/**/ 

/*
 * Builds the list of senses, displays results for the first
 */
function showResults(){
	var sensesPanel1 =
		"\t\t\t\t\t\t\t\t\t<table class='ks-List' cellpadding='0' cellspacing='0'>\n" +
		"\t\t\t\t\t\t\t\t\t<tbody>\n";
	var sensesTable = new StringBuffer();
	var sensesPanel2 =
		"\t\t\t\t\t\t\t\t\t</tbody>\n" +
		"\t\t\t\t\t\t\t\t\t</table>\n";
	var hiddenMajorTranslationTables = new StringBuffer();	
	
	var x_translations_string = getUIString("XTranslations");
	var initialDisplaySense = 0;
	var cls = "ks-SinkItem";

	//display a maximum of 10 senses
	for ( var senseIndex = 0; senseIndex < gimages.info.senses.length && senseIndex < 10; senseIndex++ ) {
		gimages.info.senses[senseIndex].senseIndex = senseIndex;
				
		var sense = gimages.info.senses[senseIndex];
		if(gimages.initialSense != undefined && gimages.initialSense == sense.id) 
			initialDisplaySense=senseIndex;
			
		var x_translations = x_translations_string.replace("[X]", sense.size);
		//link to display the translations table 	
		sensesTable.append(
			"\t\t\t\t\t\t\t\t\t\t<tr>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t<td style='vertical-align: top;' align='left'>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t\t<div id='sense" + senseIndex + "LinkDiv' style='position: static; cursor:default' class='" + cls + "'> " +
			"<a href='javascript: if (gimages.currentlyDisplayedState != " + senseIndex + ") displaySense(" + senseIndex + ");'> " +
			(senseIndex + 1) + ". " + ((sense.description == null || sense.description =="null") ? "   " : sense.description) + 
			" (" + x_translations + ")</a></div>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t</td>\n" +
			"\t\t\t\t\t\t\t\t\t\t</tr>\n");
			
		//creates a place to fill in the translations table	
		hiddenMajorTranslationTables.append(
				"<div id='s" + senseIndex + "Translations' style='white-space: normal; display: none;' class='gwt-HTML'>\n" + 
				"</div>");
	}
	
	//link to display other translations
	senseIndex = gimages.info.senses.length;
	sensesTable.append(
			"\t\t\t\t\t\t\t\t\t\t<tr>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t<td style='vertical-align: top;' align='left'>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t\t<div id='sense" + senseIndex + "LinkDiv' style='position: static; cursor:default' class='" + cls + "'> " +
			"<a href='javascript: if (gimages.currentlyDisplayedState != " + senseIndex + ") showOtherTranslations();'> " +
			getUIString("OtherTranslations") +"</a></div>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t</td>\n" +
			"\t\t\t\t\t\t\t\t\t\t</tr>\n");
	//link to display more senses			
	if (gimages.info.senses.length > 10) {
			sensesTable.append(
			"<tr>" +
				"<td style='vertical-align: top;' align='left'>" +
					"<div id='moreSenses' style='position:static; cursor:defualt;'>" +
						"(<span style='text-decoration: underline;color: blue;cursor: pointer;' onclick='showMoreSenses()'>"+getUIString("SeeMoreMeanings")+"</span>)" +
					"</div>" +
				"</td>" +
			"</tr>");
	}
	
	//render HTML
	var sensesPanel = sensesPanel1 + sensesTable.toString() + sensesPanel2;
	var sensesHolder = document.getElementById("sensesHolder");
	sensesHolder.innerHTML = sensesPanel;
	
	var majorTranslationsHolder = document.getElementById("majorTranslationsHolder");
	majorTranslationsHolder.innerHTML = hiddenMajorTranslationTables.toString();
	
	var chooseTransLanguage = document.getElementById("checkTransLanguageSelection");
	populateLanguageSelectBox(chooseTransLanguage);
	
	var resultsTable = document.getElementById("resultsTable");
	resultsTable.style.visible = "";

	//display results for first sense
	displaySense(initialDisplaySense);

	//hide messages, show results
	var messagesDiv = document.getElementById("messagesDiv2");
	messagesDiv.style.display="none";
	resultsTable.style.display="block";
	var internationalDiv = document.getElementById("hideMeWhileSearching");
	internationalDiv.style.display="block";
	document.getElementById("hideMeWhileSearching2").style.display="block";
	
	gimages.waiting = false;

}


/* Display results for a sense.  old version, not in use. ~ono 8/11/2008
function displaySense (id) {
	if ( gimages.currentlyDisplayedState != id ) {
		if (document.getElementById("NewTranslationsSingleLang") != null) {			
			document.getElementById("NewTranslationsSingleLang").style.display = "none";
		}
		if(gimages.addingTranslation[0]) {
			cancelAddTranslation(1);
		}
		if(gimages.addingTranslation[1]) {
			cancelAddTranslation(2);
		}
		if (gimages.addingTranslation[2]) {
			cancelAddTranslation(3);
		}
		if (gimages.addingTranslation[3]) {
			cancelAddTranslation(4);
		}
		if (gimages.addingTranslation[4]) {
			cancelAddTranslation(5);
		}
		if(gimages.removingTranslation) 
			cancelRemoveTranslation();
/*		for ( var i = 0; i < gimages.info.senses.length; i++ ) {
			var senseLink = document.getElementById("sense" + i + "LinkDiv");
			var majorSenseTranslations = document.getElementById("s" + i + "MajorTranslations");
			var allSenseTranslations = document.getElementById("s" + i + "AllTranslations");*\/
/* "translations to check" pane not in use.  ~ono 7/21/2008
			var newSenseTranslationsShort = document.getElementById("s" + i + "NewTranslationsShort");
*\/
/*			var newSenseTranslationsLong = document.getElementById("s" + i + "NewTranslationsLong");
			var checkSenseTransLangList = document.getElementById("s"+i+"langList");

			if ( i != id ) {
				removeClass(senseLink, "ks-SinkItem-selected");
				majorSenseTranslations.style.display = "none";
				allSenseTranslations.style.display = "none";*\/
/* "translations to check" pane not in use.  ~ono 7/21/2008				
				newSenseTranslationsShort.style.display = "none";
*\/
/*				if (newSenseTranslationsLong != null) {
					newSenseTranslationsLong.style.display = "none";
					checkSenseTransLangList.style.display = "none";
				}
			}
		}*\/
			
		var currSense = gimages.currentlyDisplayedState;
		if (currSense != undefined && currSense < gimages.info.senses.length && currSense >= 0) {			
			var senseLink = document.getElementById("sense" + currSense + "LinkDiv");
			var majorSenseTranslations = document.getElementById("s" + currSense + "MajorTranslations");
			var allSenseTranslations = document.getElementById("s" + currSense + "AllTranslations");
			var newSenseTranslationsLong = document.getElementById("s" + currSense + "NewTranslationsLong");
			var checkSenseTransLangList = document.getElementById("s"+currSense+"langList");

			removeClass(senseLink, "ks-SinkItem-selected");
			majorSenseTranslations.style.display = "none";
			allSenseTranslations.style.display = "none";
			if (newSenseTranslationsLong != null) {
				newSenseTranslationsLong.style.display = "none";
				checkSenseTransLangList.style.display = "none";
			}
		}
					
		if (id != gimages.info.senses.length && gimages.info.other != null) {
			document.getElementById("OtherTranslations").style.display = "none";
			removeClass(document.getElementById("sense"+gimages.info.senses.length+"LinkDiv"), "ks-SinkItem-selected");
		}
		var senseLink = document.getElementById("sense" + id + "LinkDiv");
		addClass(senseLink, "ks-SinkItem-selected");
		
		var majorSenseTranslations;
		var allSenseTranslations;
		if (id != gimages.info.senses.length){
			majorSenseTranslations = document.getElementById("s" + id + "MajorTranslations");
			allSenseTranslations = document.getElementById("s" + id + "AllTranslations");
/* "translations to check" pane not in use.  ~ono 7/21/2008		
		var newSenseTranslations = document.getElementById("s" + id + "NewTranslationsShort");
*\/
		} else {
			majorSenseTranslations = document.getElementById("OtherTranslations");
		}
		var translationsPanelCaption = document.getElementById("translationsPanelCaption");
		
		
		document.getElementById("majorTranslationsHolder").style.display = "";
		majorSenseTranslations.style.display = "block";
		
		if (id != gimages.info.senses.length) {
			document.getElementById("allTranslationsHolder").style.display = "";
			allSenseTranslations.style.display = "block";
	/* "translations to check" pane not in use.  ~ono 7/21/2008		
			newSenseTranslations.style.display = "block";
	*\/		
			
			var s = getUIString("SenseXOfY");
			var sense_string = s.replace("[X]", (id+1));
			sense_string = sense_string.replace("[Y]", gimages.info.senses.length);
			var sense = gimages.info.senses[id];
			translationsPanelCaption.innerHTML = sense_string + ": " + ((sense.description == null) ? "   " : (sense.description == "null") ? "   " : sense.description);
		}
		else {
			document.getElementById("allTranslationsHolder").style.display = "none";
			translationsPanelCaption.innerHTML = getUIString("OtherTranslations") + " for \""+gimages.sourceWord+"\"";
		} 

		document.getElementById("chooseTransLanguage").style.display = "none";
		document.getElementById("et2").style.display = "none";
		document.getElementById("messagesDiv").style.display = "none";
		document.getElementById("messagesDiv3").style.display = "none";
		if (id != gimages.info.senses.length) {
			document.getElementById("majorLangs").style.display = "";
			document.getElementById("otherLangs").style.display = "";		
			document.getElementById("uncertainLangs").style.display = "";
			document.getElementById("et0").style.display = "";
			document.getElementById("et1").style.display = "";	
		}
		else {
			document.getElementById("majorLangs").style.display = "none";
			document.getElementById("otherLangs").style.display = "none";
			document.getElementById("uncertainLangs").style.display = "none";
			document.getElementById("et0").style.display = "none";
			document.getElementById("et1").style.display = "none";
		}
				
		// Count the number of checked languages
		/*advanced interface stuff.  obsolete. ~ono
		 * readded per oren's request ~chris
		 */ /*
		if (gimages.advanced) {
		    gimages.numTranslationsChecked = 0;
			var sense = gimages.info.senses[id];
			for ( var languageIndex = 0; languageIndex < sense.languages.length; languageIndex++ ) {
				var language = sense.languages[languageIndex];
				for ( var translationIndex = 0; translationIndex < language.translations.length; translationIndex++) {
					var checkboxID = "s" + id + "l" + languageIndex + "t" + translationIndex + "checkbox";
					var checkbox = document.getElementById(checkboxID);
					if ( checkbox && checkbox.checked)
						gimages.numTranslationsChecked++;
				}
			}
			updateSearchCheckedTranslationsButton();
		}
		
		//update the "See more.../See fewer..." text
		if (id != gimages.info.senses.length) {
			var moreLanguages = document.getElementById("moreLanguages");
			if(gimages.showingMoreTranslations[id]==-1) {
				moreLanguages.style.display="none";			
			} else {
				moreLanguages.style.display="";
				var moreLanguagesI = document.getElementById("moreLanguagesI");
				var state;
				if(gimages.showingMoreTranslations[id]==1) {
					state = "";
					moreLanguagesI.innerHTML=getUIString("seeFewer");
				} else {
					state = "none";
					moreLanguagesI.innerHTML=getUIString("seeMore");
				}
			}
			
			var checkMoreTranslations = document.getElementById("checkMoreTranslations");
			checkMoreTranslations.style.display="";
			var checkMoreTranslationsI = document.getElementById("checkMoreTranslationsI");
			if (gimages.checkingMoreTranslations[id]!=0) {
				state = "";
				checkMoreTranslationsI.innerHTML = getUIString("hide");
			} else {
				state = "none";
				checkMoreTranslationsI.innerHTML = getUIString("show");			
			}
		}
		
		if (gimages.showingEditTranslations) {
			cancelEditTranslations();
		}
		
		document.getElementById("checkNextI").style.display = "none";
		document.getElementById("checkPrevI").style.display = "none";
	}
	
	gimages.currentlyDisplayedState = id;
} */
/**/

/*
 * Build the translations table if it doesn't exist, hide the currently displayed results, display the new ones.
 */
function displaySense (id) {
	//if translations table exists
	if (id == gimages.info.senses.length || gimages.info.senses[id].languages != null) {
		var currSense = gimages.currentlyDisplayedState;
		//hide current results
		if (currSense != undefined && currSense < gimages.info.senses.length && currSense >= 0) {			
			var senseLink = document.getElementById("sense" + currSense + "LinkDiv");
			var majorSenseTranslations = document.getElementById("s" + currSense + "Translations");
			var uncertainSenseTranslations = document.getElementById("s" + currSense + "UncertainTranslations");

			removeClass(senseLink, "ks-SinkItem-selected");
			majorSenseTranslations.style.display = "none";
			if (uncertainSenseTranslations != null) {
				uncertainSenseTranslations.style.display = "none";
			}
		} else if (currSense == gimages.info.senses.length) {
			document.getElementById("OtherTranslations").style.display = "none";
			removeClass(document.getElementById("sense"+gimages.info.senses.length+"LinkDiv"), "ks-SinkItem-selected");
		}		
		
		//show requested results
		var senseLink = document.getElementById("sense" + id + "LinkDiv");
		addClass(senseLink, "ks-SinkItem-selected");
		
		
		var majorSenseTranslations;
		if (id < gimages.info.senses.length){
			majorSenseTranslations = document.getElementById("s" + id + "Translations");
		} else {
			majorSenseTranslations = document.getElementById("OtherTranslations");
		}
		
		document.getElementById("majorTranslationsHolder").style.display = "";
		majorSenseTranslations.style.display = "block";
		
		//set results panel caption
		var translationsPanelCaption = document.getElementById("translationsPanelCaption");
		
		if (id != gimages.info.senses.length) {	
			var sense_string = getUIString("SenseXOfY").replace("[X]", (id+1)).replace("[Y]", gimages.info.senses.length);
			var sense = gimages.info.senses[id];
			translationsPanelCaption.innerHTML = sense_string + ": " + sense.description;
		}
		else {
			translationsPanelCaption.innerHTML = getUIString("OtherTranslationsFor").replace("[Word]", "\""+gimages.sourceWord+"\"" );
		} 

		if (gimages.showingEditTranslations) {
			cancelEditTranslations();
		}
		
		//show and hide labels as appropriate
		if (id != gimages.info.senses.length) {
			document.getElementById("majorLangs").style.display = "";
			if (gimages.showingMoreTranslations[id] == 1 || gimages.info.senses[id].size < 50) {
				document.getElementById("moreLanguages").style.display = "none";				
			} else {
				document.getElementById("moreLanguages").style.display = "";				
			}
			document.getElementById("et0").style.display = "";		
			document.getElementById("uncertainLangs").style.display = "";
			document.getElementById("et2").style.display = "";
			document.getElementById("chooseTransLanguage").style.display = "";
			document.getElementById("uncertainTranslationsHolder").style.display = "none";		
			document.getElementById("checkTransLanguageSelection").options[0].selected = "true";
		} else {
			document.getElementById("majorLangs").style.display = "none";
			document.getElementById("moreLanguages").style.display = "none";
			document.getElementById("et0").style.display = "none";
			document.getElementById("uncertainLangs").style.display = "none";
			document.getElementById("et2").style.display = "none";
			document.getElementById("chooseTransLanguage").style.display = "none";
			document.getElementById("uncertainTranslationsHolder").style.display = "none";	
		}
		
		gimages.currentlyDisplayedState = id;
		
	}
	
	//build translations table if it does not already exist 
	else {
		getSomeTranslations(id);
	}
}

/*
 * Retrieve some specified number of likely translations, build the results table, and display the results
 */
function getSomeTranslations(id) {
	var url = "GetSomeTranslations?sense="+gimages.info.senses[id].id;	
    url += "&stamp=" + (new Date()).getTime();
	var response = AjaxClient.invokeGet(url, false, null);
	gimages.info.senses[id].languages = response.parseJSON(null);
	processTranslations(id);
	displaySense(id);
}

/*
 * Retrieve all likely translations, build the results table, and display the results
 */
function getAllTranslations(id) {
	var url = "GetAllTranslations?sense="+gimages.info.senses[id].id;
    url += "&stamp=" + (new Date()).getTime();
	var response = AjaxClient.invokeGet(url, false, null);
	gimages.info.senses[id].languages = response.parseJSON(null);
	processTranslations(id);
	gimages.showingMoreTranslations[id] = 1;
	document.getElementById("moreLanguages").style.display = "none";
}

/*
 * Build table of translations
 */
function processTranslations(id) {
	var sense = gimages.info.senses[id];
	var senseTable = new StringBuffer(
		"\t<table id='s" +id+"TranslationsTable' " +
		"class='sense-table' style='width:100%;'>\n" +
		"\t<tbody>\n");
	
	//frequently used UI strings	
	var search_one = getUIString("SearchImagesWithOneTranslation");
	var add_translation = getUIString("addTranslation");
	
	for ( var languageIndex = 0; languageIndex < sense.languages.length; languageIndex++ ) {
		var language = sense.languages[languageIndex];	
		language.senseIndex = id;
		language.languageIndex = languageIndex;		
		
		var translationsString = new StringBuffer();

		//each translations gets a row; first translation in a language also labeled with language name
		for ( var translationIndex = 0; translationIndex < language.translations.length; translationIndex++) {
			var translation = language.translations[translationIndex];
			
			translation.senseIndex = id;
			translation.languageIndex = languageIndex;
			translation.translationIndex = translationIndex;
			
			translationsString.append("\t\t<tr>\n");
			if ( translationIndex == 0 ) {
				translationsString.append( 
					"\t\t\t<td class='translation-language'><span id='s" + id + "l" + languageIndex + "'><nobr>" + language.englishName + "</nobr></span></td>\n");
			} else {
				translationsString .append(
					"\t\t\t<td class='translation-language'>&nbsp;</td>\n");
			}

			//link to show images for this translation				
			var singleTransQuery =	"searchLang="+gimages.langID+
									"&searchTerm="+encodeURIComponent(gimages.sourceWord)+
									"&showLang="+language.id+
									"&showTerm="+encodeURIComponent(translation.translation)+
									"&senseIndex="+id+
									"&previous=" + encodeURIComponent("GImages.jsp?word="+gimages.sourceWord+"&lang="+gimages.langID);

			translationsString.append(
				"\t\t\t<td class='translation-value'>" +
				"<table style='width: 100%;' cellpadding='2' cellspacing='0'><tbody><tr>" +
				"<td style='width:100%'>" +
				"<a class='translation-span' href=\"showresults.jsp?"+singleTransQuery+"\" title='" + search_one + "' id='s" 
					+ id + "l" + languageIndex + "t" + translationIndex + "'>" 
					+ translation.translation + "" +
				"</a>" +
				"</td>" +
				"<td style='text-align:right'>");
		
			translationsString.append(
				"</td>" +
				"</tr></tbody></table>" +
				"</td>\n");
			translationsString.append("\t\t</tr>\n");					
		}
		senseTable.append(translationsString);
	}	
	//link to add a translation
	senseTable.append(
		"<tr id='s"+id+"AddTranslationEndRow1'>\n" +
			"<td class='translation-language' id='s"+id+"OtherLanguageLanguage1'>" +
				"<span id='s"+id+"OtherLanguageSpan1' style='text-decoration:underline;color:blue;cursor:pointer;'>" +
					"<nobr>"+add_translation+"</nobr>" +
				"</span>" +
			"</td>\n" +
			"<td class='translation-value' id='s"+id+"OtherLanguageTranslation1' style='width:100%'>&nbsp;" +
			"</td>" +
		"</tr>\n");

	senseTable.append(
		"\t</tbody>\n" +
		"\t</table>\n");
		
	//render HTML
	document.getElementById("s"+id+"Translations").innerHTML = senseTable.toString();
}

/*
 * Show list of other translations
 */
function showOtherTranslations() {
	//build the table of other translations if it doesn't exist
	if (document.getElementById("OtherTranslations") == null){
   		var encodedWord = encodeURIComponent( gimages.sourceWord );
		var url = "GetOtherTranslations?word=" + encodedWord + "&language=" + gimages.langID
		url += "&stamp=" + (new Date()).getTime();
		AjaxClient.invokeGet(url, false, gimages.processOtherTranslations);
	}
	
	//do nothing if no results are returned
	if (gimages.info.other.length == 0) {
		return;
	}
	//if there are no PanDictTranslations
	else if (gimages.info.senses.length == 0) {
		var senseIndex = gimages.info.senses.length;	
		var cls = "ks-SinkItem";
		var sensesPanel1 =
			"\t\t\t\t\t\t\t\t\t<table class='ks-List' cellpadding='0' cellspacing='0'>\n" +
			"\t\t\t\t\t\t\t\t\t<tbody>\n";
		var sensesTable = new StringBuffer();
		var sensesPanel2 =
			"\t\t\t\t\t\t\t\t\t</tbody>\n" +
			"\t\t\t\t\t\t\t\t\t</table>\n";	
		sensesTable.append(
			"\t\t\t\t\t\t\t\t\t\t<tr>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t<td style='vertical-align: top;' align='left'>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t\t<div id='sense" + senseIndex + "LinkDiv' style='position: static; cursor:default' class='" + cls + "'> " +
			"<a href='javascript: if (gimages.currentlyDisplayedState != " + senseIndex + ") showOtherTranslations();'> " +
			(senseIndex + 1) + ". " + getUIString("OtherTranslations") +"</a></div>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t</td>\n" +
			"\t\t\t\t\t\t\t\t\t\t</tr>\n");
		
		var sensesPanel = sensesPanel1 + sensesTable.toString() + sensesPanel2;

		var sensesHolder = document.getElementById("sensesHolder");
		sensesHolder.innerHTML = sensesPanel.toString();
		
	}
	document.getElementById("resultsTable").style.display = "";
	displaySense(gimages.info.senses.length);
	document.getElementById("messagesDiv2").style.display = "none";			
	
	//hide the "Translations to be checked" labels
	hideUncertainResults();
}

/*
 * Build the table of other translations
 */
GImages.prototype.processOtherTranslations = function( responseText ) {
	gimages.waiting = false;
	gimages.info.other = responseText.parseJSON(null);
	
	//if there are no results, do nothing
	if (gimages.info.other.length == 0) {
		return;
	}
	
	
	var otherTranslations = new StringBuffer(
				"<div id='OtherTranslations' style='white-space: normal; display: none;' class='gwt-HTML'>\n" +
				"\t<table id='OtherTranslationsTable' class='sense-table' style='width:100%'>\n" +
				"\t<tbody>\n");		
				
	var search_one = getUIString("SearchImagesWithOneTranslation");
	
	for ( var languageIndex = 0; languageIndex < gimages.info.other.length; languageIndex++ ) {
		var language = gimages.info.other[languageIndex];

		var translationsString = new StringBuffer();

		//each translations gets a row; first translation in a language also labeled with language name
		for ( var translationIndex = 0; translationIndex < language.translations.length; translationIndex++) {		
			var translation = language.translations[translationIndex];
			if ( translationIndex == 0 ) {
				translationsString.append(
					"\t\t\t<td class='translation-language'><span id='l" + languageIndex + "'><nobr>" + language.englishName + "</nobr></span></td>\n");
			} else {
				translationsString .append(
					"\t\t\t<td class='translation-language'>&nbsp;</td>\n");
			}

			//link to view images of this word
			var singleTransQuery =	"searchLang="+gimages.langID+
									"&searchTerm="+encodeURIComponent(gimages.sourceWord)+
									"&showLang="+language.id+
									"&showTerm="+encodeURIComponent(translation.translation)+
									"&senseIndex="+gimages.info.senses.length+
									"&previous=" + encodeURIComponent("GImages.jsp?word="+gimages.sourceWord+"&lang="+gimages.langID);

			translationsString.append(
				"\t\t\t<td class='translation-value'>" +
				"<table style='width: 100%;' cellpadding='2' cellspacing='0'><tbody><tr>" +
				"<td style='width:100%'>" +
				"<a class='translation-span' href=\"showresults.jsp?"+singleTransQuery+"\" title='" + search_one + "' id='"+
				 "l" + languageIndex + "t" + translationIndex + "'>" 
					+ translation.translation +
				"</a>" +
				"</td>");

			translationsString.append(
				"</tr></tbody></table>" +
				"</td>\n");
			translationsString.append("\t\t</tr>\n");						
		}
		
		otherTranslations.append(translationsString.toString());
	}			
	otherTranslations.append(
		"\t</tbody>\n" +
		"\t</table>\n" +
		"</div>\n");
		
	//render HTML
	document.getElementById("majorTranslationsHolder").innerHTML += otherTranslations.toString();
}

/*
 * Display additional likely senses.
 */
function showMoreSenses(){
	var sensesPanel1 =
		"\t\t\t\t\t\t\t\t\t<table class='ks-List' cellpadding='0' cellspacing='0'>\n" +
		"\t\t\t\t\t\t\t\t\t<tbody>\n";
	var sensesTable = new StringBuffer();
	var sensesPanel2 =
		"\t\t\t\t\t\t\t\t\t</tbody>\n" +
		"\t\t\t\t\t\t\t\t\t</table>\n";
		
	var hiddenMajorTranslationTables = new StringBuffer();
	
	var x_translations_string = getUIString("XTranslations");
	var cls = "ks-SinkItem";
	
	for ( var senseIndex = 0; senseIndex < gimages.info.senses.length; senseIndex++ ) {
		gimages.info.senses[senseIndex].senseIndex = senseIndex;
				
		var sense = gimages.info.senses[senseIndex];
		var x_translations = x_translations_string.replace("[X]", sense.size); 	
		sensesTable.append(
			"\t\t\t\t\t\t\t\t\t\t<tr>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t<td style='vertical-align: top;' align='left'>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t\t<div id='sense" + senseIndex + "LinkDiv' style='position: static; cursor:default' class='" + cls + "'> " +
			"<a href='javascript: if (gimages.currentlyDisplayedState != " + senseIndex + ") displaySense(" + senseIndex + ");'> " +
			(senseIndex + 1) + ". " + ((sense.description == null || sense.description =="null") ? "   " : sense.description) + 
			" (" + x_translations + ")</a></div>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t</td>\n" +
			"\t\t\t\t\t\t\t\t\t\t</tr>\n");
		if (senseIndex >= 10) {
			hiddenMajorTranslationTables.append(
				"<div id='s" + senseIndex + "Translations' style='white-space: normal; display: none;' class='gwt-HTML'>\n" + 
				"</div>");
		}
	}
	sensesTable.append(
			"\t\t\t\t\t\t\t\t\t\t<tr>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t<td style='vertical-align: top;' align='left'>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t\t<div id='sense" + senseIndex + "LinkDiv' style='position: static; cursor:default' class='" + cls + "'> " +
			"<a href='javascript: if (gimages.currentlyDisplayedState != " + senseIndex + ") showOtherTranslations();'> " +
			getUIString("OtherTranslations") +"</a></div>\n" +
			"\t\t\t\t\t\t\t\t\t\t\t</td>\n" +
			"\t\t\t\t\t\t\t\t\t\t</tr>\n");
	
	var sensesPanel = sensesPanel1 + sensesTable.toString() + sensesPanel2;
	var sensesHolder = document.getElementById("sensesHolder");
	sensesHolder.innerHTML = sensesPanel;
	
	var majorTranslationsHolder = document.getElementById("majorTranslationsHolder");
	majorTranslationsHolder.innerHTML += hiddenMajorTranslationTables.toString();
	
	var currSense = gimages.currentlyDisplayedState;
	gimages.currentlyDisplayedState = -1;
	displaySense(currSense);
}


/* very similar to showResults, does not appear to actually be called from anywhere. presumed obsolete. ~ono
function showWhichSense() {
	try {
		var sensesPanel1 =
			"\t\t\t\t\t\t\t\t\t<table class='ks-List' cellpadding='0' cellspacing='0'>\n" +
			"\t\t\t\t\t\t\t\t\t<tbody>\n";
		var sensesTable = "";
		var sensesPanel2 =
			"\t\t\t\t\t\t\t\t\t</tbody>\n" +
			"\t\t\t\t\t\t\t\t\t</table>\n";
		var hiddenMajorTranslationTables = "";
		var hiddenAllTranslationTables = "";
		var hiddenNewTranslationTables = "";
		
		var initialDisplaySense = 0;
		for ( var senseIndex = 0; senseIndex < gimages.info.senses.length; senseIndex++ ) {
			gimages.info.senses[senseIndex].senseIndex = senseIndex;
			var sense = gimages.info.senses[senseIndex];
			var cls = "ks-SinkItem";
			var x_translations = getUIString("XTranslations").replace("[X]", sense.translationCount); 
			sensesTable +=
				"\t\t\t\t\t\t\t\t\t\t<tr>\n" +
				"\t\t\t\t\t\t\t\t\t\t\t<td style='vertical-align: top;' align='left'>\n" +
				"\t\t\t\t\t\t\t\t\t\t\t\t<div id='sense" + senseIndex + "LinkDiv' style='position: static;' class='" + cls + "'> " +
				// "<a href='javascript: if (gimages.currentlyDisplayedState != " + senseIndex + ") dojo.undo.browser.addToHistory(new PanImagesState(" + senseIndex + "));'> " + 
				"<input id='s" + senseIndex + "checkbox' type='checkbox' >" +
				"<a href='javascript: if (gimages.currentlyDisplayedState != " + senseIndex + ") displaySense(" + senseIndex + ");'> " +
				" " + ((sense.description == null || sense.description =="null") ? "   " : sense.description) + 
				" (" + x_translations + ")</a></div>\n" +
				"\t\t\t\t\t\t\t\t\t\t\t</td>\n" +
				"\t\t\t\t\t\t\t\t\t\t</tr>\n";
			var majorTranslationsForSense =
				"<div id='s" + senseIndex + "MajorTranslations' style='white-space: normal; display: none;' class='gwt-HTML'>\n" + 
				"\t<table id='s" + senseIndex + "MajorTranslationsTable' class='sense-table'>\n" +
				"\t<tbody>\n";

			var allTranslationsForSense =
				"<div id='s" + senseIndex + "AllTranslations' style='white-space: normal; display: none;' class='gwt-HTML'>\n" +
				"\t<table id='s" + senseIndex + "AllTranslationsTable' class='sense-table' style='width:100%'>\n" +
				"\t<tbody>\n";
				
			var newTranslationsForSenseShort = 
				"<div id='s" + senseIndex + "NewTranslationsShort' style='white-space: normal; display: none;' class='gwt-HTML'>\n" +
				"\t<table id='s" + senseIndex + "NewTranslationsTableShort' class='sense-table' style='width:100%; display: block'>\n" +
				"\t<tbody>\n";
			var newTranslationsForSenseShort = 
				"<div id='s" + senseIndex + "NewTranslationsLong' style='white-space: normal; display: none;' class='gwt-HTML'>\n" +
				"\t<table id='s" + senseIndex + "NewTranslationsTableLong' class='sense-table' style='width:100%; display: block'>\n" +
				"\t<tbody>\n";
				
			for ( var languageIndex = 0; languageIndex < sense.languages.length; languageIndex++ ) {
				gimages.info.senses[senseIndex].languages[languageIndex].senseIndex = senseIndex;
				gimages.info.senses[senseIndex].languages[languageIndex].languageIndex = languageIndex;
				var language = sense.languages[languageIndex];

				var translationsString = "";

				for ( var translationIndex = 0; translationIndex < language.translations.length; translationIndex++) {					
					gimages.info.senses[senseIndex].languages[languageIndex].translations[translationIndex].senseIndex = senseIndex;
					gimages.info.senses[senseIndex].languages[languageIndex].translations[translationIndex].languageIndex = languageIndex;
					gimages.info.senses[senseIndex].languages[languageIndex].translations[translationIndex].translationIndex = translationIndex;
					var translation = language.translations[translationIndex];
					translationsString += "\t\t<tr>\n";
					if ( translationIndex == 0 ) {
						translationsString +=
							"\t\t\t<td class='translation-language'><span id='s" + senseIndex + "l" + languageIndex + "'><nobr>" + language.englishName + "</nobr></span></td>\n";
					} else {
						translationsString +=
							"\t\t\t<td class='translation-language'>&nbsp;</td>\n";
					}
					
					var search_one = getUIString("SearchImagesWithOneTranslation");
					
					var singleTransQuery =	"searchLang="+gimages.langID+
											"&searchTerm="+encodeURIComponent(gimages.sourceWord)+
											"&showLang="+language.id+
											"&showTerm="+encodeURIComponent(translation.translation)+
											"&senseIndex="+senseIndex+
											"&previous=" + encodeURIComponent(window.location.href);

					translationsString +=
						"\t\t\t<td class='translation-value'>" +
						"<table style='width: 100%;' cellpadding='0' cellspacing='0'><tbody><tr>" +
						"<td style='width:100%'>" +
						"<a class='translation-span' href=\"showresults.jsp?"+singleTransQuery+"\" title='" + search_one + "' id='s" 
							+ senseIndex + "l" + languageIndex + "t" + translationIndex + "'>" 
							+ translation.translation + "" +
						"</a>" +
						"</td>" +
						"<td style='text-align:right'>" +
						"</td>" +
						"<td style='text-align:right'>" +
						"</td>" +
						"</tr></tbody></table>" +
						"</td>\n";
					translationsString += "\t\t</tr>\n";					
				}
				
				// see if the language is a major language
				var found = false, ar = gimages.majorLanguages, val = language.englishName;
				for (var i = 0; i < ar.length; i++) {
					if (ar[i].name == val) {
						found = true;
						break;
					}
				}

				if ( found ) {
					majorTranslationsForSense += translationsString;
				} else {
					allTranslationsForSense += translationsString;
				}
			}
			
			majorTranslationsForSense += 
				"\t</tbody>\n" +
				"\t</table>\n" +
				"</div>\n";
			allTranslationsForSense +=
				"\t</tbody>\n" +
				"\t</table>\n" +
				"</div>\n";
			newTranslationsForSenseShort +=
				"\t</tbody>\n" +
				"\t</table>\n" +
				"</div>\n";
			newTranslationsForSenseLong +=
				"\t</tbody>\n" +
				"\t</table>\n" +
				"</div>\n";				
			hiddenMajorTranslationTables += majorTranslationsForSense;
			hiddenAllTranslationTables += allTranslationsForSense;
			hiddenNewTranslationTables += newTranslationsForSense;
		}
		var sensesPanel = sensesPanel1 + sensesTable + sensesPanel2;

		var sensesHolder = document.getElementById("sensesHolder");
		var majorTranslationsHolder = document.getElementById("majorTranslationsHolder");
		var allTranslationsHolder = document.getElementById("allTranslationsHolder");
		var newTranslationsHolder = document.getElementById("newTranslationsHolder");
		var resultsTable = document.getElementById("resultsTable");

		// Actually render the html		
		sensesHolder.innerHTML = sensesPanel;
		majorTranslationsHolder.innerHTML = hiddenMajorTranslationTables;
		allTranslationsHolder.innerHTML = hiddenAllTranslationTables;
		newTranslationsHolder.innerHTML = hiddenNewTranslationTables;
//		var btn1 = document.getElementById("btnShowTranslations1");
//		var btn2 = document.getElementById("btnShowTranslations2");
//		btn1.style.display="none";
//		btn2.style.display="none";
		var selectMeaningDiv = document.getElementById("selectMeaning");
		selectMeaningDiv.style.display="none";
		
		resultsTable.style.visible = "";

		// Update the 'onclick' method of all the checkboxes
		for ( var senseIndex = 0; senseIndex < gimages.info.senses.length; senseIndex++ ) {
			var checkboxID = "s" + senseIndex + "checkbox";
			var checkbox = document.getElementById(checkboxID);
			checkbox.onclick = onClickCheckboxAT;
		}
		
		// dojo.undo.browser.setInitialState(new PanImagesState(0));
		displaySense(initialDisplaySense);
		var resultsTable = document.getElementById("resultsTable");
		resultsTable.style.display="block";
		var internationalDiv = document.getElementById("hideMeWhileSearching");
		internationalDiv.style.display="block";
		document.getElementById("hideMeWhileSearching2").style.display="block";

	} catch (x) {
	    gimages.waiting = false;	// I don't think this is needed
	    window.alert(x.message +" 687");
	}
}
*/

/* advanced interface stuff for searching with multiple translations.  obsolete. ~ono 
 * readded per Oren's request ~chris */
function onClickCheckboxAT(e) {
	// Determine which checkbox was clicked
	var targ;
	if (!e) var e = window.event;
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	if (targ.nodeType == 3) // defeat Safari bug
		targ = targ.parentNode;
		
	if (targ.checked) {
		var alertMessage = document.getElementById("alertMessage");
		alertMessage.style.display="none";
	}
}

function getSelectedSenseIndices() {
	var selected_senses = new Array();
	for ( var senseIndex = 0; senseIndex < gimages.info.senses.length; senseIndex++ ) {
		var checkboxID = "s" + senseIndex + "checkbox";
		var checkbox = document.getElementById(checkboxID);
		if ( checkbox.checked ) {
			selected_senses.push(senseIndex);
		}
	}
	return selected_senses;
}

function onClickCheckbox(e) {
	// Determine which checkbox was clicked
	var targ;
	if (!e) var e = window.event;
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	if (targ.nodeType == 3) // defeat Safari bug
		targ = targ.parentNode;
		
	if (targ.checked)
		addCheckedTranslation();
	else
		removeCheckedTranslation();
}

function addCheckedTranslation() {
	gimages.numTranslationsChecked++;
	updateSearchCheckedTranslationsButton();
}

function removeCheckedTranslation() {
	gimages.numTranslationsChecked--;
	updateSearchCheckedTranslationsButton();
}

function updateSearchCheckedTranslationsButton() {
	/*This part of advanced search functionality is no longer needed ~chris
	 * var btn1 = document.getElementById("btnShowTranslations1");
	var btn2 = document.getElementById("btnShowTranslations2");
	if ( gimages.numTranslationsChecked > 0 ) {
		btn1.disabled = false;
		btn2.disabled = false;
		btn1.innerHTML = getUIString("showImagesOfSelectedTranslations");
		btn2.innerHTML = getUIString("showImagesOfSelectedTranslations");
	} else {
		btn1.disabled = true;
		btn2.disabled = true;
		btn1.innerHTML = getUIString("showImagesOfSelectedTranslations");
		btn2.innerHTML = getUIString("showImagesOfSelectedTranslations");
	}*/
	;
}
/**/

function parseQueryString( arg1 ) {
	var queryString = arg1;
	var result = new Object(); // Hash map
	result.keySet = new Array();
    if (queryString.indexOf("?") == 0)
        queryString = queryString.substr(1);

    var items = queryString.split("&");
    for ( var i = 0; i < items.length; i++ ) {
        var pair = items[i].split("=");
        result[pair[0]] = window.decodeURIComponent(pair[1]);
        result.keySet[result.keySet.length] = pair[0];
    }
    return result;
}

/* advance interface stuff for searching with multiple translations. obsolete. ~ono
 * readded per Oren's request ~chris */
// This function will return all the translations selected within a given sense
// The return value is an object with two properties: 'list' and 'hash'
// 'list' is an array containing the unique translations selected.
// 'hash' is a hash table mapping each translation to a string containing the languages in which this
// translation appears
function getSelectedTranslations(senseIndex) {
	var retval = new Object();
	retval.hash = new Object();
	retval.list = new Array();
	var sense = gimages.info.senses[senseIndex];
	for ( var languageIndex = 0; languageIndex < sense.languages.length; languageIndex++ ) {
		var language = sense.languages[languageIndex];
		for ( var translationIndex = 0; translationIndex < language.translations.length; translationIndex++) {
			var checkboxID = "s" + senseIndex + "l" + languageIndex + "t" + translationIndex + "checkbox";
			var translationCellID = "s" + senseIndex + "l" + languageIndex + "t" + translationIndex;
			var languageCellID = "s" + senseIndex + "l" + languageIndex;
			var checkbox = document.getElementById(checkboxID);
			var translationText = getInnerText(document.getElementById(translationCellID));
            if ( translationText.indexOf(" ") > -1 )
                translationText = "\"" + translationText.replace(/\s/g, '+') + "\"";
			// var languageText = getInnerText(document.getElementById(languageCellID));

			if ( checkbox.checked ) {
				if ( retval.hash[translationText] == null ) {
					retval.hash[translationText] = language.englishName;
					retval.list.push(translationText);
				} else {
					retval.hash[translationText] = retval.hash[translationText] + ", " + language.englishName;
				}
			}
		}
	}
	return retval;
}


function onShowImages(e) {
    // AjaxClient.invokeGet(url, true, function ( responseText ) {} ); 
	    
	ShowSelectedTranslations();
}
/**/

/*old advanced interface stuff for searching with multiple translations. obsolete. ~ono
 * readded per Oren's request ~chris */
function ShowSelectedTranslations() {
	var senseIndex = gimages.currentlyDisplayedState;
	var translations = getSelectedTranslations(senseIndex);

    // I am not sure we want to say anything.  Google will take care of it nicely.
	if ( translations.list.length > 32 ) {
		// alert(
		// 	"You have selected more than 32 unique translations.  Google Images allows searches with up to " +
		// 	"32 unique terms.  Please unselect some translations and try again.");
		// return;
	}

	var showTerms = "";
	var showLangs = "";

	for ( var i = 0; i < translations.list.length; i++ ) {
		if ( showTerms == "" ) {
			showTerms = translations.list[i];
			showLangs = "{" + translations.hash[translations.list[i]] + "}";
		} else {
			showTerms = showTerms + " OR " + translations.list[i];
			showLangs = showLangs + ", {" + translations.hash[translations.list[i]] + "}";
		}
	}

    var searchLangName = document.searchPanel.getLanguageText();
    var searchLangID   = document.searchPanel.getSearchLanguageID();
    var searchTerm = document.searchPanel.getQueryText();
    openGoogleImages(searchLangName, searchLangID, searchTerm, showLangs, showTerms, senseIndex, true);
}

function SelectFirst32() {
	DeselectAll();
	var senseIndex = gimages.currentlyDisplayedState;
	var sense = gimages.info.senses[senseIndex];
	for ( var languageIndex = 0; (languageIndex < sense.languages.length) && (gimages.numTranslationsChecked < 32); languageIndex++ ) {
		var language = sense.languages[languageIndex];
		for ( var translationIndex = 0; (translationIndex < language.translations.length) && (gimages.numTranslationsChecked < 32); translationIndex++) {
			var checkboxID = "s" + senseIndex + "l" + languageIndex + "t" + translationIndex + "checkbox";
			var checkbox = document.getElementById(checkboxID);
			checkbox.checked = true;
			gimages.numTranslationsChecked++;
		}
	}
	updateSearchCheckedTranslationsButton();
}


function DeselectAll() {
	var senseIndex = gimages.currentlyDisplayedState;
	var sense = gimages.info.senses[senseIndex];
	for ( var languageIndex = 0; languageIndex < sense.languages.length; languageIndex++ ) {
		var language = sense.languages[languageIndex];
		for ( var translationIndex = 0; translationIndex < language.translations.length; translationIndex++) {
			var checkboxID = "s" + senseIndex + "l" + languageIndex + "t" + translationIndex + "checkbox";
			var checkbox = document.getElementById(checkboxID);
			checkbox.checked = false;
		}
	}
	gimages.numTranslationsChecked = 0;
	updateSearchCheckedTranslationsButton();
}
/**/

/**
 * What happens when document is clicked
 */
function onDocumentClick(e) {
	// Determine what was clicked
	var targ;
	if (!e) var e = window.event;
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	if (targ.nodeType == 3) // defeat Safari bug
		targ = targ.parentNode;
	if (targ.id == 'editMeaningsI') {
		getSenses();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if (targ.id == 'sReturnToTranslationsI') {
		editSenses(targ.parentNode.parentNode.parentNode.parentNode);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if (targ.id == 'tReturnToTranslationsI') {
		editTranslations(targ.parentNode.parentNode.parentNode.parentNode);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();		
	} else if (targ.id.match(/aReturnToTranslationsI/)) {
		cancelEditAccount();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();		
	} else if (targ.id.match(/ReturnToTranslationsI/)) {
		cancelLogin();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();		
	} else if (targ.id == 'rMoreLanguages') {
		populateAllLanguageSelectBox(document.getElementById("rPossibleLanguages"));
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();		
	} else if (targ.id == 'aMoreLanguages') {
		populateAllLanguageSelectBox(document.getElementById("aPossibleLanguages"));
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();		
	} else if (targ.id == 'loginI') {
		gimages.loc.push(0);
		showLogin();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if (targ.id == 'registerI') {
		gimages.loc.push(0);
		showRegister();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if (targ.id == 'logoutI') {
		userLogout();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if (targ.id == 'accountI') {
		viewAccount();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id == 'FinalOK' ) {
		finalOK();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id == 'FinalCancel' ) {
		finalCancel();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id == 'moreLanguagesI' ) {
		//moreLanguages();
		getAllTranslations(gimages.currentlyDisplayedState);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} 
	/*else if( targ.id =='checkMoreTranslationsI' ) {
		checkMoreTranslations();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if (targ.id =='checkNextI'){
		checkTranslationsNext();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if (targ.id =='checkPrevI'){
		checkTranslationsPrevious();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	}*/ else if ( targ.id == 'viewHighConfI' ) {
		viewHighConf();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id == 'viewMediumConfI' ) {
		viewMediumConf();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id =='viewLowConfI' ) {
		viewLowConf();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id == 'AddNewWord' ) {
		addThisWord();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} /*else if ( targ.id == 'OKTranslation' ) {
		okTranslation();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	}*/ else if ( targ.id == 'CancelTranslation' ) {
		cancelTranslation();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id == 'OKLanguage' ) {
		okLanguage();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id == 'CancelLanguage' ) {
		cancelLanguage();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id == 'CancelAddNewWord' ) {
		cancelAddNewWord();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} /* advanced interface stuff.  obsolete. ~ono 7/15/2008
	readded per Oren's request */
	  else if ( targ.className == 'ks-actionButton' ) {
		if ( targ.id == 'btnSelect32' )
			SelectFirst32();
		else if ( targ.id == 'btnDeslectAll' )
			DeselectAll();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	}/**/
	/* old user editing.  obsolete ~ono 7/15/2008*
	  else if ( targ.className == "RemoveTranslation" ) {
		removeTranslation(targ);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id.match(/CancelRemoveTranslation/) ) {
		cancelRemoveTranslation();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id.match(/ConfirmRemoveTranslation/) ) {
		confirmRemoveTranslation(targ);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	}
	*/
	  else if ( targ.parentNode && targ.parentNode.id && targ.parentNode.id.match(/OtherLanguageSpan1/) ) {
		addTranslation(1);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.parentNode && targ.parentNode.id && targ.parentNode.id.match(/OtherLanguageSpan2/) ) {
		addTranslation(2);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.parentNode && targ.parentNode.id && targ.parentNode.id.match(/OtherLanguageSpan3/) ) {	
		addTranslation(3);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.parentNode && targ.parentNode.id && targ.parentNode.id.match(/OtherLanguageSpan4/) ) {
		addTranslation(4);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.parentNode && targ.parentNode.id && targ.parentNode.id.match(/OtherLanguageSpan5/) ) {
		addTranslation(5);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id.match(/ConfirmAddTranslation/) ) {
		confirmAddTranslation();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id.match(/CancelAddTranslation1/) ) {
		cancelAddTranslation(1);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id.match(/CancelAddTranslation2/) ) {
		cancelAddTranslation(2);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id.match(/CancelAddTranslation3/) ) {
		cancelAddTranslation(3);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id.match(/CancelAddTranslation4/) ) {
		cancelAddTranslation(4);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id.match(/CancelAddTranslation5/) ) {
		cancelAddTranslation(5);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} else if ( targ.id.match(/editTranslations\d+/) ) {
		showEditTranslations();
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	} 
	/* advanced interface stuff.  obsolete. ~ono 7/15/2008
	 * readded per oren's request */
	else if ( targ.id.match(/s.*l.*t.*checkbox/) ) {
		onClickCheckbox(e);
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	}/**/
}


/**
 * More minor languages functions
 */
//If there are no minor languages, we want to show all of them.
/* no longer using minor languages
function initializeMoreLanguages() {
	for(var i=0; i<gimages.info.senses.length; i++) {
		if(gimages.showingMoreTranslations[i]==-1) {
			var senseAllTranslations = document.getElementById("s"+i+"AllTranslations");
			var otherTranslations = getElementsByClass("other", senseAllTranslations, "tr");
			for(var j=0; j<otherTranslations.length; j++) {
				otherTranslations[j].style.display="";
			}
		}
	}
}
*/
/*advanced interface stuff. obsolete.
 * readded per Oren's request ~chris */
//if advanced, we want to show all languages
function showAllLanguages() {
	for(var i=0; i<gimages.info.senses.length; i++) {
		gimages.showingMoreTranslations[i]=-1
		var senseAllTranslations = document.getElementById("s"+i+"AllTranslations");
		var otherTranslations = getElementsByClass("other", senseAllTranslations, "tr");
		for(var j=0; j<otherTranslations.length; j++) {
			otherTranslations[j].style.display="";
		}
	}
}
/**/

/* no longer in use.  ~ono 8/11/2008
function moreLanguages() {
	var moreLanguages = document.getElementById("moreLanguagesI");
	
	var state;
	if(gimages.showingMoreTranslations[gimages.currentlyDisplayedState]==1) {
		state = "none";
		gimages.showingMoreTranslations[gimages.currentlyDisplayedState] = 0;
		moreLanguages.innerHTML=getUIString("seeMore");
	} else {
		state = "";
		gimages.showingMoreTranslations[gimages.currentlyDisplayedState] = 1;
		moreLanguages.innerHTML=getUIString("seeFewer");
	}
	var senseAllTranslations = document.getElementById("s"+gimages.currentlyDisplayedState+"AllTranslations");
	var otherTranslations = getElementsByClass("other", senseAllTranslations, "tr");
	for(var i=0; i<otherTranslations.length; i++) {
		otherTranslations[i].style.display=state;
	}
}
*/

/**
 * Translations to be checked functions
 */ 
 /* no longer in use.  ~ono 8/11/2008 
function checkMoreTranslations(){	
	var translationsLong = document.getElementById("s"+gimages.currentlyDisplayedState+"NewTranslationsLong");
	if (translationsLong == null) {
		getMoreTranslations();
		translationsLong = document.getElementById("s"+gimages.currentlyDisplayedState+"NewTranslationsLong");
	}
	
	var translationsSingleLang = document.getElementById("NewTranslationsSingleLang");
	if (translationsSingleLang != null) {
		document.getElementById("newTranslationsLanguageHolder").style.display = "none";
		//translationsSingleLang.style.display = "none";
	}

	var moreTranslations = document.getElementById("checkMoreTranslationsI");
	var majorTranslations = document.getElementById("s"+gimages.currentlyDisplayedState+"Translations");
	//var allTranslations = document.getElementById("s"+gimages.currentlyDisplayedState+"AllTranslations");
/* "translations to check" pane not in use. ~ono 7/21/2008
	var translationsShort = document.getElementById("s"+gimages.currentlyDisplayedState+"NewTranslationsShort");
*\/
	var chooseTransLanguage = document.getElementById("chooseTransLanguage");
	var langList = document.getElementById("s"+gimages.currentlyDisplayedState+"langList");
	var checkTransNavigation = document.getElementById("checkTransNavigation");
	
	if(gimages.checkingMoreTranslations[gimages.currentlyDisplayedState]>0) {
		var currPageIndex = gimages.checkingMoreTranslations[gimages.currentlyDisplayedState] -  1;
		var translationsLongPage = document.getElementById("s"+gimages.currentlyDisplayedState+"p"+currPageIndex+"NewTranslationsLongTable");
		gimages.checkingMoreTranslations[gimages.currentlyDisplayedState] = 0;
		majorTranslations.style.display = "block";
		//allTranslations.style.display = "block";
/* "translations to check" pane not in use.  ~ono 7/21/2008
		translationsShort.style.display = "block";
*\/
		translationsLong.style.display = "none";
		translationsLongPage.style.display = "none";
		moreTranslations.innerHTML=getUIString("show");
		chooseTransLanguage.style.display = "none";
		checkTransNavigation.style.display="none";
		if(langList != null) {
			langList.style.display = "none";
		}
		document.getElementById("checkPrevI").style.display = "none";
		document.getElementById("checkNextI").style.display = "none";
		document.getElementById("majorLangs").style.display = "";
		//document.getElementById("otherLangs").style.display = "";
		document.getElementById("et0").style.display = "";
		//document.getElementById("et1").style.display = "";
		document.getElementById("et2").style.display = "none";
		document.getElementById("majorTranslationsHolder").style.display = "";
		//document.getElementById("allTranslationsHolder").style.display = "";
	} else {
		gimages.checkingMoreTranslations[gimages.currentlyDisplayedState] = 1;
		majorTranslations.style.display = "none";
		//allTranslations.style.display = "none";
/* not in use.  ~ono 7/21/2008
		translationsShort.style.display = "none";
*\/
		translationsLong.style.display = "block";		
		var translationsLongPage = document.getElementById("s"+gimages.currentlyDisplayedState+"p"+0+"NewTranslationsLongTable");
		translationsLongPage.style.display = "block";
		moreTranslations.innerHTML=getUIString("hide");
		chooseTransLanguage.style.display = "";
		checkTransNavigation.style.display = "";
		if (langList != null) {
			langList.style.display = "";
			document.getElementById("s"+gimages.currentlyDisplayedState+"language").selectedIndex = 0;		
		}
		if(gimages.info.senses[gimages.currentlyDisplayedState].checkLong.pages.length > 1) {
			document.getElementById("checkNextI").style.display = "";
		} 	
		document.getElementById("majorLangs").style.display = "none";
		//document.getElementById("otherLangs").style.display = "none";
		document.getElementById("et0").style.display = "none";
		//document.getElementById("et1").style.display = "none";
		document.getElementById("et2").style.display = "";
		document.getElementById("newTranslationsHolder").style.display = "";
		document.getElementById("majorTranslationsHolder").style.display = "none";
		//document.getElementById("allTranslationsHolder").style.display = "none";
	}
}


function getMoreTranslations() {
	document.body.style.cursor = "wait";
	
	var messagesDiv = document.getElementById("messagesDiv2");

	messagesDiv.innerHTML = getUIString("loading");

	messagesDiv.style.display="block";

    gimages.waiting = true;
    var waitTimer = -1;
    var me = gimages;
    var dots = 0;
    var waitFunc = function( ) {
        if ( me.waiting && dots <= 85) {
        	messagesDiv.innerHTML += ".";
        	dots++;
        } else {
        	if (dots > 85) {
        		// This error message isn't strictly true.  The website
        		// will continue to wait for the transaction to complete
        		// but, since it probably won't, it's nice to tell the
        		// client something went wrong.
        		messagesDiv.innerHTML += "connection timed out!"
        	}
        	else {
        		messagesDiv.style.display = "none";
        	}
 
        	window.clearInterval(waitTimer);
        	waitTimer = -1;
        }
    }
    waitTimer = window.setInterval(waitFunc, 500);
    
	var url = "MoreUncertainTranslations?sense="+gimages.info.senses[gimages.currentlyDisplayedState].id;
	url += "&stamp="+(new Date()).getTime();
	AjaxClient.invokeGet(url, false, gimages.processMoreTranslations);
	document.body.style.cursor = "default";
}

GImages.prototype.processMoreTranslations = function( responseText ) {
	senseIndex = gimages.currentlyDisplayedState;
	sense = gimages.info.senses[senseIndex];
	sense.checkLong = responseText.parseJSON(null);

	var newTranslationsForSenseLong = new StringBuffer(
		"<div id='s" + senseIndex + "NewTranslationsLong' style='white-space: normal; display: none;' class='gwt-HTML'>\n");	
	if (sense.checkLong.pages.length == 1 && sense.checkLong.pages[0].languages.length == 0) {
		newTranslationsForSenseLong.append("\t<table id='s" + senseIndex + "p" + 0 + "NewTranslationsLongTable' " +
			"class='sense-table' style='width:100%; display: none;'>\n" +
			"\t<tbody>\n");
		newTranslationsForSenseLong.append("<tr><td>No translations found</td></tr>");
		newTranslationsForSenseLong.append("</tbody></table></div>");
	}
	else {
		var checkTransLangListForSense = new StringBuffer();
		checkTransLangListForSense.append(
			"<FORM id='s"+senseIndex+"langList' style='display:none'>\n"+
			"<SELECT id='s"+senseIndex+"language' name='language'>\n" +
			"<OPTION VALUE='-1'>"+getUIString("language")+"</OPTION>\n" +
			"\t\t<OPTION VALUE='-1'>"+getUIString("allLanguages")+"</OPTION>\n");
			
		var search_one = getUIString("SearchImagesWithOneTranslation");
		
		for (var pageIndex = 0; pageIndex < sense.checkLong.pages.length; pageIndex++) {
			var pageString = new StringBuffer(
				"\t<table id='s" + senseIndex + "p" + pageIndex + "NewTranslationsLongTable' " +
				"class='sense-table' style='width:100%; display: none;'>\n" +
				"\t<tbody>\n");
			for ( var languageIndex = 0; languageIndex < sense.checkLong.pages[pageIndex].languages.length; languageIndex++ ) {
				gimages.info.senses[senseIndex].checkLong.pages[pageIndex].languages[languageIndex].senseIndex = senseIndex;
				gimages.info.senses[senseIndex].checkLong.pages[pageIndex].languages[languageIndex].languageIndex = languageIndex;
				var language = sense.checkLong.pages[pageIndex].languages[languageIndex];			
				if (pageIndex > 0 && languageIndex == 0) {
					var lastLanguageIndex = sense.checkLong.pages[pageIndex - 1].languages.length - 1;		
					if (language.id != sense.checkLong.pages[pageIndex - 1].languages[lastLanguageIndex].id){
						var id = language.id;
						var englishName = language.englishName;
						checkTransLangListForSense.append("\t\t<OPTION VALUE='"+id+"'>"+englishName+"</OPTION>\n");
					}
				}
				else {			
					var id = language.id;
					var englishName = language.englishName;
					checkTransLangListForSense.append("\t\t<OPTION VALUE='"+id+"'>"+englishName+"</OPTION>\n");
				}
				var translationsString = new StringBuffer();
	
				for ( var translationIndex = 0; translationIndex < language.translations.length; translationIndex++) {
					gimages.info.senses[senseIndex].checkLong.pages[pageIndex].languages[languageIndex].translations[translationIndex].senseIndex = senseIndex;
					gimages.info.senses[senseIndex].checkLong.pages[pageIndex].languages[languageIndex].translations[translationIndex].languageIndex = languageIndex;
					gimages.info.senses[senseIndex].checkLong.pages[pageIndex].languages[languageIndex].translations[translationIndex].translationIndex = translationIndex;
					var translation = language.translations[translationIndex];
					translationsString.append("\t\t<tr>\n");
					if ( translationIndex == 0 ) {
						translationsString.append( 
							"\t\t\t<td class='translation-language'><span id='s" + senseIndex + "l" + languageIndex + "'><nobr>" + language.englishName + "</nobr></span></td>\n");
					} else {
						translationsString .append(
							"\t\t\t<td class='translation-language'>&nbsp;</td>\n");
					}
						
					var singleTransQuery =	"searchLang="+gimages.langID+
											"&searchTerm="+encodeURIComponent(gimages.sourceWord)+
											"&showLang="+language.id+
											"&showTerm="+encodeURIComponent(translation.translation)+
											"&senseIndex="+senseIndex+
											"&previous=" + encodeURIComponent("GImages.jsp?word="+gimages.sourceWord+"&lang="+gimages.langID);
	
					translationsString.append(
						"\t\t\t<td class='translation-value'>" +
						"<table style='width: 100%;' cellpadding='2' cellspacing='0'><tbody><tr>" +
						"<td style='width:100%'>" +
					/*advanced interface stuff.  obsolete. ~ono
						(gimages.advanced ? "<input id='s" + senseIndex + "l" + languageIndex + "t" + translationIndex + "checkbox' type='checkbox' " + checked + " >" : "") +
					*\/
						"<a class='translation-span' href=\"showresults.jsp?"+singleTransQuery+"\" title='" + search_one + "' id='s" 
							+ senseIndex + "l" + languageIndex + "t" + translationIndex + "'>" 
							+ translation.translation + "" +
						"</a>" +
						"</td>" +
					/*advanced interface stuff.  obsolete. ~ono
						"<td style='text-align:right;'>" +
						"<nobr><span id='s" + senseIndex + "l" + languageIndex + "t" + translationIndex + "ConfirmRemoveTranslation' style='cursor:pointer;text-decoration:underline;color:blue;display:none'>"+getUIString("ok")+"</span>" +
						"<WBR><span id='s" + senseIndex + "l" + languageIndex + "t" + translationIndex + "Space' style='display:none'>&nbsp;&nbsp;</span><WBR>" +
						"<span id='s" + senseIndex + "l" + languageIndex + "t" + translationIndex + "CancelRemoveTranslation' style='cursor:pointer;text-decoration:underline;color:blue;display:none'>"+getUIString("cancel")+"</span></nobr>" +
						"</td>" +
					*\/
						"<td style='text-align:right'>");
				
					if(gimages.langID != language.id || gimages.sourceWord != translation.translation) {
						translationsString.append("<span id='s" + senseIndex + "l" + languageIndex + "t" + translationIndex + "RemoveTranslation' class='RemoveTranslation' style='color:#FF7777;cursor:pointer;display:none' title='"+getUIString("removeTranslation")+"'>X</span>");
					}
					translationsString.append(
						"</td>" +
						"</tr></tbody></table>" +
						"</td>\n");
					translationsString.append("\t\t</tr>\n");					
				}
				pageString.append(translationsString);
			}	
/*			pageString.append(
				"<tr id='s"+senseIndex+"p"+pageIndex+"AddTranslationEndRow2'>\n" +
					"<td class='translation-language' id='s"+senseIndex+"p"+pageIndex+"OtherLanguageLanguage2'>" +
						"<span id='s"+senseIndex+"p"+pageIndex+"OtherLanguageSpan2' style='text-decoration:underline;color:blue;cursor:pointer;'>" +
							"<nobr>"+getUIString("addTranslation")+"</nobr>" +
						"</span>" +
					"</td>\n" +
					"<td class='translation-value' id='s"+senseIndex+"p"+pageIndex+"OtherLanguageTranslation2' style='width:100%'>&nbsp;" +
					"</td>" +
				"</tr>\n");
*\/				
			pageString.append(
				"\t</tbody>\n" +
				"\t</table>\n");
			newTranslationsForSenseLong.append(pageString);
		}
		newTranslationsForSenseLong.append("</div>\n");
		checkTransLangListForSense.append("</SELECT>" +
				"<INPUT TYPE='BUTTON' VALUE="+getUIString("Submit")+" ONCLICK='checkTranslationsLanguage(this.form.language.value)'></form>");
				
		var checkTransLanguageSelection = document.getElementById("checkTransLanguageSelection");		
		checkTransLanguageSelection.innerHTML += checkTransLangListForSense.toString();	
	}
			
	var newTranslationsHolder = document.getElementById("newTranslationsHolder");

	newTranslationsHolder.innerHTML += newTranslationsForSenseLong.toString();
	newTranslationsHolder.style.display = "";
	document.getElementById("editTranslations2").style.display = "";
	
	gimages.waiting = false;
}

function checkTranslationsNext() {
	var oldPageIndex = gimages.checkingMoreTranslations[gimages.currentlyDisplayedState] - 1;
	var newPageIndex = gimages.checkingMoreTranslations[gimages.currentlyDisplayedState];
	var translationsPageOld = document.getElementById("s"+gimages.currentlyDisplayedState+"p"+oldPageIndex+"NewTranslationsLongTable");
	var translationsPageNew = document.getElementById("s"+gimages.currentlyDisplayedState+"p"+newPageIndex+"NewTranslationsLongTable");
	translationsPageOld.style.display = "none";
	translationsPageNew.style.display = "block";
	gimages.checkingMoreTranslations[gimages.currentlyDisplayedState]++;
	if (gimages.checkingMoreTranslations[gimages.currentlyDisplayedState] == gimages.info.senses[gimages.currentlyDisplayedState].checkLong.pages.length){
		document.getElementById("checkNextI").style.display = "none";
	}
	if (gimages.checkingMoreTranslations[gimages.currentlyDisplayedState] == 2) {
		document.getElementById("checkPrevI").style.display = "";
	}
}

function checkTranslationsPrevious() {
	var oldPageIndex = gimages.checkingMoreTranslations[gimages.currentlyDisplayedState] - 1;
	var newPageIndex = gimages.checkingMoreTranslations[gimages.currentlyDisplayedState] - 2;
	var translationsPageOld = document.getElementById("s"+gimages.currentlyDisplayedState+"p"+oldPageIndex+"NewTranslationsLongTable");
	var translationsPageNew = document.getElementById("s"+gimages.currentlyDisplayedState+"p"+newPageIndex+"NewTranslationsLongTable");
	translationsPageOld.style.display = "none";
	translationsPageNew.style.display = "block";
	gimages.checkingMoreTranslations[gimages.currentlyDisplayedState]--;
	if (gimages.checkingMoreTranslations[gimages.currentlyDisplayedState] == 1) {
		document.getElementById("checkPrevI").style.display = "none";
	}
	if (gimages.checkingMoreTranslations[gimages.currentlyDisplayedState] == gimages.info.senses[gimages.currentlyDisplayedState].checkLong.pages.length - 1) {
		document.getElementById("checkNextI").style.display = "";
	}
}

function checkTranslationsLanguage(language){
	if (language == -1) {
		gimages.checkingMoreTranslations[gimages.currentlyDisplayedState] = 0;
		checkMoreTranslations();	
	}
	
	else {
		var numPages = gimages.info.senses[gimages.currentlyDisplayedState].checkLong.pages.length;
		var languageObjects = new Array();
		//var languageObject = null;
		//var languageObject2 = null;
		for (var pageIndex = 0; pageIndex < numPages; pageIndex++){
			var numLangs = gimages.info.senses[gimages.currentlyDisplayedState].checkLong.pages[pageIndex].languages.length;
			for (var languageIndex = 0; languageIndex < numLangs; languageIndex++) {
				if (gimages.info.senses[gimages.currentlyDisplayedState].checkLong.pages[pageIndex].languages[languageIndex].id == language) {
					//languageObject = gimages.info.senses[gimages.currentlyDisplayedState].checkLong.pages[pageIndex].languages[languageIndex];
					languageObjects[0] = gimages.info.senses[gimages.currentlyDisplayedState].checkLong.pages[pageIndex].languages[languageIndex];
					i = 1;
					if (languageIndex == numLangs - 1 && pageIndex < numPages - 1 && gimages.info.senses[gimages.currentlyDisplayedState].checkLong.pages[pageIndex+1].languages[0].id == language) {
						while (pageIndex < numPages - 1 && gimages.info.senses[gimages.currentlyDisplayedState].checkLong.pages[pageIndex+1].languages[0].id == language){
							//languageObject2 = gimages.info.senses[gimages.currentlyDisplayedState].checkLong.pages[pageIndex+1].languages[0];
							languageObjects[i] = gimages.info.senses[gimages.currentlyDisplayedState].checkLong.pages[pageIndex+1].languages[0];
							i++;
							pageIndex++;
						}
					}
					languageIndex = numLangs;
					pageIndex = numPages;
				}
			}
		}
				
		var oneLangTranslations = new StringBuffer();
		oneLangTranslations.append(
				"<div id='NewTranslationsSingleLang' style='white-space: normal; display: block;' class='gwt-HTML'>\n" +
				"\t<table id='NewTranslationsSingleLangTable' class='sense-table' style='width:100%;'>\n" +
				"\t<tbody>\n");

		var search_one = getUIString("SearchImagesWithOneTranslation");		
				
		for (var languageIndex = 0; languageIndex < languageObjects.length; languageIndex++) {
			languageObject = languageObjects[languageIndex];
			for (var translationIndex = 0; translationIndex < languageObject.translations.length; translationIndex++){
				translation = languageObject.translations[translationIndex];
				if (languageIndex == 0 && translationIndex == 0){
					oneLangTranslations.append("\t\t\t<td class='translation-language'><nobr>" 
						+ languageObject.englishName + "</nobr></td>\n");
				}
				else {
					oneLangTranslations.append("\t\t\t<td class='translation-language'>&nbsp;</td>\n");
				}
						
				var singleTransQuery =	"searchLang="+gimages.langID+
										"&searchTerm="+encodeURIComponent(gimages.sourceWord)+
										"&showLang="+languageObject.id+
										"&showTerm="+encodeURIComponent(translation.translation)+
										"&senseIndex="+gimages.currentlyDisplayedState+
										"&previous=" + encodeURIComponent("GImages.jsp?word="+gimages.sourceWord+"&lang="+gimages.langID);
				oneLangTranslations.append(
					"\t\t\t<td class='translation-value'>" +
					"<table style='width: 100%;' cellpadding='2' cellspacing='0'><tbody><tr>" +
					"<td style='width:100%'>" +
					"<a class='translation-span' href=\"showresults.jsp?"+singleTransQuery+"\" title='" + search_one + "'>" 
						+ translation.translation + "" +
					"</a>" +
					"</td>" +
					"<td style='text-align:right'>");
				oneLangTranslations.append(
					"</td>" +
					"</tr></tbody></table>" +
					"</td>\n");
				oneLangTranslations.append("\t\t</tr>\n");		
			}
		}
		
		/*
		if (languageObject2 != null) {
			for (translationIndex = 0; translationIndex < languageObject2.translations.length; translationIndex++){
				translation = languageObject2.translations[translationIndex];
				oneLangTranslations.append("\t\t\t<td class='translation-language'>&nbsp;</td>\n");
				var search_one = getUIString("SearchImagesWithOneTranslation");
						
				var singleTransQuery =	"searchLang="+gimages.langID+
										"&searchTerm="+encodeURIComponent(gimages.sourceWord)+
										"&showLang="+language.id+
										"&showTerm="+encodeURIComponent(translation.translation)+
										"&senseIndex="+gimages.currentlyDisplayedState+
										"&previous=" + encodeURIComponent("GImages.jsp?word="+gimages.sourceWord+"&lang="+gimages.langID);
				oneLangTranslations.append(
					"\t\t\t<td class='translation-value'>" +
					"<table style='width: 100%;' cellpadding='2' cellspacing='0'><tbody><tr>" +
					"<td style='width:100%'>" +
					"<a class='translation-span' href=\"showresults.jsp?"+singleTransQuery+"\" title='" + search_one + "'>" 
						+ translation.translation + "" +
					"</a>" +
					"</td>" +
					"<td style='text-align:right'>");
				oneLangTranslations.append(
					"</td>" +
					"</tr></tbody></table>" +
					"</td>\n");
				oneLangTranslations.append("\t\t</tr>\n")
			}
		}
		*\/
/*		oneLangTranslations.append(
				"<tr id='s"+senseIndex+"l"+language+"AddTranslationEndRow2'>\n" +
					"<td class='translation-language' id='s"+senseIndex+"l"+language+"OtherLanguageLanguage2'>" +
						"<span id='s"+senseIndex+"l"+language+"OtherLanguageSpan2' style='text-decoration:underline;color:blue;cursor:pointer;'>" +
							"<nobr>"+getUIString("addTranslation")+"</nobr>" +
						"</span>" +
					"</td>\n" +
					"<td class='translation-value' id='s"+senseIndex+"l"+language+"OtherLanguageTranslation2' style='width:100%'>&nbsp;" +
					"</td>" +
				"</tr>\n");
*\/
		oneLangTranslations.append(
					"\t</tbody>\n" +
					"\t</table>\n" +
					"</div>\n");
		document.getElementById("newTranslationsLanguageHolder").innerHTML = oneLangTranslations.toString();
		document.getElementById("newTranslationsLanguageHolder").style.display = "";
		document.getElementById("NewTranslationsSingleLang").style.display = "block";
		document.getElementById("s"+gimages.currentlyDisplayedState+"NewTranslationsLong").style.display = "none";
		document.getElementById("s"+gimages.currentlyDisplayedState+"p"+(gimages.checkingMoreTranslations[gimages.currentlyDisplayedState]-1)+"NewTranslationsLongTable").style.display = "none";
		document.getElementById("newTranslationsHolder").style.display = "none";
		document.getElementById("checkPrevI").style.display = "none";
		document.getElementById("checkNextI").style.display = "none";
	}	
}


/*
 * Display uncertain translations for the given language; build table if it does not exist
 */
 
/*
 * Retrieve uncertain translations for the given language
 */
function checkTranslationsLanguage1(language) {
	var languageTable = document.getElementById("s"+gimages.currentlyDisplayedState+"l"+language+"Translations");
	//if table does not exist, build it
	if (languageTable == null && language > 0) {
		document.body.style.cursor = "wait";
		var url = "GetUncertainTranslationsLanguage?sense="+gimages.info.senses[gimages.currentlyDisplayedState].id+"&language="+language;
		AjaxClient.invokeGet(url, false, gimages.processUncertainTranslations);
		document.body.style.cursor = "default";
	}
	//display results 
	else {
		var uncertainTranslationsHolder = document.getElementById("uncertainTranslationsHolder");
		//hide other languages' results
		for (var i = 0; i < uncertainTranslationsHolder.childNodes.length; i++) {
			var object = uncertainTranslationsHolder.childNodes[i];
			if (object.id && object.id.match(/s\d+l\d+Translations/)) {
				object.style.display = "none";
			}
		}
		//display results - hide all if 'language'=-1
		if (languageTable != null) {
			uncertainTranslationsHolder.style.display = "";
			languageTable.style.display = "";
		} else {
			uncertainTranslationsHolder.style.display = "none";
		}
	}
}

/*
 * Build uncertain translations table
 */
GImages.prototype.processUncertainTranslations = function (responseText) {
	var languageObject = responseText.parseJSON(null);
	var languageID = languageObject.id;
	
	var oneLangTranslations = new StringBuffer();
	oneLangTranslations.append(
			"<div id='s"+gimages.currentlyDisplayedState+"l"+languageID+"Translations' style='white-space: normal; display: block;' class='gwt-HTML'>\n" +
			"\t<table id='s"+gimages.currentlyDisplayedState+"l"+languageID+"TranslationsTable' class='sense-table' style='width:100%;'>\n" +
			"\t<tbody>\n");

	var search_one = getUIString("SearchImagesWithOneTranslation");		
	
	//each translations gets a row; first translation in a language also labeled with language name
	for (var translationIndex = 0; translationIndex < languageObject.size; translationIndex++){
		translation = languageObject.translations[translationIndex];
		if (translationIndex == 0){
			oneLangTranslations.append("\t\t\t<td class='translation-language'><nobr>" 
				+ languageObject.englishName + "</nobr></td>\n");
		}
		else {
			oneLangTranslations.append("\t\t\t<td class='translation-language'>&nbsp;</td>\n");
		}
		
		//link to view images of this translation		
		var singleTransQuery =	"searchLang="+gimages.langID+
								"&searchTerm="+encodeURIComponent(gimages.sourceWord)+
								"&showLang="+languageObject.id+
								"&showTerm="+encodeURIComponent(translation.translation)+
								"&senseIndex="+gimages.currentlyDisplayedState+
								"&previous=" + encodeURIComponent("GImages.jsp?word="+gimages.sourceWord+"&lang="+gimages.langID);
		oneLangTranslations.append(
			"\t\t\t<td class='translation-value'>" +
			"<table style='width: 100%;' cellpadding='2' cellspacing='0'><tbody><tr>" +
			"<td style='width:100%'>" +
			"<a class='translation-span' href=\"showresults.jsp?"+singleTransQuery+"\" title='" + search_one + "'>" 
				+ translation.translation + "" +
			"</a>" +
			"</td>" +
			"<td style='text-align:right'>");
		oneLangTranslations.append(
			"</td>" +
			"</tr></tbody></table>" +
			"</td>\n");
		oneLangTranslations.append("\t\t</tr>\n");		
	}	
	if (languageObject.size == 0) {
		oneLangTranslations.append("<tr><td colspan='2'>"+getUIString("NoTranslations")+"</td></tr>");
	}	
	oneLangTranslations.append(
		"\t</tbody>\n" +
		"\t</table>\n" +
		"</div>\n");

	//render HTML		
	document.getElementById("uncertainTranslationsHolder").innerHTML += oneLangTranslations.toString();
	
	//display results
	checkTranslationsLanguage1(languageID);
}

/**
 * Editing translations functions
 */
 
/*
 * Display list of translations to edit, forces user to log in 
 */
function showEditTranslations() {
	//hide old messages
	document.getElementById("messagesDiv").style.display = "none";
	document.getElementById("messagesDiv3").style.display = "none";
	
	//if there is no user currently logged in, show the login screen
	if (gimages.userid == 0) {
		gimages.loc.push(-1);
		showLogin();
	}	
	else {
		//check if user has languages
		/*var url = "GetUserProfile?user="+gimages.userid;
		url += "&stamp="+(new Date()).getTime();
		responseText = AjaxClient.invokeGet(url, false, null);
		response = responseText.parseJSON(null);	
		if (response.languages == 'undefined' || response.languages == undefined || response.languages == "") {
			alert(getUIString("NoLanguages"));
		}
		//retrieve list of translations while displaying a "loading..." message
		else {*/
			document.body.style.cursor = "wait";
		
			var messagesDiv = document.getElementById("messagesDiv2");
		
			messagesDiv.innerHTML = getUIString("loading");
		
			messagesDiv.style.display="block";
		
		    gimages.waiting = true;
		    var waitTimer = -1;
		    var me = gimages;
		    var dots = 0;
		    var waitFunc = function( ) {
		        if ( me.waiting && dots <= 85) {
		        	messagesDiv.innerHTML += ".";
		        	dots++;
		        } else {
		        	if (dots > 85) {
		        		// This error message isn't strictly true.  The website
		        		// will continue to wait for the transaction to complete
		        		// but, since it probably won't, it's nice to tell the
		        		// client something went wrong.
		        		messagesDiv.innerHTML += "connection timed out!"
		        	} else {
		        		messagesDiv.style.display = "none";
		        	}
		 
		        	window.clearInterval(waitTimer);
		        	waitTimer = -1;
		        }
		    }   	
   			waitTimer = window.setInterval(waitFunc, 500);
			var url = "TranslationsToEdit?sense="+gimages.info.senses[gimages.currentlyDisplayedState].id+"&user="+encodeURIComponent(gimages.userid);
			url += "&lang="+gimages.langID+"&displang="+getDisplayLanguage();
	    	url += "&stamp=" + (new Date()).getTime(); 	
	    	AjaxClient.invokeGet(url, true, gimages.processEditTranslations);
	    	document.body.style.cursor = "default";
		/*}*/
	}	
}

/*
 * Build tables of translations to edit
 */
GImages.prototype.processEditTranslations = function ( responseText ) {

	var edit = responseText.parseJSON(null);

	// Something went wrong.  Let's abort without printing an
	// error message because this is probably just a back button
	// press or a similar interrupt
	if (edit == null) {
		return;
	}
		
	//link back to list of translations
	document.getElementById("tReturnToTranslations").innerHTML = "<span id=tReturnToTranslationsI>"+getUIString("ReturnToTranslationList")+"</span>";	
		
	var sense = edit.sense;

	//translations the system thinks are correct
	var highConfTranslations = new StringBuffer(
		"<div id='highConfTranslations' style='white-space: normal;' class='gwt-HTML'>\n" + 
		"\t<table id='highConfTranslationsTable' class='sense-table'>\n" +
		"\t<tbody>\n");

	//translatiosn the system is unsure about
	var mediumConfTranslations = new StringBuffer(
		"<div id='mediumConfTranslations' style='white-space: normal;' class='gwt-HTML'>\n" + 
		"\t<table id='mediumConfTranslationsTable' class='sense-table'>\n" +
		"\t<tbody>\n");
		
	//translations the system thinks are wrong
	var lowConfTranslations = new StringBuffer(
		"<div id='lowConfTranslations' style='white-space: normal; display: none;' class='gwt-HTML'>\n" + 
		"\t<table id='lowConfTranslationsTable' class='sense-table'>\n" +
		"\t<tbody>\n");
	
	var highConfCurrLang = -1;
	var mediumConfCurrLang = -1;
	var lowConfCurrLang = -1;
	
	var languages = sense.languages
	
	//for each language, sort into high, medium, and low confidence translations
	for (var languageIndex = 0; languageIndex < languages.length; languageIndex++){
		language = languages[languageIndex];
		var translations = language.translations;
		for (var translationIndex = 0; translationIndex < translations.length; translationIndex++) {
			var translation = translations[translationIndex];
			
			/*var newProbRight = (7.0*translation.probability+3.0)/10.0;
			var newProbWrong = -translation.probability/3.0;*/
			
			//indicate whether user is voting "correct" or "incorrect" - new probabilities will be calculated server-side
			var newProbRight = translation.probability;
			var newProbWrong;
			if (newProbRight == 0 && translation.linkProbability >= edit.link_prob_thresh) {
				newProbWrong = -1.0 - translation.linkProbability;
			} else {
				newProbWrong = (-1.0)*translation.probability;
			}
			
			//place translation in the correct table
			if (translation.probability >= edit.prob_ub){
				if (languageIndex != highConfCurrLang){
					highConfTranslations.append("\t\t<tr>\n"+
						"\t\t\t<td class='translation-language'>\n" +
							"\t\t\t\t<span id='cl" + languageIndex + "'><nobr>" + language.englishName + "</nobr>" +
							"</span>\n" +
						"\t\t\t</td>\n");
					highConfCurrLang = languageIndex;
				}
				else {
					highConfTranslations.append("\t\t<tr>\n\t\t\t<td class='translation-language'>&nbsp;</td>\n");
				}		
				highConfTranslations.append(
						"\t\t\t<td class='translation-value'>\n" +
							"\t\t\t\t<table style='width: 100%;' cellpadding='2' cellspacing='0'><tbody>\n" +
							"\t\t\t\t\t<tr>\n" +
								"\t\t\t\t\t\t<td style='width:100%'>" +
									translation.word + 
								"</td>\n" +
								"\t\t\t\t\t\t<td style='text-align:right;' class='rbIncorrect'>\n" +
									"\t\t\t\t\t\t\t<span id=cl"+languageIndex+"t"+translationIndex+"isIncorrect'>\n" +
									"\t\t\t\t\t\t\t\t<input type='radio' name='"+translation.id+"' value='"+newProbWrong+"'>\n" +
									"\t\t\t\t\t\t\t</span>\n" +
								"\t\t\t\t\t\t</td>\n" +
								"\t\t\t\t\t\t<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>\n" +
								"\t\t\t\t\t\t<td>\n"+
									"\t\t\t\t\t\t\t<span id=cl"+languageIndex+"t"+translationIndex+"noResponse'><input type='radio' name='"+translation.id+"' value='"+2+"' checked>\n" +
									"\t\t\t\t\t\t\t</span>\n" +
								"\t\t\t\t\t\t</td>\n" +
								"\t\t\t\t\t\t<td>&nbsp;&nbsp;</td>\n" +
								"\t\t\t\t\t\t<td>&nbsp;</td>\n" +
							"\t\t\t\t\t</tr>\n" +
							"\t\t\t\t</tbody></table>\n" +
						"\t\t\t</td>\n");					
				highConfTranslations.append("\t\t</tr>\n");
			}
			
			else if (translation.probability >= edit.prob_lb || translation.linkProbability >= edit.link_prob_thresh){
				if (languageIndex != mediumConfCurrLang){
					mediumConfTranslations.append(
						"<tr>\n"+
							"<td class='translation-language'>\n" +
								"\t\t\t\t<span id='ul" + languageIndex + "'><nobr>" + language.englishName + "</nobr>" +
								"</span>\n" +
							"</td>\n");
					mediumConfCurrLang = languageIndex;
				}
				else {
					mediumConfTranslations.append(
						"<tr>\n" +
							"<td class='translation-language'>&nbsp;</td>\n");
				}
				mediumConfTranslations.append(
						"<td class='translation-value'>" +
							"<table style='width: 100%;' cellpadding='2' cellspacing='0'><tbody><tr>" +
								"<td style='width:100%'>" +
									translation.word + 
								"</td>" +
								"<td style='text-align:right;' class='rbCorrect'>" +
									"<span id=ul"+languageIndex+"t"+translationIndex+"isCorrect'><input type='radio' name='"+translation.id+"' value='"+newProbRight+"'>" +
									"</span>" +
								"</td>" +
								"<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>" +
								"<td style='text-align:right;' class='rbIncorrect'>" +
									"<span id=ul"+languageIndex+"t"+translationIndex+"isIncorrect'><input type='radio' name='"+translation.id+"' value='"+newProbWrong+"'>" +
									"</span>" +
								"</td>"	+
								"<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>" +
								"<td>"+
									"<span id=ul"+languageIndex+"t"+translationIndex+"noResponse'><input type='radio' name='"+translation.id+"' value='"+2+"' checked>" +
									"</span>" +
								"</td>" +
								"<td>&nbsp;&nbsp;</td>" +
								"<td>&nbsp;</td>"  +
							"</tr></tbody></table>" +
						"</td>\n");					
				mediumConfTranslations.append("</tr>\n");
			}
			
			else {
				if (languageIndex != lowConfCurrLang){
					lowConfTranslations.append("<tr>"+
						"\t\t\t<td class='translation-language'>" +
							"<span id='il" + languageIndex + "'><nobr>" + language.englishName + "</nobr>" +
							"</span>" +
						"</td>\n");
					lowConfCurrLang = languageIndex;
				}
				else {
					lowConfTranslations.append("<tr>\t\t\t<td class='translation-language'>&nbsp;</td>\n");
				}
				lowConfTranslations.append(
						"\t\t\t<td class='translation-value'>" +
							"<table style='width: 100%;' cellpadding='2' cellspacing='0'><tbody><tr>" +
								"<td style='width:100%'>" +
									translation.word + 
								"</td>" +
								"<td style='text-align:right;' class='rbCorrect'>" +
									"<span id=il"+languageIndex+"t"+translationIndex+"isCorrect'><input type='radio' name='"+translation.id+"' value='"+newProbRight+"'>" +
									"</span>" +
								"</td>" +
								"<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>"  +
								"<td>"+
									"<span id=il"+languageIndex+"t"+translationIndex+"noResponse'><input type='radio' name='"+translation.id+"' value='"+2+"' checked>" +
									"</span>" +
								"</td>" +
								"<td>&nbsp;&nbsp;</td>"  +
								"<td>&nbsp;</td>"  +
							"</tr></tbody></table>" +
						"</td>\n");
				lowConfTranslations.append("\t\t</tr>\n");
			}
		}

	}
	
	//If any of the tables had no translations, display that message
	var no_translations = getUIString("NoTranslations");
	if (highConfCurrLang == -1) {
		highConfTranslations.append("<tr><td colspan='2'>"+no_translations+"</td></tr>");
	}
	if (mediumConfCurrLang == -1) {
		mediumConfTranslations.append("<tr><td colspan='2'>"+no_translations+"</td></tr>");		
	}
	if (lowConfCurrLang == -1) {
		lowConfTranslations.append("<tr><td colspan='2'>"+no_translations+"</td></tr>");	
	}
	
	var add_translation = getUIString("addTranslation");
	//links to add a translation
	highConfTranslations.append(
		"<tr id='AddTranslationEndRow3'>\n" +
			"<td class='translation-language' id='sOtherLanguageLanguage3'>" +
				"<span id='sOtherLanguageSpan3' style='text-decoration:underline;color:blue;cursor:pointer;'>" +
					"<nobr>"+add_translation+"</nobr>" +
				"</span>" +
			"</td>\n" +
			"<td class='translation-value' id='sOtherLanguageTranslation3' style='width:100%'>&nbsp;" +
			"</td>" +
		"</tr>\n");
	mediumConfTranslations.append(
		"<tr id='AddTranslationEndRow4'>\n" +
			"<td class='translation-language' id='sOtherLanguageLanguage4'>" +
				"<span id='sOtherLanguageSpan4' style='text-decoration:underline;color:blue;cursor:pointer;'>" +
					"<nobr>"+add_translation+"</nobr>" +
				"</span>" +
			"</td>\n" +
			"<td class='translation-value' id='sOtherLanguageTranslation4' style='width:100%'>&nbsp;" +
			"</td>" +
		"</tr>\n");
	lowConfTranslations.append(
		"<tr id='AddTranslationEndRow5'>\n" +
			"<td class='translation-language' id='sOtherLanguageLanguage5'>" +
				"<span id='sOtherLanguageSpan5' style='text-decoration:underline;color:blue;cursor:pointer;'>" +
					"<nobr>"+add_translation+"</nobr>" +
				"</span>" +
			"</td>\n" +
			"<td class='translation-value' id='sOtherLanguageTranslation5' style='width:100%'>&nbsp;" +
			"</td>" +
		"</tr>\n");
		
	highConfTranslations.append(
			"\t</tbody>\n" +
			"\t</table>\n" +
			"</div>\n");
	mediumConfTranslations.append(	
			"\t</tbody>\n" +
			"\t</table>\n" +
			"</div>\n");
	lowConfTranslations.append(
			"\t</tbody>\n" +
			"\t</table>\n" +
			"</div>\n");

	//render HTML		
	document.getElementById("highConfTranslationsHolder").innerHTML = highConfTranslations.toString();
	document.getElementById("mediumConfTranslationsHolder").innerHTML = mediumConfTranslations.toString();
	document.getElementById("lowConfTranslationsHolder").innerHTML = lowConfTranslations.toString();
	
	//show/hide appropriate panels and labels
	document.getElementById("tReturnToTranslations").style.display = "";
	document.getElementById("highConf").style.display = "";
	document.getElementById("highConfToEdit").style.display = "";
	gimages.showingHighConfTranslations = true;
	document.getElementById("mediumConf").style.display = "";
	document.getElementById("mediumConfToEdit").style.display = "";
	gimages.showingMediumConfTranslations = true;
	document.getElementById("lowConf").style.display = "";
	document.getElementById("lowConfToEdit").style.display = "";
	gimages.showingLowConfTranslations = false;
	document.getElementById("editTranslationsSubmit").style.display = "";
	
	hideMainResults();
	hideUncertainResults();
	
	gimages.showingEditTranslations = true;
	
	gimages.waiting = false;
}

/*
 * Submits edits, tells user their changes were submitted, then autorefreshes
 */
function editTranslations(form) {
	document.body.style.cursor = "wait";
	//If user was adding a translation, submit that translation to be added
	for (var i = 2; i < gimages.addingTranslation.length; i++) {
		if (gimages.addingTranslation[i] && document.addLanguagePanelEnd.isReady()) {
			document.body.style.cursor = "wait";	
			var sourceWord = gimages.sourceWord;
			var sourceLanguageID = gimages.langID;
		    var targetWord = document.addLanguagePanelEnd.autoCompleteTextBox.getText();
		    var targetLanguage = document.addLanguagePanelEnd.languageList.options[document.addLanguagePanelEnd.languageList.selectedIndex].innerHTML;
		    var targetLanguageID = document.addLanguagePanelEnd.languageList.options[document.addLanguagePanelEnd.languageList.selectedIndex].value;
		    var sense = gimages.info.senses[gimages.currentlyDisplayedState].description;
		   	sense = "\""+sense+"\"";
			var senseID = gimages.info.senses[gimages.currentlyDisplayedState].id;

			gimages.AJAXURLs.push(createURLAddTranslation(sourceWord, sourceLanguageID, targetWord, targetLanguageID, senseID));
			
			var url = gimages.AJAXURLs.pop();
			AjaxClient.invokeGet(url, false, gimages.finishAddTranslation);

			cancelAddTranslation(i+1);
		}
	}
	
	//build url
	var url = "EditTranslations?user="+gimages.userid+"&sense="+gimages.info.senses[gimages.currentlyDisplayedState].id;
	var url2 = getFormValues(form, url);
	//if changes were made, submit edits and display a message
	if (url != url2) {
		AjaxClient.invokeGet(url2, false, null);
		var messagesDiv = document.getElementById("messagesDiv");
		var messagesDiv3 = document.getElementById("messagesDiv3");
		var message = "<div style='text-align: center'>"+getUIString("ChangesSubmitted")+"</div>";
		messagesDiv.innerHTML = message;
		messagesDiv.style.display = "";
		messagesDiv3.innerHTML = message;
		messagesDiv3.style.display = "";	
		//refresh page at the current sense
		gimages.initialSense = gimages.info.senses[gimages.currentlyDisplayedState].id;
		gimages.currentlyDisplayedState = -1;
		refreshTranslationList();
	}

	//display main results
	cancelEditTranslations();
	document.body.style.cursor = "default";
}

/*
 * Hide editing interface, show main results page
 */
function cancelEditTranslations() {
	gimages.showingEditTranslations = false;
	document.getElementById("tReturnToTranslations").style.display = "none";
	document.getElementById("highConf").style.display = "none";
	document.getElementById("highConfToEdit").style.display = "none";
	document.getElementById("viewHighConfI").innerHTML=getUIString("show");
	gimages.showingHighConfTranslations = false;
	document.getElementById("mediumConf").style.display = "none";
	document.getElementById("mediumConfToEdit").style.display = "none";
	document.getElementById("viewMediumConfI").innerHTML=getUIString("hide");
	gimages.showingMediumConfTranslations = false;
	document.getElementById("lowConf").style.display = "none";
	document.getElementById("lowConfToEdit").style.display = "none";
	document.getElementById("viewLowConfI").innerHTML=getUIString("show");
	gimages.showingLowConfTranslations = false;
	document.getElementById("editTranslationsSubmit").style.display = "none";
	
	showMainResults();
}

/*
 * Show/hide the list of high confidence translations
 */
function viewHighConf() {
	var viewHighConf = document.getElementById("viewHighConfI");
	
	if(gimages.showingHighConfTranslations==true) {
		document.getElementById("highConfTranslations").style.display = "none";
		gimages.showingHighConfTranslations = false;
		viewHighConf.innerHTML=getUIString("show");
	} else {
		document.getElementById("highConfTranslations").style.display = "block";
		gimages.showingHighConfTranslations = true;
		viewHighConf.innerHTML=getUIString("hide");	
	}
}

/*
 * Show/hide the list of medium confidence translations
 */
function viewMediumConf() {
	var viewMediumConf = document.getElementById("viewMediumConfI");
	
	if(gimages.showingMediumConfTranslations==true) {
		document.getElementById("mediumConfTranslations").style.display = "none";
		gimages.showingMediumConfTranslations = false;
		viewMediumConf.innerHTML=getUIString("show");
	} else {
		document.getElementById("mediumConfTranslations").style.display = "block";
		gimages.showingMediumConfTranslations = true;
		viewMediumConf.innerHTML=getUIString("hide");
	}
}

/*
 * Show/hide the list of low confidence translations
 */
function viewLowConf() {
	var viewLowConf = document.getElementById("viewLowConfI");
	
	if(gimages.showingLowConfTranslations==true) {
		document.getElementById("lowConfTranslations").style.display = "none";
		gimages.showingLowConfTranslations = false;
		viewLowConf.innerHTML=getUIString("show");
	} else {
		document.getElementById("lowConfTranslations").style.display = "block";
		gimages.showingLowConfTranslations = true;
		viewLowConf.innerHTML=getUIString("hide");
	}
}

/**
 * Editing senses functions
 */
 
/*
 * Display a list of senses to edit, forces user to log in.
 */
function getSenses() {
	//hide old messages
	document.getElementById("messagesDiv").style.display = "none";
	document.getElementById("messagesDiv3").style.display = "none";
	//hide edit translations results
	if (gimages.showingEditTranslations){
		cancelEditTranslations();
	}
	//if there is no user logged in, display login screen
	if (gimages.userid == 0) {
		gimages.loc.push(-2);
		showLogin();
	} 
	//retrieve list of senses while displaying a "loading..." message
	else {
		document.body.style.cursor = "wait";		
		var messagesDiv = document.getElementById("messagesDiv2");
		messagesDiv.innerHTML = getUIString("loading");
	
		messagesDiv.style.display="block";
	    gimages.waiting = true;
	    var waitTimer = -1;
	    var me = gimages;
	    var dots = 0;
	    var waitFunc = function( ) {
	        if ( me.waiting && dots <= 85) {
	        	messagesDiv.innerHTML += ".";
	        	dots++;
	        } else {
	        	if (dots > 85){
	        		// This error message isn't strictly true.  The website
	        		// will continue to wait for the transaction to complete
	        		// but, since it probably won't, it's nice to tell the
	        		// client something went wrong.
	        		messagesDiv.innerHTML += "connection timed out!"
	        	} else {
	        		messagesDiv.style.display = "none";
	        	}
	 
	        	window.clearInterval(waitTimer);
	        	waitTimer = -1;
	        }
	    }
	    waitTimer = window.setInterval(waitFunc, 500);
		var url = "GetSensesToEdit?word="+gimages.sourceWord+"&language="+gimages.langID;
		url += "&stamp="+(new Date()).getTime();
		AjaxClient.invokeGet(url, false, gimages.processSenses);	
		document.body.style.cursor = "default";
	}
}

/*
 * Build the table of senses to edit
 */
GImages.prototype.processSenses = function ( responseText ) {
	var response = responseText.parseJSON(null);
	var senses = response.senses;
	var prob_thresh = response.prob_threshold;
	
	document.getElementById("sensesPanelCaption").innerHTML = getUIString("TransForWord").replace("[Word]", "\""+response.sourceword+"\"");
	var highConfSenses = new StringBuffer("<table id='HighConfSensesTable' class='sense-table' style='width: 100%;'><tbody>");
	var lowConfSenses = new StringBuffer("<table id='LowConfSensesTable' class='sense-table' style='width: 100%;'><tbody>");
	
	for (var senseIndex = 0; senseIndex < senses.length; senseIndex++) {
		
		var sense = senses[senseIndex];			
		/*var newProbRight = (7.0*sense.probability+3.0)/10.0;
		var newProbWrong = -sense.probability/3.0;*/
		//indicate whether user is voting "correct" or "incorrect"
		var newProbRight = sense.probability;
		var newProbWrong = (-1.0)*sense.probability;
		
		var editSenses;
		//add to correct table based on probability
		if (sense.probability >= prob_thresh) {
			editSenses = highConfSenses;
		} else {
			editSenses = lowConfSenses;
		}
		editSenses.append(
				"<tr><td class='translation-value'>" +
					"<table style='width: 100%;' cellpadding='2' cellspacing='0'><tbody><tr>" +
						"<td style='width:100%'>" +
							sense.description + 
						"</td>" +
						"<td style='text-align:right;' class='rbCorrect'>" +
							"<span id=s"+senseIndex+"isCorrect'><input type='radio' name='"+sense.id+"' value='"+newProbRight+"'>\t\t" +
							"</span>" +
						"</td>" +
						"<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>" +
						"<td style='text-align:right;' class='rbIncorrect'>" +
							"<span id=s"+senseIndex+"isIncorrect'><input type='radio' name='"+sense.id+"' value='"+newProbWrong+"'>" +
							"</span>" +
						"</td>"	+
						"<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>" +
						"<td>"+
							"<span id=s"+senseIndex+"noResponse'><input type='radio' name='"+sense.id+"' value='"+2+"' checked>" +
							"</span>" +
						"</td>" +
						"<td>&nbsp;&nbsp;</td>" +
					"</tr></tbody></table>" +
				"</td></tr>\n");					
	}
	highConfSenses.append("</tbody></table>");
	lowConfSenses.append("</tbody></table>");
/*editSenses.append(
			"\t</tbody>\n" +
			"\t</table>\n" +
			"</div>\n"+
			"</td></tr>");	
	editSenses.append(
			"<tr>" +
				"<td style='text-align:right' class='ks-Info'>" +
					"<INPUT type='button' value='"+getUIString("Submit")+"' onclick='javascript:editSenses(((this.parentNode).parentNode).parentNode)'>" +
					"<INPUT type='button' value='"+getUIString("CancelButton")+"' onclick='javascript:cancelEditSenses()'>" +
				"</td>" +
			"</tr>");
	editSenses.append(
			"\t</tbody>\n" +
			"\t</table>\n");
*/
	//render HTML
	document.getElementById("highConfSenses").innerHTML = highConfSenses.toString();
	document.getElementById("lowConfSenses").innerHTML = lowConfSenses.toString();
	
	//show/hide appropriate panels and labels
	document.getElementById("editSensesHolder").style.display = "block";
	document.getElementById("sReturnToTranslations").style.display = "";
	document.getElementById("sensesHolder").style.display = "none";
	document.getElementById("translationsHolder").style.display = "none";
	document.getElementById("selectMeaning").style.display = "none";
	document.getElementById("editMeanings").style.display = "none";
	
	gimages.waiting = false;
}

/*
 * Submits edits, tells user their changes were submitted, then autorefreshes
 */
function editSenses(form){
	document.body.style.cursor = "wait";
	//build url
	var url = "EditSenses?word="+gimages.sourceWord+"&language="+gimages.langID+"&user="+gimages.userid;
	var url2 = getFormValues(form, url);
	//if changes were made, submit changes and display a message
	if (url != url2){
		AjaxClient.invokeGet(url2, false, null);	
		var messagesDiv = document.getElementById("messagesDiv");
		var messagesDiv3 = document.getElementById("messagesDiv3");
		var message = "<div style='text-align:center'>"+getUIString("ChangesSubmitted")+"</div>";
		messagesDiv.innerHTML = message;
		messagesDiv.style.display = "";
		messagesDiv3.innerHTML = message;
		messagesDiv3.style.display = "";
		//autorefresh
		refreshTranslationList();
	}
	//hide edit senses interface
	cancelEditSenses();
	document.body.style.cursor = "default";
}

/*
 * Hide editing interface, show main results page
 */
function cancelEditSenses() {
	document.getElementById("editSensesHolder").style.display = "none";
	if (document.getElementById("sReturnToTranslations") != null) {
		document.getElementById("sReturnToTranslations").style.display = "none";
	}	
	
	document.getElementById("sensesHolder").style.display = "";
	document.getElementById("translationsHolder").style.display = "";
	document.getElementById("selectMeaning").style.display = "";
	document.getElementById("editMeanings").style.display = "";
	
	if (gimages.showingEditTranslations){
		cancelEditTranslations();
	}
}

/*
 * Show main results & associated labels.
 */
function showMainResults(){
	document.getElementById("majorLangs").style.display = "";
	document.getElementById("et0").style.display = "";
	document.getElementById("majorTranslationsHolder").style.display = "";
	//document.getElementById("otherLangs").style.display = "";
	//document.getElementById("et1").style.display = "";
	//document.getElementById("allTranslationsHolder").style.display = "";
	document.getElementById("uncertainLangs").style.display = "";
	document.getElementById("et2").style.display = "";	
	document.getElementById("chooseTransLanguage").style.display = "";
}

/*
 * Hide main results & associated labels;
 */
function hideMainResults(){
	document.getElementById("majorLangs").style.display = "none";
	document.getElementById("et0").style.display = "none";
	document.getElementById("majorTranslationsHolder").style.display = "none";
	//document.getElementById("otherLangs").style.display = "none";
	//document.getElementById("et1").style.display = "none";
	//document.getElementById("allTranslationsHolder").style.display = "none";
	document.getElementById("uncertainLangs").style.display = "none";
	document.getElementById("et2").style.display = "none";	
	document.getElementById("chooseTransLanguage").style.display = "none";
}

/*
 * Hide uncertain results and associated labels.
 */
function hideUncertainResults() {
	document.getElementById("uncertainLangs").style.display = "none";
	document.getElementById("et2").style.display = "none";
	document.getElementById("chooseTransLanguage").style.display = "none";
	//document.getElementById("newTranslationsHolder").style.display = "none";
	//document.getElementById("newTranslationsLanguageHolder").style.display = "none";
	document.getElementById("uncertainTranslationsHolder").style.display = "none";
	//document.getElementById("checkTransNavigation").style.display = "none";		
}

/*
 * Refresh list of translations (similar to getEngViaXMLHttp)
 */
function refreshTranslationList() {
	gimages.currentlyDisplayedState = -1;
	gimages.showingMoreTranslations = new Array();
	var messagesDiv = document.getElementById("messagesDiv2");
	messagesDiv.style.textAlign = "center";
	messagesDiv.innerHTML = getUIString("RefreshingTranslations");

	messagesDiv.style.display="block";

    this.waiting = true;
    var waitTimer = -1;
    var me = this;
    var dots = 0;
    var waitFunc = function( ) {
        if ( me.waiting && dots <= 85) {
        	messagesDiv.innerHTML += ".";
        	dots++;
        } else {
        	if (dots > 85)
        		// This error message isn't strictly true.  The website
        		// will continue to wait for the transaction to complete
        		// but, since it probably won't, it's nice to tell the
        		// client something went wrong.
        		messagesDiv.innerHTML += "connection timed out!"
 
        	window.clearInterval(waitTimer);
        	waitTimer = -1;
        }
    }
    waitTimer = window.setInterval(waitFunc, 500);

   	gimages.searchForTranslation();
}

/* old functionality, not in use?  ~ono 8/11/2008*/
function addThisWord() {
	var addThisWordSpan = document.getElementById("AddNewWord");
	if(addThisWordSpan.style.color=="black") return; //make sure "yes" is only active when blue
	addThisWordSpan.style.color="black";
	addThisWordSpan.style.textDecoration="none";
	addThisWordSpan.style.cursor="text";
	var cancelAddNewWordSpan = document.getElementById("CancelAddNewWord");
	cancelAddNewWordSpan.style.color="black";
	cancelAddNewWordSpan.style.textDecoration="none";
	cancelAddNewWordSpan.style.cursor="text";
	
	if(gimages.langID==-1) {
		askForLanguage();
	} else {
		readyForTranslation();
	}
}
function askForLanguage() {
	var messagesDiv = document.getElementById("messagesDiv");
    var temp = document.createElement("p");
    temp.innerHTML = getUIString("specifyLanguageOfWord").replace("[word]",gimages.sourceWord);

	messagesDiv.appendChild(temp);
 	
	temp = document.createElement("div");
	temp.innerHTML=
			"<table>" +
			"<tr>" +
			"<td>" +
			"	<select id='specifyLanguagePanel' size='1' style='height:20px;width:200' dir='ltr'>" +
			"</td>" +
			"<td style='border-width:3'>" +
			"	<span id='OKLanguage' style='cursor:pointer;text-decoration:underline;color:blue'>"+getUIString("ok")+"</span>&nbsp; " +
			"	<span id='CancelLanguage' style='cursor:pointer;text-decoration:underline;color:blue'>"+getUIString("cancel")+"</span>"
			"</td>" +
			"</tr>" +
			"</table>" +
			
			
	messagesDiv.appendChild(temp);

	var p = document.getElementById("specifyLanguagePanel");
	populateLanguageSelectBox(p);
}
function okLanguage() {
	var temp = document.getElementById("specifyLanguagePanel");
	if(temp.value==-1) return;
	gimages.langID=temp.value;
	document.searchPanel.setSearchLanguageID(temp.value);
	temp.disabled=true;
	
	temp = document.getElementById("OKLanguage");
	if(temp.style.color=="black") return; //make sure "OK" is only active when blue
	temp.style.color="black";
	temp.style.textDecoration="none";
	temp.style.cursor="text";
	temp = document.getElementById("CancelLanguage");
	temp.style.color="black";
	temp.style.textDecoration="none";
	temp.style.cursor="text";
	
	readyForTranslation();
}
function cancelLanguage() {
	var temp = document.getElementById("CancelLanguage");
	if(temp.style.color=="black") return; //make sure "CANCEL" is only active when blue.

	cancelT();	
}
function readyForTranslation() {
	var messagesDiv = document.getElementById("messagesDiv");
    var temp = document.createElement("p");
    temp.innerHTML = getUIString("provideTranslation").replace("[word]",gimages.sourceWord);
    
    /*advanced interface stuff.  obsolete.  ~ono
     * readded per Oren's request ~chris */
    if (gimages.advanced) {
	    document.getElementById("btnShowTranslations1").style.display = "none";
	    document.getElementById("btnShowTranslations2").style.display = "none";
    }
	/**/

	messagesDiv.appendChild(temp);
 	
	temp = document.createElement("div");
	temp.innerHTML=
			"<table>" +
			"<tr>" +
			"<td>" +
			"	<select id='cmbAddMissingLanguagePanel' size='1' style='height:20px;width:200' dir='ltr'>" +
			"</td>" +
			"<td>" +
			"	<input type='text' id='txtAddMissingLanguagePanel' style='width:200;'/>" +
			"</td>" +
			"<td style='border-width:3'>" +
			"	<span id='OKTranslation' style='cursor:pointer;text-decoration:underline;color:blue'>"+getUIString("ok")+"</span>&nbsp; " +
			"	<span id='CancelTranslation' style='cursor:pointer;text-decoration:underline;color:blue'>"+getUIString("cancel")+"</span>"
			"</td>" +
			"</tr>" +
			"</table>" +
			
			
	messagesDiv.appendChild(temp);

	var p = document.getElementById("cmbAddMissingLanguagePanel");
	populateLanguageSelectBox(p);
	document.addLanguagePanelEnd = new AddMissingLanguagePanel();
}
/*does not appear to actually be called from anywhere. presumed obsolete. ~ono 7/15/2008
function okTranslation() {
	var okTranslationSpan = document.getElementById("OKTranslation");
	if(okTranslationSpan.style.color=="black") return; //make sure "OK" is only active when blue.

	if(!document.addLanguagePanelEnd.isReady()) {
		return;
	}
	
	var resultsTable = document.getElementById("resultsTable");
	resultsTable.style.display="none";

	var messagesDiv = document.getElementById("messagesDiv");
	var temp = document.createElement("div");
	temp.innerHTML=								
		"<br/>" +
		"<p><span id='statusMessage'>"+getUIString("loading")+"</span></p>";
	messagesDiv.appendChild(temp);
	
	var statusMessage = document.getElementById("statusMessage");	
	
    gimages.waiting = true;
    var waitTimer = -1;
    var me = this;
    var dots = 0;
    var waitFunc = function( ) {
        if ( gimages.waiting && dots <= 85) {
        	statusMessage.innerHTML += ".";
        	dots++;
        } else {
        	if (dots > 85)
        		// This error message isn't strictly true.  The website
        		// will continue to wait for the transaction to complete
        		// but, since it probably won't, it's nice to tell the
        		// client something went wrong.
        		statusMessage.innerHTML += "connection timed out!"
 
        	window.clearInterval(waitTimer);
        	waitTimer = -1;
        }
    }
    waitTimer = window.setInterval(waitFunc, 500);

	var word = document.addLanguagePanelEnd.getQueryText();
	var languageID = document.addLanguagePanelEnd.getSearchLanguageID();
	    	
    var encodedWord = encodeURIComponent(word);
	var encodedLanguageID = encodeURIComponent(languageID);
	
    var url = "WiktionaryWrapper?word=" + encodedWord + "&sourceLanguage=" + encodedLanguageID;

   	if ( document.debugParameters ) {
   		for ( var i = 0; i < document.debugParameters.length; i++ ) {
   			if ( document.debugParameters[i].checkbox.checked )
	   			queryString += "&" + document.debugParameters[i].key + "=" + encodeURIComponent(document.debugParameters[i].textbox.value);
   		}
   	}

    url += "&stamp=" + (new Date()).getTime();
    gimages.currentlyAddingWord = true;
    AjaxClient.invokeGet(url, true, gimages.onOKTranslationComplete);	
}
*/
/*does not appear to actually be called from anywhere.  presumed obsolete. ~ono 7/15/2008
function finalOK() {
	var span = document.getElementById("FinalOK");
	if(span.style.color=="black") return; //make sure "OK" is only active when blue
	
	if(getSelectedSenseIndices().length==0) {
		var alertMessage=document.getElementById("alertMessage");
		alertMessage.innerHTML=getUIString("mustSelectSense");
		alertMessage.style.display="inline";
	} else {
		span.style.color="black";
		span.style.textDecoration="none";
		span.style.cursor="text";
		span = document.getElementById("FinalCancel");
		span.style.color="black";
		span.style.textDecoration="none";
		span.style.cursor="text";
		
		for ( var senseIndex = 0; senseIndex < gimages.info.senses.length; senseIndex++ ) {
			var checkboxID = "s" + senseIndex + "checkbox";
			var checkbox = document.getElementById(checkboxID);
			checkbox.disabled=true;
		}
		
		
		var statusMessage=document.getElementById("statusMessage");
		statusMessage.innerHTML=getUIString("addingTranslation")+"...";
		statusMessage.style.color="green";
		
		var sourceWord = gimages.sourceWord;
		var sourceLanguageID = gimages.langID;
		var targetWord = document.addLanguagePanelEnd.getQueryText();
		var targetLanguageID = document.addLanguagePanelEnd.getSearchLanguageID();
		
		var dominantSenses = new Array();
		var selectedSenseIndices = getSelectedSenseIndices();
		for(var i=0; i<selectedSenseIndices.length; i++) {
			if(gimages.info.senses[selectedSenseIndices[i]].size > 2) {				
				dominantSenses.push(gimages.info.senses[selectedSenseIndices[i]].senseID);
			}
			else {
				//We don't need to worry about the garbage sense because it was removed.
				gimages.AJAXURLs.push(createURLAddHack(targetWord, targetLanguageID, sourceWord, sourceLanguageID, gimages.info.senses[selectedSenseIndices[i]]));
			}
		}
		if(dominantSenses.length>0) gimages.AJAXURLs.push(createURLAddTranslation(targetWord, targetLanguageID, sourceWord, sourceLanguageID, dominantSenses));
		gimages.whenAJAXDone = finishedWhichSense;
		doAJAX();
	}
}

function finishedWhichSense() {
	var statusMessage=document.getElementById("statusMessage");
	statusMessage.innerHTML=getUIString("thankYou");
}

function cancelAddNewWord() {
	var addThisWordSpan = document.getElementById("AddNewWord");
	if(addThisWordSpan.style.color=="black") return; //make sure "no" is only active when blue.

	cancelT();	
}

function cancelTranslation() {
	var cancelTranslationSpan = document.getElementById("CancelTranslation");
	if(cancelTranslationSpan.style.color=="black") return; //make sure "CANCEL" is only active when blue.
	
	cancelT();
}

function finalCancel() {
	var span = document.getElementById("FinalCancel");
	if(span.style.color=="black") return; //make sure "Cancel" is only active when blue
	
	var resultsTable = document.getElementById("resultsTable");
	resultsTable.style.display="none";
	var internationalDiv = document.getElementById("hideMeWhileSearching");
	internationalDiv.style.display="none";
	document.getElementById("hideMeWhileSearching2").style.display="none";
	
	cancelT();
}

function cancelT() {
	var messagesDiv = document.getElementById("messagesDiv");
		messagesDiv.innerHTML = "";
		messagesDiv.style.display = "none";
	document.searchPanel.setFocus();
}

/*old user editing.  obsolete. ~ono 7/15/2008
function removeTranslation(targ) {
	gimages.removingTranslation = true;
	var idExtractor = /s(\d+)l(\d+)t(\d+)RemoveTranslation/;
	var extracted= idExtractor.exec(targ.id);
	if( extracted == null ) {
		alert("error now");
	}
	var sIndex = extracted[1];
	var lIndex = extracted[2];
	var tIndex = extracted[3];
	
	gimages.markedSenseIndex = sIndex;
	gimages.markedLanguageIndex = lIndex;
	gimages.markedTranslationIndex = tIndex;

	hideXs();
	hideAddTranslation()

	//get translation	
	var transSpanId = "s"+sIndex+"l"+lIndex+"t"+tIndex;
	var transSpan = document.getElementById(transSpanId);
	var translation = transSpan.firstChild.nodeValue;
	
	gimages.savedHTML = transSpan.innerHTML;
	transSpan.innerHTML = 
			"<span style='color:red;text-decoration:line-through'>" +
			"<span class='translation-span' style='text-decoration:none'>"+translation+
			"</span>" +
			"</span>";
	
	//display options to confirm or undo removal
	var ok = document.getElementById("s"+sIndex+"l"+lIndex+"t"+tIndex+"ConfirmRemoveTranslation");
	ok.style.display = "inline";
	var cancel = document.getElementById("s"+sIndex+"l"+lIndex+"t"+tIndex+"CancelRemoveTranslation");
	cancel.style.display = "inline";
	var space = document.getElementById("s"+sIndex+"l"+lIndex+"t"+tIndex+"Space");
	space.style.display = "inline";
}

function confirmRemoveTranslation(targ) {	
	var idExtractor = /s(\d+)l(\d+)t(\d+)ConfirmRemoveTranslation/;
	var extracted= idExtractor.exec(targ.id);
	if( extracted == null ) {
		alert("error");
	}
	var sIndex = extracted[1];
	var lIndex = extracted[2];
	var tIndex = extracted[3];
	var remove_sense = gimages.info.senses[sIndex].senseID;
	var remove_lang_id = gimages.info.senses[sIndex].languages[lIndex].id;
	var remove_word = gimages.info.senses[sIndex].languages[lIndex].translations[tIndex].translation;
		
	var word = document.searchPanel.getQueryText();
	var sourceLanguage = document.searchPanel.getSearchLanguageID();
	
    queryString = "?word=" + encodeURIComponent(word);
    queryString += "&lang=" + sourceLanguage;
	queryString += "&remove_word=" + encodeURIComponent(remove_word);
    queryString += "&remove_lang=" + encodeURIComponent(remove_lang_id);
    queryString += "&remove_sense=" + remove_sense;
    for(var i=0; i<remove_senses.length; i++) {
    	queryString += "&remove_sense=" + remove_senses[i];
    }
	
	gimages.AJAXURLs.push("RemoveTranslation"+queryString);
	gimages.whenAJAXDone=reloadPageAtSense;
	doAJAX();
}

function cancelRemoveTranslation() {	
	var sIndex=gimages.markedSenseIndex;
	var lIndex=gimages.markedLanguageIndex;
	var tIndex=gimages.markedTranslationIndex;
	
	var transSpanID = "s"+sIndex+"l"+lIndex+"t"+tIndex;
	var transSpan = document.getElementById(transSpanID);
	transSpan.innerHTML = gimages.savedHTML;
	
	//remove options to confirm or undo removal
	var ok = document.getElementById("s"+sIndex+"l"+lIndex+"t"+tIndex+"ConfirmRemoveTranslation");
	ok.style.display = "none";
	var cancel = document.getElementById("s"+sIndex+"l"+lIndex+"t"+tIndex+"CancelRemoveTranslation");
	cancel.style.display = "none";
	var space = document.getElementById("s"+sIndex+"l"+lIndex+"t"+tIndex+"Space");
	space.style.display = "none";
	
	if(gimages.advanced) showXs();
	
	showAddTranslation();
	gimages.removingTranslation = false;
}
*/
/*advanced interface stuff.  obsolete. ~ono
 * readded per Oren's request. ~chris */
function hideXs() {
	var translationsHolder = document.getElementById("translationsHolder");
	var xs = getElementsByClass("RemoveTranslation",translationsHolder,"span");
	for ( var i=0; i<xs.length; i++ ) {
		xs[i].style.display="none";
	}
}
function showXs() {
	var translationsHolder = document.getElementById("translationsHolder");
	var xs = getElementsByClass("RemoveTranslation",translationsHolder,"span");
	for ( var i=0; i<xs.length; i++ ) {
		xs[i].style.display="inline";
	}	
}
/**/
/*not called from anywhere. ~ono 7/16/2008
function showAddTranslation() {
	var sIndex = gimages.currentlyDisplayedState;	
	var row = document.getElementById("s"+sIndex+"AddTranslationEndRow");
	row.style.display="";
}

function hideAddTranslation() {
	var sIndex = gimages.currentlyDisplayedState;	
	var row = document.getElementById("s"+sIndex+"AddTranslationEndRow");
	row.style.display="none";
}
*/

/*
 * Miscellaneous useful functions
 */
function getElementsByClass(searchClass,node,tag) {
	var classElements = new Array();
	if ( node == null )
		node = document;
	if ( tag == null )
		tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp('(^|\\s)'+searchClass+'(\\s|$)');
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}
function openGoogleImages(searchLangName, searchLangID, searchTerm, queryLangs, queryString, senseIndex, submitMultiple) {
    logSubmission(searchLangName, searchTerm, queryLangs, queryString, senseIndex, submitMultiple);
	window.open("showresults.jsp?q=" + encodeURI( queryString ) + "&previous=" + encodeURIComponent("GImages.jsp?word=" + searchTerm + "&lang=" + searchLangID), "_self");
}
function logSubmission(searchLang, searchTerm, queryLangs, queryString, senseIndex, submitMultiple) {
	// Parameters:
	//	searchTerm
	//	searchLang
	//	showTerms
	//	showLangs
	//	showSense
	//	submitMultiple
    var encodedSearchTerm = encodeURIComponent( searchTerm );
    var encodedSearchLang = encodeURIComponent( searchLang );
    var encodedShowTerms = encodeURIComponent( queryString );
    var encodedShowLangs = encodeURIComponent( queryLangs );
    var url = "SubmissionLogger";
    var parameter = 
    		"searchTerm=" + encodedSearchTerm +
    		"&searchLang=" + encodedSearchLang +
    		"&showTerms=" + encodedShowTerms +
    		"&showLangs=" + encodedShowLangs +
    		"&showSense=" + senseIndex +
    		"&submitMultiple=" + submitMultiple;
    AjaxClient.invokePost(url, parameter, true, null);
}


/**
 * Adding translation functions
 */
 
/*
 * Show translation editing interface
 */
function addTranslation(loc) {
	//clear old messages
	document.getElementById("messagesDiv").style.display = "none";
	document.getElementById("messagesDiv3").style.display = "none";
	
	//if there is no user logged in, display login screen
	if(gimages.userid == 0) {
		gimages.loc.push(loc);
		showLogin();
	} 
	else {
		//set the appropriate variable - keeps track of which "add translation" panel is being displayed	
		if (loc == 1) {
			gimages.addingTranslation[0] = true;
		} else if (loc == 2) {
			gimages.addingTranslation[1] = true;
		} else if (loc == 3) {
			gimages.addingTranslation[2] = true;
		} else if (loc == 4) {
			gimages.addingTranslation[3] = true;
		} else if (loc == 5) {
			gimages.addingTranslation[4] = true;
		}
	
		//hideXs();	
		
		var sIndex;
		if (loc < 3) {
			sIndex = gimages.currentlyDisplayedState;
		} else {
			sIndex = "";
		}
		
		//display translation adding interface row
		var languageCell = document.getElementById("s"+sIndex+"OtherLanguageLanguage"+loc);
		var width = "100%";
		if(gimages.maxLanguageLength[sIndex]<25) width = 200;
		languageCell.innerHTML = "<select id='cmbAddMissingLanguagePanel"+loc+"' size='1' style='height: 20px;width="+width+"' dir='ltr'>";
		languageCell.style.width="200";
	
		var translationCell = document.getElementById("s"+sIndex+"OtherLanguageTranslation"+loc);
		translationCell.innerHTML = 
				"<table cellspacing='0' cellpadding='0' style='width:100%'><tbody><tr>" +
				"<td style='width:100%'>" +
				"	<input type='text' id='txtAddMissingLanguagePanel"+loc+"' style='width:95%;'></input>" +  //for some reason, I can't get border-style to work without doing border-color
				"</td>";
		if ( loc < 3) {
			translationCell.innerHTML +=				
				"<td>" +
				"	<nobr><span id='s" + sIndex + "ConfirmAddTranslation"+loc+"' style='cursor:pointer;text-decoration:underline;color:blue'>"+getUIString("ok")+"</span></nobr>" +
				"</td>" +
				"<td>" +
				"	&nbsp;<nobr><span id='s" + sIndex + "CancelAddTranslation"+loc+"' style='cursor:pointer;text-decoration:underline;color:blue'>"+getUIString("cancel")+"</span></nobr>"
				"</td>";
		}
		
		translationCell.innerHTML += "</tr></tbody></table>";
	
		//fill in language selection choices
		var p = document.getElementById("cmbAddMissingLanguagePanel"+loc);
		populateLanguageSelectBox(p);
	
		document.addLanguagePanelEnd = new AddMissingLanguagePanel(loc);
	}
}

/*
 * Add translation
 */
function confirmAddTranslation() {
	//check if there is a translation to be submitted
	if(!document.addLanguagePanelEnd.isReady()) {
		return;
	}
	document.body.style.cursor = "wait";	
	var sourceWord = gimages.sourceWord;
	var sourceLanguageID = gimages.langID;
    var targetWord = document.addLanguagePanelEnd.autoCompleteTextBox.getText();
    var targetLanguage = document.addLanguagePanelEnd.languageList.options[document.addLanguagePanelEnd.languageList.selectedIndex].innerHTML;
    var targetLanguageID = document.addLanguagePanelEnd.languageList.options[document.addLanguagePanelEnd.languageList.selectedIndex].value;
    var sense = gimages.info.senses[gimages.currentlyDisplayedState].description;
   	sense = "\""+sense+"\"";
	var senseID = gimages.info.senses[gimages.currentlyDisplayedState].id;
	//var size = gimages.info.senses[gimages.currentlyDisplayedState].size;
/*	if(gimages.info.senses[gimages.currentlyDisplayedState].is_garbage==true) {
		gimages.AJAXURLs.push(createURLAddNewSense(sourceWord, sourceLanguageID, targetWord, targetLanguageID));
	}
	else*/ /*if(size > 2) {*/
		gimages.AJAXURLs.push(createURLAddTranslation(sourceWord, sourceLanguageID, targetWord, targetLanguageID, senseID));
	/*}*/
	/*else {
		gimages.AJAXURLs.push(createURLAddHack(sourceWord, sourceLanguageID, targetWord, targetLanguageID, gimages.info.senses[gimages.currentlyDisplayedState]));
	}*/
	//gimages.whenAJAXDone=reloadPageAtSense;
	//doAJAX();
	
	//submit new translation
	var url = gimages.AJAXURLs.pop();
	AjaxClient.invokeGet(url, false, gimages.finishAddTranslation);

	//tell user that their translation has been added or that it already existed in the database.
	var messagesDiv = document.getElementById("messagesDiv");
	var messagesDiv3 = document.getElementById("messagesDiv3");
	if (gimages.translationAdded) {
		var message = "<div id='atMessage' style='text-align: center'>"+getUIString("TranslationAdded").replace("[Word]", "<b>\""+targetWord+"\"</b>").replace("[Language]", "<b>"+targetLanguage+"</b>").replace("[Sense]", sense)+"</div>";
	} else {
		var message = "<div id='atMessage' style='text-align: center'>"+getUIString("TranslationExists").replace("[Word]", "<b>\""+targetWord+"\"</b>").replace("[Sense]", sense)+"</div>";
	}
	messagesDiv.innerHTML = message;
	messagesDiv3.innerHTML = message;
	messagesDiv.style.display = "";
	messagesDiv3.style.display = "";

	//hide adding translation interface rows
	for (var i=0; i < gimages.addingTranslation.length; i++){
		if (gimages.addingTranslation[i]) {
			cancelAddTranslation(i+1);
		}
	}
	
	//auto-refresh
	gimages.initialSense = gimages.info.senses[gimages.currentlyDisplayedState].id;
	gimages.currentlyDisplayedState = -1;
	refreshTranslationList();


/* translationsLong no longer in use.  ~ono 8/8/2008
	var translationsLong = document.getElementById("newTranslationsHolder");
	var senseTranslationsLong = document.getElementById("s"+gimages.currentlyDisplayedState+"NewTranslationsLong");
	if (senseTranslationsLong != null && senseTranslationsLong != "null") {
		translationsLong.removeChild(senseTranslationsLong);
	}
	translationsLong.style.display="none";
*/ 
	document.body.style.cursor = "default";
}

/*
 * Find out if translation was accepted (or already existed)
 */
GImages.prototype.finishAddTranslation = function (responseText) {
	if (responseText == "This translation already exists.") {
		gimages.translationAdded = false;
	} else {
		gimages.translationAdded = true;
	}
}

/*
 * Hide translation adding interface row at given location
 */
function cancelAddTranslation(loc) {
	/*advanced interface stuff. obsolete
	 * readded per Oren's request ~chris */
	if(gimages.advanced) showXs();
	/**/
	//Remove the row for adding a language and translation
	var sIndex;
	if (loc < 3) {
		sIndex = gimages.currentlyDisplayedState;
	} else {
		sIndex = "";
	}
	//hide rows
	var languageCell = document.getElementById("s"+sIndex+"OtherLanguageLanguage"+loc);
	languageCell.innerHTML = "<span id='s"+sIndex+"OtherLanguageSpan"+loc+"' style='text-decoration:underline;color:blue;cursor:pointer;'><nobr>"+getUIString("addTranslation")+"</nobr></span>";
	var translationCell = document.getElementById("s"+sIndex+"OtherLanguageTranslation"+loc);
	translationCell.innerHTML = "&nbsp;";
	
	//set appropriate constants
	if (loc == 1) {
		gimages.addingTranslation[0] = false;
	}
	else if (loc == 2) {
		gimages.addingTranslation[1] = false;
	}
	else if (loc = 3) {
		gimages.addingTranslation[2] = false;
	}
	else if (loc = 4) {
		gimages.addingTranslation[3] = false;
	}
	else if (loc = 5) {
		gimages.addingTranslation[4] = false;
	}
}

/*
 * Fill in language selection options with searchable languages
 */
function populateLanguageSelectBox(p) {
	var languages = gimages.searchLanguages;
	
	p.options.length = 0;
	p.options[0]=new Option(getUIString("language"), -1);
	p.options[1] = new Option(getUIString("none"), -1);
	for(var i=0; i<languages.length; i++) {
		p.options[i+2]=new Option(languages[i].name + (languages[i].nativeName == null ? "" : " [" + languages[i].nativeName + "]"), languages[i].id);
	}
}

/*
 * Fill in language selection options with all languages from the Languages table
 */
function populateAllLanguageSelectBox(p) {
	var languages = gimages.allLanguages;
	
	//if necessary, retrieve the complete list of languages
	if (languages == undefined) {
		var url = "AllLanguages";
		gimages.allLanguages = AjaxClient.invokeGet(url, false, null).parseJSON(null);
		populateAllLanguageSelectBox(p);	
	}
	//add an option for each language
	else {
		for(var i=0; i<languages.length; i++) {
			p.options[i]=new Option(languages[i].name + (languages[i].nativeName == null ? "" : " [" + languages[i].nativeName + "]"), languages[i].id);
		}
	}
}

/*
 * Expand a list of languages
 */
function showMoreLanguages(prefix) {
	//prefix indicates whether the register or account editing language selection box is being modified
	populateAllLanguageSelectBox(document.getElementById(prefix+"PossibleLanguages"));
	document.getElementById(prefix+"MoreLanguages").style.display = "none";
}

/*
 * ? not in use. ~ono 8/15/20008
 */
function createURLAddNewSense(sourceWord, sourceLanguageID, targetWord, targetLanguageID) {
	return createURLAddTranslation(sourceWord, sourceLanguageID, targetWord, targetLanguageID, -1);
}
/**
 * This function adds the target word as a translation of the source word in the specified senses.
 * 
 * If either the source or target words do not already exist, they are created and added to the database.
 * If a senseID of less than or equal to 0 is entered, a new sense is created and the translation is added in to that new sense.
 * 
 * Note that senseID may be a single sense id or an array of sense ids
 */
function createURLAddTranslation(sourceWord, sourceLanguageID, targetWord, targetLanguageID, senseID/*s*/) {
	/*if(typeof(senseIDs) == "number") {
		senseIDs = [senseIDs];
	}*/
	var queryString = "?sourceWord=" + encodeURIComponent(sourceWord);
    queryString += "&sourceLanguageID=" + sourceLanguageID;
    queryString += "&targetWord=" + encodeURIComponent(targetWord);
    queryString += "&targetLanguageID=" + encodeURIComponent(targetLanguageID);
    /*for(var i=0; i<senseIDs.length; i++) {
    	alert("loop"+i);
		queryString += "&senseID=" + senseIDs[i];
    }*/
    queryString += "&senseID="+senseID;
    queryString += "&user="+gimages.userid;
    return "AddMissingTranslation"+queryString;
}

/*
 * ? not in use. ~ono 8/15/2008
 */
function createURLAddHack(sourceWord, sourceLanguageID, targetWord, targetLanguageID, jsonSense) {
	var queryString = "?sourceWord=" + encodeURIComponent(sourceWord);
    queryString += "&sourceLanguageID=" + sourceLanguageID;

    queryString += "&targetWord=" + encodeURIComponent(targetWord);
    queryString += "&targetLanguageID=" + encodeURIComponent(targetLanguageID);
    if(jsonSense.description != null) {
    	queryString += "&gloss=" + encodeURIComponent(jsonSense.description)
    }
    for(var lIndex=0; lIndex<jsonSense.languages.length; lIndex++) {
    	var language = jsonSense.languages[lIndex];
    	var languageID = language.id;
    	for(var tIndex=0; tIndex<language.translations.length; tIndex++) {
    		var translation=language.translations[tIndex];
	    	queryString += "&translation=" + encodeURIComponent(languageID+"_"+translation.translation);
    	}
    }
    
    return "AddTranslationHack"+queryString;
}

/*
 * Execute a series of AJAX requests
 */
function doAJAX(whenDone) {
	if(gimages.AJAXURLs.length>0) {
		var url = gimages.AJAXURLs.pop();
	    AjaxClient.invokeGet(url, true, doAJAX);
	    return;	
	}
	if(typeof(gimages.whenAJAXDone)=="function") {
		gimages.whenAJAXDone();
	}
}

//old refresh functions
function reloadPage() {
	document.searchPanel.btnSearchPanel.onclick();
}

function reloadPageAtSense() {
	var url = "GImages.jsp?word="+encodeURIComponent(document.searchPanel.getQueryText());
	url += "&lang="+document.searchPanel.getSearchLanguageID();
	url += "&initialSense="+gimages.info.senses[gimages.currentlyDisplayedState].id;
	url += "&stamp=" + (new Date()).getTime();
	
	if ( document.debugParameters ) {
   		for ( var i = 0; i < document.debugParameters.length; i++ ) {
   			if ( document.debugParameters[i].checkbox.checked )
	   			url += "&" + document.debugParameters[i].key + "=" + encodeURIComponent(document.debugParameters[i].textbox.value);
   		}
   	}
	
	window.open(url,"_self");
}


/**
 * User management functions
 */

/*
 * Display login window 
 */
function showLogin() {
	//build login form
	var loginPanel = new StringBuffer();
	loginPanel.append(
					"<form name='login'><h:form onkeypress='return event.keyCode != 13;'>"+
						"<table cellspacing='5'><tbody>"+
							"<tr>" +
								"<td><b>"+getUIString("Login")+"</b></td>" +
							"</tr>" +
							"<tr>" +
								"<td>" +
									"<span id=lReturnToTranslationsI style='text-decoration: underline;color: blue;cursor: pointer;'>"+getUIString("ReturnToTranslationList")+"</span>" +
								"</td>" +
							"</tr>" +
							"<tr><td>"+getUIString("Email")+"</td><td><input type='text' name='email'></td></tr>" +
							"<tr style='text-align:right'>" +
								"<td>&nbsp;</td>" +
								"<td>" +
									"<input type='button' value='"+getUIString("Login")+"' onclick='javascript:userLogin(this.parentNode.parentNode.parentNode)'>" +
									"<input type='button' value='"+getUIString("CancelButton")+"' onclick='javascript:cancelLogin()'>" +
								"</td>" +
							"</tr>" +
						"</tbody></table>" +
					"</form>");
	loginPanel.append(getUIString("NewUser")+" <span id='register' onclick='javascript:showRegister()' style='position: static; text-decoration: underline; color: blue; cursor: pointer;'>"+getUIString("Register")+".</span>");					
	
	//show login form and hide search results
	loginPanel.append("</tr></tbody></table>");
	document.getElementById("messagesDiv").innerHTML = loginPanel.toString();
	document.getElementById("messagesDiv").style.display = "";	
	document.getElementById("resultsTable").style.display = "none";
}

/*
 * Display registration screen
 */
function showRegister(){
	//build registration form
	var loginPanel = new StringBuffer();
	loginPanel.append("<form name='register'><h:form onkeypress='return event.keyCode != 13;'>" +
						"<table cellspacing='5'><tbody>"+
							"<tr>" +
								"<td colspan='2'><b>"+getUIString("Register")+"</b></td>"+
							"</tr>" +
							"<tr>" +
								"<td>" +
									"<span id=rReturnToTranslationsI style='text-decoration: underline;color: blue;cursor: pointer;'>"+getUIString("ReturnToTranslationList")+"</span>" +
								"</td>" +
							"</tr>" +
							"<tr>"+
								"<td>"+getUIString("NameLabel")+"</td>"+
								"<td><input type='text' name='name'></td>"+
							"</tr>" +
							"<tr>"+
								"<td>"+getUIString("Email")+"</td>"+
								"<td><input type='text' name='email'></td>" +
							"</tr>" +
							"<tr>"+
								"<td style='vertical-align:top;'>"+getUIString("LanguagesToEdit")+"</td>" +
								"<td>" +
									"<table><tbody>" +
										"<tr>" +
											"<td><b>"+getUIString("PossibleLanguages")+"</b> <span id=rMoreLanguages>(<span id='rMoreLanguagesI' style='text-decoration: underline;color: blue;cursor: pointer;' onclick='javascript:showMoreLanguages(\"r\")'>"+getUIString("seeMore")+"</span>)</span></td>" +
											"<td>&nbsp;</td>" +
											"<td><b>"+getUIString("SelectedLanguages")+"</b></td>" +
										"</tr>" +
										"<tr>" +
											"<td style='height:200px; width:250px;'><select multiple id='rPossibleLanguages' name='possibleLanguages' size='7' style='height:100%; width:100%;' /></td>" +
											"<td>&nbsp;</td>" +
											"<td style='height:200px; width:250px;'><select multiple id='rSelectedLanguages' name='selectedLanguages' size='7' style='height:100%; width:100%;'/></td>" +
										"</tr>" +
										"<tr>" +
											"<td style='text-align: right;'><input type='button' value='"+getUIString("add")+"' onclick='javascript:addLanguages(this.form.possibleLanguages, this.form.selectedLanguages)'></td>" +
											"<td>&nbsp;</td>" +
											"<td style='text-align: right;'><input type='button' value='"+getUIString("remove")+"' onclick='javascript:removeLanguages(this.form.selectedLanguages)'></td>" +
										"</tr>" +
									"</tbody></table>" +
								"</td>" +
							"</tr>" +
							"<tr>" +
								"<td>&nbsp;</td>" +
							"</tr>" +
							"<tr style='text-align:right'>" +
								"<td>&nbsp;</td>" +
								"<td>" +
									"<input type='button' value='"+getUIString("Register")+"' onclick='javascript:addUser(((this.parentNode).parentNode).parentNode)'>" +
									"<input type='button' value='"+getUIString("CancelButton")+"' onclick='javascript:cancelLogin()'>" +
								"</td>" +
							"</tr>" +
						"</tbody></table>" +
					"</form>");
	
	//display registration form				  
	document.getElementById("messagesDiv").innerHTML = loginPanel.toString();
	document.getElementById("messagesDiv").style.display = "";	
	document.getElementById("resultsTable").style.display = "none";
	
	//fill in language selection boxes
	var languageMenu = document.getElementById("rPossibleLanguages");
	populateLanguageSelectBox(languageMenu);
	languageMenu.options[0] = null;
	languageMenu.options[0] = null;
	document.getElementById("rSelectedLanguages").options[0]=new Option("("+getUIString("noLanguagesSelected")+")", -1);
}

/*
 * Add selected languages to the list of user languages (in interface)
 */
function addLanguages(form1, form2) {
	//form1 = possible languages
	//form2 = user languages
	var num_options1 = form1.options.length;
	var num_options2 = form2.options.length;
	if (num_options2 == 1 && form2.options[0].value == -1) {
		form2.options[0] = null;
		num_options2 = 0;
	}
	//for each selected option in possible languages, add a duplicate option to user languages
	for (var optionIndex = 0; optionIndex < num_options1; optionIndex++) {
		if (form1.options[optionIndex].selected) {
			var add = true;
			var optionValue = form1.options[optionIndex].value;
			//check if language is already in list
			for (var optionIndex2 = 0; optionIndex2 < num_options2 && add; optionIndex2++){
				if (form2.options[optionIndex2].value == optionValue) {
					add = false;
				}
			}
			if (add) {
				form2.options[num_options2] = new Option(form1.options[optionIndex].text, optionValue);
				num_options2++;
				form1.options[optionIndex].selected = "";
			}
		}
	}
	//if user has no languages selected
	if (num_options2 == 0) {
		form2.options[0] = new Option("("+getUIString("noLanguagesSelected")+")", -1);
	}	
}

/*
 * Removes languages from the list of user languages (in interface)
 */
function removeLanguages(form) {
	//for each selected language, remove it (starting from the bottom to avoid changing the indices of options still to be removed);
	for(var optionIndex = form.options.length - 1; optionIndex >= 0; optionIndex--) {
		if (form.options[optionIndex].selected) {
			form.options[optionIndex] = null;
		}
	}
	//if the user has no languages selected
	if (form.options.length == 0) {
		form.options[0] = new Option("("+getUIString("noLanguagesSelected")+")", -1);
	}
}

/*
 * Log in 
 */
function userLogin(form) {
	//Get user(s) associated with the given email address
	var url = "GetUser?";
	url = getFormValues(form, url);
	if (url != "none"){
		url += "&stamp="+(new Date()).getTime();
		AjaxClient.invokeGet(url, false, gimages.possibleUsers);
	}
}

/*
 * Register
 */
function addUser(form) {
	//add user
	var url = "AddUser?";
	url = getFormValues(form, url);
	if (url != "none") {
		url += "&stamp="+(new Date()).getTime();
		//log user in
		AjaxClient.invokeGet(url, false, gimages.loggedIn);
	}
}

/*
 * Once users for a given email address have been retrieved, do this
 */
GImages.prototype.possibleUsers = function ( responseText ) {
	var users = responseText.parseJSON(null);	
	//if there is only one user, log them in
	if (users.length == 1) {
		gimages.loggedIn(users[0].toJSONString());
	}
	//if there is more than one user, ask which they are
	else if (users.length > 1) {
		var pickUser = "<b>"+getUIString("WhoAreYou")+"</b><br />";
		pickUser += "<span id=dReturnToTranslationsI style='text-decoration: underline;color: blue;cursor: pointer;'>"+getUIString("ReturnToTranslationList")+"</span><br /><br />";
		for (var userIndex=0; userIndex < users.length; userIndex++){
			pickUser += "<div>&nbsp;&nbsp;&nbsp;-<span style='text-decoration: underline;color: blue;cursor: pointer;' onclick='javascript:gimages.loggedIn("+users[userIndex].toJSONString()+")'>"+users[userIndex].username+"</span></div>";
		}
		pickUser += "<br />"+getUIString("NewUser")+" <span id='register' onclick='javascript:showRegister()' style='position: static; text-decoration: underline; color: blue; cursor: pointer;'>"+getUIString("Register")+".</span>";
		document.getElementById("messagesDiv").innerHTML = pickUser;
	}
	//if there are no users, tell the user that the email address provided is not registered
	else {
		alert(getUIString("NotRegistered"));	
	}
}

/*
 * Log user in
 */
GImages.prototype.loggedIn = function( responseText ) {
	var user = responseText;
	if ((typeof user) == "string"){
		user = responseText.parseJSON(null);
	}
	//set page variables
	gimages.userid = user.id;
	gimages.username = user.username;
	
	//set session variables
	setUser(gimages.userid, gimages.username);
	
	//update login bar
	var loginBar = new StringBuffer(
		"<span>"+getUIString("LoggedIn").replace("[Name]", gimages.username)+"</span>"+
		"&nbsp;"+		
		"<span id='logoutI' style='text-decoration: underline;color: blue;cursor: pointer;'>"+getUIString("Logout")+"</span>"+
		"&nbsp;"+
		"<span id='accountI' style='text-decoration: underline;color: blue;cursor: pointer;'>"+getUIString("AccountInfo")+"</span>");
	document.getElementById("loginBar").innerHTML = loginBar.toString();
	
	//hide login/register screen
	hideLogin();	
	
	//return to previous screen
	var loc = gimages.loc.pop();
	if (loc == -1) {
		showEditTranslations();	
	} else if (loc == -2) {		
		getSenses();
	} else if (loc > 0) {
		addTranslation(loc);
	}
}

/*
 * Cancel login/register
 */
function cancelLogin() {
	//return to previous screen
	var loc = gimages.loc.pop();	
	if (loc == -2){
		cancelEditSenses();
	} else if (loc == -1) {
		cancelEditTranslations();
	} else if (loc > 0) {
		cancelAddTranslation(loc);
	}
	//hide login/register screen
	hideLogin();
}

/*
 * Hide login/register screen
 */
function hideLogin() {
	document.getElementById("messagesDiv").style.display = "none";
	document.getElementById("resultsTable").style.display = "block";
}

/*
 * Log out
 */
function userLogout(){
	if (gimages.userid != 0) {
		//clear page variables	
		gimages.userid = 0;
		gimages.username = "";
		//clear session variables
		clearUser();
	}
	//update login bar
	var loginBar = new StringBuffer(
		"<span id='loginI' style='text-decoration: underline;color: blue;cursor: pointer;'>"+getUIString("Login")+"</span>"+
		"&nbsp;"+
		"<span id='registerI' style='text-decoration: underline;color: blue;cursor: pointer;'>"+getUIString("Register")+"</span>");
	document.getElementById("loginBar").innerHTML = loginBar.toString();
	
	//cancel anything that requires a user to be logged in
	cancelEditSenses();
	cancelEditAccount();
	if (gimages.showingEditTranslations) {
		cancelEditTranslations();
	}
	for (var i=0; i < gimages.addingTranslation.length; i++){
		if(gimages.addingTranslation[i]){
			cancelAddTranslation(i+1);
		}
	}
}

/*
 * Retrieve user's account information
 */
function viewAccount() {
	document.body.style.cursor = "wait";
	//retrieve user profile
	var url = "GetUserProfile?user="+gimages.userid;
	url += "&stamp="+(new Date()).getTime();
	AjaxClient.invokeGet(url, false, gimages.showAccount);
	document.body.style.cursor = "default";
}

/*
 * Display user's account information
 */
GImages.prototype.showAccount = function( responseText ) {
	var userProfile = responseText.parseJSON(null);
	var languages = userProfile.languages;
	
	//build account editing form
	var accountPanel = new StringBuffer(
		"<form name='register'><h:form onkeypress='return event.keyCode != 13;'>" +
			"<table cellspacing='5'><tbody>"+
				"<tr>" +
					"<td><b>"+getUIString("EditAccount")+"</b></td>" +
				"</tr>" +
				"<tr>" +
					"<td>" +
						"<span id=aReturnToTranslationsI style='text-decoration: underline;color: blue;cursor: pointer;'>"+getUIString("ReturnToTranslationList")+"</span>" +
					"</td>" +
				"</tr>" +
				"<tr>"+
					"<td>"+getUIString("NameLabel")+"</td>"+
					"<td><input type='text' name='name' value='"+userProfile.name+"'></td>"+
				"</tr>" +
				"<tr>"+
					"<td>"+getUIString("Email")+"</td>"+
					"<td>"+userProfile.email+"</td>" +
				"</tr>" +
				"<tr>"+
					"<td style='vertical-align:top'>"+getUIString("LanguagesToEdit")+"</td>" +
					"<td>" +
							"<table><tbody>" +
								"<tr>" +
									"<td><b>"+getUIString("PossibleLanguages")+"</b> <span id=aMoreLanguages>(<span id='aMoreLanguagesI' style='text-decoration: underline;color: blue;cursor: pointer;' onclick='javascript:showMoreLanguages(\"a\")'>"+getUIString("seeMore")+"</span>)</span></td>" +
									"<td>&nbsp;</td>" +
									"<td><b>"+getUIString("SelectedLanguages")+"</b></td>" +
								"</tr>" +
								"<tr>" +
									"<td style='height:200px; width:250px;'><select multiple id='aPossibleLanguages' name='possibleLanguages' size='7' style='height:100%; width:100%;' /></td>" +
									"<td>&nbsp;</td>" +
									"<td style='height:200px; width:250px;'><select multiple id='aSelectedLanguages' name='selectedLanguages' size='7' style='height:100%; width:100%;'/></td>" +
								"</tr>" +
								"<tr>" +
									"<td style='text-align: right;'><input type='button' value='"+getUIString("add")+"' onclick='javascript:addLanguages(this.form.possibleLanguages, this.form.selectedLanguages)'></td>" +
									"<td>&nbsp;</td>" +
									"<td style='text-align: right;'><input type='button' value='"+getUIString("remove")+"' onclick='javascript:removeLanguages(this.form.selectedLanguages)'></td>" +
								"</tr>" +
							"</tbody></table>" +
						"</td>" +
				"</tr>" +
				"<tr>" +
					"<td>&nbsp;</td>" +
				"</tr>" +
				"<tr style='text-align:right'>" +
					"<td>&nbsp;</td>" +
					"<td>" +
						"<input type='button' value="+getUIString("Submit")+" onclick='javascript:editAccount((((this.parentNode).parentNode).parentNode), \""+userProfile.email+"\")'>" +
						"<input type='button' value="+getUIString("CancelButton")+" onclick='javascript:cancelEditAccount()'>" +
					"</td>" +
				"</tr>" +
			"</tbody></table>" +
		"</form>"
	);	
	
	//display account editing form
	var messagesDiv = document.getElementById("messagesDiv");
	messagesDiv.innerHTML = accountPanel.toString();
	
	//clear old messages
	var messagesDiv2 = document.getElementById("messagesDiv2");
	messagesDiv2.innerHTML = "";
	var messagesDiv3 = document.getElementById("messagesDiv3");
	messagesDiv3.innerHTML = "";
	
	//fill in language selection options
	var languageMenu = document.getElementById("aPossibleLanguages");
	populateLanguageSelectBox(languageMenu);
	languageMenu.options[0] = null;
	languageMenu.options[0] = null;
	
	//fill in user languages
	var selectedLanguageMenu = document.getElementById("aSelectedLanguages");
	if (languages.length == 0) {
		selectedLanguageMenu.options[0]=new Option("("+getUIString("noLanguagesSelected")+")", -1);
	} else {
		for (var optionIndex = 0; optionIndex < languages.length; optionIndex++) {
			var language = languages[optionIndex];
			var languageName = language.englishName;
			if (language.nativeName != undefined && language.nativeName != "undefined") {
				languageName += " ["+language.nativeName+"]";
			}
			selectedLanguageMenu.options[optionIndex] = new Option(languageName, language.id);
		}
	}

	messagesDiv.style.display = "";
	document.getElementById("resultsTable").style.display = "none"; 
}

/*
 * Submit account edits
 */
function editAccount(form, email) {
	document.body.style.cursor = "wait";
	//update profile
	var url = "UpdateUserProfile?user="+gimages.userid+"&email="+email;
	url = getFormValues(form, url);
	url += "&stamp="+(new Date()).getTime();
	var numLangs = AjaxClient.invokeGet(url, false, null);
	//display updated account information
	viewAccount();
	if (numLangs >= 0) {
		document.body.style.cursor = "default";
		var messagesDiv = document.getElementById("messagesDiv2");
		var message = getUIString("ProfileUpdated");
		message += " <span id='eaReturnToTranslationsI' style='text-decoration: underline;color: blue;cursor: pointer;'>"+getUIString("ReturnToTranslationList")+"</span>";
		messagesDiv.innerHTML = message;
		messagesDiv.style.display = "";
	}
	//if a number < 0 is returned, account information was not updated because user tried to change name to that of another user with the
	//same email address 
	else {
		document.body.style.cursor = "default";
		alert(getUIString("UserExists"));
	}
}

/*
 * Cancel editing account
 */
function cancelEditAccount() {
	//hide messages
	document.getElementById("messagesDiv").style.display = "none";
	document.getElementById("messagesDiv2").style.display = "none";
	//show results
	document.getElementById("resultsTable").style.display = "";
	//refresh editing translations screen if it was being displayed 
	if (gimages.showingEditTranslations){
		cancelEditTranslations();
		showEditTranslations();
	}
}

/*
 * Recursively extract values from a form
 */
function getFormValues(form, request){
	//text field
	if (form.type == "text") {
		if (form.name == "email") {
			//check format
			if(form.value.match(/^.+@.+\..{2,4}$/i)) {
				request += "&"+form.name+"="+form.value;
			} else {
				//tell user to enter a VALID email address	
				alert("Please enter a valid email address.")
				return "none";
			}
				
		} else if (form.name == "name"){
			if (form.value == ""){
				alert("Please enter your name.");
				return "none";
			} else {
				request += "&"+form.name+"="+form.value;
			}
		} else {
			request += "&"+form.name+"="+form.value;
		}
	}
	//radio buttons (editing - correct/incorrect/no response)
	else if (form.type == "radio") {
		//ignore "no response" votes
		if (form.checked && form.value != 2){
			request += "&"+form.name+"="+form.value;
		}
	}
	//multi-select (language selection menus)
	else if (form.type == "select-multiple") {
		if (form.name == "selectedLanguages") {
			//add all user languages
			for (var optionIndex = 0; optionIndex < form.options.length; optionIndex++){
				if (optionIndex == 0){
					request += "&languages="+form.options[0].value;
				}
				else {
					request += ","+form.options[optionIndex].value;
				}
			}
		}
	}
	else if (form.childNodes.length != 0){
		for (var i=0; i < form.childNodes.length; i++){
			request = getFormValues(form.childNodes[i], request);
			if(request == "none"){
				return "none";
			}
		}		
	}
	
	return request;
}//I have no idea why there needs to be a comment here, but if there isn't there's supposedly a syntax error.}