/*
 * Weather Calculator by Arno Paanstra - Copyright The MeteoGroup
 */

// Temperature:
// visa versa: Celsius <-> Fahrenheit <-> Kelvin

function c2k (celcius) {
	return celcius * 1 + 273.15;
}

function c2f (celcius) {
	return celcius * 1.8 + 32;
}

function f2k (fahrenheit) {
	return (fahrenheit * 1 + 459.67) / 1.8;
}

function f2c (fahrenheit) {
	return (fahrenheit * 1 - 32) / 1.8;
}

function k2c (kelvin) {
	return kelvin * 1 - 273.15;
}

function k2f (kelvin) {
	return (kelvin * 1.8) - 459.67;
}

// Wind:
// visa versa: Knots <-> m/s <-> km/h <-> mph <-> Beaufort
// base unit: m/s

function knots2ms (knots) {
	return knots * 0.5144444444;
}

function kmh2ms (kmh) {
	return kmh / 3.6;
}

function kmh2mph (kmh) {
	return kmh * 0.6215;
}

function mph2kmh (mph) {
	return mph * 1.609;
}

function mph2ms (mph) {
	return kmh2ms(mph2kmh(mph));
}

function ms2beaufort (ms) {
	if (ms < 0.2)
		return 0;
	if (ms <= 1.5)
		return 1;
	if (ms <= 3.3)
		return 2;
	if (ms <= 5.4)
		return 3;
	if (ms <= 7.9)
		return 4;
	if (ms <= 10.7)
		return 5;
	if (ms <= 13.8)
		return 6;
	if (ms <= 17.1)
		return 7;
	if (ms <= 20.7)
		return 8;
	if (ms <= 24.4)
		return 9;
	if (ms <= 28.4)
		return 10;
	if (ms <= 32.6)
		return 11;

	return 12;
}

function ms2knots (ms) {
	return ms * 1.9438445;
}

function ms2kmh (ms) {
	return ms * 3.6;
}

function ms2mph (ms) {
	return kmh2mph(ms2kmh(ms));
}

function beaufort2ms (beaufort) {
	if (beaufort == 0)
		return "<0.2";
	if (beaufort == 1)
		return "0.3 - 1.5";
	if (beaufort == 2)
		return "1.6 - 3.3";
	if (beaufort == 3)
		return "3.4 - 5.4";
	if (beaufort == 4)
		return "5.5 - 7.9";
	if (beaufort == 5)
		return "8.0 - 10.7";
	if (beaufort == 6)
		return "10.8 - 13.8";
	if (beaufort == 7)
		return "13.9 - 17.1";
	if (beaufort == 8)
		return "17.2 - 20.7";
	if (beaufort == 9)
		return "20.8 - 24.4";
	if (beaufort == 10)
		return "24.5 - 28.4";
	if (beaufort == 11)
		return "28.5 - 32.6";
	if (beaufort == 12)
		return ">32.6";

	return "";
}

function beaufort2knots (beaufort) {
	if (beaufort == 0)
		return "<1";
	if (beaufort == 1)
		return "1 - 3";
	if (beaufort == 2)
		return "4 - 6";
	if (beaufort == 3)
		return "7 - 10";
	if (beaufort == 4)
		return "11 - 16";
	if (beaufort == 5)
		return "17 - 21";
	if (beaufort == 6)
		return "22 - 27";
	if (beaufort == 7)
		return "28 - 33";
	if (beaufort == 8)
		return "34 - 40";
	if (beaufort == 9)
		return "41 - 47";
	if (beaufort == 10)
		return "48 - 55";
	if (beaufort == 11)
		return "56 - 63";
	if (beaufort == 12)
		return ">63";

	return "";
}

function beaufort2kmh (beaufort) {
	if (beaufort == 0 )
		return "<1.1";
	if (beaufort == 1 )
		return "1.1 - 5.4";
	if (beaufort == 2 )
		return "5.5 - 11.9";
	if (beaufort == 3 )
		return "12.0 - 19.4";
	if (beaufort == 4 )
		return "19.5 - 28.4";
	if (beaufort == 5 )
		return "28.5 - 38.5";
	if (beaufort == 6 )
		return "38.6 - 49.7";
	if (beaufort == 7 )
		return "49.8 - 61.5";
	if (beaufort == 8 )
		return "61.6 - 74.5";
	if (beaufort == 9 )
		return "74.6 - 87.8";
	if (beaufort == 10 )
		return "87.9 - 102.2";
	if (beaufort == 11 )
		return "102.3 - 117.3";
	if (beaufort == 12 )
		return ">117.4";

	return "";
}

function beaufort2mph (beaufort) {
	if (beaufort == 0 )
		return "<0.7";
	if (beaufort==1 )
		return "0.7 - 3.5";
	if (beaufort==2 )
		return "3.6 - 7.5";
	if (beaufort==3 )
		return "7.6 - 12.2";
	if (beaufort==4 )
		return "12.3 - 17.8";
	if (beaufort==5 )
		return "17.9 - 24.0";
	if (beaufort==6 )
		return "24.1 - 31.0";
	if (beaufort==7 )
		return "31.1 - 38.3";
	if (beaufort==8 )
		return "38.4 - 46.4";
	if (beaufort==9 )
		return "46.5 - 54.7";
	if (beaufort==10 )
		return "54.8 - 63.6";
	if (beaufort==11 )
		return "63.7 - 73.0";
	if (beaufort==12 )
		return ">73.0"

	return "";
}

// Humidity:
// input: tt && (td || rh)
// output: (td || rh)

function tttd2rh (tt, td) {
	tt *= 1;
	td *= 1;

	var Es = 6.112 * Math.pow(10.0, (7.5 * tt / (237.7 + tt)));
	var E  = 6.112 * Math.pow(10.0, (7.5 * td / (237.7 + td)));

	return Math.round((E / Es * 100) * 10 ) / 10;
}

function ttrh2td (tt, rh) {
	tt *= 1;
	rh *= 1;
	
	var Es = 6.112 * Math.pow(10.0, (7.5 * tt / (237.7 + tt)));
	var E  = (rh*Es) / 100;

	return Math.round((-430.22 + 237.7 * Math.log(E) / Math.log(Math.E)) / (-1 * Math.log(E) / Math.log(Math.E) + 19.08) * 10 ) / 10;
}

// Wind Chill:
// input: tt (c), ff (kmh)
// output: wc(usa), wc(steadmann)

// -50F to 50F	3 MPH to 110 MPH
function windchillUsa (tt, ff) {
	tt *= 1;
	ff *= 1;
	return (13.12 + 0.6215 * tt - 11.37 * Math.pow(ff,0.16)+0.3965 * tt * Math.pow(ff,0.16));
}

// tt < 6c	ff > 4 kts
function windchillSteadmann (tt, ff) {
	tt *= 1;
	ff *= 1;
	
	//return  tt + 0.0294 * (tt - 12) * (ms2knots(kmh2ms(ff)) - 4);
	ff = kmh2ms(ff);
	return 1.41 - 1.1620 * ff + 0.9800 * tt + 0.0124 * ff * ff + 0.0185 * ff * tt;
	
	
}

// Air pressure:
// visa versa: hPa <-> mbar <-> inHg <-> Torr(mmHg) <-> atm
// base unit: hPa

function hpa2mbar (hpa) {
	return hpa * 1;
}

function hpa2inhg (hpa) {
	return hpa * 0.0295300;
}

function hpa2torr (hpa) {
	return hpa * 0.750062;
}

function hpa2atm (hpa) {
	return hpa / 1013.25;
}

function mbar2hpa (mbar) {
	return mbar * 1;
}

function inhg2hpa (inhg) {
	return inhg * 33.8639;
}

function torr2hpa (torr) {
	return torr * 1.333224;
}

function atm2hpa (atm) {
	return atm * 1013.25;
}

// Heatindex
// input: tt, rh
// output: heatindex in tt and text

function ttrh2hi (tt, rh) {
	ttf = c2f(tt);
	rh *= 1;

	return f2c(-42.379 + 2.04901523*ttf + 10.14333127*rh - 0.22475541*ttf*rh - 6.83783*Math.pow(10,-3)*ttf*ttf - 5.481717*Math.pow(10,-2)*rh*rh + 1.22874*Math.pow(10,-3)*ttf*ttf*rh + 8.5282*Math.pow(10,-4)*ttf*rh*rh - 1.99*Math.pow(10,-6)*ttf*ttf*rh*rh);
}
	   
var hicat = new Array();
hicat["en"] = ["No danger","Caution","Extreme caution","Danger","Extreme danger"];
hicat["nl"] = ["Geen gevaar","Blijf alert","Voorzichtigheid geboden","Gevaar","Groot gevaar"];
hicat["de"] = ["Keine Gefahr","Vorsicht","Grosse Vorsicht","Gefahr","Grosse Gefahr"];
hicat["fr"] = ["Pas de danger","Prudence","Extrême prudence","Danger","Danger extrëme"];
hicat["se"] = ["Ingen fara","Försiktighet","Stor försiktigthet","Fara","Extrem fara"];
	        
function hi2cat (tt) {
	if (tt < 26.67)
		return 0;
	else if (tt < 32.22)
		return 1;
	else if (tt < 40.56)
		return 2;
	else if (tt < 54.44)
		return 3;
	else
		return 4;
}

// Calculate

function round(value, decimals) {
	return (Math.round(value*Math.pow(10,decimals))/Math.pow(10,decimals));
}

function calculate (lmt) {

	if (lmt.form.name == "temperature") {
		ttc = "";
		ttf = "";
		ttk = "";

		if (lmt.form.celcius.value != "") {
			ttc = lmt.form.celcius.value;
			ttf = round(c2f(ttc), 1);
			ttk = round(c2k(ttc), 1);
		}
		else if (lmt.form.fahrenheit.value != "") {
			ttf = lmt.form.fahrenheit.value;
			ttc = round(f2c(ttf), 1);
			ttk = round(f2k(ttf), 1);
		}
		else if (lmt.form.kelvin.value != "") {
			ttk = lmt.form.kelvin.value;
			ttc = round(k2c(ttk), 1);
			ttf = round(k2f(ttk), 1);
		}

		lmt.form.celcius.value = ttc;
		lmt.form.fahrenheit.value = ttf;
		lmt.form.kelvin.value = ttk;
	}
	else if (lmt.form.name == "wind") {
		ffk   = "";
		ffms  = "";
		ffkmh = "";
		ffmph = "";
		ffbft = "";

		if (lmt.form.bft.value != "") {
			ffbft = Math.round((lmt.form.bft.value));
			if (ffbft < 0 || ffbft > 12) {
				lmt.form.bft.value = "";
			}
			else {
				lmt.form.kn.value = beaufort2knots(ffbft);
				lmt.form.ms.value = beaufort2ms(ffbft);
				lmt.form.kmh.value = beaufort2kmh(ffbft);
				lmt.form.mph.value = beaufort2mph(ffbft);
			}
		}
		else {
			if (lmt.form.kn.value != "") {
				ffk = lmt.form.kn.value;
				ffms = knots2ms(ffk);
			}
			else if (lmt.form.ms.value != "") {
				ffms = lmt.form.ms.value;
			}
			else if (lmt.form.kmh.value != "") {
				ffkmh = lmt.form.kmh.value;
				ffms = kmh2ms(ffkmh);
			}
			else if (lmt.form.mph.value != "") {
				ffmph = lmt.form.mph.value;
				ffms = mph2ms(ffmph);
			}

			lmt.form.kn.value = round(ms2knots(ffms), 1);
			lmt.form.ms.value = round(ffms, 1);
			lmt.form.kmh.value = round(ms2kmh(ffms), 1);
			lmt.form.mph.value = round(ms2mph(ffms), 1);
			lmt.form.bft.value = ms2beaufort(ffms);
		}
	}
	else if (lmt.form.name == "humidity") {
		if (lmt.form.temperature.value != "") {
			tt = lmt.form.temperature.value;

			if (lmt.form.dewpoint.value != "") {
				td = lmt.form.dewpoint.value;
				rh = round(tttd2rh(tt, lmt.form.dewpoint.value), 1);
			}
			else if (lmt.form.humidity.value != "") {
				rh = lmt.form.humidity.value;
				td = round(ttrh2td(tt, lmt.form.humidity.value), 1);
			}

			lmt.form.dewpoint.value = td;
			lmt.form.humidity.value = rh;
		}
	}
	else if (lmt.form.name == "windchill") {
		if (lmt.form.temperature.value != "" && lmt.form.windspeed.value != "") {
			tt = lmt.form.temperature.value;
			ff = lmt.form.windspeed.value;
			wcusa =	windchillUsa (tt, ff);
			wcsteadmann = windchillSteadmann (tt, ff);

			lmt.form.wcusa.value = round(wcusa, 1);
			lmt.form.wcsteadmann.value = round(wcsteadmann, 1);
		}
	}
	else if (lmt.form.name == "pressure") {
		hpa = "";

		if (lmt.form.hpa.value != "") {
			hpa = lmt.form.hpa.value;
		}
		else if (lmt.form.mbar.value != "") {
			hpa = mbar2hpa(lmt.form.mbar.value);
		}
		else if (lmt.form.inhg.value != "") {
			hpa = inhg2hpa(lmt.form.inhg.value);
		}
		else if (lmt.form.mmhg.value != "") {
			hpa = torr2hpa(lmt.form.mmhg.value);
		}
		else if (lmt.form.atm.value != "") {
			hpa = atm2hpa(lmt.form.atm.value);
		}

		lmt.form.hpa.value = round(hpa , 2);
		lmt.form.mbar.value = round(hpa2mbar(hpa), 2);
		lmt.form.inhg.value = round(hpa2inhg(hpa), 2);
		lmt.form.mmhg.value = round(hpa2torr(hpa), 2);
		lmt.form.atm.value = round(hpa2atm(hpa), 2);
	}
	else if (lmt.form.name == "heatindex") {
		if (lmt.form.temperature.value != "" && lmt.form.humidity.value != "") {
			tt = lmt.form.temperature.value;
			rh = lmt.form.humidity.value;
			hi = ttrh2hi(tt, rh);
			hic = hi2cat(hi);

			lmt.form.hi.value = round(hi, 1);
			lmt.form.hicat.value = hicat[language][hic];
		}
	}
}

// Validate

function validate (lmt) {
	if (isNaN(Number(lmt.value))) lmt.value = "";
}
