/* declare global variables */
  var map;
  var geocoder = new GClientGeocoder();
  var pointHTML;

  /* unload function calls GoogleMaps API's GUnload function to clean up memory */
  function unload() {
    GUnload();
  }    

  /******************************************************/
  /*              start secondary functions             */
  /******************************************************/

  /* getGeocode function places a marker at the given address */
  /* takes an address and html for the infowindow */
  function getGeocode(address, pointHTML) {
    if (geocoder) {
      geocoder.getLatLng( address, function(point) {
        if (!point) {
        } else {
            var marker = new GMarker(point);
            pointHTML.Lat = point.lat();
            pointHTML.Lng = point.lng();
            map.addOverlay(createMarker(point, pointHTML));
        }
      });
    }
  } /* end getGeocode function */

  /* createMarker function creates a marker; takes a point and html for the infowindow */
  function createMarker(point, pointHTML) {
    var marker = new GMarker(point);
    GEvent.addListener(marker, "click", function() {
      htmlString = "<div id=\"IW\"><div class=\"IWCaption\">" + pointHTML.Caption + "</div>";
      htmlString += "<div class=\"IWContent\"><form name=\"IWForm\" action=\"\" method=\"post\">";
      htmlString += pointHTML.Address1 + "<br />";
//	  htmlString += ((pointHTML.Address2 != '') ? pointHTML.Address2 +'<br />' : '');
      htmlString += pointHTML.City + ", " + pointHTML.State + " " + pointHTML.Zip + "<br />";
      htmlString += "<strong>Phone:</strong> " + pointHTML.Phone + "<br />";
//    htmlString += "<strong>Fax:</strong> " + pointHTML.Fax + "<br />";
      htmlString += "<strong>Email:</strong> <a href=\"mailto:" + pointHTML.Email + "\">" + pointHTML.Email + "</a><br />";
      /* if not zoomed in already, show 'zoom map to this address' link */
      var zoomlevel = map.getZoom();
      if(zoomlevel < 15) {
        htmlString += "<br /><a href=\"javascript:void(0);\" onClick=\"zoomMarker(" + pointHTML.Lat + ", " + pointHTML.Lng + ", 15);\">Zoom to</a><br />";
      }
      htmlString += "</form></div>" + GetDirectionForm(pointHTML); + "</div>";
      
      var GInfoWindowOptions = {};
      GInfoWindowOptions.maxWidth = 300;
      marker.openInfoWindowHtml(htmlString, GInfoWindowOptions);
    });
    return marker;
  } /* end createMarker function*/

  /* zoomMarker function zooms map */
  /* takes location lat/lng and zoom level */ 
  function zoomMarker(lat, lng, zoom) {
//    var infowindow = map.getInfoWindow();
    map.closeInfoWindow();
    map.setCenter( new GLatLng(lat,lng),zoom); 
  } /* end zoomMarker function*/

  /* getDirections function controls directions to/from dialog box 
  /* attached to infowindow; takes map mode, force, and location lat/lng */
  function  getDirections(mode, force, lat, lng) {
    /* if the mode is set to toggle and the Directions form is invisible */
    /* we'll change the mode to 'to' and proceed */
    if(mode == "+" && document.getElementById("formGetDirections").style.display == "none") {
      mode = "to";
    }
    /* if the mode is set to toggle, and the Directions form is visible */
    /* we'll hide the form and change the toggle to a plus sign '+' */
    if(mode == "+" && document.getElementById("formGetDirections").style.display != "none") {
      document.getElementById("formGetDirections").style.display = "none";
      mode = "";
      document.getElementById("directions_toggle").innerHTML = "&nbsp;+&nbsp;";
      document.getElementById("IW").style.padding = "0";
      return;
    }
    /* set the Directions form's styles */
    document.getElementById('formGetDirections').style.background = "#fff";
    document.getElementById('formGetDirections').style.padding = "5px 10px";
    document.getElementById('formGetDirections').style.margin = "10px 0px";
    document.getElementById('formGetDirections').style.border = "1px solid #ccc";

    /* if we're here, the Directions form is open, so we need to change the */
    /* toggle to a minus sign '-' (using &ndash;) */
    document.getElementById("directions_toggle").innerHTML = "&nbsp;&ndash;&nbsp;";
    document.getElementById("IW").style.padding = "0 0 60px 0";
    /* initial condition: address box is not visible */
    var AddressBoxVisible = false;
    /* get the address of the fixed location */
    var address = document.getElementById("FixedLocation").value;
    /* assemble string for fixed location */
    document.getElementById("addr1").value = lat + ", " + lng + " (" + address + ")";
    if (mode=='to') {
      document.getElementById("AddressBoxLabel").innerHTML = 'Start address';
      document.getElementById("addr1").name = 'daddr';
      document.getElementById("addr2").name = 'saddr';
    }
    else {
      document.getElementById("AddressBoxLabel").innerHTML = 'End address';
      document.getElementById("addr1").name = 'saddr';
      document.getElementById("addr2").name = 'daddr';
    }
    if (force) {
      /* make address box visible or hidden */
      document.getElementById('formGetDirections').style.display = (AddressBoxVisible ? 'none' : 'block');
    }
    else {
      document.getElementById('formGetDirections').style.display = 'block';
    }
    /* toggle address box flag */
    AddressBoxVisible = (!AddressBoxVisible); 
    document.getElementById("addr2").focus();
  } /* end getDirections function */
  
  /* checkAddress function checks Directions textbox for user entry */
  /* if user has clicked submit button but not entered data display, */
  /* alert box and highlight textbox label */
  function checkAddress(form) {
    if (document.getElementById("addr2").value.length < 1) {
      alert("Please enter an address");
      document.getElementById("AddressBoxLabel").innerHTML = '<span style=\"font-weight: bold\">Please Enter an Address</span>';
      document.getElementById("AddressBoxLabel").focus();
      document.returnValue = false;
    }
    else {
      document.returnValue = true;
    }
  } /* end checkAddress function */
  
  /* GetDirectionForm function provides createMarker function */
  /* with html for the Directions form */  
  function GetDirectionForm(pointHTML) {
    var location = pointHTML.Lat + ", " + pointHTML.Lng;
    var address = pointHTML.Address1 + " " + pointHTML.City + " " + pointHTML.State; 
    return "<div class=\"IWDirections\">[<a id=\"directions_toggle\" onclick=\"getDirections('+', true," + location + ");\"; href=\"javascript:void(0)\" style=\"text-decoration:none;\">&nbsp;+&nbsp;</a>]&nbsp;Directions:&nbsp;<a onclick=\"getDirections('to', true," + location + ");\" href=\"javascript:void(0)\">To here</a>&nbsp;-&nbsp;<a onclick=\"getDirections('from', true," + location + ");\" href=\"javascript:void(0)\">From here</a><div id=\"formGetDirections\" style=\"display:none;\"><form name=\"formGetDirections\" action=\"http://maps.google.com/maps\" target=\"_blank\" method=\"get\"><input id=\"addr1\" name=\"daddr\" value=\"\" type=\"hidden\"><input id=\"FixedLocation\" name=\"FixedLocation\" value=\"" + address + "\" type=\"hidden\"><div id=\"AddressBoxLabel\" style=\"width: 280px;\">Start address</div><div style=\"width: 280px;\"><input value=\"\" id=\"addr2\" name=\"saddr\" value=\"\" style=\"width: 16em;\" onload=\"this.select()\" type=\"text\"></div><div style=\"width: 280px;padding-top:5px;\"><input value=\"Get Directions\" type=\"submit\" onclick=\"checkAddress(this);return document.returnValue;\"></div></form></div></div>";
  }

  /* parsePhone function concatenates area code and phone number */    
  function parsePhone(areacode, phone) {
    if(areacode!= "" && areacode!= null && phone != "" && phone != null) {
      var prefix = phone.slice(0,3);
      var number = phone.slice(3,7);
      return areacode + "." + prefix + "." + number;
    }
  }
    
    /* parseCommaSeparatedString function --     */
    /* takes a string of comma separated values, */
    /* returns an array of the values            */
    function parseCommaSeparatedString(str) { 
      var sOut = [];
      sOut = str.split(","); /* split the string into an array */
      for(var i = 0; i < sOut.length; i++) {
        sOut[i] = sOut[i].replace(" ", ""); /* eliminate any spaces */
      }
      return sOut; /* return the array */
    }
  /******************************************************/
  /*               end secondary functions              */
  /******************************************************/

  
    /* load function is called as the onload() event handler */
    /* this is the main function for the metro maps */
    function load() {

      if (GBrowserIsCompatible()) { /* the subsequent code depends on a compatible browser  */
        map = new GMap2(document.getElementById("map")); /* create a new map object */
        map.addControl(new GSmallMapControl()); /* add map controls and set the center and zoom */
        map.addControl(new GMapTypeControl());
        map.addControl(new GScaleControl()) ;
		
        /* center and zoom parameters are static variables declared in the embedded Javascript in the calling page */
        map.setCenter(new GLatLng(parseFloat(CENTER_LATTITUDE), parseFloat(CENTER_LONGITUDE)), parseFloat(ZOOMLEVEL));

        var aAreaCodes = []
        /* AREACODES is a static variable declared in the embedded Javascript in the calling page */
        aAreaCodes = parseCommaSeparatedString(AREACODES) /* convert the string into a comma separated array */
        var sAreaCodes = "|" + aAreaCodes.join("|"); /* convert the array back into a delimited string */
    
        /* load XML file of marker info */
        /* XMLFILEPATH is a static variable declared in the embedded Javascript in the calling page */
        GDownloadUrl(XMLFILEPATH, function(data, responseCode) {
          var xmlDoc = GXml.parse(data); /* parse the XML file to an XML document object */
          var oMarkers = xmlDoc.documentElement.getElementsByTagName("Tablejoin"); /* get the collection of marker nodes */
          /* declare local variables to hold instances of the marker attributes */
          var caption; 
          var officename;
          var address1;
          var address2;
          var city;
          var state;
          var zip;
          var phone;
          var fax;
          var email;
          var lat;
          var lng;
          /* for each marker, get the node values */
          /* begin For loop */
          for (i=0;i<oMarkers.length;i++) {
            /* get an object reference for the marker */
            var oMarker = xmlDoc.getElementsByTagName("Tablejoin")[i];
            
            /* to see if this marker is in the selected area */
            /* check if area code is in the areacodes[] array */
            var reAC = new RegExp(oMarker.getAttribute("PHONE_AREA_CD"))

            if(reAC.test(sAreaCodes)) {
              /* get object references for all the elements in the marker */
              /* then put the elements' text in variables */
              caption    = oMarker.getAttribute("NAME");// + " " + LOBNAME;
              officename = oMarker.getAttribute("NAME") + " " + LOBNAME + " Agency"; 
              address1   = oMarker.getAttribute("ADDR_1");
              address2   = oMarker.getAttribute("ADDR_2");
              city       = oMarker.getAttribute("CITY");
              state      = oMarker.getAttribute("STATE");
              zip        = oMarker.getAttribute("ZIP_CD");
              phone      = parsePhone(oMarker.getAttribute("PHONE_AREA_CD"),oMarker.getAttribute("PHONE_NUM"));
              fax        = parsePhone(oMarker.getAttribute("FAX_AREA_CD"),oMarker.getAttribute("FAX_NUM"));
              email      = oMarker.getAttribute("EMAIL_ADDR");
              lat        = oMarker.getAttribute("lat");
              lng        = oMarker.getAttribute("lng");
              
              /* create the elements of the text string that will be shown in the info window */
              pointHTML = new Object;
              if (caption != null)    { pointHTML.Caption    = caption; }    else { pointHTML.Caption    = ""; }
              if (officename != null) { pointHTML.Officename = officename; } else { pointHTML.Officename = ""; }
              if (address1 != null)   { pointHTML.Address1   = address1; }   else { pointHTML.Address1   = ""; }
              if (address2 != null)   { pointHTML.Address2   = address2; }   else { pointHTML.Address2   = ""; }
              if (city != null)       { pointHTML.City       = city; }       else { pointHTML.City       = ""; }
              if (state != null)      { pointHTML.State      = state; }      else { pointHTML.State      = ""; }
              if (zip != null)        { pointHTML.Zip        = zip; }        else { pointHTML.Zip        = ""; }
              if (phone != null)      { pointHTML.Phone      = phone; }      else { pointHTML.Phone      = ""; }
              if (fax != null)        { pointHTML.Fax        = fax; }        else { pointHTML.Fax        = ""; }
              if (email != null)      { pointHTML.Email      = email; }      else { pointHTML.Email      = ""; }
  
              /* check if we have been given lat and lng data in the XML file */
              if (lat != null && lng != null) {
              /* if we have lat and lng data, we can skip the Geocoding step */
                pointHTML.Lat = lat;
                pointHTML.Lng = lng;
                var point = new GLatLng(parseFloat(lat), parseFloat(lng)); /* create the point */
                var marker = new GMarker(point); /* create a marker */
                map.addOverlay(createMarker(point, pointHTML)); /* add the marker to the overlay */
              } else {
                /* assemble an address string to send to Geocode */
                var address = pointHTML.Address1 + " " + pointHTML.City + " " + pointHTML.State; 
                var location = getGeocode(address, pointHTML); /* geocode the address and create a marker */
              } /* end of inner if loop - lat/lng present */
            } /* end outer if loop - area code test */
          } /* end For loop */
        }); /* end GDownloadUrl callback function */
      } /* end if loop */
    } /* end load() function */