/*
 * mapContainerID: string | "mapContainer" | HTML element ID that the map should be placed in
 * mapController: string | null/"none", "small", "large" | Controller for panning, zooming etc
 * typeControl: boolean | null/false, true | Add controller for changing map type (map, satellite, hybrid)
 */
var gmap = new function()
{
	
	this.infoBox = null;
	this.map = null;
	this.markers = [[],[],[],[],[],[],[],[],[],[],[]];
	this.icons = [];
	this.bounds = null;
	var scope = this;
	var geocoder = null;
	this.mgr = null;
	
	// Improved infoWindow
	this.infoBox = null;
	
	this.init = function(mapContainerID)
	{
		try{
			this.map = new google.maps.Map2(document.getElementById(mapContainerID));
	
			
			if(window.location.href.indexOf('develop.sida.client.nu') > -1){
				this.map.enableScrollWheelZoom();
			}else{
				this.map.disableScrollWheelZoom();
			}
	      	this.bounds = new GLatLngBounds();
	      	//this.map.disableDoubleClickZoom();
	      	this.geocoder = new google.maps.ClientGeocoder();
	
	      	
			// Window used to display info on map
			var imageSizes = {0: {"x": 25, "y":1006}};
			var defaultMarkerArrowOffsetX = 0;
			infoBox = new FWindow(this.map, null, imageSizes, 400, "auto", defaultMarkerArrowOffsetX, -300);
			this.setInfoBox(infoBox);
			
			jQuery(window).unload(this._unload);
		}catch(ex){	if(debug) alert(ex); }
	};
	this._unload = function(){
		GUnload(); // Cleans up memory and instances of Google Maps, prevents memmory leaks in IE
	};
	
	this.setCenter = function(lng,lat,zoomLevel){
		this.map.setCenter(new google.maps.LatLng(lng, lat), zoomLevel);
	}
	
	this.setInfoBox = function(infoBox){
		this.infoBox = infoBox;
	}
	
	this.insertMarker = function(aGLatLng, TStypes, TStypesDesc, title, draggable, centerOffset, markerArrowOffsetLeft, id, zlvl){
		try{
	      	if(TStypes == 'NOT SET') {
	      		TStypes = '0xb7b494';
	      	}
	      	
			type = TStypesDesc;
			
			try {
				debugg('TStypes: ' + TStypes);
				debugg('TStypesDesc:' + TStypesDesc);
			}
			catch(e) {
				
			}
				
			var options = new Object();
			options.draggable = draggable;
			options.title = title;
			options.icon = this.icons[type];
			if (id == 0)
				options.zIndexProcess = function(marker, b) { return 1; };
			
			var marker = new google.maps.Marker(aGLatLng, options);
			marker.id = id;
			
			GEvent.addListener(marker, "click", function() {
				// Always move 1px to side so that a pan will occur to trigger new opening of FWindow
				var point = scope.map.fromLatLngToDivPixel(scope.map.getCenter());
				point.x += 10;
				point.y += 10;
				var moveToLatLng = scope.map.fromDivPixelToLatLng(point);
				scope.map.panTo(moveToLatLng);
				// Center on the marker with the correct offset
				scope.centerOnMarker(marker, centerOffset, true);
				scope.infoBox.openOnMarker(marker, title, true, 475, 600, true, markerArrowOffsetLeft);
				
				mapmanager.selectedDataId = this.id;
				
			});
			this.bounds.extend(aGLatLng);
	
			this.markers[zlvl].push(marker);
	
			return marker;
		}catch(ex){	if(debug) alert(ex); }
	}
	
	this.updateMarkerManager = function() {
		try{
			scope.mgr = scope.mgr || new MarkerManager(scope.map);
			scope.mgr.clearMarkers();
			for(i in this.markers){
				scope.mgr.addMarkers(scope.markers[i], i);
			}
			scope.mgr.refresh();
		}catch(ex){	if(debug) alert(ex); }
	}
	
	this.centerOnMarker = function(marker, offset, pan)
	{
		try{
			this.offset = offset || GPoint(0,0);
			var latLng = marker.getLatLng();
			var point = this.map.fromLatLngToDivPixel(latLng);
			point.x -= this.offset.x;
			point.y -= this.offset.y;
			var moveToLatLng = this.map.fromDivPixelToLatLng(point);
			
			if (pan == true)
				this.map.panTo(moveToLatLng);
			else
				this.map.setCenter(moveToLatLng);
		}catch(ex){	if(debug) alert(ex); }
	}
	
	this.zoomAndPanToMarkers = function(maxZoomLevel)
	{
		try{
			if (maxZoomLevel == undefined)
				maxZoomLevel = 9;
			var zoomlevel = Math.min(this.map.getBoundsZoomLevel(this.bounds), maxZoomLevel);
		
			this.map.setCenter(this.bounds.getCenter());		
			this.map.setZoom(zoomlevel);
		}catch(ex){	if(debug) alert(ex); }
	}
	
	this.moveToMarker = function(marker, zoomLevel)
	{
		try{
			if (zoomLevel == undefined)
				zoomLevel = 10;
					
			this.map.setCenter(marker.getLatLng());		
			this.map.setZoom(zoomLevel);
		}catch(ex){	if(debug) alert(ex); }
	}
	
	this.addIcon = function(image, imageSizeX, imageSizeY, shadow, shadowSizeX, shadowSizeY, name)
	{
		try{
			var icon = new GIcon();
			
			icon.image = image;
			icon.iconSize = new GSize(imageSizeX, imageSizeY);
			icon.iconAnchor = new GPoint(imageSizeX/2, imageSizeY);
			icon.infoWindowAnchor = new GPoint(imageSizeX/2, 5);
			//icon.shadow = shadow;
			//icon.shadowSize = new GSize(shadowSizeX, shadowSizeY);
			
			this.icons[name] = icon;
		}catch(ex){	if(debug) alert(ex); }
	}
	
	this.clearMarkers = function()
	{
		try{
			this.map.clearOverlays();
			this.bounds = new GLatLngBounds();
			this.markers = [[],[],[],[],[],[],[],[],[],[],[]];
		}catch(ex){	if(debug) alert(ex); }
	}
	
	this.geoSearch = function(searchWords)
	{
		try{
			this.geocoder.getLocations(searchWords, function(result)
				{
					$("#loadingAnimation").hide();
					
					if (result.Status.code == 602)
					{
						alert("Adressen hittades inte.");
					}
					else
					{
						// Loop over all results from Google. The first one that is applicable will be the one we use, the rest are ignored.
						var foundOne = false;
						for (i in result.Placemark)
						{
							// Setup latLng from result
							var lat = result.Placemark[i].Point.coordinates[1];
							var lng = result.Placemark[i].Point.coordinates[0];
							var latLng = new GLatLng(lat, lng);
							
							// Found a company directly, ignore these
							if (result.Placemark[i].AddressDetails.Accuracy >= 9)
							{
								alert("Adressen hittades inte.");
								continue;
							}
							// Street level accuracy. (Since 2.59)
							else if (result.Placemark[i].AddressDetails.Accuracy >= 6)
							{
								scope.map.setCenter(latLng, 15);
								foundOne = true;
								break;
							}
							// Town (city, village) level accuracy. (Since 2.59)
							else if (result.Placemark[i].AddressDetails.Accuracy >= 4)
							{
								scope.map.setCenter(latLng, 11);
								foundOne = true;
								break;
							}
							else
							{
								scope.map.setCenter(latLng, 4);
								foundOne = true;
								break;
							}
						}
						
						if (foundOne == false)
						{
							alert("Adressen hittades inte.");
						}
					}
			  	}
			);
		}catch(ex){	if(debug) alert(ex); }
	}
}