var map;        //GMap object
var width;
var height;
var baseIcon;   // Base icon for all of our markers that specifies the shadow, icon, dimensions, etc.
/*var baseInfoWinMsg = "<span style=\"white-space:nowrap;\">" +
                "<span class=\"boldText\">WINMSGTITLE</span><BR/>" +
                "<span class=\"boldText\">Rainfall Amount:</span> RAIN_AMT_STR<BR/>" +
                "<span class=\"boldText\">YTD Rainfall:</span> YTD_STR<Br/>" +
                "<a href='javascript:showGraph(USERID, WINMSGGRAPHYEAR);'>See YTD graph here</a></span>" +
                "<br>"; 
*/
var chartImgSrc =  "/usprn/UserRainChartServlet?year=WINMSGGRAPHYEAR&userId=USERID";
chartLink = "<img src=\"" + chartImgSrc + "\" width=\"280\" height=\"230\" border=\"0\" alt=\"Loading chart...\" />";
var baseInfoWinMsg = "<span style=\"white-space:nowrap;\">" +
                "<span class=\"boldText\">WINMSGTITLE</span><BR/>" +
                "HOUR_OF_DAY"+
                "<span class=\"boldText\">Rainfall Amount:</span> RAIN_AMT_STR\"<BR/>" +
                "<span class=\"boldText\">YTD Rainfall:</span> YTD_STR\"<Br/>" +
                "COMMENTS"+
                "<p style=\"padding-top:5px;\">"+
                "<a href=\"javascript:showGraph(USERID, WINMSGGRAPHYEAR);\" \>" +
                chartLink +
                "</a></p>" +
                "<br/></span>"; 
var otherStationsBaseInfoWinMsg = "<span style=\"white-space:nowrap;\">" +
                "<span class=\"boldText\">WINMSGTITLE</span><BR/>" +
                "<span class=\"boldText\">Rainfall Amount:</span> RAIN_AMT_STR\"<BR/>" +
                "COMMENTS"+
                "<br/></span>"; 
var iconArr = new Array();  //Controls which icons are created so we can reuse those already in memory (see if this speeds up page load)
var sponsorArr;
var subsMarker;     //RainMapper marker
var swLat = 0;
var swLng = 0;
var neLat = 0;
var neLng = 0;

window.onload = function() {
    /*
    if (window.navigator.userAgent.indexOf("Opera") > -1 || 
        window.navigator.userAgent.indexOf("Safari") > -1) {
        window.setTimeout(loadDatesWithReadings, 2000);
    } else {
        loadDatesWithReadings();    
    }
    */
    setWidthHeight();  //RV20080707: Added function to adjust page to window's size
    setMapLayout(ORIG_WIDTH, ORIG_HEIGHT);   //RV20080707: Called here instead on maps.jsp
    loadMap();
    MM_showHideLayers2("loadingMapValsDiv", "", "show");
    //loadData();
//    if (window.loadData)  window.setTimeout(loadData, 2000);  //RV20080722: took off to call loadDataFunctions
    window.setTimeout(loadDataFunctions, 2000);
    
    loadEventListeners();
    loadSponsorData(theForm.elements["id"]);
    window.setTimeout(loadDatesWithReadings, 2000); //function in rainfallDates.js
    //if (FULL_SCREEN) window.onresize = function(){repaintMap()}; 

}
/*
 * This function will modify the neccesary html layers expanding their 
 * height and allowing end-users with big screens more room to see the map
 */
function setWidthHeight(){
//  var wrapDiv = MM_findObj("wrapper");
//  var contDiv = MM_findObj("container");
//  var subnDiv = MM_findObj("subnav");
//  var bodyDiv = MM_findObj("bodydiv");
//  var mapLDiv = MM_findObj("mapLeft");
//////  var screenHeight = window.screen.height;    //screen height
//////  contDiv.style.height = "" + (screenHeight - 230)+ "px";
//////  subnDiv.style.height = "" + (screenHeight - 310)+ "px";
//////  bodyDiv.style.height = "" + (screenHeight - 355)+ "px";    
////  var screenHeight = document.documentElement.clientHeight; // window height
////  contDiv.style.height = "" + (screenHeight - 60)+ "px";
////  subnDiv.style.height = "" + (screenHeight - 135)+ "px";
////  bodyDiv.style.height = "" + (screenHeight - 180)+ "px";    
//   //if IE5 then mapLeft width is 72%, for others it's 76%
////   var userBrowser = window.navigator.userAgent;
////   if (userBrowser.toLowerCase().indexOf("msie") >-1){
////     mapLDiv.style.width = "74%";
////     /*/mapLDiv.style.border = "thin solid red";*/
////   } else {
////     mapLDiv.style.width = "77%";
////     /*/mapLDiv.style.border = "thin solid black";*/
////   }
//  var userBrowser = window.navigator.userAgent;
//  if (userBrowser.toLowerCase().indexOf("msie") >-1) {
//      mapLDiv.style.position = "relative";
//  }
//  var winSizeObj = new StdWinSize();
//  setWindowSize(winSizeObj);
////  alert(userBrowser);
//  if (winSizeObj.width > 800){
//      if (userBrowser.toLowerCase().indexOf("msie") >-1){
//          mapLDiv.style.width =  "" + (winSizeObj.width-390) + "px";
//          mapLDiv.style.height =  "" + (winSizeObj.height-208) + "px";
//      }else if (userBrowser.toLowerCase().indexOf("safari") >-1){
//          mapLDiv.style.width =  "" + (winSizeObj.width-390) + "px";
//          mapLDiv.style.height =  "" + (winSizeObj.height-193) + "px";
//      }else{
//          mapLDiv.style.width = "" + (winSizeObj.width-360) + "px";
//          mapLDiv.style.height =  "" + (winSizeObj.height-201) + "px";
//      }
//  } else {
//    if (userBrowser.toLowerCase().indexOf("msie") >-1){
//        mapLDiv.style.width = "430px";
//        wrapDiv.style.width = "720px";
//    }else 
//        mapLDiv.style.width = "440px";
//  }
  var mapLDiv = MM_findObj("mapLeft");
  var winSizeObj = new StdWinSize();
  getWindowSize(winSizeObj);
//  alert(winSizeObj.width);
  if (winSizeObj.width > 1000)
        mapLDiv.style.width = "" + (winSizeObj.width-370) + "px";
  else 
        mapLDiv.style.width = "560px";

}


function getMaxWidthForMap(){
    var userBrowser = window.navigator.userAgent;
    if (userBrowser.toLowerCase().indexOf("msie") ==-1){
      return "100%";
    }else {
      return "98%";
    }
//  var winSizeObj = new StdWinSize();
//  setWindowSize(winSizeObj);
////  alert(winSizeObj.width);
//  var userBrowser = window.navigator.userAgent;
//  if (winSizeObj.width > 800)
//          return "100%";
//  else {
//      if (userBrowser.toLowerCase().indexOf("msie") >-1)
//        return "35em";
//      else
//        return "37em";
//  }
}
function getMaxWidthForFullScreenMap(){
  return "" + (document.documentElement.clientWidth - 350) + "px";
}
function getMaxHeightForMap(){
//  var screenHeight = document.documentElement.clientHeight;
//   var winSizeObj = new StdWinSize();
//   setWindowSize(winSizeObj);
////   return "" + (screenHeight-235) + "px";
//  var userBrowser = window.navigator.userAgent;
////  if (userBrowser.toLowerCase().indexOf("opera") >-1 || 
////      userBrowser.toLowerCase().indexOf("safari") >-1){
////    return "45em";
////  } else {
////      if (winSizeObj.height > 800)
////          return "" + (winSizeObj.height-235) + "px";
////      else 
////          return "45em";
////  }
//    if (winSizeObj.height > 600)
//        return "" + (winSizeObj.height-255) + "px";
//    else 
//        return "320px";
  var winSizeObj = new StdWinSize();
  getWindowSize(winSizeObj);
    if (winSizeObj.height > 600)
        return "" + (winSizeObj.height-230) + "px";
    else 
        return "345px";
}
function getMaxHeightForFullScreenMap(){
//  var winSizeObj = new StdWinSize();
//  getWindowSize(winSizeObj);
//    if (winSizeObj.height > 600)
//        return "" + (winSizeObj.height-80) + "px";
//    else 
//        return "345px";
  return "" + (document.documentElement.clientHeight - 80) + "px";
}

function loadEventListeners(){
    theForm.elements["id"].onkeyup = function(){   //on change of basin
            changeMapToBasin(this);
            loadSponsorData(this);
        };
    theForm.elements["id"].onchange = function(){   //on change of basin
            changeMapToBasin(this);
            loadSponsorData(this);
        };
    loadCalendarEvents();
}
function loadDatesWithReadings(){
    theForm.startDateSingle.value = theForm.reportDateStart.value;
    theForm.startDateRange.value = theForm.reportDateStart.value;
    theForm.endDateRange.value = theForm.reportDateEnd.value;
}
function highlightToday(){
}    


/****************** MAP FUNCTIONS  *******************/
function repaintMap(){
    //Repaint is setup now on an onresize event on maps.jsp
    //setMapLayout();
}

function loadMap(){
      if (GBrowserIsCompatible()) {
            //setMapLayout();
            var mapDiv = MM_findObj("map");
            map = new GMap2(document.getElementById("map"));
////            var mgr = new GMarkerManager(map);
            map.setCenter(new GLatLng(parseFloat(theForm.gmap_lat_y.value), parseFloat(theForm.gmap_lng_x.value)), 
                        parseInt(theForm.gmap_zoom.value));    //call this before anything is added to the map
            map.addControl(new GMapTypeControl());
            map.setMapType(getRealMapType(theForm.gmap_type.value));
            map.enableScrollWheelZoom();
            map.addControl(new GLargeMapControl());
            mapDiv.style.display = "none";
            
            loadIcon();
            addMapListeners();
            addRainMapperLocation();

     }
}
function displayMap(){
  var mapDiv = MM_findObj("map");
  mapDiv.style.display = "block";
  //zoomToNWSE();
  map.checkResize();
}
function loadDataFunctions(){
    if (window.loadData) loadData();
    displayMap();
//    addRainMapperLocation();

}
function setMapLayout(mapWidth, mapHeight){
    var obj = MM_findObj("map");
    obj.style.width = mapWidth;
    obj.style.height = mapHeight;
    
    obj = MM_findObj("mapItem");
    obj.style.width = mapWidth;
    obj.style.height = mapHeight;

}
function setMapLayout_OLD(){
    obj = MM_findObj("map");
    var mapWidth = document.documentElement.clientWidth - 250;
    var mapHeight = document.documentElement.clientHeight - 80;
    if (FULL_SCREEN) {
        obj.style.width = "" + mapWidth + "px";
        obj.style.height = "" + mapHeight + "px";
    }
}


// Create a base icon for all of our markers that specifies the shadow, icon
// dimensions, etc.
function loadIcon(){
    baseIcon = new GIcon();
    baseIcon.shadow = "../images/spacer.gif";
//    baseIcon.iconSize = new GSize(17, 13);
    baseIcon.shadowSize = new GSize(1, 1);
    baseIcon.iconAnchor = new GPoint(9, 34);
    baseIcon.infoWindowAnchor = new GPoint(9, 2);
    baseIcon.infoShadowAnchor = new GPoint(18, 25);
}

function addMapListeners(){
    GEvent.addListener(map, 'click', function(overlay, point) {
      if (overlay) {
            //do nothing
      } else if (point) {
            //map.recenterOrPanToLatLng(point);
          map.panTo(point);
          recordMapChange();
      }
    });
    GEvent.addListener(map, 'moveend', function() {
        recordMapChange();
    });
    GEvent.addListener(map, 'zoom', function(oldZoomLevel, newZoomLevel) {
        recordMapChange();
    });
    GEvent.addListener(map, 'maptypechanged', function() {
        recordMapChange();
    });
    
}

function recordMapChange(){
    var gLatLong = map.getCenter();
    theForm.gmap_lat_y.value = gLatLong.lat();
    theForm.gmap_lng_x.value = gLatLong.lng();
    theForm.gmap_zoom.value = map.getZoom();
    theForm.gmap_type.value = getStrMapType();
}
function recordMapChange_OLD(){
    var gPoint = map.getCenterLatLng();
    theForm.gmap_lat_y.value = gPoint.y;
    theForm.gmap_lng_x.value = gPoint.x;
    theForm.gmap_zoom.value = map.getZoomLevel();
    theForm.gmap_type.value = getStrMapType();
}
function getStrMapType(){
    var myMapType = map.getCurrentMapType();
    if (myMapType == G_SATELLITE_MAP) {
      return "satellite";
    }
    if (myMapType == G_NORMAL_MAP) {
      return "map";
    }
    if (myMapType == G_HYBRID_MAP) {
      return "hybrid";
    } 
}
function getRealMapType(inType){
    if (inType == "satellite") {
        return G_SATELLITE_MAP;
    } else if (inType == "hybrid") {
        return G_HYBRID_MAP;
    } else {
        return G_NORMAL_MAP;
    }
    
}
// Creates a marker whose info window displays the letter corresponding to
// the given index
function createMarker(point, rainfall, html, tmpMapIcon){
    return createMarkerAll(point, rainfall, html, tmpMapIcon, IMAGES_URL);
}
function createMarkerES(point, rainfall, html, tmpMapIcon){
    return createMarkerAll(point, rainfall, html, tmpMapIcon, EXTERNAL_SRCS_IMAGES_URL);
}

function createMarkerAll(point, rainfall, html, tmpMapIcon, imgsUrl){
    if (!iconExists(iconArr, tmpMapIcon.imgName, imgsUrl)){
        iconArr[tmpMapIcon.imgName] = tmpMapIcon;
        var icon = new GIcon(baseIcon);
        var imageSrc = imgsUrl + tmpMapIcon.imgName + IMAGES_EXT;
//        alert(imageSrc);
        icon.image = imageSrc;
        icon.iconSize = new GSize(tmpMapIcon.width, tmpMapIcon.height);
        iconArr[tmpMapIcon.imgName].gIcon = icon;
        MM_preloadImages(imageSrc);
    }
    var marker = new GMarker(point, iconArr[tmpMapIcon.imgName].gIcon);
//    alert(marker.getIcon().image);
    icon = null;
    if (marker){
    GEvent.addListener(marker, "click", function() {
        marker.openInfoWindowHtml(html);
    });
    GEvent.addListener(marker, 'infowindowopen', function(marker, point){
        setCenterPreIW();
    });
    GEvent.addListener(marker, 'infowindowclose', function(marker, point){
        resetCenterPostIW();
    });
    }
    updateSWNE(point);
//    updateStatus();
    
    return marker;
}
function zoomAndCenterMap(newLat, newLong, newZoom){    //To consistently center a zoom
    map.setCenter(new GLatLng(newLat, newLong), newZoom);
    recordMapChange();
}

//Indicates if imgName exists in iconArr
function iconExists(iconArr, imgName, imgUrl){
    return (typeof iconArr[imgUrl+imgName] != "undefined");
}

function getImageColor(rf){
    var output = "";
    if (rf < 0) output = "trace";
    else {
	output = (""+rf).replace("\\.", "_");
    }
    //alert(output);
    return output;
}

function openFullScreen(){
    theForm.target="_blank";
    theForm.screen_size_mode.value = "full";
    submitReportForm(); //so that it can validate and do it's thing...
    theForm.screen_size_mode.value = "regular";
    theForm.target = "_self";
}
function openInGoogleEarth(){
    //theForm.target="_blank";
    theForm.action = "../xml/kml.jsp?forceLoad=1";
    submitReportForm(); //so that it can validate and do it's thing...
    theForm.target = "_self";
    theForm.action = "maps.jsp";
}

var markerCnt = 0;
//function createInfoWinMsg(winMsgTitle, 
//            rain_amt_str, 
//            ytd_str, 
//            userId, 
//            winMsgGraphYear,
//            comments,
//            hour_of_day){
///*    var thisImg = chartImgSrc;
//    thisImg = thisImg.replace(/USERID/g, userId);
//    thisImg = thisImg.replace(/WINMSGGRAPHYEAR/g, winMsgGraphYear);
//    MM_preloadImages(thisImg);*/
//
//    var output = baseInfoWinMsg;
//    output = output.replace(/USERID/g, userId);
//    output = output.replace("WINMSGTITLE", winMsgTitle);
//    output = output.replace("RAIN_AMT_STR", rain_amt_str);
//    output = output.replace("YTD_STR", ytd_str);
//    output = output.replace(/WINMSGGRAPHYEAR/g, winMsgGraphYear);
//    var baseLine = "<span class=\"boldText\">TITLE</span>MESSAGE<BR/>";
//    if (typeof comments !='undefined' && comments != ""){
//        commentLine = baseLine.replace("TITLE", "Comments: ");
//        commentLine = commentLine.replace("MESSAGE", comments);
//        output = output.replace("COMMENTS", commentLine);
//    } else {
//        output = output.replace("COMMENTS", "");
//    }
//    if (typeof hour_of_day !='undefined' && hour_of_day != ""){
//        hodLine = baseLine.replace("TITLE", "Reading Time (24hr): ");
//        hodLine = hodLine.replace("MESSAGE", hour_of_day);
//        output = output.replace("HOUR_OF_DAY", hodLine);
//    } else {
//        output = output.replace("HOUR_OF_DAY", "");
//    }
////    alert(output);
//    return output;
//}
function createInfoWinMsg(winMsgTitle, 
            rain_amt_str, 
            ytd_str, 
            userId, 
            winMsgGraphYear,
            comments,
            hour_of_day){
  return allCreateInfoWinMsg(winMsgTitle, 
            rain_amt_str, 
            ytd_str, 
            userId, 
            winMsgGraphYear,
            comments,
            hour_of_day,
            baseInfoWinMsg);
            
}
function allCreateInfoWinMsg(winMsgTitle, 
            rain_amt_str, 
            ytd_str, 
            userId, 
            winMsgGraphYear,
            comments,
            hour_of_day,
            infoWinMsg){

/*    var thisImg = chartImgSrc;
    thisImg = thisImg.replace(/USERID/g, userId);
    thisImg = thisImg.replace(/WINMSGGRAPHYEAR/g, winMsgGraphYear);
    MM_preloadImages(thisImg);*/

    var output = infoWinMsg;
    output = output.replace(/USERID/g, userId);
    output = output.replace("WINMSGTITLE", winMsgTitle);
    output = output.replace("RAIN_AMT_STR", rain_amt_str);
    output = output.replace("YTD_STR", ytd_str);
    output = output.replace(/WINMSGGRAPHYEAR/g, winMsgGraphYear);
    var baseLine = "<span class=\"boldText\">TITLE</span>MESSAGE<BR/>";
    if (typeof comments !='undefined' && comments != ""){
        commentLine = baseLine.replace("TITLE", "Comments: ");
        commentLine = commentLine.replace("MESSAGE", comments);
        output = output.replace("COMMENTS", commentLine);
    } else {
        output = output.replace("COMMENTS", "");
    }
    if (typeof hour_of_day !='undefined' && hour_of_day != ""){
        hodLine = baseLine.replace("TITLE", "Reading Time (24hr): ");
        hodLine = hodLine.replace("MESSAGE", hour_of_day);
        output = output.replace("HOUR_OF_DAY", hodLine);
    } else {
        output = output.replace("HOUR_OF_DAY", "");
    }
//    alert(output);
    return output;
}

function createInfoWinMsgES(winMsgTitle, 
            rain_amt_str, 
            comments){
  return allCreateInfoWinMsg(winMsgTitle, 
            rain_amt_str, 
            "", 
            "", 
            "",
            comments,
            "",
            otherStationsBaseInfoWinMsg);
            
}



/* This function was created to display a running total of readings loaded on the map
 * DOES NOT WORK.
 */
//function updateStatus(){
//    if (markerCnt==10){
//      document.getElementById('loadingTotal').innerHTML= " (" +  (markerCnt++) + " readings)";
//      window.setTimeout(nothingDone,10);
//    }
//}
function nothingDone(){}

function changeMapToBasin(basinSelObj){
    var basin = selectedBasin(basinSelObj);
    if (map){
        zoomAndCenterMap(basin.geo_lat, basin.geo_long, basin.zoom);
    }
}
function selectedBasin(basinSelObj){
    return allBasins[basinSelObj.options[basinSelObj.selectedIndex].value];
}

function setCenterPreIW(){
    var gLatLong = map.getCenter();
    theForm.gmap_lat_pre_iw.value = gLatLong.lat();
    theForm.gmap_lng_pre_iw.value = gLatLong.lng();
}
function resetCenterPostIW(point){
    var gLatLong = new GLatLng(parseFloat(theForm.gmap_lat_pre_iw.value), parseFloat(theForm.gmap_lng_pre_iw.value));
    map.panTo(gLatLong);
}

function updateSWNE(point){
    if (swLat == 0 || swLat > point.lat()) swLat = point.lat();
    if (swLng == 0 || swLng > point.lng()) swLng = point.lng();
    if (neLat == 0 || neLat < point.lat()) neLat = point.lat();
    if (neLng == 0 || neLng < point.lng()) neLng = point.lng();
}
var newZoom;
function zoomToNWSE(){
    if (neLat > 0 && 
        swLat > 0 &&
        theForm.gmap_lat_y.value == (""+DEFAULT_LAT)
    ){
      var ne = new GLatLng(neLat, neLng);
      var sw = new GLatLng(swLat, swLng);
      var bounds = new GLatLngBounds(sw, ne);   
      newZoom = map.getBoundsZoomLevel(bounds);
      if (newZoom == 0) {
          newZoom = 4; //IE6- fix
//          alert("" + DEFAULT_LAT + "-" + DEFAULT_LONG);
          window.setTimeout("zoomAndCenterMap(DEFAULT_LAT, DEFAULT_LONG, newZoom)", 1000);
      } else 
        zoomAndCenterMap(bounds.getCenter().lat(), bounds.getCenter().lng(), newZoom);
    } else {
        zoomAndCenterMap(parseFloat(theForm.gmap_lat_y.value), parseFloat(theForm.gmap_lng_x.value), parseInt(theForm.gmap_zoom.value));
    }
}

/***************** END OF MAP FUNCTIONS *****************/

/****************** RAINMAPPER FUNCTIONS ***************/
function addRainMapperLocation(){
    //If a subsId is found then display marker, leave otherwise
    if (theForm.subsId.value == ""
        || theForm.subs_lat_y.value == ""
        || theForm.subs_lng_x.value == "") return;
    
    var gLatLong = new GLatLng(parseFloat(theForm.subs_lat_y.value), parseFloat(theForm.subs_lng_x.value));
    if (subsMarker) map.removeOverlay(subsMarker);

    //add it to map
    subsMarker = new GMarker(gLatLong);
    map.addOverlay(subsMarker);

    map.addControl(new RainMapperMarkerControl());


}

/*** Elements for showing user-friendly zoom options **/

// A RainMapperMarkerControl is a GControl that hides the RainMapper marker

// We define the function first
function RainMapperMarkerControl() {
}

// To "subclass" the GControl, we set the prototype object to
// an instance of the GControl object
RainMapperMarkerControl.prototype = new GControl();

// Creates a one DIV for each of the buttons and places them in a container
// DIV which is returned as our control element. We add the control to
// to the map container and return the element for the map class to
// position properly.
RainMapperMarkerControl.prototype.initialize = function(map) {
  var container = document.createElement("div");

  var hideMarkerDiv = document.createElement("div");
  this.setButtonStyle_(hideMarkerDiv);
  container.appendChild(hideMarkerDiv);
  hideMarkerDiv.appendChild(document.createTextNode("Hide RainMapper"));
  GEvent.addDomListener(hideMarkerDiv, "click", function() {
    subsMarker.hide();
  });

  var showMarkerDiv = document.createElement("div");
  this.setButtonStyle_(showMarkerDiv);
  container.appendChild(showMarkerDiv);
  showMarkerDiv.appendChild(document.createTextNode("Show RainMapper"));
  GEvent.addDomListener(showMarkerDiv, "click", function() {
    subsMarker.show();
  });

  map.getContainer().appendChild(container);
  return container;
}


// By default, the control will appear in the top left corner of the
// map with 7 pixels of padding.
RainMapperMarkerControl.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(67, 7));
}

// Sets the proper CSS for the given button element.
RainMapperMarkerControl.prototype.setButtonStyle_ = function(button) {
  button.style.textDecoration = "underline";
  button.style.color = "#000000";
  button.style.backgroundColor = "white";
  button.style.font = "0.8em Arial";
  button.style.border = "1px solid black";
  button.style.padding = "2px";
  button.style.marginBottom = "3px";
  button.style.textAlign = "center";
  button.style.width = "8em";
  button.style.cursor = "pointer";
}
/****************** END OF RAINMAPPER FUNCTIONS ***************/


/****************** AJAX FUNCTIONS ***************/
function loadXML(url, queryString, functName) {
    var req = GXmlHttp.create();
    if (req) {
        req.onreadystatechange = functName;
        req.open("POST", url, true);
        req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        req.send(queryString);
    } else {
        alert("Your browser will not load the data.");
    }
    return req;
}
function isRequestReady(req){
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            return 1;
        } else {
            return 0;
        }
    } else {
        return -1;
    }
}
function endXml(){
    if (typeof req != 'undefined') req = null;
}
/****************** END OF AJAX FUNCTIONS ***************/


/**************** SPONSOR FUNCTIONS *******************/
function loadSponsorData(basinSelObj){
    var basin = selectedBasin(basinSelObj);
    var params = buildSponsorParams(basin);
    var url = "../sharedfiles/sponsorLoader.jsp";
    var sponsorsDiv = MM_findObj("sponsorsDiv");
    removeChildren(sponsorsDiv);
    if (basin.hasSponsors()){
        var req = loadXML(url, params, function(){processSponsorData(req)});
    }
}
function buildSponsorParams(basin){
    return basin.sponsorsAsURIParams();
}
function processSponsorData(req) {
    if (req) {
        var status = isRequestReady(req);
        if (status >= 0){
            if (status == 1) {
                // ...processing statements go here...
                var xml = req.responseXML;
                showSponsors(xml);
            } else {
                alert("There was a problem retrieving the sponsor data.");
            }
            endXml();
        }
    } 
}
function showSponsors(xml){
    var sponsorsDiv = MM_findObj("sponsorsDiv");
    if (xml.getElementsByTagName("sponsors").length == 0) {
        return;
    }
    addSponsorThanksToSpDiv(sponsorsDiv);
    var sponsors = xml.getElementsByTagName("sponsor");
    loadSponsors(sponsors, sponsorsDiv);
}
function removeChildren(mainNode){
    if (mainNode.hasChildNodes()){
        while (mainNode.firstChild){
            //The list is LIVE so it will re-index each call
            mainNode.removeChild(mainNode.firstChild);
        }
    }
}

//Load sponsors in sponsorsDiv. 
//For each sponsors it creates a <div> that includes an <a> and <img> tags
function loadSponsors(sponsors, sponsorsDiv){
    for (var i=0; i < sponsors.length; i++){
        var imgInfo = sponsors[i].getElementsByTagName("image")[0]; //only one image per station
        var imgObj = new MiscImage(imgInfo.getAttribute("src"), imgInfo.getAttribute("width"), 
                           imgInfo.getAttribute("height"), imgInfo.getAttribute("url"), 
                           imgInfo.getAttribute("alt"));
        addSponsorImgToSpDiv(imgObj, sponsorsDiv, sponsors[i].getAttribute("spid"));
    }
}
function addSponsorImgToSpDiv(imgObj, sponsorsDiv, spid){
    var spdiv = document.createElement("spid" + spid);
    spdiv.innerHTML = imgObj.buildLinkedImg();
    sponsorsDiv.appendChild(spdiv);
}
function addSponsorThanksToSpDiv(sponsorsDiv){
    var spdiv = document.createElement("spthanks");
    spdiv.innerHTML = "<div style=\"padding-bottom: 1em;padding-top:0.5em;\"><h2>Thanks to the following sponsor(s):</h2></div>";
    sponsorsDiv.appendChild(spdiv);
}
/**************** END OF SPONSOR FUNCTIONS *******************/


/********** MAP ICON CLASS *********/
function MapIcon(imgName, width, height){
    this.imgName = imgName;
    this.width = width;
    this.height = height;
    this.gIcon;
}
function MapIcon_toString(){
    return "Name=" + this.imgName + "&width=" + this.width
        + "&height=" + this.height + "&GIcon=" + this.gIcon.toString();
}
MapIcon.prototype.toString = MapIcon_toString;
/*************************/

/******* MISCIMG CLASS ********/
function MiscImage(src, width, height, url, alt){
    this.src = src;
    this.width = width;
    this.height = height;
    this.url = url;
    this.alt = alt;
}
function MiscImage_toString(){
    return "Src=" + this.src 
        + "&width=" + this.width
        + "&height=" + this.height + 
        + "&src=" + this.src + 
        + "&url=" + this.url
        + "&alt=" + this.alt;
}
function MiscImage_buildLinkedImg(imgTag){
    var baseSponsorImg = "<a href=\"IMG_URL\" target=\"_blank\"><img src=\"IMG_SRC\" alt=\"ALT_TEXT\" border=\"0\"/></a>";
    var output = baseSponsorImg;
    output = output.replace("IMG_URL", this.url);
    output = output.replace("IMG_SRC", this.src);
    output = output.replace("ALT_TEXT", this.alt);
    return output;
}

MiscImage.prototype.toString = MiscImage_toString;
MiscImage.prototype.buildLinkedImg = MiscImage_buildLinkedImg;
/******* END OF MISCIMG CLASS ********/


/******* BASIN CLASS **************/
var allBasins = new Array();
function Basin(basin_id, geo_lat, geo_long, zoom, sponsors){
    this.basin_id = basin_id;
    this.geo_lat = geo_lat;
    this.geo_long = geo_long;
    this.zoom = zoom;
    this.sponsors = sponsors;
}
function Basin_sponsorsAsURIParams(){
    var params = "nicknames=";
    var value = this.sponsors;
    if (value != "") {
        params += encodeURIComponent(value);
    }
    return params;
}
function Basin_hasSponsors(){
    return this.sponsors != "";
}

Basin.prototype.sponsorsAsURIParams = Basin_sponsorsAsURIParams;
Basin.prototype.hasSponsors = Basin_hasSponsors;
/******* END OF BASIN CLASS **************/


/*************** CALENDAR FUNCTIONS *******************/


function loadCalendarEvents(){
    calIcon = MM_findObj('calicon1');
    calIcon.onclick = function(){
        showSingleDateCalendar('startDateSingle', 'popcal1', theForm.popcal1);
    }
    calIcon = MM_findObj('calicon2');
    calIcon.onclick = function(){
        showStartDateRangeCalendar('startDateRange', 'endDateRange', 'popcal2', theForm.popcal2);
    }
    calIcon = MM_findObj('calicon3');
    calIcon.onclick = function(){
        showEndDateRangeCalendar('startDateRange', 'endDateRange', 'popcal3', theForm.popcal3);
    }
    theForm.startDateSingle.onfocus = function(){
        showSingleDateCalendar('startDateSingle', 'popcal1', this);
    }
    theForm.popcal1.onclick = function(){
        showSingleDateCalendar('startDateSingle', 'popcal1', this);
    }
    theForm.startDateRange.onfocus = function(){
        showStartDateRangeCalendar('startDateRange', 'endDateRange', 'popcal2', this);
    }
    theForm.popcal2.onclick = function(){
        showStartDateRangeCalendar('startDateRange', 'endDateRange', 'popcal2', this);
    }
    theForm.endDateRange.onfocus = function(){
        showEndDateRangeCalendar('startDateRange', 'endDateRange', 'popcal3', this);
    }
    theForm.popcal3.onclick = function(){
        showEndDateRangeCalendar('startDateRange', 'endDateRange', 'popcal3', this);
    }
}
/*************** END OF CALENDAR FUNCTIONS *******************/