//Copyright 2006 Harrison Digital Media Inc., All Rights Reserved
//Licensed non-exclusively to Portable Sound Laboratories for
//distributor locating web services

var geocoder = null;
var gmap = null;
var gmarkerManager = null;
var gmarkers = [];
  
var queryAddr = null;
var queryCity = null;
var queryState = null;
var queryZip = null;
var queryCountry = null;

var distributorDOM = null;
var userLatLng = null;
var directionsStartAddress = null;
var userLocationHTML = null;

function freemap()
{
  if (gmap)
  {
    gmap.closeInfoWindow();
    gmap.clearOverlays();
  }
  
  geocoder = null;
  gmarkerManager = null;
  gmarkers = null;
  
  distributorDOM = null;
  userLatLng = null;
  directionsStartAddress = null;
  userLocationHTML = null;

  queryAddr = null;
  queryCity = null;
  queryState = null;
  queryZip = null;
  queryCountry = null;

  gmap = null;
  GUnload();
}

function ShowDistributors(addr, city, state, zip, country)
{
  queryAddr = addr;
  queryCity = city;
  queryState = state;
  queryZip = zip;
  queryCountry = country;
  
  var query = addr + ' ' + city + ' ' + state + ' ' + zip + ' ' + country;
  
  if (geocoder==null)
    geocoder = new GClientGeocoder();
  
  if (geocoder) 
    geocoder.getLocations(query, userLocationCallback);
}

function initMap(latlng)
{
  //init the map
  gmap = new GMap2(document.getElementById("gmap"));  
  gmap.setCenter(latlng);
  gmap.addControl(new GLargeMapControl());
}


function userLocationCallback(response)
{
  if (response==null || response.Status.code != 200)
  {
    if (queryAddr!='')
      queryAddr = '';
    else
    if (queryZip!='')
      queryZip = '';
    else
    if (queryCity!='')
      queryCity = '';
    else
    if (queryState!='')
      queryState = '';
    else
    {
      //all attempts to find a good search result have failed. so, download the distributor
      //list and have all the results shown.
      directionsStartAddress = null;
      
      GDownloadUrl("dist.xml", ShowAllDistributors);
      return;
    }
      
    var query =
      queryAddr + ' ' +
      queryCity + ' ' +
      queryState + ' ' +
      queryZip + ' ' +
      queryCountry;
    
    if (geocoder)
      geocoder.getLocations(query, userLocationCallback);     
  }
  else
  { 
    var place = response.Placemark[0];

    directionsStartAddress = place.address;
    
    var addr = '';
    var city = '';
    var state = '';
    var zip = '';
    var country = '';
    
    var locality = null;
    
    if (place.AddressDetails!=null &&
        place.AddressDetails.Country!=null)
    {
      var countryNode = place.AddressDetails.Country;
      
      if (countryNode.Locality)
        locality = countryNode.Locality;
  
      if (countryNode.CountryName!=null)
        country = countryNode.CountryName;
      else
      if (countryNode.CountryNameCode!=null)
        country = countryNode.CountryNameCode;
  
      var adminArea = countryNode.AdministrativeArea;
          
      if (adminArea!=null)
      {
        state = adminArea.AdministrativeAreaName;

        if (adminArea.Locality)
          locality = adminArea.Locality;
      
        var subAdminArea = adminArea.SubAdministrativeArea;
        
        if (subAdminArea!=null &&
            subAdminArea.Locality!=null)
        {
          locality = countryNode.AdministrativeArea.SubAdministrativeArea.Locality;
        }
      }
    }
    
    if (locality!=null)
    {
      city = locality.LocalityName;
  
      if (locality.Thoroughfare!=null)
        addr = locality.Thoroughfare.ThoroughfareName;
      
      if (locality.PostalCode!=null)
        zip = locality.PostalCode.PostalCodeNumber;
    }
    
    if (addr!='')
    {
      userLocationHTML =
        '<span class=\"mapheader\">Your Location</span><br />' +
        '<span class=\"maptext\">' + addr + '<br />' + city + ' ' + state + ', ' + zip + '<br />' + country + '</span>';
    }
    else
    {
      userLocationHTML =
        '<span class=\"mapheader\">Your Location</span><br />' +
        '<span class=\"maptext\">' + place.address + '</span>';
    }
    
    userLatLng = new GLatLng(
      place.Point.coordinates[1],
      place.Point.coordinates[0]);
    
    //download the distributor xml if we havent already
    if (distributorDOM==null)
    {
      GDownloadUrl("dist.xml", ShowClosestDistributors);
    }
    else
    {
      //we have the distributors already, just redraw the map
      if (gmap)
      {
        gmap.closeInfoWindow();
        gmap.clearOverlays();
      }
      
      updateMap();  
    }      
  }
}

function NotFound()
{
  alert('Sorry, your address could not be found. Try entering only your postal code.');
  document.location = "http://www.imaingo.com/buy.html";
}

function MakeLatLng(lat,lon)
{
  //remove any spaces
  lat = lat.replace(' ','');
  lon = lon.replace(' ','');
  if (lat.match(/[-+]?([0-9]*\.[0-9]+|[0-9]+)/) &&
      lon.match(/[-+]?([0-9]*\.[0-9]+|[0-9]+)/))
  {
    return new GLatLng(lat, lon);
  }
  else
    return null;
}

function ShowAllDistributors(distribXml)
{
  distribXml = CleanXml(distribXml);
  distributorDOM = GXml.parse(distribXml);
  
  //find the first distributor's latlng
  var distribList = distributorDOM.getElementsByTagName('distributor'); 
  
  var distributor = distribList.item(0);
      
  var latitude = getField(distributor, 'latitude');
  var longitude = getField(distributor, 'longitude');
  
  var latlng = MakeLatLng(latitude,longitude);
  if (latlng==null)
    latlng = new GLatLng(0,0);
    
  initMap(latlng);
  
  addMarkers();
  
  if (gmarkers==null || gmarkers.length<=0)
  {
    NotFound();
    return;
  }
  
  var bounds = new GLatLngBounds(gmarkers[0].getPoint());
  
  for (i=1; i<gmarkers.length; i++)
  {
    bounds.extend(gmarkers[i].getPoint());
  }
  
  gmap.setCenter(bounds.getCenter());
  
  var zoom = gmap.getBoundsZoomLevel(bounds);
  
  if (zoom<0)
    zoom = 0;        
    
  gmap.setZoom(zoom);
  
  gmarkerManager.refresh();
  //alert('Click a distributor in your area and zoom in for a closer view.');
}


function ShowClosestDistributors(distribXml)
{
  distribXml = CleanXml(distribXml);
  distributorDOM = GXml.parse(distribXml);
  
  if (userLatLng==null)
  {
    NotFound();
    return;
  }
  
  //default zoom in close
  initMap(userLatLng);
  
  addMarkers();
  
  var closestMarker = findClosestMarker();
  
  if (closestMarker!=null)
  {  
    //set the zoom level of the map so that it is just 2 zoom levels higher than
    //the minimum zoom level that contains all of the markers
  
    var bounds = new GLatLngBounds(userLatLng);
    bounds.extend(closestMarker.getPoint());
    
    var zoom = gmap.getBoundsZoomLevel(bounds) - 2;
    
    if (zoom<0)
      zoom = 0;        
    
    gmap.setZoom(zoom);
  }
  else
  {
    gmap.setCenter(userLatLng, 15);
  }
  
  gmarkerManager.refresh();
}

function findClosestMarker()
{
  
  if (userLatLng==null || gmarkers==null || gmarkers.length<=0)
    return null;
    
  var closestLatLng = gmarkers[0].getPoint();
  var closestDistance = closestLatLng.distanceFrom(userLatLng);
  var closestMarker = gmarkers[0];
  
  var i;
  
  for (i=1; i<gmarkers.length; i++)
  {
    var latlng = gmarkers[i].getPoint();
    
    var d = latlng.distanceFrom(userLatLng);
    if (d < closestDistance)
    {
      closestDistance = d;
      closestLatLng = latlng;
      closestMarker = gmarkers[i];
    }
  }
  
  return closestMarker;
}

function getField(distributor, fieldName)
{
  //love those DOM nodes.
  if (distributor==null)
    return "";
    
  var elements = distributor.getElementsByTagName(fieldName);
  if (elements==null)
    return "";
  
  var node = elements.item(0);
  if (node==null)
    return "";
    
  var child = node.firstChild;
  if (child==null)
    return "";
    
  return child.nodeValue;
}

function addMarkers()
{
  if (gmarkerManager==null)
    gmarkerManager = new GMarkerManager(gmap);
    
  if (userLatLng!=null)
  {
    //place the user marker
    var uicon = new GIcon();
    uicon.image = "http://www.imaingo.com/images/homeoutline.png";
    uicon.shadow = "http://www.imaingo.com/images/shadow.png";
    uicon.iconSize = new GSize(39, 39);
    uicon.shadowSize = new GSize(39, 39);
    uicon.iconAnchor = new GPoint(10, 39);
    uicon.infoWindowAnchor = new GPoint(13, 20);
  
    var userMarker = new GMarker(userLatLng,{title:"Your Location", icon: uicon});
    userMarker.onClick = function()
    {
      this.openInfoWindow(userLocationHTML);
    };
  
    GEvent.bind(userMarker, 'click', userMarker, userMarker.onClick);
    gmarkerManager.addMarker(userMarker,0); //0 is the 'min zoom' at which the marker is visible
  }
  
  //place the distributor markers
  var distribList = distributorDOM.getElementsByTagName('distributor'); 
  for (i=0; i<distribList.length; i++)
  {        
    var distributor = distribList.item(i);

    //verify latitude and longitude
    var latitude = getField(distributor, 'latitude');
    var longitude = getField(distributor, 'longitude');

    var latlng = MakeLatLng(latitude,longitude);
    
    //if latlng aren't valid numbers, don't add an entry to the map
    if (latlng!=null)
    {
      //create a marker for the distributor, set the name and lat/lon
      var name = getField(distributor, 'name');    
      var marker = new GMarker(latlng,{title:name});

      gmarkers[i] = marker;
        
      //get the address and build the contents of the info window for the marker
      var address = getField(distributor, 'address');
      var city = getField(distributor, 'city');
      var state = getField(distributor, 'state');
      var zip = getField(distributor, 'zip');
      var country = getField(distributor, 'country');
      var phone = getField(distributor, 'phone');
      
      var distribFullAddress = 
        address + ' ' + 
        city + ' ' + 
        state + ' ' + 
        zip + ' ' + 
        country + 
        ' (' + name + ')';
      
      
      var saddr = directionsStartAddress;
      if (saddr==null)
      {
        //directionsStartAddress is usually provided by the user, but sometimes the lookup will
        //fail or they wont enter one, so if that is the case have the start address be the same as
        //the destination address
        saddr = distribFullAddress;
      }
      
      marker.getDirectionsHtml = 
        '<span class=\"mapheader\">' + name + '</span><br />' +
        '<span class=\"maptext\">' +
        phone + '<br />' +
        address + '<br />' + 
        city + ' ' + state + ', ' + zip + '<br />' +
        '</span><br />' + 
        '<span class=\"nodirect\">Enter an address below<br />for driving directions</span>';
      
      marker.onClick = function()
      {  
        this.openInfoWindow(this.getDirectionsHtml);
      };
      
      GEvent.bind(marker, 'click', marker, marker.onClick);
    }
  }
  //add the markers (that were generated from parsing the xml list) to the map
  if (gmarkers.length>0)
    gmarkerManager.addMarkers(gmarkers,0);
}

function CleanXml(xmlString)
{
  /*
  var s = "";
  
  var i;
  for (i=0; i<xmlString.length; i++)
  {
    var c = xmlString.charCodeAt(i);
    if (c>31 && c<128)
      s += xmlString.charAt(i);
  }*/
  var s = xmlString.replace(/[^\x00-\x7E]/g,"_");
  return s;  
}