/* ------------------------------------------------------------------
Project:        Flightmap
File:		metar.js
Abstract:	fetch metar/taf data from NWS
Version:	1.0
Authors:	Pascal Dreer / Joze Senegacnik

------------------------------------------------------------------ */


var xml_request;
var gwxml;
var firstConnection = true;
var fetchInProgress = false;
var updateTime = new Date();
var keepPastData = false;
var gMetricFormat = true;
var gShowLocalTime = true;

var metarTimer;
var metarTimer2;
var metarStations = [];


function startMetarInterval()
{
        var ids = "";
	for (var i = 0; i < gMappoints.length; i++)
        // joc // || gMappoints[i].type == 2 || gMappoints[i].type == 9) 
		if (gMappoints[i] != null && gMappoints[i].type == 1 ) { 
			if (gMappoints[i].code.length == 4) {
				ids = ids + gMappoints[i].code + ",";
				metarStations.push(gMappoints[i].code);
			}
		}
        getxmlNWS( ids );
	
	if (!metarTimer) {
		metarTimer = window.setInterval("getxmlNWS('" + ids + "')",60 * 1000 * 15);			// 15 min.
        }

	if (!metarTimer2) {
		metarTimer2 = window.setInterval("loadWXARSO()", 60 * 1000 * 10);			// 10 min.
  
      }

}


function stopMetarInterval()
{
	if (metarTimer)
		window.clearInterval(metarTimer);
}



function updateMetarInterval()
{
	for (var i = 0; i < metarStations.length; i++)
		metarStations.pop();
	
	if (metarTimer)
		window.clearInterval(metarTimer);
	
	startMetarInterval();
}

				
function putMetar(id, metar)
{
	for (var j=0;j<gMappoints.length;j++) {
		if (id.indexOf(gMappoints[j].code) >= 0) {
			gMappoints[j].metar = metar;
			gMappoints[j].flightrule = parseFlightRules(metar);
                        break;
		}
	}
}
				
function putTaf(id, taf)
{
	for (var j=0;j<gMappoints.length;j++) {
		if (id.indexOf(gMappoints[j].code) >= 0) {
			gMappoints[j].taf = taf;
                        break;
		}
	}
}


function getxmlNWS( station_ids ) {

  var responseText = "";
//  alert( station_ids );
  var wxurl = "http://weather.aero/dataserver_current/httpparam?dataSource=metars&requesttype=retrieve&format=xml&hoursBeforeNow=3&mostRecentForEachStation=constraint&stationString=" + station_ids;
  var url = "/flightmap/xmlLocal."+redirector+"?feedURL=" + escape( wxurl );

  /////////////// METARs
  GDownloadUrl( url, function(data, responseCode) {
//    alert( data );
    gwXml = GXml.parse(data);
    var metars = gwXml.documentElement.getElementsByTagName("METAR");

    if ( metars.length == 0 ) {
      alert ('No METAR reports loaded!');
      return;
    }

    for (var i = 0; i < metars.length; i++) {
        var metar = metars[i];
//      alert(i + ' '+ metars.length + ' METAR ' + metar.getElementsByTagName("raw_text")[0].firstChild.nodeValue);
        putMetar( metar.getElementsByTagName("station_id")[0].firstChild.nodeValue, metar.getElementsByTagName("raw_text")[0].firstChild.nodeValue); 
    }
    displayMPList();  
  });

  ////////////// TAFs
  wxurl = "http://weather.aero/dataserver_current/httpparam?dataSource=tafs&requesttype=retrieve&format=xml&hoursBeforeNow=3&mostRecentForEachStation=constraint&stationString=" + station_ids;
  var url = "/flightmap/xmlLocal."+redirector+"?feedURL=" + escape( wxurl );

  GDownloadUrl( url, function(data, responseCode) {
//    alert( data );
    gwXml = GXml.parse(data);
    var tafs = gwXml.documentElement.getElementsByTagName("TAF");
    if ( tafs.length == 0 ) {
      alert ('No TAF reports loaded!');
      return;
    }

    for (var i = 0; i < tafs.length; i++) {
       var taf = tafs[i];
  //   alert(i + ' '+ tafs.length + ' TAF ' + taf.getElementsByTagName("raw_text")[0].firstChild.nodeValue);
       putTaf( taf.getElementsByTagName("station_id")[0].firstChild.nodeValue, taf.getElementsByTagName("raw_text")[0].firstChild.nodeValue ); 
    }
  });
}



function displayStatusLine(elem,sourceStr,err)
{
	if (!gConfigShowMetar)
		return "";
	
	var ampmText = "";

	var lastUpdate = new Date();
	if (gMetricFormat) {
		var nowStr = ((lastUpdate.getHours() < 10) ? "0" + lastUpdate.getHours() : lastUpdate.getHours()) + ":"
					+ ((lastUpdate.getMinutes() < 10) ? "0" + lastUpdate.getMinutes() : lastUpdate.getMinutes());
		ampmText = "";
	}
	else {
		if (lastUpdate.getHours() >= 0 && lastUpdate.getHours() <= 11) {
			var nowStr = ((lastUpdate.getHours() < 10) ? "0" + lastUpdate.getHours() : lastUpdate.getHours()) + ":"
						+ ((lastUpdate.getMinutes() < 10) ? "0" + lastUpdate.getMinutes() : lastUpdate.getMinutes());
			ampmText = " AM";
		}
		else {
			var usHours = (lastUpdate.getHours() == 12) ? 12 : lastUpdate.getHours() - 12;
			var nowStr = ((usHours < 10) ? "0" + usHours : usHours) + ":"
						+ ((lastUpdate.getMinutes() < 10) ? "0" + lastUpdate.getMinutes() : lastUpdate.getMinutes());
			ampmText = " PM";
		}
	}
		
	var utcText = ((lastUpdate.getUTCHours() < 10) ? "0" + lastUpdate.getUTCHours() : lastUpdate.getUTCHours()) + ":"
					+ ((lastUpdate.getMinutes() < 10) ? "0" + lastUpdate.getMinutes() : lastUpdate.getMinutes());
	
	var updateText = "METAR updated at ";
	if (elem != null)
		document.getElementById(elem).style.color = "#009933";
	if (gShowLocalTime)
		return updateText + nowStr + ampmText + ". " + "Source: " + sourceStr + ".";
	else
		return updateText + nowStr + ampmText + " (" + utcText + " UTC). " + "Source: " + sourceStr + ".";

	if (err > 0) {
		var updateText = "METAR update failed at ";
		if (elem != null)
			document.getElementById(elem).style.color = "red";
		return updateText + nowStr + ampmText + ". " + "Source: " + sourceStr + ".";
	}
}


// -----------------------------------------------------------
// METAR PARSING
// -----------------------------------------------------------



function parseFlightRules(metarstr)
{
	var tmpstr = metarstr.substring(metarstr.indexOf(" ")+1,metarstr.length)

	var limit = tmpstr.length;

	var trend = tmpstr.indexOf("BECMG");					// omit trend data for flight condition evaluation
	if (trend > 0)
		limit = trend;
	var trend = tmpstr.indexOf("TEMPO");
	if (trend > 0 && trend < limit)
		limit = trend;
	var trend = tmpstr.indexOf("FM");
	if (trend > 0 && trend < limit)
		limit = trend;
	var trend = tmpstr.indexOf("INTER");
	if (trend > 0 && trend < limit)
		limit = trend;
	var trend = tmpstr.indexOf("RMK");
	if (trend > 0 && trend < limit)
		limit = trend;

	var mstr = tmpstr.substring(0,limit);

	if (mstr.length < 12)
		return "";


	var ceiling = 0;
	if (mstr.indexOf("CAVOK") >= 0 || mstr.indexOf("CLR ") >= 0 || mstr.indexOf("SKC") >= 0 || mstr.indexOf("NSC") >= 0 || mstr.indexOf("NCD") >= 0) {
		ceiling = 5000;
	}
	else {
		ceiling = 5000;
		var bkn = mstr.indexOf("BKN");
		if (bkn >= 0)
			ceiling = parseInt(mstr.substr(bkn+3,3),10) * 100;
			
		var ovc = mstr.indexOf("OVC");
		if (ovc >= 0) {
			var ovcCeiling = parseInt(mstr.substr(ovc+3,3),10) * 100;
			if (ovcCeiling < ceiling)
				ceiling = ovcCeiling;
		}
	}
	

	var visibility = 0;
	if (mstr.indexOf("9999") >= 0 || mstr.indexOf("10SM") >= 0) {
		visibility = 6;
	}
	else {
		var tmp = mstr.indexOf("SM ");
		if (tmp > 0) {
			var tmp3 = mstr.indexOf("/");
			if (tmp3 > 0 && tmp3 < tmp) {
				var miles = parseInt(mstr.substr(tmp3-1,1),10) / parseInt(mstr.substr(tmp3+1,1),10);
				visibility = miles;
			}
			else {
				var tmp2 = mstr.lastIndexOf(" ",tmp);
				var miles = parseInt(mstr.substring(tmp2+1,tmp),10);
				visibility = miles;
			}
		}
		else {
			var tmp = mstr.indexOf("KT ");
			if (tmp > 0) {
				if (mstr.charAt(tmp + 6) == "V")
					tmp = tmp + 10;
				
				var tmp2 = mstr.indexOf("0 ",tmp);
				if (mstr.charAt(tmp2-4) == " ") {
					visibility = parseInt(mstr.substr(tmp2-3,4),10) / 1.609344 / 1000;
				}
				else {
					visibility = 6;
				}
			}
			else {
				var tmp = mstr.indexOf("MPS ");
				if (tmp > 0) {
					if (mstr.charAt(tmp + 7) == "V")
						tmp = tmp + 11;
						
					var tmp2 = mstr.indexOf("0 ",tmp);
					if (mstr.charAt(tmp2-4) == " ") {
						visibility = parseInt(mstr.substr(tmp2-3,4),10) / 1.609344 / 1000;
					}
					else {
						visibility = 6;
					}
				}
				else {
					visibility = 6;
				}
			}
		}
	}

	if (ceiling < 500 || visibility < 1)
		return "LIFR";
	else
		if ((ceiling >= 500 && ceiling < 1000) || (visibility >= 1 && visibility < 3))
			return "IFR";
		else
			if ((ceiling >= 1000 && ceiling < 3000) || (visibility >= 3 && visibility < 5))
				return "MVFR";
			else
				if (ceiling >= 3000 && visibility >= 5)
					return "VFR";
				else
					return "";
}
