App = function (arg){
	this.tabs          = arg.tab_ui_elem;
	this.search_opt = arg.search_opt_elem;
	this.search_type   = undefined;
	this.search_cache  = {}; // for ajax caching
	this.search_recent = {}; // for kouho lookup
	this.kouho_list    = []; // kouho list
	this.kouho_check_hash = {}; // for re-displaying search result
	this.search_type_def  = {
		keyword : { displayMode : 'list' },
		address : { displayMode : 'map'  },
		placeE  : { displayMode : 'map'  },
		area    : { displayMode : 'list' },
		latlon  : { displayMode : 'map'  }
	};
	this.current_view_mode = undefined;
	this.do_not_pan_to_anchor = undefined;

	this.map = new App.Map({
		parent : this,
		canvas_elem : $('map'),
		layout_div : $('result-map')
	});

	this.pe = this._createPlaceEngine(); // for place engine

	if(location.search != ''){
		var qry = location.search.replace(/^\?/, '');
		var prm_arr = qry.split('&');
		params = {};
		for(var i=0;i<prm_arr.length;i++){
			var entry = prm_arr[i].split("=", 2);
			params[ entry[0] ] = decodeURIComponent( entry[1] );
		}
		this._loadSearchResult( params ); // for default search result
		this._loadSharedShops( params );  // for friend shared visitors
	}
};

App.prototype.search =
function (type, start){
	$('search-result').innerHTML =
		'<p style="height:400px"><img src="image/ajax_load_gray.gif" \/> searching...</p>';
	this.map.setLoadingImage();

	this.tabs.set( 'activeIndex', 1 );
	this.search_type = type;
	this.search_recent = {};

	var res;
	if(!start){ // if new search query
		if( this.do_not_pan_to_anchor ){
			this.do_not_pan_to_anchor = undefined;
		}else{
			window.location = '#tab-ui';
		}
		this.search_cache = {};
		this.changeSearchResultViewMode();
		this.map.searchInit();
		this._ajaxSearch( type );
		return;
	}else{
		res = this.search_cache[ start ]; // check cache
		if(!res){
			this.map.searchInit();
			this._ajaxSearch( type, start );
			return;
		}else{
			this.search_recent = res;
			this._updateSearchResult( res );
			return;
		}
	}
}

App.prototype.changeSearchResultViewMode =
function ( mode, switch_flg ){
	if( mode == undefined ){
		mode = this.currentViewMode
			|| this.getCurrentSearchTypeDef().displayMode;
	}
	if( switch_flg ){
		mode = (this.current_view_mode == 'list')? 'map' : 'list';
	}
	if( mode == 'map' ){
		$('result-list').style.display = 'none';
		this.map.changeSearchResultViewMode( 'block' );
	}else{
		$('result-list').style.display = 'block';
		this.map.changeSearchResultViewMode( 'none' );
	}

	// 初めて通常一覧からMAPへ切り替えた際の対策
	if( this.current_view_mode == 'list' && mode == 'map' &&
		this.search_recent.shop != undefined
	){
		this.current_view_mode = mode;
		// GMapを初期化する
		this.map.updateSearchResult( this.search_recent );
	}

	this.current_view_mode = mode;
}

App.prototype._ajaxSearch =
function (type, start){
	var myPostBody = Form.serialize( $('search_' + type) )
		+ '&' + Form.serialize( $('search_more') );
	if(start){
		myPostBody += '&Start=' + start;
	}
	var _instance = this;
	new Ajax.Request(
		'perl/search.cgi',
		{
			method: 'post',
			postBody: myPostBody,
			onComplete: function (req){
				var r = eval('(' + req.responseText + ')');
				if(r.error){
					$('search-result').innerHTML =
						'<p style="color:#880000;height:400px">' + r.error
						+ '</p>';
					_instance.map.displayError( r.error );
				}else{
					_instance._makeExtraInfo( r );
					_instance.search_cache[ r.pager.disp_from ] = r;
					_instance.search_recent = r;
					_instance._updateSearchResult( r );
				}
			}
		}
	);
}

App.prototype._makeExtraInfo =
function ( r ){
	for (var i=0; i<r.shop.length; i++){
		var s = r.shop[i];
		var c = {};
		c.PrivateRoom = this._makeCompactText( s.PrivateRoom, 'あり', 'なし' );
		c.NonSmoking  = this._makeCompactText( s.NonSmoking, '一部禁煙', '禁煙席なし' );
		c.Charter     = this._makeCompactText( s.Charter, '貸切可', '貸切不可' );
		c.Ktai        = this._makeCompactText( s.Ktai, 'つながる', 'つながらない', 'つながりにくい' );
		c.Course      = this._makeCompactText( s.Course, 'あり', 'なし');
		s._compact    = c;
	}
	return 1;
}

App.prototype._makeCompactText =
function (txt, valOK, valNG, valGray){
	res = '';
	if     ( valOK != undefined && txt.match(valOK) )    { res = '○' }
	else if( valNG != undefined && txt.match(valNG) )    { res = '×' }
	else if( valGray != undefined && txt.match(valGray) ){ res = '△' }
	else                                                 { res = txt  }
	return res;
}

App.prototype._updateSearchResult =
function ( r ){
	if( r.shop == undefined ){ return }
	var html = '';
	html += '<p style="margin-bottom:0"><strong style="font-size:1.2em">' + r.pager.total_items + '</strong> 件見つかりました:</p>';
	var pagerHtml = this._makePager( r.pager );
	html += pagerHtml;
	html += this._makeSearchResult( r.shop );
	html += pagerHtml;
	html += '<p style="margin-left:0;font-size:0.6em">※写真提供：ホットペッパー.jp</p>';
	$('search-result').innerHTML = html;
	this.map.updateSearchResult( r );
}

App.prototype._makePager =
function ( pager ){
	var html = '';
	html += '<p style="font-size:0.8em;text-align:right;margin-bottom:5px;margin-top:0"><strong style="font-size:1.4em">' + pager.disp_page_num + '</strong> / ' + pager.total_pages + ' ページを表示中　<a href="javascript:void(0)" onclick="myApp.changeSearchResultViewMode(undefined,1)">一覧&lt;&gt;地図</a></p>';
	html += '<p style="text-align:right">';
	if(pager.back){
		var page_num = pager.disp_page_num - 1;
		html += '<a href="javascript:void(0)" onclick="myApp.map.do_not_center=1;myApp.search(\'' + this.search_type + '\', ' + pager.back + ')">≪前へ</a> ';
	}
	if(pager.has_more_back){
		html += '... ';
	}
	for (var i=0; i < pager.range_info.length; i++){
		var r = pager.range_info[ i ];
		if( r.is_current ){
			html += '[' + r.page_num + '] ';
		}else{
			html += '<a href="javascript:void(0)" onclick="myApp.map.do_not_center=1;myApp.search(\'' + this.search_type + '\', ' + r.start + ')">' + r.page_num + '</a> ';
		}
	}
	if(pager.has_more_next){
		html += '... ';
	}
	if(pager.next){
		var page_num = pager.disp_page_num + 1;
		html += '<a href="javascript:void(0)" onclick="myApp.map.do_not_center=1;myApp.search(\'' + this.search_type + '\', ' + pager.next + ')">次へ≫</a>';
	}
	html += '</p>';
	return html;
}

App.prototype._makeSearchResult =
function ( list ){
	var html = '';
	html += '<table style="margin:20px 0px 20px -5px">';
	for (var i=0; i<list.length; i++){
		var s = list[i];
		html += '<tr><td colspan="2"><h4>[' + s.GenreName + '] ' + s.ShopCatch + '</h4></td></tr>';

		html += '<tr><td><img src="' + s.PictureUrl.MbLargeImg + '" alt=""/><p style="font-size:0.5em;color:#999;margin:0;margin-top:2px;padding:0">※写真提供：ホットペッパー.jp</p></td><td class="result_item"><p>' + s.GenreCatch + '</p><p style="font-size:1.0em"><strong>' + s.ShopName + '</strong></p><p style="margin-top:10px;font-size:1.0em">' + s.BudgetAverage + ' / ' + s.Capacity + '席</p><p style="margin-top:10px">' + s.StationName + ': ' + s.KtaiAccess + '</p><p>' + this._makeOptionText(s) + '</p><p>' + s.Open + '</p><p><a href="' + s.ShopUrl + '" target="_blank"><strong>詳細はこちら</strong></a></p><p style="text-align:right" id="add-kouho-' + i + '">';

		if(this.kouho_check_hash[ s.ShopIdFront ]){
			html += '<span style="color:#EA8C00;font-size:1em">[追加済み]</span>';
		}else{
			html += '<input type="button" onclick="myApp.addToKouhoList(\'' + i + '\')" value="候補リストに追加≫" />';
		}
		html += '</p></td></tr>';
		html += '<tr><td colspan="2" style="height:10px"></td></tr>';
	}
	html += '</table>';
	return html;
}

App.prototype._makeOptionText =
function ( shop ){
	var texts = [];
	texts.push('個室' + shop._compact.PrivateRoom);
	texts.push('禁煙席' + shop._compact.NonSmoking);
	texts.push('携帯' + shop._compact.Ktai);
	texts.push('貸切' + shop._compact.Charter);
	return texts.join('　');
}

App.prototype.addToKouhoList =
function (i){
	if(i == undefined){ return }
	var shop = this.search_recent.shop[ i ];
	this.kouho_list.push( shop );
	this.kouho_check_hash[ shop.ShopIdFront ] = 1;
	this._updateKouhoListHtml();
	this._updateCompareTableHtml();
	if($('add-kouho-' + i)){
		$('add-kouho-' + i).innerHTML = '<span style="color:#EA8C00;font-size:1em">[追加されました]</span>';
	}
	this.map.addToKouhoList_postHook( i );
}

App.prototype.deleteFromKouhoList =
function (tgt_i){
	var arr = [];
	for (var i=0; i<this.kouho_list.length; i++){
		if(tgt_i == i){
			var id = this.kouho_list[ i ].ShopIdFront;
			this.kouho_check_hash[ id ] = 0;
			continue;
		}
		arr.push( this.kouho_list[i] );
	}
	this.kouho_list = arr;
	this._updateKouhoListHtml();
	this._updateCompareTableHtml();
	this._updateSearchResult( this.search_recent );
}

App.prototype._updateKouhoListHtml =
function (){
	var html = '<table style="width:100%">';
	for (var i=0; i< this.kouho_list.length; i++){
		var s = this.kouho_list[ i ];

		html += '<tr><td rowspan="2"><img src="' + s.PictureUrl.MbSmallImg + '" alt=""/></td><td class="keep_item"><p>[' + s.GenreName + '] ' + s.GenreCatch + '</p><p><strong>' + s.ShopName + '</strong> - ' + s.StationName + '</p><p><a href="' + s.ShopUrl + '" target="_blank">詳細...</a></p></td></tr>';

		html += '<tr><td class="keep_item" valign="bottom"><p style="text-align:right"><input type="button" onclick="myApp.deleteFromKouhoList(' + i + ')" value="削除×" style="font-size:0.8em"/></p></td></tr><tr><td colspan="2" style="height:10px"></td></tr>';
	}
	html += '<tr><td colspan="2"><p style="text-align:center"><input type="button" onclick="myApp.tabs.set(\'activeIndex\',2);window.location=\'#tab-ui\'" value="　一 覧 表 で 比 較　"/></p></td></tr>'
	html += '</table>';
	$('kouho-list').innerHTML = html;
	this.map.updateKouhoListHtml( html );
}

App.prototype._updateCompareTableHtml =
function (){
	var items = [
		{ key: 'del',           type: '1', label: '&nbsp;'   },
		{ key: 'img',           type: '1', label: '&nbsp;'   },
		{ key: 'ShopName',      type: '2', label: '店名'     },
		{ key: 'GenreName',     type: '2', label: 'ジャンル' },
		{ key: 'GenreCatch',    type: '2', label: '&nbsp;'   },
		{ key: 'ShopCatch',     type: '2', label: 'キャッチ' },
		{ key: 'BudgetAverage', type: '2', label: '平均予算' },
		{ key: 'Capacity',      type: '2', label: '席数'     },
		{ key: 'PrivateRoom',   type: '2', label: '個室'     },
		{ key: 'NonSmoking',    type: '2', label: '禁煙席'   },
		{ key: 'Ktai',          type: '2', label: '携帯電話' },
		{ key: 'Charter',       type: '2', label: '貸切'     },
		{ key: 'Open',          type: '2', label: '営業時間' },
		{ key: 'Close',         type: '2', label: '定休日'   },
		{ key: 'StationName',   type: '2', label: '最寄り駅' },
		{ key: 'KtaiAccess',    type: '2', label: 'アクセス' },
		{ key: 'ShopAddress',   type: '2', label: '住所'     },
		{ key: 'link',          type: '2', label: '&nbsp;'   }
	];

	var trs = {};
	for (var i=0; i<items.length; i++){
		var arr = [];
		if( items[i].type == 1 ){
			arr.push( '<tr><td>&nbsp;</td>' );
		}else{
			arr.push(
				'<tr><td nowrap="nowrap" class="label">' + items[i].label + '</td>'
			);
		}
		trs[ items[i].key ] = arr;
	}

	var shop_id_list = [];
	for (var i=0; i< this.kouho_list.length; i++){
		var s = this.kouho_list[ i ];
		shop_id_list.push( s.ShopIdFront );
	
		trs.del.push( '<td class="data" style="text-align:right"><input type="button" value="削除×" onclick="myApp.deleteFromKouhoList(' + i + ')" style="font-size:0.8em"/></td>' );

		trs.img.push( '<td class="data" style="text-align:center"><img src="' + s.PictureUrl.MbSmallImg + '" alt="" border="0"/></td>' );

		trs.GenreName.push( '<td class="data">' + s.GenreName + '</td>' );
		trs.GenreCatch.push( '<td class="data">' + s.GenreCatch + '</td>' );
		trs.ShopCatch.push( '<td class="data">' + s.ShopCatch + '</td>' );
		trs.ShopName.push( '<td class="data"><a href="' + s.ShopUrl + '" target="_blank" class="image-link"><strong>' + s.ShopName + '</strong></a></td>' );
		trs.Close.push( '<td class="data">' + s.Close + '</td>' );
		trs.Open.push( '<td class="data">' + s.Open + '</td>' );
		trs.BudgetAverage.push( '<td class="data">' + s.BudgetAverage + '</td>' );
		trs.Capacity.push( '<td class="data">' + s.Capacity + '</td>' );
		trs.ShopAddress.push( '<td class="data">' + s.ShopAddress + '</td>' );
		trs.StationName.push( '<td class="data">' + s.StationName + '駅</td>' );
		trs.KtaiAccess.push( '<td class="data">' + s.KtaiAccess + '</td>' );

		trs.link.push( '<td class="data"><a href="' + s.ShopUrl + '" target="_blank">クーポン＆詳細</a></td>' );
		trs.PrivateRoom.push( '<td class="data">' + s._compact.PrivateRoom + '</td>' );
		trs.NonSmoking.push( '<td class="data">' + s._compact.NonSmoking + '</td>' );
		trs.Charter.push( '<td class="data">' + s._compact.Charter + '</td>' );
		trs.Ktai.push( '<td class="data">' + s._compact.Ktai + '</td>' );
	}

	var htmls = [];
	for (var i=0; i<items.length; i++){
		trs[ items[i].key ].push( '</tr>' );
		htmls.push( trs[ items[i].key ].join('') );
	}
	var qry = $H({ id : shop_id_list }).toQueryString();
	var share_url = document.location.toString();
	share_url = share_url.replace( document.location.search, '' );
	share_url = share_url.replace( share_url.match('#.*'), '' );
	$('compare-table').innerHTML = 
		'<p style="text-align:right;font-size:0.8em"><a href="javascript:void(0)" onclick="myApp.kouhoListToMap()">これらお店を地図で表示</a></p>'
		+ '<table>'
		+ htmls.join('')
		+ '</table>'
		+ '<p style="text-align:right;margin: 20px 0 20px 0;font-size:0.6em">※写真提供：ホットペッパー.jp</p>'
		+ '<h3 style="margin-top:0">この一覧表を友達に共有する</h3><p>以下のURLをメール等で伝える事で、この比較表を共有する事ができます：</p><p><input type="text" style="color:#EA8C00;font-size:0.8em;width:844px;border:0" value="' + share_url + '?' + qry + '" onfocus="this.select()"/></p>';
}

App.prototype._loadSharedShops =
function (params){
	if( params['id'] == undefined ){ return }
	$('compare-table').innerHTML =
		'<p><img src="image/ajax_load_gray.gif" \/> loading...</p>';
	this.tabs.set('activeIndex',2);

	var _instance = this;
	new Ajax.Request(
		'perl/load_shared_shops.cgi',
		{
			method: 'post',
			postBody: 'id=' + params['id'],
			onComplete: function (req){
				var r = eval('(' + req.responseText + ')');
				if(r.error){
					$('compare-table').innerHTML =
						'<p style="color:#880000">' + r.error
						+ '</p>';
				}else{
					_instance._makeExtraInfo( r );
					_instance.search_recent = r;
					for(var i=0; i<r.shop.length; i++){
						_instance.addToKouhoList( i );
					}
					_instance.search_recent = {};
				}
			}
		}
	);
}

App.prototype._loadSearchResult =
function (params){
	if( params['keyword'] == undefined ){ return }
	$('text').value = params['keyword'];
	this.search('keyword');
}

App.prototype._createPlaceEngine =
function (){
	var _instance = this;
	return new PEngine({
		onGetLocation: function (x, y, r, info){
			if (r > 0){
				$('pe-lat').value = y;
				$('pe-lon').value = x;
				$('pe-result').innerHTML = '<p style="color:#000;margin:0">' + info.msg + ': ' + info.addr + ' ' + info.floor + '</p><p style="text-align:right;margin:5px 0"><input type="submit" value="≫近所のお店を探す" /></p>';
			} else {
				$('pe-result').innerHTML = '<p style="color:#880000;margin:0">' + info.msg + ' </p>';
			}
		},
		onFindClient: function (){
			$('pe-ui').innerHTML = '<div style="margin:5px 0;float:right"><a href="http://www.placeengine.com/" target="_blank"><img src="image/pe_logo.gif" width="115" height="17" align="absmiddle" border="0"/></a></div><p style="margin:5px 0"><input alt="位置を教える" src="image/pe_tell_location.png" type="image" onclick="myApp.pe.registerLocation();return false" align="absmiddle"/> <input alt="現在地を取得" src="image/pe_get_location.png" type="image" onclick="$(\'pe-result\').innerHTML=\'<p><img src=\\\'image/ajax_load_gray.gif\\\' \/> searching</p>\';myApp.pe.getLocation();return false" align="absmiddle"/></p><div style="margin:0;clear:both" id="pe-result"></div>';
		},
		appkey:'kHEwlMwJjOFKvrvIhpYmvg7aihVA6UlvmdNQl-4bErAy.UTj8Y-NGz8aKFY8jAsLN5CKenR98A.Q5pmB.2nMi4jQkP8mDEAmA9LHbeWoHxYBvBgcXjbUwBfMjFqeAEgu9HBZqpxJ0TBw0PhtlIllnMkwxmi93OXHARIhj26Ql.6yj2.ItQL0DJSNclZo-gXiVHhkURLlFh2is-jCd5myual0P2P6p1AFEJdOAjGbvWHHYe4WaCJ.DSac7AbrkP3DJjOWDpiu6cJliaEEVW6iKoepJBmMynfAAjmj4Cs8KpntUlMPCSh2umtT6pyIoFXyOZz.7uHvmLV8eet0HooSVQ__,aHR0cDovL2hvdHBlcHBlci50YXRhbWlsYWIuanA_,44K344Oz44OX44Or6aOy6aOf5qSc57Si'
	});
}

App.prototype.getCurrentSearchTypeDef =
function (){
	return this.search_type_def[ this.search_type || 'keyword' ];
}

App.prototype.doSearchLatLon =
function (lat, lon){
	$('lat').value = lat;
	$('lon').value = lon;
	this.search('latlon');
}

App.prototype.kouhoListToMap =
function (){
	this.tabs.set( 'activeIndex', 1 );
	this.changeSearchResultViewMode('map');
	var r = {
		shop : this.kouho_list,
		pager : {
			total_items : this.kouho_list.length,
			total_pages : 1,
			disp_page_num : 1,
			range_info : [],
			back : 0,
			next : 0,
			has_more_back : 0,
			has_more_next : 0
		},
		map : {
			center : {
				Latitude  : this.kouho_list[0].Latitude,
				Longitude : this.kouho_list[0].Longitude
			}
		}
	};
	this._makeExtraInfo( r );
	this.search_recent = r;
	this._updateSearchResult( r );
	var center = this.map.zoomMap( r );
	this.map.canvas.setCenter( center );
}

App.prototype.searchOptFlipFlap =
function ( anchor ){
	var panel = this.search_opt;
	if(panel == undefined){ return }
	if( panel.cfg.getProperty('visible') == 'true'){
		panel.hide();
	}else{
		panel.cfg.setProperty('context',[anchor,'tr','br']);
		panel.show();
	}
}

