// Global storage for Location objects
var MBLocations = new Array();

// MapBuilder.net: Location Definition Class
function MBLocation (Latitude, Longitude, Address, City, State, Zip, Country) 
{
  this.Latitude = Latitude;
  this.Longitude = Longitude;
  this.Address = Address;
  this.City = City;
  this.State = State;
  this.Zip = Zip;
  this.Country = Country;

  // Create well formatted location address
  this.GetAddress = function() {
    var item = '';

    if (this.Address != '') {
       item = this.Address;
    }
    if (this.City != '') {
       item = (item == '') ? this.City : item + ", " + this.City;
    }
    if (this.State != '') {
       item = (item == '') ? this.State : item + ", " + this.State;
    }
    if (this.Zip != '') {
       item = (item == '') ? this.Zip : item + ", " + this.Zip;
    }
    if (this.Country != '') {
       item = (item == '') ? this.Country : item + ", " + this.Country;
    }

    return item;
  }
}

// global flag
var isIE = false;

// global request and XML document objects
var req;

// retrieve XML document (reusable generic function);
// parameter is URL string (relative or complete) to
// an .xml file whose Content-Type is a valid XML
// type, such as text/xml; XML source must be from
// same domain as HTML file
function loadXMLDoc(url, args, callbackFunction) 
{
  // branch for native XMLHttpRequest object
  if (window.XMLHttpRequest) {
    req = new XMLHttpRequest();
    req.onreadystatechange = callbackFunction;
    req.open("POST", url, true);
    req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    req.send(args);
  // branch for IE/Windows ActiveX version
  }
  else if (window.ActiveXObject) {
    isIE = true;
    req = new ActiveXObject("Microsoft.XMLHTTP");
    if (req) {
      req.onreadystatechange = callbackFunction;
      req.open("POST", url, true);
      req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      req.send(args);
    }
  }
}

// handle onreadystatechange event of req object
function processGeoCodeRequest()
{
  // only if req shows "loaded"
  if (req.readyState == 4) {
    // only if "OK"
    if (req.status == 200) {
      //clearResults();
      buildGeoSuggestList();
    }
    else {
      document.getElementById('searchInfo').innerHTML =
        "<span style=\"color:red\">Unable to retrieve XML data.</span>\n";
    }

    // Enable address
    document.locationSearchForm.locationSearchTextBox.removeAttribute("readonly");
  }
}

// handle onreadystatechange event of req object
function processHyperlinkRequest()
{
  // only if req shows "loaded"
  if (req.readyState == 4) {
    // only if "OK"
    if (req.status == 200) {
      var errors = req.responseXML.getElementsByTagName("Error");
      // Do we have an error in the xml?
      if (errors.length > 0) {
        document.getElementById('hyperlinkDisplay').innerHTML =
          "<span id=\"hyperlinkText\">The following error occurred:<br /> " +
          getElementTextNS("", "ErrorMessage", req.responseXML, 0) + "</span>\n";
        return;
      }
      var result = req.responseXML.getElementsByTagName("Result");
      var theURL = "http://routebuilder.org/" +
        getElementTextNS("", "url", result[0], 0);
      document.getElementById('hyperlinkDisplay').innerHTML = "<b><a href=\"" +
        theURL + "\"><span id=\"hyperlinkText\">" + theURL + "</span></a></b>\n";
    }
    else {
      document.getElementById('hyperlinkDisplay').innerHTML =
        "<span id=\"hyperlinkText\">Unable to retrieve XML data.</span>\n";
    }
  }
}

// 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 "n/a";
  }
}

// Remove all previous results from the screen
function clearResults()
{
  clearSelect("geoSuggestList");
  document.getElementById('searchInfo').innerHTML = '';
  //document.getElementById('searchInfo').style.display = 'none';
  document.getElementById("geoSuggestForm").style.display = 'none';
}

// Empty select list content
function clearSelect(select_name)
{
  var select = document.getElementById(select_name);
  while (select.length > 0) {
    select.remove(0);
  }
}

// Add item to select element
function appendToSelect(select, value, content)
{
  var opt;
  opt = document.createElement("option");
  opt.value = value;
  opt.appendChild(content);
  select.appendChild(opt);
}

// Fill Locations select list with items from the XML document
function buildGeoSuggestList()
{
  var select = document.getElementById("geoSuggestList");
  var errors = req.responseXML.getElementsByTagName("Error");

  // Do we have an error in the xml?
  if (errors.length > 0 && parseInt(errors[0].textContent) > 0) {
    document.getElementById('searchInfo').innerHTML =
      "<span style=\"color:red\">The following error occurred:<br> " +
      getElementTextNS("", "ErrorMessage", req.responseXML, 0) + "</span>";
    document.getElementById('geoResults').style.display = 'none';
    document.getElementById("geoSuggestForm").style.display = 'none';
    return;
  }

  clearSelect("geoSuggestList");
  var items = req.responseXML.getElementsByTagName("Result");
  var xml = req.responseXML.text;

  // loop through <Result> elements, and add each nested to the "Suggest" drop down
  for (var i = 0; i < items.length; i++) {
    // Create location object and store it in the array
    MBLocations[i] = new MBLocation
    (
      getElementTextNS("", "latitude", items[i], 0),
      getElementTextNS("", "longitude", items[i], 0),
      getElementTextNS("", "street", items[i], 0),
      getElementTextNS("", "city", items[i], 0),
      getElementTextNS("", "state", items[i], 0),
      getElementTextNS("", "zip", items[i], 0),
      getElementTextNS("", "country", items[i], 0)
    );

    // Add node to the drop down
    appendToSelect(select, i, document.createTextNode(MBLocations[i].GetAddress()));
  }

  var newCenter = new google.maps.LatLng(MBLocations[0].Latitude, MBLocations[0].Longitude)
  centerLat = newCenter.lat();
  centerLon = newCenter.lng();
  map.setCenter(newCenter);
  map.setZoom(13);

  // Do we have some suggestions from Yahoo?
  if (items.length > 1) {
    document.getElementById('searchInfo').innerHTML = 'Did you mean one of these?';
    document.getElementById("geoSuggestForm").style.display = 'block';
  }
  else {
    document.getElementById('searchInfo').innerHTML = '';
    document.getElementById("geoSuggestForm").style.display = 'none';
  }
}


// Show geo information received from Yahoo for the given ID of MBLocation object
function DumpGeoInfo(id)
{
  document.getElementById("geoResults").innerHTML =
    "<b>Geocode Result</b><br \>" +
    "Latitude: " + MBLocations[id].Latitude  + "<br \>" +
    "Longitude: " + MBLocations[id].Longitude + "<br \>" +
    "Address: " + MBLocations[id].Address + "<br \>" +
    "City: " + MBLocations[id].City + "<br \>" +
    "State: " + MBLocations[id].State + "<br \>" +
    "Zip: " + MBLocations[id].Zip + "<br \>" +
    "Country: " + MBLocations[id].Country;

  //document.getElementById("geoResults").style.visibility = 'visible';

  // Center Map and show marker
  var newCenter = new google.maps.LatLng(MBLocations[id].Latitude, MBLocations[id].Longitude)
  centerLat = newCenter.lat();
  centerLon = newCenter.lng();
  map.setCenter(newCenter);
  map.setZoom(13);
}

// 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,"");
}

