$(function(){
	var
		 mouth_title  = 'クチコミ数：'
		,coupon_title = 'クーポン：あり'
		,lococo_url   = 'http://www.lococo.jp/shops/nearest2/'
		,icon_type = {
			 1: 'icon_gourmet'
			,2: 'icon_beauty'
			,3: 'icon_life'
		}
		,balloon_icon_name = {
			 1: 'gourmet'
			,2: 'beauty'
			,3: 'life'
		}
		,max_shop_data = 40
		,z_max         = 100000
		,shops_balloon = {}
		,self = this
	;
	self.send_key = '';		// ajax送信検証キー（送信時に書き換え）
	self.pos      = null;	// 位置情報

	self.marker = new google.maps.OverlayView();
	self.balloon = new google.maps.OverlayView();

	$("#buzzmapResult-title").click(function(){
		if ($("#buzzmapResult-title").data.open ) {
			$("#buzzmapResult").css("top" , "375px");
			$("#buzzmapResult-title").data.open = false;
			$("#map").css("left", "5px");
			$("#map").css("width", "940px");
		}
		else {
			$("#buzzmapResult").css("top" , "0px");
			$("#buzzmapResult-title").data.open = true;
			$("#map").css("left", "225px");
			$("#map").css("width", "720px");
		}
	});
	$("#buzzmapResult-title").data.open = true;

	self.get_time_now = function() {
		dt = new Date();
		return Array(dt.getHours(), dt.getMinutes(), dt.getSeconds()).join('');
	}

	self.zoomLevel2range = function(zoomLevel ){
		var range = 2500;
		switch(zoomLevel ){
			case 19: range = 1; break;
			case 18: range = 1; break;
			case 17: range = 2; break;
			case 16: range = 3; break;
			case 15: range = 5; break;
			case 14: range = 8; break;
			case 13: range = 15; break;
			case 12: range = 30; break;
			case 11: range = 60; break;
			case 10: range = 120; break;
			case 9: range = 240; break;
			case 8: range = 485; break;
			case 7: range = 970; break;
			case 6: range = 1940; break;
		}
		return range;
	}

	self.range2zoomLevel = function(range ){
		var zoomLevel = 5;
		if (range<=1) zoomLevel = 18;
		else if(range<=2) zoomLevel = 17;
		else if(range<=3) zoomLevel = 16;
		else if(range<=5) zoomLevel = 15;
		else if(range<=8) zoomLevel = 14;
		else if(range<=15) zoomLevel = 13;
		else if(range<=30) zoomLevel = 12;
		else if(range<=60) zoomLevel = 11;
		else if(range<=120) zoomLevel = 10;
		else if(range<=240) zoomLevel = 9;
		else if(range<=485) zoomLevel = 8;
		else if(range<=970) zoomLevel = 7;
		else if(range<=1940) zoomLevel = 6;
		return zoomLevel;
	}

	self.range2d = function(range ){
		return range/6370*180/Math.PI;
	}

	self.getDefaultPosition = function(){
		var
			 latkey  = "top-map-lat"
			,lngkey  = "top-map-lng"
			,rngkey  = "top-map-range"
			,lat     = 35.685369469912224
			,lng     = 139.7530901196003
			,rng     = 15
			,str     = document.cookie
			,cookies = str.split(";")
			,oExp    = new RegExp(" ", "g")	// すべての半角スペースを表す正規表現
		;
		latkey = latkey.replace(oExp, "");
		lngkey = lngkey.replace(oExp, "");
		rngkey = rngkey.replace(oExp, "");
		var i = 0;
		while (cookies[i]) { // 語句ごとの処理 : マッチする要素を探す
			var tmp = cookies[i].split("=");	// さらに"="で区切る
			tmp[0] = tmp[0].replace(oExp, "");	// 半角スペース除去
			if (latkey == tmp[0]) lat = tmp[1];
			if (lngkey == tmp[0]) lng = tmp[1];
			if (rngkey == tmp[0]) rng = tmp[1];
			if (++i >= cookies.length) break;// 要素数を超えたら抜ける
		}
		return {
			 lat: lat
			,lng: lng
			,rng: rng
		};
	}
	self.pos = self.getDefaultPosition(); // プロパティに準備

	self.setDeafultPosition = function(lat, lng, rng ){
		var dt = new Date();
		dt.setDate(dt.getDate() + 3650);
		var str = "top-map-lat="+lat+"; expires=" + dt.toGMTString() + "; path=/;";
		document.cookie = str;
		var str = "top-map-lng="+lng+"; expires=" + dt.toGMTString() + "; path=/;";
		document.cookie = str;
		var str = "top-map-range="+rng+"; expires=" + dt.toGMTString() + "; path=/;";
		document.cookie = str;
	}

	self.makeValidationKey = function(lat, lng, rng, tm) {
		self.send_key = Array(lat, lng, rng, tm).join('_');
	}

	self.map = new google.maps.Map(
		 $("#map")[0]
		,{
			 zoom: self.range2zoomLevel( self.pos.rng )
			,center: new google.maps.LatLng(self.pos.lat, self.pos.lng)
			,mapTypeId: google.maps.MapTypeId.ROADMAP
		}
	);

	self.marker = function(data) {
		this.data = data;
		this.setMap(self.map);
	}
	self.marker.prototype = new google.maps.OverlayView();

	self.marker.prototype.draw = function() {
		var param =  this.data;
		if (param == undefined) {
			return;
		}

		if (param.data.c.parent_id == null) {
			return;
		}

		var
			 data = param.data.c
			,info = param
			,type = icon_type[data.parent_id]
			,icon_self = this
		;
		icon_self.obj = null;
		icon_self.obj = $("#" + type).clone();
		icon_self.obj.attr('class', 'm_' + type );
		icon_self.obj.css("display", "block");
		icon_self.obj.css("z-index", z_max--);
		icon_self.obj.attr('id', "#" + type + '_' + info.num );
		icon_self.obj.html(info.num);
		var panes = this.getPanes();
		if (icon_self.obj[0] == undefined) {
			return;
		}
		panes.overlayLayer.appendChild( icon_self.obj[0] );
		var point = this.getProjection().fromLatLngToDivPixel(new google.maps.LatLng(info.lat, info.lng));

		var self = this;
		icon_self.obj.mouseover(function(){
			for(var key in listMarker){
			    listMarker[key].infowindow.close(map, listMarker[key].marker);
			}
			$("#buzzmapBalloon")[0].parentNode.style.zIndex=110;
			for(var key in shops_balloon ){
				if(key == info.id)
					shops_balloon[key].display();
				else {
					shops_balloon[key].hidden();
				}
			}
		});

		icon_self.obj[0].style.left = (point.x-19) + 'px';
		icon_self.obj[0].style.top = (point.y-55) + 'px';
	}

// 使用されてない感じ...
//	self.marker.prototype.remove = function() {
//		if(this.obj) {
//			this.obj[0].parentNode.removeChild(this.obj[0]);
//			this.obj = null;
//		}
//	}
//
//	self.marker.prototype.display = function() {
//		if(this.obj) {
//			this.obj.css("display", "block");
//			this.obj.css("z-index", "900000");
//		}
//	}
//
//	self.marker.prototype.z_down = function() {
//		if(this.obj) {
//			this.obj.css("z-index", z_max--);
//		}
//	}



	var listMarker = {};
	var setMarker = function(lat, lng, t_json_res ){
		var latlng = new google.maps.LatLng(lat, lng);

		if(listMarker[t_json_res.id] ){
			listMarker[t_json_res.id].marker.setPosition(latlng);
			listMarker[t_json_res.id].infowindow.setContent(content);
		}else{

			listMarker[t_json_res.id] = {};
			var icon_size = new google.maps.Size(48, 48);
			var icon_position = new google.maps.Point(0, 0);
			var icon_offset = new google.maps.Point(24, 24);
			var icon_img = new google.maps.MarkerImage(
				t_json_res.profile_image_url,
				icon_size,
				icon_position,
				icon_offset
			);
			listMarker[t_json_res.id].marker = new google.maps.Marker({ 
				icon: icon_img,
				position: latlng, 
				map: map
			});
			google.maps.event.addListener(listMarker[t_json_res.id].marker, 'mouseover', function() {
				for(var key in shops_balloon ){
				    shops_balloon[key].hidden();
				}
				$("#buzzmapBalloon")[0].parentNode.style.zIndex=101;

				for(var key in listMarker){
				    if(key == t_json_res.id)listMarker[key].infowindow.open(map, listMarker[t_json_res.id].marker);
				    else listMarker[key].infowindow.close(map, listMarker[key].marker);
				}
			});
		}
	}

	var geocode = function(t_json, idx ){
		return function(results, status ){
			if(status == google.maps.GeocoderStatus.OK ){
				var lat = results[0].geometry.location.lat();
				var lng = results[0].geometry.location.lng();
				setMarker(lat, lng, t_json.results[idx]);
			}
		}
	}


//
// Balloon
//
	self.balloon = function(data) {
		this.data = data;
		this.setMap(self.map);
	}
	self.balloon.prototype = new google.maps.OverlayView();


	// balloon描画
	self.balloon.prototype.draw = function() {
		var param =  this.data;
		if (param == undefined) {
			return;
		}

		if (param.data.c.parent_id == null) {
			return;
		}

		var
			 data = param.data.c
			,info = param
			,type = balloon_icon_name[data.parent_id]
			,balloon_self = this
		;
		balloon_self.obj = null;


		var
			 c = info.data.c
			,w = info.data.w
			,l = info.data.l
			,mouth_count  = l.mouth_count ? l.mouth_count : 0
			,coupon_count = c.coupon ? c.coupon : 0
			,to_url = l.gourmet_url ? l.gourmet_url : "/shops/detail/"+w.shop_code
		;

		balloon_self.obj = $("#buzzmapBalloon").clone();
		balloon_self.obj.attr('class', 'm_ballon');
		balloon_self.obj.css("z-index", "500000");
		balloon_self.obj.find("#buzzmapBalloon-icon-value").attr("src", "/img/top/map_balloon_" + type + ".jpg");
		balloon_self.obj.find("#buzzmapBalloon-title-a").attr("href", to_url);
		balloon_self.obj.find("#buzzmapBalloon-title-a").html(w.shop_name);
		balloon_self.obj.find("#buzzmapBalloon-image-value").attr("src", w.image);
		balloon_self.obj.find("#buzzmapBalloon-far").html(w.train_line_1 + w.near_station_1 + w.access_1);
		balloon_self.obj.find("#buzzmapBalloon-buzz").html(mouth_title + mouth_count);

		if(coupon_count){
			balloon_self.obj.find("#buzzmapBalloon-coupon").html(coupon_title);
		}

		if(l.gourmet_url){
			balloon_self.obj.find("#buzzmapBalloon-title-a").attr("target", "_blank");
			balloon_self.obj.find("#buzzmapBalloon-buzz").hide();
		} else {
			balloon_self.obj.find("#buzzmapBalloon-title-a").attr("target", "_self");
			balloon_self.obj.find("#buzzmapBalloon-buzz").show();
		}

		var panes = this.getPanes();
		panes.overlayLayer.appendChild(balloon_self.obj[0]);
		balloon_self.obj.click(function(){ shops_balloon[info.id].hidden() });

		var point = this.getProjection().fromLatLngToDivPixel(new google.maps.LatLng(info.lat, info.lng ));
		balloon_self.obj[0].style.left = (point.x-19-20) + 'px';
		balloon_self.obj[0].style.top = (point.y-55-220) + 'px';
	}

	self.balloon.prototype.display = function() {
		if(this.obj) {
			this.obj.css("display", "block");
		}
	}

	self.balloon.prototype.hidden = function() {
		if(this.obj) {
			this.obj.css("display", "none");
		}
	}

	self.clear_marker = function() {
		$('div.m_icon_gourmet').remove();
		$('div.m_icon_beauty').remove();
		$('div.m_icon_life').remove();
		$('div.m_ballon').remove();
	}

	self.make_search_frame = function(shops){
		// 検索結果を初期化
		$('#buzzmapResult div.frame').html(""); // frameを一旦初期化
		var section = $('#section_format').html();

		shops_balloon = {};

		// 検索結果を構築
		for (var i=0; i<shops.length; i++) {
			var
				 w = shops[i].w	// lococo(コメント)
				,c = shops[i].c	// walker（こっちの店舗名を使う）
				,l = shops[i].l	// お店のカテゴリ
			;
			if ( w == undefined || c == undefined || l == undefined ) {
				$("#no_result").show();
				$("#buzzmapResult").hide();
				return;
			}
			var
				 m_cnt = l.mouth_count ? l.mouth_count : 0		// 口コミ
				,r_cnt = l.review_count ? l.review_count : 0	// レビュー
				,c_cnt = c.coupon ? c.coupon : 0				// クーポン
				,to_url  = l.gourmet_url ? l.gourmet_url : "/shops/detail/" + w.shop_code
				,id      = i + 1
				,id_name = '#section_' + id
				,frame   = $('#buzzmapResult div.frame').html()
			;

			$('#buzzmapResult div.frame').html( frame + section );

			// section
			var section_content = $("#__section__");
			section_content.attr('id', id_name.substr(1));

			var icon = $(id_name + ' div.icon');
			icon.attr('class', icon_type[c.parent_id]);
			icon.html(id);

			var shop_name = $(id_name + ' div.text p.title a');
			shop_name.attr('href', to_url);
			shop_name.html(w.shop_name);

			var shop_tel = $(id_name + ' div.text p.tel a');
			shop_tel.attr('href', to_url);
			shop_tel.html(w.phone_hyphen);

			// target //
			var target = l.gourmet_url ? '_blank' : '_self' ;
			shop_name.attr('target', target);
			shop_tel.attr('target', target);

			// image //
			var shop_img = $(id_name + ' div.image img');
			shop_img.attr('src', w.image);

			// 説明 //
			var shop_far = $(id_name + ' span.far');
			shop_far.html( w.train_line_1 + w.near_station_1 + w.access_1 );

			var
				 menu   = $(id_name + ' ul li.menu')
				,coupon = $(id_name + ' ul li.coupon')
				,review = $(id_name + ' ul li.review')
				,buzz   = $(id_name + ' ul li.buzz')
			;
			menu.hide();
			coupon.hide();
			review.hide();
			buzz.hide();
			if (!l.gourmet_url) {
				if (0 < c_cnt) {
					coupon.show();
					$(id_name + ' ul li.coupon a').attr('href', '/shops/coupon/' + w.shop_code);
				}

				if (0 < r_cnt) {
					review.show();
					$(id_name + ' ul li.review a').attr('href', '/shops/review/' + w.shop_code);
				}

				if (0 < m_cnt) {
					buzz.show();
					$(id_name + ' ul li.buzz a').attr('href', '/shops/mouth/' + w.shop_code);
				}
			}
			var info = {
				 lat: w.latitude
				,lng: w.longitude
				,id: w.shop_code
				,num: id
				,data: shops[i]
			}
//			shops_marker[w.shop_code] = new MyMarker(map, opt); // 上記削除するタイミングで使用する
//			shops_balloon[w.shop_code] = new MyBalloon(map, opt);
			new self.marker(info);
			shops_balloon[w.shop_code] = new self.balloon(info);
		}
	}

	var getShop = function(json){
		// CHECK <<
		var
			 shops        = null
			,response_key = ""
		;
		try {
			eval( 'var obj = ' + json );
			shops = obj['shops'];
			response_key = obj['vkey'];
		}
		catch (ex) {
			shops = {};
		}

		// マーカーの削除
		self.clear_marker();

		if (!shops.length) {
			$("#no_result").show();
			$("#buzzmapResult").hide();
			return;
		}
		else {
			if (
				typeof(shops[0].w) == undefined
			 || typeof(shops[0].c) == undefined
			 || typeof(shops[0].l) == undefined) {
				$("#no_result").show();
				$("#buzzmapResult").hide();
				return;
			}
			$("#no_result").hide();
			$("#buzzmapResult").show();
		}

		// 取得データをチェック
		if (self.send_key != response_key) {
		// 送信したキーと受け取ったキーが異なる場合は処理しない
			return;
		}

		// 表示中のピン、balloonを消す
		// self.remove_map_item();

		// 検索結果の表示
		self.make_search_frame(shops);

	}// var getShop = function(json) { ...

	self.hms = self.get_time_now();
	self.makeValidationKey( self.pos.lat, self.pos.lng, self.range2d(self.pos.rng), self.hms );
	$.get(
		 lococo_url + self.pos.lat + '/' + self.pos.lng + '/' + self.range2d(self.pos.rng) + '/' + self.hms
		,getShop
	);


	var MyMarker = function(map, opt) {
		this.opt_ = opt;
		this.setMap(map);
	}

	MyMarker.prototype = new google.maps.OverlayView();

	// ピン描画
	MyMarker.prototype.draw = function() {
		if(!this.div_) {
			var c = this.opt_.data.c;
			// アイコンid
			this.div_ = $("#" + icon_type[c.parent_id]).clone();

			this.div_.css("display", "block");
			this.div_.css("z-index", z_max--);
			
			this.div_.html(this.opt_.num);
			var panes = this.getPanes();
			panes.overlayLayer.appendChild(this.div_[0]);
			var self = this;
			this.div_.mouseover(function(){
				for(var key in listMarker){
				    listMarker[key].infowindow.close(map, listMarker[key].marker);
				}
				$("#buzzmapBalloon")[0].parentNode.style.zIndex=110;
				for(var key in shops_balloon ){
				    if(key == self.opt_.id)shops_balloon[key].display();
				    else shops_balloon[key].hidden();
				}
			});
		}

		var point = this.getProjection().fromLatLngToDivPixel(new google.maps.LatLng(this.opt_.lat, this.opt_.lng ));

		this.div_[0].style.left = (point.x-19) + 'px';
		this.div_[0].style.top = (point.y-55) + 'px';
	}

	MyMarker.prototype.remove = function() {
		if(this.div_) {
			this.div_[0].parentNode.removeChild(this.div_[0]);
			this.div_ = null;
		}
	}
	MyMarker.prototype.display = function() {
		if(this.div_) {
			this.div_.css("display", "block");
			this.div_.css("z-index", "900000");
		}
	}

	MyMarker.prototype.z_down = function() {
		if(this.div_) {
			this.div_.css("z-index", z_max--);
		}
	}



// マップ操作
	google.maps.event.addListener(self.map, 'zoom_changed', function(){
		var
			 latlng    = self.map.getCenter()
			,zoomLevel = self.map.getZoom()
			,rng       = self.zoomLevel2range(zoomLevel)
		;
		self.pos.lat = latlng.lat();
		self.pos.lng = latlng.lng();
		self.setDeafultPosition(self.pos.lat, self.pos.lng, rng);
		pos = self.getDefaultPosition();
		var hms = self.get_time_now();
		self.makeValidationKey(  pos.lat, pos.lng, self.range2d(rng), hms );
		$.get(
			 lococo_url + self.pos.lat + '/' + self.pos.lng + '/' + self.range2d(rng) + '/' + hms
			,getShop
		);
	});

// マップ操作
	google.maps.event.addListener(self.map, "dragend", function(){
		var latlng = self.map.getCenter();
		self.pos.lat = latlng.lat();
		self.pos.lng = latlng.lng();
		self.setDeafultPosition(self.pos.lat, self.pos.lng, self.pos.rng);
		pos = self.getDefaultPosition();
		var hms = self.get_time_now();
		self.makeValidationKey(self.pos.lat, self.pos.lng, self.range2d(self.pos.rng), hms );
		$.get(
			 lococo_url + self.pos.lat + '/' + self.pos.lng + '/' + self.range2d(self.pos.rng) + '/' + hms
			,getShop
		);
	});

});

