/**********************************************************************
* /js/component/dictionary-selection.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/language.js
 * require util/utilities.js
 */

var DictionarySelection = Class.create();
var DictionaryButton = Class.create();

var RESOURCE_BUTTON_HEADER_ID = 'resource-button-';
var RESOURCE_BUTTON_NAME_HEADER_ID = "resource-name";
var RESOURCE_BUTTON_BALLOON_HEADER_ID = 'resource-description-balloon-';

//add start kawauchi 20090915
//バルーンの表示・非表示を切り替えるフラグ
var flgShowBalloon=new Array();
//add end kawauchi 20090915

//* new した後にAjax.Requestにより入手したデータをloadDictionaryDataで処理する必要がある
DictionarySelection.prototype = {
	initialize: function(id){
		this.id = id;
		this.resourceArray = new Array();
		this.allResourceInfo = null;
		this.mapId2Index = {};
	},

	//* 辞書のデータをロードする。
	//* @param {String} message
	loadResourceData: function(jsonMessage){
		var resultArray = eval("("+jsonMessage+")");
		var checker = new StatusProcessor(resultArray,
			"Playground Error : Can't obtain information about dictionaries.",
			"Playground Warning : Can't obtain information about all dictionaries.");
		if(!checker.check()) return;
		resultArray = resultArray.contents;

		//* 対訳関係のペア作成処理
		var i=0;
		for(;i<resultArray.size();i+=1){
			for(j=0;j<resultArray[i]['path'].size();j++){
				var pair = resultArray[i]['path'][j].split('2');
				resultArray[i]['path'][j] = new Pair(pair[0],pair[1]);
			}
		}

		//* 辞書ボタン作成
		i=0;
		for(;i<resultArray.size();i+=1){
			//* Access limits del
			//*this.resourceArray[i] = new DictionaryButton(i,$H({name:resultArray[i]['name'],url:resultArray[i]['url'],path:resultArray[i]['path'],id:resultArray[i]['id']}));

			//* add for AccessLimits by morimoto
			this.resourceArray[i] = new DictionaryButton(i,$H(resultArray[i]));
			this.mapId2Index[resultArray[i]['id']] = i;
			//* end for AccessLimits by morimoto

		}

		//* 説明のDIVをBODYに投げる
		i=0;
		for(;i<this.resourceArray.size();i+=1){
			//* Access limits del
			//*new Insertion.Bottom($$('body')[0],this.resourceArray[i].getLayer());

			//* add for AccessLimits by morimoto
			var oDiv = document.createElement('div');
			oDiv.id = /*ExclusiveDictionarySelection.Constant.*/RESOURCE_BUTTON_BALLOON_HEADER_ID + i;

			//mod start kawauchi 20090916
			//説明バルーンが、IE時にカーソルで捉まえられないバグを修正
//			追加した関数にイベントを関連付けている
//			oDiv.setAttribute('onmouseover', 'this.show();');
//			oDiv.setAttribute('onmouseout', 'this.hide();');
			Event.observe(oDiv,"mouseover",this.ShowBalloon.bind(oDiv,i));
			Event.observe(oDiv,"mouseout",this.HideBalloon.bind(oDiv,i));
			//mod end kawauchi 20090916

			// add start kawauchi 20100107
			// バルーンが常にメニューより前面に出る様に修正
			oDiv.style.zIndex = parseInt( $("navigation").style.zIndex) + 1;
			// add end kawauchi 20100107

			oDiv.style.visibility = 'hidden';
			new Insertion.Bottom($$('body')[0],oDiv);
			this.resourceArray[i].updateInfo();
			//* end for AccessLimits by morimoto

			$(RESOURCE_BUTTON_BALLOON_HEADER_ID+i).hide();
		}

		var insertHTML = '';
		i=0;
		for(;i<this.resourceArray.size();i+=1){
			if(i%5 == 0) insertHTML += '<tr class="dictionary">';
			insertHTML += '<td>';
			insertHTML += this.resourceArray[i].getHTML();
			insertHTML += '</td>';
			if(i%5 == 4 || i == this.resourceArray.size()-1) insertHTML += '</tr>';
		}

		//* ボタンが3列以上だった場合に対応
		if(this.resourceArray.length > 10){
			$$(".sources").each(function(obj){
				obj.style.overflow = "auto";
			});
		}

		new Insertion.Bottom($(this.id).down('table'),insertHTML);

		//* add for AccessLimits by morimoto
		//* サービスプロファイルをロードする
		var param = $H(this.mapId2Index)
		.keys() //* serviceId の配列に
		.select((function(id, index){
			var isLanguageGridService = resultArray[this.mapId2Index[id]]['isLanguageGridService'];
			return typeof(isLanguageGridService) != 'undefined' && isLanguageGridService > 0;
		}).bind(this))
		.map(function(id, index){ return 'ids[]=' + id; }) //* ids[]=id という文字列の配列に
		.join('&');

		new Ajax.Request(
			'./php/ajax/load-service-profiles.php',
			{
				method: 'post',
				parameters: param,
				onSuccess: (function(httpObj){
					this.loadProfileData(httpObj.responseText);
				}).bind(this),
				onFailure: function(){ alert('Server Error.'); }
			}
		);
		//* end for AccessLimits by morimoto

		//add start kawauchi 20090915
//		IE以外のブラウザで、Dictionaryボタンにカーソルを合わせると画面がブレるバグを修正
//		ページロード時に説明を表示するバルーンの位置を絶対値で指定している
		if(!window.ActiveXObject){
			for(i=0;i<this.resourceArray.size();i+=1){
				var elm=$(RESOURCE_BUTTON_BALLOON_HEADER_ID+i);
				var cellPosition = Position.cumulativeOffset(elm);
				var containorElement=$("dictionaries");
				var bodyPosition = $$('body')[0].cumulativeOffset();
				var w=elm.getWidth();
				var h=elm.getHeight();
				var x = cellPosition[0] - bodyPosition[0]+w -15;
				var y=cellPosition[1] - (containorElement.scrollTop + bodyPosition[1]+(h/2));
				if((i % 5) > 2) x = x -(x*2)+40;
				var styleValue={position:"absolute",left:x+"px",top:y+"px"};
				elm.setStyle(styleValue);
			}
		}
		//add end kawauchi 20090915

		//add start kawauchi 20090916
		//バルーンの表示・非表示を切り替えるフラグを初期化
		for(i=0;i<this.resourceArray.size();i++){
			flgShowBalloon[i]=false;
		}
		//add end kawauchi 20090916
	},

	//add start kawauchi 20090916
	//バルーンのmouseoverイベント
	ShowBalloon:function(id){
		flgShowBalloon[id]=true;
		this.show();
	},
	//バルーンのmouseoutイベント
	HideBalloon:function(id){
		flgShowBalloon[id]=false;
		this.hide();
	},
	//add end kawauchi 20090916

	//* add for AccessLimits by morimoto
	//* サービスのプロファイルをロードする
	loadProfileData: function(jsonMessage){
		var resultArray = eval("("+jsonMessage+")");
		var checker = new StatusProcessor(resultArray, "Playground Error : Can't obtain information about dictionaries.");
		checker.warning = function(){return true;};
		if(!checker.check()) return;
		resultArray = $H(resultArray.contents);

		var selection = this;
		resultArray.keys().each(function(id){
			var profile = resultArray.get(id);
			var aryLimit = profile['AccessLimits'];
			if (aryLimit['status'] != 'OK') return;
			aryLimit = aryLimit['contents'];

			if (aryLimit.size() == 0) return;

			var limitInfo = [];
			aryLimit.each(function(limit){
				limitInfo.push(limit);
			});

			//* プロファイルを更新する
			var button = selection.resourceArray[selection.mapId2Index[id]];
			button.addLimitInfo(limitInfo);
			button.updateInfo();
		});
	},
	//* end for AccessLimits by morimoto


	//* 辞書の総数を返す
	getArrayOfResources: function(){
		return this.resourceArray;
	},

	//* IDを返す
	getId: function(){
		return this.id;
	},

	//* DOM要素を返す
	getElement: function(){
		return $(this.id);
	},

	getSourceLanguages: function(){
		var sourceLanguages = new Array();
		this.getArrayOfResources().each(function(d){
			if(d.isSelected()){
				d.getSupportedLanguagePair().each(function(p){
					if(sourceLanguages.indexOf(p.car()) == -1){
						sourceLanguages.push(p.car());
					}
				});
			}
		});
		return sourceLanguages;
	},

	getTargetLanguages: function(sourceLanguage){
		var targetLanguages = new Array();
		this.getArrayOfResources().each(function(d){
			if(d.isSelected()){
				d.getSupportedLanguagePair().each(function(p){
					if(targetLanguages.indexOf(p.cdr()) == -1 && sourceLanguage == p.car()){
						targetLanguages.push(p.cdr());
					}
				});
			}
		});
		return targetLanguages;
	},

	getWsdlUrlOfSelectedResources: function(){
		var wsdlArray = new Array();
		this.getArrayOfResources().each(function(d){
			if(d.isSelected()) wsdlArray.push(d.getWsdlUrl());
		});
		return wsdlArray;
	},

	getIdOfSelectedResources: function(){
		var wsdlArray = new Array();
		this.getArrayOfResources().each(function(d){
			if(d.isSelected()) wsdlArray.push(d.getId());
		});
		return wsdlArray;
	},

	getUrlFromId: function(resourceId){
		for(var i=0;i<this.getArrayOfResources().size();i++){
			if(this.getArrayOfResources()[i].getId() == resourceId)
				return this.getArrayOfResources()[i].getWsdlUrl();
		}
		return null;
	},

	getResourceNameFromWsdlUrl: function(wsdlUrl){
		for(var i=0;i<this.getArrayOfResources().size();i++){
			if(this.getArrayOfResources()[i].getWsdlUrl() == wsdlUrl)
				return this.getArrayOfResources()[i].getName();
		}
		return null;
	},

	getResourceNameFromId: function(resourceId){
		for(var i=0;i<this.getArrayOfResources().size();i++){
			if(this.getArrayOfResources()[i].getId() == resourceId)
				return this.getArrayOfResources()[i].getName();
		}
		return null;
	},

	//* ボタンにマウスが乗ったときのアクション
	//* @param {Number} number
	//* @param {Number} x
	//* @param {Number} y
	onMouseOverAction: function(number,x,y){
		this.resourceArray[number].showIllustration(x,y);
	},

	//* ボタンからマウスが離れたときのアクション
	//* @param {Number} number
	onMouseOutAction: function(number){

		//mod start kawauchi 20090916
//		説明を表示するバルーンがIE時にはカーソルで捉まえられないバグを修正
//		フラグによりバルーンを非表示にするかどうか判定している
//		this.resourceArray[number].hideIllustration();
		if(!flgShowBalloon[number]){this.resourceArray[number].hideIllustration();}
		//mod end kawauchi 20090916

	},

	//* ボタンがクリックされたときのアクション
	//* @param {Number} number
	onClickAction: function(number){
		this.resourceArray[number].toggleState();
	}
};

DictionaryButton.prototype = {
	initialize: function(number,hashData){
		this.number = number;
		this.hashData = hashData;
		this.selected = false;
	},

	//* 活性/非活性の状態を入れ替える
	toggleState: function(){
		if(this.isSelected()){
			this.deactivate();
		} else {
			this.activate();
		}
	},

	//* 活性化した状態の表示
	//* @param {Number} x
	//* @param {Number} y
	showIllustration: function(x,y){
		$(RESOURCE_BUTTON_BALLOON_HEADER_ID+this.number).setStyle({
			position : 'absolute' ,
			visibility: 'visible',
			left : x+'px' ,
			top : y+'px'
		});
		$(RESOURCE_BUTTON_BALLOON_HEADER_ID+this.number).show();
	},

	//* 非活性化した状態の表示
	hideIllustration: function(){
		$(RESOURCE_BUTTON_BALLOON_HEADER_ID+this.number).hide();
	},

	getWsdlUrl: function(){
		return this.hashData.get('url');
	},

	getId: function(){
		return this.hashData.get('id');
	},

	getName: function(){
		return this.hashData.get('name');
	},

	//* 活性化した状態の表示
	activate: function(){
		this.selected = true;
		$(RESOURCE_BUTTON_HEADER_ID+this.number).removeClassName('unselected');
		$(RESOURCE_BUTTON_HEADER_ID+this.number).addClassName('selected');
	},

	//* 非活性化した状態の表示
	deactivate: function(){
		this.selected = false;
		$(RESOURCE_BUTTON_HEADER_ID+this.number).addClassName('unselected');
		$(RESOURCE_BUTTON_HEADER_ID+this.number).removeClassName('selected');
	},

	//* 選択の状態を得る
	isSelected: function(){
		return this.selected;
	},

	//* 辞書を示すボタンのHTML文を返す
	getHTML: function(){
		return '<div class="unselected" id="'+RESOURCE_BUTTON_HEADER_ID+this.number+'"><div class="source-name" id="'+RESOURCE_BUTTON_NAME_HEADER_ID+this.number+'">'+this.hashData.get('name').truncate(60)+'</div></div>';
	},

	//* 辞書の説明文のHTML文を返す
	getLayer: function(){
		var pairArray = this.hashData.get('path');
		var pairInfo = this.getPairInfo();
		var popupClass = '';
		if(this.number % 5 > 2) popupClass = 'balloon bottom-right';
		else popupClass = 'balloon bottom-left';
		//* Access limits del
		//*var illustration = '<div id="'+RESOURCE_BUTTON_BALLOON_HEADER_ID+this.number+'" onmouseover="this.show();" onmouseout="this.hide();" style="visibility:hidden;"><div class="'+popupClass+'">'+

		//* add for AccessLimits by morimoto
		var illustration = '<div class="'+popupClass+'">'+
		//* end for AccessLimits by morimoto

							'<div class="top iepngfix"></div>'+
							'<div class="comment iepngfix">'+
							'<h4>NAME</h4>'+
							this.hashData.get('name')+'<br />'+
							'<h4>Supported Language Pairs</h4>'+
							'<div class="supported-language-pairs">'+
							pairInfo+
							'</div>';
		//* Access limits del
		//*if(this.getWsdlUrl() != "") illustration+='<h4>URL</h4>'+
		//*					'<a href="'+this.hashData.get('url')+'">'+this.hashData.get('url').truncate(40)+'</a>';

		//* add for AccessLimits by morimoto
		var data;
		data = this.hashData.get('url');
		if(data) {
			illustration += '<h4>URL</h4><a href="' + data + '">' + data.truncate(40) + '</a>';
		}
		data = this.hashData.get('limits');
		if(data) {
			illustration += '<h4>Access Limits</h4>';
			data.each(function(limitInfo){
				illustration += '<table><tbody>'
				+ '<tr><td>Start</td><td>' + limitInfo['startDateTime'] + '</td></tr>'
				+ '<tr><td>End</td><td>' + limitInfo['endDateTime'] + '</td></tr>'
				+ '<tr><td>Limit</td><td>' + limitInfo['limitInfo'] + '</td></tr>'
				+ '</tbody></table>';
			});
		}
		//* end for AccessLimits by morimoto
		//* Access limits del
		//*illustration+='</div><div class="bottom iepngfix"></div></div></div>';

		//* add for AccessLimits by morimoto
		illustration+='</div><div class="bottom iepngfix"></div></div>';
		//* end for AccessLimits by morimoto

		return illustration;
	},

	//* add for AccessLimits by morimoto
	updateInfo: function(){
		Element.update($(/*ExclusiveDictionarySelection.Constant.*/RESOURCE_BUTTON_BALLOON_HEADER_ID+this.number), this.getLayer());
	},

	addLimitInfo: function(aryLimitInfo){
		this.hashData.set('limits', aryLimitInfo);
	},
	//* end for AccessLimits by morimoto

	getSupportedLanguagePair: function(){
		return this.hashData.get('path');
	},

	//* サポート言語対の情報のHTMLを返す
	getPairInfo: function(){
		var pairArray = this.hashData.get('path');
		var pairKey = [];
		var keyHash = {};
		var from, to, key, keySearch;

		for (var i = 0, length = pairArray.length; i < length; i++) {
			from = pairArray[i].getFirst();
			to = pairArray[i].getSecond();
			key = from+'2'+to;
			keySearch = to+'2'+from;
			if (typeof(keyHash[keySearch]) == 'undefined') {
				pairKey.push(key);
				//* とりあえず片方向あり
				keyHash[key] = false;
			} else {
				//* 双方向OKの場合，
				keyHash[keySearch] = true;
			}
		}

		var pairInfo = [];
		var langs;
		for (var i = 0, length = pairKey.length; i < length; i++) {
			key = pairKey[i];
			langs = key.split('2');
			from = langs[0];
			to = langs[1];
			pairInfo.push(
				Language.getNameByTag(from)
				+ ' ' + ( keyHash[key] ? '&lt;' : '' ) + '-&gt; '
				+ Language.getNameByTag(to)
			);
		}
		return pairInfo.join('<br />');
	}
};

DictionarySelection.Event = {
	load: function(resourceSelection){
		new Ajax.Request(
			 './php/ajax/load-services.php',
			 {
				 method		:'post',
				 parameters	:'serviceCategory=billingualdict',
				 onSuccess	:function(httpObj){
				 	resourceSelection.loadResourceData(httpObj.responseText);
				 },
				 onFailure	:function(){
					 alert('Server Error.');
				 }
			 }
		);
	},

	clickButton: function(event,resourceSelection){
		var element = $(Event.element(event));
		if(element.id.startsWith(RESOURCE_BUTTON_HEADER_ID)){
			resourceSelection.onClickAction(parseInt(element.id.substring(RESOURCE_BUTTON_HEADER_ID.length)));
		} else if(element.id.startsWith(RESOURCE_BUTTON_NAME_HEADER_ID)){
			resourceSelection.onClickAction(parseInt(element.id.substring(RESOURCE_BUTTON_NAME_HEADER_ID.length)));
		}
	},

	mouseoverButton: function(event,resourceSelection){
		function _get_position_of_ballon(element,number){
			var cellPosition = element.cumulativeOffset();
			var containorElement = element.up('.sources');
			var bodyPosition = $$('body')[0].cumulativeOffset();
			var x = cellPosition[0] - bodyPosition[0]+element.getWidth() -15;
			var y = cellPosition[1] - containorElement.scrollTop - bodyPosition[1]+(element.getHeight())/2 - $(RESOURCE_BUTTON_BALLOON_HEADER_ID+number).getHeight();
			if(number % 5 > 2) x = x - element.getWidth() - $(RESOURCE_BUTTON_BALLOON_HEADER_ID+number).getWidth()+40;
			return new Pair(x,y);
		}

  		var element = $(Event.element(event));
		if(element.id.startsWith(RESOURCE_BUTTON_HEADER_ID)){
			var number = parseInt(element.id.substring(RESOURCE_BUTTON_HEADER_ID.length));
			var positionPair = _get_position_of_ballon(element,number);
			resourceSelection.onMouseOverAction(number,positionPair.car(),positionPair.cdr());
		} else if(element.id.startsWith(RESOURCE_BUTTON_NAME_HEADER_ID)){
			element = element.up('div');
			var number = parseInt(element.id.substring(RESOURCE_BUTTON_HEADER_ID.length));
			var positionPair = _get_position_of_ballon(element,number);
			resourceSelection.onMouseOverAction(number,positionPair.car(),positionPair.cdr());
		}
	},

	mouseoutButton: function(event,resourceSelection){
		var element = $(Event.element(event));
		if(element.id.startsWith(RESOURCE_BUTTON_HEADER_ID)){
			resourceSelection.onMouseOutAction(parseInt(element.id.substring(RESOURCE_BUTTON_HEADER_ID.length)));
		} else if(element.id.startsWith(RESOURCE_BUTTON_NAME_HEADER_ID)){
			resourceSelection.onMouseOutAction(parseInt(element.id.substring(RESOURCE_BUTTON_NAME_HEADER_ID.length)));
		}
	},

	clickAllButton: function(event,resourceSelection){
		var element = $(Event.element(event));
		var resourceArray = resourceSelection.getArrayOfResources();
		if(element.checked){
			resourceArray.each(function(d){d.activate();});
		} else {
			resourceArray.each(function(d){d.deactivate();});
		}
	}
}

