// File: MapHelper.js
// Author: Shreesh Taskar, http://www.alongdrive.com
//  Adapted from: GooMaps.js by Bill Weaver, http://techrageo.us
//
// The map data is in a Google Earth KML file with the following extensions:
//
//    MapInit Element: Tells Google Maps piece where to center the map, and other setup values
//     Sample - <MapInit centerx="-13.24449" centery="-72.48322" zoom="12" linkicon="http://www.alongdrive.com/images/misc/iconb.png" maptype="G_SATELLITE_MAP"/>
//      
//
// Valid maptypes:
//    G_NORMAL_MAP - normal street map
//    G_SATELLITE_MAP - satellite map
//    G_HYBRID_MAP - transparent street map over satellite map
//

//
// This function will parse out a parameter from the URL. The argument is the name of the parameter.
//
function gup( name )
{
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if( results == null )
	return "";
  else
	return results[1];
}

//
// Will set the attribute of a span from a URL parameter
//
function SetSpanFromParam( spanID, spanAttr, paramName)
{
	var param = gup( paramName);
	
	if( param != "")
	{
		// Set the  element.
		document.getElementById( spanID).setAttribute( spanAttr, param);
	}
}

// Modified from Google Maps API Reference
// Added support for specifying icons and html captions
function createMarker(point, theIcon, name, info) {

	var marker = new GMarker(point, { icon: theIcon, title: name});
	GEvent.addListener(marker, "click", function() {
		marker.openInfoWindowHtml( info);
	});
	return marker;
}

//
// The maptype is specified in the XML. Use that call out to get the correct maptype.
//
function MapTypeFromMapInit( mapInit) {
	// Set default maptype to Satellite
	var maptype = G_SATELLITE_MAP;

	// If maptype attribute is present get it and set accordingly
	if( mapInit[0].getAttribute("maptype") != null ) {
		mt = mapInit[0].getAttribute("maptype").toUpperCase();
		switch( mt ){
			case "G_SATELLITE_MAP" : maptype = G_SATELLITE_MAP; break;
			case "G_HYBRID_MAP" : maptype = G_HYBRID_MAP; break;
			case "G_NORMAL_MAP" : maptype = G_NORMAL_MAP; break;
		}
	}
	
	return maptype;
}

//
// Add the navigational controls to the map
//
function InitMapControls( map) {
	map.addControl(new GLargeMapControl());	// Allows user to pan and zoom
	map.addControl(new GMapTypeControl());	// Allows user to change Map type - Normal, Satellite, etc.
	map.addControl(new GScaleControl());	// Quick way to zoom in and out
	map.addControl(new GOverviewMapControl());	// Wee map used to scroll about
	map.enableContinuousZoom();
}

//
//  Given a KML point return a google maps point
//
function PointFromPlacemarkPoint( pPoint){
	var coordinates = pPoint[0].getElementsByTagName("coordinates");
	var str = coordinates[0];
	
	var lnglat = str.childNodes[0].nodeValue.split(",");
	var lng = parseFloat(lnglat[0]);
	var lat = parseFloat(lnglat[1]);
	
	return new GLatLng( lat, lng);
}

function JavaScriptFromHref( txt) {
	var idxHref = txt.indexOf( "href");
	var idxGt = txt.indexOf( "\">", idxHref);
	var endPart = txt.slice( idxGt);
	var startPart = txt.slice( 0, idxGt);

	txt = startPart.replace("href=\"","onclick=\"parent.document.location='") +
			endPart.replace("\">", "';\" style=cursor:pointer;>");
	
	return txt;
}

function FindFolder( kmlDoc, folderName)
{
	var folders = kmlDoc[0].getElementsByTagName("Folder");

	// Iterate over list
	for (var i = 0; i < folders.length; i++) {
		var fName = folders[i].getElementsByTagName("name")[0].childNodes[0].nodeValue;
		
		if( fName == folderName)
			return folders[i];
	}

	return "Folder Name Not Found " + folderName;
}

// GooMapXml
// Reads an xml file, the name of which is specified
//  in an attribute of a span with the id mapinfo.
// Sample Call from HTML
//	<html xmlns="http://www.w3.org/1999/xhtml">
//	  <head>
//	    <title>Google Maps JavaScript API Example - simple</title>
//	    <script src="http://maps.google.com/maps?file=api&v=1&key=[**your api key**]"
//	      type="text/javascript"></script>
//	    <script src="http://techrageo.us/wp-content/GooMap.js"></script>
//	  </head>
//	<body>
//	<div id="map" style="width:300px; height:200px"></div>
//	<span id="mapinfo" name="http://techrageo.us/wp-content/goomap1.xml"></span>
//	<script type="text/javascript">GooMapXml();</script>
//	</body>
//	</html>

function MapFromXml(){

	// Find mapinfo span and get name attribute
	var mapinfo = document.getElementById('points').getAttribute('name');
	
	// Create GXmlHttp object to fetch XML document
	var request = GXmlHttp.create();
	
	// Open the connection to the XML file
	request.open("GET", mapinfo, true);
	
	// Describe a function to handle the completed request
	request.onreadystatechange = function() {
		if (request.readyState == 4) {
	    	// Get XML file contents
			var xmlDoc = GXml.parse(request.responseText);
	
			// Get the kml
			var kmlDoc = xmlDoc.documentElement.getElementsByTagName("Document");

			// Get the points folder. Do NOT use the variable name folder. There is a namespace collision somewhere.
			var folderName = document.getElementById('folder').getAttribute('name');
			var aFolder = FindFolder( kmlDoc, folderName);
			var mapInit = aFolder.getElementsByTagName("MapInit");
			var openInfo = document.getElementById('opn').getAttribute('value');

			// Get image used to create the link icon
			linkIconImage = mapInit[0].getAttribute("linkicon");
			pointIconImage = mapInit[0].getAttribute("picon");
			showLine = mapInit[0].getAttribute("showline");

			// Get map div from HTML doc
			var map = new GMap2(document.getElementById("map"));

			InitMapControls( map);
     
			// Create point for center (get x,y from attributes of markers element)
			var cpt = new GLatLng(parseFloat(mapInit[0].getAttribute("centerx")),
										parseFloat(mapInit[0].getAttribute("centery")));
		
			// Center and zoom map (zoom specified in attribute of markers element)
			map.setCenter( cpt, parseInt(mapInit[0].getAttribute("zoom")));
			map.setMapType( MapTypeFromMapInit( mapInit));
			
			// Get markers, create point collection
			var placemarks = aFolder.getElementsByTagName("Placemark");
			var linePoints = [];
			var markers = [];
			var theInfos = [];
      	
			// Iterate over list
			for (var i = 0; i < placemarks.length; i++) {
				var pName = placemarks[i].getElementsByTagName("name")[0].childNodes[0].nodeValue;
				var pPoint = placemarks[i].getElementsByTagName("Point");
				var pInfo = placemarks[i].getElementsByTagName("description")[0].childNodes[0].nodeValue;

				// There can be placemarks without points!! Account for this.
				if( pPoint.length != 0) {
	        		// Create points based on lat, lng attributes
					var point = PointFromPlacemarkPoint( pPoint);
	       		
					var marker = null;
					var theIcon = new GIcon();
					var theInfo = JavaScriptFromHref( pInfo);
					
					if( placemarks[i].getElementsByTagName("linked").length > 0) {
					    theIcon.image = linkIconImage;
					    theIcon.iconSize = new GSize(32, 32);
					    theIcon.iconAnchor = new GPoint(16, 32);
					    theIcon.infoWindowAnchor = new GPoint(16, 5);
					}
					else {
					    theIcon.image = pointIconImage;
					    theIcon.iconSize = new GSize(16, 16);
					    theIcon.iconAnchor = new GPoint(6, 6);
					    theIcon.infoWindowAnchor = new GPoint(6, 6);
						
						theInfo = "<strong>"+pName+"</strong><br>"+theInfo;
					}
					
					// Call createMarker
					marker = createMarker( point, theIcon, pName, theInfo);
	       		
					// Add marker overlay to map
					map.addOverlay( marker);
					
					// Add point to array
					linePoints[i] = point;
					markers[i] = marker;
					theInfos[i] = theInfo;
				}				
			}
			
			if( showLine == "true")
				map.addOverlay( new GPolyline( linePoints));
			
			if( openInfo != -1)
				markers[openInfo].openInfoWindowHtml( theInfos[openInfo]);
		}
	}
	// Send request to get XML file
	request.send(null);
}
