// <![CDATA[

/*
 beteljuice has adapted Ken Trues AJAX script so it can be used with:
  Cumulus 1.8.5  or higher
 beteljuice October 2008 
 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

 V1.0 open Jan 09
 
 The idea is you edit / add / modify for yourself ;-)
 for updates to this script, see - haven't decided yet
 announcements of new versions will be on - somewhere to be announced
 
 IMPORTANT *******************
 Your html page MUST have
 <div id="ajaxEND" style="display; none:"></div>
just before the closing </body> tag
 
*/


// -- begin settings --------------------------------------------------------------------------
var here = 'http://www.aadal.org/weather/betel_cumulus/';  // URL PATH to the 'AJAX' directory (include trailing / )
var currdatFile = 'http://www.aadal.org/weather/realtime.txt'; // URL location of realtime.txt 
var station_day = 0;	// when does your data 'day' begin - 0 = 00:00, 1 = 09:00
var station_alt = 40;	// height of baro Above Sea Level - METRES please !
var imagedir = 'ajax-images';  // place for wind arrows, rising/falling arrows, etc.
var flashcolor = '#00CC00'; // color to flash for changed observations RGB
var flashtime  = 1000;       // miliseconds to keep flash color on (2000 = 2 seconds);
var reloadTime = 10000;       // reload AJAX conditions every 10 seconds (= 10000 ms)
var maxupdates = 0;	         // Maximum Number of updates allowed (set to zero for unlimited)
                             // maxupdates * reloadTime / 1000 = number of seconds to update

// 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 -----
// -- if you use the 'extras' there may be some additional work to do in the script ! - go investigate

var langPauseMsg = 'Updates paused - reload page to start'; // substitute this for ajaxindicator when
                             // maxupdates has been reached and updating paused.

var langDays = new Array ("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
var langMonths = new Array ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");

// -----------------------------------------------------0-------1--------2-------3-------4------5-------6-------7-------8-------9	
var langDate_suffix = new Array ( "th.", "st.", "nd.", "rd.","th." ,"th.", "th.", "th.", "th.", "th.");	// eg. 1st 2nd 3rd etc. starts 0th ;-)

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 langBeaufort_desc = new Array ( /* Beaufort 0 to 12 DESCRIPTION in array */
 "Smoke rises vertically.<br />Tree leaves don't move.", "Smoke drift indicates wind direction.", "Wind felt on face. Leaves rustle.", "Leaves and twigs in constant motion.", "Dust and loose paper raised.<br />Small branches move.", "Small trees sway.", "Large branches move.<br />Wind whistles in wires.", "Whole trees move.<br />Walking affected.", "Twigs break off trees.<br />Walking difficult.", "Slight structural damage.<br />Branches break. <font color=\"red\">TAKE COVER</font>", "Considerable structural damage.<br />Trees uprooted.  <font color=\"red\">TAKE COVER</font>", "Widespread damage.<br /> <font color=\"red\">TAKE COVER</font>", "Severe and extensive damage.<br /> <font color=\"red\">TAKE COVER</font>"
);


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 langWindVerbose = new Array( /* can be used in text for wind direction */
	"North", "North-Northeast", "Northeast", "East-Northeast", 
	"East", "East-Southeast", "Southeast", "South-Southeast", 
	"South", "South-Southwest", "Southwest", "West-Southwest", 
	"West", "West-Northwest", "Northwest", "North-Northwest");


var langWindCalm = 'Calm';
var langWindFrom = 'Wind from the '; 	/* used on alt/title tags on wind direction arrow*/

var langBaroRising = 'Risen %s hPa since last data'; /* used for 'change' arrow alt/title tags .. %s marks where value will be placed */
var langBaroFalling = 'Fallen %s hPa since last data';

var langThermoCurrently = 'Currently: '; /* used on alt/title tags for thermometer */
var langTempRising = 'Risen %s since last data'; /* used for change since last arrow alt/title tags .. %s marks where value will be placed */
var langTempFalling = 'Fallen %s since last data';
var langTempTrendRising = 'Trend: Rising %s '; /* used for trend arrow alt/title tags .. %s marks where value will be placed */
var langTempTrendFalling = 'Trend: Falling %s ';

var langCBHRising_ft = 'Risen %s ft. since last data'; /* used for 'change' arrow alt/title tags .. %s marks where value will be placed */
var langCBHFalling_ft = 'Fallen %s ft. since last data';
var langCBHRising_m = 'Risen %s m. since last data';
var langCBHFalling_m = 'Fallen %s m. since last data';

var langComfort = new Array ( /* Comfort text from  Extreme Cold => Extreme Hot */
	"SEVERE DANGER", "Extremely Cold", "Uncomfortably Cold", "Cold", "Cool", "Comfortable",
	"Warm", "Uncomfortably Hot", "SEVERE DANGER");


// -- 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)



// 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;
}	// END function get_ajax_tags


function check_ajax_class(elem) {
// check element id for class="ajax" in it

  if (ie4 && browser != "Opera") {
	var lookfor = 'className';
  } else {
	var lookfor = 'class';
  }

  var class_check = "";
  var att = elem.getAttribute(lookfor);
  if(att == 'ajax') {
       class_check = 1;
   }
   return class_check;
}
// --- END function check_ajax_class()



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;
 
      }
}	// END function reset_ajax_color



function get_last( name ) {
// return STORED value - best use BEFORE Rset_ajax_obs ! - typically used for 'change since last'
		var element = document.getElementById(name);
		if (! element ) { return ; } // V1.04 -- don't set if missing the <span id=name> tag
		var prevobs = element.getAttribute("lastobs");
		return prevobs;
}	// END function get_last



// This is the function that sets the elements 'variable' content
function Rset_ajax_obs( name, value, uom ) {
// store away the current value in both the doc and the span as lastobs="value" and forward Unit Of Measure (or user suffix)
/* explanation
	Rset_ajax_obs( *span id*, *content value*, *suffix - usually Unit of Measure*);
*/

		var element = document.getElementById(name);
		if (! element ) { return; } //  -- don't set if missing the <span id=name> tag
		var lastobs = element.getAttribute("lastobs");
//		if (value != unescape(lastobs)) {
		if (value != lastobs) {
			element.setAttribute("lastobs",value);

  			if(check_ajax_class(element) ) {	// only change text colour if class = 'ajax'
           			element.style.color=flashcolor;
 			}

 			element.innerHTML =  value+uom;
		 	 if ( doTooltip ) { element.setAttribute("title",'AJAX tag:  '+name); }
		}
}	// END function Rset_ajax_obs



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 function set_ajax_uom

// --- end of flash-green functions



function windDir ($winddir) // used for direction graphics
// 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 )];
}	// END function windDir


function windDirLang ($winddir) // user language NNW
// 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 )];
}	// END function windDirLang


function windDirVerbose ($winddir) // user language North-Northwest
// Take wind direction value, return the VERBOSE
// text label based upon 16 point compass -- function by beeker425
{
   return langWindVerbose[Math.floor(((parseInt($winddir) + 11) / 22.5) % 16 )];
}	// END function windDirVerbose


function ajax_genarrow( nowValue, thenValue, Legend, textUP, textDN, numDp, steady) {
// generate an <img> tag with alt= and title= for rising/falling values
// modified by beteljuice - steady img optional	
	
  var diff = (nowValue *1).toFixed(numDp) - (thenValue *1).toFixed(numDp);
 	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
	if(!steady){steady = false;}
	if(steady ){		//  want a graphic for no change
	    msg = "Steady";	// *************** Non-English users change this ! *************************
	    image = "<img src=\"" + here + imagedir + "/steady.gif\" alt=\"" + msg + 
	"\" title=\""+ msg + 
	"\" width=\"7\" height=\"8\" style=\"border: 0; margin: 1px 3px;\" />";
	} else { 
// 	   image = '&nbsp;'; 
	    msg = "";
	    image = "<img src=\"" + here + imagedir + "/spacer.gif\" alt=\"" + msg + 
	"\" title=\""+ msg + 
	"\" width=\"7\" height=\"8\" style=\"border: 0; margin: 1px 3px;\" />";
	}
  } else if (diff > 0) {
// now is greater 
	msg = textUP.replace(/\%s/,absDiffStr);
    image = "<img src=\"" + here + imagedir + "/rising.gif\" alt=\"" + msg + 
	"\" title=\""+ msg + 
	"\" width=\"7\" height=\"8\" style=\"border: 0; margin: 1px 3px;\" />";

  } else {
// now is lesser
    msg = textDN.replace(/\%s/,absDiffStr); // sprintf($textDN,$absDiff); 
    image = "<img src=\"" + here + 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++;
 }
}



// ----- day and month functions ---------
// to get Sun, Mon, etc. use .getDayName(true) else .getDayName()
Date.prototype.getDayName = function(shortName) {
	if (shortName) {
		return langDays[this.getDay()].substr(0,3);
	} else {
		return langDays[this.getDay()];
	}
}	// END get day name


function getMonthName(mon, shortName) {
	if(shortName) {
		return langMonths[mon -1].substr(0,3);
	} else {
		return langMonths[mon -1];
	}
}	// END get month name


// ------ beaufort look-up --- 
// Cumulus only gives bf num for ave, so we have to reverse engineer for ave. max.
// input is mph

function getBft(mph) {
	mph = parseInt(mph);
	if(mph <1) { Bft = 0;}
	if(mph >= 1 && mph <= 3){ Bft = 1;}
	if(mph >3 && mph <= 7){ Bft = 2;}
	if(mph >7 && mph <= 12){ Bft = 3;}
	if(mph >12 && mph <= 17){ Bft = 4;}
	if(mph >17 && mph <= 24){ Bft = 5;}
	if(mph >24 && mph <= 30){ Bft = 6;}
	if(mph >30 && mph <= 38){ Bft = 7;}
	if(mph >38 && mph <= 46){ Bft = 8;}
	if(mph >46 && mph <= 54){ Bft = 9;}
	if(mph >54 && mph <= 63){ Bft = 10;}
	if(mph >63 && mph <= 72){ Bft = 11;}
	if(mph >72){ Bft = 12;}
	return Bft;
} // END getBft




// ------------------------------------------------------------------------------------------
//  main function.. read realtime.txt and format <span class="ajax" id="......"></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: NS_ERROR_NOT_AVAILABLE 

    var currdat = x.responseText.replace(/\r\n/g, "");	// this gets rid of any line ending
   	var currdat = currdat.split(' ');	// populate the array

	// now make sure we got a realtime.txt with minimum content 
	// If we have a valid currdat file AND updates is < maxupdates
	if(currdat[47] && ( updates <= maxupdates || maxupdates > 0  ) ) {
		if (maxupdates > 0 ) {updates++; } // increment counter if needed

// ----- time / date  --------------------------------------------------------------- ORDER CHANGED from original
 		ajaxtimeformat = currdat[1];

		if(lastajaxtimeformat != ajaxtimeformat) {		//  filestamp check

// we need to work on the date just to get the day of the week, and we have to do a fiddle because it's only a two digit year

			jdate_year = ("20" + currdat[0].substr(6)) *1;	// change "20xx" to a number
			jdate_month = currdat[0].substr(3, 2) *1;	// change to a number
			jdate_day = currdat[0].substr( 0, 2) *1;	// change to a number

			jdate = new Date(jdate_year, jdate_month -1, jdate_day, currdat[1].substr(0, 2), currdat[1].substr(3, 2));

			dname_long = jdate.getDayName();	// eg. Monday
			dname_short = jdate.getDayName(true);	// eg Mon
			mname_long = getMonthName(jdate_month);	// eg. February
			mname_short = getMonthName(jdate_month, true);	// eg Feb

// OK - let's create some 'user' date / time formats

/* explanation
	Rset_ajax_obs( *span id*, *content value*, *suffix - usually Unit of Measure*);
*/

// complete string Mon Mar 07 00:58:59 2008
			Rset_ajax_obs("ajaxObs_native", dname_short + ' ' + mname_short + ' ' + currdat[0].substr(0, 2) + ' ' + currdat[1] + ' ' + jdate_year, "");

// Mar 07, 2008
			Rset_ajax_obs("ajaxObs_date",  mname_short + ' ' + currdat[0].substr(0, 2) +  ', ' + jdate_year, ""); 
			wk_date = currdat[0].substr(0, 2) ;		// start working out date suffix
			suff = wk_date.substr(1) *1;	// get last character (as a number again)
			if(wk_date == "11" || wk_date == "12" || wk_date == "13") { suff = 0; }	// fix to stop 11st / 12nd / 13rd
			suff = langDate_suffix[suff];	// lookup correct suffix - END
 
// Mar 7th 2008
			Rset_ajax_obs("ajaxObs_date_suff", mname_short + " " + jdate_day + suff + " " + jdate_year, "");

// 07 Mar 2008
			Rset_ajax_obs("ajaxObs_date2", currdat[0].substr(0, 2) + " " + mname_short + " " + jdate_year, "");

// 7th Mar 2008
			Rset_ajax_obs("ajaxObs_date2_suff", jdate_day + suff + " " + mname_short + " " + jdate_year, ""); 

// 19:45
			Rset_ajax_obs("ajaxObs_time", currdat[1].substr(0, 5), "");	

// 19:45:32
			Rset_ajax_obs("ajaxObs_timess", currdat[1], "");	

// Mon - for Monday use dname_long
			Rset_ajax_obs("ajaxObs_dname", dname_short, "");	

// October - for Oct use mname_short
			Rset_ajax_obs("ajaxObs_mname", mname_long, "");	

// 2008
			Rset_ajax_obs("ajaxCopy_year", jdate_year, "");
					
			if(station_day == 1) {	// data begins @ 09:00
				Rset_ajax_obs("ajax_station_day", "09:00", "");
				(currdat[1].substr(0, 2) *1 <9 ? date_day = jdate_day - 1 : date_day = jdate_day);	
				since_date = new Date(jdate_year, jdate_month -1, date_day, "9");
				diff = jdate - since_date;
				diff_hr = parseInt(diff / 3600000);
				diff_min = currdat[1].substr(3, 2);
				data_hours = diff_hr + ":" + diff_min + " hrs";
				Rset_ajax_obs("ajax_data_hours", diff_hr + ":" + diff_min, " hrs");
			} else {		// anything else day begins @ 00:00
				Rset_ajax_obs("ajax_station_day", "00:00", "");
				data_hours = currdat[1].substr(0, 5) + " hrs";
				Rset_ajax_obs("ajax_data_hours", currdat[1].substr(0, 5), " hrs");
			}


// misc - Cumulus version eg. 1.8.2
			Rset_ajax_obs("Cumulus_ver", currdat[38], "");			


// misc - Cumulus build eg. 246
			Rset_ajax_obs("Cumulus_build", currdat[39], "");			



// ----- Temperature (External) ---------------------------------------------
// as of cumlus ver 1.8.3 build 531, trend is ave/hr over 3hrs


// providing both C and F because you maybe old fashioned and want to display both
			t_temp = currdat[2] *1	// force current temp to numeric
			t_temp_Hi = currdat[26] *1	// force max temp to numeric
			t_temp_Lo = currdat[28] *1	// force min temp to numeric
			t_temp_trend = currdat[25] *1	// force temp trend to numeric

// better find out units we are getting from file ;-)
			if(currdat[14] == "C") {	// data temperatures are Celcius
//			uom_temp = "&deg;C";	// may be used as a suffix later
				temp_C = t_temp;
				temp_C_max = t_temp_Hi;
				temp_C_min = t_temp_Lo;
				temp_trend = t_temp_trend;

				temp_F = t_temp * 9 / 5 + 32;
				temp_F_max = t_temp_Hi * 9 / 5 + 32;
				temp_F_min = t_temp_Lo * 9 / 5 + 32;

			} else {		// data must be Farenheit

				temp_C = (t_temp - 32) / 9 * 5;
				temp_C_max = (t_temp_Hi - 32) / 9 * 5;
				temp_C_min = (t_temp_Lo - 32) / 9 * 5;

				temp_F = t_temp;
				temp_F_max = t_temp_Hi ;
				temp_F_min = t_temp_Lo;
				temp_trend = t_temp_trend;
			}

	// generate 'change since last arrow' if required 
			templast_C = get_last("ajaxtemp_C"); 	// let's do a subsequent change check
			if(templast_C){		// prevents trend arrow on initial data grab
				Rset_ajax_obs("ajaxtemparrow_C", ajax_genarrow(temp_C, templast_C, '', langTempRising, langTempFalling, 1 ) ,"");	
			}

			Rset_ajax_obs("ajaxtemp_C", temp_C.toFixed(1), '&deg;C');
			Rset_ajax_obs("ajaxbigtemp_C", temp_C.toFixed(0), '&deg;C');

// duplicate for F, I don't know which you are going to use ;-)

	// generate 'change since last arrow' if required 
			templast_F = get_last("ajaxtemp_F");
			if(templast_F){
				Rset_ajax_obs("ajaxtemparrow_F", ajax_genarrow(temp_F, templast_F, '', langTempRising, langTempFalling, 1) ,"");	
			}

			Rset_ajax_obs("ajaxtemp_F", temp_F.toFixed(1), "&deg;F");
			Rset_ajax_obs("ajaxbigtemp_F", temp_F.toFixed(0), "&deg;F");


// temperature trend
	// generate arrow if required
			if(currdat[14] == "C") {	// data temperatures are Celcius
				uom_temp = "&deg;C/hr";	// may be used as a suffix later
			} else {
				uom_temp = "&deg;F/hr";
			}

// using optional true parameter to generate 'steady' graphic (not normally used with 'change' arrow)
			Rset_ajax_obs("ajaxtemptrend", ajax_genarrow( temp_trend, 0, '', langTempTrendRising + uom_temp, langTempTrendFalling + uom_temp, 1, true) , "");	
			Rset_ajax_obs("ajaxtemptrend_value", temp_trend , uom_temp);	

/* If you want INTERNAL values duplicate above with different variable names
	and use currdat[22] for data
*/


	// create some min / max external temp user variables
			Rset_ajax_obs("ajaxtemp_C_Min", temp_C_min.toFixed(1), "");	// NB. no suffix / unit
			Rset_ajax_obs("ajaxtemp_C_Max", temp_C_max.toFixed(1), "");	// NB. no suffix / unit
			Rset_ajax_obs("ajaxtemp_F_Min", temp_F_min.toFixed(1), "");	// NB. no suffix / unit
			Rset_ajax_obs("ajaxtemp_F_Max", temp_F_max.toFixed(1), "");	// NB. no suffix / unit

			Rset_ajax_obs("ajaxtemp_Min_time", currdat[29], "");	// eg. 03:24
			Rset_ajax_obs("ajaxtemp_Max_time", currdat[27], "");	// eg. 12:24

// END temperature

 
// ----- Humidity (External) ---------------------------------------------------------

			humidity = currdat[3] * 1;	// make numeric for other calcs later
//			Rset_ajax_obs("ajaxhumidity", humidity, "%");
			rh_last = get_last("ajaxhumidity");	
			Rset_ajax_obs("ajaxhumidity", humidity, "%");

// arrow for change since last obs
			if(rh_last){
				Rset_ajax_obs("ajaxhumidity_last_arrow", ajax_genarrow(humidity, rh_last, '', "Risen since last sample", "Fallen since last sample",0) ,"");	
			}
/* if you want INTERNAL value duplicate with a different var name and use currdat[23] */
// END humidity

		

// ------ Dewpoint ------------------------------------------------------------

			dp_temp = currdat[4] *1;	// force dp to numeric

// better find out units we are getting from file ;-)
			if(currdat[14] == "C") {	// data temperatures are Celcius
				dew_C = dp_temp;				
				dew_F = dp_temp * 1.8 + 32;
			} else {
				dew_C = (dp_temp - 32) / 1.8;				
				dew_F = dp_temp ;
			}				

			Rset_ajax_obs("ajax_dp_C", dew_C.toFixed(1), "&deg;C");
			Rset_ajax_obs("ajax_dp_F", dew_F.toFixed(1), "&deg;F");
// END dewpoint



// ----- WindChill ------------------------------------------------------------------------------ seems to be related to gust
// -- If calculated by Cumulus with respect to average windspeed, else base station dependent

			wc_temp = currdat[24] *1;	// force data to numeric

// better find out units we are getting from file ;-)
			if(currdat[14] == "C") {	// data temperatures are Celcius
				windchill_C = wc_temp;
				windchill_F = wc_temp * 1.8 + 32;
			} else {
				windchill_C = (wc_temp - 32) / 1.8;				
				windchill_F = wc_temp ;
			}				

			Rset_ajax_obs("ajaxwindchill_C", windchill_C.toFixed(1), "&deg;C");
			Rset_ajax_obs("ajaxwindchill_F", windchill_F.toFixed(1), "&deg;F");
// END windchill



// ------ Heat Index ----------------------------------------------------------------------------
			if(currdat[41]) {	// existence check - not in early versions
				HI_temp = currdat[41] *1;	// force data to numeric

// better find out units we are getting from file ;-)
				if(currdat[14] == "C") {	// data temperatures are Celcius
					heatidx_C = HI_temp;
					heatidx_F = HI_temp * 1.8 + 32;
				} else {
					heatidx_C = (HI_temp - 32) / 1.8;				
					heatidx_F = HI_temp ;
				}				
				Rset_ajax_obs("ajaxheatidx_F", heatidx_F.toFixed(1), "&deg;F");
				Rset_ajax_obs("ajaxheatidx_C", heatidx_C.toFixed(1), "&deg;C");
			}
// END heat index (NB. by using .toFixed() the values are TEXT)



// ------ Humidex - Canadian style (uses DP instead of humidity for base ------------------

			if(currdat[42]) {	// existence check - not in early versions
				Hdex_temp = currdat[42];

				Rset_ajax_obs("ajaxhumidex", Hdex_temp, "");
			}
// END humidex



// ------ FeelsLike ------------------------------------------------------------------------------
		  if (temp_C <= 16.0 ) {		 // note.. using temps in C and converting for F
		 		feelslike_C = windchill_C; //use WindChill
			} else if (temp_C >=27.0 && humidity >= 40) {
		 		feelslike_C = heatidx_C;   // use HeatIndex
			} else {
				feelslike_C = temp_C
			}
	    Rset_ajax_obs("ajaxfeelslike_C", feelslike_C.toFixed(1), "&deg;C");
			feelslike_F = ((feelslike_C * 1.8) +32).toFixed(1);
 	    Rset_ajax_obs("ajaxfeelslike_F", feelslike_F, "&deg;F");

// used for thermometer 'mouseover'
			thermometerstr_C = langThermoCurrently +  temp_C.toFixed(1) + "\&deg;C, Feels like " + feelslike_C + "\&deg;C"; 
			thermometerstr_F = langThermoCurrently +  temp_F.toFixed(1) + "\&deg;F, Feels like " + feelslike_F + "\&deg;F"; 
// END feels like


		
//------------ Create Comfort Index Text - various reasoning ! -------------
			CI_text = "";				// default if reasoning fails !

			if ((temp_C >= 15) && (temp_C < 25)) {
				CI_text = langComfort[5];  // comfortable
			}
			if ((temp_C >= 25) && (temp_C < 38)) {	// I know this looks high, but its to cover a low Heat Index
				CI_text = langComfort[6];
			}
			if ((temp_C >= 32) && (heatidx_C < 38)){
				CI_text = langComfort[7];
			}
			if (heatidx_C >= 38) {
				CI_text = langComfort[8];
			}
			if (windchill_C < 15) {
				CI_text = langComfort[4];
				if (windchill_C < 5) {
					CI_text = langComfort[3];
				}
				if (windchill_C < 0) {
					CI_text = langComfort[2];
				}
				if (windchill_C < -20) {
					CI_text = langComfort[1];
				}
				if (windchill_C < -35) {
					CI_text = langComfort[0];
				}
			}
	       	Rset_ajax_obs("ajaxcomfort", CI_text, "");
// END comfort index text



		
// ------ Pressure -----------------------------------------------------------------------
// as of cumlus ver 1.8.3 builg 531, trend is ave/hr over 3hrs

			press_temp = currdat[10] *1;	// force data to numeric
			press_temp_Lo = currdat[36] *1;	// force data to numeric
			press_temp_Hi = currdat[34] *1;	// force data to numeric
			press_temp_trend = currdat[18] *1;	// force data to numeric

// better find out units we are getting from file ;-)
			if(currdat[15] == "in") {	// data pressure are inHg
				pressure_rel_hPa = press_temp * 33.8639;	// conversion figure from NOAA
				pressure_rel_hPa_Min = press_temp_Lo * 33.8639 ;	
				pressure_rel_hPa_Max = press_temp_Hi * 33.8639;	
				pressure_rel_hPa_Trend = press_temp_trend * 33.8639;	

				pressure_rel_inHg = press_temp;
				pressure_rel_inHg_Min = press_temp_Lo;	
				pressure_rel_inHg_Max = press_temp_Hi;	
				pressure_rel_inHg_Trend = press_temp_trend;	

			} else {		// data is quoted as hpa OR mb (or anything else !)

				pressure_rel_hPa = press_temp;	
				pressure_rel_hPa_Min = press_temp_Lo;	
				pressure_rel_hPa_Max = press_temp_Hi;	
				pressure_rel_hPa_Trend = press_temp_trend;	

				pressure_rel_inHg = press_temp * 0.02953;	// conversion figure from NOAA
				pressure_rel_inHg_Min = press_temp_Lo * 0.02953;	
				pressure_rel_inHg_Max = press_temp_Hi * 0.02953;	
				pressure_rel_inHg_Trend = press_temp_trend * 0.02953;	
			}

// hPa relative
			barolast_rel_hPa = get_last("ajaxbaro_rel_hPa");	// for change arrow
			Rset_ajax_obs("ajaxbaro_rel_hPa", pressure_rel_hPa.toFixed(1), " hPa");
// inHg relative
			barolast_rel_inHg = get_last("ajaxbaro_rel_inHg");	// for change arrow
			Rset_ajax_obs("ajaxbaro_rel_inHg", pressure_rel_inHg.toFixed(2), " inHg");

// arrows for change since last obs
			if(barolast_rel_hPa){
				Rset_ajax_obs("ajaxbaro_rel_hPa_last_arrow", ajax_genarrow(pressure_rel_hPa, barolast_rel_hPa, '', langBaroRising, langBaroFalling,1) , "");	
			}

			if(barolast_rel_inHg){
				Rset_ajax_obs("ajaxbaro_rel_inHg_last_arrow", ajax_genarrow(pressure_rel_inHg, barolast_rel_inHg, '', langBaroRising, langBaroFalling,2) , "");	
			}
		
// pressure Min / Max
			Rset_ajax_obs("ajaxbaro_rel_hPa_Min", pressure_rel_hPa_Min.toFixed(1), " hPa");
			Rset_ajax_obs("ajaxbaro_rel_hPa_Max", pressure_rel_hPa_Max.toFixed(1), " hPa");	

			Rset_ajax_obs("ajaxbaro_rel_inHg_Min", pressure_rel_inHg_Min.toFixed(2), " inHg");
			Rset_ajax_obs("ajaxbaro_rel_inHg_Max", pressure_rel_inHg_Max.toFixed(2), " inHg");	

			Rset_ajax_obs("ajaxbaro_rel_Min_Time", currdat[37], "");
			Rset_ajax_obs("ajaxbaro_rel_Max_Time", currdat[35], "");

//   Barometric Trend (3 hour) - NB. cumulus gives an hourly average of last 3 hrs
//   so we need to x3 for our weather decisions

// 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_IM_06312.pdf
// figure out a text value for barometric pressure trend

			weather_trend = pressure_rel_hPa_Trend * 3;
		  if ((weather_trend >= -0.7) && (weather_trend <= 0.7)) { 
				pressure_trend_text = langBaroTrend[0];
				p_arrow = 0;	// steady
			}
   		if ((weather_trend > 0.7) && (weather_trend < 2.0 )) {
				pressure_trend_text = langBaroTrend[1];
				p_arrow = 1;	// rising
			}
   		if (weather_trend >= 2.0) {
				pressure_trend_text = langBaroTrend[2]; 
				p_arrow = 2;	// rising rapidly
			}
   		if ((weather_trend < -0.7) && (weather_trend > -2.0)) {
				pressure_trend_text = langBaroTrend[3]; 
				p_arrow = -1;	// falling
			}
   		if (weather_trend <= -2.0) { 
				pressure_trend_text = langBaroTrend[4]; 
				p_arrow = -2;	// falling rapidly
			}

			pressure_rel_hPa_Trend_rate = (pressure_rel_hPa_Trend > 0.0 ? "+" + pressure_rel_hPa_Trend.toFixed(1) : pressure_rel_hPa_Trend.toFixed(1));

			Rset_ajax_obs("ajaxbarotrend_hPa_rate",pressure_rel_hPa_Trend_rate, " hPa");

			pressure_rel_inHg_Trend_rate = (pressure_rel_inHg_Trend > 0.0 ? "+" + pressure_rel_inHg_Trend.toFixed(2) : pressure_rel_inHg_Trend.toFixed(2));

			Rset_ajax_obs("ajaxbarotrend_inHg_rate",pressure_rel_inHg_Trend_rate, " inHg");


// OK trend arrow has to ignore 'ordinary' math comparrison and obey parameters set above
// using optional true parameter to generate 'steady' graphic (not normally used with 'change' arrow)
	
			Rset_ajax_obs("ajaxbarotrend_arrow",  ajax_genarrow(p_arrow, 0, '', pressure_trend_text, pressure_trend_text,2, true), "");	

			Rset_ajax_obs("ajaxbarotrendtext", pressure_trend_text, "");


/* at the time of writing Cumulus only has one (relative) value for pressure */
// END pressure



// -------- Wind -------------------------------------------------- lots of conversions to do
// ----- Windspeed --------------------------------------------------------------------
/* we are calculating all units from any given unit except Beaufort No. which is separate data
windrun is Statute Miles or Kilometers or Nautical Miles since 00:00 OR 09:00 */

			ws_ave_temp = currdat[5] *1;	// force data to numeric
			ws_gust_temp = currdat[6] *1;	// force data to numeric
			ws_gust_recent_temp = currdat[40] *1;	// force data to numeric
			ws_windrun = currdat[17] *1;	// force data to numeric - miles / km / nautical miles
			ws_ave_max_temp = currdat[30] *1; // force data to numeric
			ws_gust_max_temp = currdat[32] *1; // force data to numeric




// better find out units we are getting from file ;-)
// conversion figures are from NOAA
			if(currdat[13] == "mph") {	// data windspeeds are mph ;-)
				wind_mph = ws_gust_temp;
				wind_mph_ave = ws_ave_temp;
				wind_mph_recent = ws_gust_recent_temp;
				wind_mph_ave_max = ws_ave_max_temp;
				wind_mph_gust_max = ws_gust_max_temp;
				windrun_miles = ws_windrun;

				wind_ms = ws_gust_temp * 0.44704;		// windspeed metres per sec
				wind_ms_ave = ws_ave_temp * 0.44704;
				wind_ms_recent = ws_gust_recent_temp * 0.44704;
				wind_ms_ave_max = ws_ave_max_temp * 0.44704;
				wind_ms_gust_max = ws_gust_max_temp * 0.44704;

				wind_k = ws_gust_temp * 1.4667;	// windspeed kilometres per hour
				wind_k_ave = ws_ave_temp * 1.4667;
				wind_k_recent = ws_gust_recent_temp * 1.4667;
				wind_k_ave_max = ws_ave_max_temp * 1.4667;
				wind_k_gust_max = ws_gust_max_temp * 1.4667;
				windrun_k = ws_windrun * 1.609344;

				wind_kts = ws_gust_temp * 0.8689762;	// windspeed knots
				wind_kts_ave = ws_ave_temp * 0.8689762;
				wind_kts_recent = ws_gust_recent_temp * 0.8689762;
				wind_kts_ave_max = ws_ave_max_temp * 0.8689762;
				wind_kts_gust_max = ws_gust_max_temp * 0.8689762;
				windrun_kts = ws_windrun * 0.8689;
			}

			if(currdat[13] == "kts") {	// data windspeeds are knots 
				wind_mph = ws_gust_temp * 1.1507794;
				wind_mph_ave = ws_ave_temp * 1.1507794;
				wind_mph_recent = ws_gust_recent_temp * 1.1507794;
				wind_mph_ave_max = ws_ave_max_temp * 1.1507794;
				wind_mph_gust_max = ws_gust_max_temp * 1.1507794;
				windrun_miles = ws_windrun * 1.50779;

				wind_ms = ws_gust_temp * 0.514444;		// windspeed metres per sec
				wind_ms_ave = ws_ave_temp * 0.514444;
				wind_ms_recent = ws_gust_recent_temp * 0.514444;
				wind_ms_ave_max = ws_ave_max_temp * 0.514444;
				wind_ms_gust_max = ws_gust_max_temp * 0.514444;

				wind_k = ws_gust_temp * 1.852;	// windspeed kilometres per hour
				wind_k_ave = ws_ave_temp * 1.852;
				wind_k_recent = ws_gust_recent_temp * 1.852;
				wind_k_ave_max = ws_ave_max_temp * 1.852;
				wind_k_gust_max = ws_gust_max_temp * 1.852;
				windrun_k = ws_windrun * 1.582;

				wind_kts = ws_gust_temp;	// windspeed knots
				wind_kts_ave = ws_ave_temp;
				wind_kts_recent = ws_gust_recent_temp;
				wind_kts_ave_max = ws_ave_max_temp;
				wind_kts_gust_max = ws_gust_max_temp;
				windrun_kts = ws_windrun;
			}

			if(currdat[13] == "m/s") {	// data windspeeds are metres per sec
				wind_mph = ws_gust_temp * 2.23694;
				wind_mph_ave = ws_ave_temp * 2.23694;
				wind_mph_recent = ws_gust_recent_temp * 2.23694;
				wind_mph_ave_max = ws_ave_max_temp * 2.23694;
				wind_mph_gust_max = ws_gust_max_temp * 2.23694;
				windrun_miles = ws_windrun * 0.62137;

				wind_ms = ws_gust_temp;		// windspeed metres per sec
				wind_ms_ave = ws_ave_temp;
				wind_ms_recent = ws_gust_recent_temp;
				wind_ms_ave_max = ws_ave_max_temp;
				wind_ms_gust_max = ws_gust_max_temp;

				wind_k = ws_gust_temp * 3.6;	// windspeed kilometres per hour
				wind_k_ave = ws_ave_temp * 3.6;
				wind_k_recent = ws_gust_recent_temp * 3.6;
				wind_k_ave_max = ws_ave_max_temp * 3.6;
				wind_k_gust_max = ws_gust_max_temp * 3.6;
				windrun_k = ws_windrun;


				wind_kts = ws_gust_temp * 1.9438445;	// windspeed knots
				wind_kts_ave = ws_ave_temp * 1.9438445;
				wind_kts_recent = ws_gust_recent_temp * 1.9438445;
				wind_kts_ave_max = ws_ave_max_temp * 1.9438445;
				wind_kts_gust_max = ws_gust_max_temp * 1.9438445;
				windrun_kts = ws_windrun * 0.53995;
			}

			if(currdat[13] == "km/h") {	// data windspeeds are kilometres per hour
				wind_mph = ws_gust_temp * 0.681818;	// windspeed mph
				wind_mph_ave = ws_ave_temp * 0.681818;
				wind_mph_recent = ws_gust_recent_temp * 0.681818;
				wind_mph_ave_max = ws_ave_max_temp * 0.681818;
				wind_mph_gust_max = ws_gust_max_temp * 0.681818;
				windrun_miles = ws_windrun * 0.62137;

				wind_ms = ws_gust_temp * 0.277778;		// windspeed metres per sec
				wind_ms_ave = ws_ave_temp * 0.277778;
				wind_ms_recent = ws_gust_recent_temp * 0.277778;
				wind_ms_ave_max = ws_ave_max_temp * 0.277778;
				wind_ms_gust_max = ws_gust_max_temp * 0.277778;

				wind_k = ws_gust_temp;	// windspeed kilometres per hour
				wind_k_ave = ws_ave_temp;
				wind_k_recent = ws_gust_recent_temp;
				wind_k_ave_max = ws_ave_max_temp;
				wind_k_gust_max = ws_gust_max_temp;
				windrun_k = ws_windrun;

				wind_kts = ws_gust_temp * 0.5399568;	// windspeed knots
				wind_kts_ave = ws_ave_temp * 0.5399568;
				wind_kts_recent = ws_gust_recent_temp * 0.5399568;
				wind_kts_ave_max = ws_ave_max_temp * 0.5399568;
				wind_kts_gust_max = ws_gust_max_temp * 0.5399568;
				windrun_kts = ws_windrun * 0.53995;
			}

// define some user (html) variables

			Rset_ajax_obs("ajax_wind_mps", wind_ms.toFixed(1), " m/s");
			Rset_ajax_obs("ajax_wind_kph", wind_k.toFixed(1), " km/h");
			Rset_ajax_obs("ajax_wind_mph", wind_mph.toFixed(1), " mph");
			Rset_ajax_obs("ajax_wind_kts", wind_kts.toFixed(1), " kts");

			Rset_ajax_obs("ajax_wind_mps_ave", wind_ms_ave.toFixed(1), " m/s");
			Rset_ajax_obs("ajax_wind_kph_ave", wind_k_ave.toFixed(1), " km/h");
			Rset_ajax_obs("ajax_wind_mph_ave", wind_mph_ave.toFixed(1), " mph");
			Rset_ajax_obs("ajax_wind_kts_ave", wind_kts_ave.toFixed(1), " kts");

			Rset_ajax_obs("ajax_wind_mps_recent", wind_ms_recent.toFixed(1), " m/s");
			Rset_ajax_obs("ajax_wind_kph_recent", wind_k_recent.toFixed(1), " km/h");
			Rset_ajax_obs("ajax_wind_mph_recent", wind_mph_recent.toFixed(1), " mph");
			Rset_ajax_obs("ajax_wind_kts_recent", wind_kts_recent.toFixed(1), " kts");

			Rset_ajax_obs("ajax_wind_ave_max_TIME", currdat[31], "");
			Rset_ajax_obs("ajax_wind_mps_ave_max", wind_ms_ave_max.toFixed(1), " m/s");
			Rset_ajax_obs("ajax_wind_kph_ave_max", wind_k_ave_max.toFixed(1), " km/h");
			Rset_ajax_obs("ajax_wind_mph_ave_max", wind_mph_ave_max.toFixed(1), " mph");
			Rset_ajax_obs("ajax_wind_kts_ave_max", wind_kts_ave_max.toFixed(1), " kts");

			Rset_ajax_obs("ajax_wind_gust_max_TIME", currdat[33], "");
			Rset_ajax_obs("ajax_wind_mps_gust_max", wind_ms_gust_max.toFixed(1), " m/s");
			Rset_ajax_obs("ajax_wind_kph_gust_max", wind_k_gust_max.toFixed(1), " km/h");
			Rset_ajax_obs("ajax_wind_mph_gust_max", wind_mph_gust_max.toFixed(1), " mph");
			Rset_ajax_obs("ajax_wind_kts_gust_max", wind_kts_gust_max.toFixed(1), " kts");

// NB Beaufort No is a Wind AVERAGE value !!!
			wind_bf = currdat[12] *1;	// windspeed beaufort number (forced to numeric)
			Rset_ajax_obs("ajax_wind_bf_num", wind_bf.toFixed(0), "");	// hint; put 'Force: ' before # in html
			Rset_ajax_obs("ajaxbeaufort",langBeaufort[wind_bf], "");
			Rset_ajax_obs("ajaxbeaufort_desc",langBeaufort_desc[wind_bf], "");

			wind_bf_ave_max = getBft(wind_mph_ave_max);	// windspeed beaufort number
			Rset_ajax_obs("ajax_wind_bf_num_max", wind_bf_ave_max, "");	// hint; put 'Force: ' before # in html
			Rset_ajax_obs("ajaxbeaufort_max",langBeaufort[wind_bf_ave_max], "");
			Rset_ajax_obs("ajaxbeaufort_desc_max",langBeaufort_desc[wind_bf_ave_max], "");

			Rset_ajax_obs("ajax_windrun_miles", windrun_miles.toFixed(2) + " miles/" + data_hours, "");
			Rset_ajax_obs("ajax_windrun_km", windrun_k.toFixed(2) + " km/" + data_hours, "");
			Rset_ajax_obs("ajax_windrun_nautical", windrun_kts.toFixed(2) + " nautical miles/" + data_hours, "");


// WIND DIRECTION ... NOW (gust)
// we only use data degrees - this script translates to user language
// bugg*r - from 1.8.3 cumulus uses 360 as North but also uses 0 to indicate Calm !

 	    val_org = currdat[7] *1;
 	    if(val_org == 360){val_org = 0;} // used in math to determine array[x]
 	    val = windDir(val_org); // NOT user translated - to enable graphics names
 	    val2 = currdat[7] *1;
 	    if(wind_mph > 0){	// run with the directions as given - * trial comfort calm
				valLang = windDirLang( val_org ); /* to enable translations */
				valLangVerbose = windDirVerbose( val_org ); /* to enable translations */
 			Rset_ajax_obs("ajaxwind_deg", val2, "&deg;");	// wind degrees, - * trial comfort 'calm'
			} else {	// give a 'comfort' direction for calm [?]
				valLang = "--";
				valLangVerbose = "--"
 			Rset_ajax_obs("ajaxwind_deg", "--", "&deg;");	// wind degrees, - * trial comfort 'calm'
			}
			
// 			Rset_ajax_obs("ajaxwind_deg", val2, "&deg;");	// wind degrees, even when 'calm'
Rset_ajax_obs("ajaxwinddir",valLang, "");	// NNW - * trial comfort calm
Rset_ajax_obs("ajaxwinddir_long",valLangVerbose, "");	// North-Northwest - * trial comfort calm


	   
 // ************ large (35px) arrow points INTO wind, gives '?' graphic when calm
 			(wind_mph > 0 ? green_val = val : green_val = "0");
 			Rset_ajax_obs("ajaxwindarrow_green",
		  "<img src=\"" + here + imagedir + "/green_"+green_val+".png\" width=\"35\" height=\"35\" alt=\"" + 
		  langWindFrom + valLang + "\" title=\"" +langWindFrom + valLang + " (" + val2 + "\&deg;)\" /> ", "");


// direction compass rose and wind arrows - arrows NOT displayed if 'calm'
	  	if (wind_mph > 0) {
// 9px wind arrow - points in wind direction
 				Rset_ajax_obs("ajaxwindicon_9",
		 "<img src=\"" + here + imagedir + "/" +  val + "_9.gif\" width=\"9\" height=\"9\" alt=\"" + 
		  langWindFrom + valLang + "\" title=\"" +langWindFrom + valLang + " (" + val2 + "\&deg;)\" /> ", "");
// 14px wind arrow - points in wind direction
 				Rset_ajax_obs("ajaxwindicon_14",
		 "<img src=\"" + here + imagedir + "/" +  val + "_14.gif\" width=\"14\" height=\"14\" alt=\"" + 
		  langWindFrom + valLang + "\" title=\"" +langWindFrom + valLang + " (" + val2 + "\&deg;)\" /> ", "");
// small windrose (compass)
				Rset_ajax_obs("ajaxwindiconwr",
		  "<img src=\"" + here + imagedir + "/" +wrName +  val + wrType + "\" width=\""+
		   wrWidth+"\" height=\""+wrHeight+"\" alt=\"" + 
		  langWindFrom + valLang + "\" title=\"" +langWindFrom + valLang + "\" /> ", "");
// direction as text
//				Rset_ajax_obs("ajaxwinddir",valLang, "");	// NNW
//				Rset_ajax_obs("ajaxwinddir_long",valLangVerbose, "");	// North-Northwest
	  	 } else {
 // NO wind arrows if Calm - remove below and if(wind_mph > 0.0)  argument if not wanted
				Rset_ajax_obs("ajaxwindicon_9","", "");
				Rset_ajax_obs("ajaxwindicon_14","", "");
//				Rset_ajax_obs("ajaxwinddir","", "");
//				Rset_ajax_obs("ajaxwinddir_long","", "");
				if (wrCalm != '') {	// if you have set an alternative (windrose) graphic for calm
 			 		Rset_ajax_obs("ajaxwindiconwr",
		  "<img src=\"" + here + imagedir + "/" + wrCalm + "\" width=\""+
		   wrWidth+"\" height=\""+wrHeight+"\" alt=\"" + 
		  langBeaufort[0] + "\" title=\"" +langBeaufort[0] + "\" /> ", "");
				}
			 }
// END wind arrows
// END wind now (gust)


// ----- Wind Average (10min) Direction (degrees) ------ since 1.8.5
			if(currdat[46]) {	// prove existence check
			
// we only use data degrees - this script translates to user language
// bugg*r - from 1.8.3 cumulus uses 360 as North but also uses 0 to indicate Calm !

 	    	val_org_ave = currdat[46] *1;
 	    	if(val_org_ave == 360){val_org_ave = 0;} // used in math to determine array[x]
 	    	val_ave = windDir(val_org_ave); // NOT user translated - to enable graphics names
 	    	val2_ave = currdat[46] *1;

 	    if(wind_mph_ave > 0){	// run with the directions as given - * trial comfort calm
				valLang_ave = windDirLang( val_org_ave ); /* to enable translations */
				valLangVerbose_ave = windDirVerbose( val_org_ave ); /* to enable translations */
 				Rset_ajax_obs("ajaxwind_deg_ave", val2_ave, "&deg;");	// wind degrees
		} else {	// give a 'comfort' direction for calm [?]
				valLang_ave = "--";
				valLangVerbose_ave = "--"
 				Rset_ajax_obs("ajaxwind_deg_ave", "--", "&deg;");	// wind degrees, - * trial comfort 'calm'
		}


Rset_ajax_obs("ajaxwinddir_ave",valLang_ave, "");	// NNW - * trial comfort calm
Rset_ajax_obs("ajaxwinddir_long_ave",valLangVerbose_ave, "");	// North-Northwest - * trial comfort calm

 //				Rset_ajax_obs("ajaxwind_deg_ave", val2_ave, "&deg;");	// wind degrees, even when 'calm'


	   
 // ************ large (35px) arrow points INTO wind, gives '?' graphic when calm
 			(wind_mph_ave > 0 ? green_val_ave = val_ave : green_val_ave = "0");
			Rset_ajax_obs("ajaxwindarrow_green_ave",
		  "<img src=\"" + here + imagedir + "/green_"+green_val_ave+".png\" width=\"35\" height=\"35\" alt=\"" + 
		  langWindFrom + valLang_ave + "\" title=\"" +langWindFrom + valLang_ave + " (" + val2_ave + "\&deg;)\" /> ", "");


// direction compass rose and wind arrows - arrows NOT displayed if 'calm'
	  		if (wind_mph_ave > 0) {
// 9px wind arrow - points in wind direction
 					Rset_ajax_obs("ajaxwindicon_9_ave",
		 "<img src=\"" + here + imagedir + "/" +  val_ave + "_9.gif\" width=\"9\" height=\"9\" alt=\"" + 
		  langWindFrom + valLang_ave + "\" title=\"" +langWindFrom + valLang_ave + " (" + val2_ave + "\&deg;)\" /> ", "");
// 14px wind arrow - points in wind direction
 					Rset_ajax_obs("ajaxwindicon_14_ave",
		 "<img src=\"" + here + imagedir + "/" +  val_ave + "_14.gif\" width=\"14\" height=\"14\" alt=\"" + 
		  langWindFrom + valLang_ave + "\" title=\"" +langWindFrom + valLang_ave + " (" + val2_ave + "\&deg;)\" /> ", "");
// small windrose (compass)
					Rset_ajax_obs("ajaxwindiconwr_ave",
		  "<img src=\"" + here + imagedir + "/" +wrName +  val_ave + wrType + "\" width=\""+
		   wrWidth+"\" height=\""+wrHeight+"\" alt=\"" + 
		  langWindFrom + valLang_ave + "\" title=\"" +langWindFrom + valLang_ave + "\" /> ", "");
// direction as text
//					Rset_ajax_obs("ajaxwinddir_ave",valLang_ave, "");	// NNW
//					Rset_ajax_obs("ajaxwinddir_long_ave",valLangVerbose_ave, "");	// North-Northwest
	  	 	} else {
 // NO wind arrows if Calm - remove below and if(wind_mph > 0.0)  argument if not wanted
					Rset_ajax_obs("ajaxwindicon_9_ave","", "");
					Rset_ajax_obs("ajaxwindicon_14_ave","", "");
//					Rset_ajax_obs("ajaxwinddir_ave","", "");
//					Rset_ajax_obs("ajaxwinddir_long_ave","", "");
					if (wrCalm != '') {	// if you have set an alternative (windrose) graphic for calm
 			 			Rset_ajax_obs("ajaxwindiconwr_ave",
		  "<img src=\"" + here + imagedir + "/" + wrCalm + "\" width=\""+
		   wrWidth+"\" height=\""+wrHeight+"\" alt=\"" + 
		  langBeaufort[0] + "\" title=\"" +langBeaufort[0] + "\" /> ", "");
					}
			 	}
// END wind Average arrows
			}
// END wind Average
// END WIND



// ----- Rain -------------------------------------------------------------------------------
// since Cumulus 1.8.4 rain rate is calulated from last 5 mins
// Tip: you could use this to determine 'raining now' advisory, would require >= 0.1 unit/5mins
// since build 602 'rain last hour available'

			if(currdat[47]) {	// prove existence check build 602+
				rain_hr_temp = currdat[47] *1;	// force data to numeric
			} else {
				rain_hr_temp = -10;	// making sure variable is declared even if it is 'empty'
			}

			rain_rate_temp = currdat[8] *1;	// force data to numeric
			rain_today_temp = currdat[9] *1;	// force data to numeric
			rain_yesterday_temp = currdat[21] *1;	// force data to numeric
			rain_month_temp = currdat[19] *1;	// force data to numeric
			rain_year_temp = currdat[20] *1;	// force data to numeric


// better find out units we are getting from file ;-)
// conversion figures are from NOAA
			if(currdat[16] == "mm") {	// data units are mm
				rain_mm_rate = rain_rate_temp;
				rain_mm1 = rain_hr_temp;
				rain_mm24 = rain_today_temp;
				rain_mm_ago = rain_yesterday_temp;
				rain_mm_mon = rain_month_temp;
				rain_mm_year = rain_year_temp;

				rain_in_rate = rain_rate_temp / 25.4;
				rain_in1 = rain_hr_temp / 25.4;
				rain_in24 = rain_today_temp / 25.4;
				rain_in_ago = rain_yesterday_temp / 25.4;
				rain_in_mon = rain_month_temp / 25.4;
				rain_in_year = rain_year_temp / 25.4;

			} else{ 	// data units must be inches

				rain_mm_rate = rain_rate_temp * 25.4;
				rain_mm1 = rain_hr_temp * 25.4;
				rain_mm24 = rain_today_temp * 25.4;
				rain_mm_ago = rain_yesterday_temp * 25.4;
				rain_mm_mon = rain_month_temp * 25.4;
				rain_mm_year = rain_year_temp * 25.4;

				rain_in_rate = rain_rate_temp;
				rain_in1 = rain_hr_temp;
				rain_in24 = rain_today_temp;
				rain_in_ago = rain_yesterday_temp;
				rain_in_mon = rain_month_temp;
				rain_in_year = rain_year_temp;
			}

// prepare for 'change since last' arrows
			rain_then_mm = get_last("ajaxrain_mm_rate");
			rain_then_in = get_last("ajaxrain_in_rate");

// set some (html) user variables
			if(rain_hr_temp >= 0) {	// build 602+ check
				Rset_ajax_obs("ajaxrain_mm_1hr", rain_mm1.toFixed(1), " mm");
			}
			Rset_ajax_obs("ajaxrain_mm_today", rain_mm24.toFixed(1), " mm");
			Rset_ajax_obs("ajaxrain_mm_yesterday", rain_mm_ago.toFixed(1), " mm");
			Rset_ajax_obs("ajaxrain_mm_month", rain_mm_mon.toFixed(1), " mm");
			Rset_ajax_obs("ajaxrain_mm_year", rain_mm_year.toFixed(1), " mm");
			Rset_ajax_obs("ajaxrain_mm_rate", rain_mm_rate.toFixed(1), " mm/hr");
// lets make a change since last arrow - NB. requires ajaxrain_mm_rate somewhere on the html page
			if(rain_then_mm){
				Rset_ajax_obs("ajax_rain_mm_arrow", ajax_genarrow(rain_mm_rate.toFixed(1), rain_then_mm, '', '', '', 0) , "");
			}


			if(rain_hr_temp >= 0) {	// build 602+ check
				Rset_ajax_obs("ajaxrain_in_1hr", rain_in1.toFixed(2), " in");
			}
			Rset_ajax_obs("ajaxrain_in_today", rain_in24.toFixed(2), " in");
			Rset_ajax_obs("ajaxrain_in_yesterday", rain_in_ago.toFixed(2), " in");
			Rset_ajax_obs("ajaxrain_in_month", rain_in_mon.toFixed(2), " in");
			Rset_ajax_obs("ajaxrain_in_year", rain_in_year.toFixed(2), " in");
			Rset_ajax_obs("ajaxrain_in_rate", rain_in_rate.toFixed(2), " in/hr");
// lets make a change since last arrow - NB. requires ajaxrain_in_rate somewhere on the html page
			if(rain_then_in){
				Rset_ajax_obs("ajax_rain_in_arrow", ajax_genarrow(rain_in_rate.toFixed(2), rain_then_in, '', '', '', 0) , "");
			}

// END rain



// ---- Compute Cloud Base Height -------------------------------

			CBH_change_ft = get_last("ajax_CBH_ft");		// if there is change lets create a change since last arrow 
			CBH_change_m = get_last("ajax_CBH_m");
			CBH_m = 125*(temp_C - (dew_C *1));	// cloudbase local in metres
// betel(temp_C + " tC, " + dew_C *1 + " DP, " + CBH_m);
			if(CBH_m < 0) CBH_m = 0;	// stop negative values
			Rset_ajax_obs("ajax_CBH_m", CBH_m.toFixed(0), " m");
			CBH_ft = CBH_m * 3.281;	// cloud base local in feet
			if(CBH_ft < 0) CBH_ft = 0;	// stop negative values
			Rset_ajax_obs("ajax_CBH_ft", CBH_ft.toFixed(0), " ft");
			if(CBH_change_ft){
				Rset_ajax_obs("ajax_CBH_last_arrow", ajax_genarrow(CBH_ft.toFixed(0), CBH_change_ft, '', langCBHRising_ft, langCBHFalling_ft, 0) , "");
			} else {
				if(CBH_change_m){
					Rset_ajax_obs("ajax_CBH_last_arrow", ajax_genarrow(CBH_m.toFixed(0), CBH_change_m, '', langCBHRising_m, langCBHFalling_m, 0) , "");
				}
		 }
// END cloud base height



// ----- UV Index ------------
				Rset_ajax_obs("ajax_UV", currdat[43], "");	// effectively a text value, no processing

	
			
// ----- Evapo Trans whotsit ------------
				Rset_ajax_obs("ajax_EVT", currdat[44], "");	// effectively a text value, no processing


	
// ----- Solar Radiation ------------
				Rset_ajax_obs("ajax_SR", currdat[45], " W/m<sup>2</sup>");	// effectively a text value, no processing



// BEYOND ver 1.8.4 build 605 ... add logic here









// ********** EXTRAS and duplicates *************************************************************
// remember - we are still in the ajax 'grab' loop
// you can remove all these if required, or add to them ;-)




// ------- short Zambretti Forecast
// IMPORTANT - requires zambretti/betelcast.js between page <head> .. </head> tags
// BEFORE betel_cumulus_ajax.js

			if(self.z_where != null) {	// check to see if betelcast.js has been loaded
// set variables to send to betel_cast() - if you live near poles / equator / Southern hemisphere - read script !

				(wind_mph_ave >= 1 ? z_wind = val_ave : z_wind = "calm");
				(p_arrow == -1 ? z_trend = 2 : z_trend = p_arrow);
				what_forecast = betel_cast( pressure_rel_hPa, jdate_month, z_wind, z_trend);
			} else {
				what_forecast = new Array("* betelcast.js MISSING *", 0);
			}

			Rset_ajax_obs("betelcast", what_forecast[0], "");
// --- END forecast




// ------- Freeze / Snow Height ------------------------------ (Experimental unproven !)
// Height Above Sea Level that temp drops to zero C
// less 152.4m (500') for snow line
// 3 options - if one works for you delete the rest - give the PC a rest :-)

			freezeheight_ASL_m = 150 * (temp_C - (((((pressure_rel_hPa - 850) * 5.71) - station_alt) * 6.5) / 1000)) + 1000;
			freezeheight_ASL_m2 = (temp_C / 6.5 * 1000) + station_alt; // simplified equation - ignores pressure
			freezeheight_ASL_m3 = (150 * (temp_C - (((((pressure_rel_hPa - 850) * 6.769) - station_alt) * 6.5) / 1000)) + 1000) + station_alt;

			snowheight_ASL_m = freezeheight_ASL_m - 152.4;
			snowheight_ASL_m2 = freezeheight_ASL_m2 - 152.4;
			snowheight_ASL_m3 = freezeheight_ASL_m3 - 152.4;
			
			freezeheight_ASL_ft = freezeheight_ASL_m * 3.281;
			freezeheight_ASL_ft2 = freezeheight_ASL_m2 * 3.281;
			freezeheight_ASL_ft3 = freezeheight_ASL_m3 * 3.281;

			snowheight_ASL_ft = freezeheight_ASL_ft - 500;
			snowheight_ASL_ft2 = freezeheight_ASL_ft2 - 500;
			snowheight_ASL_ft3 = freezeheight_ASL_ft3 - 500;

// fix to stop negative values (below sea-level) remove if not required
			if(freezeheight_ASL_m <1) freezeheight_ASL_m = 0;
			if(freezeheight_ASL_m2 <1) freezeheight_ASL_m2 = 0;
			if(freezeheight_ASL_m3 <1) freezeheight_ASL_m3 = 0;

			if(snowheight_ASL_m <1) snowheight_ASL_m = 0;
			if(snowheight_ASL_m2 <1) snowheight_ASL_m2 = 0;
			if(snowheight_ASL_m3 <1) snowheight_ASL_m3 = 0;
			
			if(freezeheight_ASL_ft <1) freezeheight_ASL_ft = 0;
			if(freezeheight_ASL_ft2 <1) freezeheight_ASL_ft2 = 0;
			if(freezeheight_ASL_ft3 <1) freezeheight_ASL_ft3 = 0;

			if(snowheight_ASL_ft <1) snowheight_ASL_ft = 0;
			if(snowheight_ASL_ft2 <1) snowheight_ASL_ft2 = 0;
			if(snowheight_ASL_ft3 <1) snowheight_ASL_ft3 = 0;
// END negative fix


			Rset_ajax_obs("ajax_freezeheight_ASL_m", freezeheight_ASL_m.toFixed(0), " m");
			Rset_ajax_obs("ajax_freezeheight_ASL_ft", freezeheight_ASL_ft.toFixed(0), " ft");
			Rset_ajax_obs("ajax_snowheight_ASL_m", snowheight_ASL_m.toFixed(0), " m");
			Rset_ajax_obs("ajax_snowheight_ASL_ft", snowheight_ASL_ft.toFixed(0), " ft");

			Rset_ajax_obs("ajax_freezeheight_ASL_m2", freezeheight_ASL_m2.toFixed(0), " m");
			Rset_ajax_obs("ajax_freezeheight_ASL_ft2", freezeheight_ASL_ft2.toFixed(0), " ft");
			Rset_ajax_obs("ajax_freezeheight_ASL_m3", freezeheight_ASL_m3.toFixed(0), " m");
			Rset_ajax_obs("ajax_freezeheight_ASL_ft3", freezeheight_ASL_ft3.toFixed(0), " ft");
			Rset_ajax_obs("ajax_snowheight_ASL_m2", snowheight_ASL_m2.toFixed(0), " m");
			Rset_ajax_obs("ajax_snowheight_ASL_ft2", snowheight_ASL_ft2.toFixed(0), " ft");
			Rset_ajax_obs("ajax_snowheight_ASL_m3", snowheight_ASL_m3.toFixed(0), " m");
			Rset_ajax_obs("ajax_snowheight_ASL_ft3", snowheight_ASL_ft3.toFixed(0), " ft");

/* the only use I can forsee for these is if you live in a mountainous area and would like to
    forecast conditions higher / lower than your situation.
   You would be better doing somekind of max. height check (of mountain) against eg. 
   snowheight_ASL_m
   perhaps even do a 'look-up' table for local place names ?
*/




// --------- betejuices composite weather 'graphic' ------------------------------
// IMPORTANT - requires betel_graphics_vars.js between page <head> .. </head> tags
// IMPORTANT - uses zambretti forecast - see above

// same sort of logic could be used to produce icons

// there are quite a few things to set-up and save so don't bother if it's not on page

			if(document.getElementById("beteljuice_map") ) {	// existence check

// define day / night times and background graphics 
/* TIP: If you make a cumulusTemplate for your html page
   you can delete everything between // - START, // - END 
   and in the <head> section of your cumulus htm Template put:
   	<script type="text/javascript">
      day_start = "<#sunrise>";
   		day_end = "<#sunset>";
   	</script>
   
   OK. It would be Sun up / down rather than dusk to dawn, but it is automatic and self adjusting
*/

// - START
				day_start = "06:30";
				day_end = "18:30";

// OR roughly for Midlands UK and middle month dawn to dusk values (overrides above)
// NB. overides above declarations 

				if(jdate_month == 1) { day_start = "07:30" ; day_end = "17:00"; }
				if(jdate_month == 2) { day_start = "06:50" ; day_end = "17:50"; }
				if(jdate_month == 3) { day_start = "05:50" ; day_end = "18:40"; }
				if(jdate_month == 4) { day_start = "05:40" ; day_end = "20:40"; }
				if(jdate_month == 5) { day_start = "04:30" ; day_end = "21:40"; }
				if(jdate_month == 6) { day_start = "04:00" ; day_end = "22:20"; }
				if(jdate_month == 7) { day_start = "04:20" ; day_end = "22:10"; }
				if(jdate_month == 8) { day_start = "05:15" ; day_end = "21:10"; }
				if(jdate_month == 9) { day_start = "06:10" ; day_end = "20:00"; }
				if(jdate_month == 10) { day_start = "07:00" ; day_end = "18:45"; }
				if(jdate_month == 11) { day_start = "07:00" ; day_end = "16:50"; }
				if(jdate_month == 12) { day_start = "07:30" ; day_end = "16:30"; }
// END 'rough'
// - END

				day_graphic = here + "stuff/UkMap_day2.png";
				night_graphic = here + "stuff/UkMap_night2.gif";

				day_start = day_start.replace(':', '') *1;	// turn into a 'real' number
				day_end = day_end.replace(':', '') *1;	// turn into a 'real' number
				obs_time =currdat[1].substr(0, 5);
				obs_time = obs_time.replace(':', '') *1;	// turn into a 'real' number

				if(obs_time < day_start || obs_time > day_end) {		// must be night
					graphic = night_graphic;
				} else {
					graphic = day_graphic;
				}

// create wind graphic / data - using now (gust) value
				spacer="";
				if(wind_mph >= 1) {	// build wind info section(s)
					Rset_ajax_obs("ajax_pic_windsock", "<img src=\"" + here + "stuff/wind_sock.gif\" alt=\"" + langWindFrom + valLang + "\" title=\"" +langWindFrom + valLang + " (" + val2 + "\&deg;)\" />", "");
					Rset_ajax_obs("ajax_pic_windspeed", wind_mph.toFixed(1) + "<br />", "mph");
					spacer="&nbsp;&nbsp;&nbsp;";
				}else{
					Rset_ajax_obs("ajax_pic_windsock", "", "");
					Rset_ajax_obs("ajax_pic_windspeed", "", "");
				}

				Rset_ajax_obs("ajax_pic_temp_C", spacer + temp_C.toFixed(0), '&deg;C');	// yet another temp display


// **************** need to do some weather logic somewhere !
// experimental - using zambretti algorithm (betelcast.js) and guessing by baro severity of change
// might need tweaking ;-)
// you could try making decisions on temp and cloud base as well

// ------ Sudden RAIN / STORM ----- quick and dirty - assumes 3hr baro trend, values might need tweaking
 				if(weather_trend <= -7) {		// stormwarning - overrides zambretti forecast
					Rset_ajax_obs("beteljuice_map", "<img src = \"" + graphic + "\" alt = \"Sudden STORM\" title = \"Sudden STORM\" />", ""); 
					Rset_ajax_obs("ajax_pic_weather_pic", "<img src =\"" + here + condition_img[25] + "\" />", "");
					Rset_ajax_obs("ajax_pic_weather_pic_text", condition_txt[25], "");
				} else 
				 	if(weather_trend <= -6) {		// rain warning - overrides zambretti forecast
					Rset_ajax_obs("beteljuice_map", "<img src = \"" + graphic + "\" alt = \"Sudden RAIN\" title = \"Sudden RAIN\" />", ""); 
					Rset_ajax_obs("ajax_pic_weather_pic", "<img src =\"" + here + condition_img[22] + "\" />", "");
					Rset_ajax_obs("ajax_pic_weather_pic_text", condition_txt[22], "");

 				} else {	// go with zambretti forecast
					Rset_ajax_obs("beteljuice_map", "<img src = \"" + graphic + "\" alt = \"" + what_forecast[0] + "\" title = \"" + what_forecast[0] + "\" />", ""); 
// fix for no weather graphic
					(condition_img[what_forecast[1]] != "" ? Rset_ajax_obs("ajax_pic_weather_pic", "<img src =\"" + here + condition_img[what_forecast[1]] + "\" />", "") : Rset_ajax_obs("ajax_pic_weather_pic", "", "") );
					Rset_ajax_obs("ajax_pic_weather_pic_text", condition_txt[what_forecast[1]], "");
				}
			}	// END existence check
// -- END weather 'map'



// --------- beteljuices DHTML (centigrade) stick thermometer
// ** beteljuice_thermometer_1C

			if(document.getElementById("beteljuice_thermometer_1C")) {	// existence check

// 1 deg C = 2.4px length of 'blank' on graphic	(temp range -10 to 40, 120px - 0px)

				inverse = 40 - temp_C;
				t1_C_height = (inverse * 2.4).toFixed(0);
				if(t1_C_height < 0) { t1_C_height = 0;}	// keep in graphic bounds (Max.)
				if(t1_C_height > 120) { t1_C_height = 120;}	// keep in graphic bounds (Min.)

// thermometerstr has been declared earlier

				Rset_ajax_obs("beteljuice_thermometer_1C", "<img src=\"" +here + "stuff/whitebit.png\" width=\"8\" height=\"" + t1_C_height + "\"  style=\"position: absolute; top:20px; left: 18px;\" " + "alt=\"" + thermometerstr_C + "\" " + "title=\"" + thermometerstr_C + "\" />", "" );

				inverse_max = 45 - temp_C_max;	// taking 7px font into account
				t1_C_max_height = (inverse_max * 2.4).toFixed(0);
				if(t1_C_max_height < 0) { t1_C_max_height = 0;}	// keep in graphic bounds (Max.)
				if(t1_C_max_height > 120) { t1_C_max_height = 120;}	// keep in graphic bounds (Min.)
				Rset_ajax_obs("beteljuice_thermometer_1C_max_value", temp_C_max.toFixed(1) , "" );

// this bits down and dirty but seems to work, it's why i have to check element to stop crashes
				grunt=document.getElementById("beteljuice_thermometer_1C_max").style.top = t1_C_max_height +"px";
				grunt=document.getElementById("beteljuice_thermometer_1C_max_value").style.top = t1_C_max_height -3 +"px";

				inverse_min = 45 - temp_C_min;	// taking 7px font into account
				t1_C_min_height = (inverse_min * 2.4).toFixed(0);
				if(t1_C_min_height < 0) { t1_C_min_height = 0;}	// keep in graphic bounds (Max.)
				if(t1_C_min_height > 120) { t1_C_min_height = 120;}	// keep in graphic bounds (Min.)
				Rset_ajax_obs("beteljuice_thermometer_1C_min_value", temp_C_min.toFixed(1) , "" );
				grunt=document.getElementById("beteljuice_thermometer_1C_min").style.top = t1_C_min_height +"px";
				grunt=document.getElementById("beteljuice_thermometer_1C_min_value").style.top = t1_C_min_height *1 +3 +"px";

// duplicate temperature value
				Rset_ajax_obs("beteljuice_thermometer_1C_value", temp_C.toFixed(1) , "&deg;C" );
// duplicate temp trend arrow
				Rset_ajax_obs("beteljuice_thermometer_1C_trend", ajax_genarrow( temp_trend, 0, '', langTempTrendRising + uom_temp, langTempTrendFalling + uom_temp, 1) , "");	

			}	// END existence check
// END thermometer_1C



// --------- beteljuices DHTML horizontal (c/f) thermometer
// ** beteljuice_thermometer_2CF

// 1 deg C = 4px movement of 'marker' on graphic	(temp range -25 to 55, 21px - 346px)

			if(document.getElementById("beteljuice_thermometer_2CF")) {	// existence check
				marker = 21 + ((temp_C + 25) * 4) ;
				t2_CF_offset = marker.toFixed(0);
				if(t2_CF_offset < 21) { t2_CF_offset = 21;}	// keep in graphic bounds (Min.)
				if(t2_CF_offset > 346) { t2_CF_offset = 346;}	// keep in graphic bounds (Max.)

// thermometerstr as before

				Rset_ajax_obs("beteljuice_thermometer_2CF", "<img src=\"" + here + "stuff/beteljuice_thermometer_marker.png\" width=\"12\" height=\"42\"  style=\"position: absolute; top:0px; left: " + t2_CF_offset + "px;\" " + "alt=\"" + thermometerstr_C + "\" " + "title=\"" + thermometerstr_C + "\" />", "" );
			} // END of existence check
// END thermo_2CF


// ------------ beteljuices 'feels like' thermometer colour band 'background 
// TIP - although it calculates the gradient by C, that doesn't matter - you can put F text on top just the same ;-)
// could be used for 'ordinary' temperature as well

			if(document.getElementById("beteljuice_temperature_band")) {	// existence check
				band = 0;
				temp_check = -25;
				if(feelslike_C || feelslike_C == 0) {	// don't even think of entering a while loop if you don't have any values !
					while(feelslike_C > temp_check) {
						temp_check = temp_check + 2.5;
						if(band == 29) { break; }	// safety net ! and max # of bands
						band++;
					}
				}
				Rset_ajax_obs("beteljuice_temperature_band", "<img src = \"" + here + "stuff/beteljuice_band_" + band + ".png\" width=80 height=39 border=1 alt=\"temperature band\" title=\"temperature band\" />", "");
				Rset_ajax_obs("beteljuice_feelslike", feelslike_C, "\&deg;C");
			} // END existence check
// END feelslike thermo



// ------------ beteljuices Cloud Base Height graphic (text only) #1 only - #2 uses existing 'variable'
// beteljuice_CBH

			Rset_ajax_obs("beteljuice_CBH", CBH_ft.toFixed(0) + " ft<br />" + CBH_m.toFixed(0) + " m", "");
// that's it !



// ------------ beteljuices (mm) Rain Gauge graphics (text and 'fill')
// a few things to set - so existence check first 

			if(document.getElementById("beteljuice_24_text") ) {	// existence check

// ** rain24 hr
			Rset_ajax_obs("beteljuice_24_text", rain_mm24.toFixed(1), "<br />mm");

// what about the fill
				if(rain_mm24 > 0) {
// 1st scale 24hr to fit
					if(rain_mm24 <= 19 && rain_mm24 >= 10) {	// not much to show - increase scale
						factor = 0.5;
					} else {
						if(rain_mm24 <= 9) {	// even less to show - increase scale more
							factor = 0.17;
						} else 					// 1:1 or decrease scale
						factor = Math.ceil(rain_mm24 / 50);	// 50px is max. fill height
					}

					fill24 = Math.ceil(rain_mm24 / factor); // round UP to make sure at least 1px display
					fill24 = "<img src=\"" + here + "stuff/beteljuice_bucket_colour.png\" height=" + fill24 + " width=22>";

				} else {
					fill24 = "";
				}
				Rset_ajax_obs("beteljuice_fill24", fill24, "");

// ----- now for rain last 60m
// rain_mm1 = 30.2;
				Rset_ajax_obs("beteljuice_60_text", rain_mm1.toFixed(1), "<br />mm");

				if(rain_mm1 > 0) {
// use same ratio as fill24 so the two buckets are 'to scale'
					fill60 = Math.ceil(rain_mm1 / factor); // round UP to make sure at least 1px display
					fill60 = "<img src=\"" + here + "stuff/beteljuice_bucket_colour.png\" height=" + fill60 + " width=22>";
				} else {
					fill60 = "";
				}
				Rset_ajax_obs("beteljuice_fill60", fill60, "");
// fun no rain image
				fun="";
				if(rain_mm24 == 0) {	// only need to check rain24 - if 60min MUST be in 24 ;-)
					fun = "<img src=\"" + here + "stuff/nah.gif\" style=\"position: absolute; bottom: 55px; left: 10px;\" alt= \"NO RAIN\" title = \"NO RAIN\" />";
				}
				Rset_ajax_obs("beteljuice_norain", fun, "");
			
				if(currdat[47]) {	// build 602+ rain rate existence check
					Rset_ajax_obs("ajaxrain_mm_rate2", rain_mm_rate.toFixed(1), " mm/hr");		// duplicate
				}
				if(rain_then_mm){
					Rset_ajax_obs("ajax_rain_mm_arrow2", ajax_genarrow(rain_mm_rate.toFixed(1), rain_then_mm, '', '', '', 0) , "");
				}
			
			} // END existence check

// END beteljuice rainbucket graphics




/* Wind Gust: definition
Is a sudden, brief increase in speed of the wind. According to U.S. weather observing practice,
gusts are reported when the peak wind speed reaches at least 16 knots and the variation
in wind speed between the peaks and lulls is at least 9 knots. 
The duration of a gust is usually less than 20 seconds. 

OK, we don't know what the 'lulls' are, so we'll make a dodgy assumption of 75% of AVERAGE
UNLESS now (gust) is LESS - 75% might need tweaking, but it's a 'near enough' decision anyway !
so that we can generate a bit of 'eye candy'. eg. (winds) upto xxx / Gusting upto xxx
This could be used for text / graphic / advisory ...... you should have got the idea by now ;-) 
*/


// ----- beteljuices Wind blurb ------------------------
/* uses:	wind_mph_ave					AVERAGE (10 mins) wind speed (mph)
					wind_mph							NOW (gust) wind speed (mph)
					wind_mph_recent				MAX (10 mins) wind speed (mph)
					wind_bf								beaufort force eg. 0
					langWindFrom						eg. "From the "
					valLangVerbose					eg. "West-Northwest"
					langBeaufort[wind_bf]				eg. "Moderate Gale"
					langBeaufort_desc[wind_bf]		eg. "Smoke rises vertically."
					valLang_ave			eg. "WNW"
			
			I don't have room for Average direction AND warning - so decision time
*/


			wind_warn = valLang_ave; // maybe overwritten by warning
			blurb = "Wind Ave: " + wind_mph_ave.toFixed(1) + " mph ";
//			if(wind_bf >= 7) wind_warn = "<font color = \"blue\">Caution !</font>";
//			if(wind_bf >= 9) wind_warn = "<font color = \"red\">DANGER !</font>";
			if(wind_mph_recent >= 30) wind_warn = "<font color = \"blue\">Caution !</font>";
			if(wind_mph_recent >= 46) wind_warn = "<font color = \"red\">DANGER !</font>";
			blurb += wind_warn ;
			blurb += "<br />Description: " + langBeaufort[wind_bf] + "<br />" + langBeaufort_desc[wind_bf] + "<br />";
			blurb += "Now: " + wind_mph.toFixed(1) + " mph ";
			if(wind_mph > 0) blurb += valLangVerbose; 
// work out 'gusting' eye candy - 9kts = 10.36 mph, 16kts = 18.4 mph, so
			lull_check = wind_mph_ave * 0.75;
			if(wind_mph < lull_check) lull_check = wind_mph; 
			lull = wind_mph_recent - lull_check ;
			gust_chk = (wind_mph_recent >= 18.4 && lull >= 10.36 ? "GUSTING " : "");
			blurb += "<br />" + gust_chk +"upto " + wind_mph_recent.toFixed(1) + " mph.";
			Rset_ajax_obs("wind_blurb", blurb, "");
// END wind blurb



// --------- beteljuices DHTML horizontal thermometer split temp / feel like
// ** beteljuice_thermometer_2C

// 1 deg C = 4px movement of 'marker' on graphic	(temp range -25 to 55, 21px - 346px)
// duplicate of what we did before shown for clarity
// outdoor temperature

			if(document.getElementById("beteljuice_thermometer_2C") ) {	// existence check
				marker = 21 + ((temp_C + 25) * 4) ;
				t2_C_offset = marker.toFixed(0);
				if(t2_C_offset < 21) { t2_C_offset = 21;}	// keep in graphic bounds (Min.)
				if(t2_C_offset > 346) { t2_C_offset = 346;}	// keep in graphic bounds (Max.)

// thermometerstr as before

				Rset_ajax_obs("beteljuice_thermometer_2C", "<img src=\"" + here + "stuff/beteljuice_top_pointer.png\" width=\"12\" height=\"42\"  style=\"position: absolute; top:0px; left: " + t2_CF_offset + "px;\" " + "alt=\"" + thermometerstr_C + "\" " + "title=\"" + thermometerstr_C + "\" />", "" );

// feel like marker
				feelslike_C = feelslike_C *1;	// force 'text' to numeric
				feels_marker = 21 + ((feelslike_C + 25) * 4) ;
				t2_feelC_offset = feels_marker.toFixed(0);
				if(t2_feelC_offset < 21) { t2_feelC_offset = 21;}	// keep in graphic bounds (Min.)
				if(t2_feelC_offset > 346) { t2_feelC_offset = 346;}	// keep in graphic bounds (Max.)

// thermometerstr as before

				Rset_ajax_obs("beteljuice_feels_2C", "<img src=\"" + here + "stuff/beteljuice_bottom_pointer.png\" width=\"12\" height=\"42\"  style=\"position: absolute; top:0px; left: " + t2_feelC_offset + "px;\" " + "alt=\"" + thermometerstr_C + "\" " + "title=\"" + thermometerstr_C + "\" />", "" );
			} // END existence check
// END thermometer_2C







// --------- END Extras and Duplicates ---------------------

			counterSecs = 0;                      // reset timer
			lastajaxtimeformat = ajaxtimeformat; // remember this time

		
		} // END filestamp check


		// 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 */
			Rset_ajax_obs("ajaxindicator",langPauseMsg, "");
		}
		Rset_ajax_obs('ajaxupdatecount',updates, "");       /* for test pages */
		Rset_ajax_obs('ajaxmaxupdatecount',maxupdates, ""); /* for test pages */


 	  } // END if(currdat content checks)

	 } // 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(currdatFile + '?' + new Date().getTime())", reloadTime); // get new data 
    }
  }
} // end ajaxLoader function



// invoke when first loaded on page
var ajax_attempt = 0;

function start_up() {
	if(document.getElementById('ajaxEND')) {
		ajaxLoader(currdatFile + '?' + new Date().getTime());
 		window.setInterval("ajax_countup()", 1000); // run the counter for seconds since update
	} else {
		ajax_attempt++;
		if(ajax_attempt >= 50) {
			betel('Page has failed to download fully'); // 50 attempts for page to format
		} else {
			setTimeout('start_up()', 200);
		}
	}
}

start_up();



/* this is for debug - errors within ajax can do all sorts of strange things !
   normal alert may or may not work, this being called outside of the loop is more likely
   to work (depends on the error)
   line before or line after where you think the problem is use
   betel("Here");
   or 
   betel(varname);
*/

function betel(msg) {
alert(msg);
}

// ]]>