// Original script by Ken True with mods by Ken Challis and others
// Modified for NexStorm updates by Henkka Roblom
// Some added functionality by Jim McMurry
// Version 2.0
//
// No need to change anything in this script
// Everything is configured in NSconfig-inc.php
var nstotalupdates = 0;   
var nextmin = 0;
var lasttrac = 0;
var maptime = 0;
var graphtime = 0;
var prevmap = 0;
var prevtrac = 0;
var prevgraph = 0;
var mapcheck = 0;
var graphcheck = 0;
var savetime = 0;
var maprate = 0;
var tracrate = 0;
var graphrate = 0;
var timelaststrike = ""; 
var numplotted = 0;
var fntsize = "1.0em";
var currStrike = 1;
var cycles = 0;
now = new Date().getTime();
var countdowntime = now;
var countdowngraph = now;
var countdowntrac = now;
var mapnow = 0;
var graphnow = 0;
var tracnow = 0;

function ClearMap() {
	var i;
	var L = 1;
	for (i=1; i <= MaxLS; i++) {
		var chkspan = document.getElementById("LASTSTRIKE" + i);
		var toolspan = document.getElementById("TOOLTIP" + i);
		var toollink = document.getElementById("TOOLLINK" + i);
		if (chkspan.style.zIndex > 0) {
			var nowtime = new Date().getTime();
			var plottime = chkspan.getAttribute("lasttime");
			diff = ((nowtime - plottime)/1000).toFixed(0);	
			if (diff <= replot*1) {      // Need to re-order it
				var Lspan = document.getElementById("LASTSTRIKE" + L);
				Lspan = chkspan;
				var Tspan = document.getElementById("TOOLTIP" + L);				
				Tspan = toolspan;
				var Tlink = document.getElementById("TOOLLINK" + L);				
				Tlink = toollink;
				if (laststrikeChar == "") {  // We used numbers
					Lspan.innerHTML = L;
				} 
				L++;
			} else {   // Time expired - Make it disappear
				chkspan.style.zIndex = -5;
				toollink.style.left = "0px";
				toollink.style.top = "0px";
			}		
		}
	}
	currStrike = L;
	if (currStrike == 20) {
		currStrike = 1;
	}
}


function AddNewStrike(bearing, distance, type, stktime, font) {
        var httpRequest;

		url = path_to_plotstrikes + "?dir=" + bearing + "&dist=" + distance;
        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
            httpRequest = new XMLHttpRequest();
            if (httpRequest.overrideMimeType) {
                httpRequest.overrideMimeType('text/xml');
                // See note below about this line
            }
        } 
        else if (window.ActiveXObject) { // IE
            try {
                httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
                } 
                catch (e) {
                           try {
                                httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
                               } 
                             catch (e) {}
                          }
                                       }
        if (!httpRequest) {
            alert('Giving up :( Cannot create an XMLHTTP instance');
            return false;
        }
        httpRequest.onreadystatechange = function() { StrikeContents(httpRequest,bearing,distance,type,stktime,font); };
        httpRequest.open('GET', url, true);
        httpRequest.send('');
}


    function StrikeContents(httpRequest, bearing, distance, type, stktime, fsize) {
        if (httpRequest.readyState == 4) {
            if (httpRequest.status == 200) {
				if (! httpRequest.responseText.split('|')[0] == "") {
				// Plot the new Strike
					var xpos = httpRequest.responseText.split('|')[0].replace(/^\s+|\s+$/g, '') ;	// Trim trailing " " that was causing FF problems				
					var ypos = httpRequest.responseText.split('|')[1].replace(/^\s+|\s+$/g, '') ;	
					xpos = xpos - 5;   // Adjust to center on the nexstorm map
					ypos = ypos - 7;
					if ((xpos <= imgwidth) && (ypos <= imgheight)) {   // We only want the ones that will show on the map
						// Make sure the tool tip doesn't go off the right or bottom
						if (xpos > imgwidth - 85 ) {  // on right edge
							if ( ypos > imgheight - 90) {
								posit = "uleft";
							} else {
								posit = "lleft";
							} 												
						} else if (ypos > imgheight - 90) {  // on bottom edge
							if ( xpos > imgwidth - 85 ) {
								posit = "uleft";
							} else {
								posit = "uright";
							} 					
						} else  {
							posit = "lright";
						}	
						// Select image and color depending on strike type
						var typecolor;
						if (type == "+CG") {
							typecolor = pCGcolor;
							cloud = path_to_NSfiles + "pluscg.png";
						} else if (type == "-CG") {
							typecolor = nCGcolor;  
							cloud = path_to_NSfiles + "minuscg.png";
						} else if (type == "+IC") {
							cloud = path_to_NSfiles + "pluscc.png";
							typecolor = pICcolor;   
						} else {
							cloud = path_to_NSfiles + "minuscc.png";
							typecolor = nICcolor;
						}	
						var stkspan = document.getElementById("LASTSTRIKE" + currStrike);
						var nowtime = new Date().getTime();
						stkspan.setAttribute("lasttime",nowtime);   // Store the time that we plotted it
						stkspan.style.left = xpos + "px";
						stkspan.style.top = ypos + "px";
						stkspan.style.fontSize = fsize;
						stkspan.style.color = typecolor;
						stkspan.style.zIndex = 2;
						if (laststrikeChar == "") {
							thisstrikeChar = currStrike;     // Uses numbers
						} else {
							thisstrikeChar = laststrikeChar;
						}					
						stkspan.innerHTML = thisstrikeChar;	
						// Set up the tool tip feature	- this runs in a separate <a> otherwise we can't control the z-axis				
						var toollink = document.getElementById("TOOLLINK" + currStrike);
						toollink.style.left = xpos + "px";
						toollink.style.top = ypos + "px";
						toollink.className = "info " + posit;
						var toolspan = document.getElementById("TOOLTIP" + currStrike);
						toolspan.innerHTML = '<img src="' + cloud + '" alt=" Strike Type" /><br /><font color="' + typecolor + '">' + type + '</font><br />' + bearing + '&deg;<br />' + distance + ' ' + measure + '<br />' + stktime + '<br />';
						currStrike++;
						if (currStrike == MaxLS) {
							currStrike = 1;
						}
					}
				}
            }
        }
    }



function set_ajax_obsL( name, value ) {               
		var element = document.getElementById(name);
		if (! element ) { return; }   
		var lastobs = element.getAttribute("lastobs");
		element.setAttribute("lastobs",value);
		if (unescape(value) != unescape(lastobs)) {
		  element.innerHTML =  value;
		}
}


function convertalign(rawalign) {

		align = Math.floor(Number(rawalign) + Number(alignment));
		if (align > 360) {
		align = Number(align) - Number(360);
		}
		return align;
}


function bearDir ($beardir)
// Take wind direction value, return the
// text label based upon 16 point compass -- function by beeker425
//  see http://www.weather-watch.com/smf/index.php/topic,20097.0.html
{
   $bearlabel = new Array("N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW");
   return $bearlabel[Math.floor(((parseInt($beardir) + 11) / 22.5) % 16 )];
}

function subtractTime(time1, time2) {
	seconds = time1-time2; 
	minVar = Math.floor(seconds/60);  // The minutes
	secVar = seconds % 60;              // The balance of seconds
	if (secVar < 10) secVar = "0" + secVar;
	return therate = minVar + ":" + secVar;
}

function secs2Time(seconds) {  
	minVar = Math.floor(seconds/60);  // The minutes
	secVar = seconds % 60;              // The balance of seconds
	if (minVar < 10) minVar = "0" + minVar;	
	if (secVar < 10) secVar = "0" + secVar;
	return therate = minVar + ":" + secVar;
}

// Functions for graphic display of TRACReport.txt
function makeRequest(url) {
        var httpRequest;

        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
            httpRequest = new XMLHttpRequest();
            if (httpRequest.overrideMimeType) {
                httpRequest.overrideMimeType('text/xml');
                // See note below about this line
            }
        } 
        else if (window.ActiveXObject) { // IE
            try {
                httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
                } 
                catch (e) {
                           try {
                                httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
                               } 
                             catch (e) {}
                          }
                                       }
        if (!httpRequest) {
            alert('Giving up :( Cannot create an XMLHTTP instance');
            return false;
        }
        httpRequest.onreadystatechange = function() { alertContents(httpRequest); };
        httpRequest.open('GET', url, true);
        httpRequest.send('');
    }


    function alertContents(httpRequest) {

        if (httpRequest.readyState == 4) {
            if (httpRequest.status == 200) {
//set_ajax_obsL("debugline", "Ready State " + httpRequest.readyState  + " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Request Status " + httpRequest.status );			
				// Get the tracreport-data for AJAX
				if (! httpRequest.responseText.split('|')[0] == "") {  // The TRAC Report isn't empty
					document.getElementById("TRACHEAD").innerHTML = httpRequest.responseText.split('|')[0];
					document.getElementById("TRAC").innerHTML = httpRequest.responseText.split('|')[1];
					lasttrac = httpRequest.responseText.split('|')[4];
					countdowntrac = lasttrac * 1000;
					now = new Date().getTime();
					tracnow = (now - countdowntrac);				
				}				
			   maptime = httpRequest.responseText.split('|')[2];  // map time readable - 12:00pm etc
			   graphtime = httpRequest.responseText.split('|')[3];	   
			   mapupdatetime = httpRequest.responseText.split('|')[5];   // file time of the map
			   countdowntime= mapupdatetime * 1000;
			   countdowngraph = graphtime * 1000;
			   
				// Calculate Update Rates
				now = new Date().getTime();
				if (prevmap == 0) {      // first time through
					prevmap = mapupdatetime;	
					mapnow = (now - countdowntime);				
				} else if (! (mapupdatetime == prevmap)) {
					ClearMap();  // gets rid of last strike(s)
					document.getElementById("NEXMAP").src = path_to_image+"?"+ maptime;
					maprate = subtractTime(mapupdatetime, prevmap);		
					prevmap = mapupdatetime;
					mapnow = (now - countdowntime);				
					if ((showOptGraphic*1 > 0) && (! path_to_opt=="")) {
						document.getElementById("OPTGRAPHIC").src = path_to_opt+"?"+ maptime;
					}			
				}
				if (! showtime == "") {
					set_ajax_obsL("IMAGETIME", maptime);
				}
				if (prevgraph == 0) {
					prevgraph = graphtime;	
					graphnow = (now - countdowngraph);								
				} else if (! (graphtime == prevgraph)) {
					document.getElementById("NEXGRAPH").src = graphpath+"?"+graphtime;
					graphrate = subtractTime(graphtime, prevgraph);		
					prevgraph = graphtime;
					graphnow = (now - countdowngraph);												
				}
				if (prevtrac == 0) {
					prevtrac = lasttrac;
					tracnow = (now - countdowntrac);								
				} else if (! (lasttrac == prevtrac)) {
					tracrate = subtractTime(lasttrac, prevtrac);		
					prevtrac = lasttrac;
					tracnow = (now - countdowntrac);								
				}
				// For optional update rates
				set_ajax_obsL("MAPRATE", maprate);
				set_ajax_obsL("TRACRATE", tracrate);
				set_ajax_obsL("GRAPHRATE",graphrate);
				} else {
					//alert('No TRAC-data currently available.');
				}
        }
    }

function UpdateTimers() {
	// Map Counter
	now = new Date().getTime();
	difference = ((now - countdowntime - mapnow)/1000+1).toFixed(0);
	set_ajax_obsL("MAPTIME", "" + secs2Time(difference));
	
	// Graph Counter
	difference = ((now - countdowngraph - graphnow)/1000+1).toFixed(0);
	set_ajax_obsL("GRAPHTIME", "" + secs2Time(difference));
	
	// TRAC Counter
	difference = ((now - countdowntrac - tracnow)/1000+1).toFixed(0);
	set_ajax_obsL("TRACTIME", "" + secs2Time(difference));

	// Realtime File Counter
	set_ajax_obsL("LIVETIME", secs2Time(cycles+1));	

	if (cycles < updaterate -1) {
		cycles++;
		setTimeout("UpdateTimers()", 1000);
	} 
}


function NSajaxLoader(url) {
  if (document.getElementById) {
    var x = (window.ActiveXObject) ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(url);
  }
	if (x && ( nstotalupdates <= nsmaxupdates || nsmaxupdates > 0  )) { // got something back
    x.onreadystatechange = function() {
    try { if (x.readyState == 4 && x.status == 200) { 
		if (nsmaxupdates > 0 ) {nstotalupdates++; } // increment counter if needed 
			
		//Date
		set_ajax_obsL("DATE", "" + x.responseText.split(',')[2] + "." + x.responseText.split(',')[1] + "." + x.responseText.split(',')[0].substr(2, 2) + " " + x.responseText.split(',')[3] + ":" + x.responseText.split(',')[4] + ":" + x.responseText.split(',')[5] + "");

		//Since midnight
		set_ajax_obsL("MIDNIGHT", x.responseText.split(',')[15]);

		//Close since midnight
		set_ajax_obsL("CLOSEMIDNIGHT", x.responseText.split(',')[17]);

		//Total since X minute
		set_ajax_obsL("LMINTOTAL", x.responseText.split(',')[32]);

		//Close since X minute
		set_ajax_obsL("LMINCLOSE", x.responseText.split(',')[34]);
		
        //Rate
		NSLupdate = x.responseText.split(',')[39];          // High or Normal
        light = x.responseText.split(',')[24];              // Strikes
	    if ( light == undefined) {light = ""; }
        closelight = x.responseText.split(',')[26];		    // Close  
		if ( closelight == undefined) { closelight = ""; }		
			
		if (NSLupdate == "High") {
            light = "<font color=" + cautioncolor + ">" + light + "</font>";
			closelight = "<font color=" + cautioncolor + ">" + closelight + "</font>";
			graphpath = path_to_graph2;
			updaterate = Hupdaterate;
			checkmaps = Hcheckmaps;
		} else {
            light = "<font color=" + normcolor + ">" + light + "</font>";
            closelight = "<font color=" + normcolor + ">" + closelight + "</font>";
			graphpath = path_to_graph;
			updaterate = Lupdaterate;
			checkmaps = Lcheckmaps;
		}
		
		set_ajax_obsL("RATE", light);
		set_ajax_obsL("CLOSERATE", closelight);
		nsmaxupdates = maxview*(60/updaterate)+1;          // So they get the same viewing time even though the rate may have changed		
//set_ajax_obsL("debugline", updaterate);			

		//Peakrate
		set_ajax_obsL("PEAKRATE", "" + x.responseText.split(',')[22] + "/min");

		//Peaktime
		set_ajax_obsL("PEAKTIME", x.responseText.split(',')[23]);
 
 		//Last striketime
		set_ajax_obsL("LASTSTRTIME", x.responseText.split(',')[41]); 
		if (timelaststrike == "") {  // Don't want to plot it the first time around because it could be hours old
//			timelaststrike = x.responseText.split(',')[41]; 
		}
		
		// Plot  the last strike
		if(plotstrikes) {
			if( ! ( timelaststrike ==  x.responseText.split(',')[41]) || (! x.responseText.split(',')[41] == "---") ) {
				if (light*1 >= strikeLgRate*1) {
					fntsize = strikeLg;
				} else if (light*1 >= strikeMedRate*1) {
					fntsize = strikeMed;
				} else { 
					fntsize = strikeSm;
				}
				                                                       				// bearing,dist,type,font size
				dummyresult = AddNewStrike(x.responseText.split(',')[6], x.responseText.split(',')[7], x.responseText.split(',')[10], x.responseText.split(',')[41],fntsize); 
				timelaststrike = x.responseText.split(',')[41];  
			}
		}

		//Last strikedist
		set_ajax_obsL("LASTSTRDIS", x.responseText.split(',')[7]); 

		//Last striketype
		lasttype = x.responseText.split(',')[10];
		set_ajax_obsL("LASTSTRTYPE", lasttype); 

		//The Strike Type "Clouds"		
		if (showicon) {		
			if((x.responseText.split(',')[11] == 1) && (x.responseText.split(',')[24] > 0)) {
			document.getElementById("TYPE").src = path_to_NSfiles + "pluscg.png";
			}
			else if((x.responseText.split(',')[12] == 1) && (x.responseText.split(',')[24] > 0)) {
			document.getElementById("TYPE").src = path_to_NSfiles + "minuscg.png";
			}
			else if((x.responseText.split(',')[13] == 1) && (x.responseText.split(',')[24] > 0)) {
			document.getElementById("TYPE").src = path_to_NSfiles + "pluscc.png";
			}
			else if((x.responseText.split(',')[14] == 1) && (x.responseText.split(',')[24] > 0)) {
			document.getElementById("TYPE").src = path_to_NSfiles + "minuscc.png";
			}
			else {
			document.getElementById("TYPE").src = path_to_NSfiles + "nostr.png";
			}
			if(x.responseText.split(',')[24] == 0) {
			document.getElementById("TYPE").src = path_to_NSfiles + "nostr.png";
			}
		}	
		//Last strikedirec
		bear = x.responseText.split(',')[6];
		if(showbearing == 1) bearing = bearDir(bear);
		if(showbearing == 2) bearing = "" + bear + "" + bearword +"/" + bearDir(bear) +"";
		if(showbearing == 0) bearing = "" + bear + "" + bearword +"";
		set_ajax_obsL("LASTSTRDIREC", bearing);	

		// START DISTRIBUTION
		midnight = x.responseText.split(',')[15];
		xmin = x.responseText.split(',')[32];
		
		// The 1-min bar graphs
		if (bgraphs > 0) {  // These can't be running if not being used in NSDisplay or they'll stop the rest of the javascript
			//CG+ Today
			set_ajax_obsL("CGPTOD", x.responseText.split(',')[18]); 
			cgptod = x.responseText.split(',')[18];
			if(cgptod == 0) { cgptof = "0%"; } else { cgptof = "" + ((cgptod/midnight)*100).toFixed(0) + "%"; }
			set_ajax_obsL("CGPTODPREC", cgptof);
			cgptofbar = ((cgptod/midnight)*80).toFixed(0);
			document.getElementById("CGPTODBAR").src = path_to_NSfiles + 'BarGraph.php?a=' + cgptofbar + '&c=' + pCGcolor.substring(1);
	
			//CG- Today
			set_ajax_obsL("CG-TOD", x.responseText.split(',')[19]);
			cgmtod = x.responseText.split(',')[19];
			if(cgmtod == 0) { cgmtof = "0%"; } else { cgmtof = "" + ((cgmtod/midnight)*100).toFixed(0) + "%"; }
			set_ajax_obsL("CG-TODPREC", cgmtof);
			cgmtofbar = ((cgmtod/midnight)*80).toFixed(0);
			document.getElementById("CGMTODBAR").src = path_to_NSfiles + "BarGraph.php?a=" + cgmtofbar + '&c=' + nCGcolor.substring(1);

			//CC+ Today
			set_ajax_obsL("CCPTOD", x.responseText.split(',')[20]); 
			ccptod = x.responseText.split(',')[20];
			if(ccptod == 0) { ccptof = "0%"; } else { ccptof = "" + ((ccptod/midnight)*100).toFixed(0) + "%"; }
			set_ajax_obsL("CCPTODPREC", ccptof);
			ccptofbar = ((ccptod/midnight)*80).toFixed(0);
			document.getElementById("CCPTODBAR").src = path_to_NSfiles + "BarGraph.php?a=" + ccptofbar + '&c=' + pICcolor.substring(1);
	
			//CC- Today
			set_ajax_obsL("CC-TOD", x.responseText.split(',')[21]);
			ccmtod = x.responseText.split(',')[21];
			if(ccmtod == 0) { ccmtof = "0%"; } else { ccmtof = "" + ((ccmtod/midnight)*100).toFixed(0) + "%"; }
			set_ajax_obsL("CC-TODPREC", ccmtof);
			ccmtofbar = ((ccmtod/midnight)*80).toFixed(0);
			document.getElementById("CCMTODBAR").src = path_to_NSfiles + "BarGraph.php?a=" + ccmtofbar + '&c=' + nICcolor.substring(1);
		}
		
		// The x-min bar graphs
		if (bgraphs > 1) {  // These can't be running if not used in NSDisplay or they'll stop the rest of the javascript
			//CG+ Xmin
			set_ajax_obsL("CGPXMIN", x.responseText.split(',')[35]); 
			cgpxmin = x.responseText.split(',')[35];
			if(cgpxmin == 0) { cgpymin = "0%"; } else { cgpymin = "" + ((cgpxmin/xmin)*100).toFixed(0) + "%"; }
			set_ajax_obsL("CGPXMINPREC", cgpymin);
			cgpxminbar = ((cgpxmin/xmin)*80).toFixed(0);
			document.getElementById("CGPXMINBAR").src = path_to_NSfiles + "BarGraph.php?a=" + cgpxminbar + '&c=' + pCGcolor.substring(1);
 
 			//CG- Xmin
			set_ajax_obsL("CG-XMIN", x.responseText.split(',')[36]);
			cgmxmin = x.responseText.split(',')[36];
			if(cgmxmin == 0) { cgmymin = "0%"; } else { cgmymin = "" + ((cgmxmin/xmin)*100).toFixed(0) + "%"; }
			set_ajax_obsL("CG-XMINPREC", cgmymin);
			cgmxminbar = ((cgmxmin/xmin)*80).toFixed(0);
			document.getElementById("CGMXMINBAR").src = path_to_NSfiles + "BarGraph.php?a=" + cgmxminbar + '&c=' + nCGcolor.substring(1);

			//CC+ Xmin
			xmin = x.responseText.split(',')[32];
			set_ajax_obsL("CCPXMIN", x.responseText.split(',')[37]); 
			ccpxmin = x.responseText.split(',')[37];
			if(ccpxmin == 0) { ccpymin = "0%"; } else { ccpymin = "" + ((ccpxmin/xmin)*100).toFixed(0) + "%"; }
			set_ajax_obsL("CCPXMINPREC", ccpymin);
			ccpxminbar = ((ccpxmin/xmin)*80).toFixed(0);
			document.getElementById("CCPXMINBAR").src = path_to_NSfiles + "BarGraph.php?a=" + ccpxminbar + '&c=' + pICcolor.substring(1);

			//CC- Xmin
			set_ajax_obsL("CC-XMIN", x.responseText.split(',')[38]);
			ccmxmin = x.responseText.split(',')[38];
			if(ccmxmin == 0) { ccmymin = "0%"; } else { ccmymin = "" + ((ccmxmin/xmin)*100).toFixed(0) + "%"; }
			set_ajax_obsL("CC-XMINPREC", ccmymin);
			ccmxminbar = ((ccmxmin/xmin)*80).toFixed(0);
			document.getElementById("CCMXMINBAR").src = path_to_NSfiles + "BarGraph.php?a=" + ccmxminbar + '&c=' + nICcolor.substring(1);
		}

		//Uptime
		len = x.responseText.split(',')[40].length;
		set_ajax_obsL("UPTIME", x.responseText.split(',')[40].substr(0,len-3));
		
		// Update the map, trac and graph each minute
		thismin = x.responseText.split(',')[4];	
		
		if (thismin*1 >= nextmin*1) {
			//Calling the tracreportshort
			humm = makeRequest(path_to_tracajax + "?tractime=" + lasttrac + "&lang=" + lang + "&img=" + imgwidth);
			//nextmin = Number(thismin) + Number(checkmaps);
			nextmin = thismin*1 + checkmaps*1;  // Now can configure how often to check
			if (nextmin >= 60) {
					nextmin = nextmin - 60;
			}
//set_ajax_obsL("debugline", "Checking Maps " + thismin + " " + nextmin + " " + checkmaps);			
		}
		
		// Show the pausemessage instead of TRACheader if needed
		if (nsmaxupdates > 0 && nstotalupdates > nsmaxupdates-1) { /* chg indicator to pause message */
			set_ajax_obsL("TRACHEAD", langPauseMsg);
		}
 
		// For debugging
		//You can enable one of theese at time for checking updates. Appears in the topsection of Nexstormdisplay
		//debupdates = "" + nstotalupdates + "/" + nsmaxupdates + "";
		//set_ajax_obsL("UPDATES", "<br>Debug:<br/>" + nstotalupdates + "/ " + nsmaxupdates + "");


    } // END if (x.readyState == 4 && x.status == 200)
	} // END try
	catch(e){}  // Mike Challis added fix to fix random error: NS_ERROR_NOT_AVAILABLE
    } // x.onreadystatechange = function()
    x.open("GET", url, true);
    x.send(null);
	if ( (nsmaxupdates == 0) || (nstotalupdates < nsmaxupdates-1)) {
		setTimeout("NSajaxLoader(path_to_data + '?' + new Date().getTime())", updaterate*1000); // get new data 
		cycles = 0;
		UpdateTimers();
    }
  }  // end of 'got something back'
  
  
  
} //