    /** most of my google maps learning has come from both the API:
        http://code.google.com/apis/maps/
        and this website maintained by Mike Williams:
        http://econym.googlepages.com/index.htm
    */
    var map;
    var shaveKml = "http://ewp.nssl.noaa.gov/projects/shave/data/shave.kml";
    var myCenter = new GLatLng(35.181459, -97.440279);
    //warnings overlay
    var warningKml = "http://ewp.nssl.noaa.gov/projects/shave/data/NWS_Warnings.kml";
    var myWarnings = [];
    var myWatches = [];
    var showWarnings = false;
    var warnTimeStr;
    //SPC log
    var showSpcLog = false;
    var spcLog = "http://ewp.nssl.noaa.gov/projects/shave/data/spclog.csv";
    var nwsTors = [];
    var nwsHail = [];
    var nwsWind = [];
/**    //radar map overlay
    myRadarTime = "http://ewp.nssl.noaa.gov/projects/shave/data/tiles/radartime";
    var tileCopy = new GCopyrightCollection("");
    tileCopy.addCopyright(new GCopyright(1,new GLatLngBounds(new GLatLng(21,-121),new GLatLng(51,-67)),1,"Radar data provided by NOAA/NSSL"));
    var tileRadar = new GTileLayer(tileCopy,0,8);
    tileRadar.getTileUrl = function (a,b) { return "http://ewp.nssl.noaa.gov/projects/shave07/data/tiles/" + b + "/" + a.x + "-" + a.y + ".png"; }
    tileRadar.isPng = function () { return true; }
    tileRadar.getOpacity = function () { return 0.65; }
    var radarMap = new GMapType([G_NORMAL_MAP.getTileLayers()[0],tileRadar],G_NORMAL_MAP.getProjection(),"Radar", {errormessage: "Ooops!", maxResolution:8, minResolution:0, alt:"Radar reflectivity"});
    var refBar = new GScreenOverlay("http://wdssii.nssl.noaa.gov/geotiff/colormaps/Reflectivity.gif", new GScreenPoint(575,785), new GScreenPoint(0,0), new GScreenSize(513,12));
    var refBarOn = false; */
    //marker list (so we can do things like add zoom buttons)
    var myMarkers = [];
    var numMarkers = 0;
    //table and summary html variables
    var tableHTML = ""; //table html
    var summary = ""; //summary text
    var totalReports = 0 //total # of reports
    var bigstone = -1; //largest hail stone size
    var bigmeasured = ""; //text for largest hail message
    var numHail = 0; //# of hail reports
    var numHailm = 0; //# of measured reports
    var hailSVR = 0; //# of severe hail reports
    var hailSIG = 0; //# of sig-severe hail reports
    var hailSized = 0; //# of sized hail reports
    var numWind = 0; //# of wind reports
    var numWindm = 0; //# of measured wind reports
    var wnddmg = 0; //# of wind damage reports
    var nullWind = 0; //# of no wind damage reports
    var numFlood = 0; //# of flood reports
    var numNoFlood = 0; //# of no flood reports
    var nowUTCStr; //time UTC string


    //base icon for report marker overlays
    var myIcon = new GIcon();
    myIcon.iconSize = new GSize(20,20);
    myIcon.iconAnchor = new GPoint(10,10);
    myIcon.infoWindowAnchor = new GPoint(18,2);

    //base icon for SPC log reports
    var spcIconTor = new GIcon();
    spcIconTor.iconSize = new GSize(32,32);
    spcIconTor.iconAnchor = new GPoint(15,15);
    spcIconTor.infoWindowAnchor = new GPoint(16,0);
    spcIconTor.image = "http://ewp.nssl.noaa.gov/projects/shave/data/icons/NWS_tornado.png";
    var spcIconHail = new GIcon();
    spcIconHail.iconSize = new GSize(32,32);
    spcIconHail.iconAnchor = new GPoint(15,15);
    spcIconHail.infoWindowAnchor = new GPoint(16,0);
    spcIconHail.image = "http://ewp.nssl.noaa.gov/projects/shave/data/icons/NWS_hail.png";
    var spcIconWind = new GIcon();
    spcIconWind.iconSize = new GSize(32,32);
    spcIconWind.iconAnchor = new GPoint(15,15);
    spcIconWind.infoWindowAnchor = new GPoint(16,0);
    spcIconWind.image = "http://ewp.nssl.noaa.gov/projects/shave/data/icons/NWS_wind.png";
   
    function load() {
      var container = document.getElementById("map");
      if (GBrowserIsCompatible()) {
        map = createBaseMap(container,1200,800,myCenter,4,true,true,true);
/**        GEvent.addListener(map, 'maptypechanged', function () {
            if (map.getCurrentMapType() == radarMap) {
              map.addOverlay(refBar);
              GDownloadUrl(myRadarTime,process_time);
              refBarOn = true;
            } else if (refBarOn) {
              map.removeOverlay(refBar);
              refBarOn = false;
              document.getElementById("radarvalidtime").innerHTML = "";
            }
        });
        map.addMapType(radarMap);*/
        parseWarnings(warningKml);
        parseKML(shaveKml);
        parseSpcLog(spcLog);
//        setInterval('refreshRadarTile()',180000);
        setInterval('parseKML(shaveKml)',300000);
        setInterval('parseWarnings(warningKml)',120000);
        setInterval('parseSpcLog(spcLog)',180000);
/**        var proj = G_NORMAL_MAP.getProjection();
        var coord = new GLatLng(21.0938,-66.0938);
        tilePoint = proj.fromLatLngToPixel(coord,8);
        var tileCoord = new GPoint();
        tileCoord.x = Math.floor(tilePoint.x / 256);
        tileCoord.y = Math.floor(tilePoint.y / 256);
        document.getElementById("test").innerHTML = "X=" + tileCoord.x + " Y=" + tileCoord.y + "<br>"; */
      } else {
        alert('Google Maps is not compatible with this browswer');
      }
    }

    //mouse zooming variables and functions
    //mouse wheel zooming variables
    var wheelZooming = false; //is the user currently zooming?
    var mouseLatLng; //current LatLng of the mouse

    //gets the current LatLng of the mouse
    function mouseMove(mousePt) {
      mouseLatLng = mousePt;
    }

    //zoom in/out at current mouse LatLng
    function wheelZoom(event) {
      if (wheelZooming) { return; } //don't try to zoom when already zooming
      wheelZooming = true; //let me know I am zooming
      //can I cancel the event?  if so, prevent the action
      if (event.cancelable) {
        event.preventDefault();
      }
      map.closeInfoWindow(); //close an open info window (if open)
      //zoom appropiately depending on wheel action
      if ((event.detail || -event.wheelDelta) < 0) {
        window.setTimeout(function() {
        map.zoomIn(mouseLatLng,true,true);
        wheelZooming = false;
        },200);
      } else {
        window.setTimeout(function() {
        map.zoomOut(mouseLatLng,true,true);
        wheelZooming = false;
        },200);
      }
    }
    //end mouse zooming functions/variables
    
    //process file to get current radar time
    function process_time(doc) {
      lines = doc.split(/\n/);
      var curRadarTime = new Date();
      curRadarTime.setUTCDate(parseInt(lines[0].slice(6,8)));
      var month = parseInt(lines[0].slice(4,6)) - 1;
      curRadarTime.setUTCMonth(month);
      curRadarTime.setUTCFullYear(parseInt(lines[0].slice(0,4)));
      curRadarTime.setUTCHours(parseInt(lines[0].slice(9,11)));
      curRadarTime.setUTCMinutes(parseInt(lines[0].slice(11,13)));
      curRadarTime.setUTCSeconds(parseInt(lines[0].slice(13)));
      document.getElementById("radarvalidtime").innerHTML = "Radar products valid at " + curRadarTime.toUTCString();
    }

    //get current date
    function getTime() {
      var now = new Date();
      now = now.toUTCString();
      document.getElementById('shaveValidTime').innerHTML = "SHAVE data valid at: " + now;
      return now;
    }

    //refresh radar tiles if overlay is enabled
    function refreshRadarTile() {
       if (map.getCurrentMapType() == radarMap) {
         map.setMapType(G_NORMAL_MAP);
         map.setMapType(radarMap);
         GDownloadUrl(myRadarTime,process_time);
       }
    }
 
    //reset tracking variables
    function reset() {
      for (var i=0;i<myMarkers.length;i++){
        map.removeOverlay(myMarkers[i]);
      }
      myMarkers = [];
      numMarkers = 0;
      tableHTML = ""; //table html
      summary = ""; //summary text
      totalReports = 0 //total # of reports
      validReport = false; //do we have a sized hail or non-NULL wind report
      bigstone = -1; //largest hail stone size
      bigmeasured = ""; //text for largest hail message
      numHail = 0; //# of hail reports
      numHailm = 0; //# of measured reports
      hailSVR = 0; //# of severe hail reports
      hailSIG = 0; //# of sig-severe hail reports
      hailSized = 0; //# of sized hail reports
      numWind = 0; //# of wind reports
      numWindm = 0; //# of measured wind reports
      wnddmg = 0; //# of wind damage reports
      nullWind = 0; //# of no wind damage reports
      numFlood = 0; //# of flood reports
      numNoFlood = 0; //# of no flood reports
    }

    //turn warnings off/on
    function toggleWarnings() {
      if (showWarnings) {
        for (var w = 0; w < myWatches.length; w++) {
          map.removeOverlay(myWatches[w]);
        }
        for (var w = 0; w < myWarnings.length; w++) {
          map.removeOverlay(myWarnings[w]);
        }
        showWarnings = false;
        document.getElementById("warnings").value= "Show Watches/Warnings";
        document.getElementById("warntimestr").innerHTML = ""
      } else {
        for (var w = 0; w < myWatches.length; w++) {
          map.addOverlay(myWatches[w]);
        }
        for (var w = 0; w < myWarnings.length; w++) {
          map.addOverlay(myWarnings[w]);
        }
        showWarnings = true;
        document.getElementById("warnings").value= "Hide Watches/Warnings";
        document.getElementById("warntimestr").innerHTML = warnTimeStr;
      }
    }

    //turn SPC reports off/on
    function toggleSpcLog() {
      if (showSpcLog) {
        for (var t=0;t<nwsTors.length;t++){
          map.removeOverlay(nwsTors[t]);
        }
        for (var h=0;h<nwsHail.length;h++){
          map.removeOverlay(nwsHail[h]);
        }
        for (var w=0;w<nwsWind.length;w++){
          map.removeOverlay(nwsWind[w]);
        }
        showSpcLog = false;
        document.getElementById("spcLog").value = "Show NWS Reports";
        document.getElementById("spcLogInfo").innerHTML = "";
      } else {
        for (var w=0;w<nwsWind.length;w++){
          map.addOverlay(nwsWind[w]);
nwsWind[w].getLatLng().lat() + " " + nwsWind[w].getLatLng().lng() + "<br>";
        }
        for (var h=0;h<nwsHail.length;h++){
          map.addOverlay(nwsHail[h]);
nwsHail[h].getLatLng().lat() + " " + nwsHail[h].getLatLng().lng() + "<br>";
        }
        for (var t=0;t<nwsTors.length;t++){
          map.addOverlay(nwsTors[t]);
nwsTors[t].getLatLng().lat() + " " + nwsTors[t].getLatLng().lng() + "<br>";
        }
        showSpcLog = true;
        document.getElementById("spcLog").value = "Hide NWS Reports";
        document.getElementById("spcLogInfo").innerHTML = "Data courtesy of <a href=\"http://www.spc.naoa.gov\">the Storm Prediction Center</a>(TOR-" + nwsTors.length + "; HAIL-" + nwsHail.length + "; WIND-" + nwsWind.length + ")";
      }
    }

//function to zoom in on points; x=lat, y=lng
function zoomOnReport(i) {
  if (map.getCurrentMapType().getMaximumResolution() < 15) {
    map.setZoom(map.getCurrentMapType().getMaximumResolution());
  } else {
    map.setZoom(15);
  }
  GEvent.trigger(myMarkers[i], "click");
  document.location.href = "#map";
}

//reset the zoom of the map
function resetMap() {
  map.returnToSavedPosition();
}

function value(e) {
  a = GXml.value(e);
  a = a.replace(/^\s*/,"");
  a.replace(/\s*$/,"");
  return a;
}

function parseDescrip(descrip, index) {
  lines = descrip.split(/\n/);
  //parse the description
  for (l=0;l<lines.length;l++) {
    var parts  = lines[l].split(/:\s/);
    if (lines[l].search(/Type/) != -1) {
      type = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/Start/) != -1) {
      start = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/End/) != -1) {
      end = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/Est max/) != -1) {
      maxe = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/Est avg/) != -1) {
      avge = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/Meas max/) != -1) {
      maxm = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/Meas avg/) != -1) {
      avgm = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/Est wind/) != -1) {
      winde = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/Meas wind/) != -1) {
      windm = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/Damage/) != -1) {
      wdmg = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/City/) != -1) {
      city = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/County/) != -1) {
      county = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/State/) != -1) {
      state = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/CWA/) != -1) {
      cwa = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/lat/) != -1) {
      lat = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/lng/) != -1) {
      lng = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/Flood types/) != -1) {
      floodtypes = parts[1].replace(/<br>/, "");
    } else if (lines[l].search(/No wind damage/i) != -1) {
      wdmg = "NONE";
      type = "WIND";
      windm="NULL";
      winde="NULL";
    }
  }
  //filter through report for summary and table data
  totalReports++;
  var genRow = false;
  var label = "";
  if (type == "HAIL") {
    numHail++;
    if (maxe.search(/NO|UNKNOWN/) == -1) {
      hailSized++;
      if (maxm == "NULL" || (maxm != "NULL" && maxe > maxm)) {
        genRow = true;
        label = "E" + maxe + " INCH";
        maxe = parseFloat(maxe);
        if (maxe <= 1) {
          color = "lime";
        } else if (maxe > 1 && maxe < 2) {
          color = "yellow";
        } else if (maxe >= 2 && maxe <= 3) {
          color = "red";
        } else if (maxe > 3) {
          color = "magenta";
        } else {
          color = "gray";
        }
        if (maxe >= 2) {
          hailSIG++;
          hailSVR++;
        } else if (maxe >= 0.75) {
          hailSVR++;
        }
        if (maxe > bigstone) {
          bigstone = maxe;
          bigmeasured = "was not";
        }
      } else {
        genRow = true;
        numHailm++;
        label = "M" + maxm + " INCH";
        maxm = parseFloat(maxm);
        if (maxm <= 1) {
          color = "lime";
        } else if (maxm > 1 && maxm < 2) {
          color = "yellow";
        } else if (maxm >= 2 && maxm <= 3) {
          color = "red";
        } else if (maxm > 3) {
          color = "magenta";
        } else {
          color = "gray";
        }
        if (maxm >= 2) {
          hailSIG++;
          hailSVR++;
        } else if (maxe >= 0.75) {
          hailSVR++;
        }
        if (maxm > bigstone) {
          bigstone = maxm;
          bigmeasured = "was";
        }
      }
    } else {
      return maxe;
    }
  } else if (type == "WIND") {
    if (windm.search(/NULL/) == -1) {
      numWindm++;
      numWind++;
      if (wdmg.search(/NONE|NULL/i) == -1) { wnddmg++; }
      label = "M" + windm;
      if (parseFloat(windm) < 58) {
        color = "aqua";
      } else if (parseFloat(windm) >= 58) {
        color = "blue";
      }
      genRow = true;
    } else if (winde.search(/NULL/) == -1) {
      numWind++;
      if (wdmg.search(/NONE|NULL/i) == -1) { wnddmg++; }
      label = "E" + winde;
      if (parseFloat(winde) < 58) {
        color = "aqua";
      } else if (parseFloat(winde) >= 58) {
        color = "blue";
      }
      genRow = true;
    } else if (wdmg.search(/NONE|NULL/i) == -1) {
      wnddmg++;
      numWind++;
      label = "Damage";
      color = "gray";
      genRow = true;
    } else {
      nullWind++;
      return "No wind";
    }
  } else if (type=="FLOOD") {
    if (floodtypes.search(/NULL|NONE/i) != -1) {
      numNoFlood++;
      return "No flood";
    }
    label = "Flood";
    genRow = true;
    numFlood++;
  }
  if (genRow) {
    var row = document.getElementById("datatable").insertRow(1);
    var typeCell = row.insertCell(0);
    typeCell.innerHTML = "<b>" + type + "</b>";
    if (type == "HAIL") {
      typeCell.bgColor = "lawngreen";
    } else if (type == "WIND") {
      typeCell.bgColor = "dodgerblue";
    } else if (type == "FLOOD") {
      typeCell.bgColor = "darkgreen";
    }
    var startCell = row.insertCell(1);
    startCell.innerHTML = start;
    var endCell = row.insertCell(2);
    endCell.innerHTML = end;
    var magCell = row.insertCell(3);
    if (type == "FLOOD") {
      magCell.innerHTML = "";
      magCell.bgColor = "white";
    } else {
      magCell.innerHTML = "<b>" + label + "</b>";
      magCell.bgColor = color;
    }
    var cityCell = row.insertCell(4);
    cityCell.innerHTML = city;
    var countyCell = row.insertCell(5);
    countyCell.innerHTML = county;
    var stateCell = row.insertCell(6);
    stateCell.innerHTML = state;
    var cwaCell = row.insertCell(7);
    cwaCell.innerHTML = cwa;
    var latCell = row.insertCell(8);
    //cheap sprintf for lat
    point = lat.search(/\./) + 4;
    latd = lat.slice(0,point);
    latCell.innerHTML = latd;
    var lonCell = row.insertCell(9);
    //cheap sprintf for lon
    point = lng.search(/\./) + 4;
    lngd = lng.slice(0,point);
    lonCell.innerHTML = lngd;
    var zoomCell = row.insertCell(10);
    zoomCell.innerHTML = "<input type=\"submit\" value=\"Zoom!\" onClick=\"zoomOnReport(" + index + ");\">";
  }
  return label;
}

function setBigStone() {
  if (bigstone == -1) {
    bigreport = "no report";
  } else {
    bigreport = bigstone + " inches and it " + bigmeasured + " measured";
  }
}

function setSummary() {
  nowUTCStr = getTime();
  if (hailSized > 0 || numWind > 0 || numFlood > 0) {
    summary = "SHAVE has " + totalReports + " hail, wind and/or flood reports as of " + nowUTCStr + ":<br>" + numHail + " hail related reports | " + hailSized + " \"sized\" hail reports | " + hailSVR + " severe (0.75\"+) hail reports | " + hailSIG + " significant-severe (2\"+) hail reports<br>" + numWind + " wind reports | " + wnddmg + " wind damage reports | " + numWindm + " measured wind reports | " + nullWind + " reports of no wind/wind damage<br>" + numFlood + " flood reports | " + numNoFlood + " no flood reports<br>Largest hail report thus far: "  + bigreport + "<br>";
  } else if (totalReports > 0) {
    summary = "SHAVE is operating but has no reports of hail or wind damage or flooding (though we may have nulls or reports of the questionable nature).<br>Stay tuned...<br>";
  } else {
    summary = "SHAVE is not operating today (...maybe later!)<br>";
  }
}

function createMarker(point,icon,descrip,html) {
  var title = parseDescrip(descrip,numMarkers);
  myIcon.image = icon;
  var marker = new GMarker(point,{icon:myIcon,title:title});
  if (!html) {
    GEvent.addListener(marker,"click",function() {
      map.panTo(marker.getPoint());
      marker.openInfoWindow(descrip);
    });
  } else {
    GEvent.addListener(marker,"click",function() {
        map.panTo(marker.getPoint());
        marker.openInfoWindowHtml(descrip);
    });
  }
  myMarkers[numMarkers] = marker
  numMarkers++;
  return marker;
}


function parseKML(myKML){
  for (numRow=0;numRow<document.getElementById('datatable').rows.length;row++) {
    document.getElementById('datatable').deleteRow(numRow);
  }
  if (numMarkers != 0) { reset(); }
  //kick off table script
  var row=document.getElementById('datatable').insertRow(0);
  var reportCell = row.insertCell(0);
  reportCell.innerHTML = "REPORT";
  var startCell = row.insertCell(1);
  startCell.innerHTML = "START TIME";
  var endCell = row.insertCell(2);
  endCell.innerHTML = "END TIME";
  var magCell = row.insertCell(3);
  magCell.innerHTML = "MAG";
  var cityCell = row.insertCell(4);
  cityCell.innerHTML = "CITY";
  var countyCell = row.insertCell(5);
  countyCell.innerHTML = "COUNTY";
  var stateCell = row.insertCell(6);
  stateCell.innerHTML = "STATE";
  var cwaCell = row.insertCell(7);
  cwaCell.innerHTML = "CWA";
  var latCell = row.insertCell(8);
  latCell.innerHTML = "LAT";
  var lonCell = row.insertCell(9);
  lonCell.innerHTML = "LON";
  var zoomCell = row.insertCell(10);
  //Read the KML
  var request = GXmlHttp.create();
  request.open("GET", myKML, true);
  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      var xmlDoc = GXml.parse(request.responseText);
      //loop the reports in the KML
      var reports = xmlDoc.documentElement.getElementsByTagName("Placemark");
      for (var i = 0; i < reports.length; i++) {
        //obtain name of point; will skip if "The NWC"
        var name = value(reports[i].getElementsByTagName("name")[0]);
        if (name.search(/The NWC/) != -1) {
          continue;
        }
        //obtain icon, coordinate and description of the report
        var icon = value(reports[i].getElementsByTagName("href")[0]);
        var coord = GXml.value(reports[i].getElementsByTagName("coordinates")[0]);
        coord = coord.replace(/\s+/g," "); // tidy the whitespace
        coord = coord.replace(/^ /,"");    //tremove possible leading whitespace
        coord = coord.replace(/, /,",");   // tidy the commas
        var latlng = coord.split(",");
        var point = new GLatLng(parseFloat(latlng[1]),parseFloat(latlng[0]));
        var descrip = value(reports[i].getElementsByTagName("description")[0]);
        var marker = createMarker(point,icon,descrip,false);
        map.addOverlay(marker);
      }
      setBigStone();
      setSummary();
      document.getElementById("summary").innerHTML = summary;
    }
  }
  request.send(null);
}

  //parse the warnings kml
  function parseWarnings(warningKML) {
    if (showWarnings) { //remove old warnings
      for (var w = 0; w < myWatches.length; w++) {
        map.removeOverlay(myWatches[w]);
      }
      for (var w = 0; w < myWarnings.length; w++) {
        map.removeOverlay(myWarnings[w]);
      }
    }
    myWarnings = [];
    myWatches = [];
    //Read the KML
    var request = GXmlHttp.create();
    request.open("GET", warningKML, true);
    request.onreadystatechange = function() {
      if (request.readyState == 4) {
        var xmlDoc = GXml.parse(request.responseText);
        //loop the watches/warnings in the kml
        var folders = xmlDoc.documentElement.getElementsByTagName("Folder");
        //loop folders of watches/warnings
        var name = xmlDoc.documentElement.getElementsByTagName("name");
        warnTimeStr = value(name[0]);
        for (var f = 0; f < folders.length; f++) {
          var warnType = value(folders[f].getElementsByTagName("name")[0]);
          if (warnType == "Warnings: Flash Flood" || warnType == "Warnings: Special Marine" || warnType.search("SPC") != -1 || warnType.search("Probabilities") != -1 || warnType.search("Outlook") != -1) { 
            //skip FFWs and MCDs
            continue;
          } else if (warnType.search("Warnings") != -1) {
            var watchWarn = "WARNING";
          } else if (warnType.search("Watches") != -1) {
            var watchWarn = "WATCH";
          }
          if (warnType.search("Tornado") != -1) {
            var type = "TORNADO";
          } else if (warnType.search("Severe T-Storm") != -1){
            var type = "SEVERE THUNDERSTORM";
          }
          var warnings = folders[f].getElementsByTagName("Placemark");
          for (var w = 1; w < warnings.length; w+=2) {
            var v = w-1;
            var myTabs = [];
            var isPds = false;
            var text = "";
            var summaryHtml = "";
            var info = "";
            var name = value(warnings[v].getElementsByTagName("name")[0]);
            if (name == " ") { continue; } //skip blank placemark
            var text = GXml.value(warnings[v].getElementsByTagName("description")[0]) + "</pre><input type=\"button\" value=\"Clear Warning Text\" onClick=\"clearWarningText();\"/><hr>";
            if (text.search("PARTICULARLY DANGEROUS SITUATION") != -1) {
              isPds = true;
            }
            var coords = GXml.value(warnings[w].getElementsByTagName("coordinates")[0]);
            coords=coords.replace(/\s+/g," "); // tidy the whitespace
            coords=coords.replace(/^ /,"");    // remove possible leading whitespace
            coords=coords.replace(/, /,",");   // tidy the commas

            var path = coords.split(" ");
            var latlngs = [];
            var bounds = new GLatLngBounds();
            for (var c = 0; c < path.length-1; c++){
              var stuff = path[c].split(/,/);
              var point = new GLatLng(parseFloat(stuff[1]),parseFloat(stuff[0]));
              latlngs.push(point);
              bounds.extend(point);
            }
            createWatchWarn(latlngs,bounds,watchWarn,type,text,isPds);
          }
        }
      }
        if (showWarnings) { //update immediately if displayed
        for (var w = 0; w < myWatches.length; w++) {
          map.addOverlay(myWatches[w]);
        }
        for (var w = 0; w < myWarnings.length; w++) {
          map.addOverlay(myWarnings[w]);
        }
        document.getElementById("warntimestr").innerHTML = warnTimeStr;
      }
    }
    request.send(null);
  }

  //create warning/watch polygon
  function createWatchWarn(points,bounds,watchWarn,type,text,pds) {
    var polygon;
    if (watchWarn == "WARNING") {
      if (type == "TORNADO") {
        polygon = new GPolygon(points,"#FF0000",1,1,"#FF0000",0.5,{clickable:true});
        myWarnings.unshift(polygon);
      } else if (type == "SEVERE THUNDERSTORM") {
        polygon = new GPolygon(points,"#FF9900",1,1,"#FF9900",0.5,{clickable:true});
        myWarnings.push(polygon);
      }
      GEvent.addListener(polygon,"click",function() {
        showWarningText(text);
      });
    } else if (watchWarn == "WATCH") {
      if (pds) {
        if (type == "TORNADO") {
           polygon = new GPolyline(points,"#990000",4,1,{clickable:true});
        } else if (type == "SEVERE THUNDERSTORM") {
           polygon = new GPolyline(points,"#000099",4,1,{clickable:true});
        }
      } else {
        if (type == "TORNADO") {
          polygon = new GPolyline(points,"#FF0000",4,1,{clickable:true});
        } else if (type == "SEVERE THUNDERSTORM") {
          polygon = new GPolyline(points,"#0000FF",4,1,{clickable:true});
        }
     }
     myWatches.push(polygon);
     GEvent.addListener(polygon,"click",function() {
       showWarningText(text);
     });
    }
  }

  //process SPC log
  function process_spc(doc) {
    lines = doc.split("\n");
    var reportType;
    for (var l=0;l<lines.length-1;l++){
      var cols = lines[l].split(",");
      if (lines[l].match(/^Time/)){
        if (cols[1] == "F-Scale") {
          reportType = "TOR";
        } else if (cols[1] == "Speed") {
          reportType = "WIND";
        } else {
          reportType = "HAIL";
        }
        continue;
      }
      var lat = parseFloat(cols[5]);
      var lng = parseFloat(cols[6]);
      var point = new GLatLng(lat,lng);
      createSpcMarker(reportType,point,cols);
    }
    if (showSpcLog) { //update immediately if set to display
      for (var w=0;w<nwsWind.length;w++){
        map.addOverlay(nwsWind[w]);
      }
      for (var h=0;h<nwsHail.length;h++){
        map.addOverlay(nwsHail[h]);
      }
      for (var t=0;t<nwsTors.length;t++){
        map.addOverlay(nwsTors[t]);
      }
      document.getElementById("spcLogInfo").innerHTML = "<img src=\"http://maps.google.com/mapfiles/kml/pal4/icon44.png\">--NWS report (hover for type).  Data courtesy of <a href=\"http://www.spc.naoa.gov\">the Storm Prediction Center</a>(TOR-" + nwsTors.length + "; HAIL-" + nwsHail.length + "; WIND-" + nwsWind.length + ")";
    }
  }
  //add SPC reports
  function parseSpcLog(spcLog){
    if (showSpcLog) { //remove old reports
      for (var t=0;t<nwsTors.length;t++){
        map.removeOverlay(nwsTors[t]);
      }
      for (var h=0;h<nwsHail.length;h++){
        map.removeOverlay(nwsHail[h]);
      }
      for (var w=0;w<nwsWind.length;w++){
        map.removeOverlay(nwsWind[w]);
      }
    }
    nwsTors = [];
    nwsHail = [];
    nwsWind = [];
    GDownloadUrl(spcLog,process_spc);
  }

  //SPC marker creator
  function createSpcMarker(type,point,cols){
     var unit = "";
     var size = cols[1];
     if (type == "WIND"){
       if (size == "UNK") {
         size = "UNK";
         unit = ""
       } else {
         size = parseInt(size);
         unit = "MPH";
       }
     } else if (type == "HAIL") {
       size = parseFloat(size) / 100;
       unit = "INCHES";
     }
     var html = "Time: " + cols[0] + " UTC<br>Mag: " + size + " " + unit + "<br>City: " + cols[2] + "<br>County: " + cols[3] + "<br>State: " + cols[4] + "<br>Comments: " + cols[7];
     var marker;
     if (type == "TOR") {
       marker = new GMarker(point,{icon:spcIconTor,title:type});
     } else if (type == "HAIL") {
       marker = new GMarker(point,{icon:spcIconHail,title:type});
     } else if (type == "WIND") {
       marker = new GMarker(point,{icon:spcIconWind,title:type});
     }
     GEvent.addListener(marker,"click",function(){
       marker.openInfoWindowHtml(html,{maxWidth:150});
     });
     if (type == "TOR") {
       nwsTors.push(marker);
     } else if (type == "WIND") {
       nwsWind.push(marker);
     } else {
       nwsHail.push(marker);
     }
  }
    //display warning text
    function showWarningText (text) {
      document.getElementById("warnText").innerHTML = text;
      document.location.href = "#warnText";
    }
    //clear the warning text
    function clearWarningText() {
      document.getElementById("warnText").innerHTML = "";
      document.location.href = "#map";
    }

