/**********************************************************************
* /js/component/dictionary-creation-edit-dictionary.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
***********************************************************************/

//* クラスの名前の定義
var EditDictionary = Class.create();

var DataTable = Class.create();
var DataCell = Class.create();
var DataHeadCell = Class.create();
var InputWordField = Class.create();

var CreateDictionary = Class.create();
var LoadDictionary = Class.create();
var SaveDictionary = Class.create();
var RemoveDictionary = Class.create();
var UploadDictionary = Class.create();
var DownloadDictionary = Class.create();
var SelectAddLanguage = Class.create();
var SelectDeleteLanguage = Class.create();

var DICTIONARY_EDIT_PATH = './php/ajax/composite-translation-services/dictionary-edit.php';
var DOMAIN_SPECIFIC_TRANSLATE_PATH = './php/ajax/composite-translation-services/domain-specific-translate.php';
var LOAD_SUPPORTED_LANGUAGES_PATH = './php/ajax/composite-translation-services/load-supported-languages.php';

var DEFAULT_ROWS = 3; //* 新しい辞書の作成時に作成される列の数

var ID_DICTIONARY_DATA_TABLE = 'edit-dictionary-table';
var ID_DICTIONARY_HEAD = 'edit-dictionary-head';
var ID_DICTIONARY_BODY = 'edit-dictionary-body';
var ID_DICTIONARY_MESSAGE_AREA = 'edit-dictionary-message-area';

var ID_CURRENT_FILE_NAME = 'current-file-name';
var ID_UNSAVED = 'unsaved';
var ID_DICTIONARY_TABLE_MESSAGE_AREA = 'edit-dictionary-table-message-area';

var isIE = (document.documentElement.getAttribute("style") == document.documentElement.style);
var inputWordField = null;

var createDictionary = null;
var loadDictionary = null;
var saveDictionary = null;
var removeDictionary = null;
var uploadDictionary = null;
var downloadDictionary = null;
var selectAddLanguage = null;
var selectDeleteLanguage = null;

EditDictionary.prototype = {

	//*初期化する際に、辞書のリストと対応言語を取得
	initialize: function(){

		//* 各ボタンのクラスを生成する
		this.dataTable = new DataTable(new Array(), new Array(), "");
		this.displayedDictionaryName = "Untitled";
		this.dataTable.rowSelected = false;


		//*言語リストを取得する
		this.allLanguageList = new Array();	//* 全ての言語のリスト
		this.unusedLanguageList = new Array();	//* 未使用の言語リスト
		this.usedLanguageList = new Array();	//* 使用済みの言語のリスト
		this.loadLanguageList();

		inputWordField = new InputWordField(this.dataTable);
		this.dataTable.setWordField(inputWordField);

		createDictionary = new CreateDictionary(this.dataTable);
		loadDictionary = new LoadDictionary(this.dataTable);
		saveDictionary = new SaveDictionary(this.dataTable);
		removeDictionary = new RemoveDictionary(this.dataTable);
		uploadDictionary = new UploadDictionary(this.dataTable);
		downloadDictionary = new DownloadDictionary(this.dataTable);

		selectAddLanguage = new SelectAddLanguage(this.dataTable);
		selectDeleteLanguage = new SelectDeleteLanguage(this.dataTable);

		//* 辞書のファイル操作ボタンにイベントを関連付け
		Event.observe('load-dictionary', 'click', this.openLoadDictionaryPane.bind(this));
		Event.observe('save-dictionary', 'click', this.openSaveDictionaryPane.bind(this));
		Event.observe('create-dictionary', 'click', this.openCreateDictionaryPane.bind(this));
		Event.observe('remove-dictionary', 'click', this.openRemoveDictionaryPane.bind(this));
		Event.observe('upload-dictionary', 'click', this.openUploadDictionaryPane.bind(this));
		Event.observe('download-dictionary', 'click', this.openDownloadDictionaryPane.bind(this));

		//* 辞書データの編集ボタンにイベントを関連付け
		Event.observe('add-record', 'click', this.addRecord.bind(this));
		Event.observe('up-record', 'click', this.upRecord.bind(this));
		Event.observe('down-record', 'click', this.downRecord.bind(this));
		Event.observe('delete-record', 'click', this.deleteRecord.bind(this));
		Event.observe('add-language', 'click', this.openAddLanguagePane.bind(this));
		Event.observe('delete-language', 'click', this.openDeleteLanguagePane.bind(this));

		//* クリックしたときは、行選択
		Event.observe($(ID_DICTIONARY_DATA_TABLE).down('tbody'), 'click', function(event) {
			var cells;
			if ( this.dataTable.selectedRowNumber >= 0 ) {
				cells = $(ID_DICTIONARY_DATA_TABLE).down('tbody')
				.getElementsByTagName( 'tr' )[this.dataTable.selectedRowNumber]
				.getElementsByTagName( 'td' );
				for ( var i = cells.length - 1; i >= 0; i-- ) {
					Element.removeClassName( cells[i], 'selectedRow' );
				}
			}
			cells = Event.element( event ).up( 'tr ' ).getElementsByTagName( 'td' );
			for ( var i = cells.length - 1; i >= 0; i-- ) {
				Element.addClassName( cells[i], 'selectedRow' );
			}
			this.dataTable.selectedRowNumber = parseInt( cells[0].id.split( '_' )[0] );

			this.dataTable.rowSelected = true;

		}.bind(this));

		//* ダブルクリックしたときは単語編集
		Event.observe($(ID_DICTIONARY_DATA_TABLE).down('tbody'), 'dblclick', function(event) {
			var element = $(Event.element(event));
			if ( element.tagName.toUpperCase() != 'TD' ) return;
			var tablePosition = element.id.split('_');
			inputWordField.show( element, parseInt( tablePosition[0] ), parseInt( tablePosition[1] ) );
		});

	},

	//* 対応言語のリストを取得 (USED)
	//* TODO implement
	loadLanguageList: function(){

		//* safariのために、アドレス取得に特別な処理
		var topPageLocation = location.href.substr(0, location.href.lastIndexOf("/"));

		var editDictionary = this;
		new Ajax.Request(
			topPageLocation + '/php/ajax/dictionary-creation/load-supported-languages.php',
			{
				method		:'post',
				parameters	:'serviceCategory=document-translation',
				editDictionary: editDictionary,
				onSuccess	:function(httpObj){
					var langArray = eval("("+httpObj.responseText+")");
					//* アドホックな対応だが、ワークフローの例外を防ぐためzh-TWを削る
					this.setLanguageList(langArray.contents.without("zh-TW"));
				}.bind(this),
				onFailure	:function(){
					alert('Server Error.');
				},
				onComplete :function(){
				}
			}
		);
	},

	//* 選択されている行の上に行を追加する、選択されていなければ、一番上に追加する (USED)
	addRecord: function(){
		this.dataTable.addRecord();
		this.setFileName(editDictionary.getFileName(), true);
	},

	//* 選択されている行を一行上げる (USED)
	upRecord: function(){

		//*行が選択されていない場合、行が0の場合は何も起きない
		if(this.dataTable.rowSelected === false || this.dataTable.selectedRowNumber == 0) return;

		//*ここで何らかの処理が必要そう
		this.dataTable.moveRow('up');
		this.setFileName(editDictionary.getFileName(), true);
	},

	//* 選択されている行を一行下げる (USED)
	downRecord: function(){

		//*行が選択されていない場合、行が一番下の場合は何も起きない
		if(this.dataTable.rowSelected === false || this.dataTable.selectedRowNumber == this.dataTable.cellsArray.length-1) return;

		this.dataTable.moveRow('down');
		this.setFileName(editDictionary.getFileName(), true);
	},

	//* 選択されている行を削除する (USED)
	deleteRecord: function(){
		//*行が選択されていない場合、何も起きない
		if(this.dataTable.rowSelected === false) return;

		this.dataTable.deleteRecord(this.dataTable.selectedRowNumber);
		this.setFileName(editDictionary.getFileName(), true);

	},

	//* 対応言語のリストなどを設定 (USED)
	setLanguageList: function(languageArray){
		languageArray.sort(compareName);
		function compareName(a, b){
			return Language.getNameByTag(a) > Language.getNameByTag(b) ? 1 : -1;
		};

		this.unusedLanguageList = languageArray;
		this.allLanguageList = languageArray;
	},

	//* データテーブルをCSVに変換し、
	//* targetID を持つ、tyep="hidden" の input 要素に格納する。 (USED)
	setValueToDownload: function(targetID){
		$(targetID).value = this.seriarizeDictionaryAsCSV();
	},

	//* データテーブルを単純な2次元配列に変換
	getDictioanryAsMatrix: function(){

		var tableHeadArray = this.dataTable.tableHeadArray;
		var cellsArray = this.dataTable.cellsArray;

		var rtnArray = new Array();

		//* 言語対を表す行を作成
		var langLine = new Array();
		for (var i=0; i<tableHeadArray.length; i++) {
			langLine.push(Language.getTagByName(tableHeadArray[i].language));
		}

		rtnArray.push(langLine);

		//* 対訳を表す行を作成
		for(var i=0; i<cellsArray.length; i++){
			var termLine = new Array();
			for(var j=0; j<cellsArray[i].length; j++){
				termLine.push(cellsArray[i][j].value);
			}
			rtnArray.push(termLine);
		}

		return rtnArray;
	},

	//* データテーブルをCSVに変換する
	seriarizeDictionaryAsCSV: function(){

		var tableHeadArray = this.dataTable.tableHeadArray;
		var cellsArray = this.dataTable.cellsArray;

		//* 言語対を表す行を作成
		var langLine = '';
		for (var i=0; i<tableHeadArray.length; i++) {
			langLine = langLine + Language.getTagByName(tableHeadArray[i].language) + "	";
		}

		langLine = langLine.substr(0, langLine.length-1) + "\n";

		//* 対訳を表す行を作成
		var termLines = '';

		for(var i=0; i<cellsArray.length; i++){
			var termLine = '';
			for(var j=0; j<cellsArray[i].length; j++){

				termLine = termLine + cellsArray[i][j].value + "	";
			}

			termLines = termLines + termLine.substr(0, termLine.length-1) + "\n";
		}

		termLines = termLines.substr(0, termLines.length-1);

		return langLine + termLines;
	},

	//* データテーブルをJSONに変換する
	seriarizeDictionaryAsJSON: function(){

		globalValueForDebug = this.dataTable;

		var rtnArray = new Array();

		var tableHeadArray = this.dataTable.tableHeadArray;
		var cellsArray = this.dataTable.cellsArray;

		//* 言語対を表す配列を作成
		var langArray = new Array();
		for (var i=0; i<tableHeadArray.length; i++) {
			langArray.push(Language.getTagByName(tableHeadArray[i].language));
		}

		rtnArray.push(langArray);


		//* 対訳を表す行を作成

		for(var i=0; i<cellsArray.length; i++){
			var termArray = new Array();
			for(var j=0; j<cellsArray[i].length; j++){
				termArray.push(cellsArray[i][j].value);
			}

			rtnArray.push(termArray);
		}

		return JSON.encode(rtnArray);
	},

	setLoadedValue: function(loadResult, filename){

		if(loadResult.status != 'OK'){
			//* TODO 例外処理を実装
			alert("Dictionary File Error: " + loadResult.message);
			loadDictionary.hidePane();
			this.finishLoading("Dictionary was not uploaded.");
		} else {
			this.updateTable(loadResult.contents);
			loadDictionary.hidePane();
			this.finishLoading("Dictionary was loaded.");

			this.setFileName(filename, false);
		}

	},

	setUploadedValue: function(uploadResult, filename){

		if(uploadResult.status != 'OK'){
			//* TODO 例外処理を実装
			alert("Dictionary File Error: " + uploadResult.message);
			uploadDictionary.hidePane();
			this.finishLoading("Dictionary was not uploaded.");
		} else {
			this.updateTable(uploadResult.contents);
			uploadDictionary.hidePane();
			this.finishLoading("Dictionary was uploaded.");
			if($("upload-type-selection-add") && $("upload-type-selection-add").checked)
				this.setFileName(this.getFilename(), true);
			else
				this.setFileName(filename, true);
		}

	},

	//* 辞書データを受取り、テーブルを更新する(Used)
	updateTable: function(dictData){

		$(ID_DICTIONARY_TABLE_MESSAGE_AREA).hide();

		//* 二次元配列 dictData[][]を受け取る．
		//* PHPにより，各配列の要素数が等しい事は保証されている．
		//* dictData[0]には言語コードが記述されていることが期待されている．

		//* Check if Strings in dictData[0] are valid language codes.

		var LangTags = new Array();

		if(dictData == null){
			alert("Dictionary File Format Error: Dictionary is empty.");
			editDictionary.finishLoading("Dictionary File Format Error: Dictionary is empty.");
			return;
		}

		var langLine = dictData[0];
		var aLangName;
		for(var i=0; i<dictData[0].length; i++){

			aLangName = Language.getNameByTag(langLine[i]);

			if (aLangName == langLine[i]){
				if (i == dictData[0].length - 1 && aLangName.length == 0) {
					//* 言語資源を表す行の末尾がタブだった場合に対応
					break;
				}
				else {
					//* 不適切な言語タグが含まれていた場合
					alert("Dictionary File Format Error: " + aLangName + " is Invalid Language Tag.");
					editDictionary.finishLoading("Dictionary File Format Error: " + aLangName + " is Invalid Language Tag.");
					return;
				}
			} else if(LangTags.indexOf(langLine[i]) != -1) {
				alert("Dictionary File Format Error: Dictionary Contains Multiple " + aLangName + " Rows.");
				editDictionary.finishLoading("Dictionary File Format Error: Dictionary Contains Multiple " + aLangName + " Rows.");
				return;
			} else
				LangTags[i] = langLine[i];
		}

		//* テーブル用のデータを作成
		var tableData = new Array();
		var lengthExceeded = false;

		for(var i=1; i<dictData.length; i++){
			var aRow = new Array();

			for (var j = 0; j < LangTags.length; j++) {
				if (typeof(dictData[i][j]) == "undefined") continue; //* 対訳の数が足りなかった場合
				if (dictData[i][j].length > 80) {
					dictData[i][j] = dictData[i][j].substring(0, 80);
					lengthExceeded = true;
				}
				aRow.push(dictData[i][j]);
			}

			tableData.push(aRow);
		}


		if($("upload-type-selection-add") && $("upload-type-selection-add").checked)
			this.mergeDataTable(LangTags, tableData);
		else
			this.dataTable = new DataTable(LangTags, tableData, "Untitled");

		//* inputWordFieldを追加
		inputWordField = new InputWordField(this.dataTable);
		this.dataTable.setWordField(inputWordField);

		if(lengthExceeded) alert("Part of your input was too long and cut into 80 characters.");
	},

	//* this.dataTable の末尾に tableData を追加．
	mergeDataTable : function(langTags, tableData){

		//* originalTable での列番号 → additionalTable での列番号 と対応付けるマップを作成
		var oIdx2aIdx = new Array();
		for(var oIdx=0; oIdx<this.dataTable.tableHeadArray.length; oIdx++){
			for(var aIdx=0; aIdx<langTags.length; aIdx++){
				if (this.dataTable.tableHeadArray[oIdx].code == langTags[aIdx]) {
					oIdx2aIdx[oIdx] = aIdx;
				}
			}
		}

		//* 実際にデータを追加
		for(var aIdx=0; aIdx<tableData.length; aIdx++){
			var row = new Array();
			for(var s=0; s<this.dataTable.tableHeadArray.length; s++){
				if(oIdx2aIdx[s] >= 0)
					row.push(new DataCell(tableData[aIdx][oIdx2aIdx[s]]));
				else
					row.push(new DataCell(""))
			}
			this.dataTable.cellsArray.push(row);
		}

		this.dataTable.displayDataTableBody();
	},

	startLoading : function( msg ) {
		var area = $(ID_DICTIONARY_MESSAGE_AREA);
		while ( area.firstChild ) area.removeChild( area.firstChild );
		if ( msg ) {
			area.innerHTML = msg;
		}
		var img = new Image();
		img.src = 'img/anime/ajax-loader3.gif';
		area.appendChild( img );
	},

	finishLoading : function( msg ) {
		var area = $(ID_DICTIONARY_MESSAGE_AREA);
		while ( area.firstChild ) area.removeChild( area.firstChild );
		if ( msg ) {
			area.innerHTML = msg;
		}
	},

	setFileName : function(filename, unsaved){
		this.displayedDictionaryName = filename;

		if (filename.length > 20) {
			$(ID_CURRENT_FILE_NAME).innerHTML = "<span title=" + filename + ">" + filename.substring(0, 20) + "...</span>";
		} else {
			$(ID_CURRENT_FILE_NAME).innerHTML = filename;
		}

		$(ID_UNSAVED).innerHTML = unsaved ? "*" : "";
	},

	getFileName : function(){
		return this.displayedDictionaryName;
	},

	//* ユーザの所属組織の作成したユーザ辞書リスト（文字列の配列）を取得
	loadDictionaryList: function(){

		new Ajax.Request(
			'./php/ajax/dictionary-creation/dict-listup.php',
			{
				method		:'post',
				//* asynchronous	:false //* 読み込まれるまで操作されたくないので
				onSuccess	:function(httpObj){

					var dictNameArray = eval("("+httpObj.responseText+")");

					var checker = new StatusProcessor(dictArray);
					if(!checker.check()) return;

					UserDictionary.finishLoading( 'Dictionary list was loaded. Please <span style="color:red">select</span> your dictionary and \'<span style="color:red">Load Dictionary</span>\'.' );
					userDictionary.setDictionaryList(dictArray.contents);
				},
				onFailure	:function(){
					UserDictionary.finishLoading();
					alert('Server Error.');
				},
				onComplete :function(){
				}
			}
		);
	},

	openAddLanguagePane: function(){

		var element = $('add-language');
		var cellPosition = element.cumulativeOffset();
		var bodyPosition = $$('body')[0].cumulativeOffset();

		selectAddLanguage.showPane(cellPosition[0]-bodyPosition[0]-30,cellPosition[1]-bodyPosition[1]-0+20);

	},

	openDeleteLanguagePane: function(){

		var element = $('add-language');
		var cellPosition = element.cumulativeOffset();
		var bodyPosition = $$('body')[0].cumulativeOffset();
		selectDeleteLanguage.showPane(cellPosition[0]-bodyPosition[0]-30,cellPosition[1]-bodyPosition[1]-0+20);

	},

	openCreateDictionaryPane: function(){

		var element = $('create-dictionary');
		var cellPosition = element.cumulativeOffset();
		var bodyPosition = $$('body')[0].cumulativeOffset();

		createDictionary.showPane(cellPosition[0]-bodyPosition[0]-30,cellPosition[1]-bodyPosition[1]-0+20);

	},

	openLoadDictionaryPane: function(){

		var element = $('load-dictionary');
		var cellPosition = element.cumulativeOffset();
		var bodyPosition = $$('body')[0].cumulativeOffset();

		loadDictionary.showPane(cellPosition[0]-bodyPosition[0]-30,cellPosition[1]-bodyPosition[1]-0+20);

	},

	openSaveDictionaryPane: function(){

		var element = $('save-dictionary');
		var cellPosition = element.cumulativeOffset();
		var bodyPosition = $$('body')[0].cumulativeOffset();

		saveDictionary.showPane(cellPosition[0]-bodyPosition[0]-30,cellPosition[1]-bodyPosition[1]-0+20);

	},

	openRemoveDictionaryPane: function(){

		var element = $('remove-dictionary');
		var cellPosition = element.cumulativeOffset();
		var bodyPosition = $$('body')[0].cumulativeOffset();

		removeDictionary.showPane(cellPosition[0]-bodyPosition[0]-30,cellPosition[1]-bodyPosition[1]-0+20);

	},

	openUploadDictionaryPane: function(){

		var element = $('upload-dictionary');
		var cellPosition = element.cumulativeOffset();
		var bodyPosition = $$('body')[0].cumulativeOffset();

		uploadDictionary.showPane(cellPosition[0]-bodyPosition[0]-30,cellPosition[1]-bodyPosition[1]-0+20);

	},

	openDownloadDictionaryPane: function(){

		var element = $('download-dictionary');
		var cellPosition = element.cumulativeOffset();
		var bodyPosition = $$('body')[0].cumulativeOffset();

		downloadDictionary.showPane(cellPosition[0]-bodyPosition[0]-30,cellPosition[1]-bodyPosition[1]-0+20);

	},

	isValidFilename: function(fileName){

		var pattern = /^([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]*$/; //* 半角英数字および"-","_"

		if (fileName.toString().match(pattern) == null)
			return false;
		else
			return true;
	}
};

//* @classDescription	ユーザ辞書のVisibleなテーブル

//* idが扱えるように変更しなければならない（優先度も）
DataTable.prototype = {
	//* コンストラクタ (USED)
	initialize: function(languages,data, name){

		this.selectedRowNumber = -1;
		this.rowSelected = false;

		this.dictName = name;
		this.tableHeadArray = new Array();
		this.cellsArray = new Array();

		if(languages.length == 0)return;

		//* 言語部分の処理
		for(var i=0; i<languages.length; i++){
			this.tableHeadArray.push(new DataHeadCell(languages[i]));
		}
		this.displayDataTableHead();

		//* データ部分の処理
		for(var i=0; i<data.length; i++){
			var row = new Array();
			for(var s=0; s<data[i].length; s++){
				row.push(new DataCell(data[i][s]));
			}
			this.cellsArray.push(row);
		}

		this.displayDataTableBody();


	},

	//* テーブルヘッダを表示
	//* 同時にeditDictionaryの言語リストも更新する
	displayDataTableHead: function(){

		var headTR = document.createElement('tr');
		var width = 880/this.tableHeadArray.length;

		editDictionary.unusedLanguageList = editDictionary.allLanguageList;
		editDictionary.usedLanguageList = new Array();

		for(var i=0; i<this.tableHeadArray.length; i++){

			var langTag = Language.getTagByName(this.tableHeadArray[i].getLanguage());
			editDictionary.unusedLanguageList = editDictionary.unusedLanguageList.without(langTag);
			editDictionary.usedLanguageList.push(Language.getTagByName(langTag));

			var headTH = document.createElement('th');
			headTH.id = 'userDictHeadCell_' + i;
			headTH.innerHTML = this.tableHeadArray[i].getLanguage();
			Element.setStyle(headTH, {
				'width': width + 'px'
			});
			headTR.appendChild(headTH);
		}

		// eip kawauchi mod start 20100115
		// 辞書ロード時に、前の辞書の言語リストが残ってしまうバグを修正
//		var oldHeadTR = $(ID_DICTIONARY_HEAD).childNodes;
		var oldHeadTR = $(ID_DICTIONARY_HEAD).children;
		// eip kawauchi mod end 20100115

		if(oldHeadTR.length != 0)$(ID_DICTIONARY_HEAD).removeChild(oldHeadTR[0]);
		$(ID_DICTIONARY_HEAD).appendChild(headTR);

	},

	displayDataTableBody: function(){

		var oldBodyTR = $(ID_DICTIONARY_BODY).childNodes;
		var deleteRowNumber = oldBodyTR.length;
		for(var i=0; i<deleteRowNumber; i++){
			$(ID_DICTIONARY_BODY).removeChild(oldBodyTR[0]);
		}

		var width = 880/this.tableHeadArray.length;

		for(var i=0; i<this.cellsArray.length; i++){
			var bodyTR = document.createElement('tr');
			bodyTR.id = 'rowNumber_' + i;

			for(var s=0; s<this.cellsArray[i].length; s++){
				var bodyTD = document.createElement('td');
				bodyTD.id = i + "_" + s;
				Element.setStyle(bodyTD, {
					'width': width + 'px'
				});
				if(i % 2 == 0){ //* 奇数列
					bodyTD.className = "color1";
				} else {
					bodyTD.className = "color2";
				}
				bodyTD.appendChild( document.createTextNode( this.cellsArray[i][s].getValue() ) );
				bodyTR.appendChild(bodyTD);
			}

			$(ID_DICTIONARY_BODY).appendChild(bodyTR);
		}
	},


	//* 選択されている行の上に一行追加、選択されていなければ一番上に追加
	addRecord: function(){
		var newRecord = new Array();

		for(var i=0; i<this.tableHeadArray.length;i++){
			newRecord[i] = new DataCell("");
		}

		if(this.selectedRowNumber > 0)
			this.cellsArray.splice(this.selectedRowNumber, 0, newRecord);
		else
			this.cellsArray.unshift(newRecord);

		//* 無理やり表示
		this.displayDataTableBody();
		if(this.rowSelected != false){
			this.selectedRowNumber++;
			var elementArray = $('rowNumber_' + this.selectedRowNumber).childElements();
			elementArray.each(function(e){e.addClassName('selectedRow');});
		}

		editDictionary.finishLoading( "Record is added to the dictionary." );

	},

	//* 言語を追加
	addLanguage: function(languages){

		for(var i=0; i<languages.length; i++)
			this.tableHeadArray.push(new DataHeadCell(languages[i]));

		for(var i=0; i<this.cellsArray.length; i++){
			for(var s=0; s<languages.length; s++){
				this.cellsArray[i].push(new DataCell(""));
			}
		}

		this.displayDataTableHead();
		this.displayDataTableBody();
		if(this.rowSelected != false){
			var elementArray = $('rowNumber_' + this.selectedRowNumber).childElements();
			elementArray.each(function(e){e.addClassName('selectedRow');});
		}

		if(languages.length == 1){
			editDictionary.finishLoading( '\'<span style="color:red;">' + Language.getNameByTag(languages[0]) + '</span>\' was added to the dictionary.' );
		}else if(languages.length > 1){
			var langMessage = "";
			for(var i=0; i<languages.length; i++){
				langMessage += '\'<span style="color:red;">' + Language.getNameByTag(languages[i]) + '</span>\'';
				if(i < languages.length-2){
					langMessage += "&nbsp;,&nbsp;";
				}else if(i == languages.length-2){
					langMessage += "&nbsp;and&nbsp;";
				}
			}
			editDictionary.finishLoading( langMessage + " were added to the dictionary." );
		}

		editDictionary.setFileName(editDictionary.getFileName(), true);
	},

	//* 言語を削除
	deleteLanguage: function(languages){

		for(var i=0; i<languages.length; i++){
			//* 削除する言語ごとの処理
			//* 削除する言語をヘッダから探し出し、その行を削除する

			for(var j=0; j<this.tableHeadArray.length; j++){
				if(this.tableHeadArray[j].getCode() == languages[i]){
					//* headerおよびbodyからj番目を削除

					this.tableHeadArray.splice(j, 1);
					for(var l=0; l<this.cellsArray.length; l++)
						this.cellsArray[l].splice(j, 1);
					break;
				}
			}
		}

		this.displayDataTableHead();
		this.displayDataTableBody();

		if(this.rowSelected != false){
			var elementArray = $('rowNumber_' + this.selectedRowNumber).childElements();
			elementArray.each(function(e){e.addClassName('selectedRow');});
		}

		if(languages.length == 1){
			editDictionary.finishLoading( '\'<span style="color:red;">' + Language.getNameByTag(languages[0]) + '</span>\' was deleted from the dictionary.' );
		}else if(languages.length > 1){
			var langMessage = "";
			for(var i=0; i<languages.length; i++){
				langMessage += '\'<span style="color:red;">' + Language.getNameByTag(languages[i]) + '</span>\'';
				if(i < languages.length-2){
					langMessage += "&nbsp;, &nbsp;";
				}else if(i == languages.length-2){
					langMessage += "&nbsp;and &nbsp;";
				}
			}
			editDictionary.finishLoading( langMessage + " were deleted from the dictionary." );
		}

		editDictionary.setFileName(editDictionary.getFileName(), true);
	},

	//* 行を上下に移動する (Used)
	moveRow: function(upOrDown){

		if(upOrDown == 'up'){
			var temp = this.cellsArray[this.selectedRowNumber];
			var next = this.selectedRowNumber-1;
			this.cellsArray[this.selectedRowNumber] = this.cellsArray[next];
			this.cellsArray[next] = temp;

			this.displayDataTableBody();
			this.selectedRowNumber--;
			var elementArray = $('rowNumber_' + this.selectedRowNumber).childElements();
			elementArray.each(function(e){e.addClassName('selectedRow');});

		}else if(upOrDown == 'down'){
			var temp = this.cellsArray[this.selectedRowNumber];
			var next = this.selectedRowNumber-0+1;
			this.cellsArray[this.selectedRowNumber] = this.cellsArray[next];
			this.cellsArray[next] = temp;

			this.displayDataTableBody();
			this.selectedRowNumber++;
			var elementArray = $('rowNumber_' + this.selectedRowNumber).childElements();
			elementArray.each(function(e){e.addClassName('selectedRow');});
		}

	},

	deleteRecord: function(selectedRowNum){

		this.cellsArray.splice(selectedRowNum,1);
		this.displayDataTableBody();
		editDictionary.finishLoading( "Record has been deleted." );

		this.selectedRowNumber = -1;
		this.rowSelected = false;

	},

	editTerm: function(row,col,value){

		if(value == this.cellsArray[row][col].getValue())return;
		this.updateCell(row, col, value);
		editDictionary.setFileName(editDictionary.getFileName(), true);
	},

	//* 操作する単語入力フィールドの指定
	//* @param {InputWordField} wordField
	setWordField: function(wordField){
		this.wordField = wordField;
	},

	//* 行の数を返す
	getNumberOfRow: function(){
		return this.numRow;
	},

	//* 列の数を返す
	getNumberOfCol: function(){
		return this.numCol;
	},

	//* 対応言語の配列を返す
	getSupportedLanguageArray: function(){
		//*var arr = new Array('en','ja','ko','zh','it','fr','de','es','pt');
		return this.supportedLanguageArray;
	},

	//* cellDataTableからrow行col列のセルを得る
	//* @param {Number} row
	//* @param {Number} col
	getCell: function(row,col){
		return this.cellsArray[row][col];
	},

	//* row行col列のセル値をvalueに更新
	//* @param {Number} row
	//* @param {Number} col
	//* @param {String} value
	updateCell: function(row,col,value){
		var cell = this.getCell(row,col);
		cell.setValue(value);
		$(row+'_'+col).innerHTML = cell.getValue();
	},

	//* テーブルの中身を返す
	getTableData: function(){

	},

	//* テーブルの高さを返す
	getHeight: function(){
		return $(this.id).down('tbody').getHeight();
	},

	//* テーブルの幅を返す
	getWidth: function(){
		return $(this.id).getWidth();
	}

};

//* @classDescription	テーブルの中の各セル
DataCell.prototype = {
	//* コンストラクタ
	initialize: function(value){
		if(value == null || value == 'undefined'){
			this.value = '';
		} else {
			this.value = value;
		}
	},

	//* メソッド
	//* セルの値を設定
	//* @param {String} value
	setValue: function(value){
		this.value = value;
	},

	//* セルの値を返す
	getValue: function(){
		return this.value;
	},

	//* セルの値をnum文字に省略して返す
	//* @param {Number} num
	getLabel: function(num){

	}
};

//* @classDescription	テーブルの中の各セル
DataHeadCell.prototype = {
	//* コンストラクタ
	initialize: function(langCode){
		this.code = langCode;
		this.language = Language.getNameByTag(this.code);
	},

	getCode: function(){
		return this.code;
	},

	setCode: function(langCode){
		this.code = langCode;
		this.language = Language.getNameByTag(this.code);
	},

	getLanguage: function(){
		return this.language;
	},

	setLanguage: function(langName){
		this.language = langName;
	}

};

//* @classDescription	セルをクリックしたときに現れるダイアログ
InputWordField.prototype = {
	//* コンストラクタ
	initialize: function(table){
		this.table = table;
		this.row = null;
		this.col = null;
		this.oldValue = '';

		var input = document.createElement( 'input' );
		input.type = 'text';
		Event.observe( input, 'blur', this.onblur.bindAsEventListener( this ) );
		Event.observe( input, 'keypress', this.onkeypress.bindAsEventListener( this ) );
		this.input = input;
	},

	//* メソッド
	//* ダイアログの表示
	//* @param {Number} width
	//* @param {Number} height
	//* @param {Number} row
	//* @param {Number} col
	show : function( element, row, col ) {
		var value = this.table.getCell( row, col ).getValue();
		this.oldValue = value
		this.row = row;
		this.col = col;
		this.input.value = value;
		while ( element.firstChild ) element.removeChild( element.firstChild );
		element.appendChild( this.input );
		Field.activate(this.input);
	},

	//* ダイアログの非表示
	hide: function(){
		var td = this.input.parentNode;
		this.input.parentNode.removeChild( this.input );
		if(td.childNodes.length == 0)
			td.appendChild( document.createTextNode( this.input.value ) );
	},

	cancel: function() {
		this.input.value = this.oldValue;
		this.hide();
	},

	//* データを送信
	submit: function(){
		this.hide();
		if ( this.input.value != this.oldValue ) {
			var value = this.input.value;

			//* 辞書作成Webサービスの都合により，入力文字数を制限．
			//* 正確には、DBMSのvarcharによる制限なので、こちらでもバイト数を制限すべきであるが，
			//* 文字列のバイト数を計算するのが面倒なので，全て3バイト文字でも大丈夫なように計算．(255/3 ≒ 80)
			if (value.length > 80) {
				value = value.substr(0, 80);
				alert("Your input was too long and cut into 80 characters.");
			}

			this.table.editTerm(this.row,this.col,value);
		}
	},

	onblur : function(event) {
		this.submit();
	},

	onkeypress : function(event) {
		switch ( event.keyCode ) {
		case Event.KEY_RETURN:
			this.submit();
			break;
		case Event.KEY_ESC:
			this.cancel();
			break;
		}
	}
};

//* @classDescription	言語を追加するボタン
SelectAddLanguage.prototype = {

	//* コンストラクタ
	initialize: function(tbl){

		if($('singleton-pane'))$('singleton-pane').remove();
		var ss = document.createElement("div");
		ss.id = 'singleton-pane';
		ss.className = 'input-box';
		this.paneID = 'singleton-pane';
		new Insertion.Bottom($$('body')[0],ss);
		this.table = tbl;
		this.selectedLangs = new Array();
		this.hidePane();

	},

	//* データの読み込み
	showPane: function(x,y){

		if(editDictionary.getFileName() == "Untitled") return;

		$(this.paneID).setStyle({
			position : 'absolute' ,
			left : x - 100 +'px' ,
			top : y +'px'
		});
		$(this.paneID).innerHTML = '';

		var prefix =	'<div class="popupbox"><div class="popuptitle"><img onclick="selectAddLanguage.hidePane();" src="img/common/popup-close.gif" />Add Language</div>' +
						'<form><div class="inner"><b>Select Language(s) to Add.</b><br /><div class="clearfix">';

		var postfix = 	'</div></div><div class="inner">' +
						'<div style="text-align:center;margin-top:10px;">' +
						'<input value="OK" class="button-lightblue" type="button" onclick="selectAddLanguage.submit();" />' +
						'<input type="button" onclick="selectAddLanguage.hidePane();" value="Cancel" class="button-gray" />' +
						'</div></div></form></div>';

		var chk = '';
		for (var i = 0; i < editDictionary.unusedLanguageList.length; i++) {
			chk = chk + '<span><input type="checkbox" value="' + editDictionary.unusedLanguageList[i] + '" /> ' +
			Language.getNameByTag(editDictionary.unusedLanguageList[i]) + '</span>';
		}

		if(chk=='') //* もう追加する言語がない場合
			chk = "There are no more languages to be added.";

		$(this.paneID).innerHTML = prefix + chk + postfix;
		$(this.paneID).show();
	},

	submit: function(){

		this.selectedLangs = new Array();
		var chks = $$('#singleton-pane input');
		chks.each((function(e){
			if(e.checked == true)this.selectedLangs.push(e.value);
		}).bind(this));

		editDictionary.dataTable.addLanguage(this.selectedLangs);

		this.hidePane();
	},

	hidePane: function(){
		$(this.paneID).hide();
	}
};

//* @classDescription	言語を追加するボタン
SelectDeleteLanguage.prototype = {
	//* コンストラクタ
	initialize: function(tbl){
		if($('singleton-pane'))$('singleton-pane').remove();
		var ss = document.createElement("div");
		ss.id = 'singleton-pane';
		ss.className = 'input-box';
		this.paneID = 'singleton-pane';
		new Insertion.Bottom($$('body')[0],ss);
		this.table = tbl;
		this.selectedLangs = new Array();
		this.hidePane();
	},

	//* データの読み込み
	showPane: function(x,y){

		if(editDictionary.getFileName() == "Untitled") return;

		$(this.paneID).setStyle({
			position : 'absolute' ,
			left : x - 100 +'px' ,
			top : y +'px'
		});
		$(this.paneID).innerHTML = '';

		var prefix =	'<div class="popupbox"><div class="popuptitle"><img onclick="selectDeleteLanguage.hidePane();" src="img/common/popup-close.gif" />Delete Language</div>' +
						'<form><div class="inner"><b>Select Language(s) to Delete.</b><br /><div class="clearfix">';

		var postfix = 	'<div id="delete-language-pane-alert" class="alert"></div>' +'</div></div>' +
						'<div class="inner"><div style="text-align:center;margin-top:10px;">' +
						'<input value="OK" class="button-lightblue" type="button" onclick="selectDeleteLanguage.submit();" />' +
						'<input type="button" onclick="selectDeleteLanguage.hidePane();" value="Cancel" class="button-gray" />' +
						'</div></div></form></div>';

		var chk = '';

		if (editDictionary.usedLanguageList.length <= 2) {
			chk = '<div>You cannot delete languages because the dictionary must cover at least two languages.<div>';
		}
		else {
			for (var i = 0; i < editDictionary.usedLanguageList.length; i++) {
				chk = chk + '<span><input type="checkbox" value="' + editDictionary.usedLanguageList[i] + '" /> ' +
				Language.getNameByTag(editDictionary.usedLanguageList[i]) +
				'</span>';
			}
		}

		$(this.paneID).innerHTML = prefix + chk + postfix;
		$(this.paneID).show();
	},

	submit: function(){

		this.selectedLangs = new Array();
		var chks = $$('#singleton-pane input');
		chks.each((function(e){
			if(e.checked == true)this.selectedLangs.push(e.value);
		}).bind(this));


		//* 削除後に言語数が2未満となるようなら、削除をキャンセル
		if(editDictionary.usedLanguageList.length - this.selectedLangs.length < 2){
			$('delete-language-pane-alert').innerHTML = 'Your dictionary must cover at least two languages.';
			return;
		}

		editDictionary.dataTable.deleteLanguage(this.selectedLangs);

		this.hidePane();
	},

	hidePane: function(){
		$(this.paneID).hide();
	}
};

//* @classDescription	新たに辞書を作成するボタン
CreateDictionary.prototype = {
	//* コンストラクタ
	initialize: function(tbl){
		if($('singleton-pane'))$('singleton-pane').remove();
		var cd = document.createElement("div");
		cd.id = 'singleton-pane';
		cd.className = 'input-box';
		this.paneID = 'singleton-pane';
		new Insertion.Bottom($$('body')[0],cd);
		this.table = tbl;
		this.selectedLangs = new Array();
		this.hidePane();
	},

	//* データの読み込み
	showPane: function(x,y){
		$(this.paneID).setStyle({
			position : 'absolute' ,
			left : x+'px' ,
			top : y+'px'
		});
		$(this.paneID).innerHTML = '';

		var prefix = 	'<div class="popupbox">	<div class="popuptitle"><img onclick="createDictionary.hidePane();" src="img/common/popup-close.gif" />Create Dictionary</div>' +
						'<form><div class="inner"><b>Select Languages</b><br /><div class="clearfix">';

		var postfix = 	'</div><div id="singleton-pane-alert2" class="alert"></div></div><div class="inner">' +
						'File name : <input id="create-dictionary-dictionary-name" type="text" name="textfield" class="service-input" onKeyPress="return createDictionary.submitStop(event);"/>' +
						'<br /><div id="singleton-pane-alert1" class="alert"></div>' +
						// mod start kitajima 20090821
//						'<p>Dictionaly file name can contain only(one-byte)English characters,numerals,undersore "_", hyphen "-" and period ".".</p>' +
						'<p>Dictionary file name can contain only(one-byte)English characters,numerals,undersore "_", hyphen "-" and period ".".</p>' +
						// mod end kitajima 20090821
						'<div style="text-align:center;margin-top:10px;">' +
						'<input id="create-dictionary-ok-button" name="ok" type="button" onclick="createDictionary.submit();" value="OK" class="button-lightblue" />' +
						'<input id="create-dictionary-cancel-button" type="button" onclick="createDictionary.hidePane();" name="Cancel" value="Cancel" class="button-gray" />' +
						'</div></div></form></div>'

		var chk = '';

		languages = editDictionary.allLanguageList;
		for(var i=0; i<languages.length; i++)
			chk = chk + '<span><input type="checkbox" value="' + languages[i] + '" /> ' + Language.getNameByTag(languages[i]) + '</span>';

		$(this.paneID).innerHTML = prefix + chk + postfix;
		$(this.paneID).show();
	},

	//* ちょっと不格好だが，ファイルセーブ前に前処理を入れたいので
	submitStop: function (e){

		if (!e) var e = window.event;
		if(e.keyCode == 13){
			createDictionary.submit();
			return false;
		}
	},

	submit: function(){

		//* 未セーブの場合警告を表示
		if ($(ID_UNSAVED).innerHTML == "*" &&
		!confirm('Your dictionary has not been saved after the last change.\n\nDiscard changes?')) {
			this.hidePane();
			return;
		}

		if($('create-dictionary-dictionary-name').value == ''){
			$('singleton-pane-alert1').innerHTML = 'Dictionary file name is empty';
			return;
		}

		if(!editDictionary.isValidFilename($('create-dictionary-dictionary-name').value)){
			$('singleton-pane-alert1').innerHTML = 'Invalid Dictionary file name';
			return;
		}

		$('singleton-pane-alert1').innerHTML = '';

		this.selectedLangs = new Array();

		var chks = $$('#singleton-pane input');

		chks.each((function(e){
			if(e.checked == true)this.selectedLangs.push(e.value);
		}).bind(this));

		if(this.selectedLangs.length < 2){
			$('singleton-pane-alert2').innerHTML = 'Select at least two languages.';
			return;
		}

		$(this.paneID).hide();

		editDictionary.startLoading( 'Creating Dictionary...' );

		var dictTable = new Array();

		//* 言語対を追加
		dictTable.push(this.selectedLangs);

		//* 空の対訳を追加
		for(var j=0; j<DEFAULT_ROWS; j++){
			var aLine = new Array();

			for(var k=0; k<this.selectedLangs.length; k++)
				aLine.push("");

			dictTable.push(aLine);

		}

		editDictionary.updateTable(dictTable);
		editDictionary.setFileName($('create-dictionary-dictionary-name').value, true);

		if (editDictionary.getFileName().length > 20) {
			editDictionary.finishLoading('Dictionary \'' + editDictionary.getFileName().substring(0, 20) + '...\' was created.');
		} else {
			editDictionary.finishLoading('Dictionary \'' + editDictionary.getFileName() + '\' was created.');
		}

		createDictionary.hidePane();
	},

	hidePane: function(){
		$(this.paneID).hide();
	}
};

//* @classDescription	Playgroundサーバに辞書をセーブするボタン
SaveDictionary.prototype = {
	//* コンストラクタ
	initialize: function(tbl){
		if($('singleton-pane'))$('singleton-pane').remove();
		var cd = document.createElement("div");
		cd.id = 'singleton-pane';
		cd.className = 'input-box';
		this.paneID = 'singleton-pane';
		new Insertion.Bottom($$('body')[0],cd);
		this.table = tbl;
		this.hidePane();
	},

	//* データの読み込み
	showPane: function(x,y){
		$(this.paneID).setStyle({
			position : 'absolute' ,
			left : (x-20) + 'px' ,
			top : y+'px'
		});
		$(this.paneID).innerHTML = '';

		// mod start kitajima 20090821
//		var content = 	'<div class="popupbox"><div class="popuptitle"><img onclick="saveDictionary.hidePane();" src="img/common/popup-close.gif" />Save Dictionaly</div>' +
		var content = 	'<div class="popupbox"><div class="popuptitle"><img onclick="saveDictionary.hidePane();" src="img/common/popup-close.gif" />Save Dictionary</div>' +
		// mod end kitajima 20090821
						'<form id="dict-save-form">' +
						'<div class="inner"><b>Save dictionary file to Playground server</b><br />' +
						'File name : <input type="text" name="dictName" class="service-input" value="'
						 + editDictionary.getFileName() + '" onKeyPress="return saveDictionary.submitStop(event);" />' +
						'<div id="save-dictionary-pane-alert" class="alert"></div>' +
						// mod start kitajima 20090821
//						'<p>Dictionaly file name can contain only(one-byte)English characters,numerals,undersore "_", hyphen "-" and period ".".</p>' +
						'<p>Dictionary file name can contain only(one-byte)English characters,numerals,undersore "_", hyphen "-" and period ".".</p>' +
						// mod end kitajima 20090821
						'<div style="text-align:center;margin-top:10px;">' +
						'<input value="OK" class="button-lightblue" type="button" onclick="saveDictionary.submit(\'valueToSaveDict\', \'dict-save-form\');"/>' +
						'<input type="hidden" value="" name="valueToSave" id="valueToSaveDict"/>' +
						'<input id="create-dictionary-cancel-button" type="button" onclick="saveDictionary.hidePane();" name="Cancel" value="Cancel" class="button-gray" />' +
						'</div></div></form></div>';

		$(this.paneID).innerHTML = content;

		$(this.paneID).show();
	},

	hidePane: function(){
		$(this.paneID).hide();
	},

	//* ちょっと不格好だが，ファイルセーブ前に前処理を入れたいので
	submitStop: function (e){
		if (!e) var e = window.event;
		if(e.keyCode == 13){
			saveDictionary.submit('valueToSaveDict', 'dict-save-form');
			return false;
		}
	},

	//* データをセーブする処理
	submit: function(targetID, formID){

		editDictionary.startLoading("Now saving dictionary...");

		//* セーブするためのデータを作成する
		editDictionary.setValueToDownload(targetID);

		//* 辞書が空だった場合、セーブされない
		if ($(targetID).value.length < 2) {
			editDictionary.finishLoading("Error: Empty dictionary cannot be saved.");
			removeDictionary.hidePane();
			return;
		}

		var formObj = $(formID);

		if(!editDictionary.isValidFilename(formObj.dictName.value)){
			$('save-dictionary-pane-alert').innerHTML = 'invalid Dictionary file name.';
			editDictionary.finishLoading("");
			return;
		}

		$('save-dictionary-pane-alert').innerHTML = '';

		editDictionary.setFileName(formObj.dictName.value, false);

		var callobj = {
			valueToSave: $(targetID).value,
			fileName: editDictionary.getFileName()
		};

		var formText=$H(callobj).toQueryString();

		new Ajax.Request('./php/ajax/dictionary-creation/dict-save.php', {
			method: 'post',
			asynchronous: false,
			parameters	:formText,
			onSuccess: function(httpObj){
				var resultObj = eval("("+httpObj.responseText+")");
				if (resultObj['status'] == 'WARNING' && resultObj['message'] == 'File Exists'){
					if (confirm('"' + callobj.fileName + '" already exists on the Playground server.\n\n'
						+ 'Overwrite the dictionary?')) {

						callobj.mode = "overwrite";
						var formText=$H(callobj).toQueryString();

						new Ajax.Request('./php/ajax/dictionary-creation/dict-save.php', {
							method: 'post',
							asynchronous: false,
							parameters	:formText,
							onSuccess: function(httpObj){
								var resultObj = eval("("+httpObj.responseText+")");
								if (resultObj['status'] != 'OK') {
									alert("Playground Error: " + resultObj.message);
									editDictionary.finishLoading("Dictionary was not saved.");
								} else {
									editDictionary.finishLoading("Dictionary was saved.");
								}
								saveDictionary.hidePane();
							},
							onFailure: function(){
								alert("Playground Error: failed to save dictionary on the Playground server.");
								editDictionary.finishLoading("Dictionary was not saved.");
							},
							onComplete: function(){
							}
						});
					}
					else {
						editDictionary.finishLoading("Dictionary was not saved.");
						saveDictionary.hidePane();
					}
				} else if (resultObj['status'] != 'OK') {
					alert("Playground Error: " + resultObj.message);
					editDictionary.finishLoading("Dictionary was not saved.");
				} else {
					editDictionary.finishLoading("Dictionary was saved.");
					saveDictionary.hidePane();
				}
			}.bind(callobj),
			onFailure: function(){
				alert("Playground Error: failed to save dictionary on the Playground server.");
				editDictionary.finishLoading("Dictionary was not saved.");
			},
			onComplete: function(){
			}
		});
	}
};

//* @classDescription	ローカルファイルからデータを読み込むボタン
LoadDictionary.prototype = {
	//* コンストラクタ
	initialize: function(tbl){
		if($('singleton-pane'))$('singleton-pane').remove();
		var cd = document.createElement("div");
		cd.id = 'singleton-pane';
		cd.className = 'input-box';
		this.paneID = 'singleton-pane';
		new Insertion.Bottom($$('body')[0],cd);
		this.table = tbl;
		this.selectedLangs = new Array();
		this.hidePane();
	},

	//* データの読み込み
	showPane: function(x,y){
		$(this.paneID).setStyle({
			position : 'absolute' ,
			left : x+'px' ,
			top : y+'px'
		});
		$(this.paneID).innerHTML = '';

		// mod start kitajima 20090821
//		var content =	'<div class="popupbox"><div class="popuptitle"><img onclick="loadDictionary.hidePane();" src="img/common/popup-close.gif" />Load Dictionaly</div><form id="dict-upload-form">' +
		var content =	'<div class="popupbox"><div class="popuptitle"><img onclick="loadDictionary.hidePane();" src="img/common/popup-close.gif" />Load Dictionary</div><form id="dict-upload-form">' +
		// mod end kitajima 20090821
						'<div class="inner"><b>Load dictionary file from Playground server</b><br />' +
						//* 'File name : <input type="text" name="dictName" class="service-input" value="" id="load-dictionary-dictionary-name" onKeyPress="return loadDictionary.submitStop(event);"/>' +
						'<br /><div id="dictionary-file-list-load"><div><img src="img/anime/ajax-loader8.gif" style="float:none"/> Now loading the dictionary file list...</div></div>' +
						'<div id="load-dictionary-pane-alert" class="alert"></div>' +
						'<div style="text-align:center;margin-top:10px;">' +
						'<input id="load-dictionary-ok-button" value="OK" class="button-lightblue" type="button"  onclick="loadDictionary.submit(\'dict-upload-form\');" />' +
						'<input id="load-dictionary-cancel-button" type="button" onclick="loadDictionary.hidePane();" name="Cancel" value="Cancel" class="button-gray" />' +
						'</div></div></form></div>';

		$(this.paneID).innerHTML = content;

		$(this.paneID).show();

		//* ユーザの所属組織のメンバーが作成した辞書のリストを作成
		new Ajax.Request('./php/ajax/dictionary-creation/dict-list.php', {
			method: 'post',
			asynchronous: false,
			parameters: "",
			onSuccess: function(httpObj){
				var resultObj = eval("("+httpObj.responseText+")");

				if (resultObj['status'] == 'OK') {
					if (resultObj["contents"].length == 0) {
						$("dictionary-file-list-load").firstChild.innerHTML = "Your organization have not saved any dictioanry files on the server. Please create or upload a dictioanry file first.";
					}
					else{
						var selectionObj = document.createElement("select");
						selectionObj.setAttribute("selectedIndex", "0");
						selectionObj.setAttribute("id", "dictionary-selection-list-load");
						selectionObj.setAttribute("style", "width:230px;");
						resultObj["contents"] = resultObj["contents"].sort();
						for(var i=0; i<resultObj["contents"].length; i++){
							var option = document.createElement("option");
							option.setAttribute("value",i);
							option.appendChild(document.createTextNode(resultObj["contents"][i]));
							selectionObj.appendChild(option);
						}
						$("dictionary-file-list-load").removeChild($("dictionary-file-list-load").firstChild);
						$("dictionary-file-list-load").appendChild(document.createTextNode("File name: "));
						$("dictionary-file-list-load").appendChild(selectionObj);
					}
				} else {
					alert(resultObj["message"]);
					return;
				}
			},
			onFailure: function(){
			alert("failure");
				alert("Playground Error: failed to load dictionary from the Playground server.");
				editDictionary.finishLoading("Dictionary was not loaded.");
				loadDictionary.hidePane();
				return;
			},
			onComplete: function(){}
		});
	},

	hidePane: function(){
		$(this.paneID).hide();
	},

	submitStop: function (e){
		if (!e) var e = window.event;
		if(e.keyCode == 13){
			loadDictionary.submit('dict-upload-form');
			return false;
		}
	},

	//* データをロードする処理
	submit: function(formID){

		//* 選択されている辞書名を取得
		if ($("dictionary-selection-list-load") === null) {
			loadDictionary.hidePane();
			return;
		}

		var dictName = $("dictionary-selection-list-load").options[$("dictionary-selection-list-load").selectedIndex].text;

		//* 未セーブの場合警告を表示
		if ($(ID_UNSAVED).innerHTML == "*" &&
		!confirm('Your dictionary has not been saved after the last change.\n\nDiscard changes?')) {
			this.hidePane();
			return;
		}

		if(!editDictionary.isValidFilename(dictName)){
			$('load-dictionary-pane-alert').innerHTML = "Dictionary not found on the Playground server.";
			return;
		}

		$('load-dictionary-pane-alert').innerHTML = '';

		editDictionary.startLoading("Now loading dictionary...");

		var callobj = {
			fileName: dictName
		};
		var formText=$H(callobj).toQueryString();

		new Ajax.Request('./php/ajax/dictionary-creation/dict-load.php', {
			method: 'post',
			asynchronous: false,
			parameters	:formText,
			onSuccess: function(httpObj){

				var resultObj = eval("("+httpObj.responseText+")");

				if (resultObj['status'] != 'OK') {
					if (resultObj.message.indexOf("not found") > -1) {
						$('load-dictionary-pane-alert').innerHTML = "Dictionary not found on the Playground server.";
						editDictionary.finishLoading("Dictionary not found on the Playground server.");
						this.hidePane();
						return;
					}
					else {
						alert("Playground Error: " + resultObj.message);
						editDictionary.finishLoading("Fail to load dictionary.");
						this.hidePane();
						return;
					}
				} else {
					editDictionary.setFileName(dictName, false);
					editDictionary.setLoadedValue(resultObj, dictName);

					editDictionary.finishLoading("Dictionary was loaded.");
					this.hidePane();
					return;
				}
			}.bind(dictName),
			onFailure: function(){
				alert("Playground Error: failed to load dictionary from the Playground server.");
				editDictionary.finishLoading("Dictionary was not loaded.");
				loadDictionary.hidePane();
				return;
			},
			onComplete: function(){}
		});
	}
};


RemoveDictionary.prototype = {
	//* コンストラクタ
	initialize: function(tbl){
		if($('singleton-pane'))$('singleton-pane').remove();
		var cd = document.createElement("div");
		cd.id = 'singleton-pane';
		cd.className = 'input-box';
		this.paneID = 'singleton-pane';
		new Insertion.Bottom($$('body')[0],cd);
		this.table = tbl;
		this.hidePane();
	},

	//* データの読み込み
	showPane: function(x,y){

		$(this.paneID).setStyle({
			position : 'absolute' ,
			left : x - 100 +'px' ,
			top : y +'px'
		});
		$(this.paneID).innerHTML = '';
		var title ='<div class="title">Remove Dictionary</div>';

		// mod start kitajima 20090821
//		var content = 	'<div class="popupbox"><div class="popuptitle"><img onclick="removeDictionary.hidePane();" src="img/common/popup-close.gif" />Remove Dictionaly</div>' +
		var content = 	'<div class="popupbox"><div class="popuptitle"><img onclick="removeDictionary.hidePane();" src="img/common/popup-close.gif" />Remove Dictionary</div>' +
		// mod end kitajima 20090821
						'<div class="inner">' +
						'<b>Dictionary file name to be removed from Playground server</b>' +
						//* '<br />File name : <input type="text" name="textfield" class="service-input" id="remove-dictionary-dictionary-name" onKeyPress="return removeDictionary.submitStop(event);"/>' +
						'<br /><br /><div id="dictionary-file-list-remove"><div><img src="img/anime/ajax-loader8.gif" style="float:none"/> Now loading the dictionary file list...</div></div>' +
						'<div id="remove-dictionary-pane-alert" class="alert"></div>' +
						'<div style="text-align:center;margin-top:10px;">' +
						'<input id="create-dictionary-ok-button" name="ok" type="button" onclick="removeDictionary.submit();" value="OK" class="button-lightblue" />' +
						'<input id="create-dictionary-cancel-button" type="button" onclick="removeDictionary.hidePane();" name="Cancel" value="Cancel" class="button-gray" />' +
						'</div></div>';

		$(this.paneID).innerHTML = content;

		$(this.paneID).show();

		//* ユーザの所属組織のメンバーが作成した辞書のリストを作成
		new Ajax.Request('./php/ajax/dictionary-creation/dict-list.php', {
			method: 'post',
			asynchronous: false,
			parameters: "",
			onSuccess: function(httpObj){
				var resultObj = eval("("+httpObj.responseText+")");

				if (resultObj['status'] == 'OK') {
					if (resultObj["contents"].length == 0) {
						$("dictionary-file-list-remove").firstChild.innerHTML = "Your organization have not saved any dictioanry files on the server. Please create or upload a dictioanry file first.";
					}
					else{
						var selectionObj = document.createElement("select");
						selectionObj.setAttribute("selectedIndex", "0");
						selectionObj.setAttribute("id", "dictionary-selection-list-remove");
						selectionObj.setAttribute("style", "width:230px;");
						resultObj["contents"] = resultObj["contents"].sort();
						for(var i=0; i<resultObj["contents"].length; i++){
							var option = document.createElement("option");
							option.setAttribute("value",i);
							option.appendChild(document.createTextNode(resultObj["contents"][i]));
							selectionObj.appendChild(option);
						}
						$("dictionary-file-list-remove").removeChild($("dictionary-file-list-remove").firstChild);
						$("dictionary-file-list-remove").appendChild(document.createTextNode("File name: "));
						$("dictionary-file-list-remove").appendChild(selectionObj);
					}
				} else {
					alert(resultObj["message"]);
					return;
				}
			},
			onFailure: function(){
			alert("failure");
				alert("Playground Error: failed to load dictionary from the Playground server.");
				editDictionary.finishLoading("Dictionary was not loaded.");
				loadDictionary.hidePane();
				return;
			},
			onComplete: function(){}
		});
	},

	hidePane: function(){
		$(this.paneID).hide();
	},

	submitStop: function (e){
		if (!e) var e = window.event;
		if(e.keyCode == 13){
			removeDictionary.submit();
			return false;
		}
	},

	submit: function(){

		//* 選択されている辞書名を取得
		if ($("dictionary-selection-list-remove")  === null) {
			this.hidePane();
			return;
		}


		//* 本当に削除しても良いかを確認．
		if(!window.confirm(
			"Removed dictionary file will be deleted from the server and \n"
			+ "cannot be restored.\n\n"
			+ "Are you really sure you want to remove the dicitionary file?")) return;

		var dictName = $("dictionary-selection-list-remove").options[$("dictionary-selection-list-remove").selectedIndex].text;

		if(!editDictionary.isValidFilename(dictName)){
			$('remove-dictionary-pane-alert').innerHTML = "Dictionary not found on the Playground server.";
			this.hidePane();
			return;
		}

		$('remove-dictionary-pane-alert').innerHTML = '';

		editDictionary.startLoading("Now removing dictionary '" + dictName + "' on the Playground server...");

		var callobj = {
			fileName: dictName
		};
		var formText=$H(callobj).toQueryString();

        new Ajax.Request('./php/ajax/dictionary-creation/dict-remove.php', {
            method: 'post',
            asynchronous: false,
			parameters	:formText,
            onSuccess: function(httpObj){
				var resultObj = eval("("+httpObj.responseText+")");
				if (resultObj['status'] != 'OK') {
					if (resultObj.message.indexOf("not found") > -1) {
						$('remove-dictionary-pane-alert').innerHTML = "Dictionary not found on the Playground server.";
						editDictionary.finishLoading("");
						return;
					}
					else {
						alert("Playground Error: " + resultObj.message);
						editDictionary.finishLoading("Dictionary '" + dictName + "' was not removed.");
					}
				} else {
					editDictionary.finishLoading("Dictionary '" + dictName + "' on the Playground server was removed.");
					removeDictionary.hidePane();
				}
            },
            onFailure: function(){
				alert("Playground Error: failed to remove dictionary on the Playground server.");
				editDictionary.finishLoading("Dictionary '" + dictName + "' was not removed.");
            },
            onComplete: function(){
            }
        });

	}
};

UploadDictionary.prototype = {
	//* コンストラクタ
	initialize: function(tbl){
		if($('singleton-pane'))$('singleton-pane').remove();
		var cd = document.createElement("div");
		cd.id = 'singleton-pane';
		cd.className = 'input-box';
		this.paneID = 'singleton-pane';
		new Insertion.Bottom($$('body')[0],cd);
		this.table = tbl;
		this.selectedLangs = new Array();
		this.hidePane();
	},

	//* データの読み込み
	showPane: function(x,y){

		$(this.paneID).setStyle({
			position : 'absolute' ,
			left : x - 200 +'px' ,
			top : y +'px'
		});
		$(this.paneID).innerHTML = '';

		//* テーブルに辞書が既に存在した場合、
		//* アップロードした辞書でテーブルを上書きするか、テーブルの末尾にアップロードした辞書を追加するかを指定できる
		var uploadTypeSelection = '';
		if(editDictionary.dataTable.tableHeadArray.length > 1){
			uploadTypeSelection =
			'<div style="text-align:left;margin-left:30px;"><input id="upload-type-selection-overwrite" name="upload-type-selection" value="overwrite" type="radio" checked/> Overwrite the current table.<br />' +
			'<input id="upload-type-selection-add" name="upload-type-selection" value="add" type="radio" /> Add to the bottom of the current table.<br /></div>';
		}

		// mod start kitajima 20090821
//		var content =	'<div class="popupbox"><div class="popuptitle"><img onclick="uploadDictionary.hidePane();" src="img/common/popup-close.gif" />Upload Dictionaly</div>' +
		var content =	'<div class="popupbox"><div class="popuptitle"><img onclick="uploadDictionary.hidePane();" src="img/common/popup-close.gif" />Upload Dictionary</div>' +
		// mod end kitajima 20090821
						'<form target="dummyframe" id="dict-upload-form" enctype="multipart/form-data" ' +
						'action="./php/ajax/dictionary-creation/dict-upload.php" method="post">' +
						'<div class="inner"><b>Upload dictionary file from your computer</b><br />' +
						'<input type="file" name="dictfile"  class="service-input2" />' +
						'<div style="text-align:center;margin-top:10px;">' + uploadTypeSelection +
						'<input id="create-dictionary-ok-button" name="ok" value="OK" class="button-lightblue" type="button" onclick="uploadDictionary.submit(\'dict-upload-form\');"/>' +
						'<input id="create-dictionary-cancel-button" type="button" onclick="uploadDictionary.hidePane();" name="Cancel" value="Cancel" class="button-gray" />' +
						'</div></form></div>' +
						'<iframe id="dummyframe" name="dummyframe" style="display: none;"></iframe>';

		$(this.paneID).innerHTML = content;

		$(this.paneID).show();
	},

	hidePane: function(){
		$(this.paneID).hide();
	},

	//* ちょっと不格好だが，ファイルアップロード前に前処理を入れたいので
	submitStop: function (e){
		if (!e) var e = window.event;
		if(e.keyCode == 13){
			loadDictionary.submit('dict-upload-form');
			return false;
		}
	},

	//* データをロードする処理
	submit: function(formID){

		//* 未セーブの場合警告を表示
		if (!($("upload-type-selection-add") && $("upload-type-selection-add").checked) &&
		$(ID_UNSAVED).innerHTML == "*" &&
		!confirm('Your dictionary has not been saved after the last change.\n\nDiscard changes?')) {
			this.hidePane();
			return;
		}

		editDictionary.startLoading("Now loading dictionary...");

		var formObj = $(formID);
		formObj.submit();

		uploadDictionary.hidePane();
		return;

	}
};

DownloadDictionary.prototype = {
	//* コンストラクタ
	initialize: function(tbl){
		if($('singleton-pane'))$('singleton-pane').remove();
		var cd = document.createElement("div");
		cd.id = 'singleton-pane';
		cd.className = 'input-box';
		this.paneID = 'singleton-pane';
		new Insertion.Bottom($$('body')[0],cd);
		this.table = tbl;
		this.selectedLangs = new Array();
		this.hidePane();
	},

	//* データの読み込み
	showPane: function(x,y){

		$(this.paneID).setStyle({
			position : 'absolute' ,
			left : x - 300 +'px' ,
			top : y +'px'
		});
		$(this.paneID).innerHTML = '';

		// mod start kitajima 20090821
//		var content =	'<div class="popupbox"><div class="popuptitle"><img onclick="downloadDictionary.hidePane();" src="img/common/popup-close.gif" />Download Dictionaly</div>' +
//						'<form id="dict-download-form" action="./php/ajax/dictionary-creation/dict-download.php" method="post"><div class="inner"><b>Download dictionaly file to your computer</b><br />' +
		var content =	'<div class="popupbox"><div class="popuptitle"><img onclick="downloadDictionary.hidePane();" src="img/common/popup-close.gif" />Download Dictionary</div>' +
						'<form id="dict-download-form" action="./php/ajax/dictionary-creation/dict-download.php" method="post"><div class="inner"><b>Download dictionary file to your computer</b><br />' +
		// mod end kitajima 20090821
						'File name : <input type="text" name="dictName" class="service-input" value="'
						 + editDictionary.getFileName() + '" onKeyPress="return downloadDictionary.submitStop(event);" />' +
						'<div id="download-dictionary-pane-alert" class="alert"></div>' +
						// mod start kitajima 20090821
//						'<p>Dictionaly file name can contain only(one-byte)English characters,numerals,undersore "_", hyphen "-" and period ".".</p>' +
						'<p>Dictionary file name can contain only(one-byte)English characters,numerals,undersore "_", hyphen "-" and period ".".</p>' +
						// mod end kitajima 20090821
						'<div style="text-align:center;margin-top:10px;">' +
						'<input value="OK" class="button-lightblue" type="button" onclick="downloadDictionary.submit(\'valueToDownload\', \'dict-download-form\');" />' +
						'<input type="hidden" value="" name="valueToDownload" id="valueToDownload"/>' +
						'<input type="hidden" value="" name="downloadDictName" id="downloadDictName"/>' +
						'<input id="create-dictionary-cancel-button" type="button" onclick="downloadDictionary.hidePane();" name="Cancel" value="Cancel" class="button-gray" /></div>';
						'</div></form></div>';

		$(this.paneID).innerHTML = content;

		$(this.paneID).show();
	},

	hidePane: function(){
		$(this.paneID).hide();
	},

	//* ちょっと不格好だが，ファイルダウンロード前に前処理を入れたいので
	submitStop: function (e){
		if (!e) var e = window.event;
		if(e.keyCode == 13){
			downloadDictionary.submit('valueToDownload', 'dict-download-form');
			return false;
		}
	},

	//* データをセーブする処理
	submit: function(targetID, formID){

		editDictionary.startLoading("Now saving dictionary...");

		//* セーブするためのデータを作成する
		editDictionary.setValueToDownload(targetID);

		//* 辞書が空だった場合、セーブされない
		if ($(targetID).value.length < 2) {
			editDictionary.finishLoading("Error: Empty dictionary cannot be downloaded.");
			this.hidePane();
			return;
		}

		var formObj = $(formID);

		if(!editDictionary.isValidFilename(formObj.dictName.value)){
			$('download-dictionary-pane-alert').innerHTML = 'invalid Dictionary file name.';
			editDictionary.finishLoading("");
			return;
		}

		//* editDictionary.setFileName(formObj.dictName.value, false);
		formObj.downloadDictName.value = formObj.dictName.value;

		//* ローカルに保存する処理

		formObj.submit();

		editDictionary.finishLoading("Dictionary was saved.");
		this.hidePane();
	}
};

globalVariableForDebug = null;


