// 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 addressItem = ''; 

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

    return addressItem;
  }
}

// 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, callbackFunction) {
  // branch for native XMLHttpRequest object
  if (window.XMLHttpRequest) {
    req = new XMLHttpRequest();
    req.onreadystatechange = callbackFunction;
    req.open("GET", url, true);
    req.send(null);
  // branch for IE/Windows ActiveX version
  } 
  else if (window.ActiveXObject) {
    isIE = true;
    req = new ActiveXObject("Microsoft.XMLHTTP");
    if (req) {
      req.onreadystatechange = callbackFunction;
      req.open("GET", url, true);
      req.send();
    }
  }
}

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

    // 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 style=\"color:red\">The following error occurred:<br> " + 
        getElementTextNS("", "Message", errors[0], 0) + "</span>";
        return;
      }
      var result = req.responseXML.getElementsByTagName("Result");
      var theURL = "http://www.26point2.co.uk/" + getElementTextNS("", "url", result[0], 0);
      document.getElementById('hyperlinkDisplay').innerHTML = "<b><a href=\"" + theURL + "\"><span style=\"color:red\">" + theURL + "</span></a></b>\n";
    } 
    else {
      document.getElementById('hyperlinkDisplay').innerHTML = "<span style=\"color:red\">Unable to retrieve XML data.";
    }
  }
}

// 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) {
    document.getElementById('searchInfo').innerHTML = "<span style=\"color:red\">The following error occurred:<br> " + 
      getElementTextNS("", "Message", errors[0], 0) + "</span>";
    document.getElementById('geoResults').style.display = 'none';
    document.getElementById("geoSuggestForm").style.display = 'none';
    return;
  }

  clearSelect("geoSuggestList");
  var items = req.responseXML.getElementsByTagName("Result");
  
  /* Get precision attibutes.
  * Looks like yahoo return the same 'precision' attribute for multiple "Result" element
  */
  var precision = items[0].getAttribute('precision');

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

  // Center Map and show marker
  map.centerAndZoom(new GPoint(MBLocations[0].Longitude, MBLocations[0].Latitude), 3);
  
  // 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
  //map.centerAndZoom(new GPoint(MBLocations[id].Longitude, MBLocations[id].Latitude), 3);
}

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

