// <![CDATA[

// Special thanks to: Kevin Reed http://www.tnetweather.com/
// Kevin was the first to decode the clientraw in PHP
// Special thanks to: Pinto http://www.joske-online.be/
// Pinto wrote the basic AJAX code for this page!
// Cheerfully borrowed from Tom at CarterLake.org and adapted by
// Ken True - Saratoga-weather.org  21-May-2006
// --- added flash-green on data update functions - Ken True  24-Nov-2006
//
// --- Version 2.00 - 13-Dec-2006 -- Ken True -repackaged AJAX function, added metric/english units
//     also included Mike Challis' counter script to display seconds since last update and error
//     handling for the fetch to fix to fix random error: NS_ERROR_NOT_AVAILABLE
//     Mike's site: http://www.carmosaic.com/weather/index.php
//     Thanks to FourOhFour on wxforum.net ( http://skigod.us/ ) for replacing all the
//     x.responseText.split(' ')[n] calls with a simple array lookup.. much better speed and
//     for his streamlined version of getUVrange.
// --- Version 2.01 - 17-Dec-2006 -- Corrected cloud height calculation
// --- Version 2.02 - 20-Dec-2006 -- added unescape to set_ajax_obs comparison for lastobs
// --- Version 2.03 - 07-Jan-2006 -- added wind m/s or km/h for metric variables
// --- Version 2.04 - 08-Jan-2006 -- use epoch time for get (thanks to johnnywx on WD forum)
//                                   so a numeric time without HTMLencoded characters is used
// --- Version 2.05a - 30-Jan-2006 -- added new 'anti-NaN' check from johnnywx to make sure full
//                                   clientraw.txt is read by looking for
//                                   '12345' at start and '!!' at end of record
// --- Version 2.06 - 24-Jun-2007 -- added '/' as delimiter for currentcond
// --- Version 2.07 - 21-Sep-2007 -- added support for dynamic thermometer.php display refresh
// --- Version 2.08 - 07-Nov-2007 -- added useMPH to force wind display in Miles-per-hour and
//                                   added optional Wind-Rose, optional new current icon display graphics
// --- Version 2.09 - 23-Dec-2007 -- added maxupdates feature, new ajax variables from K. Reed www.tnetweather.com
// --- Version 2.10 - 18-Jan-2008 -- fixed icon=34 for ra1.jpg
// --- Version 2.11 - 21-Feb-2008 -- added icon=35 for windyrain.gif/.jpg
// --- Version 2.12 - 07-Mar-2008 -- added fix for 'flashing icon/thermometer' from Jim at jcweather.us
// --- Version 2.13 - 20-Mar-2008 -- adapted for use w/custom data-feed client for wview (http://www.wviewweather.com)
//                                   including get_element_value() function to read data from the generate html/php
//                                   by D. Ballard
//
// for updates to this script, see http://saratoga-weather.org/scripts-WD-AJAX.php
// announcements of new versions will be on weather-watch.com and wxforum.net

// -- begin settings --------------------------------------------------------------------------
var flashcolor = '#00CC00'; // color to flash for changed observations RGB
var flashtime  = 2000;      // miliseconds to keep flash color on (2000 = 2 seconds);
var reloadTime = 15000;     // reload AJAX conditions every 15 seconds (= 15000 ms)
var maxupdates = 0;	    // Maxium Number of updates allowed (set to zero for unlimited)
                            // maxupdates * reloadTime / 1000 = number of seconds to update
var clientrawFile = '/clientdata.txt'; // location of clientraw.txt relative to this page on website
var ajaxLoaderInBody = false; // set to true if you have <body onload="ajaxLoader(..."
var imagedir = './ajax-images';  // place for wind arrows, rising/falling arrows, etc.
var useunits = 'E';         // 'E'=USA(English) or 'M'=Metric
var useKnots = false;       // set to true to use wind speed in Knots (otherwise 
			    // wind in km/hr for Metric or mph for English will be used.
var useMPS   = false;       // set to true for meters/second for metric wind speeds, false= km/h
var useMPH   = false;       // set to true to force MPH for both English and Metric units
var useFeet  = false;       // set to true to force Feet for height in both English and Metric
var showUnits = true;       //  set to false if no units are to be displayed
var thermometer = './thermometer.php'; // script for dynamic thermometer PNG image (optional)
// optional settings for the Wind Rose graphic in ajaxwindiconwr as wrName + winddir + wrType
var wrName   = 'wr-';       // first part of the graphic filename (followed by winddir to complete it)
var wrType   = '.gif';      // extension of the graphic filename
var wrHeight = '58';        // windrose graphic height=
var wrWidth  = '58';        // windrose graphic width=
var wrCalm   = 'wr-calm.gif';  // set to full name of graphic for calm display ('wr-calm.gif')
// -- end of settings -------------------------------------------------------------------------

// -- language settings -- you don't need to customize this area if you are using English -----

var langPauseMsg = 'Updates paused - reload page to start'; // substitute this for ajaxindicator when
                             // maxupdates has been reached and updating paused.

var langMonths = new Array ( "January","February","March","April","May",
			"June","July","August","September","October","November","December");

var langDays = new Array ( "Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun");	

var langBaroTrend = new Array (
 "Steady", "Rising Slowly", "Rising Rapidly", "Falling Slowly", "Falling Rapidly");

var langBeaufort = new Array ( /* Beaufort 0 to 12 in array */
 "Calm", "Light air", "Light breeze", "Gentle breeze", "Moderate breeze", "Fresh breeze",
 "Strong breeze", "Near gale", "Gale", "Strong gale", "Storm",
 "Violent storm", "Hurricane"
);

var langWindDir = new Array( /* used for alt and title tags on wind dir arrow and wind direction display */
	"N", "NNE", "NE", "ENE", 
	"E", "ESE", "SE", "SSE", 
	"S", "SSW", "SW", "WSW", 
	"W", "WNW", "NW", "NNW");

var langWindCalm = 'Calm';
var langGustNone = 'None';
var langWindFrom = 'Wind from '; /* used on alt/title tags on wind direction arrow*/

var langBaroRising = 'Rising %s '; /* used for trend arrow alt/title tags .. %s marks where value will be placed */
var langBaroFalling = 'Falling %s ';
var langBaroPerHour = '/hour.'; /* will be assembled as rising/falling + value + uom + perhour text */

var langThermoCurrently = 'Currently: '; /* used on alt/title tags for thermometer */
var langThermoMax     = 'Max: ';
var langThermoMin     = 'Min: ';

var langTempRising = 'Warmer %s '; /* used for trend arrow alt/title tags .. %s marks where value will be placed */
var langTempFalling = 'Colder %s ';
var langTempLastHour = ' than last hour.';

var langHumRising = '%s more humid '; /* used for trend arrow alt/title tags .. %s marks where value will be placed */
var langHumFalling = '%s less humid ';
var langHumLastHour = ' than last hour.';
// -- end of language settings ----------------------------------------------------------

// --- you don't need to customize the stuff below, the actions are controlled by the 
//  settings above.  

var ie4=document.all;
var browser = navigator.appName;
var counterSecs = 0;  // for MCHALLIS counter script from weather-watch.com (adapted by K. True)
var updates = 0;		// update counter for limit by maxupdates
var lastajaxtimeformat = 'unknown'; //used to reset the counter when a real update is done
var doTooltip = 0;   // set to 1 to have ajaxed variable names appear as tooltips (except for graphics)

// handle setup options for units-of-measure and whether to show them at all
var uomTemp = '&deg;F';
var uomWind = ' mph';
var uomBaro = ' inHg';
var uomRain = ' in';
var uomHeight = ' ft';
var dpBaro = 3;
var dpRain = 2;


function ajax_set_units( units ) {
  useunits = units;
  if (useunits != 'E') { // set to metric
	uomTemp = '&deg;C';
	uomWind = ' km/h';
	uomBaro = ' hPa';
	uomRain = ' mm';
	uomHeight = ' m';
	dpBaro = 1;
	dpRain = 1;
  }
  if(useKnots) { uomWind = ' kts'; }
  if(useMPS)   { uomWind = ' m/s'; }
  if(useMPH)   { uomWind = ' mph'; }
  if(useFeet)  { uomHeight = ' ft'; }
  if (! showUnits) {
	uomTemp = '';
	uomWind = '';
	uomBaro = '';
	uomRain = '';
	uomHeight = '';
  }
}

ajax_set_units(useunits);

// utility functions to navigate the HTML tags in the page
function get_ajax_tags ( ) {
// search all the span tags and return the list with class="ajax" in it
//
  if (ie4 && browser != "Opera") {
    var elem = document.body.getElementsByTagName('span');
	var lookfor = 'className';
  } else {
    var elem = document.getElementsByTagName('span');
	var lookfor = 'class';
  }
     var arr = new Array();
	 var iarr = 0;
     for(var i = 0; i < elem.length; i++) {
          var att = elem[i].getAttribute(lookfor);
          if(att == 'ajax') {
               arr[iarr] = elem[i];
               iarr++;
          }
     }

     return arr;
}

function reset_ajax_color( usecolor ) {
// reset all the <span class="ajax"...> styles to have no color override
      var elements = get_ajax_tags();
	  var numelements = elements.length;
	  for (var index=0;index!=numelements;index++) {
         var element = elements[index];
	     element.style.color=usecolor;
 
      }
}

function set_ajax_obs( name, value ) {
// store away the current value in both the doc and the span as lastobs="value"
// change color if value != lastobs

		var element = document.getElementById(name);
		if (! element ) { return; } // V1.04 -- don't set if missing the <span id=name> tag
		var lastobs = element.getAttribute("lastobs");
		element.setAttribute("lastobs",value);
		if (value != unescape(lastobs)) {
          	  element.style.color=flashcolor;
		  if ( doTooltip ) { element.setAttribute("title",'AJAX tag '+name); }
		  element.innerHTML =  value; // moved inside to fix flashing issue (Jim at jcweather.us)
		}
}

function set_ajax_uom( name, onoroff ) {
// this function will set an ID= to visible or hidden by setting the style="display: "
// from 'inline' or 'none'

		var element = document.getElementById(name);
		if (! element ) { return; } 
		if (onoroff) {
          element.style.display='inline';
		} else {
          element.style.display='none';
		}
}

// --- end of flash-green functions

function windDir ($winddir)
// 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
{
   $windlabel = new Array("N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW");
   return $windlabel[Math.floor(((parseInt($winddir) + 11) / 22.5) % 16 )];
}

function windDirLang ($winddir)
// 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
{
   return langWindDir[Math.floor(((parseInt($winddir) + 11) / 22.5) % 16 )];
}


// utility functions to handle conversions from clientraw data to desired units-of-measure
// DLB - heavily modified for my purposes. Those interested in metric values may/will need
// to change accordingly to return the correct value.
//
function convertTemp ( rawtemp ) {
	if (useunits == 'E') {
		return (rawtemp * 1.0);
	} else { 
		return( (5 * rawtemp)/9 - 32.0);
	}
}

function convertWind  ( rawwind ) {
	return(rawwind * 1.0); //DLB leave in native VPro2
}

function convertBaro ( rawpress ) {
	   return (rawpress * 1.0); //DLB leave in native Vpro2
}

function convertRain ( rawrain ) {
	   return (rawrain * 1.0); 
}

// DLB - Wview alarmd only feeds "current" information. Generated values such as daily rain, high wind, etc
// are generated with a different process and not available to us. By letting htmlgend put these values in a
// generated file, we can read these values with this function, so that we can use the values in other places.
//
function get_element_value( name ) {
// get the current value in the doc

		var element = document.getElementById(name);
		if (! element ) { return; } // V1.04 -- don't get if missing the <span id=name> tag
		var value = element.innerHTML;

		return value;
}

function ajax_get_barotrend(btrnd) {
// routine from Anole's wxsticker PHP (adapted to JS by Ken True)
// input: trend in hPa or millibars
//   Barometric Trend(3 hour)

// Change Rates
// Rapidly: =.06 inHg; 1.5 mm Hg; 2 hPa; 2 mb
// Slowly: =.02 inHg; 0.5 mm Hg; 0.7 hPa; 0.7 mb

// 5 conditions
// Rising Rapidly
// Rising Slowly
// Steady
// Falling Slowly
// Falling Rapidly

// Page 52 of the PDF Manual
// http://www.davisnet.com/product_documents/weather/manuals/07395.234-VP2_Manual.pdf
// figure out a text value for barometric pressure trend
   if ((btrnd >= -0.7) && (btrnd <= 0.7)) { return(langBaroTrend[0]); }
   if ((btrnd > 0.7) && (btrnd < 2.0)) { return(langBaroTrend[1]); }
   if (btrnd >= 2.0) { return(langBaroTrend[2]); }
   if ((btrnd < -0.7) && (btrnd > -2.0)) { return(langBaroTrend[3]); }
   if (btrnd <= -2.0) { return(langBaroTrend[4]); }
  return(btrnd);
}

function ajax_genarrow( nowTemp, yesterTemp, Legend, textUP, textDN, numDp) {
// generate an <img> tag with alt= and title= for rising/falling values	
	
  var diff = nowTemp.toFixed(3) - yesterTemp.toFixed(3);
  var absDiff = Math.abs(diff);
  var diffStr = '' + diff.toFixed(numDp);  // sprintf("%01.0f",$diff);
  var absDiffStr = '' + absDiff.toFixed(numDp); // sprintf("%01.0f",$absDiff);
  var image = '';
  var msg = '';
  
  if (diff == 0) {
 // no change
    image = '&nbsp;'; 
  } else if (diff > 0) {
// today is greater 
//    msg = textUP + " by " + diff.toFixed(1); // sprintf($textDN,$absDiff); 
	msg = textUP.replace(/\%s/,absDiffStr);
    image = "<img src=\"" + imagedir + "/rising.gif\" alt=\"" + msg + 
	"\" title=\""+ msg + 
	"\" width=\"7\" height=\"8\" style=\"border: 0; margin: 1px 3px;\" />";
  } else {
// today is lesser
    msg = textDN.replace(/\%s/,absDiffStr); // sprintf($textDN,$absDiff); 
//	msg = textDN.replace(/\%s/,absDiffStr);
    image = "<img src=\"" + imagedir + "/falling.gif\" alt=\"" + msg + 
	"\" title=\""+ msg + 
	"\" width=\"7\" height=\"8\" style=\"border: 0; margin: 1px 3px;\" />";
   
  }

   if (Legend) {
       return (diff + Legend + image);
	} else {
	   return image;
	}
} // end genarrow function

// Mike Challis' counter function (adapted by Ken True)
//
function ajax_countup() {
 element = document.getElementById("ajaxcounter");
 if (element) {
  element.innerHTML = counterSecs;
  counterSecs++;
 }
}

// ------------------------------------------------------------------------------------------
//  main function.. read clientraw.txt and format <span class="ajax" id="ajax..."></span> areas
// ------------------------------------------------------------------------------------------
function ajaxLoader(url) {
  if (document.getElementById) {
    var x = (window.ActiveXObject) ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(url);
  }
  if (x) { // got something back
    x.onreadystatechange = function() {
    try { if (x.readyState == 4 && x.status == 200) { // Mike Challis added fix to fix random error 
        var clientraw = x.responseText.split(' ');

	// now make sure we got the entire clientraw.txt  -- thanks to Johnnywx
	// valid clientraw.txt has '12345' at start and '!!' at end of record
	var wdpattern=/\d+\.\d+.*!!/; // looks for '!!nn.nn!!' version string 

	// If we have a valid clientraw file AND updates is < maxupdates
	if(clientraw[0] == '12345' && wdpattern.test(x.responseText) && 
	    ( updates <= maxupdates || maxupdates > 0  ) ) {
		if (maxupdates > 0 ) {updates++; } // increment counter if needed

		//Temperature
		temp = convertTemp(clientraw[3]);
		var temprate = get_element_value("temprate"); //Read the value straight out of the doc
		set_ajax_obs("ajaxtemp", temp.toFixed(1) + uomTemp);
		set_ajax_obs("ajaxbigtemp",temp.toFixed(0) + uomTemp);

		templast = convertTemp(temp - temprate);

		set_ajax_obs("ajaxtemparrow", 
		   ajax_genarrow(temp, templast, '', 
			 langTempRising+uomTemp+langTempLastHour,
			 langTempFalling+uomTemp+langTempLastHour,1)
		   );	

		//Humidity ...
		humidity = clientraw[4];
		set_ajax_obs("ajaxhumidity",humidity);
		
		
		//Pressure...
		pressure = convertBaro(clientraw[5]);
		set_ajax_obs("ajaxbaro",pressure.toFixed(dpBaro) + uomBaro);
		var pressuretrend = convertBaro(get_element_value("baromrate")); //Read the value out of the doc
//		pressuretrend = convertBaro(clientraw[5]);
		pressuretrend = pressuretrend.toFixed(dpBaro+1);
		if (pressuretrend > 0.0) {pressuretrend = '+' + pressuretrend; } // add '+' to rate
		set_ajax_obs("ajaxbarotrend",pressuretrend + uomBaro);
		set_ajax_obs("ajaxbaroarrow",
		   ajax_genarrow(pressure, pressure-pressuretrend, '', 
			 langBaroRising+uomBaro+langBaroPerHour,
			 langBaroFalling+uomBaro+langBaroPerHour,2)
			 );	
		
	        //Wind gust
		gust    = convertWind(clientraw[8]);

		//Windspeed ...
		wind = convertWind(clientraw[1]);

       		//WIND DIRECTION ...
        	val = windDir(clientraw[2]);
		valLang = windDirLang(clientraw[2]); /* to enable translations */

       	if (wind > 0.0) {
		set_ajax_obs("ajaxwind",wind.toFixed(1) + uomWind);
		set_ajax_uom("ajaxwinduom",true);
	   } else {
		set_ajax_obs("ajaxwind",langWindCalm);
		set_ajax_uom("ajaxwinduom",false);
	   }
	   
	   if (gust > 0.0) {
		set_ajax_obs("ajaxgust",gust.toFixed(1) + uomWind);
		set_ajax_uom("ajaxgustuom",true);
	   } else {
		set_ajax_obs("ajaxgust",langGustNone);
		set_ajax_uom("ajaxgustuom",false);
	   }
	   
   	   if (gust > 0.0 || wind > 0.0) {
 		set_ajax_obs("ajaxwindicon",
		 "<img src=\"" + imagedir + "/" +  val + ".gif\" width=\"14\" height=\"14\" alt=\"" + 
		  langWindFrom + valLang + "\" title=\"" + langWindFrom + valLang + "\" /> ");
 		set_ajax_obs("ajaxwindiconwr",
		  "<img src=\"" + imagedir + "/" +wrName +  val + wrType + "\" width=\""+
		   wrWidth+"\" height=\""+wrHeight+"\" alt=\"" + 
		  langWindFrom + valLang + "\" title=\"" +langWindFrom + valLang + "\" /> ");
		set_ajax_obs("ajaxwinddir",valLang);
	   } else {
 		set_ajax_obs("ajaxwindicon","");
		set_ajax_obs("ajaxwinddir","");
		if (wrCalm != '') {
 		 set_ajax_obs("ajaxwindiconwr",
		  "<img src=\"" + imagedir + "/" + wrCalm + "\" width=\""+
		   wrWidth+"\" height=\""+wrHeight+"\" alt=\"" + 
		  langBeaufort[0] + "\" title=\"" +langBeaufort[0] + "\" /> ");
		}
	   }


	//Rain ...
	rain = convertRain(clientraw[12]);
	set_ajax_obs("ajaxrain",rain.toFixed(dpRain) + uomRain);

	rainstorm = convertRain(clientraw[11]);
	set_ajax_obs("ajaxrainstorm",rainstorm.toFixed(dpRain)+ uomRain);

	rainmo = convertRain(clientraw[13]);
	set_ajax_obs("ajaxrainmo",rainmo.toFixed(dpRain) + uomRain);

	rainratehr = convertRain(clientraw[10]); // make per hour rate.
	set_ajax_obs("ajaxrainratehr",rainratehr.toFixed(dpRain+1) + uomRain);


	// Update the timer after we've done our work
	counterSecs = 0; 
		
	// now ensure that the indicator flashes on every AJAX fetch
        element = document.getElementById("ajaxindicator");
	if (element) {
          element.style.color = flashcolor;
	}
	if (maxupdates > 0 && updates > maxupdates-1) { /* chg indicator to pause message */
		set_ajax_obs("ajaxindicator",langPauseMsg);
	}
	set_ajax_obs('ajaxupdatecount',updates);       /* for test pages */
	set_ajax_obs('ajaxmaxupdatecount',maxupdates); /* for test pages */

       } // END if(clientraw[0] = '12345' and '!!' at end)

    } // END if (x.readyState == 4 && x.status == 200)

  } // END try

  catch(e){}  // Mike Challis added fix to fix random error: NS_ERROR_NOT_AVAILABLE

    } // END x.onreadystatechange = function() {
    x.open("GET", url, true);
    x.send(null);

    //  reset the flash colors, and restart the update unless maxupdate limit is reached
    setTimeout("reset_ajax_color('')",flashtime); // change text back to default color 

    if ( (maxupdates == 0) || (updates < maxupdates-1)) {
      setTimeout("ajaxLoader(clientrawFile + '?' + new Date().getTime())", reloadTime); // get new data 
    }
  }
} // end ajaxLoader function

window.setInterval("ajax_countup()", 1000); // run the counter for seconds since update

// invoke when first loaded on page
if (! ajaxLoaderInBody) { ajaxLoader(clientrawFile + '?' + new Date().getTime(), reloadTime); }


// ]]>
