/**********************************************************************
* /js/component/kawasaki-parallel-text-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 KawasakiParallelTextSelection = Class.create();
var KawasakiParallelTextButton = 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-';

//* new した後にAjax.Requestにより入手したデータをloadParallelTextDataで処理する必要がある
KawasakiParallelTextSelection.prototype = {
	initialize: function(id,language){
		this.id = id;
		this.language = language;
		this.resourceArray = new Array();
		this.numberOfMostRecentlyClickedResource = -1; //* 無い場合は-1
	},
	
	//* 辞書のデータをロードする。
	//* @param {String} message
	loadResourceData: function(message){
		var resultArray = eval("("+message+")");
		var checker = new StatusProcessor(resultArray,
			"Playground Error : Can't obtain information about parallel texts.",
			"Playground Warning : Can't obtain information about all parallel texts.");
		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){
			this.resourceArray[i] = new KawasakiParallelTextButton(i,resultArray[i],this.language);
		}
		
		//* ボタン作成
		var insertHTML = '';
		$(this.id).down('table').down('tr').remove();
		i=0;
		for(;i<this.resourceArray.size();i+=1){
			if(i%5 == 0) insertHTML += '<tr>';
			insertHTML += '<td class="short">';
			insertHTML += this.resourceArray[i].getHTML();
			insertHTML += '</td>';
			if(i%5 == 4 || i == this.resourceArray.size()-1) insertHTML += '</tr>';
		}
		new Insertion.Bottom($(this.id).down('table'),insertHTML);
	},
	
	//* 辞書の総数を返す
	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;
	},
	
	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;
	},
	
	setMostRecentlyClickedSourceNumber: function(number){
		this.numberOfMostRecentlyClickedResource = number;
	},
	
	//* ボタンにマウスが乗ったときのアクション
	//* @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){
		this.resourceArray[number].hideIllustration();
	},
	
	//* ボタンがクリックされたときのアクション
	//* @param {Number} number
	onClickAction: function(number){
		this.resourceArray[number].toggleState();
	},
	
	getMostRecentlyClickedDictionary: function(){
		if(this.numberOfMostRecentlyClickedResource != -1){
			var resource = this.getArrayOfResources()[this.numberOfMostRecentlyClickedResource];
			return new Pair(resource.getHashDate(),resource.isSelected());
		}
		return null;
	},
	
	loadResource: function(){
		var resourceSelection = this;
		new Ajax.Request(
			 './php/ajax/load-customized-parallel-text.php',
			 {
				 method		:'post',
				 parameters	:'serviceCategory=paralleltext',
				 resourceSelection:resourceSelection,
				 onSuccess	:function(httpObj){
				 	resourceSelection.loadResourceData(httpObj.responseText);
				 },
				 onFailure	:function(){
					 alert('Server Error.');
				 }
			 }
		);
	}
};

//* hashData
//*  - name
//*  - id
//*  - url (WSDL URL)
//*  - path [Pair, ...]
//*  - selection
//*  - dat
//*     - wrappername ("fujimitakokugo", etc..)
//*     - ja ("学校用語集", etc..)
//*     - children (Array)
//*        - category
//*        - ja
KawasakiParallelTextButton.prototype = {
	initialize: function(number,hashData,language){
		this.number = number;
		this.hashData = hashData;
		this.language = language;
		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' ,
			left : x+'px' ,
			top : y+'px' 
		});
		$(RESOURCE_BUTTON_BALLOON_HEADER_ID+this.number).show();
	},
	
	//* 非活性化した状態の表示
	hideIllustration: function(){
		$(RESOURCE_BUTTON_BALLOON_HEADER_ID+this.number).hide();
	},
	
	getHashDate: function(){
		return this.hashData;
	},
	
	getWsdlUrl: function(){
		return this.hashData.url;
	},
	
	getName: function(){
		return this.hashData.name;
	},
	
	getNameOfViewLanguage: function(){
		return this.hashData.dat[this.language];
	},
	
	//* IDを返す
	getId: function(){
		return this.hashData.id;
	},
	
	//* 活性化した状態の表示
	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 sources" id="'+RESOURCE_BUTTON_HEADER_ID+this.number+'"><div class="source-name" id="'+RESOURCE_BUTTON_NAME_HEADER_ID+this.number+'">'+this.getNameOfViewLanguage()+'</div></div>';
	},
	
	//* 辞書の説明文のHTML文を返す
	getLayer: function(){
		var pairArray = this.hashData.get('path');
		var pairInfo = this.getPairInfo();
		var popupClass = '';
		if(this.number % 5 > 2) popupClass = 'balloon top-right';
		else popupClass = 'balloon top-left';
		var illustration = '<div id="'+RESOURCE_BUTTON_BALLOON_HEADER_ID+this.number+'" onmouseover="this.show();" onmouseout="this.hide();"><div class="'+popupClass+'">'+
							'<div class="top iepngfix"></div>'+
							'<div class="comment iepngfix">'+
							'<h4>NAME</h4>'+
							this.hashData.get('name')+'<br />'+
							'<h4>Supported Language Pairs</h4>'+
							pairInfo+
							'<h4>URL</h4>'+
							'<a href="'+this.hashData.get('url')+'">'+this.hashData.get('url').truncate(40)+'</a></div>'+
							'<div class="bottom iepngfix"></div></div></div>';
		return illustration;
	},
	
	getSupportedLanguagePair: function(){
		return this.hashData.path;
	},
	
	//* サポート言語対の情報のHTMLを返す
	getPairInfo: function(){
		var pairArray = this.hashData.path;
		var pairInfo = '';
		var bidirectionalPairArray = new Array();
		var monodirectionalPairArray = new Array();
		for(i=0;i<pairArray.size();i++){
			var first = pairArray[i];
			var from = first.car();
			var to = first.cdr();
			var flag = false;
			for(j=i+1;j<pairArray.size();j++){
				if(pairArray[j].car() == to && pairArray[j].cdr() == from){
					pairArray = pairArray.without(pairArray[j]);
					bidirectionalPairArray.push(new Pair(from,to));
					flag = true;
					break;
				}
			}
			if(!flag) monodirectionalPairArray.push(new Pair(from,to));
		}
		
		for(i=0;i<bidirectionalPairArray.size();i++){
			pairInfo += Language.getNameByTag(bidirectionalPairArray[i].getFirst());
			pairInfo += ' <-> ';
			pairInfo += Language.getNameByTag(bidirectionalPairArray[i].getSecond());
			pairInfo += '<br />';
		}
		
		for(i=0;i<monodirectionalPairArray.size();i++){
			pairInfo += Language.getNameByTag(monodirectionalPairArray[i].getFirst());
			pairInfo += ' -> ';
			pairInfo += Language.getNameByTag(monodirectionalPairArray[i].getSecond());
			pairInfo += '<br />';
		}
		
		return pairInfo;
	}
};

KawasakiParallelTextSelection.Event = {
	load: function(resourceSelection){
		resourceSelection.loadResource();
	},
	
	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)));
			resourceSelection.setMostRecentlyClickedSourceNumber(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)));
			resourceSelection.setMostRecentlyClickedSourceNumber(parseInt(element.id.substring(RESOURCE_BUTTON_NAME_HEADER_ID.length)));
		} else {
			resourceSelection.setMostRecentlyClickedSourceNumber(-1);
		}
	},
	
	mouseoverButton: function(event,resourceSelection){
		//* @see Pair
		function _get_position_of_ballon(element,number){
			var cellPosition = element.cumulativeOffset();
			var bodyPosition = $$('body')[0].cumulativeOffset();
			var x = cellPosition[0] - bodyPosition[0]+element.getWidth() -15;
			var y = cellPosition[1] - bodyPosition[1]+(element.getHeight())/2;
			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();});
		}
	}
}

