//<![CDATA[
/*This script is used to plot earthquakes on google maps. 
Author: Jon Connolly
Pacific Northwest Seismic Network, University of Washington.
joncon@u.washington.edu
Acknowledgements:
Many techniques were learned from the Mike Williams' Google Maps API Tutorial
http://econym.googlepages.com/index.htm
*/

Event.observe(window, 'load', function(){
	loadMap();
	getEqs();
	//eqs
	$("eqAll").observe('click',shide);
	$("eq4").observe('click', shide);
	$("eq3").observe('click', shide);
	$("eq2").observe('click', shide);
	$("eq1").observe('click', shide);
	$("eq0").observe('click', shide);
	$("plotTime").observe('click', changePlot);
	$("plotDepth").observe('click', changePlot);
	//webicorders
	for (var i = 0; i < webiNames.length; i++){
		$(webiNames[i]).observe('click', getWebi);
	}
	//reset map view
	$('reset').observe('click', function(){
		map.setCenter(new GLatLng(mapParam.lat, mapParam.lon), mapParam.zoom);
	});
	
	//scriptacolous effects
	$('helpWebi').observe('click', function(){
		new Effect.BlindDown('webiHelpBox');
	});
	
	$('webiHelpClose').observe('click', function(){
		new Effect.BlindUp('webiHelpBox');
	});
	resetControl();
});



// unload handlers
window.unload = function(){
	GUnload();
};

//Global varaibles
var map;
var side_bar_html = "";
var gmarkers = [];
var count = 0;
var zIndex = 1000;
var depthOn = false; //if true, eq's plotted by depth, else eq's plotted by time
var webiList =[];
var eventArray = [];
var eqNum = 0; //number of events shown on map



function loadMap() {
	if (GBrowserIsCompatible()) {
		map = new GMap2($("map"));
		map.setCenter(new GLatLng(mapParam.lat, mapParam.lon), mapParam.zoom);
		map.setMapType(G_PHYSICAL_MAP);
		map.addMapType(G_HYBRID_MAP); //puts Satellite and Map in tool bar
		map.addMapType(G_PHYSICAL_MAP);//this allows the terrain map to appear in the toolbar
		map.addControl(new GOverviewMapControl()); //adds map overview map in bottom left corner.
		map.addControl(new GSmallMapControl()); //adds lefthand slider bar thingy
		map.addControl(new GHierarchicalMapTypeControl());//right-top nav bar
		map.addControl(new GScaleControl());//adds scale
	}else{
	alert("Javascript must be enabled in order for you to use REQ2. To view, you must first enable JavaScript in your browser options and try again");
	}
}

//Ajax for webicorder xml file
function getWebi(){
	map.closeInfoWindow();
	var id = this.id;
	var file = "xml/" + id +".xml";
	if (this.checked){
		$('loading').style.visibility = "visible";
		$('loadText').style.visibility = "visible";
		document.body.style.cursor="wait";
	
		new Ajax.Request(
				file,
			{
				method: "post",
				contentType: 'text/xml',
				onSuccess: parseWebi
			}
			
		);
		}else{ //remove markers and objects from array
			for (var i = 0; i < gmarkers.length; i++) {
				if (gmarkers[i].grp == id){
					gmarkers[i].remove();
				}
			}
			//remove webicorders from list
			for (var i = 0; i < webiList.length; i++) {
				if (webiList[i].typ == id){
					webiList[i] = null;
				}	
			}
			webiList = webiList.compact();//dump null elements
			eventArray.invoke('updateWindow');
	}

	
}

//parse the webicorder xml
function parseWebi(ajax){
	$('loading').style.visibility = "hidden";
	$("loadText").style.visibility = "hidden";
	document.body.style.cursor="default";
	
	if(window.ActiveXObject){ // If IE
	var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
	xmlDoc.loadXML(ajax.responseText);
	} else {
	var xmlDoc = ajax.responseXML;
	}
	var station_list = xmlDoc.getElementsByTagName('station_list')
	var staTag = xmlDoc.getElementsByTagName("station");
	for (var i =0; i < staTag.length; i++) { 
		var param = staTag[i].getElementsByTagName("param");
		var webiParam = new Hash();
		webiParam.set('typ', station_list[0].getAttribute("type"));
		for(var j = 0; j< param.length; j++){
			webiParam.set(param[j].getAttribute("name"), param[j].getAttribute("value"));
		}
		var web = new Webi(webiParam);
		webiList.push(web); //create an array of webi objects
		map.addOverlay(web.plotWebi());
	}
}



//Ajax to retrieve xml file for eqs
function getEqs(){
	$('loading').style.visibility = "visible";
	$('loadText').style.visibility = "visible";
	document.body.style.cursor="wait";
	new Ajax.Request(
			eventXml,
		{
			method: "post",
			contentType: 'text/xml',
			onSuccess: parseEqs
		}
	);
}



//parse quake xml
function parseEqs(ajax){
	$('loading').style.visibility = "hidden";
	$("loadText").style.visibility = "hidden";
	document.body.style.cursor="default";
	
	if(window.ActiveXObject){ // If IE
	var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
	xmlDoc.loadXML(ajax.responseText);
	} else {
	var xmlDoc = ajax.responseXML;
	}
	var timeNow = xmlDoc.getElementsByTagName('merge')[0].getAttribute('fileTime_loc');
	timeUtc = xmlDoc.getElementsByTagName('merge')[0].getAttribute('fileTime_utc');
	updateTime(timeNow)
	var eventTag = xmlDoc.getElementsByTagName("event");
		for (var i = eventTag.length - 1; i > 0; i--) { //puts younger events first
			var param = eventTag[i].getElementsByTagName("param");
			var eqParam = new Hash();
			eqParam.set("id", eventTag[i].getAttribute("id"));
			eqParam.set("network-code", eventTag[i].getAttribute("network-code"));
			eqParam.set("version", eventTag[i].getAttribute("version"));
			for(var j = 0; j< param.length; j++){
                                var test = eqParam.get(param[j].getAttribute("name"));
                                if (test == null){
				eqParam.set(param[j].getAttribute("name"), param[j].getAttribute("value"));
                          }
			}
			eq = new Eq(eqParam);
			eventArray.push(eq); 
			map.addOverlay(eq.plotEq());
			eq.makeList();
			eqNum++;
		}
		$("numberEQs").innerHTML= eqNum;
}

//add listener to sidebar list items
function myclick(count) {
        GEvent.trigger(gmarkers[count], "click");
      }


//////the following three functions are to manage the user checkbox clicks////////////

//show or hide (shide) selected markers
function shide(){
	var grp = this.id;
	var checked = this.checked;
	checkBoxes(grp);
	manageList(grp, checked);
	if (grp == "eqAll"){
		eqNum = 0;
	}
	for (var i=0; i<gmarkers.length; i++) {
		if (grp == "eqAll"){ //if 'eqall' button is clicked(shows all or hides all)
			if(checked){
				gmarkers[i].show();
				eqNum++;
			}else{
				if(gmarkers[i].grp.substr(0,2) =='eq' ){
					gmarkers[i].hide();
					eqNum--;
					map.closeInfoWindow();
				}	
			}
		}else{
      		if (gmarkers[i].grp == grp){//individual button clicked
				if(checked){
        			gmarkers[i].show();
					eqNum++;
				}else{
					gmarkers[i].hide();
					eqNum--;
					map.closeInfoWindow();
				}	
			}
      	}
    }
	$("numberEQs").innerHTML= eqNum;
}

//manages checkboxes, markers and list for case when 'eqAll' is checked or another button is checked when
//eqAll is already checked
function checkBoxes(grp){
	var listAll = $('eqlist').childElements();
	if (grp == "eqAll"){//uncheck all boxes when 'eqall is clicked
		for(var i =0; i < 5; i++){
			$('eq' + i).checked = false;
		}
		for(var i= 0; i < listAll.length; i ++){
			$('eqAll').checked? listAll[i].show(): listAll[i].hide();
			/*if($('eqAll').checked){
				listAll[i].show();
			}else{
				listAll[i].hide();
			}*/
		}
	}else{ //remove all icons/list-items if all is checked when another button is checked
		if($('eqAll').checked){
			for (var i=0; i<gmarkers.length; i++){
				if(gmarkers[i].grp.substr(0,2) =='eq' ){
					gmarkers[i].hide();
					eqNum--;
				}
			}
			for(var i= 0; i < listAll.length; i ++){
				listAll[i].hide();
			}
		}
		$('eqAll').checked = false;
	}
}

function manageList(grp,checked){
	var list = $$("."+ grp);
	for(var i = 0; i < list.length; i++){
		if(checked){
			list[i].show();
		}else{
			list[i].hide();
		}
	}
}

function updateTime(t){
	span = $$('#time span')[0];
	span.innerHTML ='' ;
	span.innerHTML = t;
}

//switch between depth and time plots
function changePlot(){
	map.closeInfoWindow();
	killMarkers();
	resetControl();
	count = 0;
	if(this.id =="plotDepth"){
		depthOn = true;
		$('legend').src = "images/legendReqDepth.png";
	}else{
		depthOn = false;
		$('legend').src = "images/legendReqTime.png";
	}
	getEqs();
}

//kill all markers and re-plot eqAll when when plot by time/depth is clicked
function killMarkers(){
	$("eqlist").innerHTML =""; 
	for(var i = 0; i< gmarkers.length; i++){
		gmarkers[i].remove();
	}
	eqNum = 0;
}
//resets buttons on plot change and refresh
function resetControl(){
	$("eqAll").checked = true; 
	for(var i =0; i < 5; i++){
		$('eq' + i).checked = false;
	}
	$("pnsn").checked = false;
	$("bb").checked = false;
	$("volc").checked = false;
	$("smo_n").checked = false;
	$("smo_sea").checked = false;
	$("smo_s").checked = false;
}

// creates listners for each individual list of webicorders sorted
//by distance. These are the webicorders that appear in control panel.
function webiEvents() {
	if(this.value != 'starter'){
		Event.observe('selectWebi','change', function(){
			var htmlStuff = "<img id = 'webiEventDisplayClose' src ='images/close.jpg'/>";
			htmlStuff += this.value
			$('webiEventDisplay').innerHTML = htmlStuff;
			new Effect.Appear('webiEventDisplay');
			$('webiEventDisplayClose').onclick = function(){
				new Effect.Fade('webiEventDisplay');
				$('opStart').selected = 'selected';
			}
		
		});
	}
}

////////////////////////////////begin Earthquake class//////////////////////////////////

Eq = Class.create({
	initialize: function(eq){
		this.eId = eq.get('id');
		this.net = eq.get('network-code');
		this.ver = eq.get('version');
		this.yr = eq.get('year');
		this.mon = eq.get('month');
		this.day = eq.get('day');
		this.hr = eq.get('hour');
		this.min = eq.get('minute');
		this.sec = eq.get('second');
		this.lat = eq.get('latitude');
		this.lon = eq.get('longitude');
		this.dep = eq.get('depth');
		this.mag = eq.get('magnitude');
		this.loc = eq.get('local-time')
		this.icon = eq.get('icon-style');
		this.listId;
		this.marker;
		this.point = new GLatLng(this.lat, this.lon);
	},
	//create a date string
	getDate: function(){
		return 	(this.yr + "/" + this.mon + "/" + this.day
				+ " " + this.hr + ":" + this.min + ":" + this.sec.substr(0,2));
	},
	
	//plot the earthquake
	plotEq: function(){
		side_bar_html = "";
		//plot either depth or time
		if(depthOn){
			var image = this.getDepth();
		}else{
			var image = this.icon;
		}
		if(this.net.toUpperCase() != authorNW){
			image += "_nonNet";
		}
		var siz = this.getMag();
		var grp = "eq" + this.mag.charAt(0);//sets up marker groups
		eqIcon = new GIcon();
		eqIcon.image = "images/icon_" + image + ".png";
		eqIcon.iconSize = new GSize(siz, siz);
		eqIcon.iconAnchor = new GPoint(siz/2, siz/2);
		eqIcon.infoWindowAnchor = new GPoint(siz/2, siz/2);	
		var markerOptions = {icon:eqIcon, zIndexProcess:this.order};
		this.marker = (new GMarker(this.point, markerOptions));
		this.listId = "listId" + count; //give each a unique id so an open window will highlight the list-item
		var listId = this.listId;
		this.updateWindow();
		GEvent.addListener(map,"infowindowclose", function() { //resores list-item to un-highlighted
			$(listId).style.backgroundColor="#ffffff";
		});
		this.marker.grp = grp; //add group id to each marker

		//the following is to set up the sidebar list
		gmarkers[count] = this.marker;

		side_bar_html = "javascript:myclick(" + count + ")";

		return this.marker;
	},
	
	//determine magnitude to size icons
	getMag: function(){
		var scale = 4; //these allow for fine tuning the size of icons
		var base =5;
		return size = this.mag * scale + base;
	},
	
	//check depth of event to assign proper colored icon
	 getDepth: function(){
		var z = this.dep;
		if (z < 10){
			return "1";
		}
		if (z < 20){
			return "blueGreen";
		}
		if (z < 30){
			return "green";	
		}
		if (z < 40){
			return "2";
		}
		if (z < 50){
			return "orange"
		}
		if(z < 1000){
			return "0"
		}
	},
	
	//create the side bar
	makeList: function(){
		var z = this.dep.split(".")[0];
		if (z < 10){
			z = "0" + z;
		}
		z +=" Km"
		var grp = "eq" + this.mag.charAt(0);//sets up marker classes based on mag
		var li  = document.createElement("li");
		Element.extend(li); //IE
		li.id = "listId" + count;
		li.addClassName(grp);
		var a = document.createElement("a");
		a.href = side_bar_html;
		if(this.mag >=3){//give mag 3 and greater red font
			Element.addClassName(a, "m3");
		}else{
			Element.addClassName(a, "msmall");
		}
		a.innerHTML= this.mag + " " + this.getDate() + " " + z; 
		li.appendChild(a);
		$("eqlist").appendChild(li);
		count ++;
	},
	
	//plots most recent on top
	order: function(){
		return zIndex --;
	},
	
	//creates and updates window. This function also creates a list
	//of  the event's webicorders sorted by distance from event
	updateWindow: function(){
		var windowHtml = this.getHtml();
		var marker = this.marker;
		var listId = this.listId;
		var point = this.point;
		var time = this.yr + this.mon + this.day + this.hr;
		//add listeners and html to windows
		GEvent.addListener(marker, "click", function() {
		    marker.openInfoWindowHtml(windowHtml);
			$(listId).style.backgroundColor = "yellow";
			var x = $$("#selectWebi option");//remove prior list of option elements
			
			for( var i = 0; i < x.length; i ++){
				x[i].remove();
			}
			var sta = webiList.invoke('getDistance', point, time).sort(function(a,b){return a[0] - b[0]});
			if(sta.length == 0){
				var op = document.createElement('option');
				op.innerHTML = "None Selected"
				$('selectWebi').appendChild(op);
			}else{ //create list
				var opStart = document.createElement('option');
				opStart.id = 'opStart';
				opStart.style.color = "red";
				opStart.innerHTML = 'Please Select';
				opStart.value = 'starter';
				$('selectWebi').appendChild(opStart);
				for( var i = 0; i < sta.length; i ++){
					var op = document.createElement('option');
					op.innerHTML = sta[i][1];
					op.value = sta[i][2];
					$('selectWebi').appendChild(op);
					
				}
				webiEvents();
			}
		  });
	},
	
	//html for info window
	getHtml: function(){
		var name = ["Magnitude: ", "Time (UTC):", "Time (Local):", "Depth (Km): ", "Event Id:" ];
		var param = [this.mag, this.getDate(), this.loc, this.dep, this.eId ];
		var html = "<div class = 'eqWin'> \n";
		var link = getLink(this.net, this.eId);
		link += "View Event Page</a>";
		html += link;	
		html += "<ul> \n";
			for (var i = 0; i < name.length; i++){
				html += "<li>" + name[i]  + "<span>" + param[i] + "</span> </li> \n";
			}
		html += "</ul>";
		return html; 
	}
});

///////////////////////begin Webicorder class///////////////////////

Webi = Class.create({
	initialize: function(w){
		this.typ = w.get('typ');
		this.nam = w.get('name');
		this.chan = w.get('chan');
		this.lat = w.get('lat');
		this.lon = w.get('lon');
		this.inf = w.get('info');
		this.net = w.get('network')
		this.point = new GLatLng(this.lat, this.lon);
	},
	
	//plot the webicorders 
	plotWebi: function(){
		var webiIcon = new GIcon();
		webiIcon.image = "images/icon_eq.png";
		webiIcon.iconSize = new GSize(16, 16);
		webiIcon.iconAnchor = new GPoint(8, 8);
		webiIcon.infoWindowAnchor = new GPoint(8, 8);
		markerOptions = {icon:webiIcon, title: this.nam};
		var marker = (new GMarker(this.point, markerOptions));
		marker.grp = this.typ;
		gmarkers[count] = marker;
		count ++;
		var windowHtml = this.getWebiHtml();
		GEvent.addListener(marker, "click", function() {
		    marker.openInfoWindowHtml(windowHtml);
		  });
		return marker;
	},
	//gets html for each window
	getWebiHtml: function(t){
		var time = this.timeFile(t);
		var a = getWebiLink(this.typ, this.nam, this.chan, this.net, time);
		return ("<div class = 'webi'>" + this.inf + "<br/>" + a + "</div>");
	},
	
	//used to create the proper string to retrieve webicorder links uses either a parameter
	//for older eqs or utc of recent webicorders
	timeFile: function(t){
		if(t){
			var time = t;
		}else{
			var time = timeUtc;
		}
		var  dateTime = time.substr(0,8);
		var hour = time.substr(8,2);
		if( hour < 12){
			hour = "00";
		}else{
			hour = "12";
		}
		return dateTime += hour;
	},
	
	//get distance between event and webicorders for sorting.
	getDistance: function(pointA, t){
		var dis = pointA.distanceFrom(this.point).toFixed(2);
		return (dis + ',' + this.nam + ',' + this.getWebiHtml(t)).split(',');
	}
});
//]]>);
