var map;
var request = GXmlHttp.create();
var geocoder = new GClientGeocoder();
var currentzipstart;
var currentzipend;
var orgcount = 0;
var gmarkers = [];
var htmls = [];
var ovcontrol;
var ovmap;

// Create initial map
function LoadMap(lat, lng, zoom, zipstart, zipend) {
  if (GBrowserIsCompatible()) {
    if (lng == undefined || lat == undefined) { lat = 39.7; lng = -94.6; }
    if (zoom == undefined) { zoom = 3; }
    if (zipstart == undefined) { zipstart = 0; }
    if (zipend == undefined) { zipend = 0; }
    map = new GMap2(document.getElementById("map"));
    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.addControl(new GOverviewMapControl(new GSize(165,165)));
    setOverviewPos();

    // Trigger for moveend event
    GEvent.addListener(map, 'moveend', function() {
      // Display current map center
      if (document.getElementById('longitude')) { document.getElementById("longitude").value = map.getCenter().x; }
      if (document.getElementById('longitudetext')) { document.getElementById("longitudetext").innerHTML = map.getCenter().x; }
      if (document.getElementById('latitude')) { document.getElementById("latitude").value = map.getCenter().y; }
      if (document.getElementById('latitudetext')) { document.getElementById("latitudetext").innerHTML = map.getCenter().y; }
	  // Display current zoom level
      if (document.getElementById('zoomtext')) { document.getElementById("zoomtext").innerHTML = map.getZoom(); }
    }) // GEvent.addListener

    zoomto(lat,lng,zoom,zipstart,zipend);
  }
}

function posOverview() {
  var ovmap = document.getElementById("map_overview");
  if(ovmap) {
	ovmap.style.position = "absolute";
	
	// == restyling ==
	//ovmap.firstChild.style.border = "1px solid gray";
	ovmap.firstChild.firstChild.style.left="4px";
	ovmap.firstChild.firstChild.style.top="4px";
	
	var mapdiv = document.getElementById("map");
	mapdiv.appendChild(ovmap);
  }
}

function setOverviewPos() {
 setTimeout("posOverview()", 500);
}

// Load set of markers
function LoadMarkers(zipstart,zipend) {
  map.clearOverlays();

  var xmlDoc;
  var schools;
  var point;
  var type;
  var schoolname;
  var orgs;
  var orgid;
  var orgacronym;
  var lastcontacted;
  var affiliation;
  var email;
  var website;
  var marker;

  request.open("GET", "markers.php?zipstart="+zipstart+"&zipend="+zipend, true);
  // Download the data in xml and load it on the map.
  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      xmlDoc = request.responseXML;
      schools = xmlDoc.documentElement.getElementsByTagName("school");
      orgcount = 0;

      for (var i = 0; i < schools.length; i++) {
        point = new GLatLng(parseFloat(schools[i].getAttribute("latitude")),
                            parseFloat(schools[i].getAttribute("longitude")));
        type = schools[i].getAttribute("type");
        schoolname = getElementTextNS("", "name", schools[i], 0);
        orgs = schools[i].getElementsByTagName("organization");

        html = "<div class=\"marker\">";
        for (var j = 0; j < orgs.length; j++) {
          orgid = getElementTextNS("", "orgid", orgs[j], 0);
          orgacronym = getElementTextNS("", "acronym", orgs[j], 0);
          lastcontacted = getElementTextNS("", "lastcontacted", orgs[j], 0);
          affiliation = getElementTextNS("", "affiliation", orgs[j], 0);
          email = getElementTextNS("", "email", orgs[j], 0);
          website = getElementTextNS("", "website", orgs[j], 0);

          if (j == 0) { html += "<div>"; }
          else { html += "<div style=\"margin-top:1em;\">"; }
          html += "<h3>" + schoolname + " " + orgacronym + "</h3>";
          if (email.length) { html += "<a href=\"mailto:" + email + "\">Email</a>"; }
          if (website.length) {
            if (email.length) { html += " &bull; "; }
            html += "<a href=\"" + website + "\" target=\"_blank\">Website</a>";
          }
          if (email.length || website.length) { html += "<br />"; }
          if (affiliation.length) { html += "Affiliation: " + affiliation + "<br />"; }
          html += "Last Contacted: " + lastcontacted;
          html += "</div>";
          orgcount++;
        }
        html += "</div>";

        marker = createMarker(point, type, html);
        map.addOverlay(marker);
      }
      if (document.getElementById('orgcount')) { document.getElementById('orgcount').innerHTML = orgcount; }
    }
  }
  request.send(null);
}


// Creates a marker whose info window displays the given number
function createMarker(point, type, html) {
  var icon = new GIcon();

  switch(type) {
  case "postsecondary":
    icon.image = 'images/mm_20_red.png';
    break;
  case "secondary":
    icon.image = 'images/mm_20_yellow.png';
	break;
  default:
    icon.image = 'images/mm_20_gray.png';
	break;
  }

  icon.shadow = '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);

  var marker = new GMarker(point, icon);
  
  // Show this marker's index in the info window when it is clicked
  if (html != null) {
    GEvent.addListener(marker, "click", function() {marker.openInfoWindowHtml(html);marker.icon});
  }

  return marker;
}

// This function picks up the click and opens the corresponding info window
function zoomById(i) {
  map.setCenter(gmarkers[i], 14);
}

// Zoom to a point on the map with zip code filters
function zoomto(i,j,k,newzipstart,newzipend) {
  var startTime = new Date();

  map.setCenter(new GLatLng(i, j), k);
  if (newzipstart != currentzipstart || newzipend != currentzipend) {
    LoadMarkers(newzipstart,newzipend);
    currentzipstart = newzipstart;
    currentzipend = newzipend;
  }

  var endTime = new Date();
  if (document.getElementById('loadtime')) document.getElementById('loadtime').innerHTML = endTime-startTime;
}


// FORM-BASED FUNCTIONS


function AggregateAddress() {
    var addressItem = ''; 

    if (document.addupdate.address.value != '') {
       addressItem = document.addupdate.address.value;
    }
    if (document.addupdate.city.value != '') {
       addressItem = (addressItem=='') ? document.addupdate.city.value : addressItem + ", " + document.addupdate.city.value;
    }
    if (document.addupdate.state.value != '') {
       addressItem = (addressItem=='') ? document.addupdate.state.value : addressItem + ", " + document.addupdate.state.value;
    }
    if (document.addupdate.zipcode.value != '') {
       addressItem = (addressItem=='') ? document.addupdate.zipcode.value : addressItem + ", " + document.addupdate.zipcode.value;
    }

    return addressItem;
}


function GeoCode(address) {
	var response;

	if (trim(address)=='') {
    alert ("Please, specify address for geocoding.")
    return;
  }

  document.addupdate.schoolname.setAttribute("readonly","readonly");
  document.addupdate.address.setAttribute("readonly","readonly");
  document.addupdate.city.setAttribute("readonly","readonly");
  document.addupdate.zipcode.setAttribute("readonly","readonly");

	geocoder.getLocations(address, addAddressToMap);

	document.addupdate.schoolname.removeAttribute("readonly","readonly");
	document.addupdate.address.removeAttribute("readonly","readonly");
	document.addupdate.city.removeAttribute("readonly","readonly");
	document.addupdate.zipcode.removeAttribute("readonly","readonly");
	document.addupdate.submit.removeAttribute("disabled","disabled");
	
}


// addAddressToMap() is called when the geocoder returns an
// answer.  It adds a marker to the map with an open info window
// showing the nicely formatted version of the address and the country code.
function addAddressToMap(response) {
	map.clearOverlays();
	if (!response || response.Status.code != 200) {
		alert("Sorry, we were unable to geocode that address");
	} else {
		place = response.Placemark[0];
		point = new GLatLng(place.Point.coordinates[1],
												place.Point.coordinates[0]);
		var accuracy = place.AddressDetails.Accuracy;
		var type;
		var zoom = 12;

		if (accuracy > 4) {
				zoom = 14;
		}
		html = "<div class=\"marker\"><h3>" + document.addupdate.schoolname.value + "</h3>" + place.address + "</div>";
		marker = new GMarker(point);
    marker = createMarker(point, type, html);
		map.addOverlay(marker);
    map.setCenter(point, zoom);
		marker.openInfoWindowHtml(html);
	}
}


// INTERNAL FUNCTIONS


// Retrieve text of an XML document element, including elements using namespaces
function getElementTextNS(prefix, local, parentElem, index) {
  var result = "";
  if (prefix && isIE) {
    // IE/Windows way of handling namespaces
    result = parentElem.getElementsByTagName(prefix + ":" + local)[index];
  } 
  else {
    // the namespace versions of this method 
    // (getElementsByTagNameNS()) operate
    // differently in Safari and Mozilla, but both
    // return value with just local name, provided 
    // there aren't conflicts with non-namespace element
    // names
    result = parentElem.getElementsByTagName(local)[index];
  }
  if (result) {
    // get text, accounting for possible
    // whitespace (carriage return) text nodes 
    if (result.childNodes.length > 1) {
        return result.childNodes[1].nodeValue;
    } else {
    	if (result.firstChild == null) return ''; 
        return result.firstChild.nodeValue;    		
    }
  }
  else {
    return "";
  }
}


// encode the things to pass back and forth
// the escape() method in Javascript is deprecated -- should use encodeURIComponent if available
function encode( uri ) {
  if (encodeURIComponent) {
    return encodeURIComponent(uri);
  }
  if (escape) {
    return escape(uri);
  }
}


function trim(str)
{
  return str.replace(/^\s*|\s*$/g,"");
}
