var map = null;
var owners = new Array();
var station_data = get_data();
var selected_programs = new Array();
var selected_options = new Array();
var display_labels = false;
var userpgm = null;
var userop = null;
var stniconimg = null;
var histstniconimg = null;
var badstnisonimg = null;
var tsunamiiconimg = null;
var infowindow = null;
// ID for map divs.
var ndbcmaplink;
var ndbcmaptotals;
var tsunamilinks;
var historicallinks;
var curLatLong;
var status_R;
var status_H;
var curLatLong;
var regionpicker;
var regionpolygon = null;

var op = null;
var mylabels = null;
var firstload = null;
var lblcount = 0;
var lblint = null;

var regions = {
	'tatl' : {'name':'Atlantic (Tropical)','lat':-0.7,'lon':-7.8,'zoom':3,'swlat':-22.5,'swlon':-56.6,'nelat':22.5,'nelon':5.0},
	'watl' : {'name':'Atlantic (West)','lat':27.9,'lon':-61.3,'zoom':5,'swlat':19.2,'swlon':-74.4,'nelat':36.0,'nelon':-56.7},
	'aus'  : {'name':'Australia','lat':-37.5,'lon':139.8,'zoom':3,'swlat':-61.3,'swlon':73.8,'nelat':-2.0,'nelon':-155.2},
	'ben'  : {'name':'Bay of Bengal','lat':9.3,'lon':88.1,'zoom':4,'swlat':-9.5,'swlon':55.0,'nelat':27.5,'nelon':120.8},
	'car'  : {'name':'Caribbean Sea','lat':14.6,'lon':-73.5,'zoom':5,'swlat':5.4,'swlon':-89.9,'nelat':23.6,'nelon':-57.3},
	'ca'   : {'name':'Central America','lat':13.0,'lon':-94.2,'zoom':5,'swlat':3.7,'swlon':-110.6,'nelat':22.1,'nelon':-77.9},
	'ch'   : {'name':'Chile','lat':-19.7,'lon':-78.3,'zoom':5,'swlat':-28.4,'swlon':-94.8,'nelat':-10.5,'nelon':-61.9},
	'eur'  : {'name':'Europe','lat':51.3,'lon':-2.3,'zoom':4,'swlat':37.7,'swlon':-35.3,'nelat':61.7,'nelon':30.6},
	'gak'  : {'name':'Gulf of Alaska','lat':56.8,'lon':-145.6,'zoom':5,'swlat':51.3,'swlon':-162.0,'nelat':61.6,'nelon':-129.2},
	'wgom' : {'name':'Gulf of Mexico (West)','lat':26.8,'lon':-92,'zoom':6,'swlat':22.5,'swlon':-100,'nelat':31.0,'nelon':-83.8},
	'fl'   : {'name':'Gulf of Mexico (East)/Florida','lat':26.6,'lon':-81.6,'zoom':6,'swlat':22.8,'swlon':-89.7,'nelat':30.6,'nelon':-73.5},
	'ns'   : {'name':'Nova Scotia','lat':44.6,'lon':-58.4,'zoom':6,'swlat':41.2,'swlon':-66.5,'nelat':47.8,'nelon':-50.3},
	'npac' : {'name':'Pacific (North)','lat':37.2,'lon':173.7,'zoom':3,'swlat':2.0,'swlon':107.5,'nelat':61.3,'nelon':-120.5},
	'wpac' : {'name':'Pacific (West)','lat':-2.7,'lon':162.2,'zoom':4,'swlat':-21.0,'swlon':129.5,'nelat':16.1,'nelon':-165.3},
	'ak'   : {'name':'USA-Alaska','lat':62.9,'lon':-146.9,'zoom':4,'swlat':52.8,'swlon':-180,'nelat':70.3,'nelon':-129.2},
	'ha'   : {'name':'USA-Hawaii','lat':21.8,'lon':-163.4,'zoom':5,'swlat':12.8,'swlon':-179.7,'nelat':30.4,'nelon':-147.0},
	'egl'  : {'name':'USA-Great Lakes (East)','lat':44.0,'lon':-83.5,'zoom':6,'swlat':40.5,'swlon':-91.6,'nelat':47.2,'nelon':-75.4},
	'lsup' : {'name':'USA-Lake Superior','lat':47.4,'lon':-88.2,'zoom':7,'swlat':45.9,'swlon':-92.1,'nelat':48.8,'nelon':-84.2},
	'neus' : {'name':'USA-Northeast','lat':41.5,'lon':-70.1,'zoom':6,'swlat':38.0,'swlon':-78.2,'nelat':44.9,'nelon':-62.0},
	'nwus' : {'name':'USA-Northwest','lat':47.7,'lon':-127.7,'zoom':5,'swlat':40.9,'swlon':-144.1,'nelat':53.6,'nelon':-111.3},
	'seus' : {'name':'USA-Southeast','lat':34.2,'lon':-75.3,'zoom':6,'swlat':30.3,'swlon':-83.4,'nelat':38.0,'nelon':-67.2},
	'swus' : {'name':'USA-Southwest','lat':36.1,'lon':-126.2,'zoom':5,'swlat':28.1,'swlon':-142.6,'nelat':43.4,'nelon':-109.8},
	'world': {'name':'World','lat':0,'lon':-120,'zoom':1,'swlat':-79.0,'swlon':-180.0,'nelat':84.7,'nelon':180.0}
}

// assign null program attributes to owners
for( i = 0 ; i < station_data.owner.length ; i++ ) {
	owners[i]={name:station_data.owner[i]};
	owners[i].recent=false;
	for( j = 0 ; j < station_data.program.length ; j++ ) {
		eval("owners[i]."+station_data.program[j].replace(/[^A-za-z0-9]/g,"")+"=null");
	}
}

for( i = 0 ; i < station_data.station.length; i++ ) {
	var tmp_owner = station_data.station[i].owner;
	var tmp_program = station_data.station[i].program;
	eval("owners[tmp_owner]."+station_data.program[tmp_program].replace(/[^A-za-z0-9]/g,"")+"=true");
	if (station_data.station[i].status == 'E') {
		owners[tmp_owner].recent = true;
	}
}

function initialize() {

  	// Defaults for user parameters.
	var userlat = 20;
	var userlon = -120;
	var userzoom = 1;
	var usermaptype = google.maps.MapTypeId.HYBRID;
	var userstatus = 'R';

  	if (!(document.getElementById('status_R') && document.getElementById('status_H')
		&& document.getElementById('ndbcmaplink') && document.getElementById('ndbcmaptotals')
		&& document.getElementById('tsunamilinks') && document.getElementById('historicallinks')
		&& document.getElementById('latlnglabel') && document.getElementById('regionpicker'))) {
		alert("Sorry.  Your browser does not support this application.");
		exit;
	}

	status_R = document.getElementById('status_R');
	status_H = document.getElementById('status_H');
	show_labels = document.getElementById('show_labels');
	ndbcmaplink = document.getElementById('ndbcmaplink');
	ndbcmaptotals = document.getElementById('ndbcmaptotals');
	tsunamilinks = document.getElementById('tsunamilinks');
	historicallinks = document.getElementById('historicallinks');
	curLatLong = document.getElementById('latlnglabel');
	regionpicker = document.getElementById('regionpicker');

	var html = 'Select a region:</br ><ul>';
	for (r in regions) {
		html += '<li><a href="javascript:gotoregion(\''+r+'\');" onmouseover="showRegionPolygon(\''+r+'\');" onmouseout="clearRegionPolygon(\''+r+'\');">'+regions[r].name+'</a></li>'
	}
	html += '</ul>';

	document.getElementById('regionpicker').innerHTML = html;
	var userparms = location.search.substring(1);
	var userpairs = userparms.split('&');
	for (var i=0;i<userpairs.length;i++) {
		var eq = userpairs[i].indexOf('=');
		var arg = userpairs[i].substring(0,eq).toLowerCase();
		var val = decodeURIComponent(userpairs[i].substring(eq+1).toLowerCase());
		switch (arg) {
			case 'lat': if (!isNaN(val)) { var tmp = parseFloat(val); if (!isNaN(tmp)) { userlat = tmp; }} break;
			case 'lon': if (!isNaN(val)) { var tmp = parseFloat(val); if (!isNaN(tmp)) { userlon = tmp; }} break;
			case 'zoom': if (!isNaN(val)) { var tmp = parseInt(val); if (!isNaN(tmp) && tmp >=1 && tmp <=9) { userzoom = tmp; }} break;
			case 'type':
				if (val == 'm') { usermaptype = google.maps.MapTypeId.ROADMAP; }
				if (val == 'k') { usermaptype = google.maps.MapTypeId.SATELLITE; }
				if (val == 'h') { usermaptype = google.maps.MapTypeId.HYBRID; }
				if (val == 't') { usermaptype = google.maps.MapTypeId.TERRAIN; }
				break;
			case 'status':
				if (val == 'r') { status_R.checked = true; }
				if (val == 'h') { status_H.checked = true; }
				break;
			case 'pgm':

				userpgm = val.split("|");
				break;
			case 'op':

				userop = val.split("|");
				break;
			case 'ls':
				if(val=="true"){
					display_labels = true;
				}
		}
	}

	show_labels.onclick=function(){
		if(this.checked){
			display_labels=true;
			if(!mylabels){
				mylabels=new Array();
				lblint = setInterval('createLabels()',1);
			}else{
				changeDisplay("op");
				genLink();
			}
		}else{
			display_labels=false;
			changeDisplay("op");
			genLink();
		}
	}

	if(display_labels==true){
		show_labels.checked=true;
		mylabels=new Array();
		lblint = setInterval('createLabels()',1);
	}
	generate_program_tab();

    var latlng = new google.maps.LatLng(userlat, userlon);
    var myOptions = {
      zoom: userzoom,
      minZoom: 1,
      maxZoom: 9,
      center: latlng,
      scaleControl: true,
      scaleControlOptions: { position: google.maps.ControlPosition.RIGHT_BOTTOM },
      streetViewControl: false,
      mapTypeId: usermaptype
    };
    map = new google.maps.Map(document.getElementById("ndbcmap"),
        myOptions);
//    map.enableKeyDragZoom();
    map.enableKeyDragZoom({
            visualEnabled: true,
            visualPosition: google.maps.ControlPosition.LEFT,
            visualPositionOffset: new google.maps.Size(35, 0),
            visualPositionIndex: null,
            visualSprite: "/images/maps/markers/dragzoom_btn.png",
            visualSize: new google.maps.Size(20, 20),
            visualTips: {
             off: "Turn on drag zoom mode",
             on: "Turn off drag zoom mode"
            }
         });
    stniconimg = new google.maps.MarkerImage('/images/maps/markers/tiny_active_marker.gif',
    	new google.maps.Size(11,11), new google.maps.Point(0,0), new google.maps.Point(5,5)
    );
    histstniconimg = new google.maps.MarkerImage('/images/maps/markers/tiny_historical_marker.gif',
    	new google.maps.Size(11,11), new google.maps.Point(0,0), new google.maps.Point(5,5)
    );
    badstniconimg = new google.maps.MarkerImage('/images/maps/markers/tiny_inactive_marker.gif',
    	new google.maps.Size(11,11), new google.maps.Point(0,0), new google.maps.Point(5,5)
    );
    tsunamiiconimg = new google.maps.MarkerImage('/images/maps/markers/tiny_tsunami_event_marker.gif',
    	new google.maps.Size(19,19), new google.maps.Point(0,0), new google.maps.Point(9,9), new google.maps.Size(19,19)
    );
    var len = station_data.station.length;
    var deployed = 0;
    var reporting = 0;
	for (var i=0;i<len;i++) {
        station_data.station[i].marker = createMarker(
            station_data.station[i].id, //id
            station_data.station[i].name, //name
            station_data.owner[station_data.station[i].owner], //owner (relational)
            station_data.program[station_data.station[i].program], //program (relational)
            station_data.station[i].status, //status
            station_data.station[i].data, //data
            station_data.station[i].seq, //seq for TAO stations
            station_data.station[i].lat, //latitude
            station_data.station[i].lon //longitude
        );

        if (status_R.checked && station_data.station[i].status != 'E') { station_data.station[i].marker.setVisible(false); }
        if (station_data.station[i].status == 'E') {
            deployed++;
            if (station_data.station[i].data == 'y') { reporting++; }
        }
    }
    changeDisplay('init');
	genLink();
	// idle event is fired when map becomes idle after panning or zooming
	google.maps.event.addListener(map, 'idle', function() { genLink(); });
	google.maps.event.addListener(map, 'maptypeid_changed', function() { genLink(); });
	google.maps.event.addListener(map,'mousemove',function(e){
		if(curLatLong) curLatLong.innerHTML = formatLat(Math.round(e.latLng.lat()*100)/100)+ ", "+ formatLon(Math.round(e.latLng.lng()*100)/100);
	});
	google.maps.event.addListener(map, 'mouseout', function() { curLatLong.innerHTML=''; });
}

function get_data() {
    if( typeof XMLHttpRequest == "undefined" ) {
       XMLHttpRequest = function() {
          try { return new ActiveXObject("Msxml2.XMLHTTP.6.0") } catch(e) {}
          try { return new ActiveXObject("Msxml2.XMLHTTP.3.0") } catch(e) {}
          try { return new ActiveXObject("Msxml2.XMLHTTP") } catch(e) {}
          try { return new ActiveXObject("Microsoft.XMLHTTP") } catch(e) {}
          throw new Error( "This browser does not support XMLHttpRequest." )
       }
    }
    var request =  new XMLHttpRequest();
    request.open( "GET" , "ndbcmapstations.json" , false) ;
    request.send( "" );
    eval( "var n = " + request.responseText );
    return n;
}

function gotoregion(r) {
	if (regions[r] == undefined) { return; }
	map.setOptions({center:new google.maps.LatLng(regions[r]['lat'],regions[r]['lon']),zoom:regions[r]['zoom']});
}

function showRegionPolygon(r) {
	if (r == 'world') { return; }
	if (regions[r] != undefined) {
		regionpolygon = new RegionOverlay(new google.maps.LatLngBounds(new google.maps.LatLng(regions[r]['swlat'],regions[r]['swlon']),new google.maps.LatLng(regions[r]['nelat'],regions[r]['nelon'])),map);
	}
}

function clearRegionPolygon(r) {
	if (r == 'world') { return; }
	if (regionpolygon != null) {
		regionpolygon.setMap(null);
		regionpolygon = null;
	}
}

function createLabels(){
	show_labels.disabled=true
	show_labels.parentNode.childNodes[1].nodeValue = "Loading Labels..."

	for( i = 0; i < 50; i++) {
		var lblcount2 = (lblcount * 50) + i;
		if (lblcount2 >= station_data.station.length) {
			clearInterval(lblint);
			changeDisplay("op");
			genLink();
			show_labels.disabled=false
			show_labels.parentNode.childNodes[1].nodeValue = "Show Labels"
			break;
		}
		var point = new google.maps.LatLng(station_data.station[lblcount2].lat , station_data.station[lblcount2].lon)
		var name = station_data.station[lblcount2].id.toUpperCase()
		mylabels[lblcount2] = new Label( map, point , name);
	}
	lblcount++;
}

function createMarker(stn,stnname,owner,pgm,status,data,seq,lat,lon) {
    var stnpos = new google.maps.LatLng(lat,lon);
    var marker = null;
    var title = stn.toUpperCase();
    if (stnname) { title += ' - '+stnname; }
    if (status == 'E') {
       if (data == 'y') {
          if (station_data.dartevents[stn] != undefined) {
             marker = new google.maps.Marker({map:map,position:stnpos,title:title,icon:tsunamiiconimg,optimized:false,zIndex:google.maps.Marker.MAX_ZINDEX+1000});
          } else {
             marker = new google.maps.Marker({map:map,position:stnpos,title:title,icon:stniconimg});
          }
       } else {
          marker = new google.maps.Marker({map:map,position:stnpos,title:title,icon:badstniconimg});
       }
    } else {
       marker = new google.maps.Marker({map:map,position:stnpos,title:title,icon:histstniconimg});
    }
    google.maps.event.addListener(marker, "click", function() {
       var html = null;
       if (pgm == 'TAO' && seq != null) {
          html = '<strong>Station '+stn.toUpperCase()+'<br />'+owner+'<br />Location:<\/strong> '+formatLat(lat)+' '+formatLon(lon)+'<br /><a href="http://tao.noaa.gov/refreshed/site.php?site='+seq+'" target="_blank">View Details<\/a> <img src="/images/new_window.png" width="16" height="16" alt="Opens in new window" title="Opens in new window" style="vertical-align:text-top" \/>';
       } else if (pgm == 'Tsunami') {
          html = '<img src="/plot_dart.php?station='+stn.toUpperCase()+'&uom=M&width=400&height=220" height="220" width="400" alt="Five-day plot of water level at '+stn+'"/><br />';
          if (station_data.dartevents[stn] != undefined) {
             html += '<a href="/station_page.php?station='+stn+'&type=2&seriestime='+station_data.dartevents[stn]+'" target="_blank">View Event Details<\/a> <img src="/images/new_window.png" width="16" height="16" alt="Opens in new window" title="Opens in new window" style="vertical-align:text-top" \/>';
          } else {
             html += '<a href="/station_page.php?station='+stn+'" target="_blank">View Details<\/a> <img src="/images/new_window.png" width="16" height="16" alt="Opens in new window" title="Opens in new window" style="vertical-align:text-top" \/>';
          }
       } else {
          populateInfoWindow(stn,stnpos,owner);
       }
       if (html != null) {
          if (infowindow  != null) { infowindow.close(); }
          infowindow = new google.maps.InfoWindow({content:html,position:stnpos});
          infowindow.open(map);
       }
    });
    return marker;
}

function genLink() {
	if (ndbcmaplink && map) {
		var lat = map.getCenter().lat();
		var lon = map.getCenter().lng();
		// Use LatLng to normalize longitude to -180 to 180.
		var c = new google.maps.LatLng(lat,lon);
		var lat = c.lat().toFixed(6);
		var lon = c.lng().toFixed(6);
		var zoom = map.getZoom();
		var type = map.getMapTypeId();
		if (type == google.maps.MapTypeId.ROADMAP) {
			type = 'm';
		} else if (type == google.maps.MapTypeId.SATELLITE ) {
			type = 'k';
		} else if (type == google.maps.MapTypeId.TERRAIN ) {
			type = 't';
		} else {
			type = 'h';
		}
		var status = status_R.checked?'r':'h';
		var pgm = selected_programs.join("|");
		var op = selected_options.join("|");
		var ls = display_labels;
		ndbcmaplink.href = location.pathname+'?lat='+lat+'&lon='+lon+'&zoom='+zoom+'&type='+type+'&status='+status+'&pgm='+pgm+'&op='+op+'&ls='+ls;
	}
}

function changeDisplay(mode) {
	var deployed =0;
	var reporting = 0;
	var pgm = selected_programs
	if (! pgm || pgm.length < 1) { pgm = ['All']; }
	var op = selected_options;
	if (! op || op.length < 1 ) { op = ['All']; }
	if (mode == 'pgm') { op = ['All']; }
	var status = status_R.checked?'R':'H';
	for (i=0;i<station_data.station.length;i++) {
		var typeowner = station_data.owner[station_data.station[i].owner]; //relational
		var typeprogram = station_data.program[station_data.station[i].program];
		var stationtype = station_data.station[i].type
		if (typeprogram == 'NDBC Meteorological/Ocean') {
			if (stationtype.toLowerCase()=="fixed") {
				var tmptypeowner = new Array();
				tmptypeowner[0]=typeowner;
				tmptypeowner[1]='C-MAN';
				typeowner = tmptypeowner
			} else {
				var tmptypeowner = new Array();
				tmptypeowner[0]=typeowner;
				tmptypeowner[1]='Moored Buoys';
				typeowner = tmptypeowner
			}
		}
		if ((pgm[0] == 'All' || array_match(pgm,station_data.program[station_data.station[i].program] ) )
			&& (op[0] == 'All' || array_match(op,typeowner))
			&& ((status == 'R' && station_data.station[i].status == 'E') || (status != 'R'))) {
			station_data.station[i].marker.setVisible(true);
			if (display_labels&&mylabels) {
				mylabels[i].show()
			} else if(mylabels) {
				mylabels[i].hide()
			}
			if (station_data.station[i].status == 'E') {
				deployed++;
				if (station_data.station[i].data == 'y') { reporting++; }
			}
		} else {
			station_data.station[i].marker.setVisible(false);
			if(mylabels){
				mylabels[i].hide();
			}
		}
	}
	if ( mode == 'pgm' || mode == 'init' || mode== 'status' ) { loadOwners(mode,pgm); }
	if (pgm == 'Tsunami') {
		tsunamilinks.style.display = 'block';
	} else {
		tsunamilinks.style.display = 'none';
	}
	if (status == 'H') {
		historicallinks.style.display = 'block';
	} else {
		historicallinks.style.display = 'none';
	}
	showTotals(op,pgm,deployed,reporting);
	reporting = 0;
	genLink();
}

function showTotals(op,pgm,deployed,reporting) {
	if (ndbcmaptotals) {
		ndbcmaptotals.innerHTML =
			deployed.toString()+(op=='All'?'':' '+op)+(pgm=='All'?'':' '+pgm)+' stations deployed<br />'+
			reporting.toString()+' have reported in the past 8 hours';
	}
}

function loadOwners(mode,pgm) {
    var status = status_R.checked?'R':'H';
	var opselect = null;
	selected_options = new Array();
	var typeopts = new Array();
	for (zz=0;zz<pgm.length;zz++) {
		// Kludge to handle "C-MAN" and "Moored Buoys" types in place of operator.
		if (pgm[zz] =='NDBC Meteorological/Ocean') {
			typeopts.push('C-MAN');
			typeopts.push('Moored Buoys');
		} else if (pgm[0]!=='All' && pgm !=='') {
			for (var i=0;i<owners.length;i++) {
				var chk = null;
				eval("chk = owners[i]."+pgm[zz].replace(/[^A-za-z0-9]/g,""));
				if(chk || pgm.length==0) {
					if (status == 'R' && !owners[i].recent) { continue; }
					array_remove(typeopts,owners[i].name);
					typeopts.push(owners[i].name);
				}
			}

		}
	}
	if (typeopts.length<1) {
		typeopts = station_data.owner;
	}
	create_options(typeopts);
}

function generate_program_tab() {
	var program_tab = document.getElementById("program_tab");
	var intab = document.createElement("div");
	intab.setAttribute("id","program_display_tab");
	for (i=0;i<station_data.program.length;i++) {
		var newprog = document.createElement("div");
		newprog.setAttribute("id",station_data.program[i]);
		newprog.style.backgroundColor="white";
		newprog.style.display="block";
		newprog.style.cursor="pointer"
		var chkbx = document.createElement("input");
		chkbx.setAttribute("type","checkbox");
		newprog.onclick=function() {
			array_remove(selected_programs,this.id);
			if (this.style.backgroundColor=="white"||this.style.backgroundColor=="#ffffff") {
				selected_programs.push(this.id);
				selected_programs.sort();
				this.style.backgroundColor="#c0c0c0";
				this.childNodes[0].checked=true;
			} else {
				this.style.backgroundColor="white";
				this.childNodes[0].checked=false;
			}
			changeDisplay('pgm');
		}
		newprog.appendChild(chkbx);
		newprog.appendChild(document.createTextNode(station_data.program[i]));
		intab.appendChild(newprog);
		if (userpgm) {
			if (array_match(userpgm,station_data.program[i])) {
				selected_programs.push(station_data.program[i]);
				selected_programs.sort();
				newprog.style.backgroundColor="#c0c0c0";
				newprog.childNodes[0].checked=true;
			}
		}
	}
	program_tab.appendChild(intab);
	userpgm=null;
}

function create_options(arr) {
	document.getElementById("owner_tab").innerHTML='';
	for(ilo = 0; ilo < arr.length; ilo++) 	{
		var newopt = document.createElement("div");
		newopt.setAttribute("id",arr[ilo]);
		newopt.style.backgroundColor="white";
		newopt.style.display="block";
		newopt.style.cursor="pointer";
		var chkbx = document.createElement("input");
		chkbx.setAttribute("type","checkbox");
		newopt.onclick=function(){
			array_remove(selected_options,this.id);
			if (this.style.backgroundColor=="white"||this.style.backgroundColor=="#ffffff") {
				selected_options.push(this.id);
				selected_options.sort();
				this.style.backgroundColor="#c0c0c0";
				this.childNodes[0].checked=true;
			} else {
				this.style.backgroundColor="white";
				this.childNodes[0].checked=false;
			}
			changeDisplay('op');
		}
		newopt.appendChild(chkbx);
		newopt.appendChild(document.createTextNode(arr[ilo]));
		document.getElementById("owner_tab").appendChild(newopt);
		if (userop) {
			if (array_match(userop,arr[ilo])) {
				selected_options.push(arr[ilo]);
				selected_options.sort();
				newopt.style.backgroundColor="#c0c0c0";
				newopt.childNodes[0].checked=true;
				changeDisplay("op");
			}
		}
	}
	userop=null;
}

function openHelp(doc,winname) {
	var helpwin;
	if (window.showModalDialog) {
		window.showModalDialog(doc,winname,"dialogWidth:830px;dialogHeight:600px;center:yes");
	} else {
		helpwin = window.open(doc,winname,'toolbar=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,modal=yes,height=600,width=820');
		helpwin.moveTo(0,0);
	}
}

function array_match(arr,term) {
        var n = false;
        if( arr && isArray(term) ) {
                for(i3t=0;i3t<term.length;i3t++) {
                        for(i2t=0;i2t<arr.length;i2t++) {
                                if(arr[i2t].toLowerCase() == term[i3t].toLowerCase()) {
                                        n=true;
                                        break;
                                }
                        }
                }
                return n;
        } else if (arr) {
                for(i2t=0;i2t<arr.length;i2t++) {
                        if (arr[i2t].toLowerCase() == term.toLowerCase()) {
                                n=true;
                                break;
                        }
                }
                return n;
        }
}

function isArray(obj) {
   if (obj.constructor.toString().indexOf("Array") == -1) {
      return false;
   } else {
      return true;
   }
}

function array_remove(arr,term) {
	var n = false;
	if (arr) {
		for (i=(arr.length-1);i>=0;i-=1) {
			if(arr[i].toLowerCase() == term.toLowerCase()) {
				n=true;
				arr.splice(i,1);
			}
		}
	}
	return n;
}

function formatLat(lat) {
   if (isNaN(lat)) { return lat; }
   if (lat < 0) { return Math.abs(lat).toString()+'S'; }
   if (lat > 0) { return lat.toString()+'N'; }
   return lat.toString();
}

function formatLon(lon) {
   if (isNaN(lon)) { return lon; }
   if (lon < 0) { return Math.abs(lon).toString()+'W'; }
   if (lon > 0) { return lon.toString()+'E'; }
   return lon.toString();
}

function parseiso8601(isodate) {
   var p = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})UTC$/;
   var m = isodate.match(p);
   if (m == null || m.length != 7) { return null; }
   var d = new Date();
   d.setUTCFullYear(m[1]);
   d.setUTCMonth(m[2]-1);
   d.setUTCDate(m[3]);
   d.setUTCHours(m[4]);
   d.setUTCMinutes(m[5]);
   d.setUTCSeconds(m[6]);
   d.setUTCMilliseconds(0);
   return d;
}

function deg2dir(deg){
   if (isNaN(deg)|| deg < 0 || deg > 360) { return null;}
   dir = new Array('N','NNE','NE','ENE','E','ESE','SE','SSE','S','SSW','SW','WSW','W','WNW','NW','NNW','N');
   return dir[Math.round(deg/22.5)];
}

function populateInfoWindow(stn,stnpos,owner) {
   downloadUrl("/get_observation_as_xml.php?station="+stn, function(xml, responseCode) {
      var html = null;
      if (responseCode != 200 && responseCoder != 304) {
         html = '<strong>Station '+stn.toUpperCase()+'<br />'+owner+'<br />Location:<\/strong> '+formatLat(stnpos.lat())+' '+formatLon(stnpos.lng())+'<br />There are no recent (&lt; 8 hours) meteorological data for this station.<br .>Click <a href="/station_page.php?station='+stn+'" target="_blank">here<\/a> <img src="/images/new_window.png" width="16" height="16" alt="Opens in new window" title="Opens in new window" style="vertical-align:text-top" \/> - <a href="/station_history.php?station='+stn+'" target="_blank">View History<\/a> <img src="/images/new_window.png" width="16" height="16" alt="Opens in new window" title="Opens in new window" style="vertical-align:text-top" \/> for other data from this station.';
      } else {
         if (xml.documentElement) {
            var data = {datetime:null, name:null, lat:null, lon:null, winddir:null, windspeed:null, windgust:null, waveht:null, domperiod:null, meanwavedir:null, pressure:null, airtemp:null, watertemp:null, dewpoint:null, tide:null, visibility:null};
            data['id'] = xml.documentElement.getAttribute('id');
            data['name'] = xml.documentElement.getAttribute('name');
            data['lat'] = xml.documentElement.getAttribute('lat');
            data['lon'] = xml.documentElement.getAttribute('lon');
            var items=xml.documentElement.childNodes;
            for (var i=0;i<items.length;i++) {
               if (items[i].nodeType == 1) {
                  switch (items[i].nodeName) {
                     case 'datetime':
                        data[items[i].nodeName] = parseiso8601(items[i].childNodes[0].nodeValue);
                        break;
                     case 'winddir':
                        var dir = deg2dir(items[i].childNodes[0].nodeValue);
                        if (dir != null) {
                           data[items[i].nodeName] = dir +' ('+items[i].childNodes[0].nodeValue+'&#176;)';
                        } else {
                           data[items[i].nodeName] = items[i].childNodes[0].nodeValue+'&#176;';
                        }
                        break;
                     case 'meanwavedir':
                        var dir = deg2dir(items[i].childNodes[0].nodeValue);
                        if (dir != null) {
                           data[items[i].nodeName] = dir +' ('+items[i].childNodes[0].nodeValue+'&#176;)';
                        } else {
                           data[items[i].nodeName] = items[i].childNodes[0].nodeValue+'&#176;';
                        }
                        break;
                     case 'pressure':
                        var uom = items[i].getAttribute('uom');
                        if (uom != null) {
                           data[items[i].nodeName] = items[i].childNodes[0].nodeValue + ' ' +uom;
                        } else {
                           data[items[i].nodeName] = items[i].childNodes[0].nodeValue;
                        }
                        var ptend = items[i].getAttribute('tendency');
                        if (ptend != null) {
                           data[items[i].nodeName] += ' and ' + ptend;
                        }
                        break;
                     default:
                        var uom = items[i].getAttribute('uom');
                        if (uom != null) {
                           data[items[i].nodeName] = items[i].childNodes[0].nodeValue + ' ' +uom;
                        } else {
                           data[items[i].nodeName] = items[i].childNodes[0].nodeValue;
                        }
                  }
               }
            }
            var now = new Date();
            var cutoff = new Date(Date.UTC(now.getUTCFullYear(),now.getUTCMonth(),now.getUTCDate(),now.getUTCHours(),now.getUTCMinutes(),now.getUTCSeconds())-8*60*60*1000);
            if (data['id'] != null && data['datetime'] != null && data['lat'] != null && data['lon'] != null && data['datetime'] >= cutoff) {
               var title = '<strong>Station '+data['id'].toUpperCase()+'<br />'+owner+'<br />Location:<\/strong> '+formatLat(data['lat'])+' '+formatLon(data['lon'])+'<br /><strong>Date:<\/strong> '+data['datetime'].toUTCString().replace("GMT","UTC")+'<br />';
               var body = '';
               var winds = '';
               if (data['winddir'] != null) { winds += data['winddir']; }
               if (data['windspeed'] != null) { winds += ' at '+data['windspeed']; }
               if (data['windgust'] != null) { winds += ' gusting to '+data['windgust']; }
               if (winds) {
                  body += '<strong>Winds:<\/strong> '+winds+'<br />';
               }
               if (data['waveht'] != null) { body += '<strong>Significant Wave Height:<\/strong> '+data['waveht']+'<br />'; }
               if (data['domperiod'] != null) { body += '<strong>Dominant Wave Period:<\/strong> '+data['domperiod']+'<br />'; }
               if (data['meanwavedir'] != null) { body += '<strong>Mean Wave Direction:<\/strong> '+data['meanwavedir']+'<br />'; }
               if (data['pressure'] != null) { body += '<strong>Atmospheric Pressure:<\/strong> '+data['pressure']+'<br />'; }
               if (data['airtemp'] != null) { body += '<strong>Air Temperature:<\/strong> '+data['airtemp']+'<br />'; }
               if (data['dewpoint'] != null) { body += '<strong>Dew Point:<\/strong> '+data['dewpoint']+'<br />'; }
               if (data['watertemp'] != null) { body += '<strong>Water Temperature:<\/strong> '+data['watertemp']+'<br />'; }
               if (data['visibility'] != null) { body += '<strong>Visibility:<\/strong> '+data['visibility']+'<br />'; }
               if (data['tide'] != null) { body += '<strong>Tide:<\/strong> '+data['tide']+'<br />'; }
               html = title+'<div style="max-height:120px;max-width:300px;overflow:auto;">'+body+'<\/div><a href="/station_page.php?station='+stn+'" target="_blank">View Details<\/a> <img src="/images/new_window.png" width="16" height="16" alt="Opens in new window" title="Opens in new window" style="vertical-align:text-top" \/> - <a href="/station_history.php?station='+stn+'" target="_blank">View History<\/a> <img src="/images/new_window.png" width="16" height="16" alt="Opens in new window" title="Opens in new window" style="vertical-align:text-top" \/>';
            } else {
               html = '<strong>Station '+stn.toUpperCase()+'<br />'+owner+'<br />Location:<\/strong> '+formatLat(stnpos.lat())+' '+formatLon(stnpos.lng())+'<br />There are no recent (&lt; 8 hours) meteorological data for this station.<br .>Click <a href="/station_page.php?station='+stn+'" target="_blank">here<\/a> <img src="/images/new_window.png" width="16" height="16" alt="Opens in new window" title="Opens in new window" style="vertical-align:text-top" \/> for other data from this station.';
            }
          } else {
             html = "Sorry!  Your browser does not support this application.";
             return;
          }
      }
      if (html != null) {
         if (infowindow  != null) { infowindow.close(); }
         infowindow = new google.maps.InfoWindow({content:html,position:stnpos});
         infowindow.open(map);
      }
   });
}

// Region Overlay for drawing region rectangles on the map.
// Based on Custom Overlay class at
// http://code.google.com/apis/maps/documentation/javascript/overlays.html#CustomOverlays
function RegionOverlay(bounds, map) {
	this.bounds_ = bounds;
	this.map_ = map;
   	this.div_ = null;
   	this.setMap(map);
}

RegionOverlay.prototype = new google.maps.OverlayView();

RegionOverlay.prototype.onAdd = function() {
   	var div = document.createElement('div');
   	div.style.border = "solid";
   	div.style.borderWidth = "2px";
   	div.style.position = "absolute";
   	div.style.borderColor = "#666";
   	div.style.backgroundColor = "#ccc";
   	div.style.borderColor = "#7cfc00";
   	div.style.backgroundColor = "#32cd32";
   	div.style.opacity = 0.6;
   	div.style.filter = 'alpha(opacity=60)';
   	var txtNode = document.createTextNode("");
   	div.appendChild(txtNode);
   	this.div_ = div;
   	var panes = this.getPanes();
   	panes.floatPane.appendChild(div);
}

RegionOverlay.prototype.draw = function() {
   	var overlayProjection = this.getProjection();
   	var ww = overlayProjection.getWorldWidth();
   	var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
   	var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
   	var div = this.div_;
   	div.style.left = Math.round(sw.x) + 'px';
   	div.style.top = Math.round(ne.y) + 'px';
   	if (sw.x>ne.x) {
   		div.style.width = Math.round(ne.x - sw.x%ww) + 'px';
   	} else {
   		div.style.width = Math.round(ne.x - sw.x) + 'px';
   	}
   	div.style.height = Math.round(sw.y - ne.y) + 'px';
}

RegionOverlay.prototype.onRemove = function() {
   	this.div_.parentNode.removeChild(this.div_);
   	this.div_ = null;
}

RegionOverlay.prototype.hide = function() {
	if (this.div_) {
		this.div_.style.visibility = "hidden";
	}
}

RegionOverlay.prototype.show = function() {
	if (this.div_) {
		this.div_.style.visibility = "visible";
	}
}

RegionOverlay.prototype.toggle = function() {
	if (this.div_) {
		if (this.div_.style.visibility == "hidden") {
			this.show();
		} else {
			this.hide();
		}
	}
}

RegionOverlay.prototype.toggleDOM = function() {
	if (this.getMap()) {
		this.setMap(null);
	} else {
		this.setMap(this.map_);
	}
}

window.onload = initialize;

