﻿//-----------
// Google Map
/// <reference path="jquery-1.2.6-intellisense.js" />
/// <reference path="GMAPJSHelper_Release.js" />

//Jquery to fix memory leak in IE
$(window).unload(function() {
    if(window.GUnload) {
        GUnload();
    }
   });

var OverlayType = { Marker: 0, Polyline: 1, Polygon: 2 };
var originalStyle = null;
var geocoder;
var infoWindowWidth = 400;
var isAdminView = false;
var emarkers = new Array();
var entryId = 0;

function EntryMarker() {
	this.index = 0;
	this.geoId = 0;
	this.marker = null;
	this.place = null;
	this.isNew = true;
}

function PostRender(map, geoEdit) {
	map.addMapType(G_PHYSICAL_MAP);
	geocoder = new GClientGeocoder();
	infoWindowWidth = GetInfoWindowWidth();
	GEvent.addListener(map, "click", mapClick);
	isAdminView = new Boolean(geoEdit);
	//http://code.google.com/apis/maps/documentation/reference.html#GEvent
	//http://code.google.com/apis/maps/documentation/services.html#ReverseGeocoding
	//context menu: http://groups.google.com/group/Google-Maps-API/msg/96dc8acf4c36d9fa
	//GEvent.addListener(map, "singlerightclick", function() { alert("right click"); }); //function(latlng,src,overlay); 
}
function ZoomToFitMap(map, zoom) {
	var bounds = new GLatLngBounds();

	for (var i = 0; i < reimers.map.GMap.Overlays.length; i++) {
		var o = reimers.map.GMap.Overlays[i];
		var oprops = GetOverlayEntryProperties(o);
		if (oprops.Type == OverlayType.Marker) {
			bounds.extend(o.getLatLng());
		}
		else {
			for (var j = 0; j < o.getVertexCount(); j++) {
				bounds.extend(o.getVertex(j));
			}
		}
	}
	
	//alert(zoom + ", " + map.getBoundsZoomLevel(bounds));

	if (typeof zoom == "undefined")
		zoom = map.getBoundsZoomLevel(bounds);
	else if (zoom > map.getBoundsZoomLevel(bounds)) {
		zoom = map.getBoundsZoomLevel(bounds);
	}
	//alert(zoom + ", " + map.getBoundsZoomLevel(bounds));

	map.setZoom(zoom);
	map.setCenter(bounds.getCenter());
}


function EnableRightClickMenu(map) {
	GEvent.addListener(map, "singlerightclick", rightClick);
}

//(overlay:GOverlay, latlng:GLatLng, overlaylatlng:GLatLng)
function mapClick(o, ll, oll) {
	var map = reimers.map.GMap;
	if (o != null && typeof o.getLatLng != "undefined") {
		MarkerClick(o, map);
	}
}

function rightClick(point, src, overlay) {
	if (typeof overlay.ID != "undefined") {
		oProps = GetOverlayEntryProperties(overlay);
		if (oProps.Type == OverlayType.Marker) {

			//            $.ajax({
			//                type: "POST",
			//                contentType: "application/json; charset=utf-8",
			//                url: "/WebServices/MapWebService.asmx/DeleteGeo",
			//                data: "{'geoId':" + oProps.GeoId + "}",
			//                dataType: "text"//,
			//                //success: function() { alert('success'); }
			//            });
			geocoder.getLocations(overlay.getLatLng(), function(response) {
				showAddress(response, overlay, oProps.GeoId);
			});
			//overlay.openInfoWindow("right click", { maxWidth: 400 });
		}
		//overlay.hide();
	}
}


function GetDrivingDirections(map, panel) {
	var wayPoints = new Array();
	
	for (var i = 0; i < reimers.map.GMap.Overlays.length; i++) {
		var o = reimers.map.GMap.Overlays[i];
		var oprops = GetOverlayEntryProperties(o);
		if (oprops.Type == OverlayType.Marker) {
		    o.hide();

		    var markerName = '';
		    if (mapArray != undefined) {
		        var n = mapArray[oprops.EntryId];
		        if (n != undefined) {
		            markerName = n + '@';
		        }
		    }
		    wayPoints.push(markerName + o.getLatLng());
		}
	}
	
	var directions = new GDirections(map, document.getElementById(panel));
	directions.loadFromWaypoints(wayPoints);
	
	GEvent.addListener(directions, "error", function(d) { directionsError(d); });
}
function directionsError(d) {
	alert("Sorry, we were unable to create directions for your trip.");
}

//http://code.google.com/apis/maps/documentation/services.html#Geocoding
function geocodeAddress(textbox) {
	var address = textbox.value;
	if (geocoder) {
		geocoder.getLocations(address, geocodeResponse);
	}
}

function geocodeResponse(r, marker) {
	var map = reimers.map.GMap;
	if (!r || r.Status.code != 200) {
		alert("Sorry, we were unable to geocode that address.");
	}
	else {
		p = r.Placemark[0];

		var em = new EntryMarker();
		em.place = p;
		em.index = emarkers.length;
		
		if(typeof marker != "undefined" && typeof marker.ID != "undefined") { //marker already exists
			var oProps = GetOverlayEntryProperties(marker);
			em.geoId = oProps.GeoId;
			em.isNew = false;
			em.marker = marker;
			marker.openInfoWindowHtml(getGeocodeInfoWindow(em), { maxWidth: infoWindowWidth });
		}
		else {
			point = new GLatLng(p.Point.coordinates[1],
                            p.Point.coordinates[0]);
			marker = new GMarker(point);
			em.marker = marker;

			GEvent.addListener(marker, "click", function() {
				marker.openInfoWindowHtml(getGeocodeInfoWindow(em), { maxWidth: infoWindowWidth });
			});
			map.addOverlay(marker);
			GEvent.trigger(marker, "click");
		}
		
		emarkers.push(em);
		//marker.openInfoWindowHtml(getGeocodeInfoWindow(em));
	}
}

function getGeocodeInfoWindow(emarker) {
	var html = 'Address: <b>' + emarker.place.address + '</b><br>' +
		"<b style='color:Red;'>" + getGoogleAccuracy(emarker.place.AddressDetails.Accuracy) + "</b>";

	if (emarker.isNew) {
		html += "<br /><a class='cursor-pointer' onclick='javascript:saveGeo(" + entryId + ", " + emarker.index + ")'>Save</a>";
	}
	else {
		html += "<br /><a class='cursor-pointer' onclick='javascript:deleteGeo(" + emarker.geoId + ")'>Delete</a>";
	}
	return html;
}

function saveGeo(entryId, i) {
	var em = emarkers[i];
	$.ajax({
		type: "POST",
		contentType: "application/json; charset=utf-8",
		url: "/WebServices/MapWebService.asmx/SaveGeo",
		data: "{'entryId':" + entryId + ", 'lat':" + em.marker.getLatLng().lat() + ", 'lng':" + em.marker.getLatLng().lng() + "}",
		dataType: "json",
		success: function(d, s) { saveGeoSuccess(d, s, i); }
	});
}
function saveGeoSuccess(data, textStatus, i) {
	// data could be xmlDoc, jsonObj, html, text, etc...
	//this; // the options for this ajax request
	var map = reimers.map.GMap;
	var em = emarkers[i];
	em.geoId = data.d;
	em.isNew = false;
	emarkers[i] = em;
	map.setCenter(em.marker.getLatLng());
	GEvent.trigger(em.marker, "click");
	//marker.openInfoWindowHtml(getGeocodeInfoWindow(em));
}

//http://code.google.com/apis/maps/documentation/reference.html#GGeoAddressAccuracy
function getGoogleAccuracy(a) {
	switch(a)
	{
		case 0:
			return 'Unknown location.';
			break;    
		case 1:			
			return 'Country level accuracy.';
			break;
		case 2:
			return 'Region (state, province, prefecture, etc.) level accuracy.';
			break;
		case 3:
			return 'Sub-region (county, municipality, etc.) level accuracy.';
			break;
		case 4:
			return 'Town (city, village) level accuracy.';
			break;
		case 5:
			return 'Post code (zip code) level accuracy.';
			break;
		case 6:
			return 'Street level accuracy.';
			break;
		case 7:
			return 'Intersection level accuracy.';
			break;
		case 8:
			return 'Address level accuracy.';
			break;
		case 9:
			return 'Premise (building name, property name, shopping center, etc.) level accuracy.';
			break;
		default:
			return 'Unknown location.';
			break;
	}
}

function deleteGeo(geoId) {
	$.ajax({
		type: "POST",
		contentType: "application/json; charset=utf-8",
		url: "/WebServices/MapWebService.asmx/DeleteGeo",
		data: "{'geoId':" + geoId + "}",
		dataType: "text",
		success: function() { hideMarker(geoId); }
	});
}

function hideMarker(geoId) {
	var marker = FindOverlay(geoId);
	marker.closeInfoWindow();
	marker.hide();
}
/*
function showAddress(response, marker, geoId) {
	//map.clearOverlays();
	if (!response || response.Status.code != 200) {
		alert("Status Code:" + response.Status.code);
	} else {
		place = response.Placemark[0];
		//point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
		//marker = new GMarker(point);
		//map.addOverlay(marker);
		marker.openInfoWindowHtml(
		//'<b>orig latlng:</b>' + response.name + '<br/>' +
		//'<b>latlng:</b>' + place.Point.coordinates[0] + "," + place.Point.coordinates[1] + '<br>' +
		//'<b>Status Code:</b>' + response.Status.code + '<br>' +
		//'<b>Status Request:</b>' + response.Status.request + '<br>' +
        '<b>Address: </b>' + place.address + '<br><br>' +
		//'<b>Accuracy:</b>' + place.AddressDetails.Accuracy + '<br>' +
		//'<b>Country code:</b> ' + place.AddressDetails.Country.CountryNameCode
        '<a href="javascript:deleteGeo(' + geoId + ');">Delete Marker</a>'
        , { maxWidth: infoWindowWidth });
	}
}
*/
function openMarkerInfoWindow(entryId) {
	var map = reimers.map.GMap;
	var markers = FindOverlays(entryId, OverlayType.Marker);
	for (var j = 0; j < markers.length; j++) {
		var o = markers[j];
		//map.panTo(o.getLatLng());
		GEvent.trigger(o, "click");
	}
}

function PolylineMouseOver(polyline, c, w, o) {
	originalStyle = { color: polyline.color, weight: polyline.weight, opacity: polyline.opacity };
	var style = { color: c, weight: w, opacity: o };
	var props = GetOverlayEntryProperties(polyline);

	var projectOverlays = FindOverlays(props.EntryId, OverlayType.Polyline);

	for (var j = 0; j < projectOverlays.length; j++) {
		var o = projectOverlays[j];
		o.setStrokeStyle(style);
	}
}
function PolylineMouseOut(polyline) {//, c, w, o) {
	var style = originalStyle; //{ color: c, weight: w, opacity: o };
	var props = GetOverlayEntryProperties(polyline);

	var projectOverlays = FindOverlays(props.EntryId, OverlayType.Polyline);

	for (var j = 0; j < projectOverlays.length; j++) {
		var o = projectOverlays[j];
		o.setStrokeStyle(style);
	}
}
function PolylineClick(map, point, html) {
	map.openInfoWindowHtml(point, html, { maxWidth: infoWindowWidth })
}
function MarkerClick(marker, map) {
	if (isAdminView == false) {
		var markerProperties = GetOverlayEntryProperties(marker);
		$.ajax({
			type: "POST",
			contentType: "application/json; charset=utf-8",
			url: "/WebServices/MapWebService.asmx/GetInfoWindowHTML",
			//data: "entryId=" + markerProperties.EntryId,
			data: "{'entryId':" + markerProperties.EntryId + ",'parserType':" + GetMapFeatureParser() + "}",
			dataType: "text",
			success: function(data) { MarkerClickCallback(marker, map, data); },
			error: function(XMLHttpRequest, textStatus, errorThrown) {
				alert("request:" + XMLHttpRequest + ", status: " + textStatus + ", error: " + errorThrown);
				for (var property in XMLHttpRequest) {
					window.alert(property + ": " + XMLHttpRequest[property]);
				}
			}
		});
	}
	else {
		if (typeof marker.ID != "undefined") {
			//oProps = GetOverlayEntryProperties(marker);
			if (geocoder) {
				geocoder.getLocations(marker.getLatLng(), function(r) { geocodeResponse(r, marker); });
			}
//			geocoder.getLocations(marker.getLatLng(), function(response) {
//				showAddress(response, marker, oProps.GeoId);
//			});
		}
		else {
			//GEvent.trigger(marker, "click");
		}
	}
}

function MarkerClickCallback(marker, map, data) {
	//alert(infoWindowWidth);
	marker.openInfoWindow(data, { maxWidth: infoWindowWidth });
}
//function MarkerDragEnd(marker, map) {
//    
//}

//function HideOverlay(id) {
//    reimers.map.getItem(id, reimers.map.GMap.Overlays).hide();
//}
//function ShowOverlay(id) {
//    reimers.map.getItem(id, reimers.map.GMap.Overlays).show();
//}
function ToggleDisplayOfOverlaysByKind(kindId, show) {
	if (typeof show == "undefined")
		show = true;

	var overlays = FindOverlaysByKind(kindId);
	for (var j = 0; j < overlays.length; j++) {
		var o = overlays[j];
		if (show) {
			o.show();
		}
		else {
			o.hide();
		}
	}
}
function FindOverlay(geoId) {
	var overlay;
	var oFound = false;
	for (var i = 0; i < reimers.map.GMap.Overlays.length; i++) {
		var o = reimers.map.GMap.Overlays[i];
		var oprops = GetOverlayEntryProperties(o);
		if (oprops.GeoId == geoId) {
			overlay = o;
			oFound = true;
		}
	}

	if (!oFound) {
		for (var i = 0; i < emarkers.length; i++) {
			var em = emarkers[i];
			if (em.geoId = geoId) {
				overlay = em.marker;
			}
		}
	}
	return overlay;
}
function FindOverlays(entryId, overlayType) {
	if (typeof overlayType == "undefined")
		overlayType = null;

	var overlays = new Array();
	for (var i = 0; i < reimers.map.GMap.Overlays.length; i++) {
		var o = reimers.map.GMap.Overlays[i];
		var oprops = GetOverlayEntryProperties(o);
		if (overlayType == null || oprops.Type == overlayType) {//OverlayType.Polyline) {
			if (oprops.EntryId == entryId) {
				overlays.push(o);
			}
		}
	}
	return overlays;
}
function FindOverlaysByKind(kindId, overlayType) {
	if (typeof overlayType == "undefined")
		overlayType = null;

	var overlays = new Array();
	for (var i = 0; i < reimers.map.GMap.Overlays.length; i++) {
		var o = reimers.map.GMap.Overlays[i];
		var oprops = GetOverlayEntryProperties(o);
		if (overlayType == null || oprops.Type == overlayType) {
			if (oprops.KindId == kindId) {
				overlays.push(o);
			}
		}
	}
	return overlays;
}

/*Helper Methods*/
function GetOverlayType(id) {
	if (id.indexOf("polyline") > -1) {
		return OverlayType.Polyline;
	}
	else if (id.indexOf("polygon") > -1) {
		return OverlayType.Polygon;
	}
	else {
		return OverlayType.Marker;
	}
}
function GetOverlayEntryProperties(o) {
	var id = o.ID;
	id = id.substr(id.lastIndexOf("GMap"));
	var props = id.split("_");
	var entryProperties = {
		Type: GetOverlayType(props[0]),
		KindId: props[1].slice(3),
		EntryId: props[2].slice(3),
		GeoId: props[3].slice(3)
	};
	return entryProperties;
}
