/**
 * もしもしねっと（http://mosimosi.biz/）Google Map プラグイン
 * Copyright(C) 多摩ネットワークセンター Web事業部 All Rights Reserved.
 * 
 * スクロール用　http://plugins.jquery.com/project/ScrollTo
 * 
 * $('div#gmap').gmap({
 *     addresses:[{
 *         address : 'ジオコーディングする住所',
 *         info    : 'マーカーがクリックされた時に表示する内容',
 *         lat     : 緯度,
 *         lng     : 経度,
 *         zoom    : ズーム,
 *         icon    : 'アイコン'
 *     }],
 *     anchor : 'マーカーにリンクする要素',
 *     back   : 'マーカーからの戻り先要素',
 *     backid : '戻り先要素に設定する id の接頭辞',
 *     icons  : 'オリジナルアイコンの設定.xml',
 *     edit   : {
 *         street : '住所欄のフォームID',
 *         lat    : '緯度のフォームID',
 *         lng    : '経度のフォームID',
 *         zoom   : 'ズーム値のフォームID'
 *     }
 * });
 * 
 * 緯度・経度は住所（ジオコーディング）より優先されます。
 * 
 * マーカー地点は複数指定できます。
 * $('div#gmap').gmap({addresses:[{...}, {...}, {...}]);
 * 
 * アドレスデータは xml で渡すこともできます。
 * $('div#gmap').gmap({addresses:'アドレスデータ.xml');
 * 
 * 複数指定では、全ての地点が一望できるようにズーム値を自動設定します。
 * マーカークリック時は、個々に設定した zoom 値が適用されます。
 * 
 * edit にフォームIDを渡すと、マーカー位置の編集機能が有効になります。
 * 
 * 
 * 【改訂履歴】
 * 
 * 2011-09-10　InfoWindow の初期表示オプションを追加
 * 2011-06-10　IE 6,7 でエラーが出たのを修正
 * 2011-05-08  アドレス指定 xml 対応、オリジナルアイコン仮対応
 * 2011-05-02  複数マーカー全表示のロジックを変更
 * 2010-11-22  マーカー位置の編集機能を追加
 * 
 */

(function($){
	
	$.fn.gmap = function(options) {
		
		var params = $.extend({
			addresses: [{address: '多摩センター駅', info:'多摩センター駅', zoom: 16}],
			anchor: '', // a[class="marker"]
			back: '', // table
			backid: '', // back_to_element_from_gmap
			edit: {},
			icons: '',
			window: false
		}, options || {});
		
		var icons = $.extend({}, $.fn.gmap.defaultIcons);
		
		var self = $(this);
		var element = document.getElementById($(this).attr('id'))
		var map = new google.maps.Map(element, {
			mapTypeId : google.maps.MapTypeId.ROADMAP,
			zoom : 15,
			scaleControl : true,
			scrollwheel : true,
			streetview : true
			//disableDoubleClickZoom : true,
		});
		
		var marker = [];
		var current = params.window;
		var multi = (params.addresses.length > 1);
		var bounds = new google.maps.LatLngBounds();
		
		var geocoding = function(key, value) {
			var geo = new google.maps.Geocoder();
			geo.geocode({language:'ja', country:'jp', address:value.address}, function(results, status) {
				if (status == google.maps.GeocoderStatus.OK) {
					value.position = results[0].geometry.location;
					setMarker(key, value);
					setInfo(key, value);
					setBounds(value);
				} else {
					console.log('位置情報を取得できません');
				}
			});
		}
		
		var setBounds = function(value) {
			if (multi) {
				bounds.extend(new google.maps.LatLng(value.position.lat(), value.position.lng()));
				map.fitBounds(bounds);
				map.setCenter(bounds.getCenter());
			} else {
				map.setCenter(value.position);
				map.setZoom(value.zoom);
			}
		}
		
		var setIcon = function(pattern) {
			pattern = (pattern) ? pattern : 'redDot';
			return data = {
				body: {
					img: icons[pattern].body.img,
					size: new google.maps.Size(icons[pattern].body.size.x, icons[pattern].body.size.y),
					origin: new google.maps.Point(icons[pattern].body.origin.x, icons[pattern].body.origin.y),
					anchor: new google.maps.Point(icons[pattern].body.anchor.x, icons[pattern].body.anchor.y)
				},
				shadow: {
					img: icons[pattern].shadow.img,
					size: new google.maps.Size(icons[pattern].shadow.size.x, icons[pattern].shadow.size.y),
					origin: new google.maps.Point(icons[pattern].shadow.origin.x, icons[pattern].shadow.origin.y),
					anchor: new google.maps.Point(icons[pattern].shadow.anchor.x, icons[pattern].shadow.anchor.y)
				}
			};
		}
		
		var setMarker = function(key, value) {
			var data = setIcon(value.icon);
			marker[key] = new google.maps.Marker({
				position : value.position,
				icon: new google.maps.MarkerImage(data.body.img, data.body.size, data.body.origin, data.body.anchor, data.body.scale),
				shadow: new google.maps.MarkerImage(data.shadow.img, data.shadow.size, data.shadow.origin, data.shadow.anchor, data.shadow.scale),
				title : 'marker' + key,
				draggable : (params.edit) ? true : false,
				map : map,
				zoom : parseInt(value.zoom)
			});
			if (params.edit) {
				google.maps.event.addListener(marker[key], 'dragend', function() {
					var pos = marker[key].getPosition();
					map.panTo(pos);
					setValue(pos.lat(), pos.lng(), map.getZoom());
				});
				google.maps.event.addListener(map, 'zoom_changed', function() {
					var pos = marker[key].getPosition();
					setValue(pos.lat(), pos.lng(), map.getZoom());
				});
				$('#' + params.edit.street).change(function(){
					marker.forEach(function(e, i) {
						marker[i].setMap(null);
					});
					geocoding(0, {address: $('#' + params.edit.street).val(), zoom: map.getZoom()});
				});
			}
		}
		
		var setValue = function(x, y, z) {
			$('#' + params.edit.lat).val(x);
			$('#' + params.edit.lng).val(y);
			$('#' + params.edit.zoom).val(z);
		}
		
		var setInfo = function(key, value) {
			var back = (params.backid) ? '<br /><a href="javascript:void(0);" class="' + params.backid + '">戻る</a>' : '';
			var info = new google.maps.InfoWindow({
				content : value.info + back
			});
			if (current) info.open(map, marker[key]);
			google.maps.event.addListener(marker[key], 'click', function() {
				if (current) current.close();
				map.setCenter(marker[key].getPosition());
				map.setZoom(marker[key].zoom);
				info.open(map, marker[key]);
				current = info;
				if (params.backid) {
					$('.' + params.backid).click(function() {
						$.scrollTo($('#' + params.backid + key));
					});
				}
			});
		}
		
		var view = function() {
			$.each(params.addresses, function(key, value) {
				if (value.lat && value.lng) {
					value.position = new google.maps.LatLng(value.lat, value.lng);
					setMarker(key, value);
					setInfo(key, value);
					setBounds(value);
				} else {
					geocoding(key, value);
				}
			});
		}
		
		var anchor = function() {
			if(params.anchor) {
				$(params.anchor).each(function(n) {
					$(this).parents(params.back).attr('id', params.backid + n);
					$(this).attr('id', 'marker[' + n + ']').click(function() {
						var m = eval($(this).attr('id'));
						map.setCenter(m.getPosition());
						map.setZoom(m.zoom);
						google.maps.event.trigger(m, 'click');
						$.scrollTo(self);
					});
				});
			}
		}
		
		if (typeof(params.addresses) == 'string') {
			$.ajax({
				url: params.addresses,
				dataType: 'xml',
				cache: false,
				success: function(data) {
					var addresses = new Array();
					$('address', data).each(function(i){
						addresses.push({
							address: $(this).find('addr').text(),
							info: $(this).find('info').text(),
							lat: $(this).find('lat').text(),
							lng: $(this).find('lng').text(),
							zoom: $(this).find('zoom').text(),
							icon: $(this).find('icon').text()
						});
					});
					params.addresses = addresses;
					view();
					anchor();
				}
			});
		} else {
			view();
			anchor();
		}
		
		return this;
		
	}
	
	$.fn.gmap.defaultIcons = {
		'redDot': {
			body: {
				img: 'http://maps.google.co.jp/mapfiles/ms/icons/red-dot.png',
				size: {x:32, y:32},
				origin: {x:0, y:0},
				anchor: {x:16, y:32}
			},
			shadow: {
				img: 'http://maps.google.co.jp/mapfiles/ms/icons/msmarker.shadow.png',
				size: {x:59, y:32},
				origin: {x:-14, y:0},
				anchor: {x:29, y:32}
			}
		},
		'parking': {
			body: {
				img: 'http://www.google.com/mapfiles/markerP.png ',
				size: {x:32, y:32},
				origin: {x:0, y:0},
				anchor: {x:16, y:32}
			},
			shadow: {
				img: 'http://maps.google.co.jp/mapfiles/ms/icons/msmarker.shadow.png',
				size: {x:59, y:32},
				origin: {x:-14, y:0},
				anchor: {x:29, y:32}
			}
		},
		'arrow': {
			body: {
				img: 'http://www.google.com/mapfiles/gadget/arrowSmall80.png',
				size: {x:32, y:27},
				origin: {x:0, y:0},
				anchor: {x:16, y:27}
			},
			shadow: {
				img: 'http://www.google.com/mapfiles/gadget/arrowshadowSmall80.png',
				size: {x:45, y:27},
				origin: {x:-14, y:0},
				anchor: {x:29, y:27}
			}
		}
	};
	
})(jQuery);

		

