//
//
// --- global variables ---
var focusRowID=undefined;
var dsConfs =null;
var dsDl    =null;
var dsADLs  =null;
var CSGBL = {
	waitMsg: 'Loading data... Wait a moment.',
	mode: 'event',
	timerID: null
};
var uqLoc  =null;

// ----
// データをソートする関数
function sortData(mode) {
	if (0==mode) {
		dsConfs.sort('startdate');
	} else if (1==mode) {
		dsConfs.sort('title');
	} else if (2==mode) {
		dsConfs.sort('country');
	} else {
		alert('Unknown sort mode');
	}
}

// EventレコードのEventIDからSpry.DataSetのRowIDを取得する関数
function getEventRowIDbyIdOfEvent(eventID) {
	var allrows=dsConfs.getData();

	for (var i=0; i<allrows.length; ++i) {
		if ( eventID == allrows[i]["id"] ) {
			return allrows[i]["ds_RowID"];
		}
	}

	return undefined;
}

// ---
function goToDetail(eventId) {
	focusRowID=getEventRowIDbyIdOfEvent(eventId);
	if (undefined != focusRowID) {
		dsConfs.setCurrentRow(focusRowID);
	}

	LBControl.start(); // このtransition効果終了後，toggleDetail関数が実行される
}

// ---
// 詳細画面とリスト画面を切り替えるための関数
function toggleDetail() {
	var mnblk=document.getElementById('ListBlock');
	if (!mnblk) { 
		alert('Error: failed to get ListBlock block!'); return ; 
	}
	var dtblk=document.getElementById('Detail');
	if (!dtblk) { 
		alert('Error: failed to get Detail block!'); return ; 
	}

	if ('none'!=mnblk.style.display) {
		mnblk.style.display='none';
		dtblk.style.display='block';

		window.onbeforeunload=onBeforeUnload; // register a onbeforeunload callback
		showDetail(focusRowID); // 詳細画面構築用関数(この位置である必要あり!)
	} else {
		mnblk.style.display='block';
		dtblk.style.display='none';
		window.onbeforeunload=null; // unregister a onebeforeunload callback
		setMainViewHeight();
	}
}

// ---
// 詳細画面を生成する関数
function showDetail(rowID) {

	// 選択行のデータを取得する
	var row=dsConfs.getRowByID(rowID);

	var blk=document.getElementById('Detail');
	if (!blk) { alert('Error: failed to get Detail block.'); return; }

	var cont='';
	if (row) {
		cont+='<div class="vname"><a href="'+row.url+'" target="_blank">'+row.name+'</a></div>';

		{
		cont+='<div class="vbtns">';
		cont+='<input type="button" value="Back to list" onclick="LBControl.start()" />';
		cont+='</div>';
		}

		cont+='<table class="vdltable">';
		cont+='<tr>';
		cont+='<th><b>Dates:&nbsp;</b></td><td align="left">'+row.period+'</td>';
		cont+='</tr><tr>';
		cont+='<th><b>Location:&nbsp;</b></th><td align="left">'+row.city+', '+row.country+'</td>';
		cont+='</tr><tr>';
		cont+='<th><b>Web page:&nbsp;</b></th><td align="left"><a href="'+row.url+'" target="_blank">'+row.url+'</a></td>';
		cont+='</tr>';
		cont+='</table>';

		// Google Map用Div block
		cont+='<div id="vmap" ido="'+row.ido+'" kdo="'+row.kdo+'"><h3 align="center">No location data</h3></div>';

		// Deadline情報用table
		cont+='<table class="vdltable">';
		cont+='<tr>';
		cont+='<th class="tbheader"><b>Deadlines:&nbsp;</b></th><td>';
		cont+='<div id="dls">Wait a moment...</div>';
		cont+='</td>';
		cont+='</tr>';
		cont+='</table>';

		// Web更新情報用table
		cont+='<table class="vdltable">';
		cont+='<tr>';
		cont+='<th class="tbheader"><b>Update history:&nbsp;</b><br /><a href="./rss/webUpdt_'+row.id+'.rss" target="_blank">RSS</a></th><td>';
		cont+='<div id="uhy">Wait a moment...</div>';
		cont+='</td>';
		cont+='</tr>';
		cont+='</table>';

		{ // ボタン用ブロック
		cont+='<div class="vbtns">';

		cont+='<input type="button" value="Back to list" onclick="LBControl.start()" />';
		cont+='&nbsp;';
		cont+='<input type="button" value="Update" onclick="location.href=\'/~zetaka/cgi-bin/ConfShare/inputEvent.cgi?id='+row.id+'\'" />&nbsp;';

		cont+='</div>';
		}

		cont+='<p class="notice">Notice: You should check deadline dates and latest conference information by YOURSELF accessing to <a href="'+row.url+'">Conference Web site</a>, because the information in this page may become out of date or wrong information. The ConfShare do not have any responsibilities about a correctness of the information in this service.</p>';

	} else {
		cont+='<h3>Failed to get detail data (ID='+row.id+')<h3>';
	}

	// add DOM tree to the document node
	blk.innerHTML=cont;

	// current Row IDが変更されていない場合はここで各内容を描画する
	// current Row IDが変更された場合はPostLoadのcallback関数にてデータを描画する
	drawStatusOfDeadlines();
	drawUpdateHistories();

	// Google Mapの表示
	if (row.kdo && row.ido) {
		document.getElementById('vmap').style.height='280px';
		showPos('vmap', row.kdo, row.ido, 5);
	}

	return;
}

// ----
// リスト画面のリスト表示ブロックの高さを調整するための関数
function setMainViewHeight() {
	var footerHeight=24;

	// var target=document.getElementById('evtList');
	var target=document.getElementById('scrollBlock');
	if (!target) { alert('no target elem'); return; }

	var po=getElementPos(target);
	if (window.innerHeight) {
		var nh=window.innerHeight-po.y-footerHeight;
		target.style.height=nh.toString()+'px';
		target.style.overflow='auto';
	} else if (document.body.clientHeight) {
		var nh=document.body.clientHeight-po.y-footerHeight;
		target.style.height=nh;
		target.style.overflow='auto';
	} else {
		alert('Resize 1 failed!');
	}
}

//  ----
// Event ListとDeadline Listを切り替える関数
function swListContent(flag) {
	var tg1=document.getElementById('evtList');
	var tg2=document.getElementById('dlList');
	if (!tg1 || !tg2) { alert('no target for operation'); return; }

	// console.log('flag: '+flag);
	if (1==flag){
		tg2.style.display='block';
		tg1.style.display='none';
		CSGBL.mode='deadline';

	} else {
		tg1.style.display='block';
		tg2.style.display='none';
		CSGBL.mode='event';

	}

	updateFooterMsg();
}

// ---------------------------------------------------------------------
// filterのための関数． Spry.Data.filter()関数に渡される
// filter対象のデータソースはdsConfs 
function listFilterFunc() {
	// 検索文字列を取得する
	var tf=document.getElementById('searchStr');
	if ( ! tf ) { return; }

	// --- 
	// フィルタ処理の必要性確認
	if (tf.value.length < 1 && false==GmfSW) {
		// 検索文字列がなく，地図フィルタも有効になっていなければ，
		// フィルタ関数を解除する
		dsConfs.filter(null);
		dsADLs.filter(null);

	} else {
		if ('deadline'==CSGBL.mode) {
			// デッドライン情報をフィルタリングする関数を設定
			filterDeadlines();
		} else if ('event'==CSGBL.mode) {
			// イベント情報をフィルタリングする関数を設定
			filterEvents() ;
		}

	}

	updateFooterMsg();
	putMarkers();
}

// ---
// 緯度経度と文字列でイベント情報をフィルタリングする関数
function filterEvents() {
	// 検索文字列を取得する
	var tf=document.getElementById('searchStr');
	if ( ! tf ) { return; }

	var filterCBF=function (ds, row, rowNumber) {
		// 地図による検索
		if ( GmfSW ) {
			// console.log('kdo: '+row["kdo"]);
			// console.log('min: '+GBnds[0]+', max: '+GBnds[1]);

			var res = locationFilterFunc(ds, row, rowNumber);
			if (res) {
				return null;
			}

			if (0) {
			// 経度の条件確認 
			if (GBnds[0] > GBnds[1]) {
				if ((row["kdo"]>=0.0 && row["kdo"] < GBnds[0]) ||
				    (row["kdo"]<0.0  && GBnds[1] < row["kdo"])) {
					return null;
				}
			} else {
				if (row["kdo"] < GBnds[0] || GBnds[1] < row["kdo"]) {
					return null;
				}
			}

			// 緯度の条件確認
			if (row["ido"] < GBnds[2] || GBnds[3] < row["ido"]) {
				return null;
			}
			}
		}

		// 文字列検索
		if (tf.value.length > 0) {
			var re=new RegExp(tf.value, "i"); // "i"はignore caseの意味
			var str= row["name"]+' '
			        +row["city"]+' '
			        +row["country"];
			if ( -1 == str.search(re) ) { return null; }
		}

		return row;
	};

	// フィルタ処理実行
	dsConfs.filter(filterCBF);
}

// ---
// 緯度経度と文字列でデッドライン情報をフィルタリングする関数
function filterDeadlines() {
	// 検索文字列を取得する
	var tf=document.getElementById('searchStr');
	if ( ! tf ) { return; }

	if ('deadline'==CSGBL.mode) {

		var filterCBF=function (ds, row, rowNumber) {
			// 地図による検索
			if ( GmfSW ) {
				// console.log('kdo: '+row["kdo"]);
				// console.log('min: '+GBnds[0]+', max: '+GBnds[1]);
				// 経度の条件確認 
				if (GBnds[0] > GBnds[1]) {
					if ((row["kdo"]>=0.0 && row["kdo"] < GBnds[0]) ||
					    (row["kdo"]<0.0  && GBnds[1] < row["kdo"])) {
						return null;
					}
				} else {
					if (row["kdo"] < GBnds[0] || GBnds[1] < row["kdo"]) {
						return null;
					}
				}

				// 緯度の条件確認
				if (row["ido"] < GBnds[2] || GBnds[3] < row["ido"]) {
					return null;
				}
			}

			// 文字列検索
			if (tf.value.length > 0) {
				var re=new RegExp(tf.value, "i"); // "i"はignore caseの意味
				var str= row["deadline_desc"]+' '
				        +row["title"]+' '
				        +row["abbrtitle"]+' '
				        +row["city"]+' '
				        +row["country"];
				if ( -1 == str.search(re) ) { return null; }
			}

			return row;
		};

		// フィルタ処理実行
		dsADLs.filter(filterCBF);

	}
}

function setLocFilter () {
	dsConfs.addFilter(locationFilterFunc);
	dsADLs.addFilter(locationFilterFunc);
}
function unsetLocFilter () {
	dsConfs.removeFilter(locationFilterFunc);
	dsADLs.removeFilter(locationFilterFunc);
}
function doFilter () {
	dsConfs.applyFilters();
	dsADLs.applyFilters();

	putMarkers();
	updateFooterMsg();
}

function locationFilterFunc(ds, row, index) {
	// console.log("West: "+GBnds[0]+", East: "+GBnds[1]+" ido: "+row["ido"]+" kdo: "+row["kdo"]);

	// 経度の条件確認 
	// 経度の場合は2つの状況に場合分けする
	// mapの左右端の値の大小関係がが，状況によって逆転するから
	if (GBnds[0] > GBnds[1]) {
		if ( (row["kdo"]>=0.0 && row["kdo"] < GBnds[0]) ||
			(row["kdo"]<0.0  && GBnds[1] < row["kdo"]) ) {
			return null;
		}
	} else {
		if (row["kdo"] < GBnds[0] || GBnds[1] < row["kdo"]) {
			return null;
		}
	}

	// 緯度の条件確認
		if (row["ido"] < GBnds[2] || GBnds[3] < row["ido"]) {
		return null;
	}
	
	return row;
}

function stringFilterFunc(ds, row, index) {
	// 検索文字列を取得する
	var tf=document.getElementById('searchStr');
	if ( !tf ) { return null; }

	// 文字列検索
	var tgtstr= "";
	if (tf.value.length > 0) {
		var re=new RegExp(tf.value, "i"); // "i"はignore caseの意味
		if (undefined != row["deadline_desc"]) { 
			tgtstr+= row["deadline_desc"]+' '; 
		}
		if (row["title"]) { 
			tgtstr+= row["title"]+' '; 
		}
		if (undefined != row["abbrtitle"]) { 
			tgtstr+= row["abbrtitle"]+' '; 
		}
		if (undefined != row["city"]) { 
			tgtstr+= row["city"]+' ';
		}
		if (row["country"]) { 
			tgtstr+= row["country"]; 
		}

		// console.log(tgtstr);
		if ( -1 == tgtstr.search(re) ) { return null; }
	}

	return row;
}

// --- keyword searchのsearch fieldをクリアし，フィルタなしの表示の戻す関数
function resetStringFilter() {
	var tf=document.getElementById('searchStr');
	if (tf) { tf.value=""; }
	
	// 検索文字列がない => フィルタ関数を解除
	dsConfs.removeFilter(stringFilterFunc);
	dsADLs.removeFilter(stringFilterFunc);

	doFilter() ;
	// listFilterFunc();
}

// ---
// textfieldのonkeyupイベントで呼び出されるフィルタ処理開始のための処理
function fireFilterTimer() {
	if (CSGBL.timerID) {
		clearTimeout(CSGBL.timerID);
	}

	CSGBL.timerID=setTimeout(
		function(){ 
			CSGBL.timerID=null; 

			// 検索文字列を取得する
			var tf=document.getElementById('searchStr');
			if ( tf ) {
				// 文字列の有無に応じてフィルタ関数設定
				if (tf.value.length > 0) {
					// 検索文字列がある => フィルタ関数を設定
					dsConfs.addFilter(stringFilterFunc);
					dsADLs.addFilter(stringFilterFunc);
				} else {
					// 検索文字列がない => フィルタ関数を解除
					dsConfs.removeFilter(stringFilterFunc);
					dsADLs.removeFilter(stringFilterFunc);
				}
			}

			// console.log('filter by String');
			// if (tf.value) { console.log(': '+tf.value); }

			doFilter() ;
			// listFilterFunc(); 
		}, 
		250
	);
}

// ---------------------------------------------------------------------
// Observer object for dsConfs 
// dsConfs objectは，index.html内に定義されている
// この関数で，全データの位置情報に基づき，地図にマーカを設置する
function putMarkers (){
	if (!dsConfs) {
		alert('No data source.');
		return;
	}
	var rws=dsConfs.getData();

	// 一旦，すべてのマーカーを削除する 
	clearAllMarkers();

	// make unique by location (ido-kdo)
	{
		if (uqLoc) { delete uqLoc; }
		uqLoc=new Object();
		for (var i=0; i<rws.length; ++i) {
			var ikstr=rws[i]["ido"]+','+rws[i]["kdo"];
			if (! uqLoc[ikstr]) {
				uqLoc[ikstr] = new Array();
			}
			uqLoc[ikstr].push(rws[i]);
		}

		for (var x in uqLoc) {
			var loc=x.split(",");
			if (2 != loc.length) {
				alert('wrong location index: '+x);
				continue;
			}

			var hs='<div style="max-width:420px;">';
			hs+='<div id="fukidashi-loc">'+uqLoc[x][0].city+', '+uqLoc[x][0].country+'</div>';
			hs+='<table border="1" cellspacing="0" cellpadding="2">';
			for (var y=0; y<uqLoc[x].length; ++y) {
				var oref=uqLoc[x][y];
				hs+='<tr><td>';
				// hs+='<a href="'+oref.url+'" target="_blank">';
				hs+='<a href="javascript:void(0)" onclick="goToDetail('+oref.id+');">';
				if (oref.abbrtitle.length > 0) {
					hs+=oref.abbrtitle+':&nbsp;';
				}
				hs+=oref.title+'</a>';
				// hs+='</td><td>';
				// hs+='<input type="button" value="Show detail" onclick="goToDetail('+oref.id+');" />';
				hs+='</td></tr>';
			}
			hs+='</table>';
			hs+='</div>';

			putSmallMarker2(loc[0], loc[1], hs);
		}
	}

	// 全データをなめて，地図上にマーカーを置く
	// alert('putMarks: '+rws.length);
	// for (var i=0; i<rws.length; ++i) {
		// putSmallMarker(rws[i]);
	// }
}

function waitCircleOff() {
	var wc=document.getElementById('waitCircle');
	if (!wc) { 
		alert('Error: failed to get wait block.'); 
		return; 
	}
	wc.style.display='none';
}

function waitCircleOn() {
	var wc=document.getElementById('waitCircle');
	if (!wc) {
		alert('Error: failed to get wait block.'); 
		return; 
	}
	wc.style.display='block';
}

// ----
// イベント情報をload完了した時に呼び出される関数
function callbackOfPostLoad (){
	waitCircleOff();

	// ウィンドウの高さを元に表示領域の高さを調整
	setMainViewHeight();

	// Google Mapの初期化
	ovvwGmap('ConfMap', undefined, undefined, 1, true);
	// マーカーを地図に設置 
	putMarkers();

	updateFooterMsg();
}

// ----
// イベント情報をload命令が発行された時に呼び出される関数
function callbackOfPreLoad (){
	var blk=document.getElementById('ListBlock');
	blk.style.display='block';

	waitCircleOn();
}

// ----
// デッドライン情報をloadし始める前に呼び出される関数
function callbackOfPreLoadOfaDL (){
	var tg=document.getElementById('dls');
	if (!tg) { return; }
	tg.innerHTML=CSGBL.waitMsg;
}

// ----
// デッドライン情報をload完了した時に呼び出される関数
function callbackOfPostLoadOfaDL (){
	drawStatusOfDeadlines();
}

// ----
// Web更新情報をload完了した時に呼び出される関数
function callbackOfPostLoadOfUhy() {
	drawUpdateHistories();
}

// ---
// 画面下部の右隅のメッセージを設定する関数
function updateFooterMsg() {
	wc=document.getElementById('footerMsg');
	if ( !wc ) { alert('failed to find a block!'); return; }

	var cont='';
	var fc=0, ufc=0;
	if ('deadline'==CSGBL.mode) {
		fc=dsADLs.getRowCount(false);
		// console.log('filtered count: '+fc);
		if (fc > 0) {
			cont+='show '+fc+' record(s), ';
		}

		ufc=dsADLs.getRowCount(true);
		cont+='Total '+ufc+' record(s)';
	} else if ('event'==CSGBL.mode) {
		fc=dsConfs.getRowCount(false);
		// console.log('filtered count: '+fc);
		if (fc >= 0) {
			cont+='show '+fc+' record(s), ';
		}

		ufc=dsConfs.getRowCount(true);
		cont+='Total '+ufc+' record(s)';
	}

	wc.innerHTML=cont;
}

// ---
// 詳細表示画面にてデッドライン情報(群)を表示するための関数
function drawStatusOfDeadlines() {
	var tg=document.getElementById('dls');
	if (!tg) { return; }

	var cont='No deadline info.';

	if ( dsDl.getDataWasLoaded() ) {
		var rws=dsDl.getData();

		if (rws && rws.length > 0) {
			cont='';

			for (var i=0; i<rws.length; ++i) {
				cont+='<div class="dldate">';
				cont+=rws[i]["datetime"];
				cont+='&nbsp;(';

				if (rws[i]["restdays"] < 0) {
					cont+='<span class="alreadyPass">Already passed</span>';
				} else {
					cont+=rws[i]["restdays"];
					cont+=(rws[i]["restdays"]>1) ? ' days rest' : ' day rest';
				}

				cont+=')';
				cont+='</div>';
				cont+='<div class="dldesc">';
				cont+=rws[i]["desc"];
				cont+='</div>';
			}
		}
	} else if (dsUhs.getLoadDataRequestIsPending()) {
		cont=CSGBL.waitMsg;
	}

	tg.innerHTML=cont;
}

// ---
// 詳細表示画面にてWeb更新情報(群)を表示するための関数
function drawUpdateHistories() {
	var tg=document.getElementById('uhy');
	if (!tg) { return; }

	var cont='No update history info.';

	if ( dsUhs.getDataWasLoaded() ) {
		var rws=dsUhs.getData();

		if (rws && rws.length > 0) {
			cont='';

			for (var i=0; i<rws.length; ++i) {
				cont+='<div class="dldate">';
				cont+=rws[i]["datetime"];
				cont+='&nbsp;(';
				cont+=rws[i]["pastdays"];
				cont+=(rws[i]["pastdays"]>1) ? ' days ago' : ' day ago';
				cont+=')';
				cont+='</div>';
				cont+='<div style="clear:both;"></div>';

				if (i > 4) { // display 6 data at max
					cont+='<div class="dldate">...</div>';
					break; 
				} 
			}
		}
	} else if (dsUhs.getLoadDataRequestIsPending()) {
		cont=CSGBL.waitMsg;
	}

	tg.innerHTML=cont;
}

// ----
function onBeforeUnload() {
	return 'Are you really quit using a ConfShare?';
}

// ----
function overlapConf(sdt, edt) {
	// console.log(sdt+', '+edt);
}

// ----
function initializeConfShare() {
	// ウィンドウの高さを元に表示領域の高さを調整
	setMainViewHeight();

	// Google Mapの初期化
	ovvwGmap('ConfMap', undefined, undefined, 1, true);
}

// ---------------------------------------------------------------------
// ----
//引数で指定した要素の絶対位置座標オブジェクトを返す関数
function getElementPos(elem) {
	var obj=new Object();

	obj.x=elem.offsetLeft;
	obj.y=elem.offsetTop;

	while (elem.offsetParent) {
		elem=elem.offsetParent;
		obj.x+=elem.offsetLeft;
		obj.y+=elem.offsetTop;
	}

	return obj;
}

// ----
// イベントハンドラー設定用関数
function addListener(elem, eventType, func, cap) {
	if (elem.addEventListener) {
		elem.addEventListener(eventType, func, cap);
	} else if (elem.attachEvent){
		elem.attachEvent('on'+eventType, func);
	} else {
		alert('Do not support your web browser.')
		return false;
	}
}

// --- calback functions for window object 
// addListener(window, 'load', initializeConfShare, false);
// addListener(window, 'load', setMainViewHeight, false);
addListener(window, 'resize', setMainViewHeight, false);

//
// ends here
//
