/**********************************************************************
* /js/component/concept-dictionary-search.js
* Copyright (C) 2007-2008 Kyoto University
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* 
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
* 
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-
* 1301  USA
***********************************************************************/
/**
 * require util/utilities.js
 */

var DictionarySearch = Class.create();
var SourceLanguageMenu = Class.create();
var TargetLanguageMenu = Class.create();
var ResultArea = Class.create();
var ResultDictionaryContainer = Class.create();
var Recursive = Class.create();

//* new した後にAjax.Requestにより入手したデータをloadDictionaryDataで処理する必要がある
DictionarySearch.prototype = {
	initialize: function(wordAreaId,matchingMethodId,sourceLanguageId,targetLanguageId,resultAreaId){
		this.wordAreaId = wordAreaId;
		this.matchingMethodId = matchingMethodId;
		this.sourceLanguageMenu = new SourceLanguageMenu(sourceLanguageId);
		//this.targetLanguageMenu = new TargetLanguageMenu(targetLanguageId);
		this.resultArea = new ResultArea(resultAreaId);
	},
	
	changeLanguages: function(languages){
		this.sourceLanguageMenu.setMenuLanguages(languages);
		this.sourceLanguageMenu.draw();
	},
	
	resetLanguages: function(){
		this.sourceLanguageMenu.resetSelectedLanguage();
		this.sourceLanguageMenu.resetMenuLanguage();
		this.sourceLanguageMenu.draw()
	},
	
	changeSourceLanguages: function(languages){
		this.sourceLanguageMenu.setMenuLanguages(languages);
		this.sourceLanguageMenu.draw();
	},
	
	changeTargetLanguages: function(languages){
		this.targetLanguageMenu.setMenuLanguages(languages);
		this.targetLanguageMenu.draw();
	},
	
	resetSourceLanguages: function(){
		this.sourceLanguageMenu.resetSelectedLanguage();
		this.sourceLanguageMenu.resetMenuLanguage();
		this.sourceLanguageMenu.draw();
	},
	
	resetTargetLanguages: function(){
		this.targetLanguageMenu.resetSelectedLanguage();
		this.targetLanguageMenu.resetMenuLanguage();
		this.targetLanguageMenu.draw();
	},
	
	isEmptyWordArea: function(){
		return $(this.wordAreaId).value == "";
	},
	
	unselectedTargetLanguages: function(){
		return this.targetLanguageMenu.getSelectedLanguages() == null;
	},
	
	getSelectedSourceLanguage: function(){
		return this.sourceLanguageMenu.getSelectedLanguage();
	},
	
	getSourceLanguageMenu: function(){
		return this.sourceLanguageMenu;
	},
	
	getTargetLanguageMenu: function(){
		return this.targetLanguageMenu;
	},
	
	getResultArea: function(){
		return this.resultArea;
	},
	
	getWordArea: function(){
		return $(this.wordAreaId);
	},
	
	getMatchingMethod: function(){
		return $(this.matchingMethodId);
	}
};

SourceLanguageMenu.prototype = {
	initialize: function(id){
		this.id = id;
		this.element = $(this.id);
		this.selectedLanguage = null;
		this.menuLanguages = new Array();
	},
	
	setSelectedLanguage: function(language){
		this.selectedLanguage = language;
	},
	
	getSelectedLanguage: function(){
		return this.selectedLanguage;
	},
	
	getElement: function(){
		return this.element;
	},
	
	setMenuLanguages: function(languages){
		this.menuLanguages = languages;
	},
	
	resetSelectedLanguage: function(){
		this.selectedLanguage = null;
	},
	
	resetMenuLanguage: function(){
		this.menuLanguages = new Array();
	},
	
	draw: function(){
		this.element.innerHTML = '';
		if (this.menuLanguages.size() == 0) {
			var opt = document.createElement('option');
			opt.innerHTML = '&nbsp;';
			this.element.appendChild(opt);
		}
		else {
			var hasPreviousSelectedLanguage = false;
			for (var n = 0; n < this.menuLanguages.size(); n++) {
				var opt = document.createElement('option');
				if (this.menuLanguages[n] == this.selectedLanguage) {
					opt.selected = "true";
					hasPreviousSelectedLanguage = true;
				}
				opt.value = this.menuLanguages[n];
				opt.innerHTML = Language.getNameByTag( this.menuLanguages[n] );
				this.element.appendChild(opt);
			}
			if (!hasPreviousSelectedLanguage) {
				this.element.firstChild.selected = "true";
				this.selectedLanguage = this.element.firstChild.value;
			}
		}
	}
};

TargetLanguageMenu.prototype = {
	initialize: function(id){
		this.id = id;
		this.element = $(this.id);
		this.selectedLanguages = new Array();
		this.previousSelectedLanguages = new Array();
		this.menuLanguages = new Array();
	},
	
	setSelectedLanguage: function(language){
		this.selectedLanguages.push(language);
	},
	
	removeSelectedLanguage: function(language){
		this.selectedLanguages = this.selectedLanguages.without(language);
	},
	
	getSelectedLanguages: function(){
		var languages = new Array();
		$$('#'+this.id+' input').each(function(i){
			if(i.checked) languages.push(i.value);
		});
		return languages;
	},
	
	setMenuLanguages: function(languages){
		this.previousSelectedLanguages = this.getSelectedLanguages();
		this.menuLanguages = languages;
	},
	
	resetSelectedLanguage: function(){
		this.selectedLanguages = new Array();
	},
	
	resetMenuLanguage: function(){
		this.menuLanguages = new Array();
	},
	
	draw: function(){
		this.element.innerHTML = '';
		if(this.previousSelectedLanguages.size() + this.menuLanguages.size() == this.previousSelectedLanguages.concat(this.menuLanguages).uniq().size()){
			for(var n=0;n<this.menuLanguages.size();n++){
				if(n == 0){
					this.element.innerHTML = this.element.innerHTML + '<input id="' + 'to'+n + '" name="'+'to'+n+'" type="checkbox" value="'+this.menuLanguages[n]+'" checked />'
					+ '<img src="img/common/space.gif" width="2px"/>' + this.menuLanguages[n] + '<img src="img/common/space.gif" width="7px"/>';
				}else{
					this.element.innerHTML = this.element.innerHTML + '<input id="' + 'to'+n + '" name="'+'to'+n+'" type="checkbox" value="'+this.menuLanguages[n]+'" />'
					+ '<img src="img/common/space.gif" width="2px"/>' + this.menuLanguages[n] + '<img src="img/common/space.gif" width="7px"/>';
				}
			}
		} else {
			for(var n=0;n<this.menuLanguages.size();n++){
				if(this.previousSelectedLanguages.indexOf(this.menuLanguages[n]) != -1){
					this.element.innerHTML = this.element.innerHTML + '<input id="' + 'to'+n + '" name="'+'to'+n+'" type="checkbox" value="'+this.menuLanguages[n]+'" checked />'
					+ '<img src="img/common/space.gif" width="2px"/>' + this.menuLanguages[n] + '<img src="img/common/space.gif" width="7px"/>';
				}else{
					this.element.innerHTML = this.element.innerHTML + '<input id="' + 'to'+n + '" name="'+'to'+n+'" type="checkbox" value="'+this.menuLanguages[n]+'" />'
					+ '<img src="img/common/space.gif" width="2px"/>' + this.menuLanguages[n] + '<img src="img/common/space.gif" width="7px"/>';
				}
			}
		}
	}
};

ResultArea.prototype = {
	initialize: function(id){
		this.id = id;
		this.element = $(this.id);
	},
	
	draw: function(response,resourceSelection){		
		var strRes = new String(response);
		if (strRes.match("Fatal error: Maximum execution time")!=null || strRes.match("Timed out read")!=null) {
			alert ('Time out. Please try more specific word or use complete as Matching Method');
			return;
		}
		var resultObj = eval("("+response+")");
		//add start kawauchi 090929
		//対応していないエラーが発生した時、Dictionary毎にメッセージを表示
		for(var i=0;i<resultObj.contents.length;i++){
			var obj=resultObj.contents[i].result;
			if(obj.status=="ERROR"){
				var id=resultObj.contents[i].serviceId;
				var msg=id+":\n";
				if (resultObj.contents[i].result.message.match(/The specified language \(".+?"\)  is not supported by the service./)) {
					continue; // 辞書で使用できない言語
				} else if (id.match(/WordNetJa/)) {
					for(var o in obj.contents){
						if(obj.contents[o].description){
							msg=msg+obj.contents[o].description;
							break;
						}
					}
				} else {
					msg=msg+obj.message;
				}
				
				alert(msg);
			}
		}
		//add end kawauchi 090929
		this.element.innerHTML = '';
		var checker = new StatusProcessor(resultObj);
		checker.warning = function(){
			if (this.isLimitationWarning()) alert(this.message);
			return true;
		}
		checker.error = function(){
			if (this.isLimitationError()) {
				alert(this.message);
				return false;
			} 
			return true;
		}
		if(!checker.check()) return;
		resultObj = resultObj['contents'];
		for(var i=0;i<resultObj.length; i++){
			var container = new ResultDictionaryContainer(resultObj[i]);
			this.element.appendChild(container.getElement(resourceSelection));
		}
	}
};

ResultDictionaryContainer.prototype = {
	initialize: function(resultObj){
		this.resultObj = resultObj;
		this.resultDl = document.createElement('dl');
		this.tw = document.createElement('dd');
	},
	
	callRecursive: function(contents, parent, space){
		try {

			for(var k=0; k < contents.length; k++){
				for (var l=0; l < space; l++)
					this.tw.innerHTML = this.tw.innerHTML + '&nbsp;&nbsp;&nbsp;&nbsp; ';
				// 20090925 koyama add start
				if (contents[k].glosses.length == 0 || contents[k].glosses[0].glossText == "") {
					continue;
				}
				// 20090925 koyama add end
				this.tw.innerHTML = this.tw.innerHTML + '=> ';
				for(var l=0; l < contents[k].synset.length-1; l++){							
					this.tw.innerHTML = this.tw.innerHTML + contents[k].synset[l].lemmaForm + ', ';						
				}
				this.tw.innerHTML = this.tw.innerHTML + contents[k].synset[contents[k].synset.length-1].lemmaForm;
				// 2009-06-11 koyama modified start
//				this.tw.innerHTML = this.tw.innerHTML + ' (';
				if (contents[k].glosses != null && contents[k].glosses.length > 0) {
					this.tw.innerHTML = this.tw.innerHTML + ' (';
					for(var l=0; l < contents[k].glosses.length-1; l++){							
						this.tw.innerHTML = this.tw.innerHTML + contents[k].glosses[l].glossText + ', ';						
					}
					this.tw.innerHTML = this.tw.innerHTML + contents[k].glosses[contents[k].glosses.length-1].glossText;
					this.tw.innerHTML = this.tw.innerHTML + ')';
				}
				this.tw.innerHTML = this.tw.innerHTML + '<br>&nbsp;&nbsp;&nbsp;&nbsp;';
				/**
				for(var l=0; l < contents[k].glosses.length-1; l++){							
					this.tw.innerHTML = this.tw.innerHTML + contents[k].glosses[l].glossText + ', ';						
				}
				this.tw.innerHTML = this.tw.innerHTML + contents[k].glosses[contents[k].glosses.length-1].glossText;
				this.tw.innerHTML = this.tw.innerHTML + ') <br>&nbsp;&nbsp;&nbsp;&nbsp;';
				*/
				// 2009-06-11 koyama modified end
				if (contents[k].relations.length>0) {
					for(var l=0; l < contents[k].relations.length; l++){	
						if (parent==contents[k].relations[l].relation) {
							// calling recursive function for the same relation
							this.callRecursive(contents[k].relations[l].contents, parent, space+1);
						}
					}
				} 
			}
		} catch (e) {
			;
		}
	},
	
	appendSense: function(contents, parent){
		try {
			// 2009-06-11 koyama add start
			if (contents == null || contents.length == 0) {
				var slw = document.createElement('dt');
				slw.innerHTML = slw.innerHTML + 'Not found.<br>';
				this.resultDl.appendChild(slw);
				return;
			}
			// 2009-06-11 koyama add end
			for (var i=0; i < contents.length; i++) {
				var slw = document.createElement('dt');
				slw.innerHTML = '';
				// 2009-06-10 koyama modified start
				if (contents[i].glosses != null && contents[i].glosses.length > 0) {
					for(var j=0; j < contents[i].glosses.length-1; j++){
						slw.innerHTML = slw.innerHTML + contents[i].glosses[j].glossText + ', ';
					}	
					slw.innerHTML = slw.innerHTML + contents[i].glosses[contents[i].glosses.length-1].glossText;
				}
				/**
				for(var j=0; j < contents[i].glosses.length-1; j++){
					slw.innerHTML = slw.innerHTML + contents[i].glosses[j].glossText + ', ';
				}	
				slw.innerHTML = slw.innerHTML + contents[i].glosses[contents[i].glosses.length-1].glossText;
				 */
				// 2009-06-10 koyama modified end
				this.resultDl.appendChild(slw);
				this.tw = document.createElement('dd');
				this.tw.innerHTML = '';
				for(var j=0; j < contents[i].synset.length-1; j++){
					this.tw.innerHTML = this.tw.innerHTML + contents[i].synset[j].lemmaForm + ', ';
				}				
				this.tw.innerHTML = this.tw.innerHTML + contents[i].synset[contents[i].synset.length-1].lemmaForm;
				this.tw.innerHTML = this.tw.innerHTML + ' (' + contents[i].partOfSpeech + ')';
				if (contents[i].relations.length>0) {
					this.tw.innerHTML = this.tw.innerHTML + '<br>&nbsp;&nbsp;&nbsp;&nbsp;';
					for(var j=0; j < contents[i].relations.length; j++){
						if (contents[i].relations[j].relation == undefined) {
							if (j == 0)
								this.tw.innerHTML = this.tw.innerHTML + 'Available relations: &nbsp;';
							this.tw.innerHTML = this.tw.innerHTML + contents[i].relations[j] ;					
							if (j < contents[i].relations.length-1)
								this.tw.innerHTML = this.tw.innerHTML + ', &nbsp;';
							else
								this.tw.innerHTML = this.tw.innerHTML + '<br> &nbsp;&nbsp;&nbsp;&nbsp;';	
						}
						else {
							this.tw.innerHTML = this.tw.innerHTML + contents[i].relations[j].relation + ': <br>&nbsp;&nbsp;&nbsp;&nbsp;';
							//calling recursive function
							this.callRecursive(contents[i].relations[j].contents, contents[i].relations[j].relation,1);
						}
					}						
				}
				this.resultDl.appendChild(this.tw);
			}	
		} catch (e) {
			;
		}
	},
		
	getElement: function(resourceSelection){
		var checker = new StatusProcessor(this.resultObj.result);
		checker.error = function(){
			var divElement = document.createElement('div');
			divElement.className = "error-message";
			divElement.appendChild(document.createTextNode("ERROR : " + checker.response.message));
			this.resultDl.appendChild(divElement);
			return false;
		}.bind(this);
		checker.warning = function(){
			var divElement = document.createElement('div');
			divElement.className = "warning-message";
			divElement.appendChild(document.createTextNode("WARNING : "+this.response.message));
			this.resultDl.appendChild(divElement);
			return false;
		}
		if(checker.check()) {
			// calling the presentation of the contents, might be recursive
			this.appendSense(this.resultObj.result.contents, null);
		}
					
		var resourceName = document.createElement('div');
		resourceName.className = 'resource-name';
		if (resourceSelection.getUrlFromId(this.resultObj.id) != "") {
			var atag = document.createElement('a');
			atag.appendChild(document.createTextNode(resourceSelection.getResourceNameFromId(this.resultObj.id)));
			atag.setAttribute('href', resourceSelection.getUrlFromId(this.resultObj.id));
		} else {
			var atag = document.createElement('span');
			atag.appendChild(document.createTextNode(resourceSelection.getResourceNameFromId(this.resultObj.id)));
		}
		resourceName.appendChild(atag);
		this.resultDl.appendChild(resourceName);
		
		//add start kawauchi 090924
		//翻訳結果に＝＞（）の記号だけが表示されるバグを修正
		//ノードのテキストに（）だけが含まれていれば、そのノードを削除する
		var arrChild=this.resultDl.children;
		for (var i = 0; i < arrChild.length; i++) {
			try {
				var f = i % 2; //0ならタイトル、１なら内容
				var arrChildNodes = arrChild[i].childNodes;
				if(f == 0){
					if(arrChildNodes.length == 0) {
						arrChild[i].innerHTML="No gloss was found.";
					}
				} else {
					for (var j = arrChildNodes.length - 1; j > -1; j--){
						if (arrChildNodes[j].textContent == null) {
							continue;
						}
						var text = arrChildNodes[j].textContent;
						var n = text.indexOf("()");
						if (n != -1) {
							Element.remove(arrChildNodes[j]);
							Element.remove(arrChildNodes[j - 1]);
						}
					}
				}
			} catch (e) {
				alert(e);
				;
			}
		}
		//add end kawauchi 090924
		
		return this.resultDl;
	}
};

DictionarySearch.Event = {
	changeSourceLanguage: function(event,resourceSearch){
		var language = resourceSearch.getSourceLanguageMenu().getElement().value;
		resourceSearch.getSourceLanguageMenu().setSelectedLanguage(language);
	}
}

