// ----------------------------------------------------------------------------
// Copyright - J. C. Parker 2009
// ----------------------------------------------------------------------------

var map = null;

var URL_BASE_1 = 'http://www.lynedochpublications.com.au/radiosites/radio_sites.php';
var URL_BASE_2 = 'http://www.lynedochpublications.com.au/gmaps/redirector.php';

var cookieName    = 'gmapsHomeQTH';
var cookieVersion = 1;

// array to hold a copy of the markers and its index
var navigationMarker  = null;
var moveendHandle = null;
var downLoadListenerHandle = null;
var homeQThPoint = null;

// the cookie variables
var mapCenterLat = 0.0;  // set the default to just south of Ghana
var mapCenterLng = 0.0;  // set the default to just south of Ghana
var mapZoom      = 2;
var mapType      = G_SATELLITE_MAP;
var mapTypeText  = "k";
var viewIdx      = 0;
var homeQThName  = 'GE_MAPS';
var homeQThLat   = 0.0;  // set the default to just south of Ghana
var homeQThLng   = 0.0;  // set the default to just south of Ghana
var modeStartUp  = true;

var siteTypesCount = 0;
var Beacons_10m  = [];
var Beacons_6m   = [];
var Beacons_2m   = [];
var Beacons_70cm = [];
var Beacons_23cm = [];
var Beacons_SHF  = [];
var Beacons_TV   = [];
var Field_sites  = [];
var QTHs         = [];
var gmarkers     = [];

var bearingLine = null;

var selectedSiteName = '';
var selectedQThLat   = 0.0;
var selectedQThLng   = 0.0;

// ----------------------------------------------------------------------------

var sitesTypes = [];

sitesTypes[0] = "b_10m";
sitesTypes[1] = "b_6m";
sitesTypes[2] = "b_2m";
sitesTypes[3] = "b_70cm";
sitesTypes[4] = "b_23cm";
sitesTypes[5] = "b_SHF";
sitesTypes[6] = "b_TV";
sitesTypes[7] = "field_s";
sitesTypes[8] = "QTH";

// ----------------------------------------------------------------------------

   var baseIcon = new google.maps.Icon();
   baseIcon.iconSize         = new google.maps.Size(32,32);
   baseIcon.shadowSize       = new google.maps.Size(56,32);
   //baseIcon.shadowSize       = new google.maps.Size(0,0);     // no shadows
   baseIcon.iconAnchor       = new google.maps.Point(16,16);  // middle of icon
   baseIcon.infoWindowAnchor = new google.maps.Point(16,16);  // middle of icon

   var qthIcon     = new google.maps.Icon(baseIcon, "http://maps.google.com/mapfiles/kml/pal2/icon10.png");
   var homeqthIcon = new google.maps.Icon(baseIcon, "http://maps.google.com/mapfiles/kml/pal2/icon2.png");
   var field_sIcon = new google.maps.Icon(baseIcon, 'http://maps.google.com/mapfiles/kml/pal3/icon29.png');

   var b_10mIcon   = new google.maps.Icon(baseIcon, 'http://home.exetel.com.au/dwsmith/radiosites/support/yagi10m_blue.png');
   var b_6mIcon    = new google.maps.Icon(baseIcon, 'http://home.exetel.com.au/dwsmith/radiosites/support/yagi6m_mauve.png');
   var b_2mIcon    = new google.maps.Icon(baseIcon, 'http://home.exetel.com.au/dwsmith/radiosites/support/yagi2m_green.png');
   var b_70cmIcon  = new google.maps.Icon(baseIcon, 'http://home.exetel.com.au/dwsmith/radiosites/support/yagi70cm_yellow.png');
   var b_23cmIcon  = new google.maps.Icon(baseIcon, 'http://home.exetel.com.au/dwsmith/radiosites/support/yagi23cm_orange.png');
   var b_SHFIcon   = new google.maps.Icon(baseIcon, 'http://home.exetel.com.au/dwsmith/radiosites/support/dish1_active.png');
   var b_TVIcon    = new google.maps.Icon(baseIcon, 'http://home.exetel.com.au/dwsmith/radiosites/support/tower1.png');

// ----------------------------------------------------------------------------
// Determine what region the home QTH is in. This determines what they see
// ----------------------------------------------------------------------------

function findRegion(lat, lng)
{
   var region = '';

   if ((lng >= 90.0) || (lng < -165.0))
   {
      region = 'pac';
   }
   else if ((lng >= -165.0) && (lng < -30.0))
   {
      if (lat >= 13.0)
         region = 'nam';
      else
         region = 'sam';
   }
   else  // lng >= -30.0 and lng < 90.0
   {
      if (lat >= 28.0)
         region = 'eur';
      else
         region = 'afr';
   }
   return region;
}

// ----------------------------------------------------------------------------
// Populate the map with the KML data
// ----------------------------------------------------------------------------

function getMarkers(siteTypes, nlName)
{
   // what region is the home QTH in?
   var region = findRegion (homeQThLat, homeQThLng);

   if (region !== 'pac')
      urlBase = URL_BASE_1;
   else // is 'pac'
      urlBase = URL_BASE_2;

   var uri = urlBase + "?ver=1&sn=" + homeQThName.replace(/ /g,'_')
           + "&lat=" + homeQThLat +"&lng=" + homeQThLng
           + "&rgn=" + region + "&nln=" + nlName + "&uap=gm";

   uri = encodeURI(uri);
   //GLog.write(uri);

   // set the call back function - this waits for the
   // request to complete as a background thread
   google.maps.DownloadUrl(uri, function(data, responseCode)
   {
      // check status code for success or HTTP errors
      if (responseCode == 200)
      {
         // get all the placemarks
         var xmlDoc = google.maps.Xml.parse(data);
         var placemarks = xmlDoc.documentElement.getElementsByTagName("Placemark");

         // process the placemarks
         for (var i = 0; i < placemarks.length; i++)
         {
            // placemarks do not necessarily contain markers
            // markers have a 'Point' tag
            if (placemarks[i].getElementsByTagName("Point").length > 0)
            {
               var point  = placemarks[i].getElementsByTagName("Point")[0];
               var coords = point.getElementsByTagName("coordinates")[0].childNodes[0].nodeValue;
               coords     = coords.split(",");
               var name   = placemarks[i].getElementsByTagName("name")[0].childNodes[0].nodeValue;

               // placemarks don't have to have descriptions
               var description = "";
               if (placemarks[i].getElementsByTagName("description").length > 0)
                  description = placemarks[i].getElementsByTagName("description")[0].childNodes[0].nodeValue;

               // placemarks don't have to have a styleUrl
               var styleUrl = "";
               var icon = new google.maps.Icon(G_DEFAULT_ICON);
               if (placemarks[i].getElementsByTagName("styleUrl").length > 0)
               {
                  styleUrl = placemarks[i].getElementsByTagName("styleUrl")[0].childNodes[0].nodeValue;

                  // map the styles to the icons
                  switch (styleUrl)
                  {
                     case '#sty_qth':
                        icon = qthIcon;
                        break;
                     case '#sty_b_10m':
                        icon = b_10mIcon;
                        break;
                     case '#sty_b_6m':
                        icon = b_6mIcon;
                        break;
                     case '#sty_b_2m':
                        icon = b_2mIcon;
                        break;
                     case '#sty_b_70cm':
                        icon = b_70cmIcon;
                        break;
                     case '#sty_b_23cm':
                        icon = b_23cmIcon;
                        break;
                     case '#sty_b_SHF':
                        icon = b_SHFIcon;
                        break;
                     case '#sty_b_TV':
                        icon = b_TVIcon;
                        break;
                     case '#sty_field_s':
                        icon = field_sIcon;
                        break;
                     case '#sty_home_qth':
                        icon = homeqthIcon;
                        break;
                     default:
                        break;
                  }
               }

               // create the marker
               var latLng = new google.maps.LatLng (parseFloat(coords[1]), parseFloat(coords[0]));
               var marker = createMarker(latLng, icon, name, description);

               siteTypes.push(marker);
            }
         }  // end for all the points
      }     // end response code OK
      else if (responseCode == -1)
      {
         alert ("Data request timed out. Please try later.");
      }
      else
      {
         alert ("Request resulted in an error. Check file is retrievable.");
      }

      // flag that this download has completed, regardless of the outcome
      google.maps.Event.trigger(map,'downLoadDone');

   });   // end google.maps.DownloadUrl function definition
}

// ----------------------------------------------------------------------------
// Waits till everything is downloaded and then shows the selected markers
// ----------------------------------------------------------------------------

function createDownLoadListener()
{
   if (downLoadListenerHandle !== null) return;

   downLoadListenerHandle = google.maps.Event.addListener(map,'downLoadDone',function()
   {
      siteTypesCount++;
      //GLog.write('Download completed '+siteTypesCount);

      if (siteTypesCount == sitesTypes.length)
      {
         document.getElementById("siteTypesOptions").disabled = false;
         changeSitesType();
      }
   });
}

// ----------------------------------------------------------------------------
// Focus on the sites selected in the pulldown list
// ----------------------------------------------------------------------------

function changeSitesType()
{
   var siteTypesOptions = document.getElementById("siteTypesOptions");
   var showTheseSites   = siteTypesOptions.selectedIndex;

   /* How the google.maps.XmlHttp request object works is a bit confusing until you realize that
   it doesn't execute inline. Once you call the request object, control returns to the
   next line in the code while the "get" happens in the background. The request object
   waits patiently for the server to return the results (the onreadystate = 4) and
   then acts on the received data. */

   map.clearOverlays();

   // get the selected marker array
   switch (showTheseSites)
   {
      case 0:
         gmarkers = Beacons_10m;
         break;
      case 1:
         gmarkers = Beacons_6m;
         break;
      case 2:
         gmarkers = Beacons_2m;
         break;
      case 3:
         gmarkers = Beacons_70cm;
         break;
      case 4:
         gmarkers = Beacons_23cm;
         break;
      case 5:
         gmarkers = Beacons_SHF;
         break;
      case 6:
         gmarkers = Beacons_TV;
         break;
      case 7:
         gmarkers = Field_sites;
         break;
      case 8:
         gmarkers = QTHs;
         break;
      default:
         gmarkers = [];
         break;
   }

   var sideBarHTML = '';

   // add all the markers to the map and
   // create the side bar HTML code
   var gmarkersLength = gmarkers.length;
   for (var j = 0; j < gmarkersLength; j++)
   {
      var theMarker = gmarkers[j];
      map.addOverlay(theMarker);

      // add a line to the side bar
      sideBarHTML += '<a href="javascript:sideBarClick(' + j + ')">' + theMarker.getTitle() + '</a><br/>';
   }

   // show the total count in the side bar
   sideBarHTML = 'Sites found = ' + gmarkersLength + '<br/>' + sideBarHTML;

   // put the assembled sideBar contents into the side bar div
   document.getElementById("sideBar").innerHTML = sideBarHTML;
}

// ----------------------------------------------------------------------------
// Set the map parameters in the cookie
// ----------------------------------------------------------------------------

// the 'moveend' listener can't pass parameters - so it's done here
function setCookieParms()
{
   var latLngStr = map.getCenter().toUrlValue();
   var latLng    = latLngStr.split(",");
   mapCenterLat  = parseFloat(latLng[0]);
   mapCenterLng  = parseFloat(latLng[1]);

   setCookieParameters(3);
}

function setCookieParameters(years)
{
   // the cookie holds the map layout and the home QTH
   var cookieValue = cookieVersion +','
                   + mapCenterLat +','+ mapCenterLng +','
                   + mapZoom +','
                   + mapTypeText +','
                   + viewIdx +','
                   + homeQThName.replace(/ /g,'_') +','
                   + homeQThLat +','+ homeQThLng +','
                   + modeStartUp;

   // set the expiry time
   var date = new Date();
   date.setTime(date.getTime()+(years*365*24*60*60*1000));

   // set the cookie
   document.cookie = cookieName+'='+escape(cookieValue)
                   + '; expires='+date.toGMTString()
                   + '; path=/';

   // if the year is -1 the cookie is destroyed
   return (years != -1);
}

// ----------------------------------------------------------------------------
// Get the map set up parameters from the cookie
// ----------------------------------------------------------------------------

function getCookieParms()
{
   // set the defaults in case there is no cookie
   mapCenterLat = 0.0;  // set the default to just south of Ghana
   mapCenterLng = 0.0;  // set the default to just south of Ghana
   mapZoom      = 2;
   mapType      = G_SATELLITE_MAP;
   mapTypeText  = "k";
   viewIdx      = 0;  // select the 'b_10m' option in the pulldown list as the default
   homeQThName  = 'GE_MAPS';
   homeQThLat   = mapCenterLat;
   homeQThLng   = mapCenterLng;

   // can the map be centered by estimating the user's location from their IP address?
   if (google.loader.ClientLocation)
   {
      // set the default to client's estimated location
      mapCenterLat = google.loader.ClientLocation.latitude;
      mapCenterLng = google.loader.ClientLocation.longitude;
      homeQThLat   = mapCenterLat;
      homeQThLng   = mapCenterLng;

      mapZoom      = 9;
   }

   // got a cookie? - if not RETURN
   var results = document.cookie.match (cookieName + '=(.*?)(;|$)');
   if (!results)
      return false;

// ----------------------------------------------------------------------------

   // a cookie was found
   var cookiePrms = unescape(results[1]).split(',');

   // is the cookie up to date?
   if (cookiePrms[0] != cookieVersion)
      return false;

   // a cookie was found - load the data from it
   mapCenterLat = parseFloat(cookiePrms[1]);
   mapCenterLng = parseFloat(cookiePrms[2]);

   mapZoom = parseInt(cookiePrms[3],10);

   mapTypeText = cookiePrms[4];
   if      (mapTypeText == "p") { mapType = G_PHYSICAL_MAP;  }
   else if (mapTypeText == "k") { mapType = G_SATELLITE_MAP; }
   else if (mapTypeText == "h") { mapType = G_HYBRID_MAP;    }
   else                         { mapType = G_NORMAL_MAP; mapTypeText = "m"; }

   viewIdx     = cookiePrms[5];
   homeQThName = cookiePrms[6];
   homeQThLat  = parseFloat(cookiePrms[7]);
   homeQThLng  = parseFloat(cookiePrms[8]);

   var modeStartUpStr = cookiePrms[9];
   var tmp = modeStartUpStr.toLowerCase().indexOf("true");

   // shouldn't need the temp var but it doesn't work without it
   modeStartUp = (tmp === 0);

   //GLog.write('Val  = '+ tmp);
   //GLog.write('Bool = '+ modeStartUp.toString());

   return true;
}

// ----------------------------------------------------------------------------
// When the user operates the button, handle (un)locking the home QTH icon
// ----------------------------------------------------------------------------

function lockButtonClicked()
{
   if (modeStartUp)  // lock reference point
   {
      modeStartUp = false;

      homeQThName = document.getElementById("siteNameEntry").value;

      //GLog.write('Here 1 homeQThName  = '+ homeQThName );

     if (navigationMarker !== null)
         homeQThPoint = navigationMarker.getPoint();
      else
         homeQThPoint = new google.maps.LatLng(homeQThLat,homeQThLng);

      var latLngStr = homeQThPoint.toUrlValue();
      var latLng    = latLngStr.split(",");
      homeQThLat    = parseFloat(latLng[0]);
      homeQThLng    = parseFloat(latLng[1]);

      document.getElementById("siteNameEntry").value    = 'Locked to ' + homeQThName;
      document.getElementById("siteNameEntry").disabled = true;
      document.getElementById("lockButton").value       = 'Change reference point';
      document.getElementById("lockButton").disabled    = false;

      setCookieParameters(3);
      setupMarkers();  // this will destroy any pre existing navigation marker
   }
   else  // change reference point
   {
      modeStartUp = true;

      //GLog.write('Here 2 homeQThName  = '+ homeQThName );

      homeQThPoint = null;

      // the pull down list cannot be used till the data is loaded
      document.getElementById("siteTypesOptions").disabled = true;

      document.getElementById("siteNameEntry").value    = 'Enter your call sign here';
      document.getElementById("siteNameEntry").disabled = false;
      document.getElementById("lockButton").value       = 'Lock map to?';
      document.getElementById("lockButton").disabled    = true;

      setCookieParameters(3);

      // clear all the radio site markers off the map
      map.clearOverlays();
      createNavigator();
   }
}

// ----------------------------------------------------------------------------
// Get all the markers and display them
// ----------------------------------------------------------------------------

function setupMarkers()
{
   destroyNavigator();

   createDownLoadListener();

   var sideBarLoadingMsgHTML = '<p><img src="http://www.lynedochpublications.com.au/gmaps/spinner.gif" alt="Spinner"/>Loading .....</p>';

   // put the "Loading" message into the side bar div
   document.getElementById("sideBar").innerHTML = sideBarLoadingMsgHTML;

   Beacons_10m  = [];
   Beacons_6m   = [];
   Beacons_2m   = [];
   Beacons_70cm = [];
   Beacons_23cm = [];
   Beacons_SHF  = [];
   Beacons_TV   = [];
   Field_sites  = [];
   QTHs         = [];
   gmarkers     = [];

   siteTypesCount = 0;
   getMarkers(Beacons_10m,  sitesTypes[0]);
   getMarkers(Beacons_6m,   sitesTypes[1]);
   getMarkers(Beacons_2m,   sitesTypes[2]);
   getMarkers(Beacons_70cm, sitesTypes[3]);
   getMarkers(Beacons_23cm, sitesTypes[4]);
   getMarkers(Beacons_SHF,  sitesTypes[5]);
   getMarkers(Beacons_TV,   sitesTypes[6]);
   getMarkers(Field_sites,  sitesTypes[7]);
   getMarkers(QTHs,         sitesTypes[8]);

   if (moveendHandle !== null)
      google.maps.Event.removeListener(moveendHandle);
   moveendHandle = google.maps.Event.addListener(map, "moveend", setCookieParms);

   // at this point nothing happens until all the 'downLoadDone' events have been
   // fired, which then results in the changeSitesType function being called
}

// ----------------------------------------------------------------------------
// A function to create the marker and set up the info window
// ----------------------------------------------------------------------------

function createMarker(point, icon, name, description)
{
   var marker = new google.maps.Marker(point, {icon:icon, title:name});

   google.maps.Event.addListener(marker, "click", function()
      {
      if (homeQThPoint !== null)
      {
         var lineCoords = [marker.getPoint(), homeQThPoint];
         if (bearingLine !== null)
            map.removeOverlay(bearingLine);

         bearingLine = new google.maps.Polyline(lineCoords, "#ff0000", 2, 1, {geodesic:true});
         map.addOverlay(bearingLine);
      }

      var htmlCode = '<p><b>' + name + '</b></p>' + description;
      var divStyle = '<div class="gmapinfowindow">';
      htmlCode = divStyle + htmlCode + '</div>';

      marker.openInfoWindowHtml(htmlCode, {maxHeight:500,autoScroll:true});
      //alert (htmlCode);
      }
   );

   return marker;
}

// ----------------------------------------------------------------------------
// Echo each key press to the lock button text
// ----------------------------------------------------------------------------

function keyPressed()
{
   // ignore the keypresses if the entry box is not enabled
   if (document.getElementById("siteNameEntry").disabled)
      return;

   var siteNameTxt = document.getElementById("siteNameEntry").value;

   // limit the entry to 20 characters in length
   siteNameTxt = siteNameTxt.substr(0,20);

   // replace all spaces with underscores
   siteNameTxt = siteNameTxt.replace(/ /g,'_');

   // up date the lock button
   document.getElementById("lockButton").value = 'Lock map to ' + siteNameTxt;

   // only enable the lock button when 4 or more characters are available
   document.getElementById("lockButton").disabled = siteNameTxt.length < 4;
}

// ----------------------------------------------------------------------------
// This function picks up the side bar click and opens the associated info window
// ----------------------------------------------------------------------------

function sideBarClick(i)
{
   google.maps.Event.trigger(gmarkers[i], "click");
}

// ----------------------------------------------------------------------------
// Set up the navigator icon
// ----------------------------------------------------------------------------

function createNavigator()
{
    if (navigationMarker !== null) return;

  var English= "Once a reference point has been entered, this map can show the distance and bearing of 'Radio Sites' around the world from that reference point.<br/><br/>To make your QTH that reference point, follow these instructions:<br/><br/>After closing this window using the X, centre this icon right on top of your QTH by moving the map around - it will help to zoom right in.  If you can't find your location using the 'Satellite' view, try the 'Map' button to more readily determine your home location. Type in your call sign in the entry box below and click on the 'Lock map to' button.<br/><br/>Your callsign and location will be remembered by your PC. The next time you use this map, the distance and bearing to all the 'Radio Sites' will be specified in relationship to your QTH.<br/><br/>Try the Google Earth version of <a href=\"http://home.exetel.com.au/dwsmith/radiosites/radio_site_display.html\">'Radio Site Display'</a> also.";

  var Spanish = "Una vez que se haya incorporado un punto de referencia, este mapa puede demostrar la distancia y el cojinete de los “sitios de radio” alrededor del mundo de ese punto de referencia.<br/><br/>Para hacer tu QTH que el punto de referencia, sigue estas instrucciones:<br/><br/>Después de cerrar esta ventana usando el X, centrar la esta derecha del icono encima de tu QTH moviendo el mapa alrededor - ayudará a enfocar pulg. derecho. Si no puedes encontrar tu localización usando visión “basada en los satélites”, intentar el botón del “mapa” a determinan más fácilmente tu localización casera. Mecanografiar adentro tu indicativo en la caja de la entrada abajo y chascar encendido el “mapa de la cerradura” para abotonar.<br/><br/>Tu callsign y localización serán recordados por tu PC. La próxima vez que utilizas este mapa, la distancia y el cojinete a todos los “sitios de radio” serán especificados en la relación a tu QTH.<br/><br/>Pruebe la versión de Google Earth de <a href=\"http://home.exetel.com.au/dwsmith/radiosites/radio_site_display.html\">'Radio Site Display'</a> también.";

  var German = "Sobald ein Bezugspunkt eingetragen worden ist, kann dieses Diagramm den Abstand und das Lager „der Radioaufstellungsorte“ um die Welt zeigen von diesem Bezugspunkt.<br/><br/>Dein QTH bilden, dem Bezugspunkt, diese Anweisungen befolgen:<br/><br/>Nachdem Sie dieses Fenster mit dem X geschlossen haben, dieses Ikone Recht auf dein QTH zentrieren, indem Sie herum das Diagramm verschieben - es hilft zoom rechter inch. Wenn du nicht deine Position mit der „Satelliten“ Ansicht, versuchen „Diagramm“ Taste finden kannst zu feststellen bereitwillig deine Hauptposition. Dein Rufzeichen im Eintragung Kasten unten eintippen und das „Verriegelung Diagramm an klicken“ zu knöpfen.<br/><br/>An dein Rufzeichen und Position werden durch deinen PC erinnert. Naechstes Mal wenn du dieses Diagramm benutzt, werden der Abstand und das Lager zu allen „Radioaufstellungsorten“ im Verhältnis zu deinem QTH spezifiziert.<br/><br/>Probieren Sie die Google Earth-Version von <a href=\"http://home.exetel.com.au/dwsmith/radiosites/radio_site_display.html\">'Radio Site Display'</a> auch.";

   // make a tabbed marker and add in the translations
   navigationMarker = new google.maps.Marker(map.getCenter(), {icon:homeqthIcon, title:'Place this icon right on top of your QTH'});

   google.maps.Event.addListener(navigationMarker, "click", function()
      {
      var divStyle = '<div class="gmapinfowindow">';

      English = divStyle + English + '</div>';
      Spanish = divStyle + Spanish + '</div>';
      German  = divStyle + German  + '</div>';

      navigationMarker.openInfoWindowTabsHtml([
         new google.maps.InfoWindowTab('English', English),
         new google.maps.InfoWindowTab('Español', Spanish),
         new google.maps.InfoWindowTab('Deutsch', German)
         ], {maxHeight:500,autoScroll:true});
      }
   );

   map.addOverlay(navigationMarker);

   document.getElementById("sideBar").innerHTML = 'Read the instructions to set up your QTH as the map reference point.';

   if (moveendHandle !== null)
      google.maps.Event.removeListener(moveendHandle);
   moveendHandle = google.maps.Event.addListener(map, "moveend", trackMapCenter);

   // display the marker's help bubble
   google.maps.Event.trigger(navigationMarker, "click");
}

// ----------------------------------------------------------------------------
// Convert decimal degrees to DMS
// ----------------------------------------------------------------------------

function decToDMS(decDeg, latPassedIn)
{
   degAbs = Math.abs(decDeg);

   var deg    = Math.floor(degAbs);
   var decMin = (degAbs -deg)*60.0;
   var mins   = Math.floor(decMin);
   var sec    = Math.round((decMin-mins)*60.0);

   var dmsStr = deg +'\u00B0 '+ mins +"' "+ sec + '" ';

   if (decDeg >= 0.0)
      if (latPassedIn)
         dmsStr = dmsStr + 'N';
      else
         dmsStr = dmsStr + 'E';
   else
      if (latPassedIn)
         dmsStr = dmsStr + 'S';
      else
         dmsStr = dmsStr + 'W';

   return dmsStr;
}

// ----------------------------------------------------------------------------
// This function moves the navigation icon to the new map center
// It's triggered by the moveend event
// ----------------------------------------------------------------------------

function trackMapCenter()
{
   // if the info window is on show freeze the icon position
   if (!map.getInfoWindow().isHidden())
      return;

   // display the icon lat lng
   var iconLocation = map.getCenter();
   var latLngStr    = iconLocation.toUrlValue();

   var latLng = latLngStr.split(",");
   var lat    = parseFloat(latLng[0]);
   var latDMS = decToDMS(lat, true);
   var lng    = parseFloat(latLng[1]);
   var lngDMS = decToDMS(lng, false);

   document.getElementById("sideBar").innerHTML =
      '<p>Icon currently located at lat, lng:<br/>' + lat +', '+ lng + '<br/>' + latDMS +', '+ lngDMS + '</p>';

   // place the icon at the new lat lng
   navigationMarker.setPoint(iconLocation);

   // the map position changed - save it
   setCookieParameters(3);
}

// ----------------------------------------------------------------------------
// Get rid of the navigator icon
// ----------------------------------------------------------------------------

function destroyNavigator()
{
   if (navigationMarker === null) return;

   map.removeOverlay(navigationMarker);

   if (moveendHandle !== null)
   {
      google.maps.Event.removeListener(moveendHandle);
      moveendHandle = null;
   }

   navigationMarker  = null;
}

// ----------------------------------------------------------------------------
// The information window has closed
// ----------------------------------------------------------------------------

function infoWindowClosed()
{
   // the map moves when the infowindow opens
   // we'll stick it back to where it came from
   map.returnToSavedPosition();

   document.getElementById("siteNameEntry").select();

   // at this point the 'moveend' event is fired
}

// ----------------------------------------------------------------------------
// Don't name this 'onload' as it's a reserved word in Firefox
// ----------------------------------------------------------------------------

function load()
{
   // the pull down list cannot be used till the data is loaded
   document.getElementById("siteTypesOptions").disabled = true;

   // get the cookie if there is one
   getCookieParms();

   // set the radio sites to view in the pulldown list
   document.getElementById("siteTypesOptions").selectedIndex = viewIdx;

   if (GBrowserIsCompatible())
   {
      if (map === null)
      {
         map = new google.maps.Map2(document.getElementById("mapDiv"));

         // ready map center
         var mapCenter = new google.maps.LatLng(mapCenterLat,mapCenterLng);

         // got the center and zoom level so set it
         map.setCenter(mapCenter, mapZoom, mapType);

         // set up the UI controls on the map
         map.setUIToDefault();

         google.maps.Event.addListener(map, "zoomend", function(oldLevel, newLevel)
         {
            // the zoom level changed - save it
            mapZoom = newLevel;
            setCookieParameters(3);
         });

         google.maps.Event.addListener(map, "maptypechanged", function()
         {
            // the map type changed - save it
            mapType     = map.getCurrentMapType();
            mapTypeText = mapType.getUrlArg();
            setCookieParameters(3);
         });

         google.maps.Event.addListener(map, "infowindowopen", function()
         {
            // the map moves when the infowindow opens - later
            // on we'll stick it back to where it came from
            map.savePosition();
         });

         google.maps.Event.addListener(map, "infowindowclose", infoWindowClosed);
      }

      homeQThPoint = new google.maps.LatLng(homeQThLat,homeQThLng);

      if (!modeStartUp)
         document.getElementById("siteNameEntry").value = homeQThName;

      // set up the map depending on the mode
      modeStartUp = !modeStartUp; // force the correct mode
      lockButtonClicked();
   }
   else
      alert("Sorry, the Google Maps API is not compatible with this browser");
}

// ----------------------------------------------------------------------------

