/*
Functions for CSOCast, Regulator, Outfall, and Rep Outfall versions.

Casey Thomas, 2008
*/


/*
Calculates basic statistics for the regulators.

Loops through the array of regulators and
counts the total number, the number overflowing,
the number not overflowing, and the number of no
datas. Returns a table in HTML that is displayed
on the side menu, which contains the results

output changes based on value parameter
O for outfalls
R for regs

*/
function allRegStats(value,outfallArray,tableTitle,tableClass){
		

	var total_num = 0;
	var cur_overflow = 0;
	var past_overflow = 0;
	var no_overflow = 0;
	var no_data = 0;
	var not_mon = 0;
		
		for(var i=0;i<outfallArray.length;i++){
				total_num++;
				if(outfallArray[i] == 4){
					cur_overflow++;
				}else if(outfallArray[i] == 3){
					past_overflow++;
				}else if(outfallArray[i] == 2){
					no_data++;
				}else if(outfallArray[i] == 1){
					no_overflow++;
				}else if(outfallArray[i] == 0){
					not_mon++;
				}
		}


	if(value == "R"){
		output = "<table class=\"regstats\"><tr><td colspan=\"2\" class=\"title\">" + tableTitle + " Outfall Summary</td></tr>" + 			 
					"<tr><td>Total</td><td>" + total_num + "</td></tr> " +
					"<tr><td>Currently overflowing</td><td>" + cur_overflow + "</td></tr>" + 
					"<tr><td>Overflow in past 24 hours</td><td>" + past_overflow + "</td></tr> " + 
					"<tr><td>No overflow in past 24 hours</td><td>" + no_overflow + "</td></tr> " + 
					"<tr><td>Currently no data</td><td>" + no_data + "</td></tr>" +
					"<tr><td>Not monitored</td><td>" + not_mon + "</td></tr></table>"
	}else{
			
			no_data = no_data + not_mon
			
		 output = "<table class=\"" +  tableClass  + "\"><tr><td colspan=\"2\" class=\"title\">" + tableTitle + " Outfall Summary</td></tr>" + 				 
					"<tr><td>Total</td><td>" + total_num + "</td></tr> " +
					"<tr><td>Currently overflowing</td><td>" + cur_overflow + "</td></tr>" + 
					"<tr><td>Overflow in past 24 hours</td><td>" + past_overflow + "</td></tr>" + 
					"<tr><td>No overflow in past 24 hours</td><td>" + no_overflow + "</td></tr> " + 
					"<tr><td>Currently no data</td><td>" + no_data + "</td></tr></table>"
	}

	return output;

}


/*
Pans to a regulator based on a selection in the search 
results window. 

The name of the selected regulator is
passed through as the parameter. The regArrIndex is then
searched through looking for a match on the regulator name.
The returned indexed number is used to retrieve the 
lat/lngs from the regArr for the selected regulator. 
The map then pans to those coordinates. The markerArray 
is then searched through to find the selected regulator
marker. A click event is then initiated on ther marker,
which opens up the info window.
*/
function zoomtoreg (reg){
		
		x = regArrIndex.indexOf(reg);
		
		lat = regArr[x][1];
		lng = regArr[x][2];
		
		map.panTo(new GLatLng(lat,lng));
		
		y = markerArrayIndex.indexOf(reg);
		z = markerArray[y][1];
		
		GEvent.trigger(z,"click");

}


/*
Computes and returns the distances from the search result
to the closest regulators.

Loops through the regArr and grabs the coordinates of 
each regulator. Then a point object is created based off 
those coordinates; which is then used to create a marker. 
The search result marker from AddressSearch() is passed 
as a parameter. The search result and the regulator marker 
are used with the distanceFrom() function to calculate the
distance from the search result to the regulator marker. 
The distance is converted to miles and stored in the regArr.
Once distances have been calculated for all of the regulators,
the regArr is sorted ascendingly by the distance element.
The names of the regulators are then copied over to 
regArrIndex in their sorted order. HTML code for the 5 closest
regulators with their distances are returned for display in 
the search result info window.
*/
function getClosestRegs(searchResult){

    for(var i=0; i<regArr.length; i++){	
				
			var lat = regArr[i][1];
			var lng = regArr[i][2];
			var point = new GLatLng(lat,lng);
			var regMarker = createMarker(point);
			var d = searchResult.getPoint().distanceFrom(regMarker.getPoint()) * 0.000621371192;
				
			regArr[i][3] = d;

		}

		regArr.sort(sortNum);
		
		for(var z=0; z<regArr.length; z++){
			
			regArrIndex[z] = regArr[z][0];
			
		}
	
		top5 = "<div id=\"infowindow\"><br><b>5 Closest Outfalls:</b><br>" + "<a href = \"javascript:zoomtoreg('" + regArr[0][0] + "')\">" + regArr[0][0] + "</a>, " + regArr[0][3].toFixed(2) + " miles<br>"
			 + "<a href = \"javascript:zoomtoreg('" + regArr[1][0] + "')\">" + regArr[1][0] + "</a>, " + regArr[1][3].toFixed(2) + " miles<br>"
			 + "<a href = \"javascript:zoomtoreg('" + regArr[2][0] + "')\">" + regArr[2][0] + "</a>, " + regArr[2][3].toFixed(2) + " miles<br>"
			 + "<a href = \"javascript:zoomtoreg('" + regArr[3][0] + "')\">" + regArr[3][0] + "</a>, " + regArr[3][3].toFixed(2) + " miles<br>"
			 + "<a href = \"javascript:zoomtoreg('" + regArr[4][0] + "')\">" + regArr[4][0] + "</a>, " + regArr[4][3].toFixed(2) + " miles<br></div>";

		return top5;	

}


/*
Zooms to waterbodies based on clicks in sidebar. Also
displays regulator summary chart for the corresponding
water body.

When a river/creek is clicked on the side menu, the ID
is passed as a parameter. Once the ID is matched to one
of the if statements, the map centers and zooms to the 
set coordinates. regStatsbyBody() is called to calculate 
summary statistics for the corresponding river body. 
regStatsByBody() returns an HTML table which is then displayed
under the selected creek/river. Any other summary tables
that are being shown are cleared out. 
*/
function zoomtobody(waterbody){

	if(waterbody == "Phila"){
		map.setCenter(new GLatLng(40.001935,-75.125157));
		map.setZoom(11);
		//document.getElementById("int_reg_stats").innerHTML = "";
		return;
	}
	

	//document.getElementById("int_reg_stats").innerHTML = "";
	//regstats = regStatsbyBody(waterbody);
	//document.getElementById("int_reg_stats").innerHTML = regstats;

	switch(waterbody)
	{
		case "C":
			map.setCenter(new GLatLng(39.9506,-75.2464));
			map.setZoom(13);
			break;
		case "D":
			map.setCenter(new GLatLng(39.9782,-75.0802));
			map.setZoom(12);
			break;
		case "P":
			map.setCenter(new GLatLng(40.0583,-75.0485));
			map.setZoom(13);
			break;
		case "PQ":
			map.setCenter(new GLatLng(40.0992,-74.9800));
			map.setZoom(13);
			break;
		case "S":
			map.setCenter(new GLatLng(39.9432,-75.2019));
			map.setZoom(13);
			break;
		case "T":
			map.setCenter(new GLatLng(40.0138,-75.0979));
			map.setZoom(13);
			break;
		case "W":
			map.setCenter(new GLatLng(40.05311,-75.2170));
			map.setZoom(13);
			break;
		case "Phila":
			map.setCenter(new GLatLng(39.999035,-75.130157));
			map.setZoom(11);
			break;
	}
}
/*
Zooms to interceptor systems based on clicks in sidebar. Also
displays regulator summary chart for the corresponding
system.

When a river/creek is clicked on the side menu, the ID
is passed as a parameter. Once the ID is matched to one
of the if statements, the map centers and zooms to the 
set coordinates. regStatsbyIntSys() is called to calculate 
summary statistics for the corresponding inteceptor system. 
regStatsbyIntSys() returns an HTML table which is then displayed
under the selected creek/river. Any other summary tables
that are being shown are cleared out. 
*/
function zoomtosys(sys){

	if(sys == "Phila"){
		map.setCenter(new GLatLng(39.999035,-75.130157));
		map.setZoom(11);
		document.getElementById("int_reg_stats").innerHTML = "";
		return;
	}

	document.getElementById("int_reg_stats").innerHTML = "";
	regstats = regStatsbyIntSys(sys);
	document.getElementById("int_reg_stats").innerHTML = regstats;

	switch(sys)
	{ 
		case "SOM":
			map.setCenter(new GLatLng(39.991193,-75.127258));
			map.setZoom(13);
			break;
		case "UDLL":
			map.setCenter(new GLatLng(40.009012,-75.0509548));
			map.setZoom(14);
			break;
		case "PP":
			map.setCenter(new GLatLng(40.039345,-75.022115));
			map.setZoom(15);
			break;
		case "TAC":
			map.setCenter(new GLatLng(40.048511,-75.144767));
			map.setZoom(13);
			break;
		case "UFLL":
			map.setCenter(new GLatLng(40.009110,-75.094642));
			map.setZoom(15);
			break;
		case "LFLL":
			map.setCenter(new GLatLng(40.020553,-75.074386));
			map.setZoom(14);
			break;
		case "LDLL":
			map.setCenter(new GLatLng(39.973765,-75.146570));
			map.setZoom(14);
			break;
		case "Oregon":
			map.setCenter(new GLatLng(39.911283,-75.138888));
			map.setZoom(15);
			break;
		case "LSES":
			map.setCenter(new GLatLng(39.922079,-75.206608));
			map.setZoom(14);
			break;
		case "CSES":
			map.setCenter(new GLatLng(39.959293,-75.183563));
			map.setZoom(14);
			break;
		case "CSWS":
			map.setCenter(new GLatLng(39.959293,-75.183563));
			map.setZoom(14);
			break;
		case "SWMG":
			map.setCenter(new GLatLng(39.936460,-75.219354));
			map.setZoom(14);
			break;
		case "LSWS":
			map.setCenter(new GLatLng(39.926983,-75.209999));
			map.setZoom(14);
			break;
		case "CCHL":
			map.setCenter(new GLatLng(39.968963,-75.269181));
			map.setZoom(14);
			break;
		case "CCLL":
			map.setCenter(new GLatLng(39.923297,-75.243902));
			map.setZoom(14);
			break;
	}
		

}


/*
Allows indexOf to work with Arrays
*/
//Array.indexOf( value, begin, strict ) 
//Return index of the first element that matches value
Array.prototype.indexOf = function( v, b, s ) {
for( var i = +b || 0, l = this.length; i < l; i++ ) {

 	if( this[i]===v || s && this[i]==v ) { return i; }

	}
		return -1;
};


/*
Sorts an array of numbers asecendingly. Takes in
two array elements. Works with multidimensional arrays.
Currently set to look at the third array of a multidimensional
array (in this case, the distance from search marker element of regArr).
*/
function sortNum(a, b){

		var x = a[3];
		var y = b[3];

		return x - y;
}	


/*
Calculates summary statistics for a water body. 
Similar to regStatsAll()

Initiated when a selection is made on the side bar menu.
A value is passed through the function which designates
which interceptor system to compute for.
Loops through regArr looking for regulators that are
on the specified system. When they are found, total_num
is incremeneted, which counts the total number of regulators
on the system. Then, based on the overflow status of the reg,
either overflow, no_overflow, no_data, or not_mon is incremented.

HTML code for a table is returned, which is displayed on the 
side bar menu of the webpage.
*/
function regStatsbyIntSys(sys){
		
	var total_num = 0;
	var cur_overflow = 0;
	var past_overflow = 0;
	var no_overflow = 0;
	var no_data = 0;
	var not_mon = 0;
		
		for(var i=0;i<regArr.length;i++){
			if(regArr[i][5] == sys){	
				total_num++;
				if(regArr[i][4] == 4){
					cur_overflow++;
				}else if(regArr[i][4] == 3){
					past_overflow++;
				}else if(regArr[i][4] == 2){
					no_data++;
				}else if(regArr[i][4] == 1){
					no_overflow++;
				}else if(regArr[i][4] == 0){
					not_mon++;
				}
			}
		}


		output = "<table class=\"regstats\"><tr><td colspan=\"2\" class=\"title\">Interceptor System Regulator Summary</td></tr>" + 			 
					"<tr><td>Total</td><td>" + total_num + "</td></tr> " +
					"<tr><td>Currently overflowing</td><td>" + cur_overflow + "</td></tr>" + 
					"<tr><td>Overflow in past 24 hours</td><td>" + past_overflow + "</td></tr> " + 
					"<tr><td>No overflow in past 24 hours</td><td>" + no_overflow + "</td></tr> " + 
					"<tr><td>Currently no data</td><td>" + no_data + "</td></tr>" +
					"<tr><td>Not monitored</td><td>" + not_mon + "</td></tr></table>"
	

	return output;

}

/*
Calculates summary statistics for a water body. 
Similar to regStatsbyIntSys()

Initiated when a selection is made on the side bar menu.
A value is passed through the function which designates
which waterbody to compute for.
Loops through regArr looking for regulators that discharge
to the specified waterbody (kept in element 6 of regArr). 
When they are found, total_num
is incremeneted, which counts the total number of regulators
on the system. Then, based on the overflow status of the reg,
either overflow, no_overflow,  no_data, or not_mon is incremented.

HTML code for a table is returned, which is displayed on the 
side bar menu of the webpage. Before the table is returned
no_data and not_mon are added together, since we don't want to
differentiate which outfalls are not monitored versus no data.
*/
function regStatsbyBody(body){
		
	var total_num = 0;
	var cur_overflow = 0;
	var past_overflow = 0;
	var no_overflow = 0;
	var no_data = 0;
	var not_mon = 0;
		
		for(var i=0;i<regArr.length;i++){
			if(regArr[i][6] == body){
				total_num++;
				if(regArr[i][4] == 4){
					cur_overflow++;
				}else if(regArr[i][4] == 3){
					past_overflow++;
				}else if(regArr[i][4] == 2){
					no_data++;
				}else if(regArr[i][4] == 1){
					no_overflow++;
				}else if(regArr[i][4] == 0){
					not_mon++;
				}
			}
		}


	no_data = no_data + not_mon;


	output = "<table class=\"regstats\"><tr><td colspan=\"2\" class=\"title\">Waterbody Outfall Summary</td></tr>" + 			 
					"<tr><td>Total</td><td>" + total_num + "</td></tr> " +
					"<tr><td>Currently overflowing</td><td>" + cur_overflow + "</td></tr>" + 
					"<tr><td>Overflow in past 24 hours</td><td>" + past_overflow + "</td></tr>" + 
					"<tr><td>No overflow in past 24 hours</td><td>" + no_overflow + "</td></tr> " + 
					"<tr><td>Currently no data</td><td>" + no_data + "</td></tr></table>"

	return output;

}

/*Creates a polygon based on coordinates in a text file.
Currently runs a bit slow and the polygon is clunky.

function create_shed(doc){
		
		lines = doc.split("\n");
		
		var points = new Array();
			
		for (var i=0; i<lines.length; i++) {
			
			if (lines[i].length > 1) {
		
					parts = lines[i].split(",");
          var lat = parts[1];
          var lng = parts[0];
					points[i] = (new GLatLng(lat,lng));
				
			}
		}
		
		var polygon = new GPolygon(points,"#000000",1,1,0.5,{clickable:false});
		
		map.addOverlay(polygon);
		
		polys.push(polygon);
}
		
GDownloadUrl("shed_PP.txt", create_shed);

*/

/*
Thank you Mike Williams
http://econym.googlepages.com/range.htm


If map is moved outside of a bounding box initialized on the map page, the map is
moved back within the box.

*/

 // If the map position is out of range, move it back
  function checkBounds() {
  // Perform the check and return if OK
		if (allowedBounds.contains(map.getCenter())) {
        return;
    }
        // It`s not OK, so find the nearest allowed point and move there
    var C = map.getCenter();
    var X = C.lng();
    var Y = C.lat();

    var AmaxX = allowedBounds.getNorthEast().lng();
    var AmaxY = allowedBounds.getNorthEast().lat();
    var AminX = allowedBounds.getSouthWest().lng();
    var AminY = allowedBounds.getSouthWest().lat();

    if (X < AminX) {X = AminX;}
    if (X > AmaxX) {X = AmaxX;}
    if (Y < AminY) {Y = AminY;}
    if (Y > AmaxY) {Y = AmaxY;}

    map.setCenter(new GLatLng(Y,X));
 }
 
 
/*show overlay on wissahickon and poquessing when map is centered over 
 waterbody, remove overlay when map moves away
*/ 

//box for wissahickon
var wissBox = new GLatLngBounds(new GLatLng(40.021332,-75.251027), new GLatLng(40.082925,-75.185262));

//box for poquessing
var poqBox = new GLatLngBounds(new GLatLng(40.052367,-75.004183), new GLatLng(40.126083,-74.951026));

var wissAdded = 0;
var poqAdded = 0;

function showOutfallWm() {
	if (wissBox.containsLatLng(map.getCenter()) && wissAdded == 0 && map.getZoom() >= 13) {
		map.addOverlay(wissWm);
		wissAdded = 1;
	} else if (wissBox.containsLatLng(map.getCenter()) == false || map.getZoom() < 13){
		map.removeOverlay(wissWm);
		wissAdded = 0;
	}
	
	if (poqBox.containsLatLng(map.getCenter()) && poqAdded == 0  && map.getZoom() >= 13) {
		map.addOverlay(poqWm);
		poqAdded = 1;
	} else if (poqBox.containsLatLng(map.getCenter()) == false || map.getZoom() < 13){
		map.removeOverlay(poqWm);
		poqAdded = 0;
	}
}