/**
 *
 */

String.prototype.htmlEscape = function() {
	var obj = document.createElement('pre');
    if (typeof obj.textContent != 'undefined') {
        obj.textContent = this;
    } else {
        obj.innerText = this;
    }
    return obj.innerHTML;

};

String.prototype.replaceAll = function(target, replacement) {
	return this.split(target).join(replacement);
};


$(window).load(function() {
});

var Sparql = function(result_func){
	this.result_func = result_func;
	this.index = 0;
	this.sessionid = "";
};

Sparql.prototype.init = function(callback){

	var me = this;

	if ($('#popup_process')[0] == undefined){
		$('#container').append(
				$('<div></div>')
				.attr({
					'id': 'popup_process',
					'width': '400px',
					'height': '200px'
				})
		);
		$('#popup_process').html('検索中です');
		$('#popup_process').hide();
	}

	if ($('#popup_error')[0] == undefined){
		$('#container').append(
				$('<div></div>')
				.attr({
					'id': 'popup_error',
					'width': '500px',
					'height': '200px'
				})
		);
		$('#popup_error').html('エンドポイント異常です');
		$('#popup_error').hide();
	}

	
	// 左ペイン初期化
	if (this.menuCondition instanceof Array){

		var propStr = '';
		for (var d in this.menuCondition){
			propStr += '<h3 id="menu_'+d+'" class="left_menu">' + this.menuCondition[d].label+'</h3>\n';
		}
		$("#left").html(propStr);

		for (var d in this.menuCondition){

			$('#menu_'+d).click(function(event){
				var id = event.target.id;
				var index = id.lastIndexOf('_');
				id = id.slice(index+1);
				var query = me.menuCondition[id].query;
				me.findMenuQuery(query);
			});
		}

	} else {
		$("#right").removeClass('rightonly');
		$("#right").addClass('rightonly');
	}

	if (this.predicates instanceof Array){
		// データを整形する
		for (var d in this.predicates){
			if (typeof this.predicates[d].subject != 'undefined'){
				this.predicates[d].pred = 'subject';
			}
		}
	}
	if (this.viewPreds != undefined){
		for (var d in this.viewPreds.data){
			if (typeof this.viewPreds.data[d].label != 'undefined'){
				if (typeof this.viewPreds.data[d].pred == 'undefined'){
					this.viewPreds.data[d].valiable = 's';
				}
			}
		}
	}


	// 初期処理
	var cmd = this.endpoint;

	var server = this.server + "/SparqlFinder/Initialize?callback=?";
	if (this.sessionid != ""){
		server = this.server + "/SparqlFinder/Initialize;jsessionid=" + this.sessionid + "?callback=?";
	}

	this.process(true);
	$.getJSON(
			server,
			cmd).then(
			function(result, status){
				result = JSON.parse(me.getResponse(result));
				me.seed = result.seed;
				
				me.prevEndpoint = me.endpoint;
				
				if (callback != undefined){
					callback(result.result);
				}
				
				me.process(false);
			},
			function(result, status, error){
				if (callback != undefined){
					callback(false);
				}
				me.process(false);
			}
		);

};

Sparql.prototype.clearCondition = function(){};

Sparql.prototype.addCondition = function(){

	var index = this.index++;

	var me = this;

	var id = "condition_"+index;
	$('#find_condition').append(
			$('<span></span>').attr({
				'id': id
			})
	);
	if (index != 0){
		$('#'+id).prepend('<br/>');
	}

	if (index != 0){
//		{
		var mix_id = "mix_list_"+index;
		$('#'+id).append(
				$('<select></select>')
				.attr({
					'id': mix_id,
					'size': 1
				})
		);
		var propStr = '<option value="and">かつ</option><option value="or">あるいは</option>';
		$("select#"+mix_id).html(propStr);

	}

	var text_id = "find_text_"+index;
	$('#'+id).append(
			$('<input>')
			.attr({
				'id': text_id,
				'type': 'text'
			})
	);
	var text_select_id = "find_select_"+index;
	$('#'+id).append(
			$('<select>')
			.attr({
				'id': text_select_id
			})
	);

	$('#'+id).append('が');
	var pred_id = "predicate_list_"+index;
	$('#'+id).append(
			$('<select></select>')
			.attr({
				'id': pred_id,
				'name': 'predicate'
			})
	);
	$('select#'+pred_id).change(function(event){
		var id = event.target.id;
		var index = id.slice(id.lastIndexOf('_')+1);

		me.updateFindWordBox(index);

	});
	this.updateCB(this.predicates, $("select#"+pred_id));

	$('#'+id).append('に');
	var select_id = "type_list_"+index;
	$('#'+id).append(
			$('<select></select>')
			.attr({
				'id': select_id,
				'size': 1
			})
	);
	var propStr = '<option value="part">含まれる</option><option value="full">一致する</option>';
	$("select#"+select_id).html(propStr);

	if (index != 0){

		var del_id = "del_"+index;
		$('#'+id).append(
				$('<input>')
				.attr({
					'id': del_id,
					'type': 'button',
					'value': 'del'
				})
		);
		$('#'+del_id).click(function(event){
			var id = event.target.id;
			var index = id.lastIndexOf('_');
			var i = id.slice(index+1);
			i = parseInt(i);

			var del_id = "condition_"+i;
			$('span#'+del_id).remove();

		});
	}

	this.updateFindWordBox(index);


};

Sparql.prototype.updateFindWordBox = function(index){
	var predicate_index = $('select#predicate_list_'+index).val();
//	var predicate_val = this.predicates[predicate_index].pred;
	var select_id = "find_select_"+index;
	var text_id = "find_text_"+index;
	var type_id = "type_list_"+index;

	for (var i=0; i<this.predicates.length; i++){
//		if (this.predicates[i].pred == predicate_val){
		if (i == predicate_index){
			if (typeof this.predicates[i].types != 'undefined'){
				var obj = $("select#"+select_id);
				var propStr = '';

				for (var d in this.predicates[i].types){
					propStr += '<option value="' +(this.predicates[i].types[d])+'">'+this.predicates[i].types[d].htmlEscape()+'</option>\n';
				}
				obj.html(propStr);
				$('select#'+select_id).show();
				$('input#'+text_id).hide();
			} else {
				//
				$('select#'+select_id).hide();
				$('input#'+text_id).show();
			}
		}
	}
};


Sparql.prototype.find = function(){

	var param = new Array();

	for (var i=0; i<this.index; i++){
		var word = $('#find_text_'+i).val();
		if ($('#find_text_'+i).is(':visible')){
			word = $('#find_text_'+i).val();
		} else if ($('#find_select_'+i).is(':visible')){
			word = $('select#find_select_'+i).val();
		}

		var and_or = $('select#mix_list_'+i).val();
		var type = $('select#type_list_'+i).val();
		var target = $('select#predicate_list_'+i).val();
		target = this.predicates[target].pred;
		if (word != '' && word != undefined && word != null){
			var p =	{"word": encodeURI(word), "predicate":encodeURI(target), "type":type, "and_or": and_or };
			param.push(p);
		}
	}


	var me = this;

	if (param.length > 0){
		if (this.prevEndpoint != this.endpoint){
			this.init(function(){
				me.find_(param);
			});
		} else {
			this.find_(param);
		}
	}

};


Sparql.prototype.find_ = function(param){

	var param;
	var limit = $('select#limit').val();

	var me = this;

	if (typeof this.sparqlConditionHead == 'undefined'){
		param = {"seed":this.seed, "target":JSON.stringify(this.viewPreds.data), "param":encodeURI(JSON.stringify(param)), "limit":limit, "offset":"0" };
	} else {
		param = {"seed":this.seed, "target":JSON.stringify(this.viewPreds.data), "head":encodeURI(this.sparqlConditionHead), "param":encodeURI(JSON.stringify(param)), "limit":limit, "offset":"0" };
	}

	this.process(true);

	$.getJSON(
			this.server + "/SparqlFinder/FindByCondition;jsessionid=" + this.sessionid + "?callback=?",
			param).then(
				function(result, status){
					//
					result = JSON.parse(me.getResponse(result));

					me.update(result);
					me.process(false);
				},
				function(result, status, error){
					me.process(false);
				}
		);

};

Sparql.prototype.findByQuery = function(query){

	var me = this;

	if (this.prevEndpoint != this.endpoint){
		this.init(function(isOK){
			if (isOK){
				me.findByQuery_(query);
			} else {
				me.awakeError();
			}
		});
	} else {
		me.findByQuery_(query);
	}
	

};

Sparql.prototype.findByQuery_ = function(query){
	var param = {"seed":this.seed, "query":encodeURI(query) };

	this.process(true);

	var me = this;
	
	$.getJSON(
			this.server + "/SparqlFinder/FindByQuery;jsessionid=" + this.sessionid + "?callback=?",
			param).then(
				function(result, status){
					//
					result = JSON.parse(me.getResponse(result));

					me.update(result, true);
					me.process(false);
				},
				function(result, status, error){
					me.process(false);
				}
		);
}


Sparql.prototype.viewCondition = function(){

	var param = new Array();

	for (var i=0; i<this.index; i++){
		var word = $('#find_text_'+i).val();
		if ($('#find_text_'+i).is(':visible')){
			word = $('#find_text_'+i).val();
		} else if ($('#find_select_'+i).is(':visible')){
			word = $('select#find_select_'+i).val();
		}
		var and_or = $('select#mix_list_'+i).val();
		var type = $('select#type_list_'+i).val();
		var target = $('select#predicate_list_'+i).val();
		target = this.predicates[target].pred;
		if (word != '' && word != undefined && word != null){
			var p =	{"word": encodeURI(word), "predicate":encodeURI(target), "type":type, "and_or": and_or };
			param.push(p);
		}
	}

	var me = this;

	if (param.length > 0){
		if (this.prevEndpoint != this.endpoint){
			this.init(function(isOK){
				if (isOK){
					me.viewCondition_(param);
				} else {
					me.awakeError();
				}
			});
		} else {
			this.viewCondition_(param);
		}

	}

};

Sparql.prototype.viewCondition_ = function(param){

	var param =	{"seed":this.seed, "param":JSON.stringify(param) };
	var me = this;

	this.process(true);
	$.getJSON(
			this.server + "/SparqlFinder/GetMenuCondition;jsessionid=" + this.sessionid + "?callback=?",
			param).then(
				function(result, status){
					//
					result = JSON.parse(me.getResponse(result));

					$('#popup_condition').html((result.query).htmlEscape());
					$('#popup').dialog({
						draggable:true
					});
					me.process(false);
				},
				function(result, status, error){
					me.process(false);
				}
		);



};

Sparql.prototype.getViewQuery = function(){

	var param = new Array();

	for (var i=0; i<this.index; i++){
		var word = $('#find_text_'+i).val();
		if ($('#find_text_'+i).is(':visible')){
			word = $('#find_text_'+i).val();
		} else if ($('#find_select_'+i).is(':visible')){
			word = $('select#find_select_'+i).val();
		}
		var and_or = $('select#mix_list_'+i).val();
		var type = $('select#type_list_'+i).val();
		var target = $('select#predicate_list_'+i).val();
		target = this.predicates[target].pred;
		if (word != '' && word != undefined && word != null){
			var p =	{"word": encodeURI(word), "predicate":encodeURI(target), "type":type, "and_or": and_or };
			param.push(p);
		}
	}

	var me = this;

	if (param.length > 0){
		if (this.prevEndpoint != this.endpoint){
			this.init(function(isOK){
				if (isOK){
					me.getViewQuery_(param);
				} else {
					me.awakeError();
				}
			});
		} else {
			this.getViewQuery_(param);
		}
	}

};

Sparql.prototype.getViewQuery_ = function(param){


	var limit = $('select#limit').val();
	var me = this;
	if (typeof this.sparqlConditionHead == 'undefined'){
		param = {"seed":this.seed, "target":JSON.stringify(this.viewPreds.data), "param":encodeURI(JSON.stringify(param)), "limit":limit, "offset":"0" };
	} else {
		param = {"seed":this.seed, "target":JSON.stringify(this.viewPreds.data), "head":encodeURI(this.sparqlConditionHead), "param":encodeURI(JSON.stringify(param)), "limit":limit, "offset":"0" };
	}

	this.process(true);

	$.getJSON(
			this.server + "/SparqlFinder/GetViewQuery;jsessionid=" + this.sessionid + "?callback=?",
			param).then(
				function(result, status){
					result = JSON.parse(me.getResponse(result));
					//
					$('#popup_query').html((result.query).htmlEscape().replaceAll('\n','<br/>'));
					$('#popup_2').dialog({
						draggable:true
					});
//					$('#query_area').val(result.query);
					me.process(false);
				},
				function(result, status, error){
					me.process(false);
				}
		);
};


Sparql.prototype.findMenuQuery = function(menuQuery){
	var me = this;

	if (this.prevEndpoint != this.endpoint){
		this.init(function(isOK){
			if (isOK){
				me.findMenuQuery_(menuQuery);
			} else {
				me.awakeError();
			}
		});
	} else {
		me.findMenuQuery_(menuQuery);
	}

};


Sparql.prototype.findMenuQuery_ = function(menuQuery){

	var param;
	var me = this;
	var limit = $('select#limit').val();

	if (typeof this.sparqlConditionHead == 'undefined'){
		param =	{"seed":this.seed, "target":JSON.stringify(this.viewPreds.data), "param":encodeURI(menuQuery), "limit":limit, "offset":"0" };
	} else {
		param =	{"seed":this.seed, "target":JSON.stringify(this.viewPreds.data), "head":encodeURI(this.sparqlConditionHead), "param":encodeURI(menuQuery), "limit":limit, "offset":"0" };
	}

	this.process(true);

	$.getJSON(
			this.server + "/SparqlFinder/FindByCondition;jsessionid=" + this.sessionid + "?callback=?",
			param).then(
				function(result, status){
					result = JSON.parse(me.getResponse(result));
					//
					me.update(result);
					me.process(false);
				},
				function(result, status, error){
					me.process(false);
				}
		);
};

Sparql.prototype.find_offset = function(type){
	var me = this;

	var param =	{"seed":this.seed, "type":type };

	$.getJSON(
			this.server + "/SparqlFinder/OffsetFind;jsessionid=" + this.sessionid + "?callback=?",
			param).then(
				function(result, status){
					result = JSON.parse(me.getResponse(result));
					//
					me.update(result);
				},
				function(result, status,error){
					//
//					me($.parseJSON(result.responseText));//TODO error
				}
		);

};


Sparql.prototype.history = function(historyType){
	var me = this;
	var param =	{"seed":this.seed, "history": historyType};

	this.process(true);

	$.getJSON(
			this.server + "/SparqlFinder/SparqlFinder;jsessionid=" + this.sessionid + "?callback=?",
			cmd).then(
				function(result, status){
					result = JSON.parse(me.getResponse(result));
					//
					me.update(result);
					me.process(false);
				},
				function(result, status, error){
					me.process(false);
				}
		);


};


Sparql.prototype.updateCB = function(data, obj){
	if (data instanceof Array){
		var propStr = '';

		for (var d in data){
//			propStr += '<option value="' +data[d].pred+'">'+data[d].label+'</option>\n';
			propStr += '<option value="' +d+'">'+data[d].label+'</option>\n';
		}
		obj.html(propStr);

	}

};


Sparql.prototype.update = function(data, addSubject){


	history = data;

	if (data.hasNext){
		$('#next_offset').show();
	} else {
		$('#next_offset').hide();
	}

	if (data.hasPrev){
		$('#prev_offset').show();
	} else {
		$('#prev_offset').hide();
	}

	if (data.results instanceof Array){

		if (this.result_func == undefined){
			this.updateTable(data.results, addSubject);
		} else {
			this.result_func(data.results);
		}
	}
};

Sparql.prototype.updateTable = function(data, addSubject){
	if (this.result_div == undefined){
		this.result_div = $('#result_div');
	}


	var table = $('#result_list')[0];

	if (table == undefined){
		table = $("#" + this.result_div[0].id + '_list')[0];

		if (table == undefined){
			this.result_div.append(
					$('<table></table>')
					.attr({
						'id': this.result_div[0].id + '_list',
						'class': 'table'
					})
			);
			table = $("#" + this.result_div[0].id + '_list')[0];
		}
	}

	while(table.rows.length > 0){
		table.deleteRow(0);	// 行を追加
	}

	if (data instanceof Array){
		this.result_div.show();
		// ヘッダ
		var header = table.createTHead();	// 行を追加
		var headerRow = header.insertRow(0);

		id = 1;
		for (var d=0; d<data.length; d++){
			var row1 = table.insertRow(d+1);	// 行を追加

			if (d == 0){
				if (!addSubject){
					var th = document.createElement('th');
					th.innerHTML = ''; // ID
					headerRow.appendChild(th);
				}
				for (var key in data[0]){
					if (!addSubject && key == 's'){
						continue;
					}
					var th = document.createElement('th');
					var label = key;
					if (this.viewPreds != undefined){
						for (var i=0; i<this.viewPreds.data.length; i++){
							if (this.viewPreds.data[i].valiable == key){
								key = this.viewPreds.data[i].label;
								break;
							}
						}
					}
					th.innerHTML = key;
					headerRow.appendChild(th);
				}
			}

			var i=0;
			// ID
			if (!addSubject){
				var cell = row1.insertCell(i++);	// １つ目のセルを追加
				var subject = data[d].s;
				var prevS = undefined;
				if (d > 0){
					prevS = data[d-1].s;
				}
				if (subject == prevS){
					subject = '<span class="same">〃</span>';
				} else {
					if (this.viewPreds != undefined && this.viewPreds.link){
						cell.innerHTML = '[<a href="' + subject + '" target="_blank">' + (id++ )+'</a>]';
					} else {
						cell.innerHTML = '[' + (id++ )+']';
					}
				}
			}
			for (var key in data[d]) {
				if (!addSubject && key == 's'){
					continue;
				}
				var cell = row1.insertCell(i++);	// ２つ目以降のセルを追加
				var value = data[d][key];
				var prev = undefined;
				if (d > 0){
					prev = data[d-1][key];
				}


				if (value == null){
					value = '';
				}

				if (value == prev){
					cell.style.textAlign = 'center';
					value = '<span class="same">〃</span>';
				}

				var link = true;
				if (this.viewPreds != undefined){
					for (var k=0; k<this.viewPreds.data.length; k++){
						if (this.viewPreds.data[k].valiable == key){
							link = this.viewPreds.data[k].link;
							break;
						}
					}
				}

				if (link){
					if (value != null && value.indexOf("http://") == 0){
						value = '<a href="'+value+'" target="_blank">'+value+'</a>';
					}
				}
				cell.innerHTML = value;
			}
		}
	}
};

Sparql.prototype.getResponse = function (response){
	this.sessionid = response.sessionid;

	return response.response;
};

Sparql.prototype.process = function (processing){
	if (processing){
		$('#popup_process').dialog({
			closeOnEscape: false,
			modal:true,
			draggable:true,
			open:function(event, ui){ $(".ui-dialog-titlebar-close").hide();}
		});
	} else {
		$('#popup_process').dialog('close');
		 $(".ui-dialog-titlebar-close").show();
	}
};

Sparql.prototype.awakeError = function (){
	$('#popup_error').dialog({
		closeOnEscape: false,
		modal:true,
		draggable:true
	});
};

