// Google Maps API Integration with Markers - 10/22/2009/RNY
// Early implementation of Google Maps
// Should be refactored into a portable class
// More portable now.  A full-featured API integration should be made.
function gMAP(mapid,dataurl) {
	var infowindow;
	var map;
	var geocoder;
	var updating = false;
	var infowindowMarkerPos;
	var statusDiv;
	var countDiv;
	var markerCount;
	// alert("tst");
	
	
	google.maps.Map.prototype.markers = new Array();
	
	google.maps.Map.prototype.addMarker = function(marker) {
	this.markers[this.markers.length] = marker;
	};
	
	google.maps.Map.prototype.getMarkers = function() {
	return this.markers
	};
	
	google.maps.Map.prototype.clearMarkers = function() {
		/*
		if(infowindow) {
		  infowindow.close();
		}
		*/
		markerCount = 0;
		for(var i=0; i<this.markers.length; i++){
		  this.markers[i].setMap(null);
		}
	};
	
	
	this.gInitialize = function () {
		geocoder = new google.maps.Geocoder();
		updating = true;
		statusDiv = document.getElementById('statusdiv');
		//countDiv = document.getElementById('countdiv');
		markerCount = 0;
		var myLatlng = new google.maps.LatLng(30,-200);
		var myOptions = {
		  zoom: 1,
		  center: myLatlng,
		  mapTypeId: google.maps.MapTypeId.ROADMAP,
		  mapTypeControl: true,
		  mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
		  navigationControl: true,
		  navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL}
		}
		map = new google.maps.Map(document.getElementById(mapid), myOptions);
		downloadUrl(dataurl, function(data) {
		  var markers = data.documentElement.getElementsByTagName("marker");
		 // if(markers.length == 0) {
		/*
				  var myLatlng = new google.maps.LatLng(30,-200);
					var myOptions = {
					  zoom: 1,
					  center: myLatlng,
					  mapTypeId: google.maps.MapTypeId.ROADMAP,
					  mapTypeControl: true,
				      mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
					  navigationControl: true,
					  navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL}
					}
					map = new google.maps.Map(document.getElementById(mapid), myOptions);
		*/
		 // }
		  for (var i = 0; i < markers.length; i++) {
				if(i == 0) { /*
					var myLatlng = new google.maps.LatLng(30,-200);
					var myOptions = {
					  zoom: 1,
					  center: myLatlng,
					  mapTypeId: google.maps.MapTypeId.ROADMAP,
					  mapTypeControl: true,
				      mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
					  //navigationControl: true,
					  //navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL}
					}
					map = new google.maps.Map(document.getElementById(mapid), myOptions);
				*/}
			var latlng = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));
			var marker = createMarker(markers[i].getAttribute("name"), latlng, markers[i].getAttribute("count"));
		   }
		   google.maps.event.addListener(map,"dragend",function(){
				if (infowindow) {
					infowindow.close(); 
				  }												
				markerCount = 0;
				map.clearMarkers();														   
		   		loadMarkers();
		   });
		   google.maps.event.addListener(map,"zoom_changed",function(){
				markerCount = 0;
				 if (infowindow) {
					infowindow.close(); 
				  }													 
				map.clearMarkers();														   
		   		loadMarkers();
		   });
		   /*google.maps.event.addListener(map,"click",function() {
				if (infowindow) {
					infowindow.close(); 
				}				
				map.setCenter(latlng);
				if(map.getZoom() == 1) {
					map.setZoom(3);
				} else {
					map.setZoom(map.getZoom() + 1);
				}
			});*/
		   updating = false;
		 });
	}
	
	
	
	function loadMarkers() {
		var bnds = map.getBounds();
		var zoom = map.getZoom();
		var url = dataurl + "?swlat=" + bnds.getSouthWest().lat() + "&swlng=" + bnds.getSouthWest().lng() + "&nelat=" + bnds.getNorthEast().lat() + "&nelng=" + bnds.getNorthEast().lng() + "&zoom=" + zoom;
		
		if(!updating) {
			map.clearMarkers();
			downloadUrl(url, function(data) {
			  var markers = data.documentElement.getElementsByTagName("marker");
			  for (var i = 0; i < markers.length; i++) {
				var latlng = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));
				var marker = createMarker(markers[i].getAttribute("name"), latlng, markers[i].getAttribute("count"));
			  }
			});
		}
	}
	
	function createMarker(name, latlng, count) {
		//map = this.map;
		// Add markers to the map
		
		// Marker sizes are expressed as a Size of X,Y
		// where the origin of the image (0,0) is located
		// in the top left of the image.
		
		// Origins, anchor positions and coordinates of the marker
		// increase in the X direction to the right and in
		// the Y direction down.
		var image = new google.maps.MarkerImage('http://www.google.com/intl/en_us/mapfiles/ms/micons/green-dot.png',
		//    var image = new google.maps.MarkerImage('images/customicon.png.php?text=' + count, 
		// This marker is 20 pixels wide by 32 pixels tall.
		new google.maps.Size(30, 32),
		// The origin for this image is 0,0.
		new google.maps.Point(0,0),
		// The anchor for this image is the base of the flagpole at 0,32.
		new google.maps.Point(0, 32));
		/*
		var shadow = new google.maps.MarkerImage('images/mapmaker_shadow.png',
		// The shadow image is larger in the horizontal dimension
		// while the position and offset are the same as for the main image.
		new google.maps.Size(37, 32),
		new google.maps.Point(0,0),
		new google.maps.Point(0, 32));
		*/
		// Shapes define the clickable region of the icon.
		// The type defines an HTML &lt;area&gt; element 'poly' which
		// traces out a polygon as a series of X,Y points. The final
		// coordinate closes the poly by connecting to the first
		// coordinate.
		var shape = {
			coord: [1, 1, 1, 32, 30, 32, 30 , 1],
			type: 'poly'
		};
		var marker = new google.maps.Marker({
			position: latlng,
			map: map,
			flat: true,
			icon: image,
			shape: shape,
			title: count
		});
		if(map.getZoom() > 10 || (count && count < 5)) {
			google.maps.event.addListener(marker, "click", function() {
			  if (infowindow) {
				infowindow.close(); 
		  	  }
		 	  updating = false;
		  	  if(map.getZoom() == 1) {
				//map.clearMarkers();
				map.setCenter(latlng);
				map.setZoom(5);
		  	  } else {
			  	updating = true;
				infowindow = new google.maps.InfoWindow({content: name});
				infowindow.open(map, marker);
		  	  }
		  	  updating = false;
			});
		} else {
			google.maps.event.addListener(marker, "click", function(event) {
					//map.clearMarkers();												
					map.setCenter(latlng);
					if(map.getZoom() == 1) {
						map.setCenter(latlng);
						map.setZoom(5);
					} else {
						var localzoom = map.getZoom();
						if(localzoom > 2) localzoom += 1;
						else if(localzoom > 7) localzoom += 1;
						else if(localzoom > 15) localzoom += 1;
						else localzoom += 2;
						map.setZoom(localzoom);
					}
			});
		} 
		map.addMarker(marker);
		markerCount++;
		//countDiv.innerHTML = '' + markerCount + ' Markers';
//alert('marker');
		return marker;
	}
	
	/**
	* Returns an XMLHttp instance to use for asynchronous
	* downloading. This method will never throw an exception, but will
	* return NULL if the browser does not support XmlHttp for any reason.
	* @return {XMLHttpRequest|Null}
	*/
	function createXmlHttpRequest() {
	 try {
	   if (typeof ActiveXObject != 'undefined') {
		 return new ActiveXObject('Microsoft.XMLHTTP');
	   } else if (window["XMLHttpRequest"]) {
		 return new XMLHttpRequest();
	   }
	 } catch (e) {
	   changeStatus(e);
	 }
	 return null;
	};
	
	/**
	* This functions wraps XMLHttpRequest open/send function.
	* It lets you specify a URL and will call the callback if
	* it gets a status code of 200.
	* @param {String} url The URL to retrieve
	* @param {Function} callback The function to call once retrieved.
	*/
	function downloadUrl(url, callback) {
	 var status = -1;
	 var request = createXmlHttpRequest();
	 if (!request) {
	   return false;
	 }
	
	 request.onreadystatechange = function() {
	   if (request.readyState == 4) {
		 try {
		   status = request.status;
		 } catch (e) {
		   // Usually indicates request timed out in FF.
		 }
		 if (status == 200) {
		   markerCount = 0;
		   callback(request.responseXML, request.status);
		   if(statusDiv) statusDiv.innerHTML = "Data Loaded";
		   if(statusDiv) statusDiv.style.visibility = "hidden";
		   if(statusDiv) statusDiv.style.textDecoration = "none";
		   //if(markerCount == 0) alert(url);
		  // countDiv.innerHTML = '' + markerCount + ' Markers';
		   request.onreadystatechange = function() {};
		 }
	   }
	 }
	 request.open('GET', url, true);
//alert(url);
	 if(statusDiv) statusDiv.innerHTML = "Data Loading...";
	 if(statusDiv) statusDiv.style.visibility = "visible";
	 if(statusDiv) statusDiv.style.textDecoration = "blink";
	 try {
	   request.send(null);
	 } catch (e) {
	   changeStatus(e);
	 }
	};
	
	/**
	 * Parses the given XML string and returns the parsed document in a
	 * DOM data structure. This function will return an empty DOM node if
	 * XML parsing is not supported in this browser.
	 * @param {string} str XML string.
	 * @return {Element|Document} DOM.
	 */
	function xmlParse(str) {
	  if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined') {
		var doc = new ActiveXObject('Microsoft.XMLDOM');
		doc.loadXML(str);
		return doc;
	  }
	
	  if (typeof DOMParser != 'undefined') {
		return (new DOMParser()).parseFromString(str, 'text/xml');
	  }
	
	  return createElement('div', null);
	}
	
	/**
	 * Appends a JavaScript file to the page.
	 * @param {string} url
	 */
	function downloadScript(url) {
	  var script = document.createElement('script');
	  script.src = url;
	  document.body.appendChild(script);
	}

	

}
