/**
 * @author mtanaka
 */

var GMapHandler = Class.create();

GMapHandler.prototype = {
	
	gmap: null, // Google mapsのハンドラ GMap2
	hashSearchResultOverlay: new Array(), // 検索結果のオーバーレイ
	arrayDestinationMarkers: new Array(), // 目的地の結果のオーバーレイ
	arrayRoutelines: new Array(), // 経路のオーバレイ
	idPrefix: 'maphandler_',

	
	/**
	 * コンストラクタ
	 * @param {Object} params
	 *  params.gmap Google mapsのハンドラ GMap2
	 *  params.lat 表示開始時の地図中心の緯度
	 *  params.lng 表示開始時の地図中心の経度
	 */
	initialize: function(params) {
		
		this.gmap = params.gmap;

		this.gmap.enableScrollWheelZoom();
		this.gmap.setCenter(new GLatLng(params.lat, params.lng), params.zoom);
		this.gmap.addControl(new GLargeMapControl());
		this.gmap.addControl(new GMapTypeControl());
		this.gmap.addControl(new google.maps.LocalSearch());

		GEvent.addListener(this.gmap, "click", this.showAddDestinationInfoWindow.bind(this));
	},
	
	/**
	 * Google mapsのハンドラ GMap2 を返す
	 */
	getMap: function() {
		return this.gmap;
	},
	
	/**
	 * 何もない地点がクリックされたときに情報ウィンドウを表示するコールバック関数
	 * @param {Object} overlay
	 * @param {Object} point
	 */
	showAddDestinationInfoWindow: function(overlay, point) {

		if (overlay) {
			// すでに存在するオーバーレイをクリックした場合
			// この条件分岐は必須
		} else {
			
			var name = "";
			var address = "";
			var desc = "";
			var lng = point.lng();
			var lat = point.lat();
			var id = 'click_' + MD5_hexhash(String(lat) + String(lng));
			
			// 「目的地に追加」とだけ表示．ユーザクリック時に緯度，経度を渡す
			strHtml = '<div class="destination_infowindow">'
				+ '<div class="infowindow_operation" onClick="manager.addDestination('
				+ 'new GeoInfo('
				+ '\'' + id + '\'' + ','
				+ 'new GLatLng(' + lat + ',' + lng + ')' + ','
				+ '\'' + name + '\'' + ','
				+ '\'' + address + '\'' + ','
				+ '\'' + desc + '\''
				+ '));"><img src="img/icon_add.gif"/>目的地に追加</div></div>';

			this.gmap.openInfoWindowHtml(point, strHtml);
		}
	},
	
	
	showSearchResultInfoWindow: function(point, strHtml) {
		this.gmap.openInfoWindowHtml(point, strHtml);
	},
	
	/**
	 * 地図上に検索結果のオーバーレイを追加
	 * @param {GeoInfo} info 場所
	 */
	addSearchResultOverlay: function(info, htmlText, iconType) {
		manager.addGeoInfo(info);
		
		var icon = new GIcon();
		icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
		icon.iconSize = new GSize(12, 20);
		icon.shadowSize = new GSize(22, 20);
		icon.iconAnchor = new GPoint(6, 20);
		icon.infoWindowAnchor = new GPoint(5, 1);

		icon.image = "http://labs.google.com/ridefinder/images/mm_20_orange.png";
		if(iconType == 'keyword') icon.image = "http://labs.google.com/ridefinder/images/mm_20_green.png";
		if(iconType == 'hotel') icon.image = "http://labs.google.com/ridefinder/images/mm_20_yellow.png";
		if(iconType == 'restaurant') icon.image = "http://labs.google.com/ridefinder/images/mm_20_blue.png";
		if(iconType == 'article') icon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";

		m = new GMarker(info.getPoint(), icon);
		m.bindInfoWindowHtml(htmlText);

		this.gmap.addOverlay(m);
		
		this.hashSearchResultOverlay[info.getId()] = m;
//		this.arraySearchResultOverlay.push(m);
		
		return m;
	},
		
	/**
	 * 指定された位置にある検索結果のオーバーレイを削除
	 * @param {GeoInfo} info
	 */
	removeSearchResultOverlay: function(info) {
		var m = this.hashSearchResultOverlay[info.getId()];
		this.gmap.removeOverlay(m);
		
//		for(var i=0; i<this.arraySearchResultOverlay.length; i++) {
//			var p = this.arraySearchResultOverlay[i].getLatLng();
//			if (p.equals(point)) {
//				this.gmap.removeOverlay(this.arraySearchResultOverlay[i]);
//				return;
//			}
//		}
	},
	
	/**
	 * 地図上の検索結果のオーバーレイを全て削除
	 */
//	removeAllSearchResultOverlay: function() {
//		
//		for(var i=0; i<this.arraySearchResultOverlay.length; i++) {
//			this.gmap.removeOverlay(this.arraySearchResultOverlay[i]);
//		}
//		this.arraySearchResultOverlay = new Array();
//	},
	
	/**
	 * 地図に目的地を追加
	 * @param {GeoInfo} info 
	 * @param {int} index マーカのインデックス 0 -> A, 1 -> B, ...
	 */
	addDestinationMarker: function(info, index) {
		
		this.gmap.closeInfoWindow();

		// Create a base icon for all of our markers that specifies the
		// shadow, icon dimensions, etc.
		var baseIcon = new GIcon();
		baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
		baseIcon.iconSize = new GSize(20, 34);
		baseIcon.shadowSize = new GSize(37, 34);
		baseIcon.iconAnchor = new GPoint(9, 34);
		baseIcon.infoWindowAnchor = new GPoint(9, 2);
		baseIcon.infoShadowAnchor = new GPoint(18, 25);

		// Create a lettered icon for this point using our icon class
		var letter = String.fromCharCode("A".charCodeAt(0) + index);
		var letteredIcon = new GIcon(baseIcon);
		letteredIcon.image = "http://www.google.com/mapfiles/marker" + letter + ".png";
		// Set up our GMarkerOptions object
		markerOptions = { icon:letteredIcon };

		var m=new GMarker(info.getPoint(), markerOptions);
		this.gmap.addOverlay(m);
		this.arrayDestinationMarkers.push(m);
		
		GEvent.addListener(m, 'click', function() {
			// 名前，出発地点に設定，到着地点に設定，付近のホテル，付近のレストラン
			var strHtml = '<div class="destination_infowindow"><div class="infowindow_name">' + info.getName() + '</div>'
					+ '<div class="infowindow_operation" onClick="manager.setStart(\'' + info.getId() + '\')"><img src="img/icon_start.gif"/>出発地点に設定</div>'
					+ '<div class="infowindow_operation" onClick="manager.setEnd(\'' + info.getId() + '\')"><img src="img/icon_end.gif"/>到着地点に設定</div>'
					+ '<div class="infowindow_operation" onClick="manager.removeDestination(\'' + info.getId() + '\')"><img src="img/icon_delete.png"/>目的地から削除</div>'
					+ '<div class="infowindow_operation" onClick="hotelManager.addHotelSearchResult(\'' + info.getId() + '\')"><img src="img/icon_hotel.png"/>付近のホテル</div>'
					+ '<div class="infowindow_operation" onClick="restaurantManager.addRestaurantSearchResult(\'' + info.getId() + '\')"><img src="img/icon_restaurant.png"/>付近のレストラン</div>'
					+ '<div class="infowindow_operation" onClick="articleManager.addArticleSearchResult(\'' + info.getId() + '\')"><img src="img/icon_article.png"/>付近に関する記事</div>'
					+ '</div>';
					
	        m.openInfoWindow(strHtml);
    	});
	},

	removeAllDestinationMarkers: function() {
		
		for(var i=0; i<this.arrayDestinationMarkers.length; i++) {
			this.gmap.removeOverlay(this.arrayDestinationMarkers[i]);
		}
		this.arrayDestinationMarkers = new Array();
	},
		
	/**
	 * 地図上にルートを表示
	 * @param {GPolyLines[]} lines
	 */
	showRoute: function(arrayRoutelines) {
		this.hideRoute();
		
		for (var i = 0; i < arrayRoutelines.length; i++) {
			this.gmap.addOverlay(arrayRoutelines[i]);
			arrayRoutelines[i].setStrokeStyle({"color":"#0000FF", "weight":5, "opacity": 0.5});
		}
			
		// 保存しておく
		this.arrayRoutelines = arrayRoutelines;
	},
	
	/**
	 * 地図上にルートを追加
	 */
	addRoute: function(routeline) {
		// 保存しておく
		this.arrayRoutelines.push(routeline);

		this.gmap.addOverlay(routeline);
		routeline.setStrokeStyle({"color":"#00FF00", "weight":5, "opacity": 0.5});
	},
	
	/**
	 * 地図上のルートを非表示
	 */
	hideRoute: function() {
		for (var i = 0; i < this.arrayRoutelines.length; i++) {
			this.gmap.removeOverlay(this.arrayRoutelines[i]);
		}
	}
	

}
